mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-01 03:40:02 +00:00
pass over COFF archive parser
This commit is contained in:
@@ -114,14 +114,6 @@
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#if ARCH_LITTLE_ENDIAN
|
||||
# define BE_U32(x) bswap_u32(x)
|
||||
#else
|
||||
# define BE_U32(x) (x)
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U64 major;
|
||||
|
||||
@@ -243,6 +243,19 @@ key_value_pair_is_before_u64(void *raw_a, void *raw_b)
|
||||
return a->key_u64 < b->key_u64;
|
||||
}
|
||||
|
||||
internal U32 *
|
||||
keys_from_hash_table_u32(Arena *arena, HashTable *ht)
|
||||
{
|
||||
U32 *result = push_array_no_zero(arena, U32, ht->count);
|
||||
for (U64 bucket_idx = 0, cursor = 0; bucket_idx < ht->cap; ++bucket_idx) {
|
||||
for (BucketNode *n = ht->buckets[bucket_idx].first; n != 0; n = n->next) {
|
||||
Assert(cursor < ht->count);
|
||||
result[cursor++] = n->v.key_u32;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal KeyValuePair *
|
||||
key_value_pairs_from_hash_table(Arena *arena, HashTable *ht)
|
||||
{
|
||||
|
||||
@@ -75,6 +75,7 @@ internal B32 hash_table_search_path_u64(HashTable *ht, String8 key, U64 *value_o
|
||||
|
||||
//- key-value helpers
|
||||
|
||||
internal U32 * keys_from_hash_table_u32(Arena *arena, HashTable *ht);
|
||||
internal KeyValuePair * key_value_pairs_from_hash_table(Arena *arena, HashTable *ht);
|
||||
internal void sort_key_value_pairs_as_u32(KeyValuePair *pairs, U64 count);
|
||||
internal void sort_key_value_pairs_as_u64(KeyValuePair *pairs, U64 count);
|
||||
|
||||
+2
-2
@@ -1221,7 +1221,7 @@ internal void
|
||||
lnk_push_input_from_lazy(Arena *arena, PathStyle path_style, LNK_LazySymbol *lazy, LNK_InputImportList *input_import_list, LNK_InputObjList *input_obj_list)
|
||||
{
|
||||
// parse member
|
||||
COFF_ArchiveMember member_info = coff_read_archive_member(lazy->lib->data, lazy->member_offset);
|
||||
COFF_ArchiveMember member_info = coff_archive_member_from_offset(lazy->lib->data, lazy->member_offset);
|
||||
COFF_DataType member_type = coff_data_type_from_data(member_info.data);
|
||||
|
||||
switch (member_type) {
|
||||
@@ -1231,7 +1231,7 @@ lnk_push_input_from_lazy(Arena *arena, PathStyle path_style, LNK_LazySymbol *laz
|
||||
} break;
|
||||
case COFF_DataType_BIG_OBJ:
|
||||
case COFF_DataType_OBJ: {
|
||||
String8 obj_path = coff_read_archive_long_name(lazy->lib->long_names, member_info.header.name);
|
||||
String8 obj_path = coff_parse_long_name(lazy->lib->long_names, member_info.header.name);
|
||||
|
||||
// obj path in thin archive has slash appended which screws up
|
||||
// file lookup on disk; it couble be there to enable paths to symbols
|
||||
|
||||
+16
-13
@@ -109,25 +109,28 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path)
|
||||
lnk_not_implemented("TODO: data is not archive");
|
||||
}
|
||||
|
||||
COFF_ArchiveParse parse = coff_archive_parse_from_data(arena, data);
|
||||
COFF_ArchiveParse parse = coff_archive_parse_from_data(data);
|
||||
|
||||
// report archive parser errors
|
||||
if (parse.error.size) {
|
||||
lnk_error(LNK_Error_IllData, "%S: %S", path, parse.error);
|
||||
}
|
||||
|
||||
// try to init library from optional second member
|
||||
if (parse.second_member.member_count) {
|
||||
COFF_ArchiveSecondMember second_member = parse.second_member;
|
||||
Assert(second_member.symbol_count == second_member.symbol_indices.size / sizeof(U16));
|
||||
Assert(second_member.member_count == second_member.member_offsets.size / sizeof(U32));
|
||||
Assert(second_member.symbol_count == second_member.symbol_index_count);
|
||||
Assert(second_member.member_count == second_member.member_offset_count);
|
||||
|
||||
symbol_count = second_member.symbol_count;
|
||||
string_table = second_member.string_table;
|
||||
member_off_arr = push_array_no_zero(arena, U32, symbol_count);
|
||||
|
||||
// decompress member offsets
|
||||
U32 *comp_off_arr = (U32*)second_member.member_offsets.str;
|
||||
U16 *off_number_arr = (U16*)second_member.symbol_indices.str;
|
||||
for (U64 symbol_idx = 0; symbol_idx < symbol_count; symbol_idx += 1) {
|
||||
U16 off_number = off_number_arr[symbol_idx];
|
||||
U16 off_number = second_member.symbol_indices[symbol_idx];
|
||||
if (0 < off_number && off_number <= second_member.member_count) {
|
||||
member_off_arr[symbol_idx] = comp_off_arr[off_number - 1];
|
||||
member_off_arr[symbol_idx] = second_member.member_offsets[off_number - 1];
|
||||
} else {
|
||||
// TODO: log bad offset
|
||||
member_off_arr[symbol_idx] = max_U32;
|
||||
@@ -138,19 +141,19 @@ lnk_lib_from_data(Arena *arena, String8 data, String8 path)
|
||||
// and lld-link with /DLL emits only first member
|
||||
else if (parse.first_member.symbol_count) {
|
||||
COFF_ArchiveFirstMember first_member = parse.first_member;
|
||||
Assert(first_member.symbol_count == first_member.member_offsets.size / sizeof(U32));
|
||||
Assert(first_member.symbol_count == first_member.member_offset_count);
|
||||
|
||||
symbol_count = first_member.symbol_count;
|
||||
string_table = first_member.string_table;
|
||||
member_off_arr = (U32*)first_member.member_offsets.str;
|
||||
member_off_arr = first_member.member_offsets;
|
||||
|
||||
// convert big endian offsets
|
||||
for (U32 offset_idx = 0; offset_idx < symbol_count; offset_idx += 1) {
|
||||
member_off_arr[offset_idx] = BE_U32(member_off_arr[offset_idx]);
|
||||
member_off_arr[offset_idx] = from_be_u32(member_off_arr[offset_idx]);
|
||||
}
|
||||
} else {
|
||||
symbol_count = 0;
|
||||
string_table = str8(0,0);
|
||||
string_table = str8_zero();
|
||||
member_off_arr = 0;
|
||||
}
|
||||
|
||||
@@ -472,7 +475,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
|
||||
// first linker member (obsolete, but kept for compatability reasons)
|
||||
{
|
||||
U32 symbol_count_be = BE_U32(symbol_count);
|
||||
U32 symbol_count_be = from_be_u32(symbol_count);
|
||||
U32 *member_off32_arr = push_array_no_zero(scratch.arena, U32, symbol_count);
|
||||
|
||||
for (U64 symbol_idx = 0; symbol_idx < symbol_count; symbol_idx += 1) {
|
||||
@@ -480,7 +483,7 @@ lnk_coff_archive_from_lib_build(Arena *arena, LNK_LibBuild *lib, B32 emit_second
|
||||
|
||||
// write big endian member offset
|
||||
U64 member_off = member_base_off + member_off_arr[symbol->member_idx];
|
||||
U32 member_off32 = BE_U32(safe_cast_u32(member_off));
|
||||
U32 member_off32 = from_be_u32(safe_cast_u32(member_off));
|
||||
member_off32_arr[symbol_idx] = member_off32;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ THREAD_POOL_TASK_FUNC(lnk_obj_initer)
|
||||
COFF_SectionHeader *coff_sect = &coff_sect_arr[sect_idx];
|
||||
|
||||
// read name
|
||||
String8 sect_name = coff_section_header_get_name(coff_sect, input->data, coff_info.string_table_off);
|
||||
String8 sect_name = coff_name_from_section_header(coff_sect, input->data, coff_info.string_table_off);
|
||||
|
||||
// parse section name
|
||||
String8 name, postfix;
|
||||
|
||||
Reference in New Issue
Block a user