Skip to content

Commit

Permalink
server: Kind of introduce archives
Browse files Browse the repository at this point in the history
  • Loading branch information
dd86k committed Jan 22, 2024
1 parent 288fdbd commit 0256b2a
Show file tree
Hide file tree
Showing 8 changed files with 351 additions and 31 deletions.
86 changes: 86 additions & 0 deletions app/dump/ar.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/// Library archive dumper
///
/// Authors: dd86k <[email protected]>
/// Copyright: © dd86k <[email protected]>
/// License: BSD-3-Clause
module dump.ar;

import adbg.disassembler.core;
import adbg.object.server;
import adbg.object.machines;
import adbg.object.format.ar;
import adbg.utils.bit : adbg_bswap32;
import core.stdc.ctype : isdigit;
import dumper;
import utils : realstring;

extern (C):

int dump_archive(ref Dumper dump, adbg_object_t *o) {
if (dump.selected_headers())
dump_archive_headers(dump, o);

return 0;
}

private:

void dump_archive_headers(ref Dumper dump, adbg_object_t *o) {
print_header("Header");

ar_member_header *rhdr = void; // Root headers
for (size_t i; (rhdr = adbg_object_ar_header(o, i)) != null; ++i) {
print_section(cast(uint)i);
print_stringl("Name", rhdr.Name.ptr, rhdr.Name.sizeof);
print_stringl("Date", rhdr.Date.ptr, rhdr.Date.sizeof);
print_stringl("UserID", rhdr.UserID.ptr, rhdr.UserID.sizeof);
print_stringl("GroupID", rhdr.GroupID.ptr, rhdr.GroupID.sizeof);
print_stringl("Mode", rhdr.Mode.ptr, rhdr.Mode.sizeof);
print_stringl("Size", rhdr.Size.ptr, rhdr.Size.sizeof);

char[10] b = void;
int l = realstring(b.ptr, 10, rhdr.End.ptr, 2, '"', '"');
print_x16l("End", rhdr.EndMarker, b.ptr, l);

/+void *data = adbg_object_ar_data(o, rhdr);
if (data == null) {
print_string("warning", "Could not get data pointer");
continue;
}
int size = adbg_object_ar_header_size(o, rhdr);
if (size <= 0) {
print_string("warning", "Could not get size of data");
continue;
}
import core.stdc.stdio : printf;
int symcnt = *cast(int*)data;
int *symoffs = cast(int*)data + 1;
for (int isym; isym < symcnt; ++isym) {
int off = adbg_bswap32(symoffs[isym]);
ar_member_header *table = void;
if (adbg_object_offset(o, cast(void**)&table, off)) {
print_string("warning", "aaaaaaaaaaa cringe");
printf("there was %d headers\n", isym);
return;
}
print_stringl("Name", table.Name.ptr, table.Name.sizeof);
print_stringl("Date", table.Date.ptr, table.Date.sizeof);
print_stringl("UserID", table.UserID.ptr, table.UserID.sizeof);
print_stringl("GroupID", table.GroupID.ptr, table.GroupID.sizeof);
print_stringl("Mode", table.Mode.ptr, table.Mode.sizeof);
print_stringl("Size", table.Size.ptr, table.Size.sizeof);
l = realstring(b.ptr, 10, table.End.ptr, 2, '"', '"');
print_x16l("End", table.EndMarker, b.ptr, l);
if (table.Name[0] != '/' || isdigit(table.Name[1]) == 0)
continue;
}+/
}
}
11 changes: 10 additions & 1 deletion app/dump/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,13 @@
*/
module dump;

public import dump.mz, dump.ne, dump.lx, dump.pe, dump.elf, dump.macho, dump.pdb70, dump.pdb20;
public import
dump.mz,
dump.ne,
dump.lx,
dump.pe,
dump.elf,
dump.macho,
dump.pdb70,
dump.pdb20,
dump.ar;
57 changes: 56 additions & 1 deletion app/dumper.d
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,17 @@ int app_dump() {
case macho: return dump_macho(dump, o);
case pdb20: return dump_pdb20(dump, o);
case pdb70: return dump_pdb70(dump, o);
default: return EXIT_FAILURE;
case archive: return dump_archive(dump, o);
default: assert(0, "Invalid object type"); // Raw/unknown
}
}

