* 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.
This commit is contained in:
Alan Modra 2006-06-20 14:34:08 +00:00
parent add68859a9
commit e36284abcf
7 changed files with 112 additions and 83 deletions

View file

@ -1,3 +1,31 @@
2006-06-21 Alan Modra <amodra@bigpond.net.au>
* 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 <jakub@redhat.com> 2006-06-20 Jakub Jelinek <jakub@redhat.com>
* bfd.c (bfd_record_phdr): Clear p_align and p_align_valid fields. * bfd.c (bfd_record_phdr): Clear p_align and p_align_valid fields.

View file

@ -836,6 +836,11 @@ struct elf_backend_data
bfd_boolean (*elf_backend_modify_segment_map) bfd_boolean (*elf_backend_modify_segment_map)
(bfd *, struct bfd_link_info *); (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 /* This function is called during section garbage collection to
mark sections that define global symbols. */ mark sections that define global symbols. */
bfd_boolean (*gc_mark_dynamic_ref) bfd_boolean (*gc_mark_dynamic_ref)

View file

@ -3734,8 +3734,6 @@ elf_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
m->count = new_count; 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); bed = get_elf_backend_data (abfd);
if (bed->elf_backend_modify_segment_map != NULL) 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 alloc;
unsigned int i; unsigned int i;
if (!elf_modify_segment_map (abfd, link_info)) if (link_info == NULL
&& !elf_modify_segment_map (abfd, link_info))
return FALSE; return FALSE;
alloc = 0; alloc = 0;
@ -4720,8 +4719,8 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
if (lp->p_type == PT_LOAD if (lp->p_type == PT_LOAD
&& lp->p_vaddr <= link_info->relro_end && lp->p_vaddr <= link_info->relro_end
&& lp->p_vaddr >= link_info->relro_start && lp->p_vaddr >= link_info->relro_start
&& lp->p_vaddr + lp->p_filesz && (lp->p_vaddr + lp->p_filesz
>= link_info->relro_end) >= link_info->relro_end))
break; break;
} }
@ -4823,6 +4822,12 @@ assign_file_positions_except_relocs (bfd *abfd,
if (!assign_file_positions_for_non_load_sections (abfd, link_info)) if (!assign_file_positions_for_non_load_sections (abfd, link_info))
return FALSE; 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. */ /* Write out the program headers. */
alloc = tdata->program_header_size / bed->s->sizeof_phdr; alloc = tdata->program_header_size / bed->s->sizeof_phdr;
if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0 if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0

View file

@ -4156,7 +4156,6 @@ elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
if (!info->relocatable) if (!info->relocatable)
{ {
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
asection *sec;
/* Force a PT_GNU_STACK segment to be created. */ /* Force a PT_GNU_STACK segment to be created. */
if (! elf_tdata (output_bfd)->stack_flags) if (! elf_tdata (output_bfd)->stack_flags)
@ -4182,64 +4181,51 @@ elf32_bfinfdpic_always_size_sections (bfd *output_bfd,
h->def_regular = 1; h->def_regular = 1;
h->type = STT_OBJECT; 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; return TRUE;
} }
static bfd_boolean static bfd_boolean
elf32_bfinfdpic_modify_segment_map (bfd *output_bfd, elf32_bfinfdpic_modify_program_headers (bfd *output_bfd,
struct bfd_link_info *info) struct bfd_link_info *info)
{ {
struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
struct elf_segment_map *m; struct elf_segment_map *m;
Elf_Internal_Phdr *p;
/* objcopy and strip preserve what's already there using /* objcopy and strip preserve what's already there using
elf32_bfinfdpic_copy_private_bfd_data (). */ elf32_bfinfdpic_copy_private_bfd_data (). */
if (! info) if (! info)
return TRUE; 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) if (m->p_type == PT_GNU_STACK)
break; break;
if (m) if (m)
{ {
asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
if (sec)
{
/* Obtain the pointer to the __stacksize symbol. */ /* Obtain the pointer to the __stacksize symbol. */
h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
FALSE, FALSE, FALSE); FALSE, FALSE, FALSE);
if (h)
{
while (h->root.type == bfd_link_hash_indirect while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning) || 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); BFD_ASSERT (h->root.type == bfd_link_hash_defined);
}
/* Set the section size from the symbol value. We /* Set the header p_memsz from the symbol value. We
intentionally ignore the symbol section. */ intentionally ignore the symbol section. */
if (h->root.type == bfd_link_hash_defined) if (h && h->root.type == bfd_link_hash_defined)
sec->size = h->root.u.def.value; p->p_memsz = h->root.u.def.value;
else else
sec->size = DEFAULT_STACK_SIZE; p->p_memsz = DEFAULT_STACK_SIZE;
/* Add the stack section to the PT_GNU_STACK segment, p->p_align = 8;
such that its size and alignment requirements make it
to the segment. */
if (m->count == 0)
{
m->sections[m->count] = sec;
m->count++;
}
}
} }
return TRUE; return TRUE;
@ -5594,9 +5580,9 @@ error_return:
#undef elf_backend_always_size_sections #undef elf_backend_always_size_sections
#define elf_backend_always_size_sections \ #define elf_backend_always_size_sections \
elf32_bfinfdpic_always_size_sections elf32_bfinfdpic_always_size_sections
#undef elf_backend_modify_segment_map #undef elf_backend_modify_program_headers
#define elf_backend_modify_segment_map \ #define elf_backend_modify_program_headers \
elf32_bfinfdpic_modify_segment_map elf32_bfinfdpic_modify_program_headers
#undef bfd_elf32_bfd_copy_private_bfd_data #undef bfd_elf32_bfd_copy_private_bfd_data
#define bfd_elf32_bfd_copy_private_bfd_data \ #define bfd_elf32_bfd_copy_private_bfd_data \
elf32_bfinfdpic_copy_private_bfd_data elf32_bfinfdpic_copy_private_bfd_data

