From 63e8fb86255ac97c31d368221be18850ad53039d Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 15 Jul 2023 08:46:35 +0930 Subject: Support NEXT_SECTION in ALIGNOF and SIZEOF This patch is aimed at making __bss_start properly aligned with the first of any bss-style sections following. Most of the work here involves keeping track of the last output section seen when processing the linker script. You can almost align __bss_start properly by using ${RELOCATING+. = ALIGN(${DATA_SDATA-${NO_SMALL_DATA-ALIGNOF(.${SBSS_NAME}) != 0 ? ALIGNOF(.${SBSS_NAME}) : }}${BSS_PLT+ALIGNOF(.plt) != 0 ? ALIGNOF(.plt) : }ALIGNOF(.${BSS_NAME}));} and changing every place that defines NO_SMALL_DATA to use " ", but having two .plt sections (marked SPECIAL) on some backends foils that idea. The problem is that you only want to pick up the following .plt, not the one preceeding __bss_start in the data segment if the backend decides that is the proper .plt section. Perhaps that could be fixed too, but I decided instead to extend the linker script a little. THIS_SECTION and PREV_SECTION could easily be added too. * ld.texi (ALIGNOF, SIZEOF): Update and mention NEXT_SECTION. * ldexp.c (output_section_find): New function. (fold_name ): Use output_section_find. (exp_fold_tree): Add os parameter. Adjust all calls. (exp_fold_tree_no_dot, exp_get_vma, exp_get_power): Likewise. * ldexp.h (struct ldexp_control): Add last_os. (exp_fold_tree, exp_fold_tree_no_dot): Update prototypes. (exp_get_vma, exp_get_power): Likewise. * ldlang.c: Pass last output section to expression folder calls throughout file. (open_input_bfds): Add os parameter to track last os seen. (lang_size_sections_1): Rename output_section_statement param to current_os. Track last os. (lang_do_assignments_1): Track last os. * scripttempl/arclinux.sc: Align to ALIGNOF NEXT_SECTION before defining __bss_start. * scripttempl/elf.sc: Likewise. * scripttempl/elf64bpf.sc: Likewise. * scripttempl/elf64hppa.sc: Likewise. * scripttempl/elf_chaos.sc: Likewise. * scripttempl/elfarc.sc: Likewise. * scripttempl/elfd10v.sc: Likewise. * scripttempl/elfxtensa.sc: Likewise. * scripttempl/epiphany_4x4.sc: Likewise. * scripttempl/iq2000.sc: Likewise. * scripttempl/mep.sc: Likewise. * scripttempl/nds32elf.sc: Likewise. * scripttempl/xstormy16.sc: Likewise. * testsuite/ld-x86-64/pe-x86-64-5.od: Update expected __bss_start. * testsuite/ld-x86-64/pe-x86-64-5.rd: Likewise. --- ld/ld.texi | 21 +++-- ld/ldexp.c | 43 ++++++++--- ld/ldexp.h | 20 +++-- ld/ldlang.c | 141 +++++++++++++++++----------------- ld/scripttempl/arclinux.sc | 2 +- ld/scripttempl/elf.sc | 2 +- ld/scripttempl/elf64bpf.sc | 2 +- ld/scripttempl/elf64hppa.sc | 1 + ld/scripttempl/elf_chaos.sc | 1 + ld/scripttempl/elfarc.sc | 1 + ld/scripttempl/elfd10v.sc | 1 + ld/scripttempl/elfxtensa.sc | 1 + ld/scripttempl/epiphany_4x4.sc | 2 +- ld/scripttempl/iq2000.sc | 1 + ld/scripttempl/mep.sc | 1 + ld/scripttempl/nds32elf.sc | 2 +- ld/scripttempl/xstormy16.sc | 1 + ld/testsuite/ld-x86-64/pe-x86-64-5.od | 2 +- ld/testsuite/ld-x86-64/pe-x86-64-5.rd | 2 +- 19 files changed, 149 insertions(+), 98 deletions(-) (limited to 'ld') diff --git a/ld/ld.texi b/ld/ld.texi index 40d388a..406e87e 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -7114,10 +7114,13 @@ The builtin function @code{NEXT} is closely related to @code{ALIGN}. @kindex ALIGNOF(@var{section}) @cindex section alignment Return the alignment in bytes of the named @var{section}, if that section has -been allocated. If the section has not been allocated when this is -evaluated, the linker will report an error. In the following example, -the alignment of the @code{.output} section is stored as the first -value in that section. +been allocated, or zero if the section has not been allocated. If the +section does not exist in the linker script the linker will report an +error. If @var{section} is @code{NEXT_SECTION} then @code{ALIGNOF} will +return the alignment of the next allocated section specified in the +linker script, or zero if there is no such section. In the following +example, the alignment of the @code{.output} section is stored as the +first value in that section. @smallexample @group SECTIONS@{ @dots{} @@ -7266,9 +7269,13 @@ name. @kindex SIZEOF(@var{section}) @cindex section size Return the size in bytes of the named @var{section}, if that section has -been allocated. If the section has not been allocated when this is -evaluated, the linker will report an error. In the following example, -@code{symbol_1} and @code{symbol_2} are assigned identical values: +been allocated, or zero if the section has not been allocated. If the +section does not exist in the linker script the linker will report an +error. If @var{section} is @code{NEXT_SECTION} then @code{SIZEOF} will +return the alignment of the next allocated section specified in the +linker script, or zero if there is no such section. In the following +example, @code{symbol_1} and @code{symbol_2} are assigned identical +values: @smallexample @group SECTIONS@{ @dots{} diff --git a/ld/ldexp.c b/ld/ldexp.c index 170e1ed..8b9d6dc 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -691,6 +691,24 @@ fold_trinary (etree_type *tree) : tree->trinary.rhs); } +static lang_output_section_statement_type * +output_section_find (const char *name) +{ + lang_output_section_statement_type *os = lang_output_section_find (name); + + if (os == NULL && strcmp (name, "NEXT_SECTION") == 0) + { + os = expld.last_os; + if (os != NULL) + while ((os = os->next) != NULL) + if (os->constraint >= 0 && os->bfd_section != NULL) + break; + if (os == NULL) + os = abs_output_section; + } + return os; +} + static void fold_name (etree_type *tree) { @@ -850,7 +868,7 @@ fold_name (etree_type *tree) { lang_output_section_statement_type *os; - os = lang_output_section_find (tree->name.name); + os = output_section_find (tree->name.name); if (os == NULL) { if (expld.phase == lang_final_phase_enum) @@ -1270,29 +1288,32 @@ exp_fold_tree_1 (etree_type *tree) } void -exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) +exp_fold_tree (etree_type *tree, lang_output_section_statement_type *os, + asection *current_section, bfd_vma *dotp) { expld.rel_from_abs = false; expld.dot = *dotp; expld.dotp = dotp; expld.section = current_section; + expld.last_os = os; exp_fold_tree_1 (tree); } void -exp_fold_tree_no_dot (etree_type *tree) +exp_fold_tree_no_dot (etree_type *tree, lang_output_section_statement_type *os) { expld.rel_from_abs = false; expld.dot = 0; expld.dotp = NULL; expld.section = bfd_abs_section_ptr; + expld.last_os = os; exp_fold_tree_1 (tree); } static void exp_value_fold (etree_type *tree) { - exp_fold_tree_no_dot (tree); + exp_fold_tree_no_dot (tree, NULL); if (expld.result.valid_p) { tree->type.node_code = INT; @@ -1547,11 +1568,12 @@ exp_print_tree (etree_type *tree) } bfd_vma -exp_get_vma (etree_type *tree, bfd_vma def, char *name) +exp_get_vma (etree_type *tree, lang_output_section_statement_type *os, + bfd_vma def, char *name) { if (tree != NULL) { - exp_fold_tree_no_dot (tree); + exp_fold_tree_no_dot (tree, os); if (expld.result.valid_p) return expld.result.value; else if (name != NULL && expld.phase != lang_mark_phase_enum) @@ -1567,9 +1589,10 @@ exp_get_vma (etree_type *tree, bfd_vma def, char *name) NULL or cannot be resolved, return -1. */ int -exp_get_power (etree_type *tree, char *name) +exp_get_power (etree_type *tree, lang_output_section_statement_type *os, + char *name) { - bfd_vma x = exp_get_vma (tree, -1, name); + bfd_vma x = exp_get_vma (tree, os, -1, name); bfd_vma p2; int n; @@ -1593,7 +1616,7 @@ exp_get_fill (etree_type *tree, fill_type *def, char *name) if (tree == NULL) return def; - exp_fold_tree_no_dot (tree); + exp_fold_tree_no_dot (tree, NULL); if (!expld.result.valid_p) { if (name != NULL && expld.phase != lang_mark_phase_enum) @@ -1647,7 +1670,7 @@ exp_get_abs_int (etree_type *tree, int def, char *name) { if (tree != NULL) { - exp_fold_tree_no_dot (tree); + exp_fold_tree_no_dot (tree, NULL); if (expld.result.valid_p) { diff --git a/ld/ldexp.h b/ld/ldexp.h index 70908c1..7c30275 100644 --- a/ld/ldexp.h +++ b/ld/ldexp.h @@ -133,6 +133,8 @@ enum relro_enum { exp_seg_relro_end, }; +struct lang_output_section_statement_struct; + typedef struct { enum phase_enum phase; @@ -176,10 +178,17 @@ struct ldexp_control { etree_value_type result; bfd_vma dot; - /* Current dot and section passed to ldexp folder. */ + /* Current dot and section passed to ldexp folder. SECTION will be + bfd_abs_section for expressions outside of an output section + statement. */ bfd_vma *dotp; asection *section; + /* Last output section statement. For expressions within an output + section statement, this will be the current output section + statement being processed. */ + struct lang_output_section_statement_struct *last_os; + /* State machine and results for DATASEG. */ seg_align_type dataseg; }; @@ -211,9 +220,10 @@ etree_type *exp_bigintop etree_type *exp_relop (asection *, bfd_vma); void exp_fold_tree - (etree_type *, asection *, bfd_vma *); + (etree_type *, struct lang_output_section_statement_struct *, + asection *, bfd_vma *); void exp_fold_tree_no_dot - (etree_type *); + (etree_type *, struct lang_output_section_statement_struct *); etree_type *exp_binop (int, etree_type *, etree_type *); etree_type *exp_trinop @@ -233,9 +243,9 @@ etree_type *exp_assert void exp_print_tree (etree_type *); bfd_vma exp_get_vma - (etree_type *, bfd_vma, char *); + (etree_type *, struct lang_output_section_statement_struct *, bfd_vma, char *); int exp_get_power - (etree_type *, char *); + (etree_type *, struct lang_output_section_statement_struct *, char *); fill_type *exp_get_fill (etree_type *, fill_type *, char *); bfd_vma exp_get_abs_int diff --git a/ld/ldlang.c b/ld/ldlang.c index b3a89bf..4b86c16 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -2433,7 +2433,7 @@ init_os (lang_output_section_statement_type *s, flagword flags) /* If supplied an alignment, set it. */ if (s->section_alignment != NULL) - s->bfd_section->alignment_power = exp_get_power (s->section_alignment, + s->bfd_section->alignment_power = exp_get_power (s->section_alignment, s, "section alignment"); } @@ -3488,17 +3488,20 @@ static struct bfd_link_hash_entry *plugin_undefs = NULL; #endif static void -open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) +open_input_bfds (lang_statement_union_type *s, + lang_output_section_statement_type *os, + enum open_bfd_mode mode) { for (; s != NULL; s = s->header.next) { switch (s->header.type) { case lang_constructors_statement_enum: - open_input_bfds (constructor_list.head, mode); + open_input_bfds (constructor_list.head, os, mode); break; case lang_output_section_statement_enum: - open_input_bfds (s->output_section_statement.children.head, mode); + os = &s->output_section_statement; + open_input_bfds (os->children.head, os, mode); break; case lang_wild_statement_enum: /* Maybe we should load the file's symbols. */ @@ -3507,7 +3510,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) && !wildcardp (s->wild_statement.filename) && !archive_path (s->wild_statement.filename)) lookup_name (s->wild_statement.filename); - open_input_bfds (s->wild_statement.children.head, mode); + open_input_bfds (s->wild_statement.children.head, os, mode); break; case lang_group_statement_enum: { @@ -3526,7 +3529,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) plugin_insert_save = plugin_insert; #endif undefs = link_info.hash->undefs_tail; - open_input_bfds (s->group_statement.children.head, + open_input_bfds (s->group_statement.children.head, os, mode | OPEN_BFD_FORCE); } while (undefs != link_info.hash->undefs_tail @@ -3613,7 +3616,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) break; case lang_assignment_statement_enum: if (s->assignment_statement.exp->type.node_class != etree_assert) - exp_fold_tree_no_dot (s->assignment_statement.exp); + exp_fold_tree_no_dot (s->assignment_statement.exp, os); break; default: break; @@ -4221,7 +4224,7 @@ map_input_to_output_sections } else { - exp_fold_tree_no_dot (os->sectype_value); + exp_fold_tree_no_dot (os->sectype_value, os); if (expld.result.valid_p) type = expld.result.value; else @@ -4648,6 +4651,7 @@ print_output_section_statement if (output_section_statement->update_dot_tree != NULL) exp_fold_tree (output_section_statement->update_dot_tree, + output_section_statement, bfd_abs_section_ptr, &print_dot); } @@ -4686,7 +4690,7 @@ print_assignment (lang_assignment_statement_type *assignment, osec = bfd_abs_section_ptr; if (assignment->exp->type.node_class != etree_provide) - exp_fold_tree (tree, osec, &print_dot); + exp_fold_tree (tree, output_section, osec, &print_dot); else expld.result.valid_p = false; @@ -5417,6 +5421,7 @@ size_input_section if (output_section_statement->subsection_alignment != NULL) i->alignment_power = exp_get_power (output_section_statement->subsection_alignment, + output_section_statement, "subsection alignment"); if (o->alignment_power < i->alignment_power) @@ -5755,7 +5760,7 @@ ldlang_check_relro_region (lang_statement_union_type *s) static bfd_vma lang_size_sections_1 (lang_statement_union_type **prev, - lang_output_section_statement_type *output_section_statement, + lang_output_section_statement_type *current_os, fill_type *fill, bfd_vma dot, bool *relax, @@ -5764,6 +5769,7 @@ lang_size_sections_1 lang_statement_union_type *s; lang_statement_union_type *prev_s = NULL; bool removed_prev_s = false; + lang_output_section_statement_type *os = current_os; /* Size up the sections from their constituent parts. */ for (s = *prev; s != NULL; prev_s = s, s = s->header.next) @@ -5775,7 +5781,6 @@ lang_size_sections_1 case lang_output_section_statement_enum: { bfd_vma newdot, after, dotdelta; - lang_output_section_statement_type *os; lang_memory_region_type *r; int section_alignment = 0; @@ -5794,7 +5799,7 @@ lang_size_sections_1 os->addr_tree = exp_intop (0); if (os->addr_tree != NULL) { - exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot); + exp_fold_tree (os->addr_tree, os, bfd_abs_section_ptr, &dot); if (expld.result.valid_p) { @@ -5899,7 +5904,7 @@ lang_size_sections_1 section_alignment = os->bfd_section->alignment_power; } else - section_alignment = exp_get_power (os->section_alignment, + section_alignment = exp_get_power (os->section_alignment, os, "section alignment"); /* Align to what the section needs. */ @@ -5987,6 +5992,7 @@ lang_size_sections_1 statement. */ if (os->lma_region != os->region) section_alignment = exp_get_power (os->section_alignment, + os, "section alignment"); if (section_alignment > 0) lma = align_power (lma, section_alignment); @@ -6076,7 +6082,7 @@ lang_size_sections_1 dot += dotdelta; if (os->update_dot_tree != 0) - exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot); + exp_fold_tree (os->update_dot_tree, os, bfd_abs_section_ptr, &dot); /* Update dot in the region ? We only do this if the section is going to be allocated, @@ -6107,8 +6113,7 @@ lang_size_sections_1 break; case lang_constructors_statement_enum: - dot = lang_size_sections_1 (&constructor_list.head, - output_section_statement, + dot = lang_size_sections_1 (&constructor_list.head, current_os, fill, dot, relax, check_regions); break; @@ -6116,14 +6121,13 @@ lang_size_sections_1 { unsigned int size = 0; - s->data_statement.output_offset = - dot - output_section_statement->bfd_section->vma; - s->data_statement.output_section = - output_section_statement->bfd_section; + s->data_statement.output_offset = dot - current_os->bfd_section->vma; + s->data_statement.output_section = current_os->bfd_section; /* We might refer to provided symbols in the expression, and need to mark them as needed. */ - exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot); + exp_fold_tree (s->data_statement.exp, os, + bfd_abs_section_ptr, &dot); switch (s->data_statement.type) { @@ -6146,10 +6150,9 @@ lang_size_sections_1 if (size < TO_SIZE ((unsigned) 1)) size = TO_SIZE ((unsigned) 1); dot += TO_ADDR (size); - if (!(output_section_statement->bfd_section->flags - & SEC_FIXED_SIZE)) - output_section_statement->bfd_section->size - = TO_SIZE (dot - output_section_statement->bfd_section->vma); + if (!(current_os->bfd_section->flags & SEC_FIXED_SIZE)) + current_os->bfd_section->size + = TO_SIZE (dot - current_os->bfd_section->vma); } break; @@ -6158,29 +6161,27 @@ lang_size_sections_1 { int size; - s->reloc_statement.output_offset = - dot - output_section_statement->bfd_section->vma; - s->reloc_statement.output_section = - output_section_statement->bfd_section; + s->reloc_statement.output_offset + = dot - current_os->bfd_section->vma; + s->reloc_statement.output_section + = current_os->bfd_section; size = bfd_get_reloc_size (s->reloc_statement.howto); dot += TO_ADDR (size); - if (!(output_section_statement->bfd_section->flags - & SEC_FIXED_SIZE)) - output_section_statement->bfd_section->size - = TO_SIZE (dot - output_section_statement->bfd_section->vma); + if (!(current_os->bfd_section->flags & SEC_FIXED_SIZE)) + current_os->bfd_section->size + = TO_SIZE (dot - current_os->bfd_section->vma); } break; case lang_wild_statement_enum: dot = lang_size_sections_1 (&s->wild_statement.children.head, - output_section_statement, - fill, dot, relax, check_regions); + current_os, fill, dot, relax, + check_regions); break; case lang_object_symbols_statement_enum: - link_info.create_object_symbols_section - = output_section_statement->bfd_section; - output_section_statement->bfd_section->flags |= SEC_KEEP; + link_info.create_object_symbols_section = current_os->bfd_section; + current_os->bfd_section->flags |= SEC_KEEP; break; case lang_output_statement_enum: @@ -6201,8 +6202,7 @@ lang_size_sections_1 if (again) *relax = true; } - dot = size_input_section (prev, output_section_statement, - fill, &removed, dot); + dot = size_input_section (prev, current_os, fill, &removed, dot); } break; @@ -6210,8 +6210,7 @@ lang_size_sections_1 break; case lang_fill_statement_enum: - s->fill_statement.output_section = - output_section_statement->bfd_section; + s->fill_statement.output_section = current_os->bfd_section; fill = s->fill_statement.fill; break; @@ -6223,9 +6222,7 @@ lang_size_sections_1 expld.dataseg.relro = exp_seg_relro_none; - exp_fold_tree (tree, - output_section_statement->bfd_section, - &newdot); + exp_fold_tree (tree, os, current_os->bfd_section, &newdot); ldlang_check_relro_region (s); @@ -6236,11 +6233,11 @@ lang_size_sections_1 || tree->type.node_class == etree_assign) && (tree->assign.dst [0] != '.' || tree->assign.dst [1] != '\0')) - output_section_statement->update_dot = 1; + current_os->update_dot = 1; - if (!output_section_statement->ignored) + if (!current_os->ignored) { - if (output_section_statement == abs_output_section) + if (current_os == abs_output_section) { /* If we don't have an output section, then just adjust the default memory address. */ @@ -6253,7 +6250,7 @@ lang_size_sections_1 put the pad before when relaxing, in case the assignment references dot. */ insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot), - output_section_statement->bfd_section, dot); + current_os->bfd_section, dot); /* Don't neuter the pad below when relaxing. */ s = s->header.next; @@ -6262,11 +6259,11 @@ lang_size_sections_1 should have space allocated to it, unless the user has explicitly stated that the section should not be allocated. */ - if (output_section_statement->sectype != noalloc_section - && (output_section_statement->sectype != noload_section + if (current_os->sectype != noalloc_section + && (current_os->sectype != noload_section || (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour))) - output_section_statement->bfd_section->flags |= SEC_ALLOC; + current_os->bfd_section->flags |= SEC_ALLOC; } dot = newdot; } @@ -6287,13 +6284,13 @@ lang_size_sections_1 section. bfd_set_section_contents will complain even for a pad size of zero. */ s->padding_statement.output_offset - = dot - output_section_statement->bfd_section->vma; + = dot - current_os->bfd_section->vma; break; case lang_group_statement_enum: dot = lang_size_sections_1 (&s->group_statement.children.head, - output_section_statement, - fill, dot, relax, check_regions); + current_os, fill, dot, relax, + check_regions); break; case lang_insert_statement_enum: @@ -6540,6 +6537,8 @@ lang_do_assignments_1 (lang_statement_union_type *s, bfd_vma dot, bool *found_end) { + lang_output_section_statement_type *os = current_os; + for (; s != NULL; s = s->header.next) { switch (s->header.type) @@ -6551,10 +6550,9 @@ lang_do_assignments_1 (lang_statement_union_type *s, case lang_output_section_statement_enum: { - lang_output_section_statement_type *os; bfd_vma newdot; - os = &(s->output_section_statement); + os = &s->output_section_statement; os->after_end = *found_end; init_opb (os->bfd_section); newdot = dot; @@ -6581,7 +6579,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, newdot += TO_ADDR (os->bfd_section->size); if (os->update_dot_tree != NULL) - exp_fold_tree (os->update_dot_tree, + exp_fold_tree (os->update_dot_tree, os, bfd_abs_section_ptr, &newdot); } dot = newdot; @@ -6601,7 +6599,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, break; case lang_data_statement_enum: - exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot); + exp_fold_tree (s->data_statement.exp, os, bfd_abs_section_ptr, &dot); if (expld.result.valid_p) { s->data_statement.value = expld.result.value; @@ -6637,7 +6635,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, break; case lang_reloc_statement_enum: - exp_fold_tree (s->reloc_statement.addend_exp, + exp_fold_tree (s->reloc_statement.addend_exp, os, bfd_abs_section_ptr, &dot); if (expld.result.valid_p) s->reloc_statement.addend_value = expld.result.value; @@ -6676,7 +6674,7 @@ lang_do_assignments_1 (lang_statement_union_type *s, if (strcmp (p, "end") == 0) *found_end = true; } - exp_fold_tree (s->assignment_statement.exp, + exp_fold_tree (s->assignment_statement.exp, os, (current_os->bfd_section != NULL ? current_os->bfd_section : bfd_und_section_ptr), &dot); @@ -8106,7 +8104,7 @@ lang_process (void) /* Create a bfd for each input file. */ current_target = default_target; lang_statement_iteration++; - open_input_bfds (statement_list.head, OPEN_BFD_NORMAL); + open_input_bfds (statement_list.head, NULL, OPEN_BFD_NORMAL); /* Now that open_input_bfds has processed assignments and provide statements we can give values to symbolic origin/length now. */ @@ -8136,7 +8134,12 @@ lang_process (void) link_info.lto_all_symbols_read = true; /* Open any newly added files, updating the file chains. */ plugin_undefs = link_info.hash->undefs_tail; - open_input_bfds (*added.tail, OPEN_BFD_NORMAL); + lang_output_section_statement_type *last_os = NULL; + if (lang_os_list.head != NULL) + last_os = ((lang_output_section_statement_type *) + ((char *) lang_os_list.tail + - offsetof (lang_output_section_statement_type, next))); + open_input_bfds (*added.tail, last_os, OPEN_BFD_NORMAL); if (plugin_undefs == link_info.hash->undefs_tail) plugin_undefs = NULL; /* Restore the global list pointer now they have all been added. */ @@ -8187,7 +8190,7 @@ lang_process (void) /* Rescan archives in case new undefined symbols have appeared. */ files = file_chain; lang_statement_iteration++; - open_input_bfds (statement_list.head, OPEN_BFD_RESCAN); + open_input_bfds (statement_list.head, NULL, OPEN_BFD_RESCAN); lang_list_remove_tail (&file_chain, &files); while (files.head != NULL) { @@ -8842,7 +8845,7 @@ lang_new_phdr (const char *name, n = stat_alloc (sizeof (struct lang_phdr)); n->next = NULL; n->name = name; - n->type = exp_get_vma (type, 0, "program header type"); + n->type = exp_get_vma (type, NULL, 0, "program header type"); n->filehdr = filehdr; n->phdrs = phdrs; n->at = at; @@ -8956,12 +8959,12 @@ lang_record_phdrs (void) if (l->flags == NULL) flags = 0; else - flags = exp_get_vma (l->flags, 0, "phdr flags"); + flags = exp_get_vma (l->flags, NULL, 0, "phdr flags"); if (l->at == NULL) at = 0; else - at = exp_get_vma (l->at, 0, "phdr load address"); + at = exp_get_vma (l->at, NULL, 0, "phdr load address"); if (!bfd_record_phdr (link_info.output_bfd, l->type, l->flags != NULL, flags, l->at != NULL, @@ -9721,7 +9724,7 @@ lang_do_memory_regions (bool update_regions_p) { if (r->origin_exp) { - exp_fold_tree_no_dot (r->origin_exp); + exp_fold_tree_no_dot (r->origin_exp, NULL); if (update_regions_p) { if (expld.result.valid_p) @@ -9736,7 +9739,7 @@ lang_do_memory_regions (bool update_regions_p) } if (r->length_exp) { - exp_fold_tree_no_dot (r->length_exp); + exp_fold_tree_no_dot (r->length_exp, NULL); if (update_regions_p) { if (expld.result.valid_p) diff --git a/ld/scripttempl/arclinux.sc b/ld/scripttempl/arclinux.sc index 20429df..3c27625 100644 --- a/ld/scripttempl/arclinux.sc +++ b/ld/scripttempl/arclinux.sc @@ -613,7 +613,7 @@ cat <DATA} .bss ${RELOCATING-0} : diff --git a/ld/scripttempl/elfxtensa.sc b/ld/scripttempl/elfxtensa.sc index 7c71525..9c85d15 100644 --- a/ld/scripttempl/elfxtensa.sc +++ b/ld/scripttempl/elfxtensa.sc @@ -500,6 +500,7 @@ cat <