diff options
author | Alan Modra <amodra@gmail.com> | 2023-07-15 08:46:35 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2023-07-17 08:17:44 +0930 |
commit | 63e8fb86255ac97c31d368221be18850ad53039d (patch) | |
tree | 508341e8d8cdeab39688128e43308332161307f6 /ld | |
parent | 5c77898d60cfea469a86fc6026f51b4a6d8e7444 (diff) | |
download | gdb-63e8fb86255ac97c31d368221be18850ad53039d.zip gdb-63e8fb86255ac97c31d368221be18850ad53039d.tar.gz gdb-63e8fb86255ac97c31d368221be18850ad53039d.tar.bz2 |
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 <ALIGNOF, SIZEOF>): 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.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ld.texi | 21 | ||||
-rw-r--r-- | ld/ldexp.c | 43 | ||||
-rw-r--r-- | ld/ldexp.h | 20 | ||||
-rw-r--r-- | ld/ldlang.c | 141 | ||||
-rw-r--r-- | ld/scripttempl/arclinux.sc | 2 | ||||
-rw-r--r-- | ld/scripttempl/elf.sc | 2 | ||||
-rw-r--r-- | ld/scripttempl/elf64bpf.sc | 2 | ||||
-rw-r--r-- | ld/scripttempl/elf64hppa.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/elf_chaos.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/elfarc.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/elfd10v.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/elfxtensa.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/epiphany_4x4.sc | 2 | ||||
-rw-r--r-- | ld/scripttempl/iq2000.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/mep.sc | 1 | ||||
-rw-r--r-- | ld/scripttempl/nds32elf.sc | 2 | ||||
-rw-r--r-- | ld/scripttempl/xstormy16.sc | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pe-x86-64-5.od | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-x86-64/pe-x86-64-5.rd | 2 |
19 files changed, 149 insertions, 98 deletions
@@ -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{} @@ -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) { @@ -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 <<EOF ${DATA_SDATA-${SDATA}} ${DATA_SDATA-${OTHER_SDATA_SECTIONS}} ${RELOCATING+${DATA_END_SYMBOLS-${USER_LABEL_PREFIX}_edata = .; PROVIDE (${USER_LABEL_PREFIX}edata = .);}} - ${RELOCATING+. = .;} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+${USER_LABEL_PREFIX}__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${DATA_SDATA-${SBSS}} diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 82de4ed..fe921cd 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -689,7 +689,7 @@ cat <<EOF ${RELOCATING+${SYMBOL_ABI_ALIGNMENT+. = ALIGN(${SYMBOL_ABI_ALIGNMENT});}} ${RELOCATING+${DATA_END_SYMBOLS-${CREATE_SHLIB+PROVIDE (}$(def_symbol "_edata")${CREATE_SHLIB+)}; PROVIDE ($(def_symbol "edata"));}} ${PERSISTENT} - ${RELOCATING+. = .;} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+${CREATE_SHLIB+PROVIDE (}$(def_symbol "__bss_start")${CREATE_SHLIB+)};} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${DATA_SDATA-${SBSS}} diff --git a/ld/scripttempl/elf64bpf.sc b/ld/scripttempl/elf64bpf.sc index 7415458..07a0726 100644 --- a/ld/scripttempl/elf64bpf.sc +++ b/ld/scripttempl/elf64bpf.sc @@ -636,7 +636,7 @@ cat <<EOF ${DATA_SDATA-${SDATA}} ${DATA_SDATA-${OTHER_SDATA_SECTIONS}} ${RELOCATING+${DATA_END_SYMBOLS-${CREATE_SHLIB+PROVIDE (}${USER_LABEL_PREFIX}_edata = .${CREATE_SHLIB+)}; PROVIDE (${USER_LABEL_PREFIX}edata = .);}} - ${RELOCATING+. = .;} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+${CREATE_SHLIB+PROVIDE (}${USER_LABEL_PREFIX}__bss_start = .${CREATE_SHLIB+)};} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${DATA_SDATA-${SBSS}} diff --git a/ld/scripttempl/elf64hppa.sc b/ld/scripttempl/elf64hppa.sc index e85dd39..b3be5a2 100644 --- a/ld/scripttempl/elf64hppa.sc +++ b/ld/scripttempl/elf64hppa.sc @@ -490,6 +490,7 @@ cat <<EOF ${SDATA} ${OTHER_SDATA_SECTIONS} ${RELOCATING+${DATA_END_SYMBOLS-${USER_LABEL_PREFIX}_edata = .; PROVIDE (${USER_LABEL_PREFIX}edata = .);}} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/elf_chaos.sc b/ld/scripttempl/elf_chaos.sc index 72f91c9..88b573c 100644 --- a/ld/scripttempl/elf_chaos.sc +++ b/ld/scripttempl/elf_chaos.sc @@ -303,6 +303,7 @@ cat <<EOF ${OTHER_SDATA_SECTIONS} ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/elfarc.sc b/ld/scripttempl/elfarc.sc index 57cd0a5..1ae0248 100644 --- a/ld/scripttempl/elfarc.sc +++ b/ld/scripttempl/elfarc.sc @@ -365,6 +365,7 @@ cat <<EOF ${OTHER_SDATA_SECTIONS} ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/elfd10v.sc b/ld/scripttempl/elfd10v.sc index e52aaed..316fa89 100644 --- a/ld/scripttempl/elfd10v.sc +++ b/ld/scripttempl/elfd10v.sc @@ -156,6 +156,7 @@ SECTIONS ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} .sbss ${RELOCATING-0} : { *(.sbss)${RELOCATING+ *(.scommon)} } ${RELOCATING+ >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 <<EOF ${SDATA} ${OTHER_SDATA_SECTIONS} ${RELOCATING+${DATA_END_SYMBOLS-${USER_LABEL_PREFIX}_edata = .; PROVIDE (${USER_LABEL_PREFIX}edata = .);}} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/epiphany_4x4.sc b/ld/scripttempl/epiphany_4x4.sc index 0f4e74f..ee253af 100644 --- a/ld/scripttempl/epiphany_4x4.sc +++ b/ld/scripttempl/epiphany_4x4.sc @@ -578,7 +578,7 @@ cat <<EOF /* Align ___bss_start and _end to a multiple of 8 so that we can use strd to clear bss. N.B., without adding any extra alignment, we would have to clear the bss byte by byte. */ - ${RELOCATING+. = ALIGN(8);} + ${RELOCATING+. = ALIGN(MAX(8,ALIGNOF(NEXT_SECTION)));} ${RELOCATING+___bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/iq2000.sc b/ld/scripttempl/iq2000.sc index 47bd777..c3d3620 100644 --- a/ld/scripttempl/iq2000.sc +++ b/ld/scripttempl/iq2000.sc @@ -373,6 +373,7 @@ cat <<EOF ${RELOCATING+${OTHER_SDATA_SECTIONS}} ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} .sbss ${RELOCATING-0} : diff --git a/ld/scripttempl/mep.sc b/ld/scripttempl/mep.sc index 6b80c36..d49f848 100644 --- a/ld/scripttempl/mep.sc +++ b/ld/scripttempl/mep.sc @@ -385,6 +385,7 @@ cat <<EOF ${OTHER_SDATA_SECTIONS} ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/nds32elf.sc b/ld/scripttempl/nds32elf.sc index 9645e80..36d04cd 100644 --- a/ld/scripttempl/nds32elf.sc +++ b/ld/scripttempl/nds32elf.sc @@ -557,7 +557,7 @@ cat <<EOF ${OTHER_SDATA_SECTIONS} ${RELOCATING+. = ALIGN(4);} ${RELOCATING+${DATA_END_SYMBOLS-${USER_LABEL_PREFIX}_edata = .; PROVIDE (${USER_LABEL_PREFIX}edata = .);}} - ${RELOCATING+. = .;} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+${USER_LABEL_PREFIX}__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} ${SBSS} diff --git a/ld/scripttempl/xstormy16.sc b/ld/scripttempl/xstormy16.sc index ccae0a2..b29f720 100644 --- a/ld/scripttempl/xstormy16.sc +++ b/ld/scripttempl/xstormy16.sc @@ -143,6 +143,7 @@ SECTIONS ${RELOCATING+${OTHER_GOT_SECTIONS}} ${RELOCATING+_edata = .;} ${RELOCATING+PROVIDE (edata = .);} + ${RELOCATING+. = ALIGN(ALIGNOF(NEXT_SECTION));} ${RELOCATING+__bss_start = .;} ${RELOCATING+${OTHER_BSS_SYMBOLS}} .bss ${RELOCATING-0} : diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.od b/ld/testsuite/ld-x86-64/pe-x86-64-5.od index ffd6622..2a1b69b 100644 --- a/ld/testsuite/ld-x86-64/pe-x86-64-5.od +++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.od @@ -6,7 +6,7 @@ SYMBOL TABLE: 0+402010 g .data 0000000000000000 initdummy 0+400000 g .text\$mn 0000000000000000 __executable_start 0+401000 g .text\$mn 0000000000000000 begin -0+402012 g .bss 0000000000000000 __bss_start +0+402014 g .bss 0000000000000000 __bss_start 0+402000 g .data 0000000000000000 Struct 0+402011 g .data 0000000000000000 initializedVar 0+402012 g .data 0000000000000000 _edata diff --git a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd index 2370528..060233e 100644 --- a/ld/testsuite/ld-x86-64/pe-x86-64-5.rd +++ b/ld/testsuite/ld-x86-64/pe-x86-64-5.rd @@ -6,7 +6,7 @@ Symbol table '.symtab' contains 11 entries: +[a-f0-9]+: 0000000000402010 0 NOTYPE GLOBAL DEFAULT 2 initdummy +[a-f0-9]+: 0000000000400000 0 NOTYPE GLOBAL DEFAULT 1 __executable_start +[a-f0-9]+: 0000000000401000 0 NOTYPE GLOBAL DEFAULT 1 begin - +[a-f0-9]+: 0000000000402012 0 NOTYPE GLOBAL DEFAULT 3 __bss_start + +[a-f0-9]+: 0000000000402014 0 NOTYPE GLOBAL DEFAULT 3 __bss_start +[a-f0-9]+: 0000000000402000 0 NOTYPE GLOBAL DEFAULT 2 Struct +[a-f0-9]+: 0000000000402011 0 NOTYPE GLOBAL DEFAULT 2 initializedVar +[a-f0-9]+: 0000000000402012 0 NOTYPE GLOBAL DEFAULT 2 _edata |