View file

@ -5603,7 +5603,6 @@ elf32_frvfdpic_always_size_sections (bfd *output_bfd,
if (!info->relocatable) if (!info->relocatable)
{ {
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
asection *sec;
/* Force a PT_GNU_STACK segment to be created. */ /* Force a PT_GNU_STACK segment to be created. */
if (! elf_tdata (output_bfd)->stack_flags) if (! elf_tdata (output_bfd)->stack_flags)
@ -5630,13 +5629,6 @@ elf32_frvfdpic_always_size_sections (bfd *output_bfd,
h->type = STT_OBJECT; h->type = STT_OBJECT;
/* This one must NOT be hidden. */ /* 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; return TRUE;
@ -5718,51 +5710,45 @@ elf32_frvfdpic_relax_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
} }
static bfd_boolean static bfd_boolean
elf32_frvfdpic_modify_segment_map (bfd *output_bfd, elf32_frvfdpic_modify_program_headers (bfd *output_bfd,
struct bfd_link_info *info) struct bfd_link_info *info)
{ {
struct elf_obj_tdata *tdata = elf_tdata (output_bfd);
struct elf_segment_map *m; struct elf_segment_map *m;
Elf_Internal_Phdr *p;
/* objcopy and strip preserve what's already there using /* objcopy and strip preserve what's already there using
elf32_frvfdpic_copy_private_bfd_data (). */ elf32_frvfdpic_copy_private_bfd_data (). */
if (! info) if (! info)
return TRUE; 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) if (m->p_type == PT_GNU_STACK)
break; break;
if (m) if (m)
{ {
asection *sec = bfd_get_section_by_name (output_bfd, ".stack");
struct elf_link_hash_entry *h; struct elf_link_hash_entry *h;
if (sec)
{
/* Obtain the pointer to the __stacksize symbol. */ /* Obtain the pointer to the __stacksize symbol. */
h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize", h = elf_link_hash_lookup (elf_hash_table (info), "__stacksize",
FALSE, FALSE, FALSE); FALSE, FALSE, FALSE);
if (h)
{
while (h->root.type == bfd_link_hash_indirect while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning) || 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); BFD_ASSERT (h->root.type == bfd_link_hash_defined);
}
/* Set the section size from the symbol value. We /* Set the header p_memsz from the symbol value. We
intentionally ignore the symbol section. */ intentionally ignore the symbol section. */
if (h->root.type == bfd_link_hash_defined) if (h && h->root.type == bfd_link_hash_defined)
sec->size = h->root.u.def.value; p->p_memsz = h->root.u.def.value;
else else
sec->size = DEFAULT_STACK_SIZE; p->p_memsz = DEFAULT_STACK_SIZE;
/* Add the stack section to the PT_GNU_STACK segment, p->p_align = 8;
such that its size and alignment requirements make it
to the segment. */
if (m->count == 0)
{
m->sections[m->count] = sec;
m->count++;
}
}
} }
return TRUE; return TRUE;
@ -6973,9 +6959,9 @@ elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
#undef elf_backend_always_size_sections #undef elf_backend_always_size_sections
#define elf_backend_always_size_sections \ #define elf_backend_always_size_sections \
elf32_frvfdpic_always_size_sections elf32_frvfdpic_always_size_sections
#undef elf_backend_modify_segment_map #undef elf_backend_modify_program_headers
#define elf_backend_modify_segment_map \ #define elf_backend_modify_program_headers \
elf32_frvfdpic_modify_segment_map elf32_frvfdpic_modify_program_headers
#undef bfd_elf32_bfd_copy_private_bfd_data #undef bfd_elf32_bfd_copy_private_bfd_data
#define bfd_elf32_bfd_copy_private_bfd_data \ #define bfd_elf32_bfd_copy_private_bfd_data \
elf32_frvfdpic_copy_private_bfd_data elf32_frvfdpic_copy_private_bfd_data

