Skip to content

Commit

Permalink
objectserver: turn "get section" into "search section", vararg
Browse files Browse the repository at this point in the history
  • Loading branch information
dd86k committed Aug 11, 2024
1 parent 45aba52 commit 38a7c36
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 27 deletions.
8 changes: 5 additions & 3 deletions dumper/format/elf.d
Original file line number Diff line number Diff line change
Expand Up @@ -447,10 +447,13 @@ void dump_elf_section64(Elf64_Shdr *shdr, uint idx, const(char)* name, int nmax)
//TODO: Section machine-specific flags (like SHF_X86_64_LARGE)

void dump_elf_exports(adbg_object_t *o) {
adbg_section_t *dynsym = adbg_object_search_section_by_name(o, ".dynsym");
adbg_section_t *dynsym =
adbg_object_search_section(o, AdbgObjectSearch.exactName, ".dynsym".ptr);
if (dynsym == null)
panic_adbg(".dynsym section missing");
adbg_section_t *dynstr = adbg_object_search_section_by_name(o, ".dynstr");

adbg_section_t *dynstr =
adbg_object_search_section(o, AdbgObjectSearch.exactName, ".dynstr".ptr);
if (dynstr == null)
panic_adbg(".dynstr section missing");

Expand Down Expand Up @@ -498,7 +501,6 @@ void dump_elf_exports(adbg_object_t *o) {
default:
panic_adbg();
}

}

