[llvm] r227044 - [ELFYAML] Support mips64 relocation record format in yaml2obj/obj2yaml

Kuperstein, Michael M michael.m.kuperstein at intel.com
Wed Jan 28 05:12:54 PST 2015


Hi Simon,

This fails on MSVC Debug builds. 
The problem seems to be that the Addend field is uninitialized when it's supposed to be 0, and the result I get is:

Relocations [
  Section (2) .rela.text {
    0x14 R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 main 0x4
    0x1C R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 main 0x8
    0x20 R_MIPS_GOT_PAGE/R_MIPS_NONE/R_MIPS_NONE .rodata 0xCDCDCDCDCDCDCDCD
    0x24 R_MIPS_GOT_OFST/R_MIPS_NONE/R_MIPS_NONE .rodata 0xCDCDCDCDCDCDCDCD
    0x28 R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE printf 0xCDCDCDCDCDCDCDCD
    0x30 R_MIPS_GPREL16/R_MIPS_LO16/R_MIPS_NONE printf 0xCDCDCDCDCDCDCDCD
  }
]

Don't know enough about how yaml2obj works to fix it. 
Can you fix or revert?

Thanks,
   Michael

-----Original Message-----
From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Simon Atanasyan
Sent: Sunday, January 25, 2015 15:29
To: llvm-commits at cs.uiuc.edu
Subject: [llvm] r227044 - [ELFYAML] Support mips64 relocation record format in yaml2obj/obj2yaml

Author: atanasyan
Date: Sun Jan 25 07:29:25 2015
New Revision: 227044

URL: http://llvm.org/viewvc/llvm-project?rev=227044&view=rev
Log:
[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

Added:
    llvm/trunk/test/Object/Mips/elf-mips64-rel.yaml
Modified:
    llvm/trunk/include/llvm/Object/ELFTypes.h
    llvm/trunk/include/llvm/Object/ELFYAML.h
    llvm/trunk/include/llvm/Support/ELF.h
    llvm/trunk/lib/Object/ELFYAML.cpp
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/include/llvm/Object/ELFTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFTypes.h?rev=227044&r1=227043&r2=227044&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFTypes.h (original)
+++ llvm/trunk/include/llvm/Object/ELFTypes.h Sun Jan 25 07:29:25 2015
@@ -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: llvm/trunk/include/llvm/Object/ELFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFYAML.h?rev=227044&r1=227043&r2=227044&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/Object/ELFYAML.h Sun Jan 25 07:29:25 2015
@@ -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: llvm/trunk/include/llvm/Support/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ELF.h?rev=227044&r1=227043&r2=227044&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ELF.h (original)
+++ llvm/trunk/include/llvm/Support/ELF.h Sun Jan 25 07:29:25 2015
@@ -796,6 +796,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: llvm/trunk/lib/Object/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELFYAML.cpp?rev=227044&r1=227043&r2=227044&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELFYAML.cpp (original)
+++ llvm/trunk/lib/Object/ELFYAML.cpp Sun Jan 25 07:29:25 2015
@@ -415,6 +415,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()); @@ -540,11 +550,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);  }
 