View file

@ -1737,17 +1737,30 @@ elfNN_ia64_modify_segment_map (bfd *abfd,
} }
} }
return TRUE;
}
/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of /* 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 the input sections for each output section in the segment and testing
for SHF_IA_64_NORECOV on each. */ for SHF_IA_64_NORECOV on each. */
for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
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) if (m->p_type == PT_LOAD)
{ {
int i; int i;
for (i = m->count - 1; i >= 0; --i) for (i = m->count - 1; i >= 0; --i)
{ {
struct bfd_link_order *order = m->sections[i]->map_head.link_order; struct bfd_link_order *order = m->sections[i]->map_head.link_order;
while (order)
while (order != NULL)
{ {
if (order->type == bfd_indirect_link_order) 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; bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
if (flags & SHF_IA_64_NORECOV) if (flags & SHF_IA_64_NORECOV)
{ {
m->p_flags |= PF_IA_64_NORECOV; p->p_flags |= PF_IA_64_NORECOV;
goto found; goto found;
} }
} }
@ -5728,6 +5741,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
elfNN_ia64_additional_program_headers elfNN_ia64_additional_program_headers
#define elf_backend_modify_segment_map \ #define elf_backend_modify_segment_map \
elfNN_ia64_modify_segment_map elfNN_ia64_modify_segment_map
#define elf_backend_modify_program_headers \
elfNN_ia64_modify_program_headers
#define elf_info_to_howto \ #define elf_info_to_howto \
elfNN_ia64_info_to_howto elfNN_ia64_info_to_howto

View file

@ -402,6 +402,9 @@
#ifndef elf_backend_modify_segment_map #ifndef elf_backend_modify_segment_map
#define elf_backend_modify_segment_map 0 #define elf_backend_modify_segment_map 0
#endif #endif
#ifndef elf_backend_modify_program_headers
#define elf_backend_modify_program_headers 0
#endif
#ifndef elf_backend_ecoff_debug_swap #ifndef elf_backend_ecoff_debug_swap
#define elf_backend_ecoff_debug_swap 0 #define elf_backend_ecoff_debug_swap 0
#endif #endif
@ -603,6 +606,7 @@ static struct elf_backend_data elfNN_bed =
elf_backend_final_write_processing, elf_backend_final_write_processing,
elf_backend_additional_program_headers, elf_backend_additional_program_headers,
elf_backend_modify_segment_map, elf_backend_modify_segment_map,
elf_backend_modify_program_headers,
elf_backend_gc_mark_dynamic_ref, elf_backend_gc_mark_dynamic_ref,
elf_backend_gc_mark_hook, elf_backend_gc_mark_hook,
elf_backend_gc_sweep_hook, elf_backend_gc_sweep_hook,