]> granicus.if.org Git - llvm/commitdiff
[mips] Implement generation of relocations "chains" used by N32 ABI
authorSimon Atanasyan <simon@atanasyan.com>
Thu, 21 Sep 2017 14:04:53 +0000 (14:04 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Thu, 21 Sep 2017 14:04:53 +0000 (14:04 +0000)
In case of using a "nested" relocation expressions like this
`%hi(%neg(%gp_rel()))`, N32 ABI requires generation of three consecutive
relocations. That differs from the N64 ABI case where all relocations
are packed into the single relocation record.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313879 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/ELFObjectWriter.cpp
test/MC/Mips/elf-N32.s [new file with mode: 0644]

index b37a950908effa370ba38355d01d9a3989bdd1fa..eef2757b93b43ebee031f65763cc8eba262e5fec 100644 (file)
@@ -1131,6 +1131,23 @@ void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
 
       if (hasRelocationAddend())
         write(uint32_t(Entry.Addend));
+
+      if (TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
+        if (uint32_t RType = TargetObjectWriter->getRType2(Entry.Type)) {
+          write(uint32_t(Entry.Offset));
+
+          ERE32.setSymbolAndType(0, RType);
+          write(ERE32.r_info);
+          write(uint32_t(0));
+        }
+        if (uint32_t RType = TargetObjectWriter->getRType3(Entry.Type)) {
+          write(uint32_t(Entry.Offset));
+
+          ERE32.setSymbolAndType(0, RType);
+          write(ERE32.r_info);
+          write(uint32_t(0));
+        }
+      }
     }
   }
 }
diff --git a/test/MC/Mips/elf-N32.s b/test/MC/Mips/elf-N32.s
new file mode 100644 (file)
index 0000000..34a0cd0
--- /dev/null
@@ -0,0 +1,22 @@
+// Check generation of N32 ABI relocations.
+
+// RUN: llvm-mc -filetype=obj -triple=mips64-linux-gnu -mcpu=mips3 \
+// RUN:         -target-abi=n32  %s -o - | llvm-readobj -r | FileCheck %s
+
+// CHECK:      Relocations [
+// CHECK-NEXT:   Section (3) .rela.text {
+// CHECK-NEXT:     0x0 R_MIPS_GPREL16 foo 0x4
+// CHECK-NEXT:     0x0 R_MIPS_SUB - 0x0
+// CHECK-NEXT:     0x0 R_MIPS_HI16 - 0x0
+// CHECK-NEXT:     0x4 R_MIPS_GPREL16 foo 0x4
+// CHECK-NEXT:     0x4 R_MIPS_SUB - 0x0
+// CHECK-NEXT:     0x4 R_MIPS_LO16 - 0x0
+// CHECK-NEXT:   }
+
+  .globl  foo
+  .ent  foo
+foo:
+  lui   $gp, %hi(%neg(%gp_rel(foo+4)))
+  addiu $gp, $gp, %lo(%neg(%gp_rel(foo+4)))
+  daddu $gp, $gp, $25
+  .end  foo