+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
#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, \
/* 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)
(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
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))
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
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 ();
{
s = elf_linked_to_section (sec);
if (s)
- 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)
+ if (link_info != NULL)
{
- s = p->u.indirect.section;
- if (p->type == bfd_indirect_link_order
- && (bfd_get_flavour (s->owner)
- == bfd_target_elf_flavour))
+ /* For linker, elf_linked_to_section points to the
+ input section. */
+ if (elf_discarded_section (s))
{
- 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
+ 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)
{
- 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;
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
}
- break;
+ s = kept;
}
+ s = s->output_section;
+ BFD_ASSERT (s != NULL);
}
+ d->this_hdr.sh_link = elf_section_data (s)->this_idx;
+ }
+ else
+ {
+ /* 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);
}
}
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. */
|| 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. */
#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). */
{
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;
+}
#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). */
.#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, \
. {* 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)
+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.
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)))
{
/* 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;
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
os = lang_output_section_find (exp->name.name);
if (os != NULL && os->bfd_section == NULL)
- init_os (os);
+ init_os (os, NULL);
}
}
break;
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;
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;
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. */
(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;
+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
.* 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 *