If a symbol is used as tls, mark it as tls even if not declare as so. Probably
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 24 Nov 2010 02:19:40 +0000 (02:19 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 24 Nov 2010 02:19:40 +0000 (02:19 +0000)
fixes PR8659.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120076 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCELFStreamer.cpp
test/MC/ELF/tls.s

index a3c716bdcb7f6876c942e2cd2f30e6ec7b30944b..1eddda9fefca9c3b6f100d753dbc2f228203483b 100644 (file)
@@ -144,6 +144,8 @@ private:
   virtual void EmitInstToFragment(const MCInst &Inst);
   virtual void EmitInstToData(const MCInst &Inst);
 
+  void fixSymbolsInTLSFixups(const MCExpr *expr);
+
   struct LocalCommon {
     MCSymbolData *SD;
     uint64_t Size;
@@ -450,6 +452,38 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) {
   SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
 }
 
+void  MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
+  switch (expr->getKind()) {
+  case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
+  case MCExpr::Constant:
+    break;
+
+  case MCExpr::Binary: {
+    const MCBinaryExpr *be = cast<MCBinaryExpr>(expr);
+    fixSymbolsInTLSFixups(be->getLHS());
+    fixSymbolsInTLSFixups(be->getRHS());
+    break;
+  }
+
+  case MCExpr::SymbolRef: {
+    const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(expr);
+    MCSymbolRefExpr::VariantKind kind = symRef.getKind();
+    if (kind != MCSymbolRefExpr::VK_TLSGD &&
+       kind != MCSymbolRefExpr::VK_TLSLD &&
+       kind != MCSymbolRefExpr::VK_TLSLDM &&
+       kind != MCSymbolRefExpr::VK_ARM_TLSGD)
+      return;
+    MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol());
+    SetType(SD, ELF::STT_TLS);
+    break;
+  }
+
+  case MCExpr::Unary:
+    fixSymbolsInTLSFixups(cast<MCUnaryExpr>(expr)->getSubExpr());
+    break;
+  }
+}
+
 void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
   MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
 
@@ -463,6 +497,9 @@ void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
   VecOS.flush();
 
+  for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
+    fixSymbolsInTLSFixups(Fixups[i].getValue());
+
   IF->getCode() = Code;
   IF->getFixups() = Fixups;
 }
@@ -476,6 +513,9 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
   getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
   VecOS.flush();
 
+  for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
+    fixSymbolsInTLSFixups(Fixups[i].getValue());
+
   // Add the fixups and data.
   for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
     Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
index 395c2703b2bde05d4487d86b8c023709cab9ea70..19e0c763e04c35a5b3ad98753e7284f43f9f050d 100644 (file)
@@ -1,15 +1,27 @@
 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump  | FileCheck %s
 
-// Test that foobar is of type STT_TLS.
+// Test that foo and foobar is of type STT_TLS.
+
+       leaq    foo@TLSGD(%rip), %rdi
 
        .section        .zed,"awT",@progbits
 foobar:
        .long   43
 
-// CHECK:      (('st_name', 0x00000001) # 'foobar'
+// CHECK:      (('st_name', 0x00000005) # 'foobar'
 // CHECK-NEXT:  ('st_bind', 0x00000000)
 // CHECK-NEXT:  ('st_type', 0x00000006)
 // CHECK-NEXT:  ('st_other', 0x00000000)
 // CHECK-NEXT:  ('st_shndx', 0x00000004)
 // CHECK-NEXT:  ('st_value', 0x00000000)
 // CHECK-NEXT:  ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+
+// CHECK:      (('st_name', 0x00000001) # 'foo'
+// CHECK-NEXT:  ('st_bind', 0x00000001)
+// CHECK-NEXT:  ('st_type', 0x00000006)
+// CHECK-NEXT:  ('st_other', 0x00000000)
+// CHECK-NEXT:  ('st_shndx', 0x00000000)
+// CHECK-NEXT:  ('st_value', 0x00000000)
+// CHECK-NEXT:  ('st_size', 0x00000000)
+// CHECK-NEXT: ),