diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2014-11-06 22:46:24 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2014-11-06 22:46:24 +0000 |
| commit | 60e1a7924210894107e1f16f7b861543ccfbfbb9 (patch) | |
| tree | e25312c9d771107a4b69102f7d283dfe0ea188a7 | |
| parent | e2541bd60ea3a7518778ed388771e61da6d556a2 (diff) | |
| download | bcm5719-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.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Object/ELFYAML.cpp | 38 | ||||
| -rw-r--r-- | llvm/test/Object/yaml2obj-elf-symbol-visibility.yaml | 4 | ||||
| -rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 2 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2elf.cpp | 2 |
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); } |

