summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-04-30 15:40:54 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-04-30 15:40:54 +0000
commite87dadc44b1544c35e13cf48dfe167109929a944 (patch)
treeb5142993e8acc356f130f2e58f4ae1aefdbd8d17
parent1872730c5a0d95ba9d2ed7e1e9607e86c50e9070 (diff)
downloadllvm-e87dadc44b1544c35e13cf48dfe167109929a944.tar.gz
llvm-e87dadc44b1544c35e13cf48dfe167109929a944.tar.bz2
llvm-e87dadc44b1544c35e13cf48dfe167109929a944.tar.xz
Fix Addend computation for non external relocations on Macho.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180790 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Object/MachO.h1
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp38
-rw-r--r--lib/Object/MachOObjectFile.cpp10
-rw-r--r--test/ExecutionEngine/MCJIT/non-extern-addend.ll12
4 files changed, 33 insertions, 28 deletions
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h
index 17a8fc2bff..14cd4d767d 100644
--- a/include/llvm/Object/MachO.h
+++ b/include/llvm/Object/MachO.h
@@ -130,6 +130,7 @@ public:
unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const;
unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const;
unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const;
+ SectionRef getRelocationSection(const macho::RelocationEntry &RE) const;
// Walk load commands.
LoadCommandInfo getFirstLoadCommandInfo() const;
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index 6054b2ab79..b3467a9ab3 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -232,12 +232,12 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
unsigned Size = MachO->getAnyRelocationLength(RE);
uint64_t Offset;
RelI.getOffset(Offset);
- if (isExtern) {
- uint8_t *LocalAddress = Section.Address + Offset;
- unsigned NumBytes = 1 << Size;
- uint64_t Addend = 0;
- memcpy(&Addend, LocalAddress, NumBytes);
+ uint8_t *LocalAddress = Section.Address + Offset;
+ unsigned NumBytes = 1 << Size;
+ uint64_t Addend = 0;
+ memcpy(&Addend, LocalAddress, NumBytes);
+ if (isExtern) {
// Obtain the symbol name which is referenced in the relocation
SymbolRef Symbol;
RelI.getSymbol(Symbol);
@@ -260,29 +260,11 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
}
}
} else {
- error_code err;
- uint8_t sectionIndex = static_cast<uint8_t>(RelType & 0xFF);
- section_iterator si = Obj.begin_sections(),
- se = Obj.end_sections();
- for (uint8_t i = 1; i < sectionIndex; i++) {
- error_code err;
- si.increment(err);
- if (si == se)
- break;
- }
- assert(si != se && "No section containing relocation!");
- Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID);
- Value.Addend = 0;
- // FIXME: The size and type of the relocation determines if we can
- // encode an Addend in the target location itself, and if so, how many
- // bytes we should read in order to get it. We don't yet support doing
- // that, and just assuming it's sizeof(intptr_t) is blatantly wrong.
- //Value.Addend = *(const intptr_t *)Target;
- if (Value.Addend) {
- // The MachO addend is an offset from the current section. We need it
- // to be an offset from the destination section
- Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress;
- }
+ SectionRef Sec = MachO->getRelocationSection(RE);
+ Value.SectionID = findOrEmitSection(Obj, Sec, true, ObjSectionToID);
+ uint64_t Addr;
+ Sec.getAddress(Addr);
+ Value.Addend = Addend - Addr;
}
if (Arch == Triple::arm && (RelType & 0xf) == macho::RIT_ARM_Branch24Bit) {
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index f6840b8c15..dfd8d3d3dd 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -1414,6 +1414,16 @@ MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const {
return getPlainRelocationType(this, RE);
}
+SectionRef
+MachOObjectFile::getRelocationSection(const macho::RelocationEntry &RE) const {
+ if (isRelocationScattered(RE) || getPlainRelocationExternal(RE))
+ return *end_sections();
+ unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1;
+ DataRefImpl DRI;
+ DRI.d.a = SecNum;
+ return SectionRef(DRI, this);
+}
+
MachOObjectFile::LoadCommandInfo
MachOObjectFile::getFirstLoadCommandInfo() const {
MachOObjectFile::LoadCommandInfo Load;
diff --git a/test/ExecutionEngine/MCJIT/non-extern-addend.ll b/test/ExecutionEngine/MCJIT/non-extern-addend.ll
new file mode 100644
index 0000000000..3a6e634412
--- /dev/null
+++ b/test/ExecutionEngine/MCJIT/non-extern-addend.ll
@@ -0,0 +1,12 @@
+; RUN: %lli_mcjit %s > /dev/null
+
+define i32 @foo(i32 %X, i32 %Y, double %A) {
+ %cond212 = fcmp ueq double %A, 2.000000e+00 ; <i1> [#uses=1]
+ %cast110 = zext i1 %cond212 to i32 ; <i32> [#uses=1]
+ ret i32 %cast110
+}
+
+define i32 @main() {
+ %reg212 = call i32 @foo( i32 0, i32 1, double 1.000000e+00 ) ; <i32> [#uses=1]
+ ret i32 %reg212
+}