Index: include/llvm/MC/MCContext.h =================================================================== --- include/llvm/MC/MCContext.h +++ include/llvm/MC/MCContext.h @@ -98,6 +98,7 @@ /// Keeps tracks of names that were used both for used declared and /// artificial symbols. StringMap UsedNames; + StringMap UsedSectionNames; /// The next ID to dole out to an unnamed assembler temporary symbol with /// a given prefix. Index: lib/MC/ELFObjectWriter.cpp =================================================================== --- lib/MC/ELFObjectWriter.cpp +++ lib/MC/ELFObjectWriter.cpp @@ -375,9 +375,24 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { + // Section symbols are used as definitions for undefined symbols with matching + // names. If there are multiple sections with the same name, the first one is + // used. + for (const MCSection &Sec : Asm) { + const MCSymbol *Begin = Sec.getBeginSymbol(); + if (!Begin) + continue; + + const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName()); + if (!Alias || !Alias->isUndefined()) + continue; + + Renames.insert( + std::make_pair(cast(Alias), cast(Begin))); + } + // The presence of symbol versions causes undefined symbols and // versions declared with @@@ to be renamed. - for (const MCSymbol &A : Asm.symbols()) { const auto &Alias = cast(A); // Not an alias. Index: lib/MC/MCContext.cpp =================================================================== --- lib/MC/MCContext.cpp +++ lib/MC/MCContext.cpp @@ -39,7 +39,7 @@ const MCObjectFileInfo *mofi, const SourceMgr *mgr, bool DoAutoReset) : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(), - Symbols(Allocator), UsedNames(Allocator), + Symbols(Allocator), UsedNames(Allocator), UsedSectionNames(Allocator), CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4), AllowTemporaryLabels(true), DwarfCompileUnitID(0), @@ -78,6 +78,7 @@ MCSubtargetAllocator.DestroyAll(); UsedNames.clear(); + UsedSectionNames.clear(); Symbols.clear(); SectionSymbols.clear(); Allocator.Reset(); @@ -129,19 +130,9 @@ return Sym; StringRef Name = Section.getSectionName(); - - MCSymbol *&OldSym = Symbols[Name]; - if (OldSym && OldSym->isUndefined()) { - Sym = cast(OldSym); - return Sym; - } - - auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first; + auto NameIter = UsedSectionNames.insert(std::make_pair(Name, true)).first; Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); - if (!OldSym) - OldSym = Sym; - return Sym; } Index: test/MC/ELF/section-sym-err.s =================================================================== --- test/MC/ELF/section-sym-err.s +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o 2>&1 | FileCheck %s - -.section foo -foo: - -// CHECK: error: invalid symbol redefinition Index: test/MC/ELF/section-sym-redefine.s =================================================================== --- /dev/null +++ test/MC/ELF/section-sym-redefine.s @@ -0,0 +1,116 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -t -r --expand-relocs | FileCheck %s + +// Local symbol overriding section. +.section x1,"a",@progbits +.local x1 +.comm x1,4,4 +.long x1 // reloc: .bss + 0 + +// Section declared after local. Local symbol wins. +.local x2 +.comm x2,4,4 +.section x2,"a",@progbits +.long x2 // reloc: .bss + 4 + +// No overriding symbol. +.section x3,"a",@progbits +.long x3 // reloc: x3(section) + 0 + +// Global vs section. +.section x4,"a",@progbits +.long 0 +.globl x4 +x4: +.long 0 +.long x4 // reloc: x4(global) + 0 + +// CHECK: Relocations [ +// CHECK: Section (4) .relax1 { +// CHECK: Relocation { +// CHECK: Offset: 0x0 +// CHECK: Type: R_X86_64_32 (10) +// CHECK: Symbol: .bss (3) +// CHECK: Addend: 0x0 +// CHECK: } +// CHECK: } +// CHECK: Section (7) .relax2 { +// CHECK: Relocation { +// CHECK: Offset: 0x0 +// CHECK: Type: R_X86_64_32 (10) +// CHECK: Symbol: .bss (3) +// CHECK: Addend: 0x4 +// CHECK: } +// CHECK: } +// CHECK: Section (9) .relax3 { +// CHECK: Relocation { +// CHECK: Offset: 0x0 +// CHECK: Type: R_X86_64_32 (10) +// CHECK: Symbol: x3 (4) +// CHECK: Addend: 0x0 +// CHECK: } +// CHECK: } +// CHECK: Section (11) .relax4 { +// CHECK: Relocation { +// CHECK: Offset: 0x8 +// CHECK: Type: R_X86_64_32 (10) +// CHECK: Symbol: x4 (5) +// CHECK: Addend: 0x0 +// CHECK: } +// CHECK: } +// CHECK: ] +// CHECK: Symbols [ +// CHECK: Symbol { +// CHECK: Name: (0) +// CHECK: Value: 0x0 +// CHECK: Size: 0 +// CHECK: Binding: Local (0x0) +// CHECK: Type: None (0x0) +// CHECK: Other: 0 +// CHECK: Section: Undefined (0x0) +// CHECK: } +// CHECK: Symbol { +// CHECK: Name: x1 (57) +// CHECK: Value: 0x0 +// CHECK: Size: 4 +// CHECK: Binding: Local (0x0) +// CHECK: Type: Object (0x1) +// CHECK: Other: 0 +// CHECK: Section: .bss (0x5) +// CHECK: } +// CHECK: Symbol { +// CHECK: Name: x2 (49) +// CHECK: Value: 0x4 +// CHECK: Size: 4 +// CHECK: Binding: Local (0x0) +// CHECK: Type: Object (0x1) +// CHECK: Other: 0 +// CHECK: Section: .bss (0x5) +// CHECK: } +// CHECK: Symbol { +// CHECK: Name: (0) +// CHECK: Value: 0x0 +// CHECK: Size: 0 +// CHECK: Binding: Local (0x0) +// CHECK: Type: Section (0x3) +// CHECK: Other: 0 +// CHECK: Section: .bss (0x5) +// CHECK: } +// CHECK: Symbol { +// CHECK: Name: (0) +// CHECK: Value: 0x0 +// CHECK: Size: 0 +// CHECK: Binding: Local (0x0) +// CHECK: Type: Section (0x3) +// CHECK: Other: 0 +// CHECK: Section: x3 (0x8) +// CHECK: } +// CHECK: Symbol { +// CHECK: Name: x4 (33) +// CHECK: Value: 0x4 +// CHECK: Size: 0 +// CHECK: Binding: Global (0x1) +// CHECK: Type: None (0x0) +// CHECK: Other: 0 +// CHECK: Section: x4 (0xA) +// CHECK: } +// CHECK: ]