private immutable {
/// Padding spacing to use in characters
// PE32 has fields like MinorOperatingSystemVersion (27 chars)
int __field_padding = -28;
///
int __columns = 16;
}

void print_header(const(char)* name) {
Expand Down Expand Up @@ -316,6 +319,58 @@ L_START:
goto L_START;
}

void print_raw(const(char)* name, void *data, size_t dsize, adbg_object_t *o) {
// Is size fitting within file?
if (adbg_object_outboundpl(o, data, dsize)) {
print_string("warning", "Data goes beyond file bounds.");
return;
}

import core.stdc.ctype : isprint;

print_header(name);

size_t offset = data - o.buffer;

// Print header
static immutable string _soff = "Offset ";
printf(_soff.ptr);
//TODO: Print extra spaces after offset string
for (int ib; ib < __columns; ++ib)
printf("%02x ", ib);
putchar('\n');

// Print data
ubyte *d = cast(ubyte*)data;
size_t afo; // Absolute file offset
for (size_t id; id < dsize; id += __columns, offset += __columns) {
printf("%8zx ", offset);

// Adjust column for row
size_t col = __columns;//id + __columns >= dsize ? dsize - __columns : __columns;
size_t off = afo;

// Print data bytes
for (size_t ib; ib < col; ++ib, ++off)
printf("%02x ", d[off]);

// Adjust spacing between the two
if (col < __columns) {

} else
putchar(' ');

// Print printable characters
off = afo;
for (size_t ib; ib < col; ++ib, ++off)
putchar(isprint(d[off]) ? d[off] : '.');

// New row
afo += col;
putchar('\n');
}
}

void print_directory_entry(const(char)* name, uint rva, uint size) {
printf("%*s: 0x%08x %u\n", __field_padding, name, rva, size);
}
Expand Down
86 changes: 86 additions & 0 deletions app/utils.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,92 @@
module utils;

import core.stdc.stdio : sscanf;
import core.stdc.ctype : isprint;

char hexc0(ubyte upper) {
ubyte h = upper >> 4;
return cast(char)(h >= 0xa ? h + ('a' - 0xa) : h + '0');
}
unittest {
assert(hexc0(0x00) == '0');
assert(hexc0(0x10) == '1');
assert(hexc0(0x20) == '2');
assert(hexc0(0x30) == '3');
assert(hexc0(0x40) == '4');
assert(hexc0(0x50) == '5');
assert(hexc0(0x60) == '6');
assert(hexc0(0x70) == '7');
assert(hexc0(0x80) == '8');
assert(hexc0(0x90) == '9');
assert(hexc0(0xa0) == 'a');
assert(hexc0(0xb0) == 'b');
assert(hexc0(0xc0) == 'c');
assert(hexc0(0xd0) == 'd');
assert(hexc0(0xe0) == 'e');
assert(hexc0(0xf0) == 'f');
}
char hexc1(ubyte lower) {
ubyte l = lower & 15;
return cast(char)(l >= 0xa ? l + ('a' - 0xa) : l + '0');
}
unittest {
assert(hexc1(0) == '0');
assert(hexc1(1) == '1');
assert(hexc1(2) == '2');
assert(hexc1(3) == '3');
assert(hexc1(4) == '4');
assert(hexc1(5) == '5');
assert(hexc1(6) == '6');
assert(hexc1(7) == '7');
assert(hexc1(8) == '8');
assert(hexc1(9) == '9');
assert(hexc1(0xa) == 'a');
assert(hexc1(0xb) == 'b');
assert(hexc1(0xc) == 'c');
assert(hexc1(0xd) == 'd');
assert(hexc1(0xe) == 'e');
assert(hexc1(0xf) == 'f');
}

