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,46 @@ 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 a symbol was in PROVIDE(), we need to define it only when + // it is an undefined symbol. + 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 +328,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 +370,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 Index: test/ELF/linkerscript/symbol-assignexpr.s =================================================================== --- test/ELF/linkerscript/symbol-assignexpr.s +++ test/ELF/linkerscript/symbol-assignexpr.s @@ -13,14 +13,18 @@ # RUN: symbol9 = - 4; \ # RUN: symbol10 = 0xfedcba9876543210; \ # RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \ +# RUN: symbol12 = 0x1234; \ +# RUN: symbol12 += 1; \ +# RUN: bar = 0x5678; \ # RUN: }" > %t.script # RUN: ld.lld -o %t1 --script %t.script %t # RUN: llvm-objdump -t %t1 | FileCheck %s # CHECK: SYMBOL TABLE: # CHECK-NEXT: 0000000000000000 *UND* 00000000 -# CHECK-NEXT: .text 00000000 _start -# CHECK-NEXT: .text 00000000 foo +# CHECK-NEXT: 0000000000000000 .text 00000000 _start +# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar +# CHECK-NEXT: 0000000000000001 .text 00000000 foo # CHECK-NEXT: 0000000000001000 *ABS* 00000000 symbol # CHECK-NEXT: 0000000000002234 *ABS* 00000000 symbol2 # CHECK-NEXT: 0000000000002234 *ABS* 00000000 symbol3 @@ -32,6 +36,7 @@ # CHECK-NEXT: fffffffffffffffc *ABS* 00000000 symbol9 # CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10 # CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11 +# CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12 # RUN: echo "SECTIONS { \ # RUN: symbol2 = symbol; \ @@ -46,3 +51,7 @@ .global foo foo: + nop + +.global bar +bar = 0x1234 Index: test/ELF/mips-gp-ext.s =================================================================== --- test/ELF/mips-gp-ext.s +++ test/ELF/mips-gp-ext.s @@ -1,10 +1,6 @@ # Check that the linker use a value of _gp symbol defined # in a linker script to calculate GOT relocations. -# FIXME: This test is xfailed because it depends on D27276 patch -# that enables absolute symbols redefinition by a linker's script. -# XFAIL: * - # RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { \