Path: blob/main/contrib/llvm-project/clang/lib/Driver/ToolChains/AVR.cpp
35294 views
//===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "AVR.h"9#include "CommonArgs.h"10#include "clang/Driver/Compilation.h"11#include "clang/Driver/DriverDiagnostic.h"12#include "clang/Driver/InputInfo.h"13#include "clang/Driver/Options.h"14#include "llvm/ADT/StringExtras.h"15#include "llvm/MC/MCSubtargetInfo.h"16#include "llvm/Option/ArgList.h"17#include "llvm/Support/FileSystem.h"18#include "llvm/Support/Path.h"19#include "llvm/TargetParser/SubtargetFeature.h"2021using namespace clang::driver;22using namespace clang::driver::toolchains;23using namespace clang::driver::tools;24using namespace clang;25using namespace llvm::opt;2627namespace {2829// NOTE: This list has been synchronized with gcc-avr 7.3.0 and avr-libc 2.0.0.30constexpr struct {31StringRef Name;32StringRef SubPath;33StringRef Family;34unsigned DataAddr;35} MCUInfo[] = {36{"at90s1200", "", "avr1", 0},37{"attiny11", "", "avr1", 0},38{"attiny12", "", "avr1", 0},39{"attiny15", "", "avr1", 0},40{"attiny28", "", "avr1", 0},41{"at90s2313", "tiny-stack", "avr2", 0x800060},42{"at90s2323", "tiny-stack", "avr2", 0x800060},43{"at90s2333", "tiny-stack", "avr2", 0x800060},44{"at90s2343", "tiny-stack", "avr2", 0x800060},45{"at90s4433", "tiny-stack", "avr2", 0x800060},46{"attiny22", "tiny-stack", "avr2", 0x800060},47{"attiny26", "tiny-stack", "avr2", 0x800060},48{"at90s4414", "", "avr2", 0x800060},49{"at90s4434", "", "avr2", 0x800060},50{"at90s8515", "", "avr2", 0x800060},51{"at90c8534", "", "avr2", 0x800060},52{"at90s8535", "", "avr2", 0x800060},53{"attiny13", "avr25/tiny-stack", "avr25", 0x800060},54{"attiny13a", "avr25/tiny-stack", "avr25", 0x800060},55{"attiny2313", "avr25/tiny-stack", "avr25", 0x800060},56{"attiny2313a", "avr25/tiny-stack", "avr25", 0x800060},57{"attiny24", "avr25/tiny-stack", "avr25", 0x800060},58{"attiny24a", "avr25/tiny-stack", "avr25", 0x800060},59{"attiny25", "avr25/tiny-stack", "avr25", 0x800060},60{"attiny261", "avr25/tiny-stack", "avr25", 0x800060},61{"attiny261a", "avr25/tiny-stack", "avr25", 0x800060},62{"at86rf401", "avr25", "avr25", 0x800060},63{"ata5272", "avr25", "avr25", 0x800100},64{"ata6616c", "avr25", "avr25", 0x800100},65{"attiny4313", "avr25", "avr25", 0x800060},66{"attiny44", "avr25", "avr25", 0x800060},67{"attiny44a", "avr25", "avr25", 0x800060},68{"attiny84", "avr25", "avr25", 0x800060},69{"attiny84a", "avr25", "avr25", 0x800060},70{"attiny45", "avr25", "avr25", 0x800060},71{"attiny85", "avr25", "avr25", 0x800060},72{"attiny441", "avr25", "avr25", 0x800100},73{"attiny461", "avr25", "avr25", 0x800060},74{"attiny461a", "avr25", "avr25", 0x800060},75{"attiny841", "avr25", "avr25", 0x800100},76{"attiny861", "avr25", "avr25", 0x800060},77{"attiny861a", "avr25", "avr25", 0x800060},78{"attiny87", "avr25", "avr25", 0x800100},79{"attiny43u", "avr25", "avr25", 0x800060},80{"attiny48", "avr25", "avr25", 0x800100},81{"attiny88", "avr25", "avr25", 0x800100},82{"attiny828", "avr25", "avr25", 0x800100},83{"at43usb355", "avr3", "avr3", 0x800100},84{"at76c711", "avr3", "avr3", 0x800060},85{"atmega103", "avr31", "avr31", 0x800060},86{"at43usb320", "avr31", "avr31", 0x800060},87{"attiny167", "avr35", "avr35", 0x800100},88{"at90usb82", "avr35", "avr35", 0x800100},89{"at90usb162", "avr35", "avr35", 0x800100},90{"ata5505", "avr35", "avr35", 0x800100},91{"ata6617c", "avr35", "avr35", 0x800100},92{"ata664251", "avr35", "avr35", 0x800100},93{"atmega8u2", "avr35", "avr35", 0x800100},94{"atmega16u2", "avr35", "avr35", 0x800100},95{"atmega32u2", "avr35", "avr35", 0x800100},96{"attiny1634", "avr35", "avr35", 0x800100},97{"atmega8", "avr4", "avr4", 0x800060},98{"ata6289", "avr4", "avr4", 0x800100},99{"atmega8a", "avr4", "avr4", 0x800060},100{"ata6285", "avr4", "avr4", 0x800100},101{"ata6286", "avr4", "avr4", 0x800100},102{"ata6612c", "avr4", "avr4", 0x800100},103{"atmega48", "avr4", "avr4", 0x800100},104{"atmega48a", "avr4", "avr4", 0x800100},105{"atmega48pa", "avr4", "avr4", 0x800100},106{"atmega48pb", "avr4", "avr4", 0x800100},107{"atmega48p", "avr4", "avr4", 0x800100},108{"atmega88", "avr4", "avr4", 0x800100},109{"atmega88a", "avr4", "avr4", 0x800100},110{"atmega88p", "avr4", "avr4", 0x800100},111{"atmega88pa", "avr4", "avr4", 0x800100},112{"atmega88pb", "avr4", "avr4", 0x800100},113{"atmega8515", "avr4", "avr4", 0x800060},114{"atmega8535", "avr4", "avr4", 0x800060},115{"atmega8hva", "avr4", "avr4", 0x800100},116{"at90pwm1", "avr4", "avr4", 0x800100},117{"at90pwm2", "avr4", "avr4", 0x800100},118{"at90pwm2b", "avr4", "avr4", 0x800100},119{"at90pwm3", "avr4", "avr4", 0x800100},120{"at90pwm3b", "avr4", "avr4", 0x800100},121{"at90pwm81", "avr4", "avr4", 0x800100},122{"ata5702m322", "avr5", "avr5", 0x800200},123{"ata5782", "avr5", "avr5", 0x800200},124{"ata5790", "avr5", "avr5", 0x800100},125{"ata5790n", "avr5", "avr5", 0x800100},126{"ata5791", "avr5", "avr5", 0x800100},127{"ata5795", "avr5", "avr5", 0x800100},128{"ata5831", "avr5", "avr5", 0x800200},129{"ata6613c", "avr5", "avr5", 0x800100},130{"ata6614q", "avr5", "avr5", 0x800100},131{"ata8210", "avr5", "avr5", 0x800200},132{"ata8510", "avr5", "avr5", 0x800200},133{"atmega16", "avr5", "avr5", 0x800060},134{"atmega16a", "avr5", "avr5", 0x800060},135{"atmega161", "avr5", "avr5", 0x800060},136{"atmega162", "avr5", "avr5", 0x800100},137{"atmega163", "avr5", "avr5", 0x800060},138{"atmega164a", "avr5", "avr5", 0x800100},139{"atmega164p", "avr5", "avr5", 0x800100},140{"atmega164pa", "avr5", "avr5", 0x800100},141{"atmega165", "avr5", "avr5", 0x800100},142{"atmega165a", "avr5", "avr5", 0x800100},143{"atmega165p", "avr5", "avr5", 0x800100},144{"atmega165pa", "avr5", "avr5", 0x800100},145{"atmega168", "avr5", "avr5", 0x800100},146{"atmega168a", "avr5", "avr5", 0x800100},147{"atmega168p", "avr5", "avr5", 0x800100},148{"atmega168pa", "avr5", "avr5", 0x800100},149{"atmega168pb", "avr5", "avr5", 0x800100},150{"atmega169", "avr5", "avr5", 0x800100},151{"atmega169a", "avr5", "avr5", 0x800100},152{"atmega169p", "avr5", "avr5", 0x800100},153{"atmega169pa", "avr5", "avr5", 0x800100},154{"atmega32", "avr5", "avr5", 0x800060},155{"atmega32a", "avr5", "avr5", 0x800060},156{"atmega323", "avr5", "avr5", 0x800060},157{"atmega324a", "avr5", "avr5", 0x800100},158{"atmega324p", "avr5", "avr5", 0x800100},159{"atmega324pa", "avr5", "avr5", 0x800100},160{"atmega324pb", "avr5", "avr5", 0x800100},161{"atmega325", "avr5", "avr5", 0x800100},162{"atmega325a", "avr5", "avr5", 0x800100},163{"atmega325p", "avr5", "avr5", 0x800100},164{"atmega325pa", "avr5", "avr5", 0x800100},165{"atmega3250", "avr5", "avr5", 0x800100},166{"atmega3250a", "avr5", "avr5", 0x800100},167{"atmega3250p", "avr5", "avr5", 0x800100},168{"atmega3250pa", "avr5", "avr5", 0x800100},169{"atmega328", "avr5", "avr5", 0x800100},170{"atmega328p", "avr5", "avr5", 0x800100},171{"atmega328pb", "avr5", "avr5", 0x800100},172{"atmega329", "avr5", "avr5", 0x800100},173{"atmega329a", "avr5", "avr5", 0x800100},174{"atmega329p", "avr5", "avr5", 0x800100},175{"atmega329pa", "avr5", "avr5", 0x800100},176{"atmega3290", "avr5", "avr5", 0x800100},177{"atmega3290a", "avr5", "avr5", 0x800100},178{"atmega3290p", "avr5", "avr5", 0x800100},179{"atmega3290pa", "avr5", "avr5", 0x800100},180{"atmega406", "avr5", "avr5", 0x800100},181{"atmega64", "avr5", "avr5", 0x800100},182{"atmega64a", "avr5", "avr5", 0x800100},183{"atmega640", "avr5", "avr5", 0x800200},184{"atmega644", "avr5", "avr5", 0x800100},185{"atmega644a", "avr5", "avr5", 0x800100},186{"atmega644p", "avr5", "avr5", 0x800100},187{"atmega644pa", "avr5", "avr5", 0x800100},188{"atmega645", "avr5", "avr5", 0x800100},189{"atmega645a", "avr5", "avr5", 0x800100},190{"atmega645p", "avr5", "avr5", 0x800100},191{"atmega649", "avr5", "avr5", 0x800100},192{"atmega649a", "avr5", "avr5", 0x800100},193{"atmega649p", "avr5", "avr5", 0x800100},194{"atmega6450", "avr5", "avr5", 0x800100},195{"atmega6450a", "avr5", "avr5", 0x800100},196{"atmega6450p", "avr5", "avr5", 0x800100},197{"atmega6490", "avr5", "avr5", 0x800100},198{"atmega6490a", "avr5", "avr5", 0x800100},199{"atmega6490p", "avr5", "avr5", 0x800100},200{"atmega64rfr2", "avr5", "avr5", 0x800200},201{"atmega644rfr2", "avr5", "avr5", 0x800200},202{"atmega16hva", "avr5", "avr5", 0x800100},203{"atmega16hva2", "avr5", "avr5", 0x800100},204{"atmega16hvb", "avr5", "avr5", 0x800100},205{"atmega16hvbrevb", "avr5", "avr5", 0x800100},206{"atmega32hvb", "avr5", "avr5", 0x800100},207{"atmega32hvbrevb", "avr5", "avr5", 0x800100},208{"atmega64hve", "avr5", "avr5", 0x800100},209{"atmega64hve2", "avr5", "avr5", 0x800100},210{"at90can32", "avr5", "avr5", 0x800100},211{"at90can64", "avr5", "avr5", 0x800100},212{"at90pwm161", "avr5", "avr5", 0x800100},213{"at90pwm216", "avr5", "avr5", 0x800100},214{"at90pwm316", "avr5", "avr5", 0x800100},215{"atmega32c1", "avr5", "avr5", 0x800100},216{"atmega64c1", "avr5", "avr5", 0x800100},217{"atmega16m1", "avr5", "avr5", 0x800100},218{"atmega32m1", "avr5", "avr5", 0x800100},219{"atmega64m1", "avr5", "avr5", 0x800100},220{"atmega16u4", "avr5", "avr5", 0x800100},221{"atmega32u4", "avr5", "avr5", 0x800100},222{"atmega32u6", "avr5", "avr5", 0x800100},223{"at90usb646", "avr5", "avr5", 0x800100},224{"at90usb647", "avr5", "avr5", 0x800100},225{"at90scr100", "avr5", "avr5", 0x800100},226{"at94k", "avr5", "avr5", 0x800060},227{"m3000", "avr5", "avr5", 0x800060},228{"atmega128", "avr51", "avr51", 0x800100},229{"atmega128a", "avr51", "avr51", 0x800100},230{"atmega1280", "avr51", "avr51", 0x800200},231{"atmega1281", "avr51", "avr51", 0x800200},232{"atmega1284", "avr51", "avr51", 0x800100},233{"atmega1284p", "avr51", "avr51", 0x800100},234{"atmega128rfa1", "avr51", "avr51", 0x800200},235{"atmega128rfr2", "avr51", "avr51", 0x800200},236{"atmega1284rfr2", "avr51", "avr51", 0x800200},237{"at90can128", "avr51", "avr51", 0x800200},238{"at90usb1286", "avr51", "avr51", 0x800200},239{"at90usb1287", "avr51", "avr51", 0x800200},240{"atmega2560", "avr6", "avr6", 0x800200},241{"atmega2561", "avr6", "avr6", 0x800200},242{"atmega256rfr2", "avr6", "avr6", 0x800200},243{"atmega2564rfr2", "avr6", "avr6", 0x800200},244{"attiny4", "avrtiny", "avrtiny", 0x800040},245{"attiny5", "avrtiny", "avrtiny", 0x800040},246{"attiny9", "avrtiny", "avrtiny", 0x800040},247{"attiny10", "avrtiny", "avrtiny", 0x800040},248{"attiny20", "avrtiny", "avrtiny", 0x800040},249{"attiny40", "avrtiny", "avrtiny", 0x800040},250{"attiny102", "avrtiny", "avrtiny", 0x800040},251{"attiny104", "avrtiny", "avrtiny", 0x800040},252{"atxmega16a4", "avrxmega2", "avrxmega2", 0x802000},253{"atxmega16a4u", "avrxmega2", "avrxmega2", 0x802000},254{"atxmega16c4", "avrxmega2", "avrxmega2", 0x802000},255{"atxmega16d4", "avrxmega2", "avrxmega2", 0x802000},256{"atxmega32a4", "avrxmega2", "avrxmega2", 0x802000},257{"atxmega32a4u", "avrxmega2", "avrxmega2", 0x802000},258{"atxmega32c3", "avrxmega2", "avrxmega2", 0x802000},259{"atxmega32c4", "avrxmega2", "avrxmega2", 0x802000},260{"atxmega32d3", "avrxmega2", "avrxmega2", 0x802000},261{"atxmega32d4", "avrxmega2", "avrxmega2", 0x802000},262{"atxmega32e5", "avrxmega2", "avrxmega2", 0x802000},263{"atxmega16e5", "avrxmega2", "avrxmega2", 0x802000},264{"atxmega8e5", "avrxmega2", "avrxmega2", 0x802000},265{"atxmega64a3", "avrxmega4", "avrxmega4", 0x802000},266{"atxmega64a3u", "avrxmega4", "avrxmega4", 0x802000},267{"atxmega64a4u", "avrxmega4", "avrxmega4", 0x802000},268{"atxmega64b1", "avrxmega4", "avrxmega4", 0x802000},269{"atxmega64b3", "avrxmega4", "avrxmega4", 0x802000},270{"atxmega64c3", "avrxmega4", "avrxmega4", 0x802000},271{"atxmega64d3", "avrxmega4", "avrxmega4", 0x802000},272{"atxmega64d4", "avrxmega4", "avrxmega4", 0x802000},273{"atxmega64a1", "avrxmega5", "avrxmega5", 0x802000},274{"atxmega64a1u", "avrxmega5", "avrxmega5", 0x802000},275{"atxmega128a3", "avrxmega6", "avrxmega6", 0x802000},276{"atxmega128a3u", "avrxmega6", "avrxmega6", 0x802000},277{"atxmega128b1", "avrxmega6", "avrxmega6", 0x802000},278{"atxmega128b3", "avrxmega6", "avrxmega6", 0x802000},279{"atxmega128c3", "avrxmega6", "avrxmega6", 0x802000},280{"atxmega128d3", "avrxmega6", "avrxmega6", 0x802000},281{"atxmega128d4", "avrxmega6", "avrxmega6", 0x802000},282{"atxmega192a3", "avrxmega6", "avrxmega6", 0x802000},283{"atxmega192a3u", "avrxmega6", "avrxmega6", 0x802000},284{"atxmega192c3", "avrxmega6", "avrxmega6", 0x802000},285{"atxmega192d3", "avrxmega6", "avrxmega6", 0x802000},286{"atxmega256a3", "avrxmega6", "avrxmega6", 0x802000},287{"atxmega256a3u", "avrxmega6", "avrxmega6", 0x802000},288{"atxmega256a3b", "avrxmega6", "avrxmega6", 0x802000},289{"atxmega256a3bu", "avrxmega6", "avrxmega6", 0x802000},290{"atxmega256c3", "avrxmega6", "avrxmega6", 0x802000},291{"atxmega256d3", "avrxmega6", "avrxmega6", 0x802000},292{"atxmega384c3", "avrxmega6", "avrxmega6", 0x802000},293{"atxmega384d3", "avrxmega6", "avrxmega6", 0x802000},294{"atxmega128a1", "avrxmega7", "avrxmega7", 0x802000},295{"atxmega128a1u", "avrxmega7", "avrxmega7", 0x802000},296{"atxmega128a4u", "avrxmega7", "avrxmega7", 0x802000},297{"attiny202", "avrxmega3/short-calls", "avrxmega3", 0x803F80},298{"attiny204", "avrxmega3/short-calls", "avrxmega3", 0x803F80},299{"attiny212", "avrxmega3/short-calls", "avrxmega3", 0x803F80},300{"attiny214", "avrxmega3/short-calls", "avrxmega3", 0x803F80},301{"attiny402", "avrxmega3/short-calls", "avrxmega3", 0x803F00},302{"attiny404", "avrxmega3/short-calls", "avrxmega3", 0x803F00},303{"attiny406", "avrxmega3/short-calls", "avrxmega3", 0x803F00},304{"attiny412", "avrxmega3/short-calls", "avrxmega3", 0x803F00},305{"attiny414", "avrxmega3/short-calls", "avrxmega3", 0x803F00},306{"attiny416", "avrxmega3/short-calls", "avrxmega3", 0x803F00},307{"attiny417", "avrxmega3/short-calls", "avrxmega3", 0x803F00},308{"attiny804", "avrxmega3/short-calls", "avrxmega3", 0x803E00},309{"attiny806", "avrxmega3/short-calls", "avrxmega3", 0x803E00},310{"attiny807", "avrxmega3/short-calls", "avrxmega3", 0x803E00},311{"attiny814", "avrxmega3/short-calls", "avrxmega3", 0x803E00},312{"attiny816", "avrxmega3/short-calls", "avrxmega3", 0x803E00},313{"attiny817", "avrxmega3/short-calls", "avrxmega3", 0x803E00},314{"atmega808", "avrxmega3/short-calls", "avrxmega3", 0x803C00},315{"atmega809", "avrxmega3/short-calls", "avrxmega3", 0x803C00},316{"atmega1608", "avrxmega3", "avrxmega3", 0x803800},317{"atmega1609", "avrxmega3", "avrxmega3", 0x803800},318{"atmega3208", "avrxmega3", "avrxmega3", 0x803000},319{"atmega3209", "avrxmega3", "avrxmega3", 0x803000},320{"atmega4808", "avrxmega3", "avrxmega3", 0x802800},321{"atmega4809", "avrxmega3", "avrxmega3", 0x802800},322{"attiny1604", "avrxmega3", "avrxmega3", 0x803C00},323{"attiny1606", "avrxmega3", "avrxmega3", 0x803C00},324{"attiny1607", "avrxmega3", "avrxmega3", 0x803C00},325{"attiny1614", "avrxmega3", "avrxmega3", 0x803800},326{"attiny1616", "avrxmega3", "avrxmega3", 0x803800},327{"attiny1617", "avrxmega3", "avrxmega3", 0x803800},328{"attiny1624", "avrxmega3", "avrxmega3", 0x803800},329{"attiny1626", "avrxmega3", "avrxmega3", 0x803800},330{"attiny1627", "avrxmega3", "avrxmega3", 0x803800},331{"attiny3216", "avrxmega3", "avrxmega3", 0x803800},332{"attiny3217", "avrxmega3", "avrxmega3", 0x803800},333};334335std::string GetMCUSubPath(StringRef MCUName) {336for (const auto &MCU : MCUInfo)337if (MCU.Name == MCUName)338return std::string(MCU.SubPath);339return "";340}341342std::optional<StringRef> GetMCUFamilyName(StringRef MCUName) {343for (const auto &MCU : MCUInfo)344if (MCU.Name == MCUName)345return std::optional<StringRef>(MCU.Family);346return std::nullopt;347}348349std::optional<unsigned> GetMCUSectionAddressData(StringRef MCUName) {350for (const auto &MCU : MCUInfo)351if (MCU.Name == MCUName && MCU.DataAddr > 0)352return std::optional<unsigned>(MCU.DataAddr);353return std::nullopt;354}355356const StringRef PossibleAVRLibcLocations[] = {357"/avr",358"/usr/avr",359"/usr/lib/avr",360};361362} // end anonymous namespace363364/// AVR Toolchain365AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,366const ArgList &Args)367: Generic_ELF(D, Triple, Args) {368GCCInstallation.init(Triple, Args);369370if (getCPUName(D, Args, Triple).empty())371D.Diag(diag::warn_drv_avr_mcu_not_specified);372373// Only add default libraries if the user hasn't explicitly opted out.374if (!Args.hasArg(options::OPT_nostdlib) &&375!Args.hasArg(options::OPT_nodefaultlibs) && GCCInstallation.isValid()) {376GCCInstallPath = GCCInstallation.getInstallPath();377std::string GCCParentPath(GCCInstallation.getParentLibPath());378getProgramPaths().push_back(GCCParentPath + "/../bin");379}380}381382void AVRToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,383ArgStringList &CC1Args) const {384if (DriverArgs.hasArg(options::OPT_nostdinc) ||385DriverArgs.hasArg(options::OPT_nostdlibinc))386return;387388// Omit if there is no avr-libc installed.389std::optional<std::string> AVRLibcRoot = findAVRLibcInstallation();390if (!AVRLibcRoot)391return;392393// Add 'avr-libc/include' to clang system include paths if applicable.394std::string AVRInc = *AVRLibcRoot + "/include";395if (llvm::sys::fs::is_directory(AVRInc))396addSystemInclude(DriverArgs, CC1Args, AVRInc);397}398399void AVRToolChain::addClangTargetOptions(400const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,401Action::OffloadKind DeviceOffloadKind) const {402// By default, use `.ctors` (not `.init_array`), as required by libgcc, which403// runs constructors/destructors on AVR.404if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,405options::OPT_fno_use_init_array, false))406CC1Args.push_back("-fno-use-init-array");407// Use `-fno-use-cxa-atexit` as default, since avr-libc does not support408// `__cxa_atexit()`.409if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit,410options::OPT_fno_use_cxa_atexit, false))411CC1Args.push_back("-fno-use-cxa-atexit");412}413414Tool *AVRToolChain::buildLinker() const {415return new tools::AVR::Linker(getTriple(), *this);416}417418std::string419AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,420FileType Type = ToolChain::FT_Static) const {421assert(Type == ToolChain::FT_Static && "AVR only supports static libraries");422// Since AVR can never be a host environment, its compiler-rt library files423// should always have ".a" suffix, even on windows.424SmallString<32> File("/libclang_rt.");425File += Component.str();426File += ".a";427// Return the default compiler-rt path appended with428// "avr/libclang_rt.$COMPONENT.a".429SmallString<256> Path(ToolChain::getCompilerRTPath());430llvm::sys::path::append(Path, "avr");431llvm::sys::path::append(Path, File.str());432return std::string(Path);433}434435void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,436const InputInfo &Output,437const InputInfoList &Inputs, const ArgList &Args,438const char *LinkingOutput) const {439const auto &TC = static_cast<const AVRToolChain &>(getToolChain());440const Driver &D = getToolChain().getDriver();441442// Compute information about the target AVR.443std::string CPU = getCPUName(D, Args, getToolChain().getTriple());444std::optional<StringRef> FamilyName = GetMCUFamilyName(CPU);445std::optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation();446std::optional<unsigned> SectionAddressData = GetMCUSectionAddressData(CPU);447448// Compute the linker program path, and use GNU "avr-ld" as default.449const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);450std::string Linker = A ? getToolChain().GetLinkerPath(nullptr)451: getToolChain().GetProgramPath(getShortName());452453ArgStringList CmdArgs;454455CmdArgs.push_back("-o");456CmdArgs.push_back(Output.getFilename());457458// Enable garbage collection of unused sections.459if (!Args.hasArg(options::OPT_r))460CmdArgs.push_back("--gc-sections");461462// Add library search paths before we specify libraries.463Args.AddAllArgs(CmdArgs, options::OPT_L);464getToolChain().AddFilePathLibArgs(Args, CmdArgs);465466// Currently we only support libgcc and compiler-rt.467auto RtLib = TC.GetRuntimeLibType(Args);468assert(469(RtLib == ToolChain::RLT_Libgcc || RtLib == ToolChain::RLT_CompilerRT) &&470"unknown runtime library");471472// Only add default libraries if the user hasn't explicitly opted out.473bool LinkStdlib = false;474if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_r) &&475!Args.hasArg(options::OPT_nodefaultlibs)) {476if (!CPU.empty()) {477if (!FamilyName) {478// We do not have an entry for this CPU in the family479// mapping table yet.480D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented)481<< CPU;482} else if (!AVRLibcRoot) {483// No avr-libc found and so no runtime linked.484D.Diag(diag::warn_drv_avr_libc_not_found);485} else {486std::string SubPath = GetMCUSubPath(CPU);487// Add path of avr-libc.488CmdArgs.push_back(489Args.MakeArgString(Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath));490if (RtLib == ToolChain::RLT_Libgcc)491CmdArgs.push_back(Args.MakeArgString("-L" + TC.getGCCInstallPath() +492"/" + SubPath));493LinkStdlib = true;494}495}496if (!LinkStdlib)497D.Diag(diag::warn_drv_avr_stdlib_not_linked);498}499500if (!Args.hasArg(options::OPT_r)) {501if (SectionAddressData) {502CmdArgs.push_back(503Args.MakeArgString("--defsym=__DATA_REGION_ORIGIN__=0x" +504Twine::utohexstr(*SectionAddressData)));505} else {506// We do not have an entry for this CPU in the address mapping table507// yet.508D.Diag(diag::warn_drv_avr_linker_section_addresses_not_implemented)509<< CPU;510}511}512513if (D.isUsingLTO()) {514assert(!Inputs.empty() && "Must have at least one input.");515// Find the first filename InputInfo object.516auto Input = llvm::find_if(517Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); });518if (Input == Inputs.end())519// For a very rare case, all of the inputs to the linker are520// InputArg. If that happens, just use the first InputInfo.521Input = Inputs.begin();522523addLTOOptions(TC, Args, CmdArgs, Output, *Input,524D.getLTOMode() == LTOK_Thin);525}526527// If the family name is known, we can link with the device-specific libgcc.528// Without it, libgcc will simply not be linked. This matches avr-gcc529// behavior.530if (LinkStdlib) {531assert(!CPU.empty() && "CPU name must be known in order to link stdlibs");532533CmdArgs.push_back("--start-group");534535// Add the object file for the CRT.536std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o");537CmdArgs.push_back(Args.MakeArgString(CrtFileName));538539// Link to libgcc.540if (RtLib == ToolChain::RLT_Libgcc)541CmdArgs.push_back("-lgcc");542543// Link to generic libraries of avr-libc.544CmdArgs.push_back("-lm");545CmdArgs.push_back("-lc");546547// Add the link library specific to the MCU.548CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU));549550// Add the relocatable inputs.551AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);552553// We directly use libclang_rt.builtins.a as input file, instead of using554// '-lclang_rt.builtins'.555if (RtLib == ToolChain::RLT_CompilerRT) {556std::string RtLib =557getToolChain().getCompilerRT(Args, "builtins", ToolChain::FT_Static);558if (llvm::sys::fs::exists(RtLib))559CmdArgs.push_back(Args.MakeArgString(RtLib));560}561562CmdArgs.push_back("--end-group");563564// Add avr-libc's linker script to lld by default, if it exists.565if (!Args.hasArg(options::OPT_T) &&566Linker.find("avr-ld") == std::string::npos) {567std::string Path(*AVRLibcRoot + "/lib/ldscripts/");568Path += *FamilyName;569Path += ".x";570if (llvm::sys::fs::exists(Path))571CmdArgs.push_back(Args.MakeArgString("-T" + Path));572}573// Otherwise add user specified linker script to either avr-ld or lld.574else575Args.AddAllArgs(CmdArgs, options::OPT_T);576577if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true))578CmdArgs.push_back("--relax");579} else {580AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);581}582583// Specify the family name as the emulation mode to use.584// This is almost always required because otherwise avr-ld585// will assume 'avr2' and warn about the program being larger586// than the bare minimum supports.587if (Linker.find("avr-ld") != std::string::npos && FamilyName)588CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));589590C.addCommand(std::make_unique<Command>(591JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),592CmdArgs, Inputs, Output));593}594595std::optional<std::string> AVRToolChain::findAVRLibcInstallation() const {596// Search avr-libc installation according to avr-gcc installation.597std::string GCCParent(GCCInstallation.getParentLibPath());598std::string Path(GCCParent + "/avr");599if (llvm::sys::fs::is_directory(Path))600return Path;601Path = GCCParent + "/../avr";602if (llvm::sys::fs::is_directory(Path))603return Path;604605// Search avr-libc installation from possible locations, and return the first606// one that exists, if there is no avr-gcc installed.607for (StringRef PossiblePath : PossibleAVRLibcLocations) {608std::string Path = getDriver().SysRoot + PossiblePath.str();609if (llvm::sys::fs::is_directory(Path))610return Path;611}612613return std::nullopt;614}615616617