summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp5
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp1
-rw-r--r--lld/test/elf/Mips/rel-hi0-lo16-micro.test58
3 files changed, 63 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
index 51c7376a836..49e6ea00cd1 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
@@ -148,6 +148,7 @@ static MipsRelocationParams getRelocationParams(uint32_t rType) {
case R_MICROMIPS_HI16:
return {4, 0xffff, 0, true, gpDispCheck<16>};
case R_MICROMIPS_LO16:
+ case R_MICROMIPS_HI0_LO16:
case R_MICROMIPS_HIGHER:
case R_MICROMIPS_HIGHEST:
return {4, 0xffff, 0, true, dummyCheck};
@@ -237,7 +238,8 @@ static int32_t relocHi16(uint64_t P, uint64_t S, int64_t AHL, bool isGPDisp) {
}
/// \brief R_MIPS_LO16, R_MIPS_TLS_DTPREL_LO16, R_MIPS_TLS_TPREL_LO16,
-/// R_MICROMIPS_LO16, R_MICROMIPS_TLS_DTPREL_LO16, R_MICROMIPS_TLS_TPREL_LO16
+/// R_MICROMIPS_LO16, R_MICROMIPS_HI0_LO16,
+/// R_MICROMIPS_TLS_DTPREL_LO16, R_MICROMIPS_TLS_TPREL_LO16
/// local/external: lo16 AHL + S (truncate)
/// _gp_disp : lo16 AHL + GP - P + 4 (verify)
static int32_t relocLo16(uint64_t P, uint64_t S, int64_t AHL, bool isGPDisp,
@@ -389,6 +391,7 @@ static ErrorOr<int64_t> calculateRelocation(Reference::KindValue kind,
case R_MIPS_PCLO16:
return tgtAddr + addend - relAddr;
case R_MICROMIPS_LO16:
+ case R_MICROMIPS_HI0_LO16:
return relocLo16(relAddr, tgtAddr, addend, isGP, true);
case R_MIPS_GOT_LO16:
case R_MIPS_CALL_LO16:
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
index 1d7f01b3b08..f05d9d1198a 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
@@ -545,6 +545,7 @@ void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom,
case R_MIPS_PCLO16:
case R_MICROMIPS_HI16:
case R_MICROMIPS_LO16:
+ case R_MICROMIPS_HI0_LO16:
// FIXME (simon): Handle dynamic/static linking differently.
handlePlain(atom, ref);
break;
diff --git a/lld/test/elf/Mips/rel-hi0-lo16-micro.test b/lld/test/elf/Mips/rel-hi0-lo16-micro.test
new file mode 100644
index 00000000000..a9b84ebcf5d
--- /dev/null
+++ b/lld/test/elf/Mips/rel-hi0-lo16-micro.test
@@ -0,0 +1,58 @@
+# Check handling of R_MICROMIPS_HI0_LO16 relocation.
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t.o
+# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK-NEXT: 400130 00000420
+# ^ 0x402000 + 0x4 = 0x402004
+
+# CHECK: 00402000 g .data 00000004 D0
+
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
+ EF_MIPS_ARCH_32, EF_MIPS_MICROMIPS]
+
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 16
+ Content: "00000400"
+
+ - Name: .rel.text
+ Type: SHT_REL
+ Link: .symtab
+ AddressAlign: 4
+ Info: .text
+ Relocations:
+ - Offset: 0
+ Symbol: D0
+ Type: R_MICROMIPS_HI0_LO16
+
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_WRITE ]
+ AddressAlign: 16
+ Size: 4
+
+Symbols:
+ Global:
+ - Name: T0
+ Type: STT_FUNC
+ Section: .text
+ Value: 0
+ Size: 4
+ Other: [STO_MIPS_MICROMIPS]
+ - Name: D0
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0
+ Size: 4
+...
OpenPOWER on IntegriCloud