void dump_elf_disasm(adbg_object_t *o) {
Expand Down
16 changes: 15 additions & 1 deletion src/adbg/objects/elf.d
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ struct internal_elf_t {
union { align(1):
Elf32_Ehdr eheader32;
Elf64_Ehdr eheader64;
struct { align(1): // Same aligned members for all EHdr types
struct { align(1): // Same aligned members for all Ehdr types
ubyte ident_magic1;
ubyte ident_magic2;
ubyte ident_magic3;
Expand Down Expand Up @@ -1168,6 +1168,20 @@ int adbg_object_elf_class(adbg_object_t *o) {
return (cast(internal_elf_t*)o.internal).ident_class;
}

int adbg_object_elf_section_count(adbg_object_t *o) {
if (o == null) {
adbg_oops(AdbgError.invalidArgument);
return -1;
}
if (o.internal == null) {
adbg_oops(AdbgError.uninitiated);
return -1;
}
internal_elf_t *internal = cast(internal_elf_t*)o.internal;
return internal.ident_class == ELF_CLASS_64 ?
internal.eheader64.e_shnum : internal.eheader32.e_shnum;
}

void* adbg_object_elf_phdr(adbg_object_t *o, size_t index) {
if (o == null) {
adbg_oops(AdbgError.invalidArgument);
Expand Down
97 changes: 74 additions & 23 deletions src/adbg/objectserver.d
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import adbg.debugger.memory : adbg_memory_read;
import adbg.debugger.process : adbg_process_t;
import adbg.error;
import adbg.machines : AdbgMachine, adbg_machine_name;
import adbg.utils.math; // For MiB template
import adbg.utils.math;
import adbg.include.c.stdlib;
import adbg.include.c.stdarg;
import adbg.os.file;
Expand All @@ -37,15 +37,25 @@ import core.stdc.string;

extern (C):

// NOTE: Function names
// At best, prefer adbg_object_OBJECT_xyz where OBJECT is the type
// (e.g., pe, elf, etc.) to make things consistent. This is why
// auxiliary names are simply "adbg_object_offset", for example.
// NOTE: For object submodule implementations.
//
// Function names
// At best, prefer adbg_object_OBJECT_xyz where OBJECT is the type
// (e.g., pe, elf, etc.) to make things consistent. This is why
// auxiliary names are simply "adbg_object_offset", for example.
//
// Performance
// Keeping crucial information, like the sectiontable, in memory,
// can greatly accelerate a lot of the operations, including section
// searches, but should only be allocated on-demand. Headers, program
// headers, and sections usually should be read when loading a new
// object instance.

// TODO: Clean the section search functions
// TODO: Consider structure definition, using a template
// Uses:
// - For swapping, uses less code than inlining it
// - For displaying and using field offsets
// Uses:
// - For swapping, uses less code than inlining it
// - For displaying and using field offsets
// TODO: adbg_object_endiannes
// Why? Machine module do not include endianness.
// And would be beneficial when host has incompatible endianness.
Expand All @@ -56,8 +66,14 @@ extern (C):
// TODO: adbg_object_load_debug(adbg_object_t *o)
// Attach debug object instance to this one. Likely to be used internally for stuff
// like getting symbols off memory addresses.
// PE32: Load PDB from debug entry (absolute or relative), try DWARF if previous fails
// ELF: Load embedded DWARF
// PE32:
// - Load PDB from debug entry (PDB absolute or try relative same folder)
// ELF:
// - DWARF (".debug_info" and others)
// - Compact C type Format (CTF, ".ctf"): https://github.com/lovasko/libctf
// - BPF Type Format (BTF)
// Mach-O:
// - uuid_command points to dSYM file

/// Executable or object file format.
enum AdbgObject {
Expand Down Expand Up @@ -480,14 +496,48 @@ int adbg_object_loadv(adbg_object_t *o) {
return adbg_oops(AdbgError.objectUnknownFormat);
}

//TODO: Flags: Contains (default: exact), case insensitive, executable only, etc.
//TODO: unix archives (ar), by member name
adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char) *name, int flags = 0) {
if (o == null || name == null) {
/// Add a search parameter query to adbg_object_search_section.
enum AdbgObjectSearch {
/// Get section exactly by this name. Case-sensitive.
/// Type: Null terminated string pointer (char*).
/// Default: null
exactName = 1,
}

// TODO: Flags: Contains (default: exact), case insensitive, executable only, etc.
// TODO: unix archives (ar), by member name
// TODO: Search Address: if address >= sectionAddress && address < sectionAddress + sectionSize

/// Search and obtain one section from query.
/// Params:
/// o = Object instance.
/// ... = Search parameters (see AdbgObjectSearch).
/// Returns: Allocated section instance.
adbg_section_t* adbg_object_search_section(adbg_object_t *o, ...) {
if (o == null) {
adbg_oops(AdbgError.invalidArgument);
return null;
}

va_list list = void;
va_start(list, o);

const(char) *name;
Loption:
switch (va_arg!int(list)) with (AdbgObjectSearch) {
case 0: break;
case exactName:
name = va_arg!(const(char)*)(list);
if (name == null) {
adbg_oops(AdbgError.invalidValue);
return null;
}
goto Loption;
default:
adbg_oops(AdbgError.invalidOption);
return null;
}

// Search every section for its name
void *section_header;
size_t section_header_size;
Expand All @@ -498,7 +548,7 @@ adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char)
size_t i;
for (pe_section_entry_t *s = void; (s = adbg_object_pe_section(o, i)) != null; ++i) {
//TODO: Section name function (in case of long section names)
if (strncmp(name, s.Name.ptr, s.Name.sizeof) == 0) {
if (name && strncmp(name, s.Name.ptr, s.Name.sizeof) == 0) {
section_header = s;
section_header_size = pe_section_entry_t.sizeof;
section_offset = s.PointerToRawData;
Expand All @@ -516,7 +566,7 @@ adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char)
if (macho64) {
macho_section64_t *s64 = cast(macho_section64_t*)s;

if (strncmp(name, s64.sectname.ptr, s64.sectname.sizeof) == 0) {
if (name && strncmp(name, s64.sectname.ptr, s64.sectname.sizeof) == 0) {
section_header = s64;
section_header_size = macho_section64_t.sizeof;
section_offset = s64.offset;
Expand All @@ -526,7 +576,7 @@ adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char)
} else { // 32-bit
macho_section_t *s32 = cast(macho_section_t*)s;

if (strncmp(name, s32.sectname.ptr, s32.sectname.sizeof) == 0) {
if (name && strncmp(name, s32.sectname.ptr, s32.sectname.sizeof) == 0) {
section_header = s32;
section_header_size = macho_section_t.sizeof;
section_offset = s32.offset;
Expand All @@ -542,10 +592,10 @@ adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char)
switch (adbg_object_elf_class(o)) {
case ELF_CLASS_32:
for (Elf32_Shdr *s = void; (s = adbg_object_elf_shdr32(o, i)) != null; ++i) {
const(char) *sname = adbg_object_elf_shdr32_name(o, s);
if (sname == null)
const(char) *secname = adbg_object_elf_shdr32_name(o, s);
if (secname == null)
continue;
if (strcmp(name, sname) == 0) {
if (name && strcmp(name, secname) == 0) {
section_header = s;
section_header_size = Elf32_Shdr.sizeof;
section_offset = s.sh_offset;
Expand All @@ -556,10 +606,10 @@ adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char)
break;
case ELF_CLASS_64:
for (Elf64_Shdr *s = void; (s = adbg_object_elf_shdr64(o, i)) != null; ++i) {
const(char) *sname = adbg_object_elf_shdr64_name(o, s);
if (sname == null)
const(char) *secname = adbg_object_elf_shdr64_name(o, s);
if (secname == null)
continue;
if (strcmp(name, sname) == 0) {
if (name && strcmp(name, secname) == 0) {
section_header = s;
section_header_size = Elf32_Shdr.sizeof;
section_offset = s.sh_offset;
Expand All @@ -569,6 +619,7 @@ adbg_section_t* adbg_object_search_section_by_name(adbg_object_t *o, const(char)
}
break;
default:
adbg_oops(AdbgError.objectInvalidClass);
return null;
}
break;
Expand Down

0 comments on commit 38a7c36

Please sign in to comment.