[llvm-commits] [llvm] r159299 - in /llvm/trunk: include/llvm/MC/MCELFObjectWriter.h lib/MC/ELFObjectWriter.cpp lib/MC/MCELFObjectTargetWriter.cpp lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp

Jack Carter jcarter at mips.com
Wed Jun 27 15:28:30 PDT 2012


Author: jacksprat
Date: Wed Jun 27 17:28:30 2012
New Revision: 159299

URL: http://llvm.org/viewvc/llvm-project?rev=159299&view=rev
Log:
The ELF relocation record format is different for N64 
which many Mips 64 ABIs use than for O64 which many 
if not all other target ABIs use.

Most architectures have the following 64 bit relocation record format:

  typedef struct
  {
    Elf64_Addr   r_offset; /* Address of reference */
    Elf64_Xword  r_info;   /* Symbol index and type of relocation */
  } Elf64_Rel;

  typedef struct
  {
    Elf64_Addr    r_offset;
    Elf64_Xword   r_info;
    Elf64_Sxword  r_addend;
  } Elf64_Rela;

Whereas N64 has the following format:

  typedef struct
  {
    Elf64_Addr    r_offset;/* Address of reference */
    Elf64_Word  r_sym;     /* Symbol index */
    Elf64_Byte  r_ssym;    /* Special symbol */
    Elf64_Byte  r_type3;   /* Relocation type */
    Elf64_Byte  r_type2;   /* Relocation type */
    Elf64_Byte  r_type;    /* Relocation type */
  } Elf64_Rel;

  typedef struct
  {
    Elf64_Addr    r_offset;/* Address of reference */
    Elf64_Word  r_sym;     /* Symbol index */
    Elf64_Byte  r_ssym;    /* Special symbol */
    Elf64_Byte  r_type3;   /* Relocation type */
    Elf64_Byte  r_type2;   /* Relocation type */
    Elf64_Byte  r_type;    /* Relocation type */
    Elf64_Sxword  r_addend;
  } Elf64_Rela;

The structure is the same size, but the r_info data element 
is now 5 separate elements. Besides the content aspects, 
endian byte reordering will be different for the area with 
each element being endianized separately.

I treat this as generic and continue to pass r_type as 
an integer masking and unmasking the byte sized N64 
values for N64 mode. I've implemented this and it causes no 
affect on other current targets.

This passes make check.

Jack

Modified:
    llvm/trunk/include/llvm/MC/MCELFObjectWriter.h
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp
    llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp

Modified: llvm/trunk/include/llvm/MC/MCELFObjectWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCELFObjectWriter.h?rev=159299&r1=159298&r2=159299&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCELFObjectWriter.h (original)
+++ llvm/trunk/include/llvm/MC/MCELFObjectWriter.h Wed Jun 27 17:28:30 2012
@@ -54,11 +54,13 @@
   const uint16_t EMachine;
   const unsigned HasRelocationAddend : 1;
   const unsigned Is64Bit : 1;
