summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@freebsd.org>2011-12-12 17:34:04 +0000
committerRoman Divacky <rdivacky@freebsd.org>2011-12-12 17:34:04 +0000
commita0c17a495b12debcb7f206993bbc6020e2e6e8df (patch)
treede8c97fac0dbb38a0e2480ea66776796b61943e7
parentb813f924a749396ffb4a4bd087ee1dbb678551f3 (diff)
downloadllvm-a0c17a495b12debcb7f206993bbc6020e2e6e8df.tar.gz
llvm-a0c17a495b12debcb7f206993bbc6020e2e6e8df.tar.bz2
llvm-a0c17a495b12debcb7f206993bbc6020e2e6e8df.tar.xz
Add support for gnu_indirect_function.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146377 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/ELF.h1
-rw-r--r--lib/MC/MCELF.cpp4
-rw-r--r--lib/MC/MCELFStreamer.cpp5
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp1
-rw-r--r--test/MC/ELF/type.s14
5 files changed, 22 insertions, 3 deletions
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index a81be55258..6dd76ea170 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -888,6 +888,7 @@ enum {
STT_TLS = 6, // Thread local data object
STT_LOOS = 7, // Lowest operating system-specific symbol type
STT_HIOS = 8, // Highest operating system-specific symbol type
+ STT_GNU_IFUNC = 10, // GNU indirect function
STT_LOPROC = 13, // Lowest processor-specific symbol type
STT_HIPROC = 15 // Highest processor-specific symbol type
};
diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp
index dad2e7ba98..f9f98e0f73 100644
--- a/lib/MC/MCELF.cpp
+++ b/lib/MC/MCELF.cpp
@@ -37,7 +37,7 @@ void MCELF::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);
+ Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC);
uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STT_Shift);
SD.setFlags(OtherFlags | (Type << ELF_STT_Shift));
@@ -48,7 +48,7 @@ unsigned MCELF::GetType(const MCSymbolData &SD) {
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);
+ Type == ELF::STT_TLS || Type == ELF::STT_GNU_IFUNC);
return Type;
}
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 0ea3c64a28..dcc4666a26 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -130,7 +130,6 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
case MCSA_WeakDefinition:
case MCSA_WeakDefAutoPrivate:
case MCSA_Invalid:
- case MCSA_ELF_TypeIndFunction:
case MCSA_IndirectSymbol:
assert(0 && "Invalid symbol attribute for ELF!");
break;
@@ -162,6 +161,10 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCELF::SetType(SD, ELF::STT_FUNC);
break;
+ case MCSA_ELF_TypeIndFunction:
+ MCELF::SetType(SD, ELF::STT_GNU_IFUNC);
+ break;
+
case MCSA_ELF_TypeObject:
MCELF::SetType(SD, ELF::STT_OBJECT);
break;
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index d89112645c..ffc400b203 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -476,6 +476,7 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
.Case("common", MCSA_ELF_TypeCommon)
.Case("notype", MCSA_ELF_TypeNoType)
.Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
+ .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
.Default(MCSA_Invalid);
if (Attr == MCSA_Invalid)
diff --git a/test/MC/ELF/type.s b/test/MC/ELF/type.s
index 2b25a6b69f..ec53e4ffa5 100644
--- a/test/MC/ELF/type.s
+++ b/test/MC/ELF/type.s
@@ -12,6 +12,10 @@ bar:
// Test that gnu_unique_object is accepted.
.type zed,@gnu_unique_object
+ifunc:
+ .global ifunc
+ .type ifunc,@gnu_indirect_function
+
// CHECK: # Symbol 4
// CHECK-NEXT: (('st_name', 0x00000005) # 'bar'
// CHECK-NEXT: ('st_bind', 0x1)
@@ -30,3 +34,13 @@ bar:
// CHECK-NEXT: ('st_value', 0x0000000000000000)
// CHECK-NEXT: ('st_size', 0x0000000000000000)
// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 6
+// CHECK-NEXT: (('st_name', 0x00000009) # 'ifunc'
+// CHECK-NEXT: ('st_bind', 0x1)
+// CHECK-NEXT: ('st_type', 0xa)
+// CHECK-NEXT: ('st_other', 0x00)
+// CHECK-NEXT: ('st_shndx', 0x0001)
+// CHECK-NEXT: ('st_value', 0x0000000000000000)
+// CHECK-NEXT: ('st_size', 0x0000000000000000)
+// CHECK-NEXT: ),
+