mirror of
https://github.com/RPCS3/llvm.git
synced 2025-03-01 07:09:02 +00:00
[mips][mcjit] Calculate correct addend for HI16 and PCHI16 reloc
Previously, for O32 ABI we did not calculate correct addend for R_MIPS_HI16 and R_MIPS_PCHI16 relocations. This patch fixes that. Patch by Vladimir Radosavljevic. Differential Revision: http://reviews.llvm.org/D11186 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@244897 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ccc0cf3d8d
commit
319eb435fd
@ -522,6 +522,9 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
|
||||
Offset += Size;
|
||||
Addr += Size;
|
||||
}
|
||||
|
||||
if (Checker)
|
||||
Checker->registerSection(Obj.getFileName(), SectionID);
|
||||
}
|
||||
|
||||
unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
|
||||
|
@ -1123,6 +1123,29 @@ void RuntimeDyldELF::processSimpleRelocation(unsigned SectionID, uint64_t Offset
|
||||
addRelocationForSection(RE, Value.SectionID);
|
||||
}
|
||||
|
||||
uint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType,
|
||||
bool IsLocal) const {
|
||||
switch (RelType) {
|
||||
case ELF::R_MICROMIPS_GOT16:
|
||||
if (IsLocal)
|
||||
return ELF::R_MICROMIPS_LO16;
|
||||
break;
|
||||
case ELF::R_MICROMIPS_HI16:
|
||||
return ELF::R_MICROMIPS_LO16;
|
||||
case ELF::R_MIPS_GOT16:
|
||||
if (IsLocal)
|
||||
return ELF::R_MIPS_LO16;
|
||||
break;
|
||||
case ELF::R_MIPS_HI16:
|
||||
return ELF::R_MIPS_LO16;
|
||||
case ELF::R_MIPS_PCHI16:
|
||||
return ELF::R_MIPS_PCLO16;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ELF::R_MIPS_NONE;
|
||||
}
|
||||
|
||||
relocation_iterator RuntimeDyldELF::processRelocationRef(
|
||||
unsigned SectionID, relocation_iterator RelI, const ObjectFile &O,
|
||||
ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) {
|
||||
@ -1331,17 +1354,35 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
|
||||
addRelocationForSection(RE, SectionID);
|
||||
Section.StubOffset += getMaxStubSize();
|
||||
}
|
||||
} else if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) {
|
||||
int64_t Addend = (Opcode & 0x0000ffff) << 16;
|
||||
RelocationEntry RE(SectionID, Offset, RelType, Addend);
|
||||
PendingRelocs.push_back(std::make_pair(Value, RE));
|
||||
} else if (RelType == ELF::R_MIPS_LO16 || RelType == ELF::R_MIPS_PCLO16) {
|
||||
int64_t Addend = Value.Addend + SignExtend32<16>(Opcode & 0x0000ffff);
|
||||
for (auto I = PendingRelocs.begin(); I != PendingRelocs.end();) {
|
||||
const RelocationValueRef &MatchingValue = I->first;
|
||||
RelocationEntry &Reloc = I->second;
|
||||
if (MatchingValue == Value &&
|
||||
RelType == getMatchingLoRelocation(Reloc.RelType) &&
|
||||
SectionID == Reloc.SectionID) {
|
||||
Reloc.Addend += Addend;
|
||||
if (Value.SymbolName)
|
||||
addRelocationForSymbol(Reloc, Value.SymbolName);
|
||||
else
|
||||
addRelocationForSection(Reloc, Value.SectionID);
|
||||
I = PendingRelocs.erase(I);
|
||||
} else
|
||||
++I;
|
||||
}
|
||||
RelocationEntry RE(SectionID, Offset, RelType, Addend);
|
||||
if (Value.SymbolName)
|
||||
addRelocationForSymbol(RE, Value.SymbolName);
|
||||
else
|
||||
addRelocationForSection(RE, Value.SectionID);
|
||||
} else {
|
||||
// FIXME: Calculate correct addends for R_MIPS_HI16, R_MIPS_LO16,
|
||||
// R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations.
|
||||
if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16)
|
||||
Value.Addend += (Opcode & 0x0000ffff) << 16;
|
||||
else if (RelType == ELF::R_MIPS_LO16)
|
||||
Value.Addend += (Opcode & 0x0000ffff);
|
||||
else if (RelType == ELF::R_MIPS_32)
|
||||
if (RelType == ELF::R_MIPS_32)
|
||||
Value.Addend += Opcode;
|
||||
else if (RelType == ELF::R_MIPS_PCLO16)
|
||||
Value.Addend += SignExtend32<16>((Opcode & 0x0000ffff));
|
||||
else if (RelType == ELF::R_MIPS_PC16)
|
||||
Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
|
||||
else if (RelType == ELF::R_MIPS_PC19_S2)
|
||||
@ -1719,6 +1760,10 @@ RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(unsigned SectionID, uint64_t
|
||||
|
||||
void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
|
||||
ObjSectionToIDMap &SectionMap) {
|
||||
if (IsMipsO32ABI)
|
||||
if (!PendingRelocs.empty())
|
||||
report_fatal_error("Can't find matching LO16 reloc");
|
||||
|
||||
// If necessary, allocate the global offset table
|
||||
if (GOTSectionID != 0) {
|
||||
// Allocate memory for the section
|
||||
|
@ -123,6 +123,10 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
||||
// no particular advanced processing.
|
||||
void processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value);
|
||||
|
||||
// Return matching *LO16 relocation (Mips specific)
|
||||
uint32_t getMatchingLoRelocation(uint32_t RelType,
|
||||
bool IsLocal = false) const;
|
||||
|
||||
// The tentative ID for the GOT section
|
||||
unsigned GOTSectionID;
|
||||
|
||||
@ -138,6 +142,10 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
||||
// A map to avoid duplicate got entries (Mips64 specific)
|
||||
StringMap<uint64_t> GOTSymbolOffsets;
|
||||
|
||||
// *HI16 relocations will be added for resolving when we find matching
|
||||
// *LO16 part. (Mips specific)
|
||||
SmallVector<std::pair<RelocationValueRef, RelocationEntry>, 8> PendingRelocs;
|
||||
|
||||
// When a module is loaded we save the SectionID of the EH frame section
|
||||
// in a table until we receive a request to register all unregistered
|
||||
// EH frame sections with the memory manager.
|
||||
|
@ -1,10 +1,10 @@
|
||||
# RUN: llvm-mc -triple=mipsel-unknown-linux -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_O32.o %s
|
||||
# RUN: llc -mtriple=mipsel-unknown-linux -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_O32.o %S/Inputs/ExternalFunction.ll
|
||||
# RUN: llvm-rtdyld -triple=mipsel-unknown-linux -verify -map-section test_ELF_O32.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32.o,.text=0x10000 -check=%s %T/test_ELF_O32.o %T/test_ELF_ExternalFunction_O32.o
|
||||
# RUN: llvm-rtdyld -triple=mipsel-unknown-linux -verify -map-section test_ELF_O32.o,"<common symbols>"=0x7FF8 -map-section test_ELF_O32.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32.o,.text=0x10000 -check=%s %T/test_ELF_O32.o %T/test_ELF_ExternalFunction_O32.o
|
||||
|
||||
# RUN: llvm-mc -triple=mips-unknown-linux -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_O32.o %s
|
||||
# RUN: llc -mtriple=mips-unknown-linux -relocation-model=pic -filetype=obj -o %/T/test_ELF_ExternalFunction_O32.o %S/Inputs/ExternalFunction.ll
|
||||
# RUN: llvm-rtdyld -triple=mips-unknown-linux -verify -map-section test_ELF_O32.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32.o,.text=0x10000 -check=%s %T/test_ELF_O32.o %T/test_ELF_ExternalFunction_O32.o
|
||||
# RUN: llvm-rtdyld -triple=mips-unknown-linux -verify -map-section test_ELF_O32.o,"<common symbols>"=0x7FF8 -map-section test_ELF_O32.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32.o,.text=0x10000 -check=%s %T/test_ELF_O32.o %T/test_ELF_ExternalFunction_O32.o
|
||||
|
||||
.data
|
||||
# rtdyld-check: *{4}R_MIPS_32 = foo[31:0]
|
||||
@ -52,4 +52,13 @@ R_MIPS_HI16:
|
||||
R_MIPS_LO16:
|
||||
lui $1, %lo(foo)
|
||||
|
||||
# rtdyld-check: decode_operand(R_MIPS_HI16_ADDEND, 1)[15:0] = (var+0x8008)[31:16]
|
||||
R_MIPS_HI16_ADDEND:
|
||||
lui $2, %hi(var+8)
|
||||
|
||||
# rtdyld-check: decode_operand(R_MIPS_LO16_ADDEND, 2)[15:0] = (var+0x8)[15:0]
|
||||
R_MIPS_LO16_ADDEND:
|
||||
lb $2, %lo(var+8)($2)
|
||||
|
||||
.size bar, .-bar
|
||||
.comm var,9,1
|
||||
|
Loading…
x
Reference in New Issue
Block a user