diff --git a/src/gnu/gnu.c b/src/gnu/gnu.c new file mode 100644 index 00000000..c56091f9 --- /dev/null +++ b/src/gnu/gnu.c @@ -0,0 +1,53 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +internal GNU_LinkMap64 +gnu_linkmap64_from_linkmap32(GNU_LinkMap32 linkmap32) +{ + GNU_LinkMap64 linkmap64 = {0}; + linkmap64.addr_vaddr = linkmap32.addr_vaddr; + linkmap64.name_vaddr = linkmap32.name_vaddr; + linkmap64.ld_vaddr = linkmap32.ld_vaddr; + linkmap64.next_vaddr = linkmap32.next_vaddr; + linkmap64.prev_vaddr = linkmap32.prev_vaddr; + return linkmap64; +} + +internal U64 +gnu_rdebug_info_size_from_arch(Arch arch) +{ + U64 size = 0; + switch (byte_size_from_arch(arch)) { + case 0: break; + case 4: size = sizeof(GNU_RDebugInfo32); break; + case 8: size = sizeof(GNU_RDebugInfo64); break; + default: InvalidPath; break; + } + return size; +} + +internal U64 +gnu_r_brk_offset_from_arch(Arch arch) +{ + U64 offset = 0; + switch (gnu_rdebug_info_size_from_arch(arch)) { + case 0: offset = 0; break; + case sizeof(GNU_RDebugInfo32): offset = OffsetOf(GNU_RDebugInfo32, r_brk); break; + case sizeof(GNU_RDebugInfo64): offset = OffsetOf(GNU_RDebugInfo64, r_brk); break; + default: InvalidPath; break; + } + return offset; +} + +internal GNU_RDebugInfo64 +gnu_rdebug_info64_from_rdebug_info32(GNU_RDebugInfo32 rdebug32) +{ + GNU_RDebugInfo64 result = {0}; + result.r_version = rdebug32.r_version; + result.r_map = rdebug32.r_map; + result.r_brk = rdebug32.r_brk; + result.r_state = rdebug32.r_state; + result.r_ldbase = rdebug32.r_ldbase; + return result; +} + diff --git a/src/gnu/gnu.h b/src/gnu/gnu.h new file mode 100644 index 00000000..679f11c9 --- /dev/null +++ b/src/gnu/gnu.h @@ -0,0 +1,58 @@ +// Copyright (c) Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef GNU_H +#define GNU_H + +typedef struct GNU_LinkMap64 +{ + U64 addr_vaddr; + U64 name_vaddr; + U64 ld_vaddr; // address of the dynamic section + U64 next_vaddr; + U64 prev_vaddr; +} GNU_LinkMap64; + +typedef struct GNU_LinkMap32 +{ + U32 addr_vaddr; + U32 name_vaddr; + U32 ld_vaddr; + U32 next_vaddr; + U32 prev_vaddr; +} GNU_LinkMap32; + +typedef U32 GNU_RT; +enum +{ + GNU_RT_Consistent = 0, + GNU_RT_Add = 1, + GNU_RT_Delete = 2, +}; + +// struct reflects r_debug from /usr/include/link.h +typedef struct GNU_RDebugInfo64 +{ + S32 r_version; // must be greater than 0 + U64 r_map; // address of first loaded object + U64 r_brk; // when module is loared/unloaded DL calls this function + GNU_RT r_state; + U64 r_ldbase; // base addres of dynamic linker +} GNU_RDebugInfo64; + +typedef struct GNU_RDebugInfo32 +{ + S32 r_version; + U32 r_map; + U32 r_brk; + GNU_RT r_state; + U32 r_ldbase; +} GNU_RDebugInfo32; + +//////////////////////////////// + +internal GNU_LinkMap64 elf_linkmap64_from_linkmap32(GNU_LinkMap32 linkmap32); +internal U64 gnu_rdebug_info_size_from_arch(Arch arch); +internal U64 gnu_r_brk_offset_from_arch(Arch arch); + +#endif // GNU_H diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 60693051..a83bd0b6 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -210,6 +210,7 @@ #include "pe/pe.h" #include "elf/elf.h" #include "elf/elf_parse.h" +#include "gnu/gnu.h" #include "codeview/codeview.h" #include "codeview/codeview_parse.h" #include "msf/msf.h" @@ -257,6 +258,7 @@ #include "pe/pe.c" #include "elf/elf.c" #include "elf/elf_parse.c" +#include "gnu/gnu.c" #include "codeview/codeview.c" #include "codeview/codeview_parse.c" #include "msf/msf.c"