aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-07-15 08:46:35 +0930
committerAlan Modra <amodra@gmail.com>2023-07-17 08:17:44 +0930
commit63e8fb86255ac97c31d368221be18850ad53039d (patch)
tree508341e8d8cdeab39688128e43308332161307f6
parent5c77898d60cfea469a86fc6026f51b4a6d8e7444 (diff)
downloadgdb-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.
-rw-r--r--ld/ld.texi21
-rw-r--r--ld/ldexp.c43
-rw-r--r--ld/ldexp.h20
-rw-r--r--ld/ldlang.c141
-rw-r--r--ld/scripttempl/arclinux.sc2
-rw-r--r--ld/scripttempl/elf.sc2
-rw-r--r--ld/scripttempl/elf64bpf.sc2
-rw-r--r--ld/scripttempl/elf64hppa.sc1
-rw-r--r--ld/scripttempl/elf_chaos.sc1
-rw-r--r--ld/scripttempl/elfarc.sc1
-rw-r--r--ld/scripttempl/elfd10v.sc1
-rw-r--r--ld/scripttempl/elfxtensa.sc1
-rw-r--r--ld/scripttempl/epiphany_4x4.sc2
-rw-r--r--ld/scripttempl/iq2000.sc1
-rw-r--r--ld/scripttempl/mep.sc1
-rw-r--r--ld/scripttempl/nds32elf.sc2
-rw-r--r--ld/scripttempl/xstormy16.sc1
-rw-r--r--ld/testsuite/ld-x86-64/pe-x86-64-5.od2
-rw-r--r--ld/testsuite/ld-x86-64/pe-x86-64-5.rd2
19 files changed, 149 insertions, 98 deletions
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 <<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