mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-15 00:22:23 -07:00
assign layout offsets and sizes to merged sections
This commit is contained in:
committed by
Ryan Fleury
parent
f75cdd23d7
commit
03e4958190
+34
-17
@@ -2281,6 +2281,11 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S
|
||||
{
|
||||
ProfBegin("Finalize Sections Layout");
|
||||
|
||||
// merge sections
|
||||
if (config->flags & LNK_ConfigFlag_Merge) {
|
||||
lnk_section_table_merge(sectab, config->merge_list);
|
||||
}
|
||||
|
||||
// sort contribs
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
for (LNK_SectionContribChunk *sc_chunk = sect_n->data.contribs.first; sc_chunk != 0; sc_chunk = sc_chunk->next) {
|
||||
@@ -2289,32 +2294,31 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S
|
||||
}
|
||||
}
|
||||
|
||||
// merge sections
|
||||
if (config->flags & LNK_ConfigFlag_Merge) {
|
||||
lnk_section_table_merge(sectab, config->merge_list);
|
||||
}
|
||||
|
||||
// assign contribs offsets, sizes, and section indices
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
lnk_finalize_section_layout(sectab, §_n->data, config->file_align);
|
||||
}
|
||||
|
||||
// remove empty sections
|
||||
String8List empty_sect_list = {0};
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
LNK_Section *sect = §_n->data;
|
||||
if (sect->vsize == 0) {
|
||||
str8_list_push(scratch.arena, &empty_sect_list, sect->name);
|
||||
{
|
||||
String8List empty_sect_list = {0};
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
LNK_Section *sect = §_n->data;
|
||||
if (sect->vsize == 0) {
|
||||
str8_list_push(scratch.arena, &empty_sect_list, sect->name);
|
||||
}
|
||||
}
|
||||
for (String8Node *name_n = empty_sect_list.first; name_n != 0; name_n = name_n->next) {
|
||||
lnk_section_table_remove(sectab, name_n->string);
|
||||
}
|
||||
}
|
||||
for (String8Node *name_n = empty_sect_list.first; name_n != 0; name_n = name_n->next) {
|
||||
lnk_section_table_remove(sectab, name_n->string);
|
||||
}
|
||||
|
||||
// assign section indices to sections
|
||||
U64 sect_idx = 0;
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
sect_n->data.sect_idx = sect_idx++;
|
||||
{
|
||||
U64 sect_idx = 0;
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
sect_n->data.sect_idx = sect_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
// assign section indices to contribs
|
||||
@@ -2327,6 +2331,19 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S
|
||||
}
|
||||
}
|
||||
|
||||
// assing layout offsets and sizes to merged sections
|
||||
for (LNK_SectionNode *sect_n = sectab->merge_list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
LNK_Section *sect = §_n->data;
|
||||
LNK_SectionContrib *first_sc = lnk_get_first_section_contrib(sect);
|
||||
LNK_SectionContrib *last_sc = lnk_get_last_section_contrib(sect);
|
||||
LNK_Section *final_sect = lnk_finalized_section_from_id(sectab, sect->merge_id);
|
||||
sect->voff = final_sect->voff + first_sc->u.off;
|
||||
sect->vsize = (last_sc->u.off - first_sc->u.off) + last_sc->u.size;
|
||||
sect->foff = final_sect->foff + first_sc->u.off;
|
||||
sect->fsize = (last_sc->u.off - first_sc->u.off) + last_sc->u.size;
|
||||
sect->sect_idx = final_sect->sect_idx;
|
||||
}
|
||||
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
@@ -3054,7 +3071,7 @@ lnk_build_win32_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_S
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
// patch Debug
|
||||
// patch debug
|
||||
{
|
||||
LNK_Section *debug_dir_sect = lnk_section_table_search(sectab, str8_lit(".RAD_LINKER_DEBUG_DIR"), PE_RDATA_SECTION_FLAGS);
|
||||
if (debug_dir_sect) {
|
||||
|
||||
@@ -1436,12 +1436,11 @@ lnk_apply_cmd_option_to_config(Arena *arena, LNK_Config *config, String8 cmd_nam
|
||||
|
||||
case LNK_CmdSwitch_Merge: {
|
||||
if (value_strings.node_count == 1) {
|
||||
LNK_MergeDirective merge = {0};;
|
||||
LNK_MergeDirective merge = {0};
|
||||
if (lnk_parse_merge_directive(push_str8_copy(arena, value_strings.first->string), &merge)) {
|
||||
lnk_merge_directive_list_push(arena, &config->merge_list, merge);
|
||||
} else {
|
||||
lnk_error_cmd_switch(LNK_Warning_InvalidMergeDirectiveFormat, obj_path, lib_path, cmd_switch, "invalid merge directive format expected \"/MERGE:FROM=TO\" but got \"%S\"",
|
||||
value_strings.first->string);
|
||||
lnk_error_cmd_switch(LNK_Warning_InvalidMergeDirectiveFormat, obj_path, lib_path, cmd_switch, "unable to parse merge directive, expected format \"/MERGE:FROM=TO\" but got \"%S\"", value_strings.first->string);
|
||||
}
|
||||
} else {
|
||||
lnk_error_cmd_switch(LNK_Error_Cmdl, obj_path, lib_path, cmd_switch, "invalid number of parameters %d", value_strings.node_count);
|
||||
|
||||
@@ -91,6 +91,17 @@ lnk_get_first_section_contrib(LNK_Section *sect)
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal LNK_SectionContrib *
|
||||
lnk_get_last_section_contrib(LNK_Section *sect)
|
||||
{
|
||||
if (sect->contribs.chunk_count > 0) {
|
||||
if (sect->contribs.last->count > 0) {
|
||||
return sect->contribs.last->v[0];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
internal LNK_SectionTable *
|
||||
lnk_section_table_alloc(void)
|
||||
{
|
||||
@@ -148,7 +159,7 @@ lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags
|
||||
return sect;
|
||||
}
|
||||
|
||||
internal void
|
||||
internal LNK_SectionNode *
|
||||
lnk_section_table_remove(LNK_SectionTable *sectab, String8 name)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
@@ -190,6 +201,7 @@ lnk_section_table_remove(LNK_SectionTable *sectab, String8 name)
|
||||
}
|
||||
|
||||
ProfEnd();
|
||||
return node;
|
||||
}
|
||||
|
||||
internal LNK_Section *
|
||||
@@ -210,8 +222,12 @@ lnk_section_table_search(LNK_SectionTable *sectab, String8 full_or_partial_name,
|
||||
}
|
||||
|
||||
internal LNK_SectionArray
|
||||
lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 name)
|
||||
lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name)
|
||||
{
|
||||
String8 name = {0};
|
||||
String8 postfix = {0};
|
||||
coff_parse_section_name(full_or_partial_name, &name, &postfix);
|
||||
|
||||
U64 match_count = 0;
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
if (str8_match(sect_n->data.name, name, 0)) {
|
||||
@@ -223,7 +239,7 @@ lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 na
|
||||
|
||||
if (match_count > 0) {
|
||||
result.count = 0;
|
||||
result.v = push_array(arena, LNK_Section *, match_count);
|
||||
result.v = push_array(arena, LNK_Section *, match_count);
|
||||
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
if (str8_match(sect_n->data.name, name, 0)) {
|
||||
@@ -307,9 +323,14 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l
|
||||
// merge section with destination
|
||||
lnk_section_contrib_chunk_list_concat_in_place(&dst->contribs, &src->contribs);
|
||||
src->is_merged = 1;
|
||||
src->merge_id = dst->id;
|
||||
|
||||
// remove from output section list
|
||||
lnk_section_table_remove(sectab, src->name);
|
||||
LNK_SectionNode *merge_node = lnk_section_table_remove(sectab, src->name);
|
||||
|
||||
// move node to the merge list
|
||||
SLLQueuePush(sectab->merge_list.first, sectab->merge_list.last, merge_node);
|
||||
sectab->merge_list.count += 1;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
@@ -387,3 +408,22 @@ lnk_assign_section_file_space(LNK_Section *sect, U64 *foff_cursor)
|
||||
}
|
||||
}
|
||||
|
||||
internal LNK_Section *
|
||||
lnk_finalized_section_from_id(LNK_SectionTable *sectab, U64 id)
|
||||
{
|
||||
for (LNK_SectionNode *sect_n = sectab->list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
if (sect_n->data.id == id) {
|
||||
return §_n->data;
|
||||
}
|
||||
}
|
||||
|
||||
for (LNK_SectionNode *sect_n = sectab->merge_list.first; sect_n != 0; sect_n = sect_n->next) {
|
||||
if (sect_n->data.id == id) {
|
||||
return lnk_finalized_section_from_id(sectab, sect_n->data.merge_id);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,12 +60,12 @@ typedef struct LNK_SectionDefinition
|
||||
|
||||
typedef struct LNK_Section
|
||||
{
|
||||
U64 id;
|
||||
String8 name;
|
||||
COFF_SectionFlags flags;
|
||||
B32 has_layout;
|
||||
B32 is_merged;
|
||||
|
||||
U64 id;
|
||||
String8 name;
|
||||
COFF_SectionFlags flags;
|
||||
B32 has_layout;
|
||||
B32 is_merged;
|
||||
U64 merge_id;
|
||||
LNK_SectionContribChunkList contribs;
|
||||
|
||||
U64 voff;
|
||||
@@ -101,7 +101,7 @@ typedef struct LNK_SectionTable
|
||||
U64 id_max;
|
||||
U64 next_sect_idx;
|
||||
LNK_SectionList list;
|
||||
LNK_SectionList free_list;
|
||||
LNK_SectionList merge_list;
|
||||
HashTable *sect_ht; // name -> LNK_Section *
|
||||
} LNK_SectionTable;
|
||||
|
||||
@@ -116,11 +116,18 @@ internal LNK_SectionArray lnk_section_array_from_list(Arena *arena, LNK_SectionL
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal LNK_SectionContrib * lnk_get_last_section_contrib(LNK_Section *sect);
|
||||
internal LNK_SectionTable * lnk_section_table_alloc(void);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal LNK_SectionTable * lnk_section_table_alloc(void);
|
||||
internal void lnk_section_table_release(LNK_SectionTable **st_ptr);
|
||||
internal LNK_Section * lnk_section_table_push(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
|
||||
internal void lnk_section_table_remove(LNK_SectionTable *sectab, String8 name);
|
||||
internal LNK_SectionNode * lnk_section_table_remove(LNK_SectionTable *sectab, String8 name);
|
||||
internal LNK_Section * lnk_section_table_search(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
|
||||
internal LNK_SectionArray lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name);
|
||||
internal void lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list);
|
||||
internal LNK_SectionArray lnk_section_table_get_output_sections(Arena *arena, LNK_SectionTable *sectab);
|
||||
internal LNK_Section * lnk_finalized_section_from_id(LNK_SectionTable *sectab, U64 id);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user