mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
fix(relinker): retain imported ELF symbol types through parsing
This commit is contained in:
1 parent
c0bd62e46e
commit
70329ada1c
5 files changed
+26
-17
No files matched your search
@@ -69,6 +69,7 @@ struct NidReference {
|
||||
std::int64_t Addend;
|
||||
bool Weak = false;
|
||||
bool Function = false;
|
||||
std::uint8_t SymbolType = 0;
|
||||
};
|
||||
|
||||
struct CallSiteInfo {
|
||||
|
||||
@@ -158,7 +158,6 @@ inline constexpr std::uint32_t R_X86_64_IRELATIVE = 37;
|
||||
inline constexpr std::uint8_t STB_GLOBAL = 1;
|
||||
inline constexpr std::uint8_t STB_WEAK = 2;
|
||||
inline constexpr std::uint8_t STT_NOTYPE = 0;
|
||||
inline constexpr std::uint8_t STT_OBJECT = 1;
|
||||
inline constexpr std::uint8_t STT_FUNC = 2;
|
||||
inline constexpr std::uint8_t STT_TLS = 6;
|
||||
inline constexpr std::uint8_t STV_DEFAULT = 0;
|
||||
|
||||
@@ -92,7 +92,7 @@ SysVDynamicSection SysVDynamicSectionBuilder::BuildDynamicSection(
|
||||
if (ref.Nid.empty()) return static_cast<std::uint8_t>((STB_WEAK << 4) | STT_NOTYPE);
|
||||
const bool tls = ref.RelocationTypeValue == R_X86_64_DTPMOD64 || ref.RelocationTypeValue == R_X86_64_DTPOFF64
|
||||
|| ref.RelocationTypeValue == R_X86_64_TPOFF64;
|
||||
const auto type = tls ? STT_TLS : ref.Function ? STT_FUNC : STT_OBJECT;
|
||||
const auto type = tls ? STT_TLS : ref.SymbolType;
|
||||
return static_cast<std::uint8_t>(((ref.Weak ? STB_WEAK : STB_GLOBAL) << 4) | type);
|
||||
};
|
||||
|
||||
|
||||
@@ -369,8 +369,9 @@ RelinkResult RelinkerPipeline::Relink() {
|
||||
[](const std::uint8_t byte) { return byte != 0; })))
|
||||
throw RelinkerException("Unnamed import symbol is not a null symbol entry", symOff);
|
||||
const bool weak = (raw[symOff + 4] >> 4) == STB_WEAK;
|
||||
const bool function = (raw[symOff + 4] & 15) == STT_FUNC;
|
||||
nidRefs.push_back({name, Domain::ImportModule(name, importModules, neededLibraries), relType, pos, rOffset, rAddend, weak, function});
|
||||
const auto symbolType = static_cast<std::uint8_t>(raw[symOff + 4] & 15);
|
||||
const bool function = symbolType == STT_FUNC;
|
||||
nidRefs.push_back({name, Domain::ImportModule(name, importModules, neededLibraries), relType, pos, rOffset, rAddend, weak, function, symbolType});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,25 +7,26 @@ from test_guest_symbol_names import (DYNAMIC, GOT, RELOCATIONS, STRINGS, SYMBOLS
|
||||
string_table, symbol_name)
|
||||
from test_guest_intel_trampolines import main_fixture
|
||||
|
||||
STT_OBJECT = 1
|
||||
STT_FUNC = 2
|
||||
|
||||
|
||||
def importing_executable(imports):
|
||||
def importing_executable(imports, binding=1, relocation_type=6):
|
||||
image = main_fixture()
|
||||
strings, offsets = string_table(name for name, _ in imports)
|
||||
image[STRINGS:STRINGS + len(strings)] = strings
|
||||
for index, (offset, (_, kind)) in enumerate(zip(offsets, imports), 1):
|
||||
struct.pack_into("<IBBHQQ", image, SYMBOLS + index * 24, offset, 0x10 | kind, 0, 0, 0, 0)
|
||||
struct.pack_into("<QQq", image, RELOCATIONS + (index - 1) * 24, GOT + (index - 1) * 8, (index << 32) | 6, 0)
|
||||
tags = [(5, STRINGS), (10, len(strings)), (6, SYMBOLS), (11, 24), (7, RELOCATIONS), (8, len(imports) * 24), (9, 24), (0, 0)]
|
||||
struct.pack_into("<IBBHQQ", image, SYMBOLS + index * 24, offset, (binding << 4) | kind, 0, 0, 0, 0)
|
||||
struct.pack_into("<QQq", image, RELOCATIONS + (index - 1) * 24, GOT + (index - 1) * 8, (index << 32) | relocation_type, 0)
|
||||
tags = [(5, STRINGS), (10, len(strings)), (6, SYMBOLS), (11, 24)]
|
||||
if relocation_type == 7:
|
||||
tags += [(3, GOT), (23, RELOCATIONS), (2, len(imports) * 24), (20, 7)]
|
||||
else:
|
||||
tags += [(7, RELOCATIONS), (8, len(imports) * 24), (9, 24)]
|
||||
tags.append((0, 0))
|
||||
for index, tag in enumerate(tags):
|
||||
struct.pack_into("<qQ", image, DYNAMIC + index * 16, *tag)
|
||||
struct.pack_into("<QQQQQ", image, 120 + 8, DYNAMIC, DYNAMIC, DYNAMIC, len(tags) * 16, len(tags) * 16)
|
||||
return image
|
||||
|
||||
|
||||
def imported_types(image):
|
||||
def imported_symbols(image):
|
||||
tags = dynamic_tags(image)
|
||||
symbols = file_offset(image, tags[6])
|
||||
types = {}
|
||||
@@ -37,16 +38,23 @@ def imported_types(image):
|
||||
info, = struct.unpack_from("<Q", image, position + 8)
|
||||
index = info >> 32
|
||||
if index:
|
||||
types[symbol_name(image, tags, index)] = image[symbols + index * 24 + 4] & 15
|
||||
types[symbol_name(image, tags, index)] = image[symbols + index * 24 + 4]
|
||||
return types
|
||||
|
||||
|
||||
def main():
|
||||
relinker = Path(sys.argv[1]).resolve()
|
||||
with tempfile.TemporaryDirectory(prefix="anyps5-import-types-") as directory:
|
||||
output = relink(relinker, Path(directory), importing_executable([("FFFFFFFFFFF", STT_FUNC), ("DDDDDDDDDDD", STT_OBJECT)]), {})
|
||||
types = imported_types(output.read_bytes())
|
||||
assert types == {"FFFFFFFFFFF": STT_FUNC, "DDDDDDDDDDD": STT_OBJECT}, types
|
||||
for relocation_type in (6, 7):
|
||||
for binding in (1, 2):
|
||||
for kind in range(16):
|
||||
imports = [("FFFFFFFFFFF", 2), ("DDDDDDDDDDD", 1), ("NNNNNNNNNNN", kind)]
|
||||
case = Path(directory) / f"{relocation_type}-{binding}-{kind}"
|
||||
case.mkdir()
|
||||
output = relink(relinker, case, importing_executable(imports, binding, relocation_type), {})
|
||||
symbols = imported_symbols(output.read_bytes())
|
||||
expected = {name: (binding << 4) | symbol_type for name, symbol_type in imports}
|
||||
assert symbols == expected, (relocation_type, binding, kind, symbols, expected)
|
||||
print("Import symbol type tests passed")
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user