Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -56,30 +56,19 @@ LinkerScriptBase *elf::ScriptBase; ScriptConfiguration *elf::ScriptConfig; -template static void addRegular(SymbolAssignment *Cmd) { +template static SymbolBody *addRegular(SymbolAssignment *Cmd) { uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; Symbol *Sym = Symtab::X->addRegular(Cmd->Name, Visibility, STT_NOTYPE, 0, 0, STB_GLOBAL, nullptr, nullptr); - Cmd->Sym = Sym->body(); - - // If we have no SECTIONS then we don't have '.' and don't call - // assignAddresses(). We calculate symbol value immediately in this case. - if (!ScriptConfig->HasSections) - cast>(Cmd->Sym)->Value = Cmd->Expression(0); + return Sym->body(); } -template static void addSynthetic(SymbolAssignment *Cmd) { - // If we have SECTIONS block then output sections haven't been created yet. +template static SymbolBody *addSynthetic(SymbolAssignment *Cmd) { const OutputSectionBase *Sec = ScriptConfig->HasSections ? nullptr : Cmd->Expression.Section(); Symbol *Sym = Symtab::X->addSynthetic( Cmd->Name, Sec, 0, Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT); - Cmd->Sym = Sym->body(); - - // If we already know section then we can calculate symbol value immediately. - if (Sec) - cast>(Cmd->Sym)->Value = - Cmd->Expression(0) - Sec->Addr; + return Sym->body(); } static bool isUnderSysroot(StringRef Path) { @@ -91,21 +80,44 @@ return false; } -template static void addSymbol(SymbolAssignment *Cmd) { - if (Cmd->Expression.IsAbsolute()) - addRegular(Cmd); - else - addSynthetic(Cmd); +template static void assignSymbol(SymbolAssignment *Cmd) { + // If there are no sections and the symbol value needs to be assigned, + // then do it now. Otherwise, let the value be assigned later in + // `assignAddresses`. + if (ScriptConfig->HasSections) + return; + + uint64_t Value = Cmd->Expression(0); + if (Cmd->Expression.IsAbsolute()) { + cast>(Cmd->Sym)->Value = Value; + } else { + const OutputSectionBase *Sec = Cmd->Expression.Section(); + if (Sec) + cast>(Cmd->Sym)->Value = Value - Sec->Addr; + } } -// If a symbol was in PROVIDE(), we need to define it only when -// it is an undefined symbol. -template static bool shouldDefine(SymbolAssignment *Cmd) { + +template static void addSymbol(SymbolAssignment *Cmd) { if (Cmd->Name == ".") - return false; - if (!Cmd->Provide) - return true; + return; + SymbolBody *B = Symtab::X->find(Cmd->Name); - return B && B->isUndefined(); + auto CreateSymbol = [=](void) { + Cmd->Sym = Cmd->Expression.IsAbsolute() ? addRegular(Cmd) + : addSynthetic(Cmd); + }; + if (Cmd->Provide) { + if (B && B->isUndefined()) { + CreateSymbol(); + assignSymbol(Cmd); + } + } else { + if (!B || B->isUndefined()) + CreateSymbol(); + else + Cmd->Sym = B; + assignSymbol(Cmd); + } } bool SymbolAssignment::classof(const BaseCommand *C) { @@ -314,8 +326,7 @@ // Handle symbol assignments outside of any output section. if (auto *Cmd = dyn_cast(Base1.get())) { - if (shouldDefine(Cmd)) - addSymbol(Cmd); + addSymbol(Cmd); continue; } @@ -357,8 +368,7 @@ // ".foo : { ...; bar = .; }". Handle them. for (const std::unique_ptr &Base : Cmd->Commands) if (auto *OutCmd = dyn_cast(Base.get())) - if (shouldDefine(OutCmd)) - addSymbol(OutCmd); + addSymbol(OutCmd); // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign // is given, input sections are aligned to that value, whether the