elf: Strip zero-sized dynamic sections

ELF size_dynamic_sections is called by the ELF backend linker after all
the linker input files have been seen but before the section sizes have
been set.  After the sections sizes have been set, target-specific,
global optimizations may make some dynamic sections zero-sized if they
are no longer needed.

Add ELF strip_zero_sized_dynamic_sections so that ELF backend linker can
strip zero-sized dynamic sections after the sections sizes have been set.

bfd/

	PR ld/25849
	* elf-bfd.h (elf_backend_data): Add
	elf_backend_strip_zero_sized_dynamic_sections.
	(_bfd_elf_strip_zero_sized_dynamic_sections): New prototype.
	* elf64-alpha.c (elf_backend_strip_zero_sized_dynamic_sections):
	New macro.
	* elflink.c (_bfd_elf_strip_zero_sized_dynamic_sections): New
	function.
	* elfxx-target.h (elf_backend_strip_zero_sized_dynamic_sections):
	New macro.
	(elfNN_bed): Add elf_backend_strip_zero_sized_dynamic_sections.

ld/

	PR ld/25849
	* ldelfgen.c (ldelf_map_segments): Call
	elf_backend_strip_zero_sized_dynamic_sections.
	* testsuite/ld-alpha/tlsbinr.rd: Updated.
This commit is contained in:
H.J. Lu 2020-04-21 05:23:51 -07:00
parent 1f7f2abbc3
commit 6f6fd151cb
8 changed files with 194 additions and 52 deletions

View File

@ -1,3 +1,17 @@
2020-04-21 H.J. Lu <hongjiu.lu@intel.com>
PR ld/25849
* elf-bfd.h (elf_backend_data): Add
elf_backend_strip_zero_sized_dynamic_sections.
(_bfd_elf_strip_zero_sized_dynamic_sections): New prototype.
* elf64-alpha.c (elf_backend_strip_zero_sized_dynamic_sections):
New macro.
* elflink.c (_bfd_elf_strip_zero_sized_dynamic_sections): New
function.
* elfxx-target.h (elf_backend_strip_zero_sized_dynamic_sections):
New macro.
(elfNN_bed): Add elf_backend_strip_zero_sized_dynamic_sections.
2020-04-21 H.J. Lu <hongjiu.lu@intel.com>
* elf64-alpha.c (alpha_elf_reloc_entry): Replace reltext with

View File

@ -1083,6 +1083,12 @@ struct elf_backend_data
bfd_boolean (*elf_backend_size_dynamic_sections)
(bfd *output_bfd, struct bfd_link_info *info);
/* The STRIP_ZERO_SIZED_DYNAMIC_SECTIONS function is called by the
ELF backend linker to strip zero-sized dynamic sections after
the section sizes have been set. */
bfd_boolean (*elf_backend_strip_zero_sized_dynamic_sections)
(struct bfd_link_info *info);
/* Set TEXT_INDEX_SECTION and DATA_INDEX_SECTION, the output sections
we keep to use as a base for relocs and symbols. */
void (*elf_backend_init_index_section)
@ -2520,6 +2526,8 @@ extern bfd_boolean bfd_elf_link_add_symbols
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_add_dynamic_entry
(struct bfd_link_info *, bfd_vma, bfd_vma);
extern bfd_boolean _bfd_elf_strip_zero_sized_dynamic_sections
(struct bfd_link_info *);
extern int bfd_elf_add_dt_needed_tag
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_link_check_relocs

View File

@ -5538,6 +5538,9 @@ static const struct elf_size_info alpha_elf_size_info =
#define elf_backend_special_sections \
elf64_alpha_special_sections
#define elf_backend_strip_zero_sized_dynamic_sections \
_bfd_elf_strip_zero_sized_dynamic_sections
/* A few constants that determine how the .plt section is set up. */
#define elf_backend_want_got_plt 0
#define elf_backend_plt_readonly 0

View File

@ -3501,6 +3501,104 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
return TRUE;
}
/* Strip zero-sized dynamic sections. */
bfd_boolean
_bfd_elf_strip_zero_sized_dynamic_sections (struct bfd_link_info *info)
{
struct elf_link_hash_table *hash_table;
const struct elf_backend_data *bed;
asection *s, *sdynamic, **pp;
asection *rela_dyn, *rel_dyn;
Elf_Internal_Dyn dyn;
bfd_byte *extdyn, *next;
void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
bfd_boolean strip_zero_sized;
bfd_boolean strip_zero_sized_plt;
if (bfd_link_relocatable (info))
return TRUE;
hash_table = elf_hash_table (info);
if (!is_elf_hash_table (hash_table))
return FALSE;
if (!hash_table->dynobj)
return TRUE;
sdynamic= bfd_get_linker_section (hash_table->dynobj, ".dynamic");
if (!sdynamic)
return TRUE;
bed = get_elf_backend_data (hash_table->dynobj);
swap_dyn_in = bed->s->swap_dyn_in;
strip_zero_sized = FALSE;
strip_zero_sized_plt = FALSE;
/* Strip zero-sized dynamic sections. */
rela_dyn = bfd_get_section_by_name (info->output_bfd, ".rela.dyn");
rel_dyn = bfd_get_section_by_name (info->output_bfd, ".rel.dyn");
for (pp = &info->output_bfd->sections; (s = *pp) != NULL;)
if (s->size == 0
&& (s == rela_dyn
|| s == rel_dyn
|| s == hash_table->srelplt->output_section
|| s == hash_table->splt->output_section))
{
*pp = s->next;
info->output_bfd->section_count--;
strip_zero_sized = TRUE;
if (s == rela_dyn)
s = rela_dyn;
if (s == rel_dyn)
s = rel_dyn;
else if (s == hash_table->splt->output_section)
{
s = hash_table->splt;
strip_zero_sized_plt = TRUE;
}
else
s = hash_table->srelplt;
s->flags |= SEC_EXCLUDE;
s->output_section = bfd_abs_section_ptr;
}
else
pp = &s->next;
if (strip_zero_sized_plt)
for (extdyn = sdynamic->contents;
extdyn < sdynamic->contents + sdynamic->size;
extdyn = next)
{
next = extdyn + bed->s->sizeof_dyn;
swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
switch (dyn.d_tag)
{
default:
break;
case DT_JMPREL:
case DT_PLTRELSZ:
case DT_PLTREL:
/* Strip DT_PLTRELSZ, DT_JMPREL and DT_PLTREL entries if
the procedure linkage table (the .plt section) has been
removed. */
memmove (extdyn, next,
sdynamic->size - (next - sdynamic->contents));
next = extdyn;
}
}
if (strip_zero_sized)
{
/* Regenerate program headers. */
elf_seg_map (info->output_bfd) = NULL;
return _bfd_elf_map_sections_to_segments (info->output_bfd, info);
}
return TRUE;
}
/* Add a DT_NEEDED entry for this dynamic object. Returns -1 on error,
1 if a DT_NEEDED tag already exists, and 0 on success. */

View File

@ -485,6 +485,9 @@
#ifndef elf_backend_size_dynamic_sections
#define elf_backend_size_dynamic_sections 0
#endif
#ifndef elf_backend_strip_zero_sized_dynamic_sections
#define elf_backend_strip_zero_sized_dynamic_sections 0
#endif
#ifndef elf_backend_init_index_section
#define elf_backend_init_index_section _bfd_void_bfd_link
#endif
@ -831,6 +834,7 @@ static struct elf_backend_data elfNN_bed =
elf_backend_adjust_dynamic_symbol,
elf_backend_always_size_sections,
elf_backend_size_dynamic_sections,
elf_backend_strip_zero_sized_dynamic_sections,
elf_backend_init_index_section,
elf_backend_relocate_section,
elf_backend_finish_dynamic_symbol,

View File

@ -1,3 +1,10 @@
2020-04-21 H.J. Lu <hongjiu.lu@intel.com>
PR ld/25849
* ldelfgen.c (ldelf_map_segments): Call
elf_backend_strip_zero_sized_dynamic_sections.
* testsuite/ld-alpha/tlsbinr.rd: Updated.
2020-04-20 Alan Modra <amodra@gmail.com>
* testsuite/ld-powerpc/tlsopt5.s: Rename foo to aaaaa.

View File

@ -73,6 +73,19 @@ ldelf_map_segments (bfd_boolean need_layout)
if (tries == 0)
einfo (_("%F%P: looping in map_segments"));
if (link_info.output_bfd->xvec->flavour == bfd_target_elf_flavour
&& lang_phdr_list == NULL)
{
/* If we don't have user supplied phdrs, strip zero-sized dynamic
sections and regenerate program headers. */
const struct elf_backend_data *bed
= get_elf_backend_data (link_info.output_bfd);
if (bed->elf_backend_strip_zero_sized_dynamic_sections
&& !bed->elf_backend_strip_zero_sized_dynamic_sections
(&link_info))
einfo (_("%F%P: failed to strip zero-sized dynamic sections"));
}
}
/* We want to emit CTF early if and only if we are not targetting ELF with this

View File

@ -16,8 +16,6 @@ Section Headers:
+\[[ 0-9]+\] \.dynsym +.*
+\[[ 0-9]+\] \.dynstr +.*
+\[[ 0-9]+\] \.rela\.dyn +.*
+\[[ 0-9]+\] \.rela\.plt +.*
+\[[ 0-9]+\] \.plt +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 0+ +AX +0 +0 +16
+\[[ 0-9]+\] \.text +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 0+ +AX +0 +0 4096
+\[[ 0-9]+\] \.eh_frame +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 00 +A +0 +0 +8
+\[[ 0-9]+\] \.tdata +PROGBITS +[0-9a-f]+ [0-9a-f]+ [0-9a-f]+ 0+ WAT +0 +0 +4
@ -70,59 +68,56 @@ Symbol table '\.symtab' contains [0-9]+ entries:
[0-9 ]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +9
[0-9 ]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +10
[0-9 ]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +11
[0-9 ]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +12
[0-9 ]+: [0-9a-f]+ +0 +SECTION +LOCAL +DEFAULT +13
.* FILE +LOCAL +DEFAULT +ABS .*
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl1
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl2
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl3
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl4
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl5
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl6
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl7
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +10 sl8
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl1
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl2
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl3
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl4
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl5
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl6
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl7
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +8 sl8
.* FILE +LOCAL +DEFAULT +ABS .*
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl1
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl2
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl3
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl4
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl5
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl6
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl7
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +11 bl8
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl1
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl2
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl3
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl4
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl5
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl6
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl7
[0-9 ]+: [0-9a-f]+ +0 +TLS +LOCAL +DEFAULT +9 bl8
.* FILE +LOCAL +DEFAULT +ABS .*
[0-9 ]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +12 _DYNAMIC
[0-9 ]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +7 _PROCEDURE_LINKAGE_TABLE_
[0-9 ]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +13 _GLOBAL_OFFSET_TABLE_
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg8
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg8
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg6
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg3
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg3
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh3
[0-9 ]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +10 _DYNAMIC
[0-9 ]+: [0-9a-f]+ +0 +OBJECT +LOCAL +DEFAULT +11 _GLOBAL_OFFSET_TABLE_
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg8
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg8
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg6
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg3
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg3
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh3
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +UND sG2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg4
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg5
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg5
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg4
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg5
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg5
[0-9 ]+: [0-9a-f]+ +0 +FUNC +GLOBAL +DEFAULT +UND __tls_get_addr
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh7
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh8
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg1
[0-9 ]+: [0-9a-f]+ +52 +FUNC +GLOBAL +DEFAULT +8 _start
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh4
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg7
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh5
[0-9 ]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +13 __bss_start
[0-9 ]+: [0-9a-f]+ +136 +FUNC +GLOBAL +DEFAULT +\[STD GPLOAD\] +8 fn2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh7
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh8
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg1
[0-9 ]+: [0-9a-f]+ +52 +FUNC +GLOBAL +DEFAULT +6 _start
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh4
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg7
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh5
[0-9 ]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 __bss_start
[0-9 ]+: [0-9a-f]+ +136 +FUNC +GLOBAL +DEFAULT +\[STD GPLOAD\] +6 fn2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +UND sG1
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh1
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg6
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +10 sg7
[0-9 ]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +13 _edata
[0-9 ]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +13 _end
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +10 sh6
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg1
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +11 bg4
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh1
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg6
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +8 sg7
[0-9 ]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _edata
[0-9 ]+: [0-9a-f]+ +0 +NOTYPE +GLOBAL +DEFAULT +11 _end
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +HIDDEN +8 sh6
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg2
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg1
[0-9 ]+: [0-9a-f]+ +0 +TLS +GLOBAL +DEFAULT +9 bg4