summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2015-04-10 21:00:41 +0000
committerSimon Atanasyan <simon@atanasyan.com>2015-04-10 21:00:41 +0000
commit720f52a961f995a55d8d369f1db80e56b469e185 (patch)
treee339a27e7d2301b6729368b185096461f96b5de6
parent54b1d56c0152e658c138f464ea45ff8e40ff2fbc (diff)
downloadbcm5719-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.h5
-rw-r--r--lld/lib/Driver/GnuLdDriver.cpp13
-rw-r--r--lld/lib/Driver/GnuLdOptions.td9
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp3
-rw-r--r--lld/test/elf/Mips/rel-eh-03.test128
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
+...
OpenPOWER on IntegriCloud