summaryrefslogtreecommitdiff
path: root/view/elf/elfview.cpp
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2025-03-03 15:38:27 -0500
committerBrian Potchik <brian@vector35.com>2025-03-03 15:38:27 -0500
commitd9f829e739728a1a155e11cc21c7024ae4f78b21 (patch)
tree8e206531e8bb9eb49aae14413eb9b981ed8655d4 /view/elf/elfview.cpp
parent53c5172d61f6860e5deca9e0482909fb71e367ce (diff)
Perform fixups for MIPS local GOT slots using synthetic relocation entries.
Diffstat (limited to 'view/elf/elfview.cpp')
-rw-r--r--view/elf/elfview.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/view/elf/elfview.cpp b/view/elf/elfview.cpp
index 87e126ee..7caebd95 100644
--- a/view/elf/elfview.cpp
+++ b/view/elf/elfview.cpp
@@ -1128,7 +1128,7 @@ bool ElfView::Init()
}
if (!relocationExists)
{
- int relocType = m_arch->GetAddressSize() == 4 ? 126 /* R_MIPS_COPY */ : 125 /* R_MIPS64_COPY */;
+ int relocType = m_addressSize == 4 ? 126 /* R_MIPS_COPY */ : 125 /* R_MIPS64_COPY */;
relocs.push_back(ELFRelocEntry(gotEntry, i, relocType, 0, 0, false));
}
if (entry.section != ELF_SHN_UNDEF)
@@ -1154,7 +1154,7 @@ bool ElfView::Init()
}
if (!relocationExists)
{
- int relocType = m_arch->GetAddressSize() == 4 ? 127 /*R_MIPS_JUMP_SLOT*/ : 125 /* R_MIPS64_COPY */;
+ int relocType = m_addressSize == 4 ? 127 /*R_MIPS_JUMP_SLOT*/ : 125 /* R_MIPS64_COPY */;
relocs.push_back(ELFRelocEntry(gotEntry, i, relocType, 0, 0, false));
}
if (entry.section != ELF_SHN_UNDEF)
@@ -1703,6 +1703,29 @@ bool ElfView::Init()
AddAutoSection(ss.str(), s.first, s.second, ReadOnlyDataSectionSemantics);
}
}
+
+ // Perform fixup processing on the local GOT entries if the view is relocatable.
+ if (m_relocatable)
+ {
+ uint64_t lastLocalGotEntry = gotStart + (localMipsSyms - 1) * (m_elf32 ? 4 : 8);
+ for (auto gotEntry : m_gotEntryLocations)
+ {
+ if (gotEntry > lastLocalGotEntry)
+ break;
+
+ virtualReader.Seek(gotEntry);
+ auto target = virtualReader.ReadPointer();
+ if (!target)
+ continue;
+
+ BNRelocationInfo relocInfo;
+ memset(&relocInfo, 0, sizeof(BNRelocationInfo));
+ relocInfo.address = gotEntry;
+ relocInfo.size = m_addressSize;
+ relocInfo.nativeType = m_addressSize == 4 ? 127 /*R_MIPS_JUMP_SLOT*/ : 125 /* R_MIPS64_COPY */;
+ DefineRelocation(m_arch, relocInfo, target + baseAddress, relocInfo.address);
+ }
+ }
}
// Sometimes ELF will specify Thumb entry points w/o the bottom bit set
@@ -2398,8 +2421,8 @@ bool ElfView::Init()
memset(&relocInfo, 0, sizeof(BNRelocationInfo));
relocInfo.base = gotStart;
relocInfo.address = gotStart;
- relocInfo.size = m_arch->GetAddressSize();
- relocInfo.nativeType = m_arch->GetAddressSize() == 4 ? 2 /* R_MIPS_32 */ : 18 /* R_MIPS_64 */;
+ relocInfo.size = m_addressSize;
+ relocInfo.nativeType = m_addressSize == 4 ? 2 /* R_MIPS_32 */ : 18 /* R_MIPS_64 */;
DefineRelocation(m_arch, relocInfo, symbol, relocInfo.address);
}