mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-08 23:08:08 +00:00
group forwarder and named exports and sort them together
This commit is contained in:
@@ -75,18 +75,16 @@ pe_export_parse_list_concat_in_place(PE_ExportParseList *list, PE_ExportParseLis
|
||||
internal int
|
||||
pe_named_export_is_before(void *raw_a, void *raw_b)
|
||||
{
|
||||
PE_ExportParse *a = *(PE_ExportParse **)raw_a;
|
||||
PE_ExportParse *b = *(PE_ExportParse **)raw_b;
|
||||
int cmp = str8_compar_case_sensitive(&a->name, &b->name);
|
||||
return cmp < 0;
|
||||
PE_ExportParse *a = *(PE_ExportParse **)raw_a, *b = *(PE_ExportParse **)raw_b;
|
||||
String8 name_a = a->alias.size ? a->alias : a->name;
|
||||
String8 name_b = b->alias.size ? b->alias : b->name;
|
||||
return str8_compar_case_sensitive(&name_a, &name_b) < 0;
|
||||
}
|
||||
|
||||
internal int
|
||||
pe_ordinal_export_is_before(void *raw_a, void *raw_b)
|
||||
{
|
||||
PE_ExportParse *a = raw_a;
|
||||
PE_ExportParse *b = raw_b;
|
||||
return a->ordinal < b->ordinal;
|
||||
return ((PE_ExportParse * )raw_a)->ordinal < ((PE_ExportParse *)raw_b)->ordinal;
|
||||
}
|
||||
|
||||
internal PE_FinalizedExports
|
||||
@@ -94,17 +92,13 @@ pe_finalize_export_list(Arena *arena, PE_ExportParseList export_list)
|
||||
{
|
||||
PE_ExportParsePtrArray named_exports = {0};
|
||||
PE_ExportParsePtrArray ordinal_exports = {0};
|
||||
PE_ExportParsePtrArray forwarder_exports = {0};
|
||||
{
|
||||
// group exports based on flags
|
||||
PE_ExportParseList named_exports_list = {0};
|
||||
PE_ExportParseList ordinal_exports_list = {0};
|
||||
PE_ExportParseList forwarder_exports_list = {0};
|
||||
for (PE_ExportParseNode *exp_n = export_list.first, *exp_n_next; exp_n != 0; exp_n = exp_n_next) {
|
||||
exp_n_next = exp_n->next;
|
||||
if (exp_n->data.is_forwarder) {
|
||||
pe_export_parse_list_push_node(&forwarder_exports_list, exp_n);
|
||||
} else if (exp_n->data.is_noname_present) {
|
||||
if (exp_n->data.is_noname_present) {
|
||||
AssertAlways(exp_n->data.is_ordinal_assigned);
|
||||
pe_export_parse_list_push_node(&ordinal_exports_list, exp_n);
|
||||
} else {
|
||||
@@ -114,28 +108,28 @@ pe_finalize_export_list(Arena *arena, PE_ExportParseList export_list)
|
||||
|
||||
// list -> array
|
||||
named_exports = pe_array_from_export_list(arena, named_exports_list);
|
||||
forwarder_exports = pe_array_from_export_list(arena, forwarder_exports_list);
|
||||
ordinal_exports = pe_array_from_export_list(arena, ordinal_exports_list);
|
||||
|
||||
for(int i = 0; i < ordinal_exports.count; ++i) {
|
||||
PE_ExportParse p = *ordinal_exports.v[i];
|
||||
}
|
||||
|
||||
// sort exports
|
||||
radsort(named_exports.v, named_exports.count, pe_named_export_is_before);
|
||||
radsort(ordinal_exports.v, ordinal_exports.count, pe_ordinal_export_is_before);
|
||||
radsort(forwarder_exports.v, forwarder_exports.count, pe_named_export_is_before);
|
||||
|
||||
MemoryZeroStruct(&export_list);
|
||||
pe_export_parse_list_concat_in_place(&export_list, &named_exports_list);
|
||||
pe_export_parse_list_concat_in_place(&export_list, &forwarder_exports_list);
|
||||
pe_export_parse_list_concat_in_place(&export_list, &ordinal_exports_list);
|
||||
}
|
||||
|
||||
// compute max ordinal and used ordinal flag array
|
||||
U64 ordinal_low = max_U64;
|
||||
B8 *is_ordinal_used = push_array(arena, B8, max_U16);
|
||||
for (PE_ExportParseNode *exp_n = export_list.first; exp_n != 0; exp_n = exp_n->next) {
|
||||
PE_ExportParse *exp = &exp_n->data;
|
||||
if (exp->is_ordinal_assigned) {
|
||||
ordinal_low = Min(ordinal_low, exp->ordinal);
|
||||
is_ordinal_used[exp->ordinal] = 1;
|
||||
for EachNode(exp_n, PE_ExportParseNode, export_list.first) {
|
||||
if (exp_n->data.is_ordinal_assigned) {
|
||||
ordinal_low = Min(ordinal_low, exp_n->data.ordinal);
|
||||
is_ordinal_used[exp_n->data.ordinal] = 1;
|
||||
}
|
||||
}
|
||||
if (ordinal_low == max_U64) {
|
||||
@@ -154,15 +148,6 @@ pe_finalize_export_list(Arena *arena, PE_ExportParseList export_list)
|
||||
is_ordinal_used[last_ordinal] = 1;
|
||||
}
|
||||
}
|
||||
for (U64 exp_idx = 0; exp_idx < forwarder_exports.count; exp_idx += 1) {
|
||||
PE_ExportParse *exp = forwarder_exports.v[exp_idx];
|
||||
if (!exp->is_ordinal_assigned) {
|
||||
for (; last_ordinal < max_U16 && is_ordinal_used[last_ordinal] != 0; last_ordinal += 1);
|
||||
exp->ordinal = last_ordinal;
|
||||
exp->is_ordinal_assigned = 1;
|
||||
is_ordinal_used[last_ordinal] = 1;
|
||||
}
|
||||
}
|
||||
for (U64 exp_idx = 0; exp_idx < ordinal_exports.count; exp_idx += 1) {
|
||||
PE_ExportParse *exp = ordinal_exports.v[exp_idx];
|
||||
if (!exp->is_ordinal_assigned) {
|
||||
@@ -179,18 +164,13 @@ pe_finalize_export_list(Arena *arena, PE_ExportParseList export_list)
|
||||
for (U64 exp_idx = 0; exp_idx < named_exports.count; exp_idx += 1, hint += 1) {
|
||||
named_exports.v[exp_idx]->hint = hint;
|
||||
}
|
||||
for (U64 exp_idx = 0; exp_idx < forwarder_exports.count; exp_idx += 1, hint += 1) {
|
||||
forwarder_exports.v[exp_idx]->hint = hint;
|
||||
}
|
||||
}
|
||||
|
||||
PE_FinalizedExports result = {0};
|
||||
result.ordinal_low = ordinal_low;
|
||||
result.named_exports = named_exports;
|
||||
result.forwarder_exports = forwarder_exports;
|
||||
result.ordinal_exports = ordinal_exports;
|
||||
|
||||
return result;
|
||||
return (PE_FinalizedExports) {
|
||||
.ordinal_low = ordinal_low,
|
||||
.named_exports = named_exports,
|
||||
.ordinal_exports = ordinal_exports
|
||||
};
|
||||
}
|
||||
|
||||
internal String8
|
||||
@@ -214,37 +194,37 @@ pe_make_edata_obj(Arena *arena,
|
||||
ProfBegin("Virtual Offset Table");
|
||||
{
|
||||
B8 *is_ordinal_bound = push_array(scratch.arena, B8, max_U16);
|
||||
|
||||
for (U64 arr_idx = 0; arr_idx < ArrayCount(finalized_exports.all); arr_idx += 1) {
|
||||
for (U64 exp_idx = 0; exp_idx < finalized_exports.all[arr_idx].count; exp_idx += 1) {
|
||||
for EachElement(arr_idx, finalized_exports.all) {
|
||||
for EachIndex(exp_idx, finalized_exports.all[arr_idx].count) {
|
||||
PE_ExportParse *exp = finalized_exports.all[arr_idx].v[exp_idx];
|
||||
if (is_ordinal_bound[exp->ordinal] == 0) {
|
||||
// alloc only one slot per ordinal, so it's possible to map ordinal to a virtual offset
|
||||
|
||||
// export with this ordinal was already allocated
|
||||
if (is_ordinal_bound[exp->ordinal]) { continue; }
|
||||
is_ordinal_bound[exp->ordinal] = 1;
|
||||
|
||||
// create symbol for the export address table entry
|
||||
COFF_ObjSymbol *exp_symbol;
|
||||
if (exp->is_forwarder) {
|
||||
// symbol to the forwarder string
|
||||
U64 fwd_name_offset = string_table_sect->data.total_size;
|
||||
str8_list_push(obj_writer->arena, &string_table_sect->data, push_cstr(obj_writer->arena, exp->name));
|
||||
exp_symbol = coff_obj_writer_push_symbol_static(obj_writer, exp->name, fwd_name_offset, string_table_sect);
|
||||
} else {
|
||||
// function or data symbol
|
||||
exp_symbol = coff_obj_writer_push_symbol_undef(obj_writer, exp->name);
|
||||
}
|
||||
|
||||
// create slot for the ordinal virtual offset
|
||||
U64 voff_offset = voff_table_sect->data.total_size;
|
||||
U32 *voff = push_array(obj_writer->arena, U32, 1);
|
||||
str8_list_push(obj_writer->arena, &voff_table_sect->data, str8_struct(voff));
|
||||
|
||||
COFF_ObjSymbol *exp_symbol;
|
||||
if (exp->is_forwarder) {
|
||||
U64 forwarder_name_offset = string_table_sect->data.total_size;
|
||||
String8 forwarder_name_cstr = push_cstr(obj_writer->arena, exp->name);
|
||||
str8_list_push(obj_writer->arena, &string_table_sect->data, forwarder_name_cstr);
|
||||
// symbol to the name string
|
||||
exp_symbol = coff_obj_writer_push_symbol_static(obj_writer, exp->name, forwarder_name_offset, string_table_sect);
|
||||
} else {
|
||||
// function or global var symbol
|
||||
exp_symbol = coff_obj_writer_push_symbol_undef(obj_writer, exp->name);
|
||||
}
|
||||
|
||||
// ordinal is an index into the export address table
|
||||
U16 ordinal_nb = exp->ordinal - finalized_exports.ordinal_low;
|
||||
coff_obj_writer_section_push_reloc_voff(obj_writer, voff_table_sect, ordinal_nb*sizeof(U32), exp_symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
|
||||
ProfBegin("Named & Forwarder Exports");
|
||||
|
||||
@@ -45,11 +45,10 @@ typedef struct PE_FinalizedExports
|
||||
union {
|
||||
struct {
|
||||
PE_ExportParsePtrArray named_exports;
|
||||
PE_ExportParsePtrArray forwarder_exports;
|
||||
PE_ExportParsePtrArray ordinal_exports;
|
||||
};
|
||||
PE_ExportParsePtrArray exports_with_names[2];
|
||||
PE_ExportParsePtrArray all[3];
|
||||
PE_ExportParsePtrArray exports_with_names[1];
|
||||
PE_ExportParsePtrArray all[2];
|
||||
};
|
||||
} PE_FinalizedExports;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user