This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] bfd/ld bug when using linker plugins and dynobj is dynamic
- From: Kwok Cheung Yeung <kcy at codesourcery dot com>
- To: Alan Modra <amodra at gmail dot com>
- Cc: <binutils at sourceware dot org>
- Date: Wed, 5 Jun 2013 16:49:02 +0100
- Subject: Re: [PATCH] bfd/ld bug when using linker plugins and dynobj is dynamic
- References: <51A949C1 dot 1090003 at codesourcery dot com> <20130601035037 dot GO6878 at bubble dot grove dot modra dot org>
On 01/06/2013 4:50 AM, Alan Modra wrote:
On Sat, Jun 01, 2013 at 02:09:21AM +0100, Kwok Cheung Yeung wrote:
* elf-bfd.h (struct elf_obj_tdata): Add new field.
(elf_dynamic): New macro.
* elf.c (bfd_section_from_shdr): Set elf_dynamic when a dynamic section
is encountered.
* elflink.c (elf_link_add_object_symbols): Lookup BFD and ELF sections
corresponding to dynamic section using elf_dynamic rather than by
name. Do not clear section list if the current BFD is used to store
linker-generated sections.
OK. Thanks for taking the time to write a clear description of
exactly what was going wrong. That makes reviewing easy.
Can I interest you in a followup patch? There are a number of places
in the code that call
bfd_get_section_by_name (abfd, ".dynamic").
Those that are reading input .dynamic sections ought to be converted
to use elf_dynamic. eg. bfd_elf_get_bfd_needed_list.
Apart from bfd_elf_get_bfd_needed_list, the only other place which uses the:
s = bfd_get_section_by_name (abfd, ".dynamic");
elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
shlink = elf_elfsections (abfd)[elfsec]->sh_link;
construct (and is therefore susceptible to the same failure mode) is in
_bfd_elf_print_private_bfd_data. The other places where .dynamic is looked up by
name look like they should work with the linker-generated .dynamic section.
The following patch replaces these two instances with lookups via elf_dynamic.
Kwok Cheung Yeung
2013-06-05 Kwok Cheung Yeung <kcy@codesourcery.com>
bfd/
* elf.c (_bfd_elf_print_private_bfd_data): Lookup BFD and ELF
sections for the input .dynamic section with elf_dynamic.
* elflink.c (bfd_elf_get_bfd_needed_list): Likewise.
diff -rup bfd.old/elf.c bfd/elf.c
--- bfd.old/elf.c 2013-06-05 15:40:21.585835259 +0100
+++ bfd/elf.c 2013-06-05 15:55:54.399014825 +0100
@@ -1200,10 +1200,9 @@ _bfd_elf_print_private_bfd_data (bfd *ab
}
}
- s = bfd_get_section_by_name (abfd, ".dynamic");
+ s = bfd_section_from_elf_index (abfd, elf_dynamic (abfd));
if (s != NULL)
{
- unsigned int elfsec;
unsigned long shlink;
bfd_byte *extdyn, *extdynend;
size_t extdynsize;
@@ -1214,10 +1213,7 @@ _bfd_elf_print_private_bfd_data (bfd *ab
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
goto error_return;
- elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
- if (elfsec == SHN_BAD)
- goto error_return;
- shlink = elf_elfsections (abfd)[elfsec]->sh_link;
+ shlink = elf_elfsections (abfd)[elf_dynamic (abfd)]->sh_link;
extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
diff -rup bfd.old/elflink.c bfd/elflink.c
--- bfd.old/elflink.c 2013-06-05 15:40:16.982731130 +0100
+++ bfd/elflink.c 2013-06-05 15:55:54.489193101 +0100
@@ -6986,7 +6986,6 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
{
asection *s;
bfd_byte *dynbuf = NULL;
- unsigned int elfsec;
unsigned long shlink;
bfd_byte *extdyn, *extdynend;
size_t extdynsize;
@@ -6998,18 +6997,14 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
|| bfd_get_format (abfd) != bfd_object)
return TRUE;
- s = bfd_get_section_by_name (abfd, ".dynamic");
+ s = bfd_section_from_elf_index (abfd, elf_dynamic (abfd));
if (s == NULL || s->size == 0)
return TRUE;
if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
goto error_return;
- elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
- if (elfsec == SHN_BAD)
- goto error_return;
-
- shlink = elf_elfsections (abfd)[elfsec]->sh_link;
+ shlink = elf_elfsections (abfd)[elf_dynamic (abfd)]->sh_link;
extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;