From c225cc7f2522ecde251cf735e2753bb5bcf9f956 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 18 Sep 2021 12:06:32 +0200 Subject: [PATCH] Fix R_PPC_REL24 relocations --- src/ElfUtils.cpp | 27 +++++++++------------------ src/common/relocation_defines.h | 16 ++++++++-------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/ElfUtils.cpp b/src/ElfUtils.cpp index b2d82be..310c8b5 100644 --- a/src/ElfUtils.cpp +++ b/src/ElfUtils.cpp @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (C) 2018-2020 Maschell + * Copyright (C) 2018-2021 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,18 +15,10 @@ * along with this program. If not, see . ****************************************************************************/ -#include -#include - -#include +#include #include -#include -#include -#include #include #include "utils/logger.h" - -#include "elfio/elfio.hpp" #include "ElfUtils.h" // See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 @@ -99,12 +91,12 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des // } auto distance = static_cast(value) - static_cast(target); if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) { - if (trampolin_data == NULL) { + if (trampolin_data == nullptr) { DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided"); DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, distance); return false; } else { - relocation_trampolin_entry_t *freeSlot = NULL; + relocation_trampolin_entry_t *freeSlot = nullptr; for (uint32_t i = 0; i < trampolin_data_length; i++) { // We want to override "old" relocations of imports // Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS. @@ -118,14 +110,14 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des break; } } - if (freeSlot != NULL) { + if (freeSlot == nullptr) { DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full"); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, distance); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, target - (uint32_t) &(freeSlot->trampolin[0])); return false; } if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) { DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer)."); - DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, distance); + DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X", value, target, (target - (uint32_t) &(freeSlot->trampolin[0]))); return false; } @@ -140,12 +132,11 @@ bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t des freeSlot->status = RELOC_TRAMP_FIXED; } else { // Relocations for the imports may be overridden - freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS; + freeSlot->status = RELOC_TRAMP_IMPORT_DONE; } - uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]); + auto symbolValue = (uint32_t) &(freeSlot->trampolin[0]); value = symbolValue + addend; distance = static_cast(value) - static_cast(target); - DEBUG_FUNCTION_LINE("Created tramp"); } } diff --git a/src/common/relocation_defines.h b/src/common/relocation_defines.h index 661928f..b7661f1 100644 --- a/src/common/relocation_defines.h +++ b/src/common/relocation_defines.h @@ -16,21 +16,21 @@ ****************************************************************************/ #pragma once -#include +#include typedef enum RelocationTrampolinStatus{ - RELOC_TRAMP_FREE = 0, - RELOC_TRAMP_FIXED = 1, - RELOC_TRAMP_IMPORT_IN_PROGRESS = 2, - RELOC_TRAMP_IMPORT_DONE = 3, + RELOC_TRAMP_FREE = 0, + RELOC_TRAMP_FIXED = 1, + RELOC_TRAMP_IMPORT_IN_PROGRESS = 2, + RELOC_TRAMP_IMPORT_DONE = 3, } RelocationTrampolinStatus; typedef enum RelocationType{ - RELOC_TYPE_FIXED = 0, - RELOC_TYPE_IMPORT = 1 + RELOC_TYPE_FIXED = 0, + RELOC_TYPE_IMPORT = 1 } RelocationType; typedef struct relocation_trampolin_entry_t { uint32_t trampolin[4]; - RelocationTrampolinStatus status = RELOC_TRAMP_FREE; + RelocationTrampolinStatus status; } relocation_trampolin_entry_t;