WIP MachO binutils port assisted by AI I may consider upstreaming this in the future.
0

Configure Feed

Select the types of activity you want to include in your feed.

Delay evaluation of alignment expressions in output sections

git commit 702d16713 broke expressions using CONSTANT(COMMONPAGESIZE)
in ALIGN or SUBALIGN of output section statements, because these
optional fields were evaluated at script parse time and the patch in
question delayed setting of config.commonpagesize. The right thing to
do is keep the tree representation of those fields for later
evaluation.

PR 23571
* ldlang.h (section_alignment): Make it an expression tree.
(subsection_alignment): Likewise.
* ldlang.c (topower): Delete.
(output_section_statement_newfunc): Adjust initialization.
(init_os): Evaluate section_alignment.
(lang_size_sections_1): Likewise.
(size_input_section): Evaluate subsection_alignment.
(lang_enter_output_section_statement): Don't evaluate here.
(lang_new_phdr): Use exp_get_vma rather than exp_get_value_int.
* ldexp.h (exp_get_value_int): Delete.
(exp_get_power): Declare.
* ldexp.c (exp_get_value_int): Delete.
(exp_get_power): New function.
* emultempl/pe.em (place_orphan): Build expression for section
alignment.
* emultempl/pep.em (place_orphan): Likewise.
* testsuite/ld-scripts/pr23571.d,
* testsuite/ld-scripts/pr23571.t: New test.
* testsuite/ld-scripts/align.exp: Run it.

Alan Modra (Aug 26, 2018, 10:45 PM +0930) 3d9c8f6b ed60adf0