+  const unsigned IsN64 : 1;
 
 protected:
 
   MCELFObjectTargetWriter(bool Is64Bit_, uint8_t OSABI_,
-                          uint16_t EMachine_,  bool HasRelocationAddend_);
+                          uint16_t EMachine_,  bool HasRelocationAddend,
+                          bool IsN64=false);
 
 public:
   static uint8_t getOSABI(Triple::OSType OSType) {
@@ -95,7 +97,47 @@
   uint16_t getEMachine() { return EMachine; }
   bool hasRelocationAddend() { return HasRelocationAddend; }
   bool is64Bit() const { return Is64Bit; }
+  bool isN64() const { return IsN64; }
   /// @}
+
+  // Instead of changing everyone's API we pack the N64 Type fields
+  // into the existing 32 bit data unsigned.
+#define R_TYPE_SHIFT 0
+#define R_TYPE_MASK 0xffffff00
+#define R_TYPE2_SHIFT 8
+#define R_TYPE2_MASK 0xffff00ff
+#define R_TYPE3_SHIFT 16
+#define R_TYPE3_MASK 0xff00ffff
+#define R_SSYM_SHIFT 24
+#define R_SSYM_MASK 0x00ffffff
+
+  // N64 relocation type accessors
+  unsigned getRType(uint32_t Type) const {
+    return (unsigned)((Type >> R_TYPE_SHIFT) & 0xff);
+  }
+  unsigned getRType2(uint32_t Type) const {
+    return (unsigned)((Type >> R_TYPE2_SHIFT) & 0xff);
+  }
+  unsigned getRType3(uint32_t Type) const {
+    return (unsigned)((Type >> R_TYPE3_SHIFT) & 0xff);
+  }
+  unsigned getRSsym(uint32_t Type) const {
+    return (unsigned)((Type >> R_SSYM_SHIFT) & 0xff);
+  }
+
+  // N64 relocation type setting
+  unsigned setRType(unsigned Value, unsigned Type) const {
+    return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
+  }
+  unsigned setRType2(unsigned Value, unsigned Type) const {
+    return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
+  }
+  unsigned setRType3(unsigned Value, unsigned Type) const {
+    return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
+  }
+  unsigned setRSsym(unsigned Value, unsigned Type) const {
+    return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
+  }
 };
 
 /// \brief Construct a new ELF writer instance.

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=159299&r1=159298&r2=159299&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed Jun 27 17:28:30 2012
@@ -1061,11 +1061,19 @@
       entry.Index += LocalSymbolData.size();
     if (is64Bit()) {
       String64(*F, entry.r_offset);
+      if (TargetObjectWriter->isN64()) {
+        String32(*F, entry.Index);
 
-      struct ELF::Elf64_Rela ERE64;
-      ERE64.setSymbolAndType(entry.Index, entry.Type);
-      String64(*F, ERE64.r_info);
-
+        String8(*F, TargetObjectWriter->getRSsym(entry.Type));
+        String8(*F, TargetObjectWriter->getRType3(entry.Type));
+        String8(*F, TargetObjectWriter->getRType2(entry.Type));
+        String8(*F, TargetObjectWriter->getRType(entry.Type));
+      }
+      else {
+        struct ELF::Elf64_Rela ERE64;
+        ERE64.setSymbolAndType(entry.Index, entry.Type);
+        String64(*F, ERE64.r_info);
+      }
       if (hasRelocationAddend())
         String64(*F, entry.r_addend);
     } else {

Modified: llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp?rev=159299&r1=159298&r2=159299&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp (original)
+++ llvm/trunk/lib/MC/MCELFObjectTargetWriter.cpp Wed Jun 27 17:28:30 2012
@@ -15,9 +15,11 @@
 MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
                                                  uint8_t OSABI_,
                                                  uint16_t EMachine_,
-                                                 bool HasRelocationAddend_)
+                                                 bool HasRelocationAddend_,
+                                                 bool IsN64_)
   : OSABI(OSABI_), EMachine(EMachine_),
-    HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_) {
+    HasRelocationAddend(HasRelocationAddend_), Is64Bit(Is64Bit_),
+    IsN64(IsN64_){
 }
 
 /// Default e_flags = 0

Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp?rev=159299&r1=159298&r2=159299&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp Wed Jun 27 17:28:30 2012
@@ -34,7 +34,7 @@
 
   class MipsELFObjectWriter : public MCELFObjectTargetWriter {
   public:
-    MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI);
+    MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64);
 
     virtual ~MipsELFObjectWriter();
 
@@ -52,9 +52,11 @@
   };
 }
 
-MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI)
+MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI,
+                                         bool _isN64)
   : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS,
-                            /*HasRelocationAddend*/ false) {}
+                            /*HasRelocationAddend*/ false,
+                            /*IsN64*/ _isN64) {}
 
 MipsELFObjectWriter::~MipsELFObjectWriter() {}
 
@@ -149,7 +151,6 @@
     Type = ELF::R_MIPS_PC16;
     break;
   }
-
   return Type;
 }
 
@@ -184,7 +185,7 @@
 
 void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
                                      std::vector<ELFRelocationEntry> &Relocs) {
-  // Call the defualt function first. Relocations are sorted in descending
+  // Call the default function first. Relocations are sorted in descending
   // order of r_offset.
   MCELFObjectTargetWriter::sortRelocs(Asm, Relocs);
 
@@ -244,6 +245,7 @@
                                                 uint8_t OSABI,
                                                 bool IsLittleEndian,
                                                 bool Is64Bit) {
-  MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI);
+  MCELFObjectTargetWriter *MOTW = new MipsELFObjectWriter(Is64Bit, OSABI,
+                                                (Is64Bit) ? true : false);
   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
 }





More information about the llvm-commits mailing list