FRV and Blackfin PT_GNU_STACK
Alan Modra
amodra@bigpond.net.au
Tue Jun 20 12:24:00 GMT 2006
More information about the Binutils mailing list
Tue Jun 20 12:24:00 GMT 2006
- Previous message (by thread): FRV and Blackfin PT_GNU_STACK
- Next message (by thread): FRV and Blackfin PT_GNU_STACK
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Tue, Jun 20, 2006 at 04:45:08PM +0800, Jie Zhang wrote: > On Tue, 2006-06-20 at 01:29 +0930, Alan Modra wrote: > > When testing SIZEOF_HEADERS relaxation, I noticed that a fix in > > http://sources.redhat.com/ml/binutils/2006-05/msg00318.html for PT_NOTE > > p_memsz broke PT_GNU_STACK p_memsz for frv and bfin. To get this field > > set, these ports create an output .stack section with the desired stack > > size (and alignment) and tack it on to the PT_GNU_STACK header using > > elf_backend_modify_segment_map. It's very much a hack, since you're not > > supposed to create sections like this in the output bfd. One > > consequence is that the .stack section header doesn't get its type > > correct (you'd expect NOBITS) or size set (which is fortunate in a way, > > because otherwise you'd end up with a large useless PROGBITS section in > > the object file). > > > > The question I have is this: Do you want a .stack section in the output > > file? Or should this section really be attached as an input section > > that extends the .bss output section? Or do without the section > > entirely and just magically tweak PT_GNU_STACK? > > > >From the code of binfmt_elf_fdpic.c in linux kernel, it seems the .stack > section is not needed. The kernel gets the stack size for the FDPIC ELF > application is from p_memsz of the PT_GNU_STACK segment. > > I'm not sure if my thought is right on why a .stack section is used > here, since I'm not the original writer of the code. The .stack section > is used to help set the PT_GNU_STACK segment size, since segment size is > calculated by sum up the size of all the sections of it. If we want to > eliminate the use of the section entirely, where can we magically tweak > PT_GNU_STACK? Is there is already a hook we can use or we need add one? Thanks for the feedback. Like you, I think the .stack section is only there to set PT_GNU_STACK p_memsz and p_palign. This is how I think FRV and Blackfin should set PT_GNU_STACK. No messing around with a bogus .stack section. The new hook also allows me to modify ia64 segments, so the final backend_modify_segment_map call isn't needed. * elf-bfd.h (struct elf_backend_data): Add elf_backend_modify_program_headers. * elfxx-target.h (elf_backend_modify_program_headers): Define. (elfNN_bed): Init new field. * elf.c (elf_modify_segment_map): Remove comment. (assign_file_positions_for_load_sections): Only call elf_modify_segment_map for objcopy/strip. (assign_file_positions_except_relocs): Call elf_backend_modify_program_headers. * elf32-frv.c (elf32_frvfdpic_always_size_sections): Don't make .stack section. (elf32_frvfdpic_modify_segment_map): Delete. (elf32_frvfdpic_modify_program_headers): New. (elf_backend_modify_segment_map): Don't define. (elf_backend_modify_program_headers): Define. * elf32-bfin.c (elf32_bfinfdpic_always_size_sections): Don't make .stack section. (elf32_bfinfdpic_modify_segment_map): Delete. (elf32_bfinfdpic_modify_program_headers): New. (elf_backend_modify_segment_map): Don't define. (elf_backend_modify_program_headers): Define. * elfxx-ia64.c (elfNN_ia64_modify_program_headers): New function. Split out from.. (elfNN_ia64_modify_segment_map): ..here. (elf_backend_modify_program_headers): Define. Index: bfd/elf-bfd.h =================================================================== RCS file: /cvs/src/src/bfd/elf-bfd.h,v retrieving revision 1.209 diff -u -p -r1.209 elf-bfd.h --- bfd/elf-bfd.h 20 Jun 2006 02:22:13 -0000 1.209 +++ bfd/elf-bfd.h 20 Jun 2006 03:47:47 -0000 @@ -836,6 +836,11 @@ struct elf_backend_data bfd_boolean (*elf_backend_modify_segment_map) (bfd *, struct bfd_link_info *); + /* This function is called to modify program headers just before + they are written. */ + bfd_boolean (*elf_backend_modify_program_headers) + (bfd *, struct bfd_link_info *); + /* This function is called during section garbage collection to mark sections that define global symbols. */ bfd_boolean (*gc_mark_dynamic_ref) Index: bfd/elfxx-target.h =================================================================== RCS file: /cvs/src/src/bfd/elfxx-target.h,v retrieving revision 1.95 diff -u -p -r1.95 elfxx-target.h --- bfd/elfxx-target.h 30 May 2006 16:45:31 -0000 1.95 +++ bfd/elfxx-target.h 20 Jun 2006 03:48:02 -0000 @@ -402,6 +402,9 @@ #ifndef elf_backend_modify_segment_map #define elf_backend_modify_segment_map 0 #endif +#ifndef elf_backend_modify_program_headers +#define elf_backend_modify_program_headers 0 +#endif #ifndef elf_backend_ecoff_debug_swap #define elf_backend_ecoff_debug_swap 0 #endif @@ -603,6 +606,7 @@ static struct elf_backend_data elfNN_bed elf_backend_final_write_processing, elf_backend_additional_program_headers, elf_backend_modify_segment_map, + elf_backend_modify_program_headers, elf_backend_gc_mark_dynamic_ref, elf_backend_gc_mark_hook, elf_backend_gc_sweep_hook, Index: bfd/elf.c =================================================================== RCS file: /cvs/src/src/bfd/elf.c,v retrieving revision 1.344 diff -u -p -r1.344 elf.c --- bfd/elf.c 20 Jun 2006 02:22:13 -0000 1.344 +++ bfd/elf.c 20 Jun 2006 03:47:52 -0000 @@ -3733,8 +3733,6 @@ elf_modify_segment_map (bfd *abfd, struc m->count = new_count; } - /* Yes, we call elf_backend_modify_segment_map at least two times - for the linker. The final time the link_orders are available. */ bed = get_elf_backend_data (abfd); if (bed->elf_backend_modify_segment_map != NULL) { @@ -4216,7 +4214,8 @@ assign_file_positions_for_load_sections unsigned int alloc; unsigned int i; - if (!elf_modify_segment_map (abfd, link_info)) + if (link_info == NULL + && !elf_modify_segment_map (abfd, link_info)) return FALSE; alloc = 0; @@ -4822,6 +4821,12 @@ assign_file_positions_except_relocs (bfd if (!assign_file_positions_for_non_load_sections (abfd, link_info)) return FALSE; + if (bed->elf_backend_modify_program_headers != NULL) + { + if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info)) + return FALSE; + } + /* Write out the program headers. */ alloc = tdata->program_header_size / bed->s->sizeof_phdr; if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 Index: bfd/elf32-frv.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-frv.c,v retrieving revision 1.47 diff -u -p -r1.47 elf32-frv.c --- bfd/elf32-frv.c 20 Jun 2006 02:22:13 -0000 1.47 +++ bfd/elf32-frv.c 20 Jun 2006 03:47:58 -0000 @@ -5603,7 +5603,6 @@ elf32_frvfdpic_always_size_sections (bfd if (!info->relocatable) { struct elf_link_hash_entry *h; - asection *sec; /* Force a PT_GNU_STACK segment to be created. */ if (! elf_tdata (output_bfd)->stack_flags) @@ -5630,13 +5629,6 @@ elf32_frvfdpic_always_size_sections (bfd h->type = STT_OBJECT; /* This one must NOT be hidden. */ } - - /* Create a stack section, and set its alignment. */ - sec = bfd_make_section (output_bfd, ".stack"); - - if (sec == NULL - || ! bfd_set_section_alignment (output_bfd, sec, 3)) - return FALSE; } return TRUE; @@ -5718,51 +5710,45 @@ elf32_frvfdpic_relax_section (bfd *abfd } static bfd_boolean -elf32_frvfdpic_modify_segment_map (bfd *output_bfd, - struct bfd_link_info *info) +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 (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next) + for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) 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); + if (h) { - /* 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; + 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; + /* 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; - /* Add the stack section to the PT_GNU_STACK segment, - such that its size and alignment requirements make it - to the segment. */ - if (m->count == 0) - { - m->sections[m->count] = sec; - m->count++; - } - } + p->p_align = 8; } return TRUE; @@ -6973,9 +6959,9 @@ elf32_frv_grok_psinfo (bfd *abfd, Elf_In #undef elf_backend_always_size_sections #define elf_backend_always_size_sections \ elf32_frvfdpic_always_size_sections -#undef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map \ - elf32_frvfdpic_modify_segment_map +#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 Index: bfd/elf32-bfin.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-bfin.c,v retrieving revision 1.14 diff -u -p -r1.14 elf32-bfin.c --- bfd/elf32-bfin.c 20 Jun 2006 02:22:13 -0000 1.14 +++ bfd/elf32-bfin.c 20 Jun 2006 03:56:43 -0000 @@ -4156,7 +4156,6 @@ elf32_bfinfdpic_always_size_sections (bf if (!info->relocatable) { struct elf_link_hash_entry *h; - asection *sec; /* Force a PT_GNU_STACK segment to be created. */ if (! elf_tdata (output_bfd)->stack_flags) @@ -4182,64 +4181,51 @@ elf32_bfinfdpic_always_size_sections (bf h->def_regular = 1; h->type = STT_OBJECT; } - - /* Create a stack section, and set its alignment. */ - sec = bfd_make_section (output_bfd, ".stack"); - - if (sec == NULL - || ! bfd_set_section_alignment (output_bfd, sec, 3)) - return FALSE; } return TRUE; } static bfd_boolean -elf32_bfinfdpic_modify_segment_map (bfd *output_bfd, - struct bfd_link_info *info) +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 (m = elf_tdata (output_bfd)->segment_map; m != NULL; m = m->next) + for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) 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); + if (h) { - /* 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; + 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; + /* 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; - /* Add the stack section to the PT_GNU_STACK segment, - such that its size and alignment requirements make it - to the segment. */ - if (m->count == 0) - { - m->sections[m->count] = sec; - m->count++; - } - } + p->p_align = 8; } return TRUE; @@ -5594,9 +5580,9 @@ error_return: #undef elf_backend_always_size_sections #define elf_backend_always_size_sections \ elf32_bfinfdpic_always_size_sections -#undef elf_backend_modify_segment_map -#define elf_backend_modify_segment_map \ - elf32_bfinfdpic_modify_segment_map +#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 Index: bfd/elfxx-ia64.c =================================================================== RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v retrieving revision 1.186 diff -u -p -r1.186 elfxx-ia64.c --- bfd/elfxx-ia64.c 20 Jun 2006 02:22:13 -0000 1.186 +++ bfd/elfxx-ia64.c 20 Jun 2006 03:48:02 -0000 @@ -1737,17 +1737,30 @@ elfNN_ia64_modify_segment_map (bfd *abfd } } - /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of - the input sections for each output section in the segment and testing - for SHF_IA_64_NORECOV on each. */ - for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next) + return TRUE; +} + +/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of + the input sections for each output section in the segment and testing + for SHF_IA_64_NORECOV on each. */ + +static bfd_boolean +elfNN_ia64_modify_program_headers (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED) +{ + struct elf_obj_tdata *tdata = elf_tdata (abfd); + struct elf_segment_map *m; + Elf_Internal_Phdr *p; + + for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++) if (m->p_type == PT_LOAD) { int i; for (i = m->count - 1; i >= 0; --i) { struct bfd_link_order *order = m->sections[i]->map_head.link_order; - while (order) + + while (order != NULL) { if (order->type == bfd_indirect_link_order) { @@ -1755,7 +1768,7 @@ elfNN_ia64_modify_segment_map (bfd *abfd bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags; if (flags & SHF_IA_64_NORECOV) { - m->p_flags |= PF_IA_64_NORECOV; + p->p_flags |= PF_IA_64_NORECOV; goto found; } } @@ -5728,6 +5741,8 @@ elfNN_hpux_backend_symbol_processing (bf elfNN_ia64_additional_program_headers #define elf_backend_modify_segment_map \ elfNN_ia64_modify_segment_map +#define elf_backend_modify_program_headers \ + elfNN_ia64_modify_program_headers #define elf_info_to_howto \ elfNN_ia64_info_to_howto -- Alan Modra IBM OzLabs - Linux Technology Centre
- Previous message (by thread): FRV and Blackfin PT_GNU_STACK
- Next message (by thread): FRV and Blackfin PT_GNU_STACK
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list