~laumann/hadb

a42eb2c9b9520e2256ec8b301d62e5547abb537a — Thomas Bracht Laumann Jespersen 4 months ago d608ee4
format/dwarf: decode .debug_str
1 files changed, 68 insertions(+), 0 deletions(-)

A format/dwarf/str.ha
A format/dwarf/str.ha => format/dwarf/str.ha +68 -0
@@ 0,0 1,68 @@
// Load the string table that is .debug_str
use strings;

// Return the strings in .debug_str as a list of tuples - the strings
// themselves and their index in the section.
//
// The returned list of strings must be freed by the caller.
export fn decodestr(input: []u8) (([](str, size), size) | partialread) = {
	let strs: [](str, size) = [];
	let err = true;
	defer if (err) {
		for (let i = 0z; i < len(strs); i += 1)
			free(strs[i].0);
		free(strs);
	};

	let i = 0z;
	let p = 0z;
	for (let i = 0z; i < len(input); i += 1) {
		if (input[i] == 0) {
			let s = strings::dup(strings::fromutf8_unsafe(input[p..i]));
			append(strs, (s, p));
			p = i + 1;
		};
	};
	if (input[len(input)-1] != 0)
		return partialread;
	err = false;
	return (strs, len(input));
};

@test fn decodestr() void = {
	const bin: []u8 = [
		// Hex dump of section '.debug_str':
		0x73, 0x68, 0x6f, 0x72, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x00, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x75,
		0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x00, 0x47, 0x4e, 0x55, 0x20,
		0x43, 0x31, 0x37, 0x20, 0x31, 0x33, 0x2e, 0x32, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x32, 0x33, 0x30,
		0x38, 0x32, 0x36, 0x20, 0x2d, 0x6d, 0x74, 0x75, 0x6e, 0x65, 0x3d, 0x67, 0x65, 0x6e, 0x65, 0x72,
		0x69, 0x63, 0x20, 0x2d, 0x6d, 0x61, 0x72, 0x63, 0x68, 0x3d, 0x78, 0x38, 0x36, 0x2d, 0x36, 0x34,
		0x20, 0x2d, 0x67, 0x64, 0x77, 0x61, 0x72, 0x66, 0x2d, 0x32, 0x00, 0x73, 0x68, 0x6f, 0x72, 0x74,
		0x20, 0x75, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x74, 0x00,
		0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x63, 0x00, 0x75, 0x6e, 0x73, 0x69, 0x67,
		0x6e, 0x65, 0x64, 0x20, 0x63, 0x68, 0x61, 0x72, 0x00, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x69, 0x6e,
		0x74, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00,
	];

	let expected: [](str, size) = [
		("short int", 0),
		("long unsigned int", 10),
		("GNU C17 13.2.1 20230826 -mtune=generic -march=x86-64 -gdwarf-2", 28),
		("short unsigned int", 91),
		("main.c", 110),
		("unsigned char", 117),
		("long int", 131),
		("main", 140),
	];

	let (strs, read) = decodestr(bin)!;
	assert(len(strs) == len(expected));
	assert(read == len(bin));

	for (let i = 0z; i < len(strs); i += 1) {
		let (a, ar) = strs[i];
		let (e, er) = expected[i];
		assert(a == e);
		assert(ar == er);
	};
};