[Mips] Implement R_MIPS_SUB relocation handling
authorSimon Atanasyan <simon@atanasyan.com>
Mon, 9 Mar 2015 10:53:50 +0000 (10:53 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Mon, 9 Mar 2015 10:53:50 +0000 (10:53 +0000)
llvm-svn: 231643

lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
lld/test/elf/Mips/rel-sub.test [new file with mode: 0644]

index 7a1147f..5100dab 100644 (file)
@@ -37,6 +37,7 @@ static MipsRelocationParams getRelocationParams(uint32_t rType) {
   case llvm::ELF::R_MIPS_NONE:
     return {4, 0x0, 0, false};
   case llvm::ELF::R_MIPS_64:
+  case llvm::ELF::R_MIPS_SUB:
     return {8, 0xffffffffffffffffull, 0, false};
   case llvm::ELF::R_MIPS_32:
   case llvm::ELF::R_MIPS_GPREL32:
@@ -122,6 +123,10 @@ static uint32_t reloc32(uint64_t S, int64_t A) { return S + A; }
 /// local/external: word64 S + A (truncate)
 static uint64_t reloc64(uint64_t S, int64_t A) { return S + A; }
 
+/// \brief R_MIPS_SUB
+/// local/external: word64 S - A (truncate)
+static uint64_t relocSub(uint64_t S, int64_t A) { return S - A; }
+
 /// \brief R_MIPS_PC32
 /// local/external: word32 S + A i- P (truncate)
 static uint32_t relocpc32(uint64_t P, uint64_t S, int64_t A) {
@@ -291,6 +296,8 @@ static ErrorOr<uint64_t> calculateRelocation(const Reference &ref,
     return reloc32(tgtAddr, ref.addend());
   case R_MIPS_64:
     return reloc64(tgtAddr, ref.addend());
+  case R_MIPS_SUB:
+    return relocSub(tgtAddr, ref.addend());
   case R_MIPS_26:
     return reloc26loc(relAddr, tgtAddr, ref.addend(), 2);
   case R_MICROMIPS_26_S1:
diff --git a/lld/test/elf/Mips/rel-sub.test b/lld/test/elf/Mips/rel-sub.test
new file mode 100644 (file)
index 0000000..93e569a
--- /dev/null
@@ -0,0 +1,61 @@
+# Check handling of R_MIPS_SUB relocation.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mips64el -o %t.exe %t.o
+# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
+
+# CHECK: Contents of section .data:
+# CHECK-NEXT: 120002000 cf010020 01000000 d0010020 0100ffff ... ....... ....
+#                       ^^ __start - 1 = 0x1200001cf
+#                                         ^^ __start - 0x1000000000000
+#                                              = 0Xffff0001200001d0
+# CHECK: SYMBOL TABLE:
+# CHECK: 00000001200001d0 g .rodata 00000008 __start
+
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+  Flags:   [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]
+
+Sections:
+- Name:         .text
+  Type:         SHT_PROGBITS
+  Size:         0x08
+  AddressAlign: 16
+  Flags:        [SHF_ALLOC]
+- Name:         .data
+  Type:         SHT_PROGBITS
+  Size:         0x10
+  AddressAlign: 16
+  Flags:        [SHF_ALLOC, SHF_WRITE]
+
+- Name:         .rela.data
+  Type:         SHT_RELA
+  Info:         .data
+  AddressAlign: 4
+  Relocations:
+    - Offset: 0x0
+      Symbol: __start
+      Type:   R_MIPS_SUB
+      Addend: 1
+    - Offset: 0x8
+      Symbol: __start
+      Type:   R_MIPS_SUB
+      Addend: 0x1000000000000
+
+Symbols:
+  Global:
+    - Name:    __start
+      Section: .text
+      Value:   0x0
+      Size:    8
+    - Name:    data1
+      Section: .data
+      Value:   0x0
+      Size:    8
+    - Name:    data2
+      Section: .data
+      Value:   0x8
+      Size:    8