[Mips] Implement R_MIPS_PCHI16 / R_MIPS_PCLO16 relocations handling
llvm-svn: 232757
This commit is contained in:
parent
48e088f354
commit
caadcc3f27
|
@ -241,6 +241,8 @@ private:
|
|||
switch (rel.getType(isMips64EL())) {
|
||||
case llvm::ELF::R_MIPS_HI16:
|
||||
return llvm::ELF::R_MIPS_LO16;
|
||||
case llvm::ELF::R_MIPS_PCHI16:
|
||||
return llvm::ELF::R_MIPS_PCLO16;
|
||||
case llvm::ELF::R_MIPS_GOT16:
|
||||
if (isLocalBinding(rel))
|
||||
return llvm::ELF::R_MIPS_LO16;
|
||||
|
|
|
@ -75,6 +75,8 @@ static MipsRelocationParams getRelocationParams(uint32_t rType) {
|
|||
return {4, 0x3ffffff, 2, false};
|
||||
case R_MIPS_HI16:
|
||||
case R_MIPS_LO16:
|
||||
case R_MIPS_PCHI16:
|
||||
case R_MIPS_PCLO16:
|
||||
case R_MIPS_GPREL16:
|
||||
case R_MIPS_GOT16:
|
||||
case R_MIPS_GOT_DISP:
|
||||
|
@ -185,6 +187,13 @@ static uint32_t relocHi16(uint64_t P, uint64_t S, int64_t AHL, bool isGPDisp) {
|
|||
return (result + 0x8000) >> 16;
|
||||
}
|
||||
|
||||
/// \brief R_MIPS_PCHI16
|
||||
/// local/external: hi16 (S + AHL - P)
|
||||
static uint32_t relocPcHi16(uint64_t P, uint64_t S, int64_t AHL) {
|
||||
int32_t result = S + AHL - P;
|
||||
return (result + 0x8000) >> 16;
|
||||
}
|
||||
|
||||
/// \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,
|
||||
/// LLD_R_MIPS_LO16
|
||||
|
@ -196,6 +205,13 @@ static uint32_t relocLo16(uint64_t P, uint64_t S, int64_t AHL, bool isGPDisp,
|
|||
return result;
|
||||
}
|
||||
|
||||
/// local/external: lo16 (S + AHL - P)
|
||||
static uint32_t relocPcLo16(uint64_t P, uint64_t S, int64_t AHL) {
|
||||
AHL = llvm::SignExtend32<16>(AHL);
|
||||
int32_t result = S + AHL - P;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// \brief R_MIPS_GOT16, R_MIPS_CALL16, R_MICROMIPS_GOT16, R_MICROMIPS_CALL16
|
||||
/// rel16 G (verify)
|
||||
static uint64_t relocGOT(uint64_t S, uint64_t GP) {
|
||||
|
@ -372,8 +388,12 @@ static ErrorOr<uint64_t> calculateRelocation(const Reference &ref,
|
|||
case R_MIPS_HI16:
|
||||
case R_MICROMIPS_HI16:
|
||||
return relocHi16(relAddr, tgtAddr, ref.addend(), isGP);
|
||||
case R_MIPS_PCHI16:
|
||||
return relocPcHi16(relAddr, tgtAddr, ref.addend());
|
||||
case R_MIPS_LO16:
|
||||
return relocLo16(relAddr, tgtAddr, ref.addend(), isGP, false);
|
||||
case R_MIPS_PCLO16:
|
||||
return relocPcLo16(relAddr, tgtAddr, ref.addend());
|
||||
case R_MICROMIPS_LO16:
|
||||
return relocLo16(relAddr, tgtAddr, ref.addend(), isGP, true);
|
||||
case R_MIPS_GOT16:
|
||||
|
|
|
@ -495,6 +495,8 @@ void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom,
|
|||
case R_MIPS_PC32:
|
||||
case R_MIPS_HI16:
|
||||
case R_MIPS_LO16:
|
||||
case R_MIPS_PCHI16:
|
||||
case R_MIPS_PCLO16:
|
||||
case R_MICROMIPS_HI16:
|
||||
case R_MICROMIPS_LO16:
|
||||
// FIXME (simon): Handle dynamic/static linking differently.
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
# Check R_MIPS_COPY relocation emitting caused by R_MIPS_PCHI16 / R_MIPS_PCLO16
|
||||
# relocations when linking non-shared executable file.
|
||||
#
|
||||
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
|
||||
# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
|
||||
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
|
||||
# RUN: llvm-readobj -dt -r -dynamic-table %t.exe | FileCheck %s
|
||||
|
||||
# CHECK: Relocations [
|
||||
# CHECK-NEXT: Section (5) .rel.dyn {
|
||||
# CHECK-NEXT: 0x402008 R_MIPS_COPY D1 0x0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
# CHECK: DynamicSymbols [
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: @ (0)
|
||||
# CHECK-NEXT: Value: 0x0
|
||||
# CHECK-NEXT: Size: 0
|
||||
# CHECK-NEXT: Binding: Local (0x0)
|
||||
# CHECK-NEXT: Type: None (0x0)
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: Undefined (0x0)
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: D1@ (1)
|
||||
# CHECK-NEXT: Value: 0x402008
|
||||
# CHECK-NEXT: Size: 4
|
||||
# CHECK-NEXT: Binding: Global (0x1)
|
||||
# CHECK-NEXT: Type: Object (0x1)
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: .bss (0xA)
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
# CHECK: DynamicSection [ ({{.*}} entries)
|
||||
# CHECK: 0x00000001 NEEDED SharedLibrary (rel-copy-pc.test.tmp.so)
|
||||
# CHECK-NEXT: 0x00000000 NULL 0x0
|
||||
# CHECK-NEXT: ]
|
||||
|
||||
# so.o
|
||||
---
|
||||
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_32R6]
|
||||
|
||||
Sections:
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Size: 4
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_WRITE, SHF_ALLOC]
|
||||
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: D1
|
||||
Section: .data
|
||||
Type: STT_OBJECT
|
||||
Value: 0
|
||||
Size: 4
|
||||
|
||||
# o.o
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R6]
|
||||
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Size: 4
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_EXECINSTR, SHF_ALLOC]
|
||||
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Size: 4
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_WRITE, SHF_ALLOC]
|
||||
|
||||
- Name: .rel.data
|
||||
Type: SHT_REL
|
||||
Info: .data
|
||||
AddressAlign: 4
|
||||
Relocations:
|
||||
- Offset: 0
|
||||
Symbol: D1
|
||||
Type: R_MIPS_PCHI16
|
||||
- Offset: 0
|
||||
Symbol: D1
|
||||
Type: R_MIPS_PCLO16
|
||||
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: T0
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 0
|
||||
Size: 4
|
||||
- Name: D0
|
||||
Section: .data
|
||||
Type: STT_OBJECT
|
||||
Value: 0
|
||||
Size: 4
|
||||
- Name: D1
|
||||
...
|
|
@ -0,0 +1,213 @@
|
|||
# Conditions:
|
||||
# a) Linking a non-shared executable file.
|
||||
# b) Relocations' targets are symbols defined in the shared object.
|
||||
# c) Relocations are R_MIPS_PCHI16 / R_MIPS_PCLO16.
|
||||
# Check:
|
||||
# a) Emitting R_MIPS_REL32, R_MIPS_COPY, R_MIPS_JUMP_SLOT relocations.
|
||||
# b) STO_MIPS_PLT flag in the dynamic symbol table for symbols require
|
||||
# a pointer equality.
|
||||
#
|
||||
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
|
||||
# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-so.o
|
||||
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
|
||||
# RUN: lld -flavor gnu -target mipsel -e T0 -o %t.exe %t-o.o %t.so
|
||||
# RUN: llvm-readobj -dt -r %t.exe | FileCheck -check-prefix=PLT-SYM %s
|
||||
|
||||
# PLT-SYM: Relocations [
|
||||
# PLT-SYM-NEXT: Section (5) .rel.dyn {
|
||||
# PLT-SYM-NEXT: 0x402014 R_MIPS_REL32 T2 0x0
|
||||
# PLT-SYM-NEXT: 0x402014 R_MIPS_REL32 D2 0x0
|
||||
# PLT-SYM-NEXT: 0x402018 R_MIPS_COPY D1 0x0
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: Section (6) .rel.plt {
|
||||
# PLT-SYM-NEXT: 0x402008 R_MIPS_JUMP_SLOT T3 0x0
|
||||
# PLT-SYM-NEXT: 0x40200C R_MIPS_JUMP_SLOT T1 0x0
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: ]
|
||||
|
||||
# PLT-SYM: DynamicSymbols [
|
||||
# PLT-SYM-NEXT: Symbol {
|
||||
# PLT-SYM-NEXT: Name: @ (0)
|
||||
# PLT-SYM-NEXT: Value: 0x0
|
||||
# PLT-SYM-NEXT: Size: 0
|
||||
# PLT-SYM-NEXT: Binding: Local (0x0)
|
||||
# PLT-SYM-NEXT: Type: None (0x0)
|
||||
# PLT-SYM-NEXT: Other: 0
|
||||
# PLT-SYM-NEXT: Section: Undefined (0x0)
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: Symbol {
|
||||
# PLT-SYM-NEXT: Name: D1@ (1)
|
||||
# PLT-SYM-NEXT: Value: 0x402018
|
||||
# PLT-SYM-NEXT: Size: 4
|
||||
# PLT-SYM-NEXT: Binding: Global (0x1)
|
||||
# PLT-SYM-NEXT: Type: Object (0x1)
|
||||
# PLT-SYM-NEXT: Other: 0
|
||||
# PLT-SYM-NEXT: Section: .bss (0xD)
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: Symbol {
|
||||
# PLT-SYM-NEXT: Name: T1@ (4)
|
||||
# PLT-SYM-NEXT: Value: 0x400220
|
||||
# PLT-SYM-NEXT: Size: 0
|
||||
# PLT-SYM-NEXT: Binding: Global (0x1)
|
||||
# PLT-SYM-NEXT: Type: Function (0x2)
|
||||
# PLT-SYM-NEXT: Other: 8
|
||||
# PLT-SYM-NEXT: Section: Undefined (0x0)
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: Symbol {
|
||||
# PLT-SYM-NEXT: Name: T3@ (10)
|
||||
# PLT-SYM-NEXT: Value: 0x0
|
||||
# PLT-SYM-NEXT: Size: 0
|
||||
# PLT-SYM-NEXT: Binding: Global (0x1)
|
||||
# PLT-SYM-NEXT: Type: Function (0x2)
|
||||
# PLT-SYM-NEXT: Other: 0
|
||||
# PLT-SYM-NEXT: Section: Undefined (0x0)
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: Symbol {
|
||||
# PLT-SYM-NEXT: Name: T2@ (7)
|
||||
# PLT-SYM-NEXT: Value: 0x0
|
||||
# PLT-SYM-NEXT: Size: 0
|
||||
# PLT-SYM-NEXT: Binding: Global (0x1)
|
||||
# PLT-SYM-NEXT: Type: Function (0x2)
|
||||
# PLT-SYM-NEXT: Other: 0
|
||||
# PLT-SYM-NEXT: Section: Undefined (0x0)
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: Symbol {
|
||||
# PLT-SYM-NEXT: Name: D2@ (13)
|
||||
# PLT-SYM-NEXT: Value: 0x0
|
||||
# PLT-SYM-NEXT: Size: 4
|
||||
# PLT-SYM-NEXT: Binding: Global (0x1)
|
||||
# PLT-SYM-NEXT: Type: Object (0x1)
|
||||
# PLT-SYM-NEXT: Other: 0
|
||||
# PLT-SYM-NEXT: Section: Undefined (0x0)
|
||||
# PLT-SYM-NEXT: }
|
||||
# PLT-SYM-NEXT: ]
|
||||
|
||||
# so.o
|
||||
---
|
||||
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_32R6]
|
||||
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Size: 0x0C
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_EXECINSTR, SHF_ALLOC]
|
||||
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Size: 0x08
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_WRITE, SHF_ALLOC]
|
||||
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: T1
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 0x0
|
||||
Size: 4
|
||||
- Name: T2
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 0x4
|
||||
Size: 4
|
||||
- Name: T3
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 0x8
|
||||
Size: 4
|
||||
- Name: D1
|
||||
Section: .data
|
||||
Type: STT_OBJECT
|
||||
Value: 0x0
|
||||
Size: 4
|
||||
- Name: D2
|
||||
Section: .data
|
||||
Type: STT_OBJECT
|
||||
Value: 0x4
|
||||
Size: 4
|
||||
|
||||
# o.o
|
||||
---
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R6]
|
||||
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Size: 0x08
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_EXECINSTR, SHF_ALLOC]
|
||||
|
||||
- Name: .data
|
||||
Type: SHT_PROGBITS
|
||||
Size: 0x08
|
||||
AddressAlign: 16
|
||||
Flags: [SHF_WRITE, SHF_ALLOC]
|
||||
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Info: .text
|
||||
AddressAlign: 4
|
||||
Relocations:
|
||||
- Offset: 0x04
|
||||
Symbol: T3
|
||||
Type: R_MIPS_26
|
||||
|
||||
- Name: .rel.data
|
||||
Type: SHT_REL
|
||||
Info: .data
|
||||
AddressAlign: 4
|
||||
Relocations:
|
||||
- Offset: 0x00
|
||||
Symbol: T1
|
||||
Type: R_MIPS_PCHI16
|
||||
- Offset: 0x00
|
||||
Symbol: T1
|
||||
Type: R_MIPS_PCLO16
|
||||
- Offset: 0x04
|
||||
Symbol: T2
|
||||
Type: R_MIPS_32
|
||||
|
||||
- Offset: 0x04
|
||||
Symbol: D1
|
||||
Type: R_MIPS_PCHI16
|
||||
- Offset: 0x04
|
||||
Symbol: D1
|
||||
Type: R_MIPS_PCLO16
|
||||
- Offset: 0x04
|
||||
Symbol: D2
|
||||
Type: R_MIPS_32
|
||||
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: T0
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 0x0
|
||||
Size: 8
|
||||
- Name: T1
|
||||
Type: STT_FUNC
|
||||
- Name: T2
|
||||
Type: STT_FUNC
|
||||
- Name: T3
|
||||
Type: STT_FUNC
|
||||
- Name: D0
|
||||
Section: .data
|
||||
Type: STT_OBJECT
|
||||
Value: 0x0
|
||||
Size: 8
|
||||
- Name: D1
|
||||
Type: STT_OBJECT
|
||||
- Name: D2
|
||||
Type: STT_OBJECT
|
||||
...
|
|
@ -0,0 +1,70 @@
|
|||
# Check handling of R_MIPS_PCHI16 / R_MIPS_PCLO16 relocations.
|
||||
|
||||
# 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: 400110 01000000 02000000 03000000 00000000
|
||||
# ^
|
||||
# A = 0x10000 - 1 == 0xffff
|
||||
# V = (T1 + 0xffff - T0) >> 16 =>
|
||||
# V => 0x1000b >> 16 = 1
|
||||
# ^
|
||||
# A = 0x20000 - 1 == 0x1ffff
|
||||
# V = (T1 + 0x1ffff - T0 - 4) >> 16 =>
|
||||
# V => 0x20007 >> 16 = 2
|
||||
# ^
|
||||
# A = 0xffff == -1
|
||||
# V = T1 - 1 - T0 - 8 = 3
|
||||
|
||||
# CHECK: SYMBOL TABLE:
|
||||
# CHECK: 00400110 g F .text 0000000c T0
|
||||
# CHECK: 0040011c g F .text 00000004 T1
|
||||
|
||||
FileHeader:
|
||||
Class: ELFCLASS32
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_REL
|
||||
Machine: EM_MIPS
|
||||
Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R6]
|
||||
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Content: "0100000002000000ffff000000000000"
|
||||
# ^ T0
|
||||
# ^ A := 0x1 == 0x10000
|
||||
# ^ A := 0x2 == 0x20000
|
||||
# ^ A := 0xffff == -1
|
||||
# ^ T1
|
||||
AddressAlign: 16
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
|
||||
- Name: .rel.text
|
||||
Type: SHT_REL
|
||||
Info: .text
|
||||
AddressAlign: 4
|
||||
Relocations:
|
||||
- Offset: 0
|
||||
Symbol: T1
|
||||
Type: R_MIPS_PCHI16
|
||||
- Offset: 4
|
||||
Symbol: T1
|
||||
Type: R_MIPS_PCHI16
|
||||
- Offset: 8
|
||||
Symbol: T1
|
||||
Type: R_MIPS_PCLO16
|
||||
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: T0
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 0
|
||||
Size: 12
|
||||
- Name: T1
|
||||
Section: .text
|
||||
Type: STT_FUNC
|
||||
Value: 12
|
||||
Size: 4
|
Loading…
Reference in New Issue