From 1b8d611df7a164ee63abbeecf2fb93ad95d8d11e Mon Sep 17 00:00:00 2001 From: dd86k Date: Wed, 5 Jun 2024 14:35:44 -0400 Subject: [PATCH] object: Move LX to new Object API --- dumper/format/lx.d | 30 +++++++++-------- src/adbg/object/format/lx.d | 67 ++++++++++++++++++++++++++++++++++--- src/adbg/object/server.d | 18 ++++------ 3 files changed, 85 insertions(+), 30 deletions(-) diff --git a/dumper/format/lx.d b/dumper/format/lx.d index 6e1ae684..9d3fcfeb 100644 --- a/dumper/format/lx.d +++ b/dumper/format/lx.d @@ -24,7 +24,9 @@ private: void dump_lx_hdr(adbg_object_t *o) { print_header("Header"); - with (o.i.lx.header) { + lx_header_t* header = adbg_object_lx_header(o); + + with (header) { print_x16("e32_magic", magic, magic == LE_MAGIC ? "LE" : "LX"); print_x8("e32_border", border); print_x8("e32_worder", worder); @@ -96,19 +98,19 @@ void dump_lx_hdr(adbg_object_t *o) { print_u32("winreslen", winreslen); print_x16("device_id", device_id); print_x16("ddk_version", ddk_version); - } else { - print_x8("e32_res[8]", res[8]); - print_x8("e32_res[9]", res[9]); - print_x8("e32_res[10]", res[10]); - print_x8("e32_res[11]", res[11]); - print_x8("e32_res[12]", res[12]); - print_x8("e32_res[13]", res[13]); - print_x8("e32_res[14]", res[14]); - print_x8("e32_res[15]", res[15]); - print_x8("e32_res[16]", res[16]); - print_x8("e32_res[17]", res[17]); - print_x8("e32_res[18]", res[18]); - print_x8("e32_res[19]", res[19]); + return; } + print_x8("e32_res[8]", res[8]); + print_x8("e32_res[9]", res[9]); + print_x8("e32_res[10]", res[10]); + print_x8("e32_res[11]", res[11]); + print_x8("e32_res[12]", res[12]); + print_x8("e32_res[13]", res[13]); + print_x8("e32_res[14]", res[14]); + print_x8("e32_res[15]", res[15]); + print_x8("e32_res[16]", res[16]); + print_x8("e32_res[17]", res[17]); + print_x8("e32_res[18]", res[18]); + print_x8("e32_res[19]", res[19]); } } \ No newline at end of file diff --git a/src/adbg/object/format/lx.d b/src/adbg/object/format/lx.d index 4e24770c..32f47c68 100644 --- a/src/adbg/object/format/lx.d +++ b/src/adbg/object/format/lx.d @@ -11,9 +11,10 @@ module adbg.object.format.lx; import adbg.error; -import adbg.object.server : adbg_object_t, AdbgObject; +import adbg.object.server : adbg_object_t, AdbgObject, adbg_object_read_at; import adbg.machines; import adbg.utils.bit; +import core.stdc.stdlib; // NOTE: LX is mainly 16-bit only and LE mixed 16/32-bit @@ -83,7 +84,7 @@ private enum E32RESBYTES3 = 196 - 176; // lx_header.sizeof // winnt.h:_IMAGE_VXD_HEADER /// LX/LE header -struct lx_header { // NOTE: Names are taken from spec except for its "e32_exe" name +struct lx_header_t { // NOTE: Names are taken from spec except for its "e32_exe" name /// Header magic. "LX" or "LE" ushort magic; /// Byte Ordering. @@ -216,8 +217,10 @@ struct lx_header { // NOTE: Names are taken from spec except for its "e32_exe" n } } } +// Old alias +alias lx_header = lx_header_t; -struct lx_record { +struct lx_record_t { uint size; /// Object virtual size uint addr; /// Base virtual address uint flags; @@ -360,16 +363,70 @@ enum { LX_OSF_TFLAG_ORDINAL_8BIT = 0x80, } -int adbg_object_lx_load(adbg_object_t *o) { +private +struct internal_lx_t { + lx_header_t header; +} + +int adbg_object_lx_load(adbg_object_t *o, uint e_lfanew) { + version (Trace) trace("o=%p", o); o.format = AdbgObject.lx; - o.i.lx.header = cast(lx_header*)o.i.mz.newbase; + o.internal = malloc(internal_lx_t.sizeof); + if (o.internal == null) + return adbg_oops(AdbgError.crt); + if (adbg_object_read_at(o, e_lfanew, o.internal, lx_header_t.sizeof) < 0) + return adbg_errno(); //TODO: Deal with word order return 0; } +void adbg_object_lx_unload(adbg_object_t *o) { + if (o == null) + return; + if (o.internal) free(o.internal); +} + +lx_header_t* adbg_object_lx_header(adbg_object_t *o) { + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.internal == null) { + adbg_oops(AdbgError.uninitiated); + return null; + } + return cast(lx_header_t*)o.internal; +} + +AdbgMachine adbg_object_lx_machine(adbg_object_t *o) { + if (o == null || o.internal == null) + return AdbgMachine.unknown; + lx_header_t* header = cast(lx_header_t*)o.internal; + switch (header.cpu) { + case LX_CPU_80486: + case LX_CPU_80386: return AdbgMachine.i386; + case LX_CPU_80286: return AdbgMachine.i8086; + default: + } + return AdbgMachine.unknown; +} + +const(char)* adbg_object_lx_kind_string(adbg_object_t *o) { + if (o == null) { + adbg_oops(AdbgError.invalidArgument); + return null; + } + if (o.internal == null) { + adbg_oops(AdbgError.uninitiated); + return null; + } + lx_header_t* header = cast(lx_header_t*)o.internal; + return adbg_object_lx_modtype_string(header.mflags); +} + const(char)* adbg_object_lx_cputype_string(ushort cpu) { switch (cpu) { case LX_CPU_80286: return "80286"; diff --git a/src/adbg/object/server.d b/src/adbg/object/server.d index 564ec101..79cc1a5d 100644 --- a/src/adbg/object/server.d +++ b/src/adbg/object/server.d @@ -513,6 +513,7 @@ void adbg_object_close(adbg_object_t *o) { switch (o.format) with (AdbgObject) { case mz: adbg_object_mz_unload(o); break; case ne: adbg_object_ne_unload(o); break; + case lx: adbg_object_lx_unload(o); break; case pe: //TODO: Remove junk with (o.i.pe) { @@ -658,6 +659,7 @@ int adbg_object_loadv(adbg_object_t *o, va_list args) { if (o == null) return adbg_oops(AdbgError.invalidArgument); + o.status = 0; memset(&o.p, 0, o.p.sizeof); // Init object properties memset(&o.i, 0, o.i.sizeof); // Init object internal structures @@ -791,7 +793,7 @@ L_ARG: switch (va_arg!int(args)) { case NE_MAGIC: return adbg_object_ne_load(o, sig.mzheader.e_lfanew); case LX_MAGIC, LE_MAGIC: - return adbg_object_lx_load(o); + return adbg_object_lx_load(o, sig.mzheader.e_lfanew); default: } @@ -832,6 +834,7 @@ L_ARG: switch (va_arg!int(args)) { return adbg_oops(AdbgError.objectUnknownFormat); } +deprecated export void* adbg_object_header(adbg_object_t *o) { if (o == null) { @@ -843,6 +846,7 @@ void* adbg_object_header(adbg_object_t *o) { return o.i.header; } +deprecated adbg_section_t* adbg_object_section_n(adbg_object_t *o, const(char)* name, uint flags = 0) { if (o == null || name == null) { adbg_oops(AdbgError.invalidArgument); @@ -930,14 +934,7 @@ AdbgMachine adbg_object_machine(adbg_object_t *o) { switch (o.format) with (AdbgObject) { case mz: return AdbgMachine.i8086; case ne: return adbg_object_ne_machine(o); - case lx: - switch (o.i.lx.header.cpu) { - case LX_CPU_80286: return AdbgMachine.i8086; - case LX_CPU_80386: - case LX_CPU_80486: return AdbgMachine.i386; - default: - } - break; + case lx: return adbg_object_lx_machine(o); case pe: return adbg_object_pe_machine(o.i.pe.header.Machine); case macho: // NOTE: Both Mach-O headers (regular/fat) match in layout for cputype return adbg_object_macho_machine(o.i.macho.header.cputype); @@ -1040,8 +1037,7 @@ const(char)* adbg_object_kind_string(adbg_object_t *o) { switch (o.format) with (AdbgObject) { case mz: kind = adbg_object_mz_kind_string(o); break; case ne: kind = adbg_object_ne_kind_string(o); break; - case lx: - return adbg_object_lx_modtype_string(o.i.lx.header.mflags); + case lx: kind = adbg_object_lx_kind_string(o); break; case pe: return o.i.pe.header.Characteristics & PE_CHARACTERISTIC_DLL ? `Dynamically Linked Library` : `Executable`; case macho: