diff options
author | Simon Atanasyan <simon@atanasyan.com> | 2015-04-10 21:00:41 +0000 |
---|---|---|
committer | Simon Atanasyan <simon@atanasyan.com> | 2015-04-10 21:00:41 +0000 |
commit | 720f52a961f995a55d8d369f1db80e56b469e185 (patch) | |
tree | e339a27e7d2301b6729368b185096461f96b5de6 | |
parent | 54b1d56c0152e658c138f464ea45ff8e40ff2fbc (diff) | |
download | bcm5719-llvm-720f52a961f995a55d8d369f1db80e56b469e185.tar.gz bcm5719-llvm-720f52a961f995a55d8d369f1db80e56b469e185.zip |
[Mips] Add -pcrel-eh-reloc command line option
This MIPS specific option controls R_MIPS_EH relocation handling.
If -pcrel-eh-reloc is specified R_MIPS_EH relocation should be handled
like R_MIPS_PC32 relocation.
llvm-svn: 234635
-rw-r--r-- | lld/include/lld/ReaderWriter/ELFLinkingContext.h | 5 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdDriver.cpp | 13 | ||||
-rw-r--r-- | lld/lib/Driver/GnuLdOptions.td | 9 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp | 3 | ||||
-rw-r--r-- | lld/test/elf/Mips/rel-eh-03.test | 128 |
5 files changed, 158 insertions, 0 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index a925e354934..bf3b9de274f 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -326,6 +326,10 @@ public: bool armTarget1Rel() const { return _armTarget1Rel; } void setArmTarget1Rel(bool value) { _armTarget1Rel = value; } + // Set R_MIPS_EH relocation behaviour. + bool mipsPcRelEhRel() const { return _mipsPcRelEhRel; } + void setMipsPcRelEhRel(bool value) { _mipsPcRelEhRel = value; } + /// Each time a reader reads a new file, this member function is called /// with the file's ELF magics. This is supposed to "merge" all attributes /// to generate output ELF file magic. This can also reject input files @@ -361,6 +365,7 @@ protected: bool _enableNewDtags = false; bool _collectStats = false; bool _armTarget1Rel = false; + bool _mipsPcRelEhRel = false; uint64_t _maxPageSize = 0x1000; OutputMagic _outputMagic; diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index 63548b07ce8..7a1f674ec82 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -557,6 +557,19 @@ bool GnuLdDriver::parse(int argc, const char *argv[], << "--arm-target1-abs\n"; } + // Process MIPS specific options. + if (triple.getArch() == llvm::Triple::mips || + triple.getArch() == llvm::Triple::mipsel || + triple.getArch() == llvm::Triple::mips64 || + triple.getArch() == llvm::Triple::mips64el) + ctx->setMipsPcRelEhRel(parsedArgs->hasArg(OPT_pcrel_eh_reloc)); + else { + for (const auto *arg : parsedArgs->filtered(OPT_grp_mips_targetopts)) { + diag << "warning: ignoring unsupported MIPS specific argument: " + << arg->getSpelling() << "\n"; + } + } + for (auto *arg : parsedArgs->filtered(OPT_L)) ctx->addSearchPath(arg->getValue()); diff --git a/lld/lib/Driver/GnuLdOptions.td b/lld/lib/Driver/GnuLdOptions.td index 2cb68c40f40..6cd26fa3164 100644 --- a/lld/lib/Driver/GnuLdOptions.td +++ b/lld/lib/Driver/GnuLdOptions.td @@ -329,6 +329,15 @@ def arm_target1_abs : Flag<["--"], "arm-target1-abs">, Group<grp_targetopts>, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">; //===----------------------------------------------------------------------===// +/// MIPS Target Specific Options +//===----------------------------------------------------------------------===// +def grp_mips_targetopts : OptionGroup<"MIPS SPECIFIC OPTIONS">, + Group<grp_targetopts>; +def pcrel_eh_reloc : Flag<["-", "--"], "pcrel-eh-reloc">, + Group<grp_mips_targetopts>, + HelpText<"Interpret R_MIPS_EH as R_MIPS_PC32">; + +//===----------------------------------------------------------------------===// /// Ignored options //===----------------------------------------------------------------------===// def grp_ignored: OptionGroup<"ignored">, diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index 0861fc1e01d..31db87a2a81 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -599,6 +599,9 @@ void RelocationPass<ELFT>::collectReferenceInfo( return; auto refKind = ref.kindValue(); + if (refKind == R_MIPS_EH && this->_ctx.mipsPcRelEhRel()) + ref.setKindValue(R_MIPS_PC32); + if (!isConstrainSym(atom, refKind)) return; diff --git a/lld/test/elf/Mips/rel-eh-03.test b/lld/test/elf/Mips/rel-eh-03.test new file mode 100644 index 00000000000..6a7a5fffe4c --- /dev/null +++ b/lld/test/elf/Mips/rel-eh-03.test @@ -0,0 +1,128 @@ +# Check R_MIPS_EH relocation handling in case of -pcrel-eh-reloc option. + +# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o +# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o +# RUN: lld -flavor gnu -target mipsel -e T0 \ +# RUN: -pcrel-eh-reloc -o %t.exe %t1.o %t2.o %t.so +# RUN: llvm-objdump -s -t %t.exe | FileCheck -check-prefix=RAW %s + +# RAW: Contents of section .gnu_extab: +# RAW-NEXT: 400158 00e7ffff ff000000 a01e0000 00000000 +# ^ 0x400140 + 0 - 0x400159 = 0xffffffe7 +# ^ 0x402000 + 0 - 0x400160 = 0x1ea0 +# E1 GOT entry = 0xffff8020 = -32736 ^ +# RAW: Contents of section .got: +# RAW-NEXT: 401000 00000000 00000080 + +# RAW: SYMBOL TABLE: +# RAW: 00402000 l .data 00000004 L1 +# RAW: 00400140 g F .text 00000004 T1 + +# t1.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_NOREORDER, EF_MIPS_CPIC, EF_MIPS_PIC, + EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [SHF_ALLOC, SHF_EXECINSTR] + AddressAlign: 16 + Size: 4 + +Symbols: + Global: + - Name: T1 + Type: STT_FUNC + Section: .text + Value: 0 + Size: 4 + +# t2.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MIPS + Flags: [EF_MIPS_NOREORDER, EF_MIPS_CPIC, EF_MIPS_PIC, + EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2] + +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [SHF_ALLOC, SHF_EXECINSTR] + AddressAlign: 16 + Size: 8 + + - Name: .data + Type: SHT_PROGBITS + Flags: [SHF_WRITE, SHF_ALLOC] + AddressAlign: 16 + Size: 4 + + - Name: .gnu_extab + Type: SHT_PROGBITS + Flags: [SHF_ALLOC] + AddressAlign: 4 + Size: 16 + + - Name: .rel.gnu_extab + Type: SHT_REL + Link: .symtab + AddressAlign: 4 + Info: .gnu_extab + Relocations: + - Offset: 1 + Symbol: T1 + Type: R_MIPS_EH + - Offset: 8 + Symbol: L1 + Type: R_MIPS_EH + + - Name: .eh_frame_entry + Type: SHT_PROGBITS + Flags: [SHF_ALLOC] + AddressAlign: 4 + Content: "0000000100000001" + + - Name: .rel.eh_frame_entry + Type: SHT_REL + Link: .symtab + AddressAlign: 4 + Info: .eh_frame_entry + Relocations: + - Offset: 0 + Symbol: .text + Type: R_MIPS_PC32 + - Offset: 4 + Symbol: .gnu_extab + Type: R_MIPS_PC32 + +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + - Name: .gnu_extab + Type: STT_SECTION + Section: .gnu_extab + - Name: L1 + Type: STT_OBJECT + Section: .data + Value: 0 + Size: 4 + + Global: + - Name: T0 + Type: STT_FUNC + Section: .text + Value: 0 + Size: 8 + - Name: T1 +... |