Figure out .debug_line
This commit is contained in:
parent
67398fd940
commit
1b41ea320c
174
bootstrap/lib.h
174
bootstrap/lib.h
@ -3029,6 +3029,180 @@ may_be_unused fn Hash32 hash64_fib_end(Hash64 hash)
|
||||
return result;
|
||||
}
|
||||
|
||||
STRUCT(MD5Context)
|
||||
{
|
||||
u32 buffer[4];
|
||||
u8 input[64];
|
||||
u64 size;
|
||||
};
|
||||
|
||||
// Took from: https://github.com/Zunawe/md5-c
|
||||
|
||||
#define MD5_A 0x67452301
|
||||
#define MD5_B 0xefcdab89
|
||||
#define MD5_C 0x98badcfe
|
||||
#define MD5_D 0x10325476
|
||||
|
||||
#define MD5_F(X, Y, Z) ((X & Y) | (~X & Z))
|
||||
#define MD5_G(X, Y, Z) ((X & Z) | (Y & ~Z))
|
||||
#define MD5_H(X, Y, Z) (X ^ Y ^ Z)
|
||||
#define MD5_I(X, Y, Z) (Y ^ (X | ~Z))
|
||||
|
||||
global u32 md5_s[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||
|
||||
global u32 md5_k[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
|
||||
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
|
||||
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
|
||||
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
|
||||
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
|
||||
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
|
||||
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
|
||||
|
||||
/*
|
||||
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
|
||||
*/
|
||||
global u8 md5_padding[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
|
||||
fn MD5Context md5_init()
|
||||
{
|
||||
return (MD5Context) {
|
||||
.buffer = { MD5_A, MD5_B, MD5_C, MD5_D },
|
||||
};
|
||||
}
|
||||
|
||||
fn u32 rotate_left_u32(u32 x, u32 n)
|
||||
{
|
||||
return (x << n) | (x >> (32 - n));
|
||||
}
|
||||
|
||||
fn void md5_step(u32* buffer, u32* input)
|
||||
{
|
||||
u32 aa = buffer[0];
|
||||
u32 bb = buffer[1];
|
||||
u32 cc = buffer[2];
|
||||
u32 dd = buffer[3];
|
||||
|
||||
for (u32 i = 0; i < 64; i += 1)
|
||||
{
|
||||
u32 j;
|
||||
u32 e;
|
||||
switch (i / 16)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
e = MD5_F(bb, cc, dd);
|
||||
j = i;
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
e = MD5_G(bb, cc, dd);
|
||||
j = ((i * 5) + 1) % 16;
|
||||
} break;
|
||||
case 2:
|
||||
{
|
||||
e = MD5_H(bb, cc, dd);
|
||||
j = ((i * 3) + 5) % 16;
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
e = MD5_I(bb, cc, dd);
|
||||
j = (i * 7) % 16;
|
||||
} break;
|
||||
}
|
||||
|
||||
u32 old_dd = dd;
|
||||
dd = cc;
|
||||
cc = bb;
|
||||
bb = bb + rotate_left_u32(aa + e + md5_k[i] + input[j], md5_s[i]);
|
||||
aa = old_dd;
|
||||
}
|
||||
|
||||
buffer[0] += aa;
|
||||
buffer[1] += bb;
|
||||
buffer[2] += cc;
|
||||
buffer[3] += dd;
|
||||
}
|
||||
|
||||
fn void md5_update(MD5Context* context, String input_argument)
|
||||
{
|
||||
u32 input_local[16];
|
||||
auto offset = context->size % 64;
|
||||
context->size += input_argument.length;
|
||||
|
||||
for (u64 i = 0; i < input_argument.length; i += 1)
|
||||
{
|
||||
context->input[offset] = input_argument.pointer[i];
|
||||
offset += 1;
|
||||
|
||||
if (offset % 64 == 0)
|
||||
{
|
||||
// TODO: convert to little-endian in case we are big-endian?
|
||||
for (u16 i = 0; i < 16; i += 1)
|
||||
{
|
||||
auto existing = *(u32*)&input_argument.pointer[i * 4];
|
||||
input_local[i] = existing;
|
||||
}
|
||||
md5_step(context->buffer, input_local);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STRUCT(MD5Result)
|
||||
{
|
||||
u8 hash[16];
|
||||
};
|
||||
|
||||
fn MD5Result md5_end(MD5Context* context)
|
||||
{
|
||||
u32 input[16];
|
||||
auto offset = context->size % 64;
|
||||
auto padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;
|
||||
|
||||
md5_update(context, (String) { .pointer = md5_padding, .length = padding_length });
|
||||
context->size -= (u64)padding_length;
|
||||
|
||||
for (u32 i = 0; i < 14; i += 1)
|
||||
{
|
||||
input[i] = *(u32*)&context->input[i * 4];
|
||||
}
|
||||
input[14] = (u32)(context->size * 8);
|
||||
input[15] = (u32)((context->size * 8) >> 32);
|
||||
|
||||
md5_step(context->buffer, input);
|
||||
|
||||
MD5Result result;
|
||||
for (u32 i = 0; i < 4; i += 1)
|
||||
{
|
||||
result.hash[(i * 4) + 0] = (u8)((context->buffer[i] & 0x000000ff) >> 0);
|
||||
result.hash[(i * 4) + 1] = (u8)((context->buffer[i] & 0x0000ff00) >> 8);
|
||||
result.hash[(i * 4) + 2] = (u8)((context->buffer[i] & 0x00ff0000) >> 16);
|
||||
result.hash[(i * 4) + 3] = (u8)((context->buffer[i] & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn void entry_point(int argc, char* argv[], char* envp[]);
|
||||
|
||||
#if LINK_LIBC
|
||||
|
122
bootstrap/main.c
122
bootstrap/main.c
@ -9722,21 +9722,94 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr
|
||||
uleb128_encode(&builder->file, opcode_length_lookup[i]);
|
||||
}
|
||||
|
||||
// TODO: figure out
|
||||
{
|
||||
u8 data[] = {
|
||||
0x01, 0x01, 0x1F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x1F, 0x02, 0x0F, 0x05, 0x1E, 0x01, 0x14, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
};
|
||||
memcpy(vb_add(&builder->file, sizeof(data)), data, sizeof(data));
|
||||
}
|
||||
typedef enum LineNumberHeaderEntryFormat : u8
|
||||
{
|
||||
DW_LCNT_path = 0x01,
|
||||
DW_LCNT_directory_index = 0x02,
|
||||
DW_LCNT_timestamp = 0x03,
|
||||
DW_LCNT_size = 0x04,
|
||||
DW_LCNT_MD5 = 0x05,
|
||||
} LineNumberHeaderEntryFormat;
|
||||
|
||||
// TODO: figure out
|
||||
{
|
||||
u8 checksum[] = {
|
||||
0x05, 0xAB, 0x89, 0xF5, 0x48, 0x1B, 0xC9, 0xF2, 0xD0, 0x37, 0xE7, 0x88, 0x66, 0x41, 0xE9, 0x19,
|
||||
STRUCT(FormatDescriptor)
|
||||
{
|
||||
LineNumberHeaderEntryFormat format;
|
||||
DwarfForm form;
|
||||
};
|
||||
memcpy(vb_add(&builder->file, sizeof(checksum)), checksum, sizeof(checksum));
|
||||
|
||||
FormatDescriptor directory_entry_formats[] = {
|
||||
{ DW_LCNT_path, DW_FORM_line_strp },
|
||||
};
|
||||
|
||||
auto directory_entry_format_count = cast(u8, u32, array_length(directory_entry_formats));
|
||||
*vb_add(&builder->file, 1) = directory_entry_format_count;
|
||||
|
||||
for (u8 i = 0; i < array_length(directory_entry_formats); i += 1)
|
||||
{
|
||||
FormatDescriptor descriptor = directory_entry_formats[i];
|
||||
uleb128_encode(&builder->file, descriptor.format);
|
||||
uleb128_encode(&builder->file, descriptor.form);
|
||||
}
|
||||
|
||||
u32 paths[] = { 0 };
|
||||
|
||||
auto directory_count = array_length(paths);
|
||||
uleb128_encode(&builder->file, directory_count);
|
||||
|
||||
for (u32 i = 0; i < directory_count; i += 1)
|
||||
{
|
||||
auto directory_offset = paths[i];
|
||||
*(u32*)(vb_add(&builder->file, sizeof(u32))) = directory_offset;
|
||||
}
|
||||
|
||||
FormatDescriptor filename_entry_formats[] = {
|
||||
{ DW_LCNT_path, DW_FORM_line_strp },
|
||||
{ DW_LCNT_directory_index, DW_FORM_udata },
|
||||
{ DW_LCNT_MD5, DW_FORM_data16 },
|
||||
};
|
||||
|
||||
auto filename_entry_format_count = cast(u8, u32, array_length(filename_entry_formats));
|
||||
*vb_add(&builder->file, 1) = filename_entry_format_count;
|
||||
|
||||
for (u8 i = 0; i < filename_entry_format_count; i += 1)
|
||||
{
|
||||
FormatDescriptor descriptor = filename_entry_formats[i];
|
||||
uleb128_encode(&builder->file, descriptor.format);
|
||||
uleb128_encode(&builder->file, descriptor.form);
|
||||
}
|
||||
|
||||
STRUCT(FilenameEntry)
|
||||
{
|
||||
u32 filename;
|
||||
u8 directory_index;
|
||||
MD5Result hash;
|
||||
};
|
||||
MD5Result md5_hash = { { 0x05, 0xAB, 0x89, 0xF5, 0x48, 0x1B, 0xC9, 0xF2, 0xD0, 0x37, 0xE7, 0x88, 0x66, 0x41, 0xE9, 0x19 } };
|
||||
#if 0
|
||||
String dummy_file = file_read(thread->arena, strlit("/home/david/minimal/main.c"));
|
||||
auto md5 = md5_init();
|
||||
md5_update(&md5, dummy_file);
|
||||
md5_hash = md5_end(&md5);
|
||||
#endif
|
||||
|
||||
FilenameEntry filenames[] = {
|
||||
{
|
||||
0x14,
|
||||
0,
|
||||
md5_hash,
|
||||
},
|
||||
};
|
||||
auto filename_count = array_length(filenames);
|
||||
uleb128_encode(&builder->file, filename_count);
|
||||
|
||||
for (auto i = 0; i < filename_count; i += 1)
|
||||
{
|
||||
auto filename = filenames[i];
|
||||
*(u32*)vb_add(&builder->file, sizeof(u32)) = filename.filename;
|
||||
uleb128_encode(&builder->file, filename.directory_index);
|
||||
memcpy(vb_add(&builder->file, sizeof(filename.hash)), &filename.hash, sizeof(filename.hash));
|
||||
}
|
||||
}
|
||||
|
||||
auto line_program_start_offset = builder->file.length;
|
||||
@ -9748,12 +9821,27 @@ may_be_unused fn void write_elf(Thread* thread, const ObjectOptions* const restr
|
||||
*vb_add(&builder->file, 1) = 5;
|
||||
|
||||
*vb_add(&builder->file, 1) = DW_LNS_set_prologue_end;
|
||||
}
|
||||
|
||||
// TODO: figure out
|
||||
{
|
||||
u8 data[] = { 0x00, 0x09, 0x02, 0x1C, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x03, 0x00, 0x01, 0x01, };
|
||||
memcpy(vb_add(&builder->file, sizeof(data)), data, sizeof(data));
|
||||
{
|
||||
// TODO: confirm this is the encoding of special opcodes?
|
||||
*vb_add(&builder->file, 1) = 0; // Special opcode
|
||||
*vb_add(&builder->file, 1) = 9; // Bytes ahead
|
||||
*vb_add(&builder->file, 1) = DW_LNE_set_address; // Bytes ahead
|
||||
*(u64*)vb_add(&builder->file, sizeof(u64)) = main_offset;
|
||||
}
|
||||
|
||||
*vb_add(&builder->file, 1) = 0x14; // 14, address += 0, line += 2, op-index += 0
|
||||
|
||||
// Advance PC by 3
|
||||
*vb_add(&builder->file, 1) = DW_LNS_advance_pc;
|
||||
*vb_add(&builder->file, 1) = 0x03;
|
||||
|
||||
{
|
||||
// TODO: confirm this is the encoding of special opcodes?
|
||||
*vb_add(&builder->file, 1) = 0; // Special opcode
|
||||
*vb_add(&builder->file, 1) = 1; // Bytes ahead
|
||||
*vb_add(&builder->file, 1) = DW_LNE_end_sequence;
|
||||
}
|
||||
}
|
||||
|
||||
auto size = builder->file.length - offset;
|
||||
|
Loading…
x
Reference in New Issue
Block a user