diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2015-03-30 11:39:02 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2015-03-30 11:39:02 +0000 |
| commit | f9db1643557923249fe3c111bacfff64947f7a0e (patch) | |
| tree | 1b9f65bec5475d0b5c08ad4ad929d3ad5c78e2c0 | |
| parent | de7867938bf46b55a6a2104add82f3cedc35ba94 (diff) | |
| download | bcm5719-llvm-f9db1643557923249fe3c111bacfff64947f7a0e.tar.gz bcm5719-llvm-f9db1643557923249fe3c111bacfff64947f7a0e.zip | |
[Mips] Fix writing R_MIPS_REL32 relocation addendum
If input relocation records have RELA format while output dynamic
relocations have REL format the only way to transfer a dynamic
relocation addendum is to save it into the location modified by
the dynamic relocation.
llvm-svn: 233532
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp | 14 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h | 1 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp | 8 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-13.test | 94 | ||||
| -rw-r--r-- | lld/test/elf/Mips/rel-dynamic-14.test | 94 |
5 files changed, 211 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp index 7bffcbeb5c0..8362dd54838 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp @@ -113,3 +113,17 @@ bool MipsLinkingContext::isPLTRelocation(const Reference &r) const { return false; } } + +bool MipsLinkingContext::isRelativeReloc(const Reference &r) const { + if (r.kindNamespace() != Reference::KindNamespace::ELF) + return false; + assert(r.kindArch() == Reference::KindArch::Mips); + switch (r.kindValue()) { + case llvm::ELF::R_MIPS_REL32: + case llvm::ELF::R_MIPS_GPREL16: + case llvm::ELF::R_MIPS_GPREL32: + return true; + default: + return false; + } +} diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h index 824605f5fa7..8919031f742 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h @@ -57,6 +57,7 @@ public: bool isDynamicRelocation(const Reference &r) const override; bool isCopyRelocation(const Reference &r) const override; bool isPLTRelocation(const Reference &r) const override; + bool isRelativeReloc(const Reference &r) const override; private: MipsELFFlagsMerger _flagsMerger; diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp index 173ce0e6b1a..045f614833e 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp @@ -124,6 +124,7 @@ static MipsRelocationParams getRelocationParams(uint32_t rType) { case R_MICROMIPS_JALR: return {4, 0x0, 0, true}; case R_MIPS_REL32: + return {4, 0xffffffff, 0, false}; case R_MIPS_JUMP_SLOT: case R_MIPS_COPY: case R_MIPS_TLS_DTPMOD32: @@ -554,6 +555,13 @@ std::error_code RelocationHandler<ELFT>::applyRelocation( if (auto ec = res.getError()) return ec; + // If output relocation format is REL and the input one is RELA, the only + // method to transfer the relocation addend from the input relocation + // to the output dynamic relocation is to save this addend to the location + // modified by R_MIPS_REL32. + if (ref.kindValue() == R_MIPS_REL32 && !_ctx.isRelaOutputFormat()) + res = ref.addend(); + Reference::KindValue op = ref.kindValue(); // FIXME (simon): Handle r_ssym value. diff --git a/lld/test/elf/Mips/rel-dynamic-13.test b/lld/test/elf/Mips/rel-dynamic-13.test new file mode 100644 index 00000000000..c8ed28440c3 --- /dev/null +++ b/lld/test/elf/Mips/rel-dynamic-13.test @@ -0,0 +1,94 @@ +# Conditions: +# a) Linking a non-shared 32-bit executable file. +# b) Relocations' targets are symbols defined in the shared object. +# Check: +# a) Emitting R_MIPS_REL32 relocation. +# b) Applying addendum from the original relocation. +# +# 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-objdump -s %t.exe | FileCheck -check-prefix=RAW %s +# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s + +# RAW: Contents of section .data: +# RAW-NEXT: 402000 01000000 + +# REL: Relocations [ +# REL-NEXT: Section (5) .rel.dyn { +# REL-NEXT: 0x402000 R_MIPS_REL32 T1 0x0 +# REL-NEXT: } +# REL-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_32] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [SHF_EXECINSTR, SHF_ALLOC] + +Symbols: + Global: + - Name: T1 + Section: .text + Type: STT_FUNC + 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_32] + +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_RELA + Info: .data + AddressAlign: 4 + Relocations: + - Offset: 0 + Symbol: T1 + Type: R_MIPS_32 + Addend: 1 + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + - Name: T1 + Type: STT_FUNC + - Name: D0 + Section: .data + Type: STT_OBJECT + Value: 0 + Size: 4 +... diff --git a/lld/test/elf/Mips/rel-dynamic-14.test b/lld/test/elf/Mips/rel-dynamic-14.test new file mode 100644 index 00000000000..eef8bfe03ff --- /dev/null +++ b/lld/test/elf/Mips/rel-dynamic-14.test @@ -0,0 +1,94 @@ +# Conditions: +# a) Linking a non-shared 64-bit executable file. +# b) Relocations' targets are symbols defined in the shared object. +# Check: +# a) Emitting R_MIPS_REL32/R_MIPS_64 relocation. +# b) Applying addendum from the original relocation. +# +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o +# RUN: lld -flavor gnu -target mips64el -shared -o %t.so %t-so.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o +# RUN: lld -flavor gnu -target mips64el -e T0 -o %t.exe %t-o.o %t.so +# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=RAW %s +# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s + +# RAW: Contents of section .data: +# RAW-NEXT: 120002000 04000000 00000000 + +# REL: Relocations [ +# REL-NEXT: Section (5) .rel.dyn { +# REL-NEXT: 0x120002000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE T1 0x0 +# REL-NEXT: } +# REL-NEXT: ] + +# so.o +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [SHF_EXECINSTR, SHF_ALLOC] + +Symbols: + Global: + - Name: T1 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + +# o.o +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64] + +Sections: +- Name: .text + Type: SHT_PROGBITS + Size: 4 + AddressAlign: 16 + Flags: [SHF_EXECINSTR, SHF_ALLOC] + +- Name: .data + Type: SHT_PROGBITS + Size: 8 + AddressAlign: 16 + Flags: [SHF_WRITE, SHF_ALLOC] + +- Name: .rel.data + Type: SHT_RELA + Info: .data + AddressAlign: 4 + Relocations: + - Offset: 0 + Symbol: T1 + Type: R_MIPS_64 + Addend: 4 + +Symbols: + Global: + - Name: T0 + Section: .text + Type: STT_FUNC + Value: 0 + Size: 4 + - Name: T1 + Type: STT_FUNC + - Name: D0 + Section: .data + Type: STT_OBJECT + Value: 0 + Size: 4 +... |

