From e36284abcf727bced126cad8c8a1cc7ba33ad6c2 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 20 Jun 2006 14:34:08 +0000 Subject: [PATCH] * 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. --- bfd/ChangeLog | 28 +++++++++++++++++++++++++++ bfd/elf-bfd.h | 5 +++++ bfd/elf.c | 15 ++++++++++----- bfd/elf32-bfin.c | 56 ++++++++++++++++++++---------------------------------- bfd/elf32-frv.c | 56 ++++++++++++++++++++---------------------------------- bfd/elfxx-ia64.c | 27 ++++++++++++++++++++------ bfd/elfxx-target.h | 4 ++++ 7 files changed, 110 insertions(+), 81 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a1265d8..b6996a8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,31 @@ +2006-06-21 Alan Modra + + * 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. + 2006-06-20 Jakub Jelinek * bfd.c (bfd_record_phdr): Clear p_align and p_align_valid fields. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 9813416..95686d3 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -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) diff --git a/bfd/elf.c b/bfd/elf.c index 25570ec..8a725c3 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -3734,8 +3734,6 @@ elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info) 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) { @@ -4217,7 +4215,8 @@ assign_file_positions_for_load_sections (bfd *abfd, 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; @@ -4720,8 +4719,8 @@ assign_file_positions_for_non_load_sections (bfd *abfd, if (lp->p_type == PT_LOAD && lp->p_vaddr <= link_info->relro_end && lp->p_vaddr >= link_info->relro_start - && lp->p_vaddr + lp->p_filesz - >= link_info->relro_end) + && (lp->p_vaddr + lp->p_filesz + >= link_info->relro_end)) break; } @@ -4823,6 +4822,12 @@ assign_file_positions_except_relocs (bfd *abfd, 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 diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index ed3db10..54900d0 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -4156,7 +4156,6 @@ elf32_bfinfdpic_always_size_sections (bfd *output_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) @@ -4182,64 +4181,51 @@ elf32_bfinfdpic_always_size_sections (bfd *output_bfd, 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 diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index de2358b..5f83f81 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -5603,7 +5603,6 @@ elf32_frvfdpic_always_size_sections (bfd *output_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 *output_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 ATTRIBUTE_UNUSED, asection *sec, } 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_Internal_Note *note) #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 diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index c057967..32dea4c 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -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 (bfd *abfd ATTRIBUTE_UNUSED, 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 diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index fad00f2..38aa373 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -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, -- 2.7.4