From eb3eb88fb76f27da147c3cdb36797272f1d769a6 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 23 Jan 2015 04:44:35 +0000 Subject: [PATCH] Add STB_GNU_UNIQUE to the ELF writer. This lets llvm-mc assemble files produced by gcc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226895 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/ELF.h | 1 + lib/MC/MCELF.cpp | 4 ++-- lib/MC/MCELFStreamer.cpp | 8 +++++++- test/MC/ELF/type.s | 12 +++++++++++- tools/llvm-readobj/ELFDumper.cpp | 7 ++++--- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 3d49205fa16..ef7db394573 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -761,6 +761,7 @@ enum { STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def STB_GLOBAL = 1, // Global symbol, visible to all object files being combined STB_WEAK = 2, // Weak symbol, like global but lower-precedence + STB_GNU_UNIQUE = 10, STB_LOOS = 10, // Lowest operating system-specific binding type STB_HIOS = 12, // Highest operating system-specific binding type STB_LOPROC = 13, // Lowest processor-specific binding type diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp index 386c2099f2e..369063431fe 100644 --- a/lib/MC/MCELF.cpp +++ b/lib/MC/MCELF.cpp @@ -21,7 +21,7 @@ namespace llvm { void MCELF::SetBinding(MCSymbolData &SD, unsigned Binding) { assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK); + Binding == ELF::STB_WEAK || Binding == ELF::STB_GNU_UNIQUE); uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); } @@ -29,7 +29,7 @@ void MCELF::SetBinding(MCSymbolData &SD, unsigned Binding) { unsigned MCELF::GetBinding(const MCSymbolData &SD) { uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift; assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK); + Binding == ELF::STB_WEAK || Binding == ELF::STB_GNU_UNIQUE); return Binding; } diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index bdc4a8410fb..5cfcfe5874e 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -171,10 +171,16 @@ bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, return false; case MCSA_NoDeadStrip: - case MCSA_ELF_TypeGnuUniqueObject: // Ignore for now. break; + case MCSA_ELF_TypeGnuUniqueObject: + MCELF::SetType(SD, CombineSymbolTypes(MCELF::GetType(SD), ELF::STT_OBJECT)); + MCELF::SetBinding(SD, ELF::STB_GNU_UNIQUE); + SD.setExternal(true); + BindingExplicitlySet.insert(Symbol); + break; + case MCSA_Global: MCELF::SetBinding(SD, ELF::STB_GLOBAL); SD.setExternal(true); diff --git a/test/MC/ELF/type.s b/test/MC/ELF/type.s index c82d3006cfe..f7745d88ea3 100644 --- a/test/MC/ELF/type.s +++ b/test/MC/ELF/type.s @@ -9,8 +9,8 @@ foo: .type bar,@object bar: -// Test that gnu_unique_object is accepted. .type zed,@gnu_unique_object +zed: obj: .global obj @@ -310,3 +310,13 @@ alias12: // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: .text (0x1) // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: zed (32) +// CHECK-NEXT: Value: 0x0 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Unique (0xA) +// CHECK-NEXT: Type: Object (0x1) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text (0x1) +// CHECK-NEXT: } +// CHECK-NEXT: ] diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index d68c78682d2..e4b760172a3 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -372,9 +372,10 @@ static const EnumEntry ElfMachineType[] = { }; static const EnumEntry ElfSymbolBindings[] = { - { "Local", ELF::STB_LOCAL }, - { "Global", ELF::STB_GLOBAL }, - { "Weak", ELF::STB_WEAK } + { "Local", ELF::STB_LOCAL }, + { "Global", ELF::STB_GLOBAL }, + { "Weak", ELF::STB_WEAK }, + { "Unique", ELF::STB_GNU_UNIQUE } }; static const EnumEntry ElfSymbolTypes[] = {