aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog27
-rw-r--r--bfd/bfd-in2.h7
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elf.c207
-rw-r--r--bfd/libbfd-in.h3
-rw-r--r--bfd/libbfd.c10
-rw-r--r--bfd/libbfd.h3
-rw-r--r--bfd/targets.c7
8 files changed, 153 insertions, 115 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 118c82d..d69e998 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1d93b0f..6cf7e3c 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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)
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index d011a45..90cd4ca 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -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
diff --git a/bfd/elf.c b/bfd/elf.c
index 3a139a0..b7f38be 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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;
- 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);
}
}
@@ -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. */
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 0290c84..1b1789a 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -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). */
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 3b27e08..34e32ac 100644
--- a/bfd/libbfd.c
+++ b/bfd/libbfd.c
@@ -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;
+}
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 56ad092..9125663 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -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). */
diff --git a/bfd/targets.c b/bfd/targets.c
index 271954f..7844971 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -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)