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/elflink.c | |
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/elflink.c')
-rw-r--r-- | bfd/elflink.c | 108 |
1 files changed, 84 insertions, 24 deletions
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) |