Add STB_GNU_UNIQUE to the ELF writer.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 23 Jan 2015 04:44:35 +0000 (04:44 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 23 Jan 2015 04:44:35 +0000 (04:44 +0000)
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
lib/MC/MCELF.cpp
lib/MC/MCELFStreamer.cpp
test/MC/ELF/type.s
tools/llvm-readobj/ELFDumper.cpp

index 3d49205fa168d50923b0b2df49ce7ee3d29de582..ef7db3945739d520303e5b6ad884dd7a6b5385aa 100644 (file)
@@ -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
index 386c2099f2e27277542fac3f3c0c5d23cda62d9a..369063431fefcabfc4f2ba39d9ac7494cbfae362 100644 (file)
@@ -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;
 }
 
index bdc4a8410fb226b3c83b8be300a15a2b497e4fff..5cfcfe5874eac5bb7ab2c94c3a4ec87b9ccef9f9 100644 (file)
@@ -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);
index c82d3006cfe0846d7fe64f1ccc72dc14cbf98a6e..f7745d88ea3c3870475384a01b34414c47cafec5 100644 (file)
@@ -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: ]
index d68c78682d23144288afac41c66055f70edf0f83..e4b760172a34b72861004a7a6ee9af709d4d9717 100644 (file)
@@ -372,9 +372,10 @@ static const EnumEntry<unsigned> ElfMachineType[] = {
 };
 
 static const EnumEntry<unsigned> 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<unsigned> ElfSymbolTypes[] = {