2005-10-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1487
	* elf-bfd.h (_bfd_generic_init_private_section_data): New.
	(_bfd_elf_init_private_section_data): New.

	* elf.c (elf_fake_sections): Don't set SHF_GROUP for
	relocatable link.
	(bfd_elf_set_group_contents): Don't handle relocatable link
	specially.
	(assign_section_numbers): If it isn't called by assembler,
	use the output section of elf_linked_to_section for
	SHF_LINK_ORDER.
	(_bfd_elf_init_private_section_data): New.
	(_bfd_elf_copy_private_section_data): Call it.

	* libbfd-in.h (_bfd_generic_init_private_section_data): New.

	* libbfd.c (_bfd_generic_init_private_section_data): New.

	* targets.c (BFD_JUMP_TABLE_COPY): Add
	_bfd_generic_init_private_section_data.
	(bfd_init_private_section_data): Likewise.

	* bfd-in2.h: Regenerated.
	* libbfd.h: Likewise.

ld/

2005-10-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1487
	* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Call
	bfd_match_sections_by_type to match section types.

	* ldlang.c (init_os): Take the input section. Call
	bfd_init_private_section_data if the input section isn't NULL.
	(exp_init_os): Pass NULL to init_os.
	(map_input_to_output_sections): Likewise.
	(lang_add_section): Pass the input section to init_os.

ld/testsuite/

2005-10-23  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/1487
	* ld-ia64/tlspic.rd: Updated.
This commit is contained in:
H.J. Lu 2005-10-24 01:40:58 +00:00
parent 167cadb67e
commit ccd2ec6a87
13 changed files with 190 additions and 130 deletions

View File

@ -1,3 +1,30 @@
2005-10-23 H.J. Lu <hongjiu.lu@intel.com>
PR ld/1487
* elf-bfd.h (_bfd_generic_init_private_section_data): New.
(_bfd_elf_init_private_section_data): New.
* elf.c (elf_fake_sections): Don't set SHF_GROUP for
relocatable link.
(bfd_elf_set_group_contents): Don't handle relocatable link
specially.
(assign_section_numbers): If it isn't called by assembler,
use the output section of elf_linked_to_section for
SHF_LINK_ORDER.
(_bfd_elf_init_private_section_data): New.
(_bfd_elf_copy_private_section_data): Call it.
* libbfd-in.h (_bfd_generic_init_private_section_data): New.
* libbfd.c (_bfd_generic_init_private_section_data): New.
* targets.c (BFD_JUMP_TABLE_COPY): Add
_bfd_generic_init_private_section_data.
(bfd_init_private_section_data): Likewise.
* bfd-in2.h: Regenerated.
* libbfd.h: Likewise.
2005-10-23 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (dec_dynrel_count): Don't report errors for local

View File

