summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/ELFYAML.cpp
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2015-01-25 13:29:25 +0000
committerSimon Atanasyan <simon@atanasyan.com>2015-01-25 13:29:25 +0000
commit5d19c67a68533d716fd791ea5a4cdb6b13a26ab1 (patch)
tree44a69f5e7273e2994174c1ae21f78505e8a35e7d /llvm/lib/Object/ELFYAML.cpp
parent1a603b3f13e10a378602a1ed164e59b61e2fa485 (diff)
downloadbcm5719-llvm-5d19c67a68533d716fd791ea5a4cdb6b13a26ab1.tar.gz
bcm5719-llvm-5d19c67a68533d716fd791ea5a4cdb6b13a26ab1.zip
[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 llvm-svn: 227044
Diffstat (limited to 'llvm/lib/Object/ELFYAML.cpp')
-rw-r--r--llvm/lib/Object/ELFYAML.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/llvm/lib/Object/ELFYAML.cpp b/llvm/lib/Object/ELFYAML.cpp
index 14aa8317101..f44b93718bc 100644
--- a/llvm/lib/Object/ELFYAML.cpp
+++ b/llvm/lib/Object/ELFYAML.cpp
@@ -415,6 +415,16 @@ void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
#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());
@@ -540,11 +550,48 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
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);
}
OpenPOWER on IntegriCloud