+88 -40
+23
ld/ChangeLog
··· 1 + 2018-08-26 Alan Modra <amodra@gmail.com> 2 + 3 + PR 23571 4 + * ldlang.h (section_alignment): Make it an expression tree. 5 + (subsection_alignment): Likewise. 6 + * ldlang.c (topower): Delete. 7 + (output_section_statement_newfunc): Adjust initialization. 8 + (init_os): Evaluate section_alignment. 9 + (lang_size_sections_1): Likewise. 10 + (size_input_section): Evaluate subsection_alignment. 11 + (lang_enter_output_section_statement): Don't evaluate here. 12 + (lang_new_phdr): Use exp_get_vma rather than exp_get_value_int. 13 + * ldexp.h (exp_get_value_int): Delete. 14 + (exp_get_power): Declare. 15 + * ldexp.c (exp_get_value_int): Delete. 16 + (exp_get_power): New function. 17 + * emultempl/pe.em (place_orphan): Build expression for section 18 + alignment. 19 + * emultempl/pep.em (place_orphan): Likewise. 20 + * testsuite/ld-scripts/pr23571.d, 21 + * testsuite/ld-scripts/pr23571.t: New test. 22 + * testsuite/ld-scripts/align.exp: Run it. 23 + 1 24 2018-08-24 Chenghua Xu <paul.hua.gm@gmail.com> 2 25 3 26 * testsuite/ld-mips-elf/mips-elf-flags.exp
+1 -1
ld/emultempl/pe.em
··· 2165 2165 &add_child); 2166 2166 if (bfd_link_relocatable (&link_info)) 2167 2167 { 2168 - os->section_alignment = s->alignment_power; 2168 + os->section_alignment = exp_intop (1U << s->alignment_power); 2169 2169 os->bfd_section->alignment_power = s->alignment_power; 2170 2170 } 2171 2171 }
+1 -1
ld/emultempl/pep.em
··· 1962 1962 &add_child); 1963 1963 if (bfd_link_relocatable (&link_info)) 1964 1964 { 1965 - os->section_alignment = s->alignment_power; 1965 + os->section_alignment = exp_intop (1U << s->alignment_power); 1966 1966 os->bfd_section->alignment_power = s->alignment_power; 1967 1967 } 1968 1968 }
+18 -2
ld/ldexp.c
··· 1523 1523 return def; 1524 1524 } 1525 1525 1526 + /* Return the smallest non-negative integer such that two raised to 1527 + that power is at least as large as the vma evaluated at TREE, if 1528 + TREE is a non-NULL expression that can be resolved. If TREE is 1529 + NULL or cannot be resolved, return -1. */ 1530 + 1526 1531 int 1527 - exp_get_value_int (etree_type *tree, int def, char *name) 1532 + exp_get_power (etree_type *tree, char *name) 1528 1533 { 1529 - return exp_get_vma (tree, def, name); 1534 + bfd_vma x = exp_get_vma (tree, -1, name); 1535 + bfd_vma p2; 1536 + int n; 1537 + 1538 + if (x == (bfd_vma) -1) 1539 + return -1; 1540 + 1541 + for (n = 0, p2 = 1; p2 < x; ++n, p2 <<= 1) 1542 + if (p2 == 0) 1543 + break; 1544 + 1545 + return n; 1530 1546 } 1531 1547 1532 1548 fill_type *
+2 -2
ld/ldexp.h
··· 229 229 (etree_type *); 230 230 bfd_vma exp_get_vma 231 231 (etree_type *, bfd_vma, char *); 232 - int exp_get_value_int 233 - (etree_type *, int, char *); 232 + int exp_get_power 233 + (etree_type *, char *); 234 234 fill_type *exp_get_fill 235 235 (etree_type *, fill_type *, char *); 236 236 bfd_vma exp_get_abs_int
+16 -32
ld/ldlang.c
··· 1199 1199 ret = (struct out_section_hash_entry *) entry; 1200 1200 memset (&ret->s, 0, sizeof (ret->s)); 1201 1201 ret->s.header.type = lang_output_section_statement_enum; 1202 - ret->s.output_section_statement.subsection_alignment = -1; 1203 - ret->s.output_section_statement.section_alignment = -1; 1202 + ret->s.output_section_statement.subsection_alignment = NULL; 1203 + ret->s.output_section_statement.section_alignment = NULL; 1204 1204 ret->s.output_section_statement.block_value = 1; 1205 1205 lang_list_init (&ret->s.output_section_statement.children); 1206 1206 lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next); ··· 2193 2193 exp_init_os (s->load_base); 2194 2194 2195 2195 /* If supplied an alignment, set it. */ 2196 - if (s->section_alignment != -1) 2197 - s->bfd_section->alignment_power = s->section_alignment; 2196 + if (s->section_alignment != NULL) 2197 + s->bfd_section->alignment_power = exp_get_power (s->section_alignment, 2198 + "section alignment"); 2198 2199 } 2199 2200 2200 2201 /* Make sure that all output sections mentioned in an expression are ··· 4706 4707 is greater than any seen before, then record it too. Perform 4707 4708 the alignment by inserting a magic 'padding' statement. */ 4708 4709 4709 - if (output_section_statement->subsection_alignment != -1) 4710 - i->alignment_power = output_section_statement->subsection_alignment; 4710 + if (output_section_statement->subsection_alignment != NULL) 4711 + i->alignment_power 4712 + = exp_get_power (output_section_statement->subsection_alignment, 4713 + "subsection alignment"); 4711 4714 4712 4715 if (o->alignment_power < i->alignment_power) 4713 4716 o->alignment_power = i->alignment_power; ··· 5147 5150 section_alignment = os->bfd_section->alignment_power; 5148 5151 } 5149 5152 else 5150 - section_alignment = os->section_alignment; 5153 + section_alignment = exp_get_power (os->section_alignment, 5154 + "section alignment"); 5151 5155 5152 5156 /* Align to what the section needs. */ 5153 5157 if (section_alignment > 0) ··· 5225 5229 only align according to the value in the output 5226 5230 statement. */ 5227 5231 if (os->lma_region != os->region) 5228 - section_alignment = os->section_alignment; 5232 + section_alignment = exp_get_power (os->section_alignment, 5233 + "section alignment"); 5229 5234 if (section_alignment > 0) 5230 5235 lma = align_power (lma, section_alignment); 5231 5236 } ··· 6673 6678 } 6674 6679 } 6675 6680 6676 - static int 6677 - topower (int x) 6678 - { 6679 - unsigned int i = 1; 6680 - int l; 6681 - 6682 - if (x < 0) 6683 - return -1; 6684 - 6685 - for (l = 0; l < 32; l++) 6686 - { 6687 - if (i >= (unsigned int) x) 6688 - return l; 6689 - i <<= 1; 6690 - } 6691 - 6692 - return 0; 6693 - } 6694 - 6695 6681 lang_output_section_statement_type * 6696 6682 lang_enter_output_section_statement (const char *output_section_statement_name, 6697 6683 etree_type *address_exp, ··· 6727 6713 einfo (_("%F%P:%pS: error: align with input and explicit align specified\n"), 6728 6714 NULL); 6729 6715 6730 - os->subsection_alignment = 6731 - topower (exp_get_value_int (subalign, -1, "subsection alignment")); 6732 - os->section_alignment = 6733 - topower (exp_get_value_int (align, -1, "section alignment")); 6716 + os->subsection_alignment = subalign; 6717 + os->section_alignment = align; 6734 6718 6735 6719 os->load_base = ebase; 6736 6720 return os; ··· 7748 7732 n = (struct lang_phdr *) stat_alloc (sizeof (struct lang_phdr)); 7749 7733 n->next = NULL; 7750 7734 n->name = name; 7751 - n->type = exp_get_value_int (type, 0, "program header type"); 7735 + n->type = exp_get_vma (type, 0, "program header type"); 7752 7736 n->filehdr = filehdr; 7753 7737 n->phdrs = phdrs; 7754 7738 n->at = at;
+2 -2
ld/ldlang.h
··· 143 143 fill_type *fill; 144 144 union etree_union *addr_tree; 145 145 union etree_union *load_base; 146 + union etree_union *section_alignment; 147 + union etree_union *subsection_alignment; 146 148 147 149 /* If non-null, an expression to evaluate after setting the section's 148 150 size. The expression is evaluated inside REGION (above) with '.' ··· 153 155 lang_output_section_phdr_list *phdrs; 154 156 155 157 unsigned int block_value; 156 - int subsection_alignment; /* Alignment of components. */ 157 - int section_alignment; /* Alignment of start of section. */ 158 158 int constraint; 159 159 flagword flags; 160 160 enum section_type sectype;
+4
ld/testsuite/ld-scripts/align.exp
··· 53 53 } 54 54 run_dump_test align2c 55 55 set LDFLAGS "$saved_LDFLAGS" 56 + 57 + if { [is_elf_format] && ![is_generic_elf] } { 58 + run_dump_test pr23571 59 + }
+10
ld/testsuite/ld-scripts/pr23571.d
··· 1 + #source: align2a.s 2 + #ld: -T pr23571.t -z common-page-size=0x1000 3 + #objdump: -h -w 4 + 5 + .*: +file format .* 6 + 7 + Sections: 8 + Idx Name +Size +VMA +LMA +File off +Algn +Flags 9 + +0 \.text +[0-9a-f]* +0+1000 +0+1000 .* 10 + +1 \.data +[0-9a-f]* +0+2000 +0+2000 +[0-9a-f]* +2\*\*12 .*
+11
ld/testsuite/ld-scripts/pr23571.t
··· 1 + SECTIONS 2 + { 3 + .text CONSTANT(COMMONPAGESIZE) : { 4 + *(.text) 5 + } 6 + 7 + .data : ALIGN(CONSTANT(COMMONPAGESIZE)) { 8 + *(.data) 9 + } 10 + /DISCARD/ : {*(*)} 11 + }