[PATCH] bfd/ld bug when using linker plugins and dynobj is dynamic

Kwok Cheung Yeung kcy@codesourcery.com
Wed Jun 5 15:49:00 GMT 2013


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;



More information about the Binutils mailing list