Skip to content

Commit

Permalink
[mips][mcjit] Calculate correct addend for HI16 and PCHI16 reloc
Browse files Browse the repository at this point in the history
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

llvm-svn: 244897
  • Loading branch information
petar-jovanovic committed Aug 13, 2015
1 parent 25f5185 commit d22164d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 11 deletions.
3 changes: 3 additions & 0 deletions llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
Expand Up @@ -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,
Expand Down
63 changes: 54 additions & 9 deletions llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
Expand Up @@ -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;

Expand All @@ -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.
Expand Down
@@ -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]
Expand Down Expand Up @@ -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

0 comments on commit d22164d

Please sign in to comment.