@ -4770,6 +4770,7 @@ typedef struct bfd_target
#define BFD_JUMP_TABLE_COPY(NAME) \
NAME##_bfd_copy_private_bfd_data, \
NAME##_bfd_merge_private_bfd_data, \
_bfd_generic_init_private_section_data, \
NAME##_bfd_copy_private_section_data, \
NAME##_bfd_copy_private_symbol_data, \
NAME##_bfd_copy_private_header_data, \
@ -4782,6 +4783,12 @@ typedef struct bfd_target
/* Called to merge BFD general private data from one object file
to a common output file when linking. */
bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
/* Called to initialize BFD private section data from one object file
to another. */
#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
bfd_boolean (*_bfd_init_private_section_data)
(bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
/* Called to copy BFD private section data from one object file
to another. */
bfd_boolean (*_bfd_copy_private_section_data)

View File

@ -1492,6 +1492,10 @@ extern bfd_boolean _bfd_elf_copy_private_header_data
(bfd *, bfd *);
extern bfd_boolean _bfd_elf_copy_private_symbol_data
(bfd *, asymbol *, bfd *, asymbol *);
#define _bfd_generic_init_private_section_data \
_bfd_elf_init_private_section_data
extern bfd_boolean _bfd_elf_init_private_section_data
(bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
extern bfd_boolean _bfd_elf_copy_private_section_data
(bfd *, asection *, bfd *, asection *);
extern bfd_boolean _bfd_elf_write_object_contents

217
bfd/elf.c
View File

@ -2670,29 +2670,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
if (this_hdr->sh_type == SHT_NULL)
{
if ((asect->flags & SEC_GROUP) != 0)
{
/* We also need to mark SHF_GROUP here for relocatable
link. */
struct bfd_link_order *l;
asection *elt;
for (l = asect->map_head.link_order; l != NULL; l = l->next)
if (l->type == bfd_indirect_link_order
&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
do
{
/* The name is not important. Anything will do. */
elf_group_name (elt->output_section) = "G";
elf_section_flags (elt->output_section) |= SHF_GROUP;
elt = elf_next_in_group (elt);
/* During a relocatable link, the lists are
circular. */
}
while (elt != elf_next_in_group (l->u.indirect.section));
this_hdr->sh_type = SHT_GROUP;
}
this_hdr->sh_type = SHT_GROUP;
else if ((asect->flags & SEC_ALLOC) != 0
&& (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
|| (asect->flags & SEC_NEVER_LOAD) != 0))
@ -2827,7 +2805,6 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
unsigned long symindx;
asection *elt, *first;
unsigned char *loc;
struct bfd_link_order *l;
bfd_boolean gas;
/* Ignore linker created group section. See elfNN_ia64_object_p in
@ -2896,22 +2873,6 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
break;
}
/* If this is a relocatable link, then the above did nothing because
SEC is the output section. Look through the input sections
instead. */
for (l = sec->map_head.link_order; l != NULL; l = l->next)
if (l->type == bfd_indirect_link_order
&& (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
do
{
loc -= 4;
H_PUT_32 (abfd,
elf_section_data (elt->output_section)->this_idx, loc);
elt = elf_next_in_group (elt);
/* During a relocatable link, the lists are circular. */
}
while (elt != elf_next_in_group (l->u.indirect.section));
if ((loc -= 4) != sec->contents)
abort ();
@ -3091,67 +3052,46 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
{
s = elf_linked_to_section (sec);
if (s)
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
{
if (link_info != NULL)
{
/* For linker, elf_linked_to_section points to the
input section. */
if (elf_discarded_section (s))
{
asection *kept;
(*_bfd_error_handler)
(_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
abfd, d->this_hdr.bfd_section,
s, s->owner);
/* Point to the kept section if it has the same
size as the discarded one. */
kept = _bfd_elf_check_kept_section (s);
if (kept == NULL)
{
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
s = kept;
}
s = s->output_section;
BFD_ASSERT (s != NULL);
}
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
}
else
{
struct bfd_link_order *p;
/* Find out what the corresponding section in output
is. */
for (p = sec->map_head.link_order; p != NULL; p = p->next)
{
s = p->u.indirect.section;
if (p->type == bfd_indirect_link_order
&& (bfd_get_flavour (s->owner)
== bfd_target_elf_flavour))
{
Elf_Internal_Shdr ** const elf_shdrp
= elf_elfsections (s->owner);
int elfsec
= _bfd_elf_section_from_bfd_section (s->owner, s);
elfsec = elf_shdrp[elfsec]->sh_link;
/* PR 290:
The Intel C compiler generates SHT_IA_64_UNWIND with
SHF_LINK_ORDER. But it doesn't set the sh_link or
sh_info fields. Hence we could get the situation
where elfsec is 0. */
if (elfsec == 0)
{
const struct elf_backend_data *bed
= get_elf_backend_data (abfd);
if (bed->link_order_error_handler)
bed->link_order_error_handler
(_("%B: warning: sh_link not set for section `%A'"),
abfd, s);
}
else
{
s = elf_shdrp[elfsec]->bfd_section;
if (elf_discarded_section (s))
{
asection *kept;
(*_bfd_error_handler)
(_("%B: sh_link of section `%A' points to discarded section `%A' of `%B'"),
abfd, d->this_hdr.bfd_section,
s, s->owner);
/* Point to the kept section if it has
the same size as the discarded
one. */
kept = _bfd_elf_check_kept_section (s);
if (kept == NULL)
{
bfd_set_error (bfd_error_bad_value);
return FALSE;
}
s = kept;
}
s = s->output_section;
BFD_ASSERT (s != NULL);
d->this_hdr.sh_link = elf_section_data (s)->this_idx;
}
break;
}
}
/* PR 290:
The Intel C compiler generates SHT_IA_64_UNWIND with
SHF_LINK_ORDER. But it doesn't set the sh_link or
sh_info fields. Hence we could get the situation
where s is NULL. */
const struct elf_backend_data *bed
= get_elf_backend_data (abfd);
if (bed->link_order_error_handler)
bed->link_order_error_handler
(_("%B: warning: sh_link not set for section `%A'"),
abfd, sec);
}
}
@ -5665,6 +5605,62 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
return TRUE;
}
/* Initialize private output section information from input section. */
bfd_boolean
_bfd_elf_init_private_section_data (bfd *ibfd,
asection *isec,
bfd *obfd,
asection *osec,
struct bfd_link_info *link_info)
{
Elf_Internal_Shdr *ihdr, *ohdr;
bfd_boolean need_group = link_info == NULL || link_info->relocatable;
if (ibfd->xvec->flavour != bfd_target_elf_flavour
|| obfd->xvec->flavour != bfd_target_elf_flavour)
return TRUE;
/* FIXME: What if the output ELF section type has been set to
something different? */
if (elf_section_type (osec) == SHT_NULL)
elf_section_type (osec) = elf_section_type (isec);
/* Set things up for objcopy and relocatable link. The output
SHT_GROUP section will have its elf_next_in_group pointing back
to the input group members. Ignore linker created group section.
See elfNN_ia64_object_p in elfxx-ia64.c. */
if (need_group)
{
if (elf_sec_group (isec) == NULL
|| (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
{
if (elf_section_flags (isec) & SHF_GROUP)
elf_section_flags (osec) |= SHF_GROUP;
elf_next_in_group (osec) = elf_next_in_group (isec);
elf_group_name (osec) = elf_group_name (isec);
}
}
ihdr = &elf_section_data (isec)->this_hdr;
/* We need to handle elf_linked_to_section for SHF_LINK_ORDER. We
don't use the output section of the linked-to section since it
may be NULL at this point. */
if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0)
{
ohdr = &elf_section_data (osec)->this_hdr;
ohdr->sh_flags |= SHF_LINK_ORDER;
elf_linked_to_section (osec) = elf_linked_to_section (isec);
}
osec->use_rela_p = isec->use_rela_p;
return TRUE;
}
/* Copy private section information. This copies over the entsize
field, and sometimes the info field. */
@ -5691,27 +5687,8 @@ _bfd_elf_copy_private_section_data (bfd *ibfd,
|| ihdr->sh_type == SHT_GNU_verdef)
ohdr->sh_info = ihdr->sh_info;
/* Set things up for objcopy. The output SHT_GROUP section will
have its elf_next_in_group pointing back to the input group
members. Ignore linker created group section. See
elfNN_ia64_object_p in elfxx-ia64.c. We also need to handle
elf_linked_to_section for SHF_LINK_ORDER. */
if ((ihdr->sh_flags & SHF_LINK_ORDER) != 0
&& elf_linked_to_section (isec) != 0)
elf_linked_to_section (osec)
= elf_linked_to_section (isec)->output_section;
if (elf_sec_group (isec) == NULL
|| (elf_sec_group (isec)->flags & SEC_LINKER_CREATED) == 0)
{
elf_next_in_group (osec) = elf_next_in_group (isec);
elf_group_name (osec) = elf_group_name (isec);
}
osec->use_rela_p = isec->use_rela_p;
return TRUE;
return _bfd_elf_init_private_section_data (ibfd, isec, obfd, osec,
NULL);
}
/* Copy private header information. */

View File

@ -234,6 +234,9 @@ extern bfd_boolean _bfd_generic_get_section_contents_in_window
#define _bfd_generic_bfd_print_private_bfd_data \
((bfd_boolean (*) (bfd *, void *)) bfd_true)
extern bfd_boolean _bfd_generic_init_private_section_data
(bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */

View File

@ -1042,3 +1042,13 @@ _bfd_generic_match_sections_by_type (bfd *abfd ATTRIBUTE_UNUSED,
{
return TRUE;
}
bfd_boolean
_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
asection *isec ATTRIBUTE_UNUSED,
bfd *obfd ATTRIBUTE_UNUSED,
asection *osec ATTRIBUTE_UNUSED,
struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
{
return TRUE;
}

View File

@ -239,6 +239,9 @@ extern bfd_boolean _bfd_generic_get_section_contents_in_window
#define _bfd_generic_bfd_print_private_bfd_data \
((bfd_boolean (*) (bfd *, void *)) bfd_true)
extern bfd_boolean _bfd_generic_init_private_section_data
(bfd *, asection *, bfd *, asection *, struct bfd_link_info *);
/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */

View File

@ -271,6 +271,7 @@ BFD_JUMP_TABLE macros.
.#define BFD_JUMP_TABLE_COPY(NAME) \
. NAME##_bfd_copy_private_bfd_data, \
. NAME##_bfd_merge_private_bfd_data, \
. _bfd_generic_init_private_section_data, \
. NAME##_bfd_copy_private_section_data, \
. NAME##_bfd_copy_private_symbol_data, \
. NAME##_bfd_copy_private_header_data, \
@ -283,6 +284,12 @@ BFD_JUMP_TABLE macros.
. {* Called to merge BFD general private data from one object file
. to a common output file when linking. *}
. bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *);
. {* Called to initialize BFD private section data from one object file
. to another. *}
.#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \
. BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info))
. bfd_boolean (*_bfd_init_private_section_data)
. (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *);
. {* Called to copy BFD private section data from one object file
. to another. *}
. bfd_boolean (*_bfd_copy_private_section_data)

View File

@ -1,3 +1,15 @@
2005-10-23 H.J. Lu <hongjiu.lu@intel.com>
PR ld/1487
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Call
bfd_match_sections_by_type to match section types.
* ldlang.c (init_os): Take the input section. Call
bfd_init_private_section_data if the input section isn't NULL.
(exp_init_os): Pass NULL to init_os.
(map_input_to_output_sections): Likewise.
(lang_add_section): Pass the input section to init_os.
2005-10-19 Paul Brook <paul@codesourcery.com>
* emulparams/armelf.sh: Add .ARM.attributes to OTHER_SECTIONS.

View File

@ -1363,8 +1363,9 @@ gld${EMULATION_NAME}_place_orphan (lang_input_statement_type *file, asection *s)
if (os != NULL
&& (os->bfd_section == NULL
|| os->bfd_section->flags == 0
|| ((!iself
|| sh_type == elf_section_type (os->bfd_section))
|| (bfd_match_sections_by_type (output_bfd,
os->bfd_section,
s->owner, s)
&& ((s->flags ^ os->bfd_section->flags)
& (SEC_LOAD | SEC_ALLOC)) == 0)))
{

View File

@ -1674,7 +1674,7 @@ sort_def_symbol (hash_entry, info)
/* Initialize an output section. */
static void
init_os (lang_output_section_statement_type *s)
init_os (lang_output_section_statement_type *s, asection *isec)
{
if (s->bfd_section != NULL)
return;
@ -1711,6 +1711,11 @@ init_os (lang_output_section_statement_type *s)
if (s->load_base != NULL)
exp_init_os (s->load_base);
if (isec)
bfd_init_private_section_data (isec->owner, isec,
output_bfd, s->bfd_section,
&link_info);
}
/* Make sure that all output sections mentioned in an expression are
@ -1756,7 +1761,7 @@ exp_init_os (etree_type *exp)
os = lang_output_section_find (exp->name.name);
if (os != NULL && os->bfd_section == NULL)
init_os (os);
init_os (os, NULL);
}
}
break;
@ -1833,7 +1838,7 @@ lang_add_section (lang_statement_list_type *ptr,
flagword flags;
if (output->bfd_section == NULL)
init_os (output);
init_os (output, section);
first = ! output->bfd_section->linker_has_input;
output->bfd_section->linker_has_input = 1;
@ -3099,7 +3104,7 @@ map_input_to_output_sections
are initialized. */
exp_init_os (s->data_statement.exp);
if (os != NULL && os->bfd_section == NULL)
init_os (os);
init_os (os, NULL);
/* The output section gets contents, and then we inspect for
any flags set in the input script which override any ALLOC. */
os->bfd_section->flags |= SEC_HAS_CONTENTS;
@ -3113,11 +3118,11 @@ map_input_to_output_sections
case lang_padding_statement_enum:
case lang_input_statement_enum:
if (os != NULL && os->bfd_section == NULL)
init_os (os);
init_os (os, NULL);
break;
case lang_assignment_statement_enum:
if (os != NULL && os->bfd_section == NULL)
init_os (os);
init_os (os, NULL);
/* Make sure that any sections mentioned in the assignment
are initialized. */
@ -3145,7 +3150,7 @@ map_input_to_output_sections
(s->address_statement.section_name));
if (aos->bfd_section == NULL)
init_os (aos);
init_os (aos, NULL);
aos->addr_tree = s->address_statement.address;
}
break;

View File

@ -1,3 +1,8 @@
2005-10-23 H.J. Lu <hongjiu.lu@intel.com>
PR ld/1487
* ld-ia64/tlspic.rd: Updated.
2005-10-21 H.J. Lu <hongjiu.lu@intel.com>
PR ld/1467

View File

@ -61,7 +61,6 @@ Symbol table '.dynsym' contains [0-9]+ entries:
.* NOTYPE +LOCAL +DEFAULT +UND *
.* SECTION LOCAL +DEFAULT +7 *
.* SECTION LOCAL +DEFAULT +8 *
.* SECTION LOCAL +DEFAULT +9 *
.* SECTION LOCAL +DEFAULT +10 *
.* SECTION LOCAL +DEFAULT +11 *
.* SECTION LOCAL +DEFAULT +14 *