summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2014-11-06 22:46:24 +0000
committerSimon Atanasyan <simon@atanasyan.com>2014-11-06 22:46:24 +0000
commit60e1a7924210894107e1f16f7b861543ccfbfbb9 (patch)
treee25312c9d771107a4b69102f7d283dfe0ea188a7
parente2541bd60ea3a7518778ed388771e61da6d556a2 (diff)
downloadbcm5719-llvm-60e1a7924210894107e1f16f7b861543ccfbfbb9.tar.gz
bcm5719-llvm-60e1a7924210894107e1f16f7b861543ccfbfbb9.zip
[ELF][yaml2obj] Handle additional MIPS specific st_other field flags
The ELF symbol `st_other` field might contain additional flags besides visibility ones. This patch implements support for some MIPS specific flags. llvm-svn: 221491
-rw-r--r--llvm/include/llvm/Object/ELFYAML.h8
-rw-r--r--llvm/lib/Object/ELFYAML.cpp38
-rw-r--r--llvm/test/Object/yaml2obj-elf-symbol-visibility.yaml4
-rw-r--r--llvm/tools/obj2yaml/elf2yaml.cpp2
-rw-r--r--llvm/tools/yaml2obj/yaml2elf.cpp2
5 files changed, 49 insertions, 5 deletions
diff --git a/llvm/include/llvm/Object/ELFYAML.h b/llvm/include/llvm/Object/ELFYAML.h
index fc8cc958165..687611ddb58 100644
--- a/llvm/include/llvm/Object/ELFYAML.h
+++ b/llvm/include/llvm/Object/ELFYAML.h
@@ -45,6 +45,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_REL)
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
+LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
// since 64-bit can hold 32-bit values too.
@@ -63,7 +64,7 @@ struct Symbol {
StringRef Section;
llvm::yaml::Hex64 Value;
llvm::yaml::Hex64 Size;
- ELF_STV Visibility;
+ uint8_t Other;
};
struct LocalGlobalWeakSymbols {
std::vector<Symbol> Local;
@@ -175,6 +176,11 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_STV> {
};
template <>
+struct ScalarBitSetTraits<ELFYAML::ELF_STO> {
+ static void bitset(IO &IO, ELFYAML::ELF_STO &Value);
+};
+
+template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
};
diff --git a/llvm/lib/Object/ELFYAML.cpp b/llvm/lib/Object/ELFYAML.cpp
index 6b10724c966..55009526dac 100644
--- a/llvm/lib/Object/ELFYAML.cpp
+++ b/llvm/lib/Object/ELFYAML.cpp
@@ -395,6 +395,25 @@ void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration(
#undef ECase
}
+void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
+ ELFYAML::ELF_STO &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_MIPS:
+ BCase(STO_MIPS_OPTIONAL)
+ BCase(STO_MIPS_PLT)
+ BCase(STO_MIPS_PIC)
+ BCase(STO_MIPS_MICROMIPS)
+ break;
+ default:
+ break; // Nothing to do
+ }
+#undef BCase
+#undef BCaseMask
+}
+
void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
IO &IO, ELFYAML::ELF_REL &Value) {
const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
@@ -670,13 +689,30 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
}
+namespace {
+struct NormalizedOther {
+ NormalizedOther(IO &)
+ : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {}
+ NormalizedOther(IO &, uint8_t Original)
+ : Visibility(Original & 0x3), Other(Original & ~0x3) {}
+
+ uint8_t denormalize(IO &) { return Visibility | Other; }
+
+ ELFYAML::ELF_STV Visibility;
+ ELFYAML::ELF_STO Other;
+};
+}
+
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Name", Symbol.Name, StringRef());
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Value", Symbol.Value, Hex64(0));
IO.mapOptional("Size", Symbol.Size, Hex64(0));
- IO.mapOptional("Visibility", Symbol.Visibility, ELFYAML::ELF_STV(0));
+
+ MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
+ IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
+ IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
}
void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
diff --git a/llvm/test/Object/yaml2obj-elf-symbol-visibility.yaml b/llvm/test/Object/yaml2obj-elf-symbol-visibility.yaml
index 113354a05e3..6c4037c831d 100644
--- a/llvm/test/Object/yaml2obj-elf-symbol-visibility.yaml
+++ b/llvm/test/Object/yaml2obj-elf-symbol-visibility.yaml
@@ -44,7 +44,7 @@
# OBJ-NEXT: Size: 4
# OBJ-NEXT: Binding: Global (0x1)
# OBJ-NEXT: Type: Object (0x1)
-# OBJ-NEXT: Other: 3
+# OBJ-NEXT: Other: 163
# OBJ-NEXT: Section: .data (0x1)
# OBJ-NEXT: }
@@ -77,6 +77,7 @@
# YAML-NEXT: Value: 0x0000000000000010
# YAML-NEXT: Size: 0x0000000000000004
# YAML-NEXT: Visibility: STV_PROTECTED
+# YAML-NEXT: Other: [ STO_MIPS_PIC, STO_MIPS_MICROMIPS ]
---
FileHeader:
@@ -121,6 +122,7 @@ Symbols:
- Name: protected
Type: STT_OBJECT
Visibility: STV_PROTECTED
+ Other: [ STO_MIPS_MICROMIPS, STO_MIPS_PIC ]
Section: .data
Value: 0x10
Size: 0x04
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index bff28496db1..d770ce1151e 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -133,7 +133,7 @@ std::error_code ELFDumper<ELFT>::dumpSymbol(Elf_Sym_Iter Sym,
S.Type = Sym->getType();
S.Value = Sym->st_value;
S.Size = Sym->st_size;
- S.Visibility = Sym->getVisibility();
+ S.Other = Sym->st_other;
ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(Sym);
if (std::error_code EC = NameOrErr.getError())
diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp
index 6fbeb2117af..0b446c77c2f 100644
--- a/llvm/tools/yaml2obj/yaml2elf.cpp
+++ b/llvm/tools/yaml2obj/yaml2elf.cpp
@@ -304,7 +304,7 @@ void ELFState<ELFT>::addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
Symbol.st_shndx = Index;
} // else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
Symbol.st_value = Sym.Value;
- Symbol.st_other = Sym.Visibility;
+ Symbol.st_other = Sym.Other;
Symbol.st_size = Sym.Size;
Syms.push_back(Symbol);
}
OpenPOWER on IntegriCloud