From bec84f48e8bec60a13883fdd0b65702c58e2576b Mon Sep 17 00:00:00 2001
From: dd86k
Date: Mon, 18 Mar 2024 21:22:15 -0400
Subject: [PATCH] objects: Improve errors
---
src/adbg/error.d | 42 +++--
src/adbg/object/format/ar.d | 17 +-
src/adbg/object/format/elf.d | 73 +++++++--
src/adbg/object/format/lx.d | 50 +++---
src/adbg/object/format/macho.d | 280 ++++++++++++++++-----------------
src/adbg/object/format/mz.d | 20 ++-
src/adbg/object/format/pdb.d | 22 ++-
src/adbg/object/format/pe.d | 273 ++++++++++++++++++++++----------
8 files changed, 485 insertions(+), 292 deletions(-)
diff --git a/src/adbg/error.d b/src/adbg/error.d
index 69431fc7..51a09634 100644
--- a/src/adbg/error.d
+++ b/src/adbg/error.d
@@ -28,6 +28,8 @@ import adbg.include.capstone : csh, cs_errno, cs_strerror;
// adbg_ensure_params(lvalue, "name")
// - returns string if null found
// - automatically set error code
+// adbg_errorn(AdbgError)
+// - returns null
extern (C):
@@ -37,19 +39,24 @@ enum AdbgError {
// 0-99: Generic
//
success = 0,
- invalidArgument = 1,
- emptyArgument = 2,
- uninitiated = 4, // Only when user value is important like for fopen
- invalidOption = 5,
- invalidOptionValue = 6,
+ invalidArgument = 1, /// Argument is null or zero
nullArgument = invalidArgument, // Old alias for invalidArgument
+ emptyArgument = 2, /// Argument contains an empty dataset
+ uninitiated = 4, /// Instance was not initiated
+ invalidOption = 5, /// Invalid option
+ invalidValue = 6, /// Invalid value for option
+ invalidOptionValue = invalidValue,
+ offsetBounds = 7, /// File offset is outside of file size
+ indexBounds = 8, /// Index is outside of bounds of list
+ unavailable = 9, /// Feature or item is unavailable
+ unfindable = 10, /// Item cannot be found in list
//
// 100-199: Debugger
//
- debuggerUnattached = 100,
- debuggerUnpaused = 101,
- debuggerInvalidAction = 102, /// Wrong action from creation method.
- debuggerPresent = 103, /// Debugger already present in remote process
+ debuggerUnattached = 100,
+ debuggerUnpaused = 101,
+ debuggerInvalidAction = 102, /// Wrong action from creation method.
+ debuggerPresent = 103, /// Debugger already present in remote process
// Old meanings
notAttached = debuggerUnattached, /// Old value for debuggerUnattached
notPaused = debuggerUnpaused, /// Old value for debuggerUnpaused
@@ -57,10 +64,10 @@ enum AdbgError {
//
// 200-299: Disasembler
//
- disasmUnsupportedMachine = 202,
- disasmIllegalInstruction = 220,
- disasmEndOfData = 221,
- disasmOpcodeLimit = 221,
+ disasmUnsupportedMachine = 202,
+ disasmIllegalInstruction = 220,
+ disasmEndOfData = 221,
+ disasmOpcodeLimit = 221,
// Old meanings
unsupportedPlatform = disasmUnsupportedMachine,
illegalInstruction = disasmIllegalInstruction,
@@ -80,7 +87,7 @@ enum AdbgError {
objectInvalidEndian = 313,
objectInvalidType = 314,
objectInvalidABI = 315,
- objectOutsideBounds = 320,
+ objectOutsideBounds = offsetBounds,
// Old meanings
unknownObjFormat = objectUnknownFormat,
unsupportedObjFormat = objectUnsupportedFormat,
@@ -130,7 +137,7 @@ private __gshared adbg_error_t error;
//TODO: Strongly consider string, provides .ptr and .length
private struct adbg_error_msg_t {
- uint code;
+ int code;
const(char) *msg;
}
private immutable const(char) *defaultMsg = "Unknown error occured.";
@@ -143,6 +150,10 @@ private immutable adbg_error_msg_t[] errors_msg = [
{ AdbgError.uninitiated, "Object or structure is uninitiated." },
{ AdbgError.invalidOption, "Option unknown." },
{ AdbgError.invalidOptionValue, "Option received invalid value." },
+ { AdbgError.offsetBounds, "File offset outside file size." },
+ { AdbgError.indexBounds, "Index outside of list." },
+ { AdbgError.unavailable, "Feature or item is unavailable." },
+ { AdbgError.unfindable, "Index outside of list." },
//
// Debugger
//
@@ -171,7 +182,6 @@ private immutable adbg_error_msg_t[] errors_msg = [
{ AdbgError.objectInvalidEndian, "Invalid endianess value for object." },
{ AdbgError.objectInvalidType, "Invalid object type." },
{ AdbgError.objectInvalidABI, "Invalid ABI value for object." },
- { AdbgError.objectOutsideBounds, "Access outside file or module bounds." },
//
// Symbols
//
diff --git a/src/adbg/object/format/ar.d b/src/adbg/object/format/ar.d
index 998fa13c..54c48ae7 100644
--- a/src/adbg/object/format/ar.d
+++ b/src/adbg/object/format/ar.d
@@ -106,17 +106,25 @@ int adbg_object_ar_load(adbg_object_t *o) {
return 0;
}
+//TODO: Can this be transformed into functions with _start & _next?
ar_member_header* adbg_object_ar_header(adbg_object_t *o, size_t index) {
- if (o == null)
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
return null;
+ }
version (Trace) trace("index=%zu", index);
ar_member_header *p = cast(ar_member_header*)(o.buffer + ar_file_header.sizeof);
void *max = o.buffer + 0x8000_0000; // 2 GiB limit
for (size_t i; p < max; ++i) {
- if (i == index)
- return p.EndMarker == AR_EOL ? p : null;
+ if (i == index) {
+ if (p.EndMarker != AR_EOL) {
+ adbg_oops(AdbgError.offsetBounds);
+ return null;
+ }
+ return p;
+ }
// Adjust pointer
size_t offset = atoi(p.Size.ptr) + ar_member_header.sizeof;
@@ -130,6 +138,7 @@ ar_member_header* adbg_object_ar_header(adbg_object_t *o, size_t index) {
}
}
+ adbg_oops(AdbgError.unfindable);
return null;
}
@@ -158,7 +167,7 @@ void* adbg_object_ar_data(adbg_object_t *o, ar_member_header *mhdr) {
return null;
}
if (adbg_object_outboundpl(o, p, size)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
return p;
diff --git a/src/adbg/object/format/elf.d b/src/adbg/object/format/elf.d
index a7b28f54..41d4ba31 100644
--- a/src/adbg/object/format/elf.d
+++ b/src/adbg/object/format/elf.d
@@ -416,7 +416,7 @@ enum ELF_SHT_HIPROC = 0x7fffffff; /// Processor specific
enum ELF_SHT_LOUSER = 0x80000000; /// Application specific
enum ELF_SHT_HIUSER = 0xffffffff; /// Application specific
/// This section contains unwind function table entries for stack unwinding
-enum ELF_SHT_X86_64_UNWIND = 0x70000001;
+enum ELF_SHT_X86_64_UNWIND = 0x70000001; // ELF_SHT_LOPROC + 1?
// Section flags
@@ -701,6 +701,7 @@ struct Elf64_Chdr {
//TODO: Move them to some include folder
+// There's adbg.include.linux.user
struct elf_prstatus32_timeval {
uint tv_sec;
@@ -1123,15 +1124,27 @@ int adbg_object_elf_load(adbg_object_t *o) {
}
Elf32_Ehdr* adbg_object_elf_ehdr32(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
// Return as-is, already swapped
return o.i.elf32.ehdr;
}
Elf32_Phdr* adbg_object_elf_phdr32(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.elf32.phdr == null) return null;
- if (index >= o.i.elf32.ehdr.e_phnum) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.elf32.phdr == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
+ if (index >= o.i.elf32.ehdr.e_phnum) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
Elf32_Phdr *phdr = &o.i.elf32.phdr[index];
if (o.p.reversed && o.i.elf32.reversed_phdr[index] == false) {
@@ -1149,9 +1162,18 @@ Elf32_Phdr* adbg_object_elf_phdr32(adbg_object_t *o, size_t index) {
}
Elf32_Shdr* adbg_object_elf_shdr32(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.elf32.shdr == null) return null;
- if (index >= o.i.elf32.ehdr.e_shnum) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.elf32.shdr == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
+ if (index >= o.i.elf32.ehdr.e_shnum) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
Elf32_Shdr *shdr = &o.i.elf32.shdr[index];
if (o.p.reversed && o.i.elf32.reversed_phdr[index] == false) {
@@ -1171,15 +1193,27 @@ Elf32_Shdr* adbg_object_elf_shdr32(adbg_object_t *o, size_t index) {
}
Elf64_Ehdr* adbg_object_elf_ehdr64(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
// Return as-is, already swapped
return o.i.elf64.ehdr;
}
Elf64_Phdr* adbg_object_elf_phdr64(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.elf64.phdr == null) return null;
- if (index >= o.i.elf64.ehdr.e_phnum) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.elf64.phdr == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
+ if (index >= o.i.elf64.ehdr.e_phnum) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
Elf64_Phdr *phdr = &o.i.elf64.phdr[index];
if (o.p.reversed && o.i.elf64.reversed_phdr[index] == false) {
@@ -1197,9 +1231,18 @@ Elf64_Phdr* adbg_object_elf_phdr64(adbg_object_t *o, size_t index) {
}
Elf64_Shdr* adbg_object_elf_shdr64(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.elf64.shdr == null) return null;
- if (index >= o.i.elf64.ehdr.e_shnum) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.elf64.shdr == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
+ if (index >= o.i.elf64.ehdr.e_shnum) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
Elf64_Shdr *shdr = &o.i.elf64.shdr[index];
if (o.p.reversed && o.i.elf64.reversed_phdr[index] == false) {
diff --git a/src/adbg/object/format/lx.d b/src/adbg/object/format/lx.d
index a968ca30..a4956f7c 100644
--- a/src/adbg/object/format/lx.d
+++ b/src/adbg/object/format/lx.d
@@ -267,35 +267,35 @@ enum {
}
struct lx_flat_bundle_prefix {
- ubyte b32_cnt;
- ubyte b32_type;
- ushort b32_obj;
+ ubyte b32_cnt;
+ ubyte b32_type;
+ ushort b32_obj;
}
struct flat_null_prefix {
- ubyte b32_cnt;
- ubyte b32_type;
+ ubyte b32_cnt;
+ ubyte b32_type;
}
/* values for the b32_type field */
alias bundle_types = int;
enum {
- FLT_BNDL_EMPTY = 0,
- FLT_BNDL_ENTRY16,
- FLT_BNDL_GATE16,
- FLT_BNDL_ENTRY32,
- FLT_BNDL_ENTRYFWD
+ FLT_BNDL_EMPTY = 0,
+ FLT_BNDL_ENTRY16,
+ FLT_BNDL_GATE16,
+ FLT_BNDL_ENTRY32,
+ FLT_BNDL_ENTRYFWD
}
struct lx_flat_bundle_entry32 {
- ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
- uint e32_offset;
+ ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
+ uint e32_offset;
}
struct lx_flat_bundle_gate16 {
- ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
- ushort offset;
- ushort callgate;
+ ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
+ ushort offset;
+ ushort callgate;
}
/*
@@ -303,22 +303,22 @@ struct lx_flat_bundle_gate16 {
*/
struct lx_flat_bundle_entry16 {
- ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
- ushort e32_offset;
+ ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
+ ushort e32_offset;
}
struct lx_flat_bundle_entryfwd {
- ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
- ushort modord;
- uint value;
+ ubyte e32_flags; /* flag bits are same as in OS/2 1.x */
+ ushort modord;
+ uint value;
}
struct lx_flat_res_table {
- ushort type_id;
- ushort name_id;
- uint res_size;
- ushort object;
- uint offset;
+ ushort type_id;
+ ushort name_id;
+ uint res_size;
+ ushort object;
+ uint offset;
}
/* fixup record source flags */
diff --git a/src/adbg/object/format/macho.d b/src/adbg/object/format/macho.d
index fe8e9d26..4842192e 100644
--- a/src/adbg/object/format/macho.d
+++ b/src/adbg/object/format/macho.d
@@ -60,59 +60,59 @@ struct macho_load_command {
alias int vm_prot_t;
struct macho_segment_command { /* for 32-bit architectures */
- uint cmd; /// LC_SEGMENT
- uint cmdsize; /// includes sizeof section structs
- char[16] segname; /// segment name
- uint vmaddr; /// memory address of this segment
- uint vmsize; /// memory size of this segment
- uint fileoff; /// file offset of this segment
- uint filesize; /// amount to map from the file
- vm_prot_t maxprot; /// maximum VM protection
- vm_prot_t initprot; /// initial VM protection
- uint nsects; /// number of sections in segment
- uint flags; /// flags
+ uint cmd; /// LC_SEGMENT
+ uint cmdsize; /// includes sizeof section structs
+ char[16] segname; /// segment name
+ uint vmaddr; /// memory address of this segment
+ uint vmsize; /// memory size of this segment
+ uint fileoff; /// file offset of this segment
+ uint filesize; /// amount to map from the file
+ vm_prot_t maxprot; /// maximum VM protection
+ vm_prot_t initprot; /// initial VM protection
+ uint nsects; /// number of sections in segment
+ uint flags; /// flags
}
struct macho_segment_command_64 { /* for 64-bit architectures */
- uint cmd; /// LC_SEGMENT_64
- uint cmdsize; /// includes sizeof section_64 structs
- char[16] segname; /// segment name
- ulong vmaddr; /// memory address of this segment
- ulong vmsize; /// memory size of this segment
- ulong fileoff; /// file offset of this segment
- ulong filesize; /// amount to map from the file
- vm_prot_t maxprot; /// maximum VM protection
- vm_prot_t initprot; /// initial VM protection
- uint nsects; /// number of sections in segment
- uint flags; /// flags
+ uint cmd; /// LC_SEGMENT_64
+ uint cmdsize; /// includes sizeof section_64 structs
+ char[16] segname; /// segment name
+ ulong vmaddr; /// memory address of this segment
+ ulong vmsize; /// memory size of this segment
+ ulong fileoff; /// file offset of this segment
+ ulong filesize; /// amount to map from the file
+ vm_prot_t maxprot; /// maximum VM protection
+ vm_prot_t initprot; /// initial VM protection
+ uint nsects; /// number of sections in segment
+ uint flags; /// flags
}
alias cpu_type_t = int;
enum {
- MACHO_CPUTYPE_ANY = -1,
+ MACHO_CPUTYPE_ANY = -1,
/// Used as a bitmask to mark cputype as 64-bit
- MACHO_CPUTYPE_ABI64 = 0x1000000,
- MACHO_CPUTYPE_VAX = 1,
- MACHO_CPUTYPE_ROMP = 2,
- MACHO_CPUTYPE_NS32032 = 4,
- MACHO_CPUTYPE_NS32332 = 5,
- MACHO_CPUTYPE_MC680x0 = 6,
- MACHO_CPUTYPE_I386 = 7,
- MACHO_CPUTYPE_X86_64 = MACHO_CPUTYPE_I386 | MACHO_CPUTYPE_ABI64,
- MACHO_CPUTYPE_MIPS = 8,
- MACHO_CPUTYPE_NS32532 = 9,
- MACHO_CPUTYPE_HPPA = 11,
- MACHO_CPUTYPE_ARM = 12,
- MACHO_CPUTYPE_ARM64 = MACHO_CPUTYPE_ARM | MACHO_CPUTYPE_ABI64,
- MACHO_CPUTYPE_MC88000 = 13,
- MACHO_CPUTYPE_SPARC = 14,
- MACHO_CPUTYPE_I860 = 15, // big-endian
- MACHO_CPUTYPE_I860_LITTLE = 16, // little-endian
- MACHO_CPUTYPE_RS6000 = 17,
- MACHO_CPUTYPE_MC98000 = 18,
- MACHO_CPUTYPE_POWERPC = 18,
- MACHO_CPUTYPE_POWERPC64 = MACHO_CPUTYPE_POWERPC | MACHO_CPUTYPE_ABI64,
- MACHO_CPUTYPE_VEO = 255
+ MACHO_CPUTYPE_ABI64 = 0x100_0000,
+ MACHO_CPUTYPE_VAX = 1,
+ MACHO_CPUTYPE_ROMP = 2,
+ MACHO_CPUTYPE_NS32032 = 4,
+ MACHO_CPUTYPE_NS32332 = 5,
+ MACHO_CPUTYPE_MC680x0 = 6,
+ MACHO_CPUTYPE_I386 = 7,
+ MACHO_CPUTYPE_X86_64 = MACHO_CPUTYPE_I386 | MACHO_CPUTYPE_ABI64,
+ MACHO_CPUTYPE_MIPS = 8,
+ MACHO_CPUTYPE_NS32532 = 9,
+ MACHO_CPUTYPE_HPPA = 11,
+ MACHO_CPUTYPE_ARM = 12,
+ MACHO_CPUTYPE_ARM64 = MACHO_CPUTYPE_ARM | MACHO_CPUTYPE_ABI64,
+ MACHO_CPUTYPE_MC88000 = 13,
+ MACHO_CPUTYPE_SPARC = 14,
+ MACHO_CPUTYPE_I860 = 15, // big-endian
+ MACHO_CPUTYPE_I860_LITTLE = 16, // little-endian
+ MACHO_CPUTYPE_RS6000 = 17,
+ MACHO_CPUTYPE_MC98000 = 18,
+ MACHO_CPUTYPE_POWERPC = 18,
+ MACHO_CPUTYPE_POWERPC64 = MACHO_CPUTYPE_POWERPC | MACHO_CPUTYPE_ABI64,
+ MACHO_CPUTYPE_VEO = 255
}
// =============================
@@ -121,37 +121,37 @@ enum {
// VAX subtypes
enum { // SUBTYPE_VAX
- MACHO_SUBTYPE_VAX_ALL = 0,
- MACHO_SUBTYPE_VAX780 = 1,
- MACHO_SUBTYPE_VAX785 = 2,
- MACHO_SUBTYPE_VAX750 = 3,
- MACHO_SUBTYPE_VAX730 = 4,
- MACHO_SUBTYPE_UVAXI = 5,
- MACHO_SUBTYPE_UVAXII = 6,
- MACHO_SUBTYPE_VAX8200 = 7,
- MACHO_SUBTYPE_VAX8500 = 8,
- MACHO_SUBTYPE_VAX8600 = 9,
- MACHO_SUBTYPE_VAX8650 = 10,
- MACHO_SUBTYPE_VAX8800 = 11,
- MACHO_SUBTYPE_UVAXIII = 12
+ MACHO_SUBTYPE_VAX_ALL = 0,
+ MACHO_SUBTYPE_VAX780 = 1,
+ MACHO_SUBTYPE_VAX785 = 2,
+ MACHO_SUBTYPE_VAX750 = 3,
+ MACHO_SUBTYPE_VAX730 = 4,
+ MACHO_SUBTYPE_UVAXI = 5,
+ MACHO_SUBTYPE_UVAXII = 6,
+ MACHO_SUBTYPE_VAX8200 = 7,
+ MACHO_SUBTYPE_VAX8500 = 8,
+ MACHO_SUBTYPE_VAX8600 = 9,
+ MACHO_SUBTYPE_VAX8650 = 10,
+ MACHO_SUBTYPE_VAX8800 = 11,
+ MACHO_SUBTYPE_UVAXIII = 12
}
// ROMP subtypes
enum { // SUBTYPE_ROMP
- MACHO_SUBTYPE_RT_ALL = 0,
- MACHO_SUBTYPE_RT_PC = 1,
- MACHO_SUBTYPE_RT_APC = 2,
- MACHO_SUBTYPE_RT_135 = 3
+ MACHO_SUBTYPE_RT_ALL = 0,
+ MACHO_SUBTYPE_RT_PC = 1,
+ MACHO_SUBTYPE_RT_APC = 2,
+ MACHO_SUBTYPE_RT_135 = 3
}
// 32032/32332/32532 subtypes
enum { // SUBTYPE_32032
- MACHO_SUBTYPE_MMAX_ALL = 0,
- MACHO_SUBTYPE_MMAX_DPC = 1, /* 032 CPU */
- MACHO_SUBTYPE_SQT = 2,
- MACHO_SUBTYPE_MMAX_APC_FPU = 3, /* 32081 FPU */
- MACHO_SUBTYPE_MMAX_APC_FPA = 4, /* Weitek FPA */
- MACHO_SUBTYPE_MMAX_XPC = 5, /* 532 CPU */
+ MACHO_SUBTYPE_MMAX_ALL = 0,
+ MACHO_SUBTYPE_MMAX_DPC = 1, /* 032 CPU */
+ MACHO_SUBTYPE_SQT = 2,
+ MACHO_SUBTYPE_MMAX_APC_FPU = 3, /* 32081 FPU */
+ MACHO_SUBTYPE_MMAX_APC_FPA = 4, /* Weitek FPA */
+ MACHO_SUBTYPE_MMAX_XPC = 5, /* 532 CPU */
}
private
@@ -161,95 +161,95 @@ template SUBTYPE_INTEL(short f, short m) {
// x86 subtypes
enum { // SUBTYPE_I386
- MACHO_SUBTYPE_I386_ALL = 3,
- MACHO_SUBTYPE_X86_64_ALL = MACHO_SUBTYPE_I386_ALL,
- MACHO_SUBTYPE_i386 = 3,
- MACHO_SUBTYPE_i486 = 4,
- MACHO_SUBTYPE_i486SX = 4 + 128, // "4 + 128"
- MACHO_SUBTYPE_i586 = 5,
- MACHO_SUBTYPE_PENT = SUBTYPE_INTEL!(5, 0),
- MACHO_SUBTYPE_PENPRO = SUBTYPE_INTEL!(6, 1),
- MACHO_SUBTYPE_PENTII_M3 = SUBTYPE_INTEL!(6, 3),
- MACHO_SUBTYPE_PENTII_M5 = SUBTYPE_INTEL!(6, 5),
- MACHO_SUBTYPE_PENTIUM_4 = SUBTYPE_INTEL!(10, 0),
+ MACHO_SUBTYPE_I386_ALL = 3,
+ MACHO_SUBTYPE_X86_64_ALL = MACHO_SUBTYPE_I386_ALL,
+ MACHO_SUBTYPE_i386 = 3,
+ MACHO_SUBTYPE_i486 = 4,
+ MACHO_SUBTYPE_i486SX = 4 + 128, // "4 + 128"
+ MACHO_SUBTYPE_i586 = 5,
+ MACHO_SUBTYPE_PENT = SUBTYPE_INTEL!(5, 0),
+ MACHO_SUBTYPE_PENPRO = SUBTYPE_INTEL!(6, 1),
+ MACHO_SUBTYPE_PENTII_M3 = SUBTYPE_INTEL!(6, 3),
+ MACHO_SUBTYPE_PENTII_M5 = SUBTYPE_INTEL!(6, 5),
+ MACHO_SUBTYPE_PENTIUM_4 = SUBTYPE_INTEL!(10, 0),
}
// MIPS subty
enum { // SUBTYPE_MIPS
- MACHO_SUBTYPE_MIPS_ALL = 0,
- MACHO_SUBTYPE_R2300 = 1,
- MACHO_SUBTYPE_R2600 = 2,
- MACHO_SUBTYPE_R2800 = 3,
- MACHO_SUBTYPE_R2800a = 4
+ MACHO_SUBTYPE_MIPS_ALL = 0,
+ MACHO_SUBTYPE_R2300 = 1,
+ MACHO_SUBTYPE_R2600 = 2,
+ MACHO_SUBTYPE_R2800 = 3,
+ MACHO_SUBTYPE_R2800a = 4
}
// 680x0 subtypes (m68k)
enum { // SUBTYPE_680x0
- MACHO_SUBTYPE_MC680x0_ALL = 1,
- MACHO_SUBTYPE_MC68030 = 1,
- MACHO_SUBTYPE_MC68040 = 2,
- MACHO_SUBTYPE_MC68030_ONLY = 3,
+ MACHO_SUBTYPE_MC680x0_ALL = 1,
+ MACHO_SUBTYPE_MC68030 = 1,
+ MACHO_SUBTYPE_MC68040 = 2,
+ MACHO_SUBTYPE_MC68030_ONLY = 3,
}
// HPPA subtypes
enum { // SUBTYPE_HPPA
- MACHO_SUBTYPE_HPPA7100 = 0,
- MACHO_SUBTYPE_HPPA7100LC = 1,
- MACHO_SUBTYPE_HPPA_ALL = 0,
+ MACHO_SUBTYPE_HPPA7100 = 0,
+ MACHO_SUBTYPE_HPPA7100LC = 1,
+ MACHO_SUBTYPE_HPPA_ALL = 0,
}
// Acorn subtypes
enum { // SUBTYPE_ARM
- MACHO_SUBTYPE_ACORN_ALL = 0,
- MACHO_SUBTYPE_A500_ARCH = 1,
- MACHO_SUBTYPE_A500 = 2,
- MACHO_SUBTYPE_A440 = 3,
- MACHO_SUBTYPE_M4 = 4,
- MACHO_SUBTYPE_V4T = 5,
- MACHO_SUBTYPE_V6 = 6,
- MACHO_SUBTYPE_V5TEJ = 7,
- MACHO_SUBTYPE_XSCALE = 8,
- MACHO_SUBTYPE_V7 = 9,
- MACHO_SUBTYPE_V8 = 13,
+ MACHO_SUBTYPE_ACORN_ALL = 0,
+ MACHO_SUBTYPE_A500_ARCH = 1,
+ MACHO_SUBTYPE_A500 = 2,
+ MACHO_SUBTYPE_A440 = 3,
+ MACHO_SUBTYPE_M4 = 4,
+ MACHO_SUBTYPE_V4T = 5,
+ MACHO_SUBTYPE_V6 = 6,
+ MACHO_SUBTYPE_V5TEJ = 7,
+ MACHO_SUBTYPE_XSCALE = 8,
+ MACHO_SUBTYPE_V7 = 9,
+ MACHO_SUBTYPE_V8 = 13,
}
// MC88000 subtypes
enum { // SUBTYPE_MC88000
- MACHO_SUBTYPE_MC88000_ALL = 0,
- MACHO_SUBTYPE_MMAX_JPC = 1,
- MACHO_SUBTYPE_MC88100 = 1,
- MACHO_SUBTYPE_MC88110 = 2,
+ MACHO_SUBTYPE_MC88000_ALL = 0,
+ MACHO_SUBTYPE_MMAX_JPC = 1,
+ MACHO_SUBTYPE_MC88100 = 1,
+ MACHO_SUBTYPE_MC88110 = 2,
}
// MC98000 (PowerPC) subtypes
enum { // SUBTYPE_MC98000
- MACHO_SUBTYPE_MC98000_ALL = 0,
- MACHO_SUBTYPE_MC98601 = 1,
+ MACHO_SUBTYPE_MC98000_ALL = 0,
+ MACHO_SUBTYPE_MC98601 = 1,
}
// I860 subtypes
enum { // SUBTYPE_I860
- MACHO_SUBTYPE_I860_ALL = 0,
- MACHO_SUBTYPE_I860 = 1,
+ MACHO_SUBTYPE_I860_ALL = 0,
+ MACHO_SUBTYPE_I860 = 1,
}
// I860_LITTLE subtypes
enum { // SUBTYPE_I860_LITTLE
- MACHO_SUBTYPE_I860_LITTLE_ALL = 0,
- MACHO_SUBTYPE_I860_LITTLE = 1
+ MACHO_SUBTYPE_I860_LITTLE_ALL = 0,
+ MACHO_SUBTYPE_I860_LITTLE = 1
}
// RS6000 subtypes
enum { // SUBTYPE_RS6000
- MACHO_SUBTYPE_RS6000_ALL = 0,
- MACHO_SUBTYPE_RS6000 = 1,
+ MACHO_SUBTYPE_RS6000_ALL = 0,
+ MACHO_SUBTYPE_RS6000 = 1,
}
// Sun4 subtypes (port done at CMU (?))
enum { // SUBTYPE_Sun4
- MACHO_SUBTYPE_SUN4_ALL = 0,
- MACHO_SUBTYPE_SUN4_260 = 1,
- MACHO_SUBTYPE_SUN4_110 = 2,
+ MACHO_SUBTYPE_SUN4_ALL = 0,
+ MACHO_SUBTYPE_SUN4_260 = 1,
+ MACHO_SUBTYPE_SUN4_110 = 2,
}
// SPARC subtypes
@@ -259,27 +259,27 @@ enum { // SUBTYPE_Sun4
// PowerPC subtypes
enum { // SUBTYPE_PowerPC
- MACHO_SUBTYPE_POWERPC_ALL = 0,
- MACHO_SUBTYPE_POWERPC_601 = 1,
- MACHO_SUBTYPE_POWERPC_602 = 2,
- MACHO_SUBTYPE_POWERPC_603 = 3,
- MACHO_SUBTYPE_POWERPC_603e = 4,
- MACHO_SUBTYPE_POWERPC_603ev = 5,
- MACHO_SUBTYPE_POWERPC_604 = 6,
- MACHO_SUBTYPE_POWERPC_604e = 7,
- MACHO_SUBTYPE_POWERPC_620 = 8,
- MACHO_SUBTYPE_POWERPC_750 = 9,
- MACHO_SUBTYPE_POWERPC_7400 = 10,
- MACHO_SUBTYPE_POWERPC_7450 = 11,
- MACHO_SUBTYPE_POWERPC_970 = 100,
+ MACHO_SUBTYPE_POWERPC_ALL = 0,
+ MACHO_SUBTYPE_POWERPC_601 = 1,
+ MACHO_SUBTYPE_POWERPC_602 = 2,
+ MACHO_SUBTYPE_POWERPC_603 = 3,
+ MACHO_SUBTYPE_POWERPC_603e = 4,
+ MACHO_SUBTYPE_POWERPC_603ev = 5,
+ MACHO_SUBTYPE_POWERPC_604 = 6,
+ MACHO_SUBTYPE_POWERPC_604e = 7,
+ MACHO_SUBTYPE_POWERPC_620 = 8,
+ MACHO_SUBTYPE_POWERPC_750 = 9,
+ MACHO_SUBTYPE_POWERPC_7400 = 10,
+ MACHO_SUBTYPE_POWERPC_7450 = 11,
+ MACHO_SUBTYPE_POWERPC_970 = 100,
}
// VEO subtypes
enum { // SUBTYPE_VEO
- MACHO_SUBTYPE_VEO_1 = 1,
- MACHO_SUBTYPE_VEO_2 = 2,
- MACHO_SUBTYPE_VEO_3 = 3,
- MACHO_SUBTYPE_VEO_4 = 4,
+ MACHO_SUBTYPE_VEO_1 = 1,
+ MACHO_SUBTYPE_VEO_2 = 2,
+ MACHO_SUBTYPE_VEO_3 = 3,
+ MACHO_SUBTYPE_VEO_4 = 4,
//VEO_ALL = VEO_2,
}
@@ -488,15 +488,15 @@ macho_fat_arch* adbg_object_macho_fat_arch(adbg_object_t *o, size_t index) {
return null; // not loaded
}
if (o.i.macho.fat == false) {
- adbg_oops(AdbgError.invalidArgument);
+ adbg_oops(AdbgError.unavailable);
return null;
}
if (index >= LIMIT_FAT_ARCH) {
- adbg_oops(AdbgError.objectMalformed);
+ adbg_oops(AdbgError.indexBounds);
return null;
}
if (index >= o.i.macho.fat_header.nfat_arch) {
- adbg_oops(AdbgError.objectMalformed);
+ adbg_oops(AdbgError.indexBounds);
return null;
}
@@ -525,15 +525,15 @@ macho_load_command* adbg_object_macho_load_command(adbg_object_t *o, size_t inde
return null; // not loaded
}
if (o.i.macho.fat) {
- adbg_oops(AdbgError.invalidArgument);
+ adbg_oops(AdbgError.unavailable);
return null;
}
if (index >= LIMIT_COMMANDS) {
- adbg_oops(AdbgError.objectMalformed);
+ adbg_oops(AdbgError.indexBounds);
return null;
}
if (index >= o.i.macho.header.ncmds) {
- adbg_oops(AdbgError.objectMalformed);
+ adbg_oops(AdbgError.indexBounds);
return null;
}
diff --git a/src/adbg/object/format/mz.d b/src/adbg/object/format/mz.d
index 94d9fc22..2cb21121 100644
--- a/src/adbg/object/format/mz.d
+++ b/src/adbg/object/format/mz.d
@@ -112,14 +112,26 @@ int adbg_object_mz_load(adbg_object_t *o) {
}
mz_hdr* adbg_object_mz_header(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
return o.i.mz.header;
}
mz_reloc* adbg_object_mz_reloc(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.mz.relocs == null) return null; // no relocations available
- if (index >= o.i.mz.header.e_crlc) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.mz.relocs == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null; // no relocations available
+ }
+ if (index >= o.i.mz.header.e_crlc) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
mz_reloc *reloc = &o.i.mz.relocs[index];
if (o.p.reversed && o.i.mz.reversed_relocs[index] == false) {
diff --git a/src/adbg/object/format/pdb.d b/src/adbg/object/format/pdb.d
index 31de337c..ebc353b5 100644
--- a/src/adbg/object/format/pdb.d
+++ b/src/adbg/object/format/pdb.d
@@ -462,7 +462,7 @@ int adbg_object_pdb70_load(adbg_object_t *o, size_t offset = 0) {
uint *dirblk = void;
if (adbg_object_offsetl(o, cast(void**)&dirblk, diroff, header.PageSize)) {
free(dir);
- return adbg_oops(AdbgError.assertion);
+ return adbg_oops(AdbgError.offsetBounds);
}
// Load stream directory blocks into the memory buffer
@@ -472,7 +472,7 @@ int adbg_object_pdb70_load(adbg_object_t *o, size_t offset = 0) {
void *block = void;
if (adbg_object_offsetl(o, &block, blockoff, header.PageSize)) {
free(dir);
- return adbg_oops(AdbgError.assertion);
+ return adbg_oops(AdbgError.offsetBounds);
}
memcpy(dir + (dirblkidx * header.PageSize), block, header.PageSize);
@@ -538,20 +538,26 @@ bool adbg_object_pdb70_block_free(adbg_object_t *o, uint num) {
}
ubyte* adbg_object_pdb70_get_block(adbg_object_t *o, uint num) {
- if (o == null)
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
return null;
+ }
pdb70_file_header *header = o.i.pdb70.header;
// Check with selected FPM if block is allocated
- if (adbg_object_pdb70_block_free(o, num))
+ if (adbg_object_pdb70_block_free(o, num)) {
+ adbg_oops(AdbgError.unavailable);
return null;
+ }
// Get block
ubyte *block = void;
if (adbg_object_offsetl(o, cast(void**)&block,
- num * header.PageSize, header.PageSize))
+ num * header.PageSize, header.PageSize)) {
+ adbg_oops(AdbgError.offsetBounds);
return null;
+ }
return block;
}
@@ -590,7 +596,7 @@ int adbg_object_pdb70_stream_open(adbg_object_t *o, void **ubuffer, uint *usize,
if (adbg_object_offsetl(o, &block, fileoff, readsz)) {
free(sbuffer);
*ubuffer = null;
- return adbg_oops(AdbgError.assertion);
+ return adbg_oops(AdbgError.offsetBounds);
}
// Adjust read size on last block
@@ -605,8 +611,10 @@ int adbg_object_pdb70_stream_open(adbg_object_t *o, void **ubuffer, uint *usize,
return 0;
}
void adbg_object_pdb70_stream_close(adbg_object_t *o, void **ubuffer) {
- if (o == null || ubuffer == null)
+ if (o == null || ubuffer == null) {
+ adbg_oops(AdbgError.invalidArgument);
return;
+ }
if (*ubuffer) {
free(*ubuffer);
diff --git a/src/adbg/object/format/pe.d b/src/adbg/object/format/pe.d
index f7fce01e..2107fd69 100644
--- a/src/adbg/object/format/pe.d
+++ b/src/adbg/object/format/pe.d
@@ -893,32 +893,33 @@ int adbg_object_pe_load(adbg_object_t *o) {
Reserved.size = adbg_bswap32(Reserved.size);
}
- if (o.p.reversed) {
- if (o.i.pe.header.NumberOfSections) {
- o.i.pe.reversed_sections = cast(bool*)
- calloc(o.i.pe.header.NumberOfSections, bool.sizeof);
- if (o.i.pe.reversed_sections == null)
- return adbg_oops(AdbgError.crt);
- }
- with (o.i.pe.directory.ExportTable) if (size && rva) {
- size_t count = size / PE_EXPORT_DESCRIPTOR.sizeof;
- o.i.pe.reversed_dir_exports = false;
- o.i.pe.reversed_dir_export_entries = cast(bool*)calloc(count, bool.sizeof);
- if (o.i.pe.reversed_dir_export_entries == null)
- return adbg_oops(AdbgError.crt);
- }
- with (o.i.pe.directory.ImportTable) if (size && rva) {
- size_t count = size / PE_IMPORT_DESCRIPTOR.sizeof;
- o.i.pe.reversed_dir_imports = cast(bool*)calloc(count, bool.sizeof);
- if (o.i.pe.reversed_dir_imports == null)
- return adbg_oops(AdbgError.crt);
- }
- with (o.i.pe.directory.DebugDirectory) if (size && rva) {
- size_t count = size / PE_DEBUG_DIRECTORY.sizeof;
- o.i.pe.reversed_dir_debug = cast(bool*)calloc(count, bool.sizeof);
- if (o.i.pe.reversed_dir_debug == null)
- return adbg_oops(AdbgError.crt);
- }
+ if (o.p.reversed == false)
+ return 0;
+
+ if (o.i.pe.header.NumberOfSections) {
+ o.i.pe.reversed_sections = cast(bool*)
+ calloc(o.i.pe.header.NumberOfSections, bool.sizeof);
+ if (o.i.pe.reversed_sections == null)
+ return adbg_oops(AdbgError.crt);
+ }
+ with (o.i.pe.directory.ExportTable) if (size && rva) {
+ size_t count = size / PE_EXPORT_DESCRIPTOR.sizeof;
+ o.i.pe.reversed_dir_exports = false;
+ o.i.pe.reversed_dir_export_entries = cast(bool*)calloc(count, bool.sizeof);
+ if (o.i.pe.reversed_dir_export_entries == null)
+ return adbg_oops(AdbgError.crt);
+ }
+ with (o.i.pe.directory.ImportTable) if (size && rva) {
+ size_t count = size / PE_IMPORT_DESCRIPTOR.sizeof;
+ o.i.pe.reversed_dir_imports = cast(bool*)calloc(count, bool.sizeof);
+ if (o.i.pe.reversed_dir_imports == null)
+ return adbg_oops(AdbgError.crt);
+ }
+ with (o.i.pe.directory.DebugDirectory) if (size && rva) {
+ size_t count = size / PE_DEBUG_DIRECTORY.sizeof;
+ o.i.pe.reversed_dir_debug = cast(bool*)calloc(count, bool.sizeof);
+ if (o.i.pe.reversed_dir_debug == null)
+ return adbg_oops(AdbgError.crt);
}
return 0;
@@ -929,7 +930,10 @@ int adbg_object_pe_load(adbg_object_t *o) {
// maps rva to section if found
void* adbg_object_pe_locate(adbg_object_t *o, uint rva) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
uint sections = o.i.pe.header.NumberOfSections;
for (uint si; si < sections; ++si) {
@@ -944,43 +948,68 @@ void* adbg_object_pe_locate(adbg_object_t *o, uint rva) {
void* a = o.buffer + (s.PointerToRawData + (rva - va));
if (adbg_object_outboundp(o, a)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
return a;
}
version (Trace) trace("null");
+ adbg_oops(AdbgError.unfindable);
return null;
}
PE_HEADER* adbg_object_pe_header(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
return o.i.pe.header;
}
PE_OPTIONAL_HEADER* adbg_object_pe_optheader(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
return o.i.pe.opt_header;
}
PE_OPTIONAL_HEADER64* adbg_object_pe_optheader64(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
return o.i.pe.opt_header64;
}
PE_OPTIONAL_HEADERROM* adbg_object_pe_optheaderrom(adbg_object_t *o) {
- if (o == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
return o.i.pe.opt_headerrom;
}
PE_SECTION_ENTRY* adbg_object_pe_section(adbg_object_t *o, size_t index) {
version (Trace) trace("o=%p index=%u", o, cast(uint)index);
- if (o == null) return null;
- if (o.i.pe.sections == null) return null;
- if (index > MAXIMUM_SECTIONS) return null;
- if (index >= o.i.pe.header.NumberOfSections) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.sections == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
+ if (index >= MAXIMUM_SECTIONS) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
+ if (index >= o.i.pe.header.NumberOfSections) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
PE_SECTION_ENTRY *section = &o.i.pe.sections[index];
if (o.p.reversed && o.i.pe.reversed_sections[index] == false) with (section) {
@@ -1025,23 +1054,34 @@ PE_SECTION_ENTRY* adbg_object_pe_section(adbg_object_t *o, size_t index) {
// RVA -> hint + entry
PE_EXPORT_DESCRIPTOR* adbg_object_pe_export(adbg_object_t *o) {
- if (o == null) return null;
- if (o.i.pe.directory == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory == null) {
+ adbg_oops(AdbgError.unavailable); // Due to PE-ROM
+ return null;
+ }
// Set base
- with (o.i.pe)
- if (directory_exports == null) {
+ with (o.i.pe) if (directory_exports == null) {
directory_exports = cast(PE_EXPORT_DESCRIPTOR*)
adbg_object_pe_locate(o, directory.ExportTable.rva);
// Not found
- if (directory_exports == null) return null;
+ if (directory_exports == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
}
// adbg_object_pe_locate checked pointer bounds
PE_EXPORT_DESCRIPTOR* exportdir = o.i.pe.directory_exports;
// ExportFlags must be zero
- if (exportdir.ExportFlags != 0) return null;
+ if (exportdir.ExportFlags != 0) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
if (o.p.reversed && o.i.pe.reversed_dir_exports == false) with (exportdir) {
ExportFlags = adbg_bswap32(ExportFlags);
@@ -1062,9 +1102,14 @@ PE_EXPORT_DESCRIPTOR* adbg_object_pe_export(adbg_object_t *o) {
}
const(char)* adbg_object_pe_export_name(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *export_) {
- if (o == null || export_ == null) return null;
- if (o.i.pe.directory == null) return null;
- if (o.i.pe.directory_exports == null) return null;
+ if (o == null || export_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory == null || o.i.pe.directory_exports == null) {
+ adbg_oops(AdbgError.unavailable); // Due to PE-ROM
+ return null;
+ }
const(char) *name =
cast(const(char)*)o.i.pe.directory_exports
@@ -1072,7 +1117,7 @@ const(char)* adbg_object_pe_export_name(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *
+ export_.Name;
if (adbg_object_outboundp(o, cast(void*)name)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1080,24 +1125,32 @@ const(char)* adbg_object_pe_export_name(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *
}
PE_EXPORT_ENTRY* adbg_object_pe_export_name_entry(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *export_, size_t index) {
- if (o == null || export_ == null) return null;
- if (o.i.pe.directory == null) return null;
- if (o.i.pe.directory_exports == null) return null;
- if (index >= export_.NumberOfNamePointers) return null;
+ if (o == null || export_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory == null || o.i.pe.directory_exports == null) {
+ adbg_oops(AdbgError.unavailable); // Due to PE-ROM
+ return null;
+ }
+ if (index >= export_.NumberOfNamePointers) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
// Check bounds with table RVA
void *base = cast(void*)o.i.pe.directory_exports
- o.i.pe.directory.ExportTable.rva
+ export_.NamePointer;
if (adbg_object_outboundp(o, base)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
// Check bounds with name pointer and requested index
PE_EXPORT_ENTRY *entry = cast(PE_EXPORT_ENTRY*)base + index;
if (adbg_object_outboundp(o, entry)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1110,8 +1163,10 @@ PE_EXPORT_ENTRY* adbg_object_pe_export_name_entry(adbg_object_t *o, PE_EXPORT_DE
}
const(char)* adbg_object_pe_export_name_string(adbg_object_t *o, PE_EXPORT_DESCRIPTOR *export_, PE_EXPORT_ENTRY *entry) {
- if (o == null || export_ == null || entry == null)
+ if (o == null || export_ == null || entry == null) {
+ adbg_oops(AdbgError.invalidArgument);
return null;
+ }
// NOTE: Export Table bounds
// If the address specified is not within the export section (as
@@ -1128,7 +1183,7 @@ const(char)* adbg_object_pe_export_name_string(adbg_object_t *o, PE_EXPORT_DESCR
void *base = cast(void*)o.i.pe.directory_exports -
o.i.pe.directory.ExportTable.rva + entry.Export;
if (adbg_object_outboundp(o, base)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
return cast(const(char)*)base;
@@ -1139,20 +1194,36 @@ const(char)* adbg_object_pe_export_name_string(adbg_object_t *o, PE_EXPORT_DESCR
//
PE_IMPORT_DESCRIPTOR* adbg_object_pe_import(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.pe.directory == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory == null) {
+ adbg_oops(AdbgError.unavailable); // Due to PE-ROM
+ return null;
+ }
size_t count = o.i.pe.directory.ImportTable.size / PE_IMPORT_DESCRIPTOR.sizeof;
- if (index >= count) return null;
+ if (index >= count) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
// Set base
if (o.i.pe.directory_imports == null) {
o.i.pe.directory_imports = cast(PE_IMPORT_DESCRIPTOR*)
adbg_object_pe_locate(o, o.i.pe.directory.ImportTable.rva);
// Not found
- if (o.i.pe.directory_imports == null) return null;
+ if (o.i.pe.directory_imports == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
}
PE_IMPORT_DESCRIPTOR* import_ = o.i.pe.directory_imports + index;
+ if (import_.Characteristics == 0) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
if (o.p.reversed && o.i.pe.reversed_dir_imports[index] == false) with (import_) {
Characteristics = adbg_bswap32(Characteristics);
TimeDateStamp = adbg_bswap32(TimeDateStamp);
@@ -1161,18 +1232,23 @@ PE_IMPORT_DESCRIPTOR* adbg_object_pe_import(adbg_object_t *o, size_t index) {
FirstThunk = adbg_bswap32(FirstThunk);
o.i.pe.reversed_dir_imports[index] = true;
}
- if (import_.Characteristics == 0) return null;
return import_;
}
char* adbg_object_pe_import_name(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_) {
- if (o == null || import_ == null) return null;
- if (o.i.pe.directory == null) return null;
-
- char *s = cast(char*)o.i.pe.directory_imports - o.i.pe.directory.ImportTable.rva + import_.Name;
+ if (o == null || import_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
+ char *s = cast(char*)o.i.pe.directory_imports -
+ o.i.pe.directory.ImportTable.rva + import_.Name;
if (adbg_object_outboundp(o, s)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1182,15 +1258,20 @@ char* adbg_object_pe_import_name(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_
//TODO: Byte-swap import look-up table entries
PE_IMPORT_ENTRY32* adbg_object_pe_import_entry32(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, size_t index) {
- if (o == null || import_ == null) return null;
- if (o.i.pe.directory_imports == null) return null;
+ if (o == null || import_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory_imports == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
PE_IMPORT_ENTRY32* lte32 = cast(PE_IMPORT_ENTRY32*)
(cast(char*)o.i.pe.directory_imports + (import_.Characteristics - o.i.pe.directory.ImportTable.rva))
+ index;
-
if (adbg_object_outboundp(o, lte32) || lte32.ordinal == 0) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1198,13 +1279,19 @@ PE_IMPORT_ENTRY32* adbg_object_pe_import_entry32(adbg_object_t *o, PE_IMPORT_DES
}
ushort* adbg_object_pe_import_entry32_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, PE_IMPORT_ENTRY32 *im32) {
- if (o == null || import_ == null) return null;
- if (o.i.pe.directory_imports == null) return null;
+ if (o == null || import_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory_imports == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
ushort* base = cast(ushort*)
((cast(char*)o.i.pe.directory_imports - o.i.pe.directory.ImportTable.rva) + im32.rva);
if (adbg_object_outboundp(o, base)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1212,8 +1299,14 @@ ushort* adbg_object_pe_import_entry32_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTO
}
PE_IMPORT_ENTRY64* adbg_object_pe_import_entry64(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, size_t index) {
- if (o == null || import_ == null) return null;
- if (o.i.pe.directory_imports == null) return null;
+ if (o == null || import_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory_imports == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
PE_IMPORT_ENTRY64* lte64 = cast(PE_IMPORT_ENTRY64*)
(cast(char*)o.i.pe.directory_imports + (import_.Characteristics - o.i.pe.directory.ImportTable.rva))
@@ -1222,7 +1315,7 @@ PE_IMPORT_ENTRY64* adbg_object_pe_import_entry64(adbg_object_t *o, PE_IMPORT_DES
version (Trace) trace("imports=%p lte64=%p fs=%zx", o.i.pe.directory_imports, lte64, o.file_size);
if (adbg_object_outboundp(o, lte64) || lte64.ordinal == 0) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1230,8 +1323,14 @@ PE_IMPORT_ENTRY64* adbg_object_pe_import_entry64(adbg_object_t *o, PE_IMPORT_DES
}
ushort* adbg_object_pe_import_entry64_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTOR *import_, PE_IMPORT_ENTRY64 *im64) {
- if (o == null || import_ == null) return null;
- if (o.i.pe.directory_imports == null) return null;
+ if (o == null || import_ == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory_imports == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
ushort* base = cast(ushort*)
((cast(char*)o.i.pe.directory_imports - o.i.pe.directory.ImportTable.rva) + im64.rva);
@@ -1239,7 +1338,7 @@ ushort* adbg_object_pe_import_entry64_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTO
version (Trace) trace("base=%p fs=%zx", base, o.file_size);
if (adbg_object_outboundp(o, base)) {
- adbg_oops(AdbgError.objectOutsideBounds);
+ adbg_oops(AdbgError.offsetBounds);
return null;
}
@@ -1270,17 +1369,29 @@ ushort* adbg_object_pe_import_entry64_hint(adbg_object_t *o, PE_IMPORT_DESCRIPTO
//
PE_DEBUG_DIRECTORY* adbg_object_pe_debug_directory(adbg_object_t *o, size_t index) {
- if (o == null) return null;
- if (o.i.pe.directory == null) return null;
+ if (o == null) {
+ adbg_oops(AdbgError.invalidArgument);
+ return null;
+ }
+ if (o.i.pe.directory == null) {
+ adbg_oops(AdbgError.unavailable); // Due to PE-ROM
+ return null;
+ }
size_t count = o.i.pe.directory.DebugDirectory.size / PE_DEBUG_DIRECTORY.sizeof;
- if (index >= count) return null;
+ if (index >= count) {
+ adbg_oops(AdbgError.indexBounds);
+ return null;
+ }
// Set base
if (o.i.pe.directory_debug == null) {
o.i.pe.directory_debug = cast(PE_DEBUG_DIRECTORY*)
adbg_object_pe_locate(o, o.i.pe.directory.DebugDirectory.rva);
// Not found
- if (o.i.pe.directory_debug == null) return null;
+ if (o.i.pe.directory_debug == null) {
+ adbg_oops(AdbgError.unavailable);
+ return null;
+ }
}
PE_DEBUG_DIRECTORY* debug_ = o.i.pe.directory_debug + index;