Added: llvm/trunk/test/Object/Mips/elf-mips64-rel.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Mips/elf-mips64-rel.yaml?rev=227044&view=auto
==============================================================================
--- llvm/trunk/test/Object/Mips/elf-mips64-rel.yaml (added)
+++ llvm/trunk/test/Object/Mips/elf-mips64-rel.yaml Sun Jan 25 07:29:25 
+++ 2015
@@ -0,0 +1,113 @@
+# RUN: yaml2obj -format=elf %s > %t
+# RUN: llvm-readobj -r %t | FileCheck -check-prefix=OBJ %s # RUN: 
+obj2yaml %t | FileCheck -check-prefix=YAML %s
+
+# OBJ:      Relocations [
+# OBJ-NEXT:   Section (2) .rela.text {
+# OBJ-NEXT:     0x14 R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 main 0x4
+# OBJ-NEXT:     0x1C R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 main 0x8
+# OBJ-NEXT:     0x20 R_MIPS_GOT_PAGE/R_MIPS_NONE/R_MIPS_NONE .rodata 0x0
+# OBJ-NEXT:     0x24 R_MIPS_GOT_OFST/R_MIPS_NONE/R_MIPS_NONE .rodata 0x0
+# OBJ-NEXT:     0x28 R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE printf 0x0
+# OBJ-NEXT:     0x30 R_MIPS_GPREL16/R_MIPS_LO16/R_MIPS_NONE printf 0x0
+# OBJ-NEXT:   }
+# OBJ-NEXT: ]
+
+# YAML:      Relocations:
+# YAML-NEXT:   - Offset:      0x0000000000000014
+# YAML-NEXT:     Symbol:      main
+# YAML-NEXT:     Type:        R_MIPS_GPREL16
+# YAML-NEXT:     Type2:       R_MIPS_SUB
+# YAML-NEXT:     Type3:       R_MIPS_HI16
+# YAML-NEXT:     Addend:      4
+# YAML-NEXT:   - Offset:      0x000000000000001C
+# YAML-NEXT:     Symbol:      main
+# YAML-NEXT:     Type:        R_MIPS_GPREL16
+# YAML-NEXT:     Type2:       R_MIPS_SUB
+# YAML-NEXT:     Type3:       R_MIPS_LO16
+# YAML-NEXT:     Addend:      8
+# YAML-NEXT:   - Offset:      0x0000000000000020
+# YAML-NEXT:     Symbol:      .rodata
+# YAML-NEXT:     Type:        R_MIPS_GOT_PAGE
+# YAML-NEXT:     Addend:      0
+# YAML-NEXT:   - Offset:      0x0000000000000024
+# YAML-NEXT:     Symbol:      .rodata
+# YAML-NEXT:     Type:        R_MIPS_GOT_OFST
+# YAML-NEXT:     Addend:      0
+# YAML-NEXT:   - Offset:      0x0000000000000028
+# YAML-NEXT:     Symbol:      printf
+# YAML-NEXT:     Type:        R_MIPS_CALL16
+# YAML-NEXT:     Addend:      0
+# YAML-NEXT:   - Offset:      0x0000000000000030
+# YAML-NEXT:     Symbol:      printf
+# YAML-NEXT:     Type:        R_MIPS_GPREL16
+# YAML-NEXT:     Type2:       R_MIPS_LO16
+# YAML-NEXT:     SpecSym:     RSS_GP0
+# YAML-NEXT:     Addend:      0
+
+---
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [ EF_MIPS_PIC, EF_MIPS_CPIC,
+                     EF_MIPS_NOREORDER, EF_MIPS_ARCH_64R2 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x10
+    Size:            0x60
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK ]
+    Info:            .text
+    Relocations:
+      - Offset:      0x14
+        Symbol:      main
+        Type:        R_MIPS_GPREL16
+        Type2:       R_MIPS_SUB
+        Type3:       R_MIPS_HI16
+        Addend:      4
+      - Offset:      0x1C
+        Symbol:      main
+        Type:        R_MIPS_GPREL16
+        Type2:       R_MIPS_SUB
+        Type3:       R_MIPS_LO16
+        Addend:      8
+      - Offset:      0x20
+        Symbol:      .rodata
+        Type:        R_MIPS_GOT_PAGE
+      - Offset:      0x24
+        Symbol:      .rodata
+        Type:        R_MIPS_GOT_OFST
+      - Offset:      0x28
+        Symbol:      printf
+        Type:        R_MIPS_CALL16
+      - Offset:      0x30
+        Symbol:      printf
+        Type:        R_MIPS_GPREL16
+        Type2:       R_MIPS_LO16
+        SpecSym:     RSS_GP0
+  - Name:            .rodata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    AddressAlign:    0x10
+    Size:            0x0F
+
+Symbols:
+  Local:
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+    - Name:            .rodata
+      Type:            STT_SECTION
+      Section:         .rodata
+  Global:
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x58
+    - Name:            printf
+...

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=227044&r1=227043&r2=227044&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Sun Jan 25 07:29:25 2015
@@ -321,6 +321,12 @@ ELFState<ELFT>::writeSectionContent(Elf_
   SHeader.sh_size = Section.Size;
 }
 
+static bool isMips64EL(const ELFYAML::Object &Doc) {
+  return Doc.Header.Machine == ELFYAML::ELF_EM(llvm::ELF::EM_MIPS) &&
+         Doc.Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64) &&
+         Doc.Header.Data == ELFYAML::ELF_ELFDATA(ELF::ELFDATA2LSB);
+}
+
 template <class ELFT>
 bool
 ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader, @@ -351,13 +357,13 @@ ELFState<ELFT>::writeSectionContent(Elf_
       zero(REntry);
       REntry.r_offset = Rel.Offset;
       REntry.r_addend = Rel.Addend;
-      REntry.setSymbolAndType(SymIdx, Rel.Type);
+      REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc));
       OS.write((const char *)&REntry, sizeof(REntry));
     } else {
       Elf_Rel REntry;
       zero(REntry);
       REntry.r_offset = Rel.Offset;
-      REntry.setSymbolAndType(SymIdx, Rel.Type);
+      REntry.setSymbolAndType(SymIdx, Rel.Type, isMips64EL(Doc));
       OS.write((const char *)&REntry, sizeof(REntry));
     }
   }


_______________________________________________
llvm-commits mailing list
llvm-commits at cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.





More information about the llvm-commits mailing list