From e1a2587ee273943390608df096378116ce52ffba Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Nov 2010 19:04:55 +0000 Subject: [PATCH] Mark labels declared in tls sections as STT_TLS. This matches the behavior of gas. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118818 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCELFStreamer.cpp | 69 +++++++++++++++++++---------------- lib/MC/MCParser/AsmParser.cpp | 1 - test/MC/ELF/tls.s | 15 ++++++++ 3 files changed, 52 insertions(+), 33 deletions(-) create mode 100644 test/MC/ELF/tls.s diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 414fe3e2e6c..4acf45cb68f 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -35,6 +35,38 @@ using namespace llvm; namespace { +static void SetBinding(MCSymbolData &SD, unsigned Binding) { + assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || + Binding == ELF::STB_WEAK); + uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); + SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); +} + +static unsigned 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); + return Binding; +} + +static void SetType(MCSymbolData &SD, unsigned Type) { + assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || + Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || + Type == ELF::STT_FILE || Type == ELF::STT_COMMON || + Type == ELF::STT_TLS); + + uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift); + SD.setFlags(OtherFlags | (Type << ELF_STT_Shift)); +} + +static void SetVisibility(MCSymbolData &SD, unsigned Visibility) { + assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || + Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); + + uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift); + SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift)); +} + class MCELFStreamer : public MCObjectStreamer { public: MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB, @@ -166,6 +198,11 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); + const MCSectionELF &Section = + static_cast(Symbol->getSection()); + if (Section.getFlags() & MCSectionELF::SHF_TLS) + SetType(SD, ELF::STT_TLS); + // FIXME: This is wasteful, we don't necessarily need to create a data // fragment. Instead, we should mark the symbol as pointing into the data // fragment if it exists, otherwise we should just queue the label and set its @@ -262,38 +299,6 @@ void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { Alias->setVariableValue(Value); } -static void SetBinding(MCSymbolData &SD, unsigned Binding) { - assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK); - uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); - SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); -} - -static unsigned 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); - return Binding; -} - -static void SetType(MCSymbolData &SD, unsigned Type) { - assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || - Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || - Type == ELF::STT_FILE || Type == ELF::STT_COMMON || - Type == ELF::STT_TLS); - - uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift); - SD.setFlags(OtherFlags | (Type << ELF_STT_Shift)); -} - -static void SetVisibility(MCSymbolData &SD, unsigned Visibility) { - assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || - Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); - - uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift); - SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift)); -} - void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { // Indirect symbols are handled differently, to match how 'as' handles diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index d0d073a7083..489d451f7fb 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -193,7 +193,6 @@ private: /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which /// accepts a single symbol (which should be a label or an external). bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr); - bool ParseDirectiveELFType(); // ELF specific ".type" bool ParseDirectiveComm(bool IsLocal); // ".comm" and ".lcomm" diff --git a/test/MC/ELF/tls.s b/test/MC/ELF/tls.s new file mode 100644 index 00000000000..395c2703b2b --- /dev/null +++ b/test/MC/ELF/tls.s @@ -0,0 +1,15 @@ +// 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. + + .section .zed,"awT",@progbits +foobar: + .long 43 + +// CHECK: (('st_name', 0x00000001) # '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)