diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -44,6 +44,10 @@ def warn_drv_avr_family_linking_stdlibs_not_implemented: Warning< "support for linking stdlibs for microcontroller '%0' is not implemented">, InGroup; +def warn_drv_avr_linker_section_addresses_not_implemented: Warning< + "support for passing the data section address to the linker for " + "microcontroller '%0' is not implemented">, + InGroup; def warn_drv_avr_stdlib_not_linked: Warning< "standard library not linked and so no interrupt vector table or " "compiler runtime routines will be linked">, diff --git a/clang/lib/Driver/ToolChains/AVR.cpp b/clang/lib/Driver/ToolChains/AVR.cpp --- a/clang/lib/Driver/ToolChains/AVR.cpp +++ b/clang/lib/Driver/ToolChains/AVR.cpp @@ -13,6 +13,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/SubtargetFeature.h" @@ -29,13 +30,20 @@ // TODO: Consider merging this into the AVR device table // array in Targets/AVR.cpp. -llvm::Optional GetMcuFamilyName(StringRef MCU) { +llvm::Optional GetMCUFamilyName(StringRef MCU) { return llvm::StringSwitch>(MCU) .Case("atmega328", Optional("avr5")) .Case("atmega328p", Optional("avr5")) .Default(Optional()); } +llvm::Optional GetMCUSectionAddressData(StringRef MCU) { + return llvm::StringSwitch>(MCU) + .Case("atmega328", Optional(0x800100)) + .Case("atmega328p", Optional(0x800100)) + .Default(Optional()); +} + const StringRef PossibleAVRLibcLocations[] = { "/usr/avr", "/usr/lib/avr", @@ -59,7 +67,7 @@ // We cannot link any standard libraries without an MCU specified. D.Diag(diag::warn_drv_avr_mcu_not_specified); } else { - Optional FamilyName = GetMcuFamilyName(CPU); + Optional FamilyName = GetMCUFamilyName(CPU); Optional AVRLibcRoot = findAVRLibcInstallation(); if (!FamilyName.hasValue()) { @@ -102,7 +110,8 @@ const char *LinkingOutput) const { // Compute information about the target AVR. std::string CPU = getCPUName(Args, getToolChain().getTriple()); - llvm::Optional FamilyName = GetMcuFamilyName(CPU); + llvm::Optional FamilyName = GetMCUFamilyName(CPU); + llvm::Optional SectionAddressData = GetMCUSectionAddressData(CPU); std::string Linker = getToolChain().GetProgramPath(getShortName()); ArgStringList CmdArgs; @@ -118,6 +127,17 @@ Args.AddAllArgs(CmdArgs, options::OPT_L); getToolChain().AddFilePathLibArgs(Args, CmdArgs); + if (SectionAddressData.hasValue()) { + std::string DataSectionArg = std::string("-Tdata=0x") + + llvm::utohexstr(SectionAddressData.getValue()); + CmdArgs.push_back(Args.MakeArgString(DataSectionArg)); + } else { + // We do not have an entry for this CPU in the address mapping table yet. + getToolChain().getDriver().Diag( + diag::warn_drv_avr_linker_section_addresses_not_implemented) + << CPU; + } + // If the family name is known, we can link with the device-specific libgcc. // Without it, libgcc will simply not be linked. This matches avr-gcc // behavior.