int realstring(char* buffer, size_t bsize, const(char)* str, size_t ssize,
char pre = 0, char post = 0) {
int len; // total length

if (bsize == 0)
return 0;

if (pre && bsize)
buffer[len++] = pre;

for (size_t i; i < ssize && len < bsize; ++i) {
char c = str[i];
if (isprint(c)) {
if (len >= bsize) break;
buffer[len++] = c;
} else {
if (len + 4 >= bsize) break;
buffer[len++] = '\\';
buffer[len++] = 'x';
buffer[len++] = hexc0(c);
buffer[len++] = hexc1(c);
}
}

if (post && len < bsize)
buffer[len++] = post;

return len;
}
unittest {
char[2] bi = "`\n";
char[10] bo = void; // '`' '\\x0a'
assert(realstring(bo.ptr, 10, bi.ptr, 2) == 5);
assert(bo[0] == '`');
assert(bo[1] == '\\');
assert(bo[2] == 'x');
assert(bo[3] == '0');
assert(bo[4] == 'a');
}

/// Unformat text number.
/// Params:
Expand Down
84 changes: 78 additions & 6 deletions src/adbg/object/format/ar.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
/// License: BSD-3-Clause
module adbg.object.format.ar;

import adbg.error;
import adbg.object.server;
import adbg.utils.bit;
import core.stdc.stdlib : atoi;
import core.stdc.string : memcpy;

// Sources:
// - gdb/include/aout/ar.h
Expand All @@ -20,10 +24,14 @@ import adbg.utils.bit;
// Header + Longnames Member + Data
// Header + obj n + Data

// NOTE: MSVC linker can only process libraries under 4 GiB in size.

/// COFF archive magic.
enum AR_MAGIC = CHAR64!"!<arch>\n";
/// Thin COFF archive magic.
enum AR_THIN_MAGIC = CHAR64!"!<thin>\n";
///
private enum AR_EOL = CHAR16!"`\n";

///
struct ar_file_header {
Expand Down Expand Up @@ -68,8 +76,11 @@ struct ar_member_header {
/// ASCII decimal representation of the total size of the
/// archive member, not including the size of the header.
char[10] Size;
/// The two bytes in the C string: "`\n" (0x60 0x0a).
char[2] End;
union {
/// The two bytes in the C string: "`\n" (0x60 0x0a).
char[2] End;
ushort EndMarker;
}
}

/// When first name is "/"
Expand All @@ -90,16 +101,77 @@ struct mscoff_second_linker_header {
// String Table after Indices
}

int adbg_object_ar_load(adbg_object_t *o) {
o.format = AdbgObject.archive;
return 0;
}

ar_member_header* adbg_object_ar_header(adbg_object_t *o, size_t index) {
if (o == null)
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;

// Adjust pointer
size_t offset = atoi(p.Size.ptr) + ar_member_header.sizeof;
version (Trace) trace("offset=%zu", offset);
p = cast(ar_member_header*)(cast(void*)p + offset);

// Outside bounds
if (adbg_object_outboundpl(o, p, ar_member_header.sizeof))
return null;
}

return null;
}

int adbg_object_ar_header_size(adbg_object_t *o, ar_member_header *mhdr) {
if (o == null || mhdr == null)
return -1;

char[12] str = void;
memcpy(str.ptr, mhdr.Size.ptr, mhdr.Size.sizeof);
str[10] = 0;
return atoi(str.ptr);
}

void* adbg_object_ar_data(adbg_object_t *o, ar_member_header *mhdr) {
if (o == null || mhdr == null)
return null;

void *p = cast(void*)mhdr + ar_member_header.sizeof;
int size = adbg_object_ar_header_size(o, mhdr);
if (size < 0)
return null;
if (adbg_object_outboundpl(o, p, size))
return null;
return p;
}

//
// MSCOFF import
//

///
struct mscoff_import_header {
/// Must be IMAGE_FILE_MACHINE_UNKNOWN.
ushort Sig1;
/// Must be 0xFFFF.
ushort Sig2;
union {
/// Must be a combination of IMAGE_FILE_MACHINE_UNKNOWN and 0xFFFF.
///
/// Effectively only 0xFFFF, since the enum value is 0.
uint Signature;
struct {
/// Must be IMAGE_FILE_MACHINE_UNKNOWN.
ushort Signature1;
/// Must be 0xFFFF.
ushort Signature2;
}
}
ushort Version;
ushort Machine;
uint TimeStamp;
Expand Down
Loading

0 comments on commit 0256b2a

Please sign in to comment.