From 848edb1bfaf51b229f80a8ccc9b66fde4874bc48 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Thu, 6 Nov 2014 22:46:24 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221491 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/ELFYAML.h | 8 +++- lib/Object/ELFYAML.cpp | 38 ++++++++++++++++++- .../yaml2obj-elf-symbol-visibility.yaml | 4 +- tools/obj2yaml/elf2yaml.cpp | 2 +- tools/yaml2obj/yaml2elf.cpp | 2 +- 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index fc8cc958165..687611ddb58 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/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 Local; @@ -174,6 +175,11 @@ struct ScalarEnumerationTraits { static void enumeration(IO &IO, ELFYAML::ELF_STV &Value); }; +template <> +struct ScalarBitSetTraits { + static void bitset(IO &IO, ELFYAML::ELF_STO &Value); +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp index 6b10724c966..55009526dac 100644 --- a/lib/Object/ELFYAML.cpp +++ b/lib/Object/ELFYAML.cpp @@ -395,6 +395,25 @@ void ScalarEnumerationTraits::enumeration( #undef ECase } +void ScalarBitSetTraits::bitset(IO &IO, + ELFYAML::ELF_STO &Value) { + const auto *Object = static_cast(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::enumeration( IO &IO, ELFYAML::ELF_REL &Value) { const auto *Object = static_cast(IO.getContext()); @@ -670,13 +689,30 @@ void MappingTraits::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::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 Keys(IO, Symbol.Other); + IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0)); + IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0)); } void MappingTraits::mapping( diff --git a/test/Object/yaml2obj-elf-symbol-visibility.yaml b/test/Object/yaml2obj-elf-symbol-visibility.yaml index 113354a05e3..6c4037c831d 100644 --- a/test/Object/yaml2obj-elf-symbol-visibility.yaml +++ b/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/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp index bff28496db1..d770ce1151e 100644 --- a/tools/obj2yaml/elf2yaml.cpp +++ b/tools/obj2yaml/elf2yaml.cpp @@ -133,7 +133,7 @@ std::error_code ELFDumper::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 NameOrErr = Obj.getSymbolName(Sym); if (std::error_code EC = NameOrErr.getError()) diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 6fbeb2117af..0b446c77c2f 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -304,7 +304,7 @@ void ELFState::addSymbols(const std::vector &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); } -- 2.34.1