diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2015-04-13 08:20:57 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2015-04-13 08:20:57 +0000 |
| commit | 88698b66c9d7ff9406e15425c2b7747ac93a0b4a (patch) | |
| tree | 2d6dd05aa13f68b48664fe642e4c819cc56b0588 /lld/lib | |
| parent | 62f261b014d716309bbd6d10f8fdc4370e2d9049 (diff) | |
| download | bcm5719-llvm-88698b66c9d7ff9406e15425c2b7747ac93a0b4a.tar.gz bcm5719-llvm-88698b66c9d7ff9406e15425c2b7747ac93a0b4a.zip | |
[Mips] Support R_MICROMIPS_GOT_HI/LO16 and R_MICROMIPS_CALL_HI/LO16 relocations
llvm-svn: 234726
Diffstat (limited to 'lld/lib')
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp | 12 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp | 17 |
2 files changed, 26 insertions, 3 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp index 71373f6d407..7c729f50f89 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp @@ -122,6 +122,10 @@ static MipsRelocationParams getRelocationParams(uint32_t rType) { case R_MICROMIPS_TLS_GD: case R_MICROMIPS_TLS_LDM: case R_MICROMIPS_TLS_GOTTPREL: + case R_MICROMIPS_GOT_HI16: + case R_MICROMIPS_GOT_LO16: + case R_MICROMIPS_CALL_HI16: + case R_MICROMIPS_CALL_LO16: return {4, 0xffff, 0, true}; case R_MIPS_JALR: return {4, 0x0, 0, false}; @@ -226,12 +230,14 @@ static uint64_t relocGOT(uint64_t S, uint64_t GP) { } /// \brief R_MIPS_GOT_LO16, R_MIPS_CALL_LO16 +/// R_MICROMIPS_GOT_LO16, R_MICROMIPS_CALL_LO16 /// rel16 G (truncate) static uint64_t relocGOTLo16(uint64_t S, uint64_t GP) { return S - GP; } -/// \brief R_MIPS_GOT_HI16, R_MIPS_CALL_HI16 +/// \brief R_MIPS_GOT_HI16, R_MIPS_CALL_HI16, +/// R_MICROMIPS_GOT_HI16, R_MICROMIPS_CALL_HI16 /// rel16 %high(G) (truncate) static uint64_t relocGOTHi16(uint64_t S, uint64_t GP) { return (S - GP + 0x8000) >> 16; @@ -420,9 +426,13 @@ static ErrorOr<uint64_t> calculateRelocation(Reference::KindValue kind, return relocLo16(relAddr, tgtAddr, addend, isGP, true); case R_MIPS_GOT_LO16: case R_MIPS_CALL_LO16: + case R_MICROMIPS_GOT_LO16: + case R_MICROMIPS_CALL_LO16: return relocGOTLo16(tgtAddr, gpAddr); case R_MIPS_GOT_HI16: case R_MIPS_CALL_HI16: + case R_MICROMIPS_GOT_HI16: + case R_MICROMIPS_CALL_HI16: return relocGOTHi16(tgtAddr, gpAddr); case R_MIPS_EH: case R_MIPS_GOT16: diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp index 65287abcc46..378e4cc29a8 100644 --- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp @@ -536,6 +536,10 @@ void RelocationPass<ELFT>::handleReference(const MipsELFDefinedAtom<ELFT> &atom, case R_MIPS_CALL_LO16: case R_MICROMIPS_GOT16: case R_MICROMIPS_CALL16: + case R_MICROMIPS_GOT_HI16: + case R_MICROMIPS_GOT_LO16: + case R_MICROMIPS_CALL_HI16: + case R_MICROMIPS_CALL_LO16: case R_MIPS_GOT_DISP: case R_MIPS_GOT_PAGE: handleGOT(ref); @@ -618,6 +622,8 @@ void RelocationPass<ELFT>::collectReferenceInfo( refKind != R_MIPS_26 && refKind != R_MICROMIPS_26_S1 && refKind != R_MIPS_GOT_HI16 && refKind != R_MIPS_GOT_LO16 && refKind != R_MIPS_CALL_HI16 && refKind != R_MIPS_CALL_LO16 && + refKind != R_MICROMIPS_GOT_HI16 && refKind != R_MICROMIPS_GOT_LO16 && + refKind != R_MICROMIPS_CALL_HI16 && refKind != R_MICROMIPS_CALL_LO16 && refKind != R_MIPS_EH) _requiresPtrEquality.insert(ref.target()); } @@ -649,7 +655,9 @@ bool RelocationPass<ELFT>::mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom, if (refKind == R_MIPS_CALL16 || refKind == R_MIPS_GOT16 || refKind == R_MICROMIPS_CALL16 || refKind == R_MICROMIPS_GOT16 || refKind == R_MIPS_GOT_HI16 || refKind == R_MIPS_GOT_LO16 || - refKind == R_MIPS_CALL_HI16 || refKind == R_MIPS_CALL_LO16) + refKind == R_MIPS_CALL_HI16 || refKind == R_MIPS_CALL_LO16 || + refKind == R_MICROMIPS_GOT_HI16 || refKind == R_MICROMIPS_GOT_LO16 || + refKind == R_MICROMIPS_CALL_HI16 || refKind == R_MICROMIPS_CALL_LO16) return true; if (refKind != R_MIPS_32 && refKind != R_MIPS_64) @@ -804,7 +812,12 @@ template <typename ELFT> void RelocationPass<ELFT>::handleGOT(Reference &ref) { ref.kindValue() == R_MIPS_GOT_HI16 || ref.kindValue() == R_MIPS_GOT_LO16 || ref.kindValue() == R_MIPS_CALL_HI16 || - ref.kindValue() == R_MIPS_CALL_LO16 || ref.kindValue() == R_MIPS_EH) + ref.kindValue() == R_MIPS_CALL_LO16 || + ref.kindValue() == R_MICROMIPS_GOT_HI16 || + ref.kindValue() == R_MICROMIPS_GOT_LO16 || + ref.kindValue() == R_MICROMIPS_CALL_HI16 || + ref.kindValue() == R_MICROMIPS_CALL_LO16 || + ref.kindValue() == R_MIPS_EH) ref.setTarget(getLocalGOTEntry(ref)); else if (isLocal(ref.target())) ref.setTarget(getLocalGOTPageEntry(ref)); |

