[Mips] Implement R_MIPS_PCHI16 / R_MIPS_PCLO16 relocations handling

llvm-svn: 232757
This commit is contained in:
Simon Atanasyan 2015-03-19 19:59:17 +00:00
parent 48e088f354
commit caadcc3f27
6 changed files with 420 additions and 0 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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.

View File

@ -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
...

View File

@ -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
...

View File

@ -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