diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2012-10-23 09:33:56 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@codesourcery.com> | 2012-10-23 09:33:56 +0000 |
commit | 04c3a75556c018feb1f609404c627414a7ef672e (patch) | |
tree | 16a4265a55a0a6827b7315dd44f2ac74c7b2bd93 /bfd | |
parent | f6fbab7d1b396b1ee576937b53bb0858c8f895d5 (diff) | |
download | gdb-04c3a75556c018feb1f609404c627414a7ef672e.zip gdb-04c3a75556c018feb1f609404c627414a7ef672e.tar.gz gdb-04c3a75556c018feb1f609404c627414a7ef672e.tar.bz2 |
bfd/
* bfd-in.h (bfd_elf_stack_segment_size): Declare.
* bfd-in2.h: Rebuilt.
* elfxx-target.h (elf_backend_stack_align): New.
(elfNN_bed): Add it.
* elf-bfd.h (struct elf_backend_data): Add stack_align field.
* elf.c (bfd_elf_map_sections_to_segments): Pay attention to
stack_align and stacksize for PT_GNU_STACK segment.
(assign_file_positions_for_non_load_sections): Set p_memsz for
PT_GNU_STACK segment.
(copy_elf_program_header): Copy PT_GNU_STACK size.
* elflink.c (bfd_elf_stack_segment_size): New function, taken from
uclinux backends.
(bfd_elf_size_dynamic_sections): Determine
PT_GNU_STACK requirements after calling backend. Pay attention to
stacksize.
* elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Call
bfd_elf_stack_segment_size.
(elf32_bfinfdpic_modify_program_headers): Delete.
(elf32_bfingfdpic_copy_private_bfd_data): Don't copy PT_GNU_STACK
here.
(elf_backend_stack_align): Override.
(elf_backend_modify_program_headers): Don't override.
* elf32-frv.c (frvfdpic_always_size_sections): Call
bfd_elf_stack_segment_size.
(elf32_frvfdpic_modify_program_headers): Delete.
(elf32_frvfdpic_copy_private_bfd_data): Don't copy PT_GNU_STACK
here.
(elf_backend_stack_align): Override.
(elf_backend_modify_program_headers): Don't override.
* elf32-lm32.c (lm32_elf_always_size_sections): Leave
PT_GNU_STACK creation to underlying elf support. Check
__stacksize here for backwards compatibility, and set it if
needed.
(lm32_elf_modify_segment_map): Delete.
(lm32_elf_modify_program_headers): Delete.
(elf_backend_stack_align): Override.
(elf_backend_modify_segment_map): Don't override.
(elf_backend_modify_program_headers): Don't override.
* elf32-sh.c (sh_elf_always_size_sections): Call
bfd_elf_stack_segment_size.
(sh_elf_modify_program_headers): Delete.
(sh_elf_copy_private_data): Don't copy PT_GNU_STACK
here.
(elf_backend_stack_align): Override.
(elf_backend_modify_program_headers): Don't override.
* elf32-tic6x.c (elf32_tic6x_always_size_sections): Call
bfd_elf_stack_segment_size.
(elf32_tic6x_modify_program_headers): Delete.
(elf32_tic6x_copy_private_data): Delete.
(elf_backend_stack_align): Override.
(bfd_elf32_bfd_copy_private_bfd_data): Don't override.
(elf_backend_modify_program_headers): Don't override.
include/
* bfdlink.h (struct bfd_link_info): Add stacksize option.
ld/
* ld.texinfo (stack-size): New option.
* emultempl/elf32.em: Add stack-size option.
ld/testsuite/
* ld-elf/binutils.exp: Add -z stack-size=0.
* ld-elf/elf.exp: Add stack-exec and stack-size tests.
* ld-elf/orphan-region.d: Add stack-size option. Remove xfail.
* ld-elf/stack-exec.rd: New.
* ld-elf/stack-size.rd: New.
* ld-elf/stack.s: New.
* ld-scripts/empty-aligned.d: Add stack-size option.
* ld-sh/fdpic-stack-set.d: New.
* ld-tic6x/shlib-1.rd: Remove __stacksize symbol.
* ld-tic6x/shlib-1b.rd: Likewise.
* ld-tic6x/shlib-1r.rd: Likewise.
* ld-tic6x/shlib-1rb.rd: Likewise.
* ld-tic6x/shlib-app-1.rd: Likewise.
* ld-tic6x/shlib-app-1b.rd: Likewise.
* ld-tic6x/shlib-app-1r.rd: Likewise.
* ld-tic6x/shlib-app-1rb.rd: Likewise.
* ld-tic6x/shlib-noindex.rd: Likewise.
* ld-tic6x/static-app-1.rd: Likewise.
* ld-tic6x/static-app-1b.rd: Likewise.
* ld-tic6x/static-app-1r.rd: Likewise.
* ld-tic6x/static-app-1rb.rd: Likewise.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 55 | ||||
-rw-r--r-- | bfd/bfd-in.h | 2 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 2 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 3 | ||||
-rw-r--r-- | bfd/elf.c | 19 | ||||
-rw-r--r-- | bfd/elf32-bfin.c | 109 | ||||
-rw-r--r-- | bfd/elf32-frv.c | 110 | ||||
-rw-r--r-- | bfd/elf32-lm32.c | 128 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 117 | ||||
-rw-r--r-- | bfd/elf32-tic6x.c | 124 | ||||
-rw-r--r-- | bfd/elflink.c | 108 | ||||
-rw-r--r-- | bfd/elfxx-target.h | 4 |
12 files changed, 193 insertions, 588 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4bb6d53..599e0bf 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,58 @@ +2012-10-23 Nathan Sidwell <nathan@codesourcery.com> + + * bfd-in.h (bfd_elf_stack_segment_size): Declare. + * bfd-in2.h: Rebuilt. + * elfxx-target.h (elf_backend_stack_align): New. + (elfNN_bed): Add it. + * elf-bfd.h (struct elf_backend_data): Add stack_align field. + * elf.c (bfd_elf_map_sections_to_segments): Pay attention to + stack_align and stacksize for PT_GNU_STACK segment. + (assign_file_positions_for_non_load_sections): Set p_memsz for + PT_GNU_STACK segment. + (copy_elf_program_header): Copy PT_GNU_STACK size. + * elflink.c (bfd_elf_stack_segment_size): New function, taken from + uclinux backends. + (bfd_elf_size_dynamic_sections): Determine + PT_GNU_STACK requirements after calling backend. Pay attention to + stacksize. + * elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Call + bfd_elf_stack_segment_size. + (elf32_bfinfdpic_modify_program_headers): Delete. + (elf32_bfingfdpic_copy_private_bfd_data): Don't copy PT_GNU_STACK + here. + (elf_backend_stack_align): Override. + (elf_backend_modify_program_headers): Don't override. + * elf32-frv.c (frvfdpic_always_size_sections): Call + bfd_elf_stack_segment_size. + (elf32_frvfdpic_modify_program_headers): Delete. + (elf32_frvfdpic_copy_private_bfd_data): Don't copy PT_GNU_STACK + here. + (elf_backend_stack_align): Override. + (elf_backend_modify_program_headers): Don't override. + * elf32-lm32.c (lm32_elf_always_size_sections): Leave + PT_GNU_STACK creation to underlying elf support. Check + __stacksize here for backwards compatibility, and set it if + needed. + (lm32_elf_modify_segment_map): Delete. + (lm32_elf_modify_program_headers): Delete. + (elf_backend_stack_align): Override. + (elf_backend_modify_segment_map): Don't override. + (elf_backend_modify_program_headers): Don't override. + * elf32-sh.c (sh_elf_always_size_sections): Call + bfd_elf_stack_segment_size. + (sh_elf_modify_program_headers): Delete. + (sh_elf_copy_private_data): Don't copy PT_GNU_STACK + here. + (elf_backend_stack_align): Override. + (elf_backend_modify_program_headers): Don't override. + * elf32-tic6x.c (elf32_tic6x_always_size_sections): Call + bfd_elf_stack_segment_size. + (elf32_tic6x_modify_program_headers): Delete. + (elf32_tic6x_copy_private_data): Delete. + (elf_backend_stack_align): Override. + (bfd_elf32_bfd_copy_private_bfd_data): Don't override. + (elf_backend_modify_program_headers): Don't override. + 2012-10-22 Alan Modra <amodra@gmail.com> * cache.c (cache_bmmap): Don't use void* arithmetic. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index a8c2db1..968b72c 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -648,6 +648,8 @@ extern struct bfd_link_needed_list *bfd_elf_get_needed_list (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_get_bfd_needed_list (bfd *, struct bfd_link_needed_list **); +extern bfd_boolean bfd_elf_stack_segment_size (bfd *, struct bfd_link_info *, + const char *, bfd_vma); extern bfd_boolean bfd_elf_size_dynamic_sections (bfd *, const char *, const char *, const char *, const char *, const char *, const char * const *, struct bfd_link_info *, struct bfd_section **); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 919f51a..e94e3c8 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -655,6 +655,8 @@ extern struct bfd_link_needed_list *bfd_elf_get_needed_list (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_get_bfd_needed_list (bfd *, struct bfd_link_needed_list **); +extern bfd_boolean bfd_elf_stack_segment_size (bfd *, struct bfd_link_info *, + const char *, bfd_vma); extern bfd_boolean bfd_elf_size_dynamic_sections (bfd *, const char *, const char *, const char *, const char *, const char *, const char * const *, struct bfd_link_info *, struct bfd_section **); diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 3709af9..b8d82b1 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1285,6 +1285,9 @@ struct elf_backend_data /* This is non-zero if static TLS segments require a special alignment. */ unsigned static_tls_alignment; + /* Alignment for the PT_GNU_STACK segment. */ + unsigned stack_align; + /* This is TRUE if the linker should act like collect and gather global constructors and destructors by name. This is TRUE for MIPS ELF because the Irix 5 tools can not handle the .init @@ -4140,7 +4140,14 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) m->next = NULL; m->p_type = PT_GNU_STACK; m->p_flags = elf_tdata (abfd)->stack_flags; + m->p_align = bed->stack_align; m->p_flags_valid = 1; + m->p_align_valid = m->p_align != 0; + if (info->stacksize > 0) + { + m->p_size = info->stacksize; + m->p_size_valid = 1; + } *pm = m; pm = &m->next; @@ -5022,6 +5029,11 @@ assign_file_positions_for_non_load_sections (bfd *abfd, p->p_type = PT_NULL; } } + else if (p->p_type == PT_GNU_STACK) + { + if (m->p_size_valid) + p->p_memsz = m->p_size; + } else if (m->count != 0) { if (p->p_type != PT_LOAD @@ -6166,12 +6178,15 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) map->p_align_valid = 1; map->p_vaddr_offset = 0; - if (map->p_type == PT_GNU_RELRO) + if (map->p_type == PT_GNU_RELRO + || map->p_type == PT_GNU_STACK) { /* The PT_GNU_RELRO segment may contain the first a few bytes in the .got.plt section even if the whole .got.plt section isn't in the PT_GNU_RELRO segment. We won't - change the size of the PT_GNU_RELRO segment. */ + change the size of the PT_GNU_RELRO segment. + Similarly, PT_GNU_STACK size is significant on uclinux + systems. */ map->p_size = segment->p_memsz; map->p_size_valid = 1; } diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index 6173433..c8e089b 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -4311,35 +4311,10 @@ static bfd_boolean elf32_bfinfdpic_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) { - if (!info->relocatable) - { - struct elf_link_hash_entry *h; - - /* Force a PT_GNU_STACK segment to be created. */ - if (! elf_tdata (output_bfd)->stack_flags) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; - - /* Define __stacksize if it's not defined yet. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (! h || h->root.type != bfd_link_hash_defined - || h->type != STT_OBJECT - || !h->def_regular) - { - struct bfd_link_hash_entry *bh = NULL; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "__stacksize", - BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE, - (const char *) NULL, FALSE, - get_elf_backend_data (output_bfd)->collect, &bh))) - return FALSE; - - h = (struct elf_link_hash_entry *) bh; - h->def_regular = 1; - h->type = STT_OBJECT; - } - } + if (!info->relocatable + && !bfd_elf_stack_segment_size (output_bfd, info, + "__stacksize", DEFAULT_STACK_SIZE)) + return FALSE; return TRUE; } @@ -4460,51 +4435,6 @@ bfinfdpic_elf_discard_info (bfd *ibfd, } static bfd_boolean -elf32_bfinfdpic_modify_program_headers (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_obj_tdata *tdata = elf_tdata (output_bfd); - struct elf_segment_map *m; - Elf_Internal_Phdr *p; - - /* objcopy and strip preserve what's already there using - elf32_bfinfdpic_copy_private_bfd_data (). */ - if (! info) - return TRUE; - - for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) - if (m->p_type == PT_GNU_STACK) - break; - - if (m) - { - struct elf_link_hash_entry *h; - - /* Obtain the pointer to the __stacksize symbol. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (h) - { - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - } - - /* Set the header p_memsz from the symbol value. We - intentionally ignore the symbol section. */ - if (h && h->root.type == bfd_link_hash_defined) - p->p_memsz = h->root.u.def.value; - else - p->p_memsz = DEFAULT_STACK_SIZE; - - p->p_align = 8; - } - - return TRUE; -} - -static bfd_boolean elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) { @@ -5017,8 +4947,6 @@ bfin_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) static bfd_boolean elf32_bfinfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { - unsigned i; - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return TRUE; @@ -5030,31 +4958,6 @@ elf32_bfinfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd) || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr) return TRUE; - /* Copy the stack size. */ - for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++) - if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK) - { - Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i]; - - for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++) - if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK) - { - memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr)); - - /* Rewrite the phdrs, since we're only called after they - were first written. */ - if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd) - ->s->sizeof_ehdr, SEEK_SET) != 0 - || get_elf_backend_data (obfd)->s - ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr, - elf_elfheader (obfd)->e_phnum) != 0) - return FALSE; - break; - } - - break; - } - return TRUE; } @@ -5802,6 +5705,7 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] = #define elf_backend_final_write_processing \ elf32_bfin_final_write_processing #define elf_backend_reloc_type_class elf32_bfin_reloc_type_class +#define elf_backend_stack_align 8 #define elf_backend_can_gc_sections 1 #define elf_backend_special_sections elf32_bfin_special_sections #define elf_backend_can_refcount 1 @@ -5837,9 +5741,6 @@ struct bfd_elf_special_section const elf32_bfin_special_sections[] = #undef elf_backend_always_size_sections #define elf_backend_always_size_sections \ elf32_bfinfdpic_always_size_sections -#undef elf_backend_modify_program_headers -#define elf_backend_modify_program_headers \ - elf32_bfinfdpic_modify_program_headers #undef bfd_elf32_bfd_copy_private_bfd_data #define bfd_elf32_bfd_copy_private_bfd_data \ elf32_bfinfdpic_copy_private_bfd_data diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index 271ec02..1481733 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -5494,36 +5494,10 @@ static bfd_boolean elf32_frvfdpic_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) { - if (!info->relocatable) - { - struct elf_link_hash_entry *h; - - /* Force a PT_GNU_STACK segment to be created. */ - if (! elf_tdata (output_bfd)->stack_flags) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; - - /* Define __stacksize if it's not defined yet. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (! h || h->root.type != bfd_link_hash_defined - || h->type != STT_OBJECT - || !h->def_regular) - { - struct bfd_link_hash_entry *bh = NULL; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "__stacksize", - BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE, - (const char *) NULL, FALSE, - get_elf_backend_data (output_bfd)->collect, &bh))) - return FALSE; - - h = (struct elf_link_hash_entry *) bh; - h->def_regular = 1; - h->type = STT_OBJECT; - /* This one must NOT be hidden. */ - } - } + if (!info->relocatable + && !bfd_elf_stack_segment_size (output_bfd, info, + "__stacksize", DEFAULT_STACK_SIZE)) + return FALSE; return TRUE; } @@ -5720,51 +5694,6 @@ elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, return TRUE; } -static bfd_boolean -elf32_frvfdpic_modify_program_headers (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_obj_tdata *tdata = elf_tdata (output_bfd); - struct elf_segment_map *m; - Elf_Internal_Phdr *p; - - /* objcopy and strip preserve what's already there using - elf32_frvfdpic_copy_private_bfd_data (). */ - if (! info) - return TRUE; - - for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) - if (m->p_type == PT_GNU_STACK) - break; - - if (m) - { - struct elf_link_hash_entry *h; - - /* Obtain the pointer to the __stacksize symbol. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (h) - { - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - } - - /* Set the header p_memsz from the symbol value. We - intentionally ignore the symbol section. */ - if (h && h->root.type == bfd_link_hash_defined) - p->p_memsz = h->root.u.def.value; - else - p->p_memsz = DEFAULT_STACK_SIZE; - - p->p_align = 8; - } - - return TRUE; -} - /* Fill in code and data in dynamic sections. */ static bfd_boolean @@ -6431,8 +6360,6 @@ frv_elf_arch_extension_p (flagword base, flagword extension) static bfd_boolean elf32_frvfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { - unsigned i; - if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour || bfd_get_flavour (obfd) != bfd_target_elf_flavour) return TRUE; @@ -6444,31 +6371,6 @@ elf32_frvfdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd) || ! elf_tdata (obfd) || ! elf_tdata (obfd)->phdr) return TRUE; - /* Copy the stack size. */ - for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++) - if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK) - { - Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i]; - - for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++) - if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK) - { - memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr)); - - /* Rewrite the phdrs, since we're only called after they - were first written. */ - if (bfd_seek (obfd, (bfd_signed_vma) get_elf_backend_data (obfd) - ->s->sizeof_ehdr, SEEK_SET) != 0 - || get_elf_backend_data (obfd)->s - ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr, - elf_elfheader (obfd)->e_phnum) != 0) - return FALSE; - break; - } - - break; - } - return TRUE; } @@ -6920,6 +6822,7 @@ elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) #define elf_backend_object_p elf32_frv_object_p #define elf_backend_add_symbol_hook elf32_frv_add_symbol_hook +#define elf_backend_stack_align 8 #define elf_backend_can_gc_sections 1 #define elf_backend_rela_normal 1 @@ -6964,9 +6867,6 @@ elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) #undef elf_backend_always_size_sections #define elf_backend_always_size_sections \ elf32_frvfdpic_always_size_sections -#undef elf_backend_modify_program_headers -#define elf_backend_modify_program_headers \ - elf32_frvfdpic_modify_program_headers #undef bfd_elf32_bfd_copy_private_bfd_data #define bfd_elf32_bfd_copy_private_bfd_data \ elf32_frvfdpic_copy_private_bfd_data diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c index f40536c..2579034 100644 --- a/bfd/elf32-lm32.c +++ b/bfd/elf32-lm32.c @@ -2615,136 +2615,23 @@ lm32_elf_copy_indirect_symbol (struct bfd_link_info *info, } static bfd_boolean -lm32_elf_always_size_sections (bfd *output_bfd, - struct bfd_link_info *info) +lm32_elf_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) { if (!info->relocatable) { - struct elf_link_hash_entry *h; - - /* Force a PT_GNU_STACK segment to be created. */ - if (! elf_tdata (output_bfd)->stack_flags) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; - - /* Define __stacksize if it's not defined yet. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (! h || h->root.type != bfd_link_hash_defined - || h->type != STT_OBJECT - || !h->def_regular) - { - struct bfd_link_hash_entry *bh = NULL; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "__stacksize", - BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE, - (const char *) NULL, FALSE, - get_elf_backend_data (output_bfd)->collect, &bh))) - return FALSE; - - h = (struct elf_link_hash_entry *) bh; - h->def_regular = 1; - h->type = STT_OBJECT; - /* This one must NOT be hidden. */ - } - } + if (!bfd_elf_stack_segment_size (output_bfd, info, + "__stacksize", DEFAULT_STACK_SIZE)) + return FALSE; - return TRUE; -} - -static bfd_boolean -lm32_elf_modify_segment_map (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_segment_map *m; - - /* objcopy and strip preserve what's already there using elf32_lm32fdpic_copy_ - private_bfd_data (). */ - if (! info) - return TRUE; - - for (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next) - if (m->p_type == PT_GNU_STACK) - break; - - if (m) - { asection *sec = bfd_get_section_by_name (output_bfd, ".stack"); - struct elf_link_hash_entry *h; - if (sec) - { - /* Obtain the pointer to the __stacksize symbol. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *)h->root.u.i.link; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - - /* Set the section size from the symbol value. We - intentionally ignore the symbol section. */ - if (h->root.type == bfd_link_hash_defined) - sec->size = h->root.u.def.value; - else - sec->size = DEFAULT_STACK_SIZE; - - /* Add the stack section to the PT_GNU_STACK segment, - such that its size and alignment requirements make it - to the segment. */ - m->sections[m->count] = sec; - m->count++; - } + sec->size = info->stacksize >= 0 ? info->stacksize : 0; } return TRUE; } static bfd_boolean -lm32_elf_modify_program_headers (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_obj_tdata *tdata = elf_tdata (output_bfd); - struct elf_segment_map *m; - Elf_Internal_Phdr *p; - - if (! info) - return TRUE; - - for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) - if (m->p_type == PT_GNU_STACK) - break; - - if (m) - { - struct elf_link_hash_entry *h; - - /* Obtain the pointer to the __stacksize symbol. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (h) - { - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - } - - /* Set the header p_memsz from the symbol value. We - intentionally ignore the symbol section. */ - if (h && h->root.type == bfd_link_hash_defined) - p->p_memsz = h->root.u.def.value; - else - p->p_memsz = DEFAULT_STACK_SIZE; - - p->p_align = 8; - } - - return TRUE; -} - - -static bfd_boolean lm32_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour @@ -2822,6 +2709,7 @@ lm32_elf_fdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd) #define elf_backend_rela_normal 1 #define elf_backend_object_p lm32_elf_object_p #define elf_backend_final_write_processing lm32_elf_final_write_processing +#define elf_backend_stack_align 8 #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 #define elf_backend_gc_mark_hook lm32_elf_gc_mark_hook @@ -2857,10 +2745,6 @@ lm32_elf_fdpic_copy_private_bfd_data (bfd *ibfd, bfd *obfd) #undef elf_backend_always_size_sections #define elf_backend_always_size_sections lm32_elf_always_size_sections -#undef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map lm32_elf_modify_segment_map -#undef elf_backend_modify_program_headers -#define elf_backend_modify_program_headers lm32_elf_modify_program_headers #undef bfd_elf32_bfd_copy_private_bfd_data #define bfd_elf32_bfd_copy_private_bfd_data lm32_elf_fdpic_copy_private_bfd_data diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index df4affd..8540f9f 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -3314,86 +3314,13 @@ sh_elf_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) { sh_elf_hash_table (info)->plt_info = get_plt_info (output_bfd, info->shared); - if (sh_elf_hash_table (info)->fdpic_p && !info->relocatable) - { - struct elf_link_hash_entry *h; - - /* Force a PT_GNU_STACK segment to be created. */ - if (! elf_tdata (output_bfd)->stack_flags) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; - - /* Define __stacksize if it's not defined yet. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (! h || h->root.type != bfd_link_hash_defined - || h->type != STT_OBJECT - || !h->def_regular) - { - struct bfd_link_hash_entry *bh = NULL; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "__stacksize", - BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE, - (const char *) NULL, FALSE, - get_elf_backend_data (output_bfd)->collect, &bh))) - return FALSE; - - h = (struct elf_link_hash_entry *) bh; - h->def_regular = 1; - h->type = STT_OBJECT; - } - } - return TRUE; -} - -#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED - -static bfd_boolean -sh_elf_modify_program_headers (bfd *output_bfd, struct bfd_link_info *info) -{ - struct elf_obj_tdata *tdata = elf_tdata (output_bfd); - struct elf_segment_map *m; - Elf_Internal_Phdr *p; - - /* objcopy and strip preserve what's already there using - sh_elf_copy_private_bfd_data (). */ - if (! info) - return TRUE; - - for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) - if (m->p_type == PT_GNU_STACK) - break; - - if (m) - { - struct elf_link_hash_entry *h; - - /* Obtain the pointer to the __stacksize symbol. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (h) - { - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - } - - /* Set the header p_memsz from the symbol value. We - intentionally ignore the symbol section. */ - if (h && h->root.type == bfd_link_hash_defined) - p->p_memsz = h->root.u.def.value; - else - p->p_memsz = DEFAULT_STACK_SIZE; - - p->p_align = 8; - } - + if (sh_elf_hash_table (info)->fdpic_p && !info->relocatable + && !bfd_elf_stack_segment_size (output_bfd, info, + "__stacksize", DEFAULT_STACK_SIZE)) + return FALSE; return TRUE; } -#endif - /* Set the sizes of the dynamic sections. */ static bfd_boolean @@ -6683,38 +6610,6 @@ sh_elf_copy_private_data (bfd * ibfd, bfd * obfd) if (! is_sh_elf (ibfd) || ! is_sh_elf (obfd)) return TRUE; - /* Copy the stack size. */ - if (elf_tdata (ibfd)->phdr && elf_tdata (obfd)->phdr - && fdpic_object_p (ibfd) && fdpic_object_p (obfd)) - { - unsigned i; - - for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++) - if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK) - { - Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i]; - - for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++) - if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK) - { - memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr)); - - /* Rewrite the phdrs, since we're only called after they - were first written. */ - if (bfd_seek (obfd, - (bfd_signed_vma) get_elf_backend_data (obfd) - ->s->sizeof_ehdr, SEEK_SET) != 0 - || get_elf_backend_data (obfd)->s - ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr, - elf_elfheader (obfd)->e_phnum) != 0) - return FALSE; - break; - } - - break; - } - } - return sh_elf_set_private_flags (obfd, elf_elfheader (ibfd)->e_flags); } #endif /* not sh_elf_copy_private_data */ @@ -7587,6 +7482,7 @@ sh_elf_encode_eh_address (bfd *abfd, #define elf_backend_encode_eh_address \ sh_elf_encode_eh_address +#define elf_backend_stack_align 8 #define elf_backend_can_gc_sections 1 #define elf_backend_can_refcount 1 #define elf_backend_want_got_plt 1 @@ -7649,9 +7545,6 @@ sh_elf_encode_eh_address (bfd *abfd, #define TARGET_LITTLE_SYM bfd_elf32_shfd_vec #undef TARGET_LITTLE_NAME #define TARGET_LITTLE_NAME "elf32-sh-fdpic" -#undef elf_backend_modify_program_headers -#define elf_backend_modify_program_headers \ - sh_elf_modify_program_headers #undef elf32_bed #define elf32_bed elf32_sh_fd_bed diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c index ef0d155..419b269 100644 --- a/bfd/elf32-tic6x.c +++ b/bfd/elf32-tic6x.c @@ -3520,79 +3520,10 @@ elf32_tic6x_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) static bfd_boolean elf32_tic6x_always_size_sections (bfd *output_bfd, struct bfd_link_info *info) { - if (elf32_tic6x_using_dsbt (output_bfd) && !info->relocatable) - { - struct elf_link_hash_entry *h; - - /* Force a PT_GNU_STACK segment to be created. */ - if (! elf_tdata (output_bfd)->stack_flags) - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; - - /* Define __stacksize if it's not defined yet. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (! h || h->root.type != bfd_link_hash_defined - || h->type != STT_OBJECT - || !h->def_regular) - { - struct bfd_link_hash_entry *bh = NULL; - - if (!(_bfd_generic_link_add_one_symbol - (info, output_bfd, "__stacksize", - BSF_GLOBAL, bfd_abs_section_ptr, DEFAULT_STACK_SIZE, - (const char *) NULL, FALSE, - get_elf_backend_data (output_bfd)->collect, &bh))) - return FALSE; - - h = (struct elf_link_hash_entry *) bh; - h->def_regular = 1; - h->type = STT_OBJECT; - } - } - return TRUE; -} - -static bfd_boolean -elf32_tic6x_modify_program_headers (bfd *output_bfd, - struct bfd_link_info *info) -{ - struct elf_obj_tdata *tdata = elf_tdata (output_bfd); - struct elf_segment_map *m; - Elf_Internal_Phdr *p; - - /* objcopy and strip preserve what's already there using - elf32_tic6x_copy_private_bfd_data (). */ - if (! info) - return TRUE; - - for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) - if (m->p_type == PT_GNU_STACK) - break; - - if (m) - { - struct elf_link_hash_entry *h; - - /* Obtain the pointer to the __stacksize symbol. */ - h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", - FALSE, FALSE, FALSE); - if (h) - { - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - BFD_ASSERT (h->root.type == bfd_link_hash_defined); - } - - /* Set the header p_memsz from the symbol value. We - intentionally ignore the symbol section. */ - if (h && h->root.type == bfd_link_hash_defined) - p->p_memsz = h->root.u.def.value; - else - p->p_memsz = DEFAULT_STACK_SIZE; - - p->p_align = 8; - } + if (elf32_tic6x_using_dsbt (output_bfd) && !info->relocatable + && !bfd_elf_stack_segment_size (output_bfd, info, + "__stacksize", DEFAULT_STACK_SIZE)) + return FALSE; return TRUE; } @@ -4020,49 +3951,6 @@ elf32_tic6x_merge_private_bfd_data (bfd *ibfd, bfd *obfd) return TRUE; } -static bfd_boolean -elf32_tic6x_copy_private_data (bfd * ibfd, bfd * obfd) -{ - _bfd_elf_copy_private_bfd_data (ibfd, obfd); - - if (! is_tic6x_elf (ibfd) || ! is_tic6x_elf (obfd)) - return TRUE; - - /* Copy the stack size. */ - if (elf_tdata (ibfd)->phdr && elf_tdata (obfd)->phdr - && elf32_tic6x_using_dsbt (ibfd) && elf32_tic6x_using_dsbt (obfd)) - { - unsigned i; - - for (i = 0; i < elf_elfheader (ibfd)->e_phnum; i++) - if (elf_tdata (ibfd)->phdr[i].p_type == PT_GNU_STACK) - { - Elf_Internal_Phdr *iphdr = &elf_tdata (ibfd)->phdr[i]; - - for (i = 0; i < elf_elfheader (obfd)->e_phnum; i++) - if (elf_tdata (obfd)->phdr[i].p_type == PT_GNU_STACK) - { - memcpy (&elf_tdata (obfd)->phdr[i], iphdr, sizeof (*iphdr)); - - /* Rewrite the phdrs, since we're only called after they - were first written. */ - if (bfd_seek (obfd, - (bfd_signed_vma) get_elf_backend_data (obfd) - ->s->sizeof_ehdr, SEEK_SET) != 0 - || get_elf_backend_data (obfd)->s - ->write_out_phdrs (obfd, elf_tdata (obfd)->phdr, - elf_elfheader (obfd)->e_phnum) != 0) - return FALSE; - break; - } - - break; - } - } - - return TRUE; -} - /* Add a new unwind edit to the list described by HEAD, TAIL. If TINDEX is zero, adds the edit to the start of the list. (The list must be built in order of ascending TINDEX: the function's callers are primarily responsible for @@ -4484,12 +4372,12 @@ elf32_tic6x_set_osabi (bfd *abfd, struct bfd_link_info *link_info) #define ELF_MAXPAGESIZE 0x1000 #define bfd_elf32_bfd_reloc_type_lookup elf32_tic6x_reloc_type_lookup #define bfd_elf32_bfd_reloc_name_lookup elf32_tic6x_reloc_name_lookup -#define bfd_elf32_bfd_copy_private_bfd_data elf32_tic6x_copy_private_data #define bfd_elf32_bfd_merge_private_bfd_data elf32_tic6x_merge_private_bfd_data #define bfd_elf32_mkobject elf32_tic6x_mkobject #define bfd_elf32_bfd_link_hash_table_create elf32_tic6x_link_hash_table_create #define bfd_elf32_bfd_link_hash_table_free elf32_tic6x_link_hash_table_free #define bfd_elf32_new_section_hook elf32_tic6x_new_section_hook +#define elf_backend_stack_align 8 #define elf_backend_can_gc_sections 1 #define elf_backend_default_use_rela_p 1 #define elf_backend_may_use_rel_p 1 @@ -4509,8 +4397,6 @@ elf32_tic6x_set_osabi (bfd *abfd, struct bfd_link_info *link_info) #define elf_backend_fake_sections elf32_tic6x_fake_sections #define elf_backend_gc_sweep_hook elf32_tic6x_gc_sweep_hook #define elf_backend_gc_mark_extra_sections elf32_tic6x_gc_mark_extra_sections -#define elf_backend_modify_program_headers \ - elf32_tic6x_modify_program_headers #define elf_backend_create_dynamic_sections \ elf32_tic6x_create_dynamic_sections #define elf_backend_adjust_dynamic_symbol \ diff --git a/bfd/elflink.c b/bfd/elflink.c index 232c0b1..f22e023 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -5567,6 +5567,65 @@ _bfd_elf_size_group_sections (struct bfd_link_info *info) return TRUE; } +/* Set a default stack segment size. The value in INFO wins. If it + is unset, LEGACY_SYMBOL's value is used, and if that symbol is + undefined it is initialized. */ + +bfd_boolean +bfd_elf_stack_segment_size (bfd *output_bfd, + struct bfd_link_info *info, + const char *legacy_symbol, + bfd_vma default_size) +{ + struct elf_link_hash_entry *h = NULL; + + /* Look for legacy symbol. */ + if (legacy_symbol) + h = elf_link_hash_lookup (elf_hash_table (info), legacy_symbol, + FALSE, FALSE, FALSE); + if (h && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && h->def_regular + && (h->type == STT_NOTYPE || h->type == STT_OBJECT)) + { + /* The symbol has no type if specified on the command line. */ + h->type = STT_OBJECT; + if (info->stacksize) + (*_bfd_error_handler) (_("%B: stack size specified and %s set"), + output_bfd, legacy_symbol); + else if (h->root.u.def.section != bfd_abs_section_ptr) + (*_bfd_error_handler) (_("%B: %s not absolute"), + output_bfd, legacy_symbol); + else + info->stacksize = h->root.u.def.value; + } + + if (!info->stacksize) + /* If the user didn't set a size, or explicitly inhibit the + size, set it now. */ + info->stacksize = default_size; + + /* Provide the legacy symbol, if it is referenced. */ + if (h && (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak)) + { + struct bfd_link_hash_entry *bh = NULL; + + if (!(_bfd_generic_link_add_one_symbol + (info, output_bfd, legacy_symbol, + BSF_GLOBAL, bfd_abs_section_ptr, + info->stacksize >= 0 ? info->stacksize : 0, + NULL, FALSE, get_elf_backend_data (output_bfd)->collect, &bh))) + return FALSE; + + h = (struct elf_link_hash_entry *) bh; + h->def_regular = 1; + h->type = STT_OBJECT; + } + + return TRUE; +} + /* Set up the sizes and contents of the ELF dynamic sections. This is called by the ELF linker emulation before_allocation routine. We must set the sizes of the sections before the linker sets the @@ -5596,6 +5655,26 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, return TRUE; bed = get_elf_backend_data (output_bfd); + + /* Any syms created from now on start with -1 in + got.refcount/offset and plt.refcount/offset. */ + elf_hash_table (info)->init_got_refcount + = elf_hash_table (info)->init_got_offset; + elf_hash_table (info)->init_plt_refcount + = elf_hash_table (info)->init_plt_offset; + + if (info->relocatable + && !_bfd_elf_size_group_sections (info)) + return FALSE; + + /* The backend may have to create some sections regardless of whether + we're dynamic or not. */ + if (bed->elf_backend_always_size_sections + && ! (*bed->elf_backend_always_size_sections) (output_bfd, info)) + return FALSE; + + /* Determine any GNU_STACK segment requirements, after the backend + has had a chance to set a default segment size. */ if (info->execstack) elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X; else if (info->noexecstack) @@ -5625,32 +5704,13 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, else if (bed->default_execstack) exec = PF_X; } - if (notesec) - { - elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec; - if (exec && info->relocatable - && notesec->output_section != bfd_abs_section_ptr) - notesec->output_section->flags |= SEC_CODE; - } + if (notesec || info->stacksize > 0) + elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec; + if (notesec && exec && info->relocatable + && notesec->output_section != bfd_abs_section_ptr) + notesec->output_section->flags |= SEC_CODE; } - /* Any syms created from now on start with -1 in - got.refcount/offset and plt.refcount/offset. */ - elf_hash_table (info)->init_got_refcount - = elf_hash_table (info)->init_got_offset; - elf_hash_table (info)->init_plt_refcount - = elf_hash_table (info)->init_plt_offset; - - if (info->relocatable - && !_bfd_elf_size_group_sections (info)) - return FALSE; - - /* The backend may have to create some sections regardless of whether - we're dynamic or not. */ - if (bed->elf_backend_always_size_sections - && ! (*bed->elf_backend_always_size_sections) (output_bfd, info)) - return FALSE; - dynobj = elf_hash_table (info)->dynobj; if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created) diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 5a6cae0..241743a 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -109,6 +109,9 @@ #ifndef elf_backend_default_execstack #define elf_backend_default_execstack 1 #endif +#ifndef elf_backend_stack_align +#define elf_backend_stack_align 16 +#endif #define bfd_elfNN_bfd_debug_info_start bfd_void #define bfd_elfNN_bfd_debug_info_end bfd_void @@ -770,6 +773,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_obj_attrs_order, elf_backend_obj_attrs_handle_unknown, elf_backend_static_tls_alignment, + elf_backend_stack_align, elf_backend_collect, elf_backend_type_change_ok, elf_backend_may_use_rel_p, |