diff options
-rw-r--r-- | bfd/ChangeLog | 15 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 7 | ||||
-rw-r--r-- | bfd/elflink.c | 83 | ||||
-rw-r--r-- | bfd/section.c | 7 | ||||
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/obj-elf.c | 4 | ||||
-rw-r--r-- | ld/ChangeLog | 19 | ||||
-rw-r--r-- | ld/ldlang.c | 4 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-1.s | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-1.t | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-1a.d | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-1b.d | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-2.s | 32 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-2.t | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-2a.d | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-2b-alt.d | 21 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-2b.d | 22 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-3.s | 27 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-3a.d | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-3a.t | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-3b.d | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/pr26256-3b.t | 16 |
22 files changed, 354 insertions, 25 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index df9cb20..f1ae342 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,18 @@ +2021-01-04 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/26256 + * elflink.c (compare_link_order): Place unordered sections before + ordered sections. + (elf_fixup_link_order): Add a link info argument. Allow mixed + ordered and unordered input sections for non-relocatable link. + Sort the consecutive bfd_indirect_link_order sections with the + same pattern. Change the offsets of the bfd_indirect_link_order + sections only. + (bfd_elf_final_link): Pass info to elf_fixup_link_order. + * section.c (bfd_section): Add pattern. + (BFD_FAKE_SECTION): Initialize pattern to NULL. + * bfd-in2.h: Regenerated. + 2021-01-04 Alexander Fedotov <alfedotov@gmail.com> * elf32-arm.c (elf32_arm_print_private_bfd_data): Prefix hex value diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 5196bb6..43ead18 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1184,6 +1184,9 @@ typedef struct bfd_section struct bfd_symbol *symbol; struct bfd_symbol **symbol_ptr_ptr; + /* The matching section name pattern in linker script. */ + const char *pattern; + /* Early in the link process, map_head and map_tail are used to build a list of input sections attached to an output section. Later, output sections use these fields for a list of bfd_link_order @@ -1377,8 +1380,8 @@ discarded_section (const asection *sec) /* target_index, used_by_bfd, constructor_chain, owner, */ \ 0, NULL, NULL, NULL, \ \ - /* symbol, symbol_ptr_ptr, */ \ - (struct bfd_symbol *) SYM, &SEC.symbol, \ + /* symbol, symbol_ptr_ptr, pattern, */ \ + (struct bfd_symbol *) SYM, &SEC.symbol, NULL, \ \ /* map_head, map_tail, already_assigned */ \ { NULL }, { NULL }, NULL \ diff --git a/bfd/elflink.c b/bfd/elflink.c index 448989a..df5b997 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11869,8 +11869,21 @@ compare_link_order (const void *a, const void *b) const struct bfd_link_order *blo = *(const struct bfd_link_order **) b; asection *asec = elf_linked_to_section (alo->u.indirect.section); asection *bsec = elf_linked_to_section (blo->u.indirect.section); - bfd_vma apos = asec->output_section->lma + asec->output_offset; - bfd_vma bpos = bsec->output_section->lma + bsec->output_offset; + bfd_vma apos, bpos; + + /* Check if any sections are unordered. */ + if (asec == NULL || bsec == NULL) + { + /* Place unordered sections before ordered sections. */ + if (bsec != NULL) + return -1; + else if (asec != NULL) + return 1; + return 0; + } + + apos = asec->output_section->lma + asec->output_offset; + bpos = bsec->output_section->lma + bsec->output_offset; if (apos < bpos) return -1; @@ -11905,14 +11918,14 @@ compare_link_order (const void *a, const void *b) sections. Ideally we'd do this in the linker proper. */ static bfd_boolean -elf_fixup_link_order (bfd *abfd, asection *o) +elf_fixup_link_order (struct bfd_link_info *info, bfd *abfd, asection *o) { size_t seen_linkorder; size_t seen_other; size_t n; struct bfd_link_order *p; bfd *sub; - struct bfd_link_order **sections; + struct bfd_link_order **sections, **indirect_sections; asection *other_sec, *linkorder_sec; bfd_vma offset; /* Octets. */ @@ -11943,7 +11956,9 @@ elf_fixup_link_order (bfd *abfd, asection *o) else seen_other++; - if (seen_other && seen_linkorder) + /* Allow mixed ordered and unordered input sections for + non-relocatable link. */ + if (bfd_link_relocatable (info) && seen_other && seen_linkorder) { if (other_sec && linkorder_sec) _bfd_error_handler @@ -11963,6 +11978,10 @@ elf_fixup_link_order (bfd *abfd, asection *o) if (!seen_linkorder) return TRUE; + /* Non-relocatable output can have both ordered and unordered input + sections. */ + seen_linkorder += seen_other; + sections = bfd_malloc (seen_linkorder * sizeof (*sections)); if (sections == NULL) return FALSE; @@ -11971,22 +11990,48 @@ elf_fixup_link_order (bfd *abfd, asection *o) for (p = o->map_head.link_order; p != NULL; p = p->next) sections[seen_linkorder++] = p; - /* Sort the input sections in the order of their linked section. */ - qsort (sections, seen_linkorder, sizeof (*sections), compare_link_order); + for (indirect_sections = sections, n = 0; + n < seen_linkorder; + indirect_sections++, n++) + { + /* Find the first bfd_indirect_link_order section. */ + if (indirect_sections[0]->type == bfd_indirect_link_order) + { + /* Count the consecutive bfd_indirect_link_order sections + with the same pattern. */ + size_t i, n_indirect; + const char *pattern + = indirect_sections[0]->u.indirect.section->pattern; + for (i = n + 1; i < seen_linkorder; i++) + if (sections[i]->type != bfd_indirect_link_order + || sections[i]->u.indirect.section->pattern != pattern) + break; + n_indirect = i - n; + /* Sort the bfd_indirect_link_order sections in the order of + their linked section. */ + qsort (indirect_sections, n_indirect, sizeof (*sections), + compare_link_order); + indirect_sections += n_indirect; + n += n_indirect; + } + } - /* Change the offsets of the sections. */ + /* Change the offsets of the bfd_indirect_link_order sections. */ offset = 0; for (n = 0; n < seen_linkorder; n++) - { - bfd_vma mask; - asection *s = sections[n]->u.indirect.section; - unsigned int opb = bfd_octets_per_byte (abfd, s); - - mask = ~(bfd_vma) 0 << s->alignment_power * opb; - offset = (offset + ~mask) & mask; - sections[n]->offset = s->output_offset = offset / opb; - offset += sections[n]->size; - } + if (sections[n]->type == bfd_indirect_link_order) + { + bfd_vma mask; + asection *s = sections[n]->u.indirect.section; + unsigned int opb = bfd_octets_per_byte (abfd, s); + + mask = ~(bfd_vma) 0 << s->alignment_power * opb; + offset = (offset + ~mask) & mask; + sections[n]->offset = s->output_offset = offset / opb; + offset += sections[n]->size; + } + else + offset = sections[n]->offset + sections[n]->size; free (sections); return TRUE; @@ -12629,7 +12674,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) /* Reorder SHF_LINK_ORDER sections. */ for (o = abfd->sections; o != NULL; o = o->next) { - if (!elf_fixup_link_order (abfd, o)) + if (!elf_fixup_link_order (info, abfd, o)) return FALSE; } diff --git a/bfd/section.c b/bfd/section.c index 3e6ba0c..10efc3c 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -541,6 +541,9 @@ CODE_FRAGMENT . struct bfd_symbol *symbol; . struct bfd_symbol **symbol_ptr_ptr; . +. {* The matching section name pattern in linker script. *} +. const char *pattern; +. . {* Early in the link process, map_head and map_tail are used to build . a list of input sections attached to an output section. Later, . output sections use these fields for a list of bfd_link_order @@ -734,8 +737,8 @@ CODE_FRAGMENT . {* target_index, used_by_bfd, constructor_chain, owner, *} \ . 0, NULL, NULL, NULL, \ . \ -. {* symbol, symbol_ptr_ptr, *} \ -. (struct bfd_symbol *) SYM, &SEC.symbol, \ +. {* symbol, symbol_ptr_ptr, pattern, *} \ +. (struct bfd_symbol *) SYM, &SEC.symbol, NULL, \ . \ . {* map_head, map_tail, already_assigned *} \ . { NULL }, { NULL }, NULL \ diff --git a/gas/ChangeLog b/gas/ChangeLog index 4c370a6..03ea1a1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2021-01-04 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/26256 + * config/obj-elf.c (obj_elf_change_section): Also filter out + SHF_LINK_ORDER. + 2021-01-04 Alan Modra <amodra@gmail.com> PR 27102 diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index bf79b05..94fa805 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -666,7 +666,9 @@ obj_elf_change_section (const char *name, } } - if (old_sec == NULL && ((attr & ~(SHF_MASKOS | SHF_MASKPROC)) + if (old_sec == NULL && ((attr & ~(SHF_LINK_ORDER + | SHF_MASKOS + | SHF_MASKPROC)) & ~ssect->attr) != 0) { /* As a GNU extension, we permit a .note section to be diff --git a/ld/ChangeLog b/ld/ChangeLog index 8d45491..1fe689a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2021-01-04 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/26256 + * ldlang.c (gc_section_callback): Set pattern. + * testsuite/ld-elf/pr26256-1.s: New file. + * testsuite/ld-elf/pr26256-1.t: Likewise. + * testsuite/ld-elf/pr26256-1a.d: Likewise. + * testsuite/ld-elf/pr26256-1b.d: Likewise. + * testsuite/ld-elf/pr26256-2.s: Likewise. + * testsuite/ld-elf/pr26256-2.t: Likewise. + * testsuite/ld-elf/pr26256-2a.d: Likewise. + * testsuite/ld-elf/pr26256-2b-alt.d: Likewise. + * testsuite/ld-elf/pr26256-2b.d: Likewise. + * testsuite/ld-elf/pr26256-3.s: Likewise. + * testsuite/ld-elf/pr26256-3a.d: Likewise. + * testsuite/ld-elf/pr26256-3a.t: Likewise. + * testsuite/ld-elf/pr26256-3b.d: Likewise. + * testsuite/ld-elf/pr26256-3b.t: Likewise. + 2021-01-04 Alan Modra <amodra@gmail.com> PR 26822 diff --git a/ld/ldlang.c b/ld/ldlang.c index 32450fb..8cbeda6 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -7488,7 +7488,7 @@ lang_reset_memory_regions (void) static void gc_section_callback (lang_wild_statement_type *ptr, - struct wildcard_list *sec ATTRIBUTE_UNUSED, + struct wildcard_list *sec, asection *section, struct flag_info *sflag_info ATTRIBUTE_UNUSED, lang_input_statement_type *file ATTRIBUTE_UNUSED, @@ -7498,6 +7498,8 @@ gc_section_callback (lang_wild_statement_type *ptr, should be as well. */ if (ptr->keep_sections) section->flags |= SEC_KEEP; + if (sec) + section->pattern = sec->spec.name; } /* Iterate over sections marking them against GC. */ diff --git a/ld/testsuite/ld-elf/pr26256-1.s b/ld/testsuite/ld-elf/pr26256-1.s new file mode 100644 index 0000000..7351f76 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-1.s @@ -0,0 +1,20 @@ + .section .text.bar,"ax",%progbits + .globl bar + .type bar, %function +bar: + .section __patchable_function_entries,"awo",%progbits,bar + .dc.a .LPFE1 + .section .text.bar,"ax",%progbits +.LPFE1: + .byte 0 + .section .text._start,"ax",%progbits + .globl _start + .type _start, %function +_start: + .section __patchable_function_entries,"awo",%progbits,_start + .dc.a .LPFE2 + .section .text._start,"ax",%progbits +.LPFE2: + .byte 0 + .section .init.data,"aw",%progbits + .byte 0 diff --git a/ld/testsuite/ld-elf/pr26256-1.t b/ld/testsuite/ld-elf/pr26256-1.t new file mode 100644 index 0000000..f93fff9 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-1.t @@ -0,0 +1,13 @@ +SECTIONS +{ + .text : { *(.text*) } + .init.data : + { + *(.init.data); + *(__patchable_function_entries); + } + /DISCARD/ : + { + *(.reginfo) *(.MIPS.abiflags) *(.MIPS.options) *(.trampolines) + } +} diff --git a/ld/testsuite/ld-elf/pr26256-1a.d b/ld/testsuite/ld-elf/pr26256-1a.d new file mode 100644 index 0000000..025ace0 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-1a.d @@ -0,0 +1,7 @@ +#source: pr26256-1.s +#ld: -e _start -T pr26256-1.t +#nm: -n + +#... +[0-9a-f]+ T _start +#pass diff --git a/ld/testsuite/ld-elf/pr26256-1b.d b/ld/testsuite/ld-elf/pr26256-1b.d new file mode 100644 index 0000000..760c6d8 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-1b.d @@ -0,0 +1,7 @@ +#source: pr26256-1.s +#ld: -e _start +#nm: -n + +#... +[0-9a-f]+ T _start +#pass diff --git a/ld/testsuite/ld-elf/pr26256-2.s b/ld/testsuite/ld-elf/pr26256-2.s new file mode 100644 index 0000000..70e3693 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-2.s @@ -0,0 +1,32 @@ + .section .text,"ax",%progbits,unique,0 + .globl text0 +text0: + .nop + .section .text,"ax",%progbits,unique,1 + .globl text1 +text1: + .nop + .section .linkorder,"ao",%progbits,0,unique,0 + .globl linkorder2 +linkorder2: + .byte 0 + .section .linkorder,"ao",%progbits,text0 + .globl linkorder0 +linkorder0: + .byte 1 + .section .linkorder,"ao",%progbits,text1 + .globl linkorder1 +linkorder1: + .byte 2 + .section .linkorder,"a",%progbits + .globl linkorder3 +linkorder3: + .byte 3 + .section .linkorder,"ao",%progbits,0,unique,3 + .globl linkorder4 +linkorder4: + .byte 4 + .text + .global _start +_start: + .nop diff --git a/ld/testsuite/ld-elf/pr26256-2.t b/ld/testsuite/ld-elf/pr26256-2.t new file mode 100644 index 0000000..0c5e5bc --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-2.t @@ -0,0 +1,9 @@ +SECTIONS +{ + .linkorder : { *(.linkorder.*) } + .text : { *(.text) } + /DISCARD/ : + { + *(.reginfo) *(.MIPS.abiflags) *(.MIPS.options) *(.trampolines) + } +} diff --git a/ld/testsuite/ld-elf/pr26256-2a.d b/ld/testsuite/ld-elf/pr26256-2a.d new file mode 100644 index 0000000..03804d8 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-2a.d @@ -0,0 +1,20 @@ +#source: pr26256-2.s +#ld: -e _start -T pr26256-2.t +#nm: -n +#xfail: [is_generic] + +#... +[0-9a-f]+ R linkorder2 +#... +[0-9a-f]+ R linkorder3 +#... +[0-9a-f]+ R linkorder4 +#... +[0-9a-f]+ R linkorder0 +#... +[0-9a-f]+ R linkorder1 +#... +[0-9a-f]+ T text0 +#... +[0-9a-f]+ T text1 +#pass diff --git a/ld/testsuite/ld-elf/pr26256-2b-alt.d b/ld/testsuite/ld-elf/pr26256-2b-alt.d new file mode 100644 index 0000000..f2f03a0 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-2b-alt.d @@ -0,0 +1,21 @@ +#source: pr26256-2.s +#ld: -e _start +#nm: -n +#target: fr30-*-* iq2000-*-* ip2k-*-* xstormy16-*-* +# These targets place .linkorder sections before .text sections. + +#... +[0-9a-f]+ R linkorder2 +#... +[0-9a-f]+ R linkorder3 +#... +[0-9a-f]+ R linkorder4 +#... +[0-9a-f]+ R linkorder0 +#... +[0-9a-f]+ R linkorder1 +#... +[0-9a-f]+ T text0 +#... +[0-9a-f]+ T text1 +#pass diff --git a/ld/testsuite/ld-elf/pr26256-2b.d b/ld/testsuite/ld-elf/pr26256-2b.d new file mode 100644 index 0000000..60c3bff --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-2b.d @@ -0,0 +1,22 @@ +#source: pr26256-2.s +#ld: -e _start +#nm: -n +#xfail: [is_generic] +#notarget: fr30-*-* iq2000-*-* ip2k-*-* xstormy16-*-* +# These targets place .linkorder sections before .text sections. + +#... +[0-9a-f]+ T text0 +#... +[0-9a-f]+ T text1 +#... +[0-9a-f]+ R linkorder2 +#... +[0-9a-f]+ R linkorder3 +#... +[0-9a-f]+ R linkorder4 +#... +[0-9a-f]+ R linkorder0 +#... +[0-9a-f]+ R linkorder1 +#pass diff --git a/ld/testsuite/ld-elf/pr26256-3.s b/ld/testsuite/ld-elf/pr26256-3.s new file mode 100644 index 0000000..baad9dc --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-3.s @@ -0,0 +1,27 @@ + .text + .global _start +_start: + .long 0x33333333 + .long 0x33333333 + .long 0x33333333 + .long 0x33333333 + + .section .rosection,"a" + .byte 9 + + .section .text.bar,"a",%progbits + .long 0x22222222 + .long 0x22222222 + .long 0x22222222 + .long 0x22222222 + .section .text.foo,"a",%progbits + .long 0x11111111 + .long 0x11111111 + .long 0x11111111 + .long 0x11111111 + .section .rodata.foo,"ao",%progbits,.text.foo + .byte 1 + .section .rodata.bar,"a",%progbits + .byte 2 + .section .rodata.bar,"ao",%progbits,.text.bar + .byte 3 diff --git a/ld/testsuite/ld-elf/pr26256-3a.d b/ld/testsuite/ld-elf/pr26256-3a.d new file mode 100644 index 0000000..4546f0a --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-3a.d @@ -0,0 +1,11 @@ +#source: pr26256-3.s +#ld: -e _start -T pr26256-3a.t +#readelf: -x .rodata -x .text + +Hex dump of section \'.rodata\': + 0x[a-f0-9]+ +00010203 +040907 +.+ + +Hex dump of section \'.text\': + 0x[a-f0-9]+ +22222222 +22222222 +22222222 +.+ + 0x[a-f0-9]+ +11111111 +11111111 +11111111 +.+ + 0x[a-f0-9]+ +33333333 +33333333 +33333333 +.+ diff --git a/ld/testsuite/ld-elf/pr26256-3a.t b/ld/testsuite/ld-elf/pr26256-3a.t new file mode 100644 index 0000000..12f6fd1 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-3a.t @@ -0,0 +1,17 @@ +SECTIONS +{ + .rodata : + { + BYTE(0) + *(.rodata.foo) + *(.rodata.bar) + BYTE(4) + *(.rosection) + BYTE(7) + } + .text : {*(.text.bar) *(.text.foo)} + /DISCARD/ : + { + *(.reginfo) *(.MIPS.abiflags) *(.MIPS.options) *(.trampolines) + } +} diff --git a/ld/testsuite/ld-elf/pr26256-3b.d b/ld/testsuite/ld-elf/pr26256-3b.d new file mode 100644 index 0000000..7d6dff2 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-3b.d @@ -0,0 +1,12 @@ +#source: pr26256-3.s +#ld: -e _start -T pr26256-3b.t +#readelf: -x .rodata -x .text +#xfail: [is_generic] + +Hex dump of section \'.rodata\': + 0x[a-f0-9]+ +00020301 +040907 +.+ + +Hex dump of section \'.text\': + 0x[a-f0-9]+ +22222222 +22222222 +22222222 +.+ + 0x[a-f0-9]+ +11111111 +11111111 +11111111 +.+ + 0x[a-f0-9]+ +33333333 +33333333 +33333333 +.+ diff --git a/ld/testsuite/ld-elf/pr26256-3b.t b/ld/testsuite/ld-elf/pr26256-3b.t new file mode 100644 index 0000000..952c8d2 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26256-3b.t @@ -0,0 +1,16 @@ +SECTIONS +{ + .rodata : + { + BYTE(0) + *(.rodata*) + BYTE(4) + *(.rosection) + BYTE(7) + } + .text : {*(.text.bar) *(.text.foo)} + /DISCARD/ : + { + *(.reginfo) *(.MIPS.abiflags) *(.MIPS.options) *(.trampolines) + } +} |