diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2015-05-07 15:40:48 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2015-05-07 15:40:48 +0000 |
commit | 04d9e653ed4f40824a222d27c815a81b47c65e81 (patch) | |
tree | 1177ae4795c6f8c8b941bd7f95b60cbf94eafc55 | |
parent | c914de277059a2962178e3bf7d5ad50ad01ba73a (diff) | |
download | bcm5719-llvm-04d9e653ed4f40824a222d27c815a81b47c65e81.tar.gz bcm5719-llvm-04d9e653ed4f40824a222d27c815a81b47c65e81.zip |
[obj2yaml/yaml2obj] Add SHT_MIPS_ABIFLAGS section support
This change adds support for the SHT_MIPS_ABIFLAGS section
reading/writing to the obj2yaml and yaml2obj tools.
llvm-svn: 236738
-rw-r--r-- | llvm/include/llvm/Object/ELFYAML.h | 59 | ||||
-rw-r--r-- | llvm/lib/Object/ELFYAML.cpp | 119 | ||||
-rw-r--r-- | llvm/test/Object/Mips/abi-flags.yaml | 63 | ||||
-rw-r--r-- | llvm/test/Object/obj2yaml.test | 7 | ||||
-rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 37 | ||||
-rw-r--r-- | llvm/tools/yaml2obj/yaml2elf.cpp | 37 |
6 files changed, 320 insertions, 2 deletions
diff --git a/llvm/include/llvm/Object/ELFYAML.h b/llvm/include/llvm/Object/ELFYAML.h index 45cbdbd2da3..b45507920a9 100644 --- a/llvm/include/llvm/Object/ELFYAML.h +++ b/llvm/include/llvm/Object/ELFYAML.h @@ -48,6 +48,13 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV) LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA) + // For now, hardcode 64 bits everywhere that 32 or 64 would be needed // since 64-bit can hold 32-bit values too. struct FileHeader { @@ -78,7 +85,7 @@ struct SectionOrType { }; struct Section { - enum class SectionKind { Group, RawContent, Relocation }; + enum class SectionKind { Group, RawContent, Relocation, MipsABIFlags }; SectionKind Kind; StringRef Name; ELF_SHT Type; @@ -122,6 +129,26 @@ struct RelocationSection : Section { return S->Kind == SectionKind::Relocation; } }; + +// Represents .MIPS.abiflags section +struct MipsABIFlags : Section { + llvm::yaml::Hex16 Version; + MIPS_ISA ISALevel; + llvm::yaml::Hex8 ISARevision; + MIPS_AFL_REG GPRSize; + MIPS_AFL_REG CPR1Size; + MIPS_AFL_REG CPR2Size; + MIPS_ABI_FP FpABI; + MIPS_AFL_EXT ISAExtension; + MIPS_AFL_ASE ASEs; + MIPS_AFL_FLAGS1 Flags1; + llvm::yaml::Hex32 Flags2; + MipsABIFlags() : Section(SectionKind::MipsABIFlags) {} + static bool classof(const Section *S) { + return S->Kind == SectionKind::MipsABIFlags; + } +}; + struct Object { FileHeader Header; std::vector<std::unique_ptr<Section>> Sections; @@ -209,6 +236,36 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> { }; template <> +struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> { + static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value); +}; + +template <> +struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> { + static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value); +}; + +template <> +struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> { + static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value); +}; + +template <> +struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> { + static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value); +}; + +template <> +struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> { + static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value); +}; + +template <> +struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> { + static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value); +}; + +template <> struct MappingTraits<ELFYAML::FileHeader> { static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); }; diff --git a/llvm/lib/Object/ELFYAML.cpp b/llvm/lib/Object/ELFYAML.cpp index d63571e6646..69a9f12e303 100644 --- a/llvm/lib/Object/ELFYAML.cpp +++ b/llvm/lib/Object/ELFYAML.cpp @@ -13,6 +13,7 @@ #include "llvm/Object/ELFYAML.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/MipsABIFlags.h" namespace llvm { @@ -461,6 +462,93 @@ void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( #undef ELF_RELOC } +void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration( + IO &IO, ELFYAML::MIPS_AFL_REG &Value) { +#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X); + ECase(REG_NONE) + ECase(REG_32) + ECase(REG_64) + ECase(REG_128) +#undef ECase +} + +void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration( + IO &IO, ELFYAML::MIPS_ABI_FP &Value) { +#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X); + ECase(FP_ANY) + ECase(FP_DOUBLE) + ECase(FP_SINGLE) + ECase(FP_SOFT) + ECase(FP_OLD_64) + ECase(FP_XX) + ECase(FP_64) + ECase(FP_64A) +#undef ECase +} + +void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration( + IO &IO, ELFYAML::MIPS_AFL_EXT &Value) { +#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X); + ECase(EXT_NONE) + ECase(EXT_XLR) + ECase(EXT_OCTEON2) + ECase(EXT_OCTEONP) + ECase(EXT_LOONGSON_3A) + ECase(EXT_OCTEON) + ECase(EXT_5900) + ECase(EXT_4650) + ECase(EXT_4010) + ECase(EXT_4100) + ECase(EXT_3900) + ECase(EXT_10000) + ECase(EXT_SB1) + ECase(EXT_4111) + ECase(EXT_4120) + ECase(EXT_5400) + ECase(EXT_5500) + ECase(EXT_LOONGSON_2E) + ECase(EXT_LOONGSON_2F) + ECase(EXT_OCTEON3) +#undef ECase +} + +void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration( + IO &IO, ELFYAML::MIPS_ISA &Value) { + IO.enumCase(Value, "MIPS1", 1); + IO.enumCase(Value, "MIPS2", 2); + IO.enumCase(Value, "MIPS3", 3); + IO.enumCase(Value, "MIPS4", 4); + IO.enumCase(Value, "MIPS5", 5); + IO.enumCase(Value, "MIPS32", 32); + IO.enumCase(Value, "MIPS64", 64); +} + +void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset( + IO &IO, ELFYAML::MIPS_AFL_ASE &Value) { +#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X); + BCase(DSP) + BCase(DSPR2) + BCase(EVA) + BCase(MCU) + BCase(MDMX) + BCase(MIPS3D) + BCase(MT) + BCase(SMARTMIPS) + BCase(VIRT) + BCase(MSA) + BCase(MIPS16) + BCase(MICROMIPS) + BCase(XPA) +#undef BCase +} + +void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset( + IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) { +#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X); + BCase(ODDSPREG) +#undef BCase +} + void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO, ELFYAML::FileHeader &FileHdr) { IO.mapRequired("Class", FileHdr.Class); @@ -536,6 +624,26 @@ void MappingTraits<ELFYAML::SectionOrType>::mapping( IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType); } +static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Version", Section.Version, Hex16(0)); + IO.mapRequired("ISA", Section.ISALevel); + IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0)); + IO.mapOptional("ISAExtension", Section.ISAExtension, + ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE)); + IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0)); + IO.mapOptional("FpABI", Section.FpABI, + ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY)); + IO.mapOptional("GPRSize", Section.GPRSize, + ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE)); + IO.mapOptional("CPR1Size", Section.CPR1Size, + ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE)); + IO.mapOptional("CPR2Size", Section.CPR2Size, + ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE)); + IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0)); + IO.mapOptional("Flags2", Section.Flags2, Hex32(0)); +} + void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping( IO &IO, std::unique_ptr<ELFYAML::Section> &Section) { ELFYAML::ELF_SHT sectionType; @@ -556,6 +664,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping( Section.reset(new ELFYAML::Group()); groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get())); break; + case ELF::SHT_MIPS_ABIFLAGS: + if (!IO.outputting()) + Section.reset(new ELFYAML::MipsABIFlags()); + sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get())); + break; default: if (!IO.outputting()) Section.reset(new ELFYAML::RawContentSection()); @@ -625,5 +738,11 @@ void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) { IO.setContext(nullptr); } +LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1) + } // end namespace yaml } // end namespace llvm diff --git a/llvm/test/Object/Mips/abi-flags.yaml b/llvm/test/Object/Mips/abi-flags.yaml new file mode 100644 index 00000000000..8a11fc4124c --- /dev/null +++ b/llvm/test/Object/Mips/abi-flags.yaml @@ -0,0 +1,63 @@ +# RUN: yaml2obj -format=elf %s > %t +# RUN: llvm-readobj -mips-abi-flags %t | FileCheck -check-prefix=OBJ %s +# RUN: obj2yaml %t | FileCheck -check-prefix=YAML %s + +# OBJ: MIPS ABI Flags { +# OBJ-NEXT: Version: 0 +# OBJ-NEXT: ISA: MIPS64r5 +# OBJ-NEXT: ISA Extension: Cavium Networks Octeon3 (0x13) +# OBJ-NEXT: ASEs [ (0x103) +# OBJ-NEXT: DSP (0x1) +# OBJ-NEXT: DSPR2 (0x2) +# OBJ-NEXT: VZ (0x100) +# OBJ-NEXT: ] +# OBJ-NEXT: FP ABI: Hard float (double precision) (0x1) +# OBJ-NEXT: GPR size: 64 +# OBJ-NEXT: CPR1 size: 64 +# OBJ-NEXT: CPR2 size: 0 +# OBJ-NEXT: Flags 1 [ (0x1) +# OBJ-NEXT: ODDSPREG (0x1) +# OBJ-NEXT: ] +# OBJ-NEXT: Flags 2: 0x0 +# OBJ-NEXT: } + +# YAML: Sections: +# YAML-NEXT: - Name: .MIPS.abiflags +# YAML-NEXT: Type: SHT_MIPS_ABIFLAGS +# YAML-NEXT: AddressAlign: 0x0000000000000008 +# YAML-NEXT: ISA: MIPS64 +# YAML-NEXT: ISARevision: 0x05 +# YAML-NEXT: ISAExtension: EXT_OCTEON3 +# YAML-NEXT: ASEs: [ DSP, DSPR2, VIRT ] +# YAML-NEXT: FpABI: FP_DOUBLE +# YAML-NEXT: GPRSize: REG_64 +# YAML-NEXT: CPR1Size: REG_64 +# YAML-NEXT: Flags1: [ ODDSPREG ] + +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2MSB + Type: ET_REL + Machine: EM_MIPS + +Sections: +- Name: .MIPS.abiflags + Type: SHT_MIPS_ABIFLAGS + AddressAlign: 8 + Version: 0 + ISA: MIPS64 + ISARevision: 5 + ISAExtension: EXT_OCTEON3 + ASEs: [ DSP, DSPR2, VIRT ] + FpABI: FP_DOUBLE + GPRSize: REG_64 + CPR1Size: REG_64 + CPR2Size: REG_NONE + Flags1: [ ODDSPREG ] + Flags2: 0x0 + +Symbols: + Local: + - Name: .MIPS.abiflags + Type: STT_SECTION + Section: .MIPS.abiflags diff --git a/llvm/test/Object/obj2yaml.test b/llvm/test/Object/obj2yaml.test index e654dcdccf5..2a3f7c841dd 100644 --- a/llvm/test/Object/obj2yaml.test +++ b/llvm/test/Object/obj2yaml.test @@ -253,7 +253,12 @@ ELF-MIPSEL-NEXT: - Name: .MIPS.abiflags ELF-MIPSEL-NEXT: Type: SHT_MIPS_ABIFLAGS ELF-MIPSEL-NEXT: Flags: [ SHF_ALLOC ] ELF-MIPSEL-NEXT: AddressAlign: 0x0000000000000008 -ELF-MIPSEL-NEXT: Content: '000020010101000100000000000000000100000000000000' +ELF-MIPSEL-NEXT: ISA: MIPS32 +ELF-MIPSEL-NEXT: ISARevision: 0x01 +ELF-MIPSEL-NEXT: FpABI: FP_DOUBLE +ELF-MIPSEL-NEXT: GPRSize: REG_32 +ELF-MIPSEL-NEXT: CPR1Size: REG_32 +ELF-MIPSEL-NEXT: Flags1: [ ODDSPREG ] ELF-MIPSEL-NEXT: Symbols: ELF-MIPSEL-NEXT: Local: ELF-MIPSEL-NEXT: - Name: trivial.ll diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index e606df2a084..8ce70bc3652 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -41,6 +41,7 @@ class ELFDumper { ErrorOr<ELFYAML::RawContentSection *> dumpContentSection(const Elf_Shdr *Shdr); ErrorOr<ELFYAML::Group *> dumpGroup(const Elf_Shdr *Shdr); + ErrorOr<ELFYAML::MipsABIFlags *> dumpMipsABIFlags(const Elf_Shdr *Shdr); public: ELFDumper(const object::ELFFile<ELFT> &O); @@ -96,6 +97,13 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() { Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); break; } + case ELF::SHT_MIPS_ABIFLAGS: { + ErrorOr<ELFYAML::MipsABIFlags *> G = dumpMipsABIFlags(&Sec); + if (std::error_code EC = G.getError()) + return EC; + Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(G.get())); + break; + } default: { ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec); if (std::error_code EC = S.getError()) @@ -319,6 +327,35 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) { } template <class ELFT> +ErrorOr<ELFYAML::MipsABIFlags *> +ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) { + assert(Shdr->sh_type == ELF::SHT_MIPS_ABIFLAGS && + "Section type is not SHT_MIPS_ABIFLAGS"); + auto S = make_unique<ELFYAML::MipsABIFlags>(); + if (std::error_code EC = dumpCommonSection(Shdr, *S)) + return EC; + + ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); + if (std::error_code EC = ContentOrErr.getError()) + return EC; + + auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>( + ContentOrErr.get().data()); + S->Version = Flags->version; + S->ISALevel = Flags->isa_level; + S->ISARevision = Flags->isa_rev; + S->GPRSize = Flags->gpr_size; + S->CPR1Size = Flags->cpr1_size; + S->CPR2Size = Flags->cpr2_size; + S->FpABI = Flags->fp_abi; + S->ISAExtension = Flags->isa_ext; + S->ASEs = Flags->ases; + S->Flags1 = Flags->flags1; + S->Flags2 = Flags->flags2; + return S.release(); +} + +template <class ELFT> static std::error_code elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) { ELFDumper<ELFT> Dumper(Obj); diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp index 17dbe8b03da..1226506f624 100644 --- a/llvm/tools/yaml2obj/yaml2elf.cpp +++ b/llvm/tools/yaml2obj/yaml2elf.cpp @@ -133,6 +133,9 @@ class ELFState { ContiguousBlobAccumulator &CBA); bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group, ContiguousBlobAccumulator &CBA); + bool writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::MipsABIFlags &Section, + ContiguousBlobAccumulator &CBA); // - SHT_NULL entry (placed first, i.e. 0'th entry) // - symbol table (.symtab) (placed third to last) @@ -235,6 +238,9 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders, SHeader.sh_info = SymIdx; if (!writeSectionContent(SHeader, *S, CBA)) return false; + } else if (auto S = dyn_cast<ELFYAML::MipsABIFlags>(Sec.get())) { + if (!writeSectionContent(SHeader, *S, CBA)) + return false; } else llvm_unreachable("Unknown section type"); @@ -413,6 +419,37 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, return true; } +template <class ELFT> +bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::MipsABIFlags &Section, + ContiguousBlobAccumulator &CBA) { + if (Section.Type != llvm::ELF::SHT_MIPS_ABIFLAGS) { + errs() << "error: Invalid section type.\n"; + return false; + } + + object::Elf_Mips_ABIFlags<ELFT> Flags; + zero(Flags); + SHeader.sh_entsize = sizeof(Flags); + SHeader.sh_size = SHeader.sh_entsize; + + auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset); + Flags.version = Section.Version; + Flags.isa_level = Section.ISALevel; + Flags.isa_rev = Section.ISARevision; + Flags.gpr_size = Section.GPRSize; + Flags.cpr1_size = Section.CPR1Size; + Flags.cpr2_size = Section.CPR2Size; + Flags.fp_abi = Section.FpABI; + Flags.isa_ext = Section.ISAExtension; + Flags.ases = Section.ASEs; + Flags.flags1 = Section.Flags1; + Flags.flags2 = Section.Flags2; + OS.write((const char *)&Flags, sizeof(Flags)); + + return true; +} + template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() { SN2I.addName(".symtab", getDotSymTabSecNo()); SN2I.addName(".strtab", getDotStrTabSecNo()); |