Date: Tue, 24 Mar 2015 22:06:37 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r280471 - in projects/lld-import/contrib/llvm: include/llvm/Object include/llvm/Support lib/Object Message-ID: <201503242206.t2OM6bnw030197@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Tue Mar 24 22:06:36 2015 New Revision: 280471 URL: https://svnweb.freebsd.org/changeset/base/280471 Log: Pull in r227044 from upstream llvm trunk (by Simon Atanasyan): [ELFYAML] Support mips64 relocation record format in yaml2obj/obj2yaml MIPS64 ELF file has a very specific relocation record format. Each record might specify up to three relocation operations. So the `r_info` field in fact consists of three relocation type sub-fields and optional code of "special" symbols. http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf page 40 The patch implements support of the MIPS64 relocation record format in yaml2obj/obj2yaml tools by introducing new optional Relocation fields: Type2, Type3, and SpecSym. These fields are recognized only if the object/YAML file relates to the MIPS64 target. Differential Revision: http://reviews.llvm.org/D7136 This is a prerequisite for building lld trunk. Modified: projects/lld-import/contrib/llvm/include/llvm/Object/ELFTypes.h projects/lld-import/contrib/llvm/include/llvm/Object/ELFYAML.h projects/lld-import/contrib/llvm/include/llvm/Support/ELF.h projects/lld-import/contrib/llvm/lib/Object/ELFYAML.cpp Modified: projects/lld-import/contrib/llvm/include/llvm/Object/ELFTypes.h ============================================================================== --- projects/lld-import/contrib/llvm/include/llvm/Object/ELFTypes.h Tue Mar 24 21:59:12 2015 (r280470) +++ projects/lld-import/contrib/llvm/include/llvm/Object/ELFTypes.h Tue Mar 24 22:06:36 2015 (r280471) @@ -302,7 +302,10 @@ struct Elf_Rel_Base<ELFType<TargetEndian assert(!isMips64EL); return r_info; } - void setRInfo(uint32_t R) { r_info = R; } + void setRInfo(uint32_t R, bool IsMips64EL) { + assert(!IsMips64EL); + r_info = R; + } }; template <endianness TargetEndianness, std::size_t MaxAlign> @@ -321,9 +324,12 @@ struct Elf_Rel_Base<ELFType<TargetEndian return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); } - void setRInfo(uint64_t R) { - // FIXME: Add mips64el support. - r_info = R; + void setRInfo(uint64_t R, bool IsMips64EL) { + if (IsMips64EL) + r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) | + ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56); + else + r_info = R; } }; @@ -338,7 +344,10 @@ struct Elf_Rel_Base<ELFType<TargetEndian assert(!isMips64EL); return r_info; } - void setRInfo(uint32_t R) { r_info = R; } + void setRInfo(uint32_t R, bool IsMips64EL) { + assert(!IsMips64EL); + r_info = R; + } }; template <endianness TargetEndianness, std::size_t MaxAlign> @@ -358,9 +367,12 @@ struct Elf_Rel_Base<ELFType<TargetEndian return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) | ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff); } - void setRInfo(uint64_t R) { - // FIXME: Add mips64el support. - r_info = R; + void setRInfo(uint64_t R, bool IsMips64EL) { + if (IsMips64EL) + r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) | + ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56); + else + r_info = R; } }; @@ -380,10 +392,14 @@ struct Elf_Rel_Impl<ELFType<TargetEndian uint32_t getType(bool isMips64EL) const { return (uint32_t)(this->getRInfo(isMips64EL) & 0xffffffffL); } - void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } - void setType(uint32_t t) { setSymbolAndType(getSymbol(), t); } - void setSymbolAndType(uint32_t s, uint32_t t) { - this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL)); + void setSymbol(uint32_t s, bool IsMips64EL) { + setSymbolAndType(s, getType(), IsMips64EL); + } + void setType(uint32_t t, bool IsMips64EL) { + setSymbolAndType(getSymbol(), t, IsMips64EL); + } + void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL) { + this->setRInfo(((uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL); } }; @@ -401,10 +417,14 @@ struct Elf_Rel_Impl<ELFType<TargetEndian unsigned char getType(bool isMips64EL) const { return (unsigned char)(this->getRInfo(isMips64EL) & 0x0ff); } - void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } - void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } - void setSymbolAndType(uint32_t s, unsigned char t) { - this->setRInfo((s << 8) + t); + void setSymbol(uint32_t s, bool IsMips64EL) { + setSymbolAndType(s, getType(), IsMips64EL); + } + void setType(unsigned char t, bool IsMips64EL) { + setSymbolAndType(getSymbol(), t, IsMips64EL); + } + void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL) { + this->setRInfo((s << 8) + t, IsMips64EL); } }; Modified: projects/lld-import/contrib/llvm/include/llvm/Object/ELFYAML.h ============================================================================== --- projects/lld-import/contrib/llvm/include/llvm/Object/ELFYAML.h Tue Mar 24 21:59:12 2015 (r280470) +++ projects/lld-import/contrib/llvm/include/llvm/Object/ELFYAML.h Tue Mar 24 22:06:36 2015 (r280471) @@ -41,6 +41,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_EL LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF) LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS) // Just use 64, since it can hold 32-bit values too. LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF) LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) @@ -186,6 +187,11 @@ struct ScalarEnumerationTraits<ELFYAML:: }; template <> +struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> { + static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value); +}; + +template <> struct MappingTraits<ELFYAML::FileHeader> { static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); }; Modified: projects/lld-import/contrib/llvm/include/llvm/Support/ELF.h ============================================================================== --- projects/lld-import/contrib/llvm/include/llvm/Support/ELF.h Tue Mar 24 21:59:12 2015 (r280470) +++ projects/lld-import/contrib/llvm/include/llvm/Support/ELF.h Tue Mar 24 22:06:36 2015 (r280471) @@ -795,6 +795,14 @@ enum { STN_UNDEF = 0 }; +// Special relocation symbols used in the MIPS64 ELF relocation entries +enum { + RSS_UNDEF = 0, // None + RSS_GP = 1, // Value of gp + RSS_GP0 = 2, // Value of gp used to create object being relocated + RSS_LOC = 3 // Address of location being relocated +}; + // Relocation entry, without explicit addend. struct Elf32_Rel { Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr) Modified: projects/lld-import/contrib/llvm/lib/Object/ELFYAML.cpp ============================================================================== --- projects/lld-import/contrib/llvm/lib/Object/ELFYAML.cpp Tue Mar 24 21:59:12 2015 (r280470) +++ projects/lld-import/contrib/llvm/lib/Object/ELFYAML.cpp Tue Mar 24 22:06:36 2015 (r280471) @@ -414,6 +414,16 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO #undef BCaseMask } +void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration( + IO &IO, ELFYAML::ELF_RSS &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X); + ECase(RSS_UNDEF) + ECase(RSS_GP) + ECase(RSS_GP0) + ECase(RSS_LOC) +#undef ECase +} + void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration( IO &IO, ELFYAML::ELF_REL &Value) { const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); @@ -539,11 +549,48 @@ StringRef MappingTraits<std::unique_ptr< return "Section size must be greater or equal to the content size"; } +namespace { +struct NormalizedMips64RelType { + NormalizedMips64RelType(IO &) + : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), + Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), + Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)), + SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {} + NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original) + : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF), + Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {} + + ELFYAML::ELF_REL denormalize(IO &) { + ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24; + return Res; + } + + ELFYAML::ELF_REL Type; + ELFYAML::ELF_REL Type2; + ELFYAML::ELF_REL Type3; + ELFYAML::ELF_RSS SpecSym; +}; +} + void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO, ELFYAML::Relocation &Rel) { + const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext()); + assert(Object && "The IO context is not initialized"); + IO.mapRequired("Offset", Rel.Offset); IO.mapRequired("Symbol", Rel.Symbol); - IO.mapRequired("Type", Rel.Type); + + if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) && + Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) { + MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key( + IO, Rel.Type); + IO.mapRequired("Type", Key->Type); + IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE)); + IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE)); + IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF)); + } else + IO.mapRequired("Type", Rel.Type); + IO.mapOptional("Addend", Rel.Addend); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503242206.t2OM6bnw030197>