From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by sourceware.org (Postfix) with ESMTPS id B99573858D20 for ; Wed, 12 Jul 2023 03:54:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B99573858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-1b8a8154f9cso2077735ad.1 for ; Tue, 11 Jul 2023 20:54:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1689134077; x=1691726077; h=content-disposition:mime-version:message-id:subject:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=nmaSQAQ4O4dS9Rxn2J2EFJIVTyZuYaOHu6jWGKO0ays=; b=HTyz0skUILXnS+auAYO23UXeU3gMrbKKDH6vxfkafQxs3W4wChK4uJ9WWhOMH4ZnyR gdrDo209uDswK9Zu9OzPJgKgTHJwiQSSn3zoytH3Uir0ptlQvV86gcYo24/5NC4f/vih Si632U8XXXh/VCZHJzNjQNmJqQElmQsGc/YMYQurwZcXSvR7ZxkJeU009FofZEkvsoft SXF8rKCeoKLGkPz2QLUVmj5PucFjMw4xoZm8bpiF3ySiiFKLhsF8NvceKd2X6xMGNqPN /NdKuSho2v+0vCrQn0dKbxNPasFCJm6ysnz4Ni7CLJQVQahyMGZsZ6xl3f/yQHIRvj4c cCMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689134077; x=1691726077; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nmaSQAQ4O4dS9Rxn2J2EFJIVTyZuYaOHu6jWGKO0ays=; b=EZQGyJ7nqbRCBDAIJbwQRa1tC/3U5g6YYtStmBjvVL2mzr6F8cyeXmHebbO08XLKJd 0yLIf+A3CpoCYnRHean5siTBA3YbohQ0WYv0oTxjW2x8kRiQMmY6QiI5lBRUHEZeYRhf zSa9C/hmsY0PTWxOtaToZaLIVYt87AtXZkUaZ56fpFJtKdPn+JV0elpwbGegOPb2UyJG CRQPz94hdfHqmQ3kwfJ1yuzGDpa0C50qtdFCY14Ga/T8V+b5n83m5wUnvTfsy55sNrmG /uTNWUl6T0YzErUR2vGVjtm7GZ97qUY+8w6aC/86FOc2QrszRiuRVzGUJmS4KCGzctGw mQgQ== X-Gm-Message-State: ABy/qLYNNvINlntBi3glp+tt5WQpEmTP6uJ0BdibNy2T9sWUY68SQ0iC BsYUHzQDVjEFcaOzChEe6Wv8UiaSGYk= X-Google-Smtp-Source: APBJJlFdJKR/Lqhrgz73SEI+IG3ybY4P8WMtAVbCii8etJRFgtEMpxK+en6nqpB9biJax12KL5ePRw== X-Received: by 2002:a17:902:db10:b0:1b8:a936:1915 with SMTP id m16-20020a170902db1000b001b8a9361915mr909063plx.22.1689134076465; Tue, 11 Jul 2023 20:54:36 -0700 (PDT) Received: from squeak.grove.modra.org (158.106.96.58.static.exetel.com.au. [58.96.106.158]) by smtp.gmail.com with ESMTPSA id bg4-20020a1709028e8400b001b53be3d942sm2710176plb.232.2023.07.11.20.54.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Jul 2023 20:54:35 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 5FBCC1142A71; Wed, 12 Jul 2023 13:24:33 +0930 (ACST) Date: Wed, 12 Jul 2023 13:24:33 +0930 From: Alan Modra To: binutils@sourceware.org Subject: Support NEXT_SECTION in ALIGNOF and SIZEOF Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3033.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_STOCKGEN,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: 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 .plt being marked SPECIAL foils that idea. The problem is that you only want to pick up the following .plt, not the one preceeding this 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. Are there any objections to this script extension for mainline? * 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. diff --git a/ld/ld.texi b/ld/ld.texi index aa8b1aa86eb..4f925f9d034 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -7110,10 +7110,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{} @@ -7262,9 +7265,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 170e1ed7f56..8b9d6dcce0b 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 70908c17eb5..7c302753192 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 b3a89bf041b..4b86c164843 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 20429df45a8..3c27625fedb 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 7c71525cbeb..9c85d157881 100644 --- a/ld/scripttempl/elfxtensa.sc +++ b/ld/scripttempl/elfxtensa.sc @@ -500,6 +500,7 @@ cat <