From ede43b71f802ad65c030557876939bcc1f7636b8 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Thu, 21 Sep 2017 14:04:53 +0000 Subject: [PATCH] [mips] Implement generation of relocations "chains" used by N32 ABI 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. llvm-svn: 313879 --- llvm/lib/MC/ELFObjectWriter.cpp | 17 +++++++++++++++++ llvm/test/MC/Mips/elf-N32.s | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 llvm/test/MC/Mips/elf-N32.s diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index b37a950908ef..eef2757b93b4 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -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/llvm/test/MC/Mips/elf-N32.s b/llvm/test/MC/Mips/elf-N32.s new file mode 100644 index 000000000000..34a0cd0f8be0 --- /dev/null +++ b/llvm/test/MC/Mips/elf-N32.s @@ -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