bfd/
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 8 Feb 2010 07:09:39 +0000 (07:09 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Mon, 8 Feb 2010 07:09:39 +0000 (07:09 +0000)
* elf32-ppc.c (ppc_elf_begin_write_processing): Allow empty
apuinfo sections, only scan input sections once and reuse the
buffer.
ld/testsuite/
* ld-powerpc/apuinfo-nul.s: New.
* ld-powerpc/apuinfo.rd: Add it.
* ld-powerpc/powerpc.exp: Likewise.

bfd/ChangeLog
bfd/elf32-arm.c
bfd/elf32-ppc.c
ld/testsuite/ChangeLog
ld/testsuite/ld-powerpc/apuinfo-nul.s [new file with mode: 0644]
ld/testsuite/ld-powerpc/apuinfo.rd
ld/testsuite/ld-powerpc/powerpc.exp

index 0dcad6c..f9ca746 100644 (file)
@@ -1,3 +1,9 @@
+2010-02-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * elf32-ppc.c (ppc_elf_begin_write_processing): Allow empty
+       apuinfo sections, only scan input sections once and reuse the
+       buffer.
+
 2010-02-08  Philipp Tomsich  <philipp.tomsich@theobroma-systems.com>
 
        * archures.c (bfd_mach_ppc_titan): Define.
index 470e495..8f8d32c 100644 (file)
@@ -9831,7 +9831,8 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
        {
          _bfd_error_handler
            (_("error: %B uses VFP register arguments, %B does not"),
-            ibfd, obfd);
+            in_attr[Tag_ABI_VFP_args].i ? ibfd : obfd,
+            in_attr[Tag_ABI_VFP_args].i ? obfd : ibfd);
          result = FALSE;
        }
     }
index c9f22bb..e7a310c 100644 (file)
@@ -2159,123 +2159,92 @@ ppc_elf_begin_write_processing (bfd *abfd, struct bfd_link_info *link_info)
 {
   bfd *ibfd;
   asection *asec;
-  char *buffer;
-  unsigned num_input_sections;
-  bfd_size_type        output_section_size;
+  char *buffer = NULL;
+  bfd_size_type largest_input_size = 0;
   unsigned i;
   unsigned num_entries;
-  unsigned long        offset;
   unsigned long length;
   const char *error_message = NULL;
 
   if (link_info == NULL)
     return;
 
-  /* Scan the input bfds, looking for apuinfo sections.  */
-  num_input_sections = 0;
-  output_section_size = 0;
-
-  for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
-    {
-      asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
-      if (asec)
-       {
-         ++ num_input_sections;
-         output_section_size += asec->size;
-       }
-    }
-
-  /* We need at least one input sections
-     in order to make merging worthwhile.  */
-  if (num_input_sections < 1)
-    return;
-
-  /* Just make sure that the output section exists as well.  */
-  asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
-  if (asec == NULL)
-    return;
-
-  /* Allocate a buffer for the contents of the input sections.  */
-  buffer = bfd_malloc (output_section_size);
-  if (buffer == NULL)
-    return;
-
-  offset = 0;
   apuinfo_list_init ();
 
   /* Read in the input sections contents.  */
   for (ibfd = link_info->input_bfds; ibfd; ibfd = ibfd->link_next)
     {
       unsigned long datum;
-      char *ptr;
 
       asec = bfd_get_section_by_name (ibfd, APUINFO_SECTION_NAME);
       if (asec == NULL)
        continue;
 
+      error_message = _("corrupt %s section in %B");
       length = asec->size;
-      if (length < 24)
+      if (length < 20)
+       goto fail;
+
+      if (largest_input_size < asec->size)
        {
-         error_message = _("corrupt or empty %s section in %B");
-         goto fail;
+         if (buffer)
+           free (buffer);
+         largest_input_size = asec->size;
+         buffer = bfd_malloc (largest_input_size);
+         if (!buffer)
+           return;
        }
-
+      
       if (bfd_seek (ibfd, asec->filepos, SEEK_SET) != 0
-         || (bfd_bread (buffer + offset, length, ibfd) != length))
+         || (bfd_bread (buffer, length, ibfd) != length))
        {
          error_message = _("unable to read in %s section from %B");
          goto fail;
        }
 
-      /* Process the contents of the section.  */
-      ptr = buffer + offset;
-      error_message = _("corrupt %s section in %B");
-
       /* Verify the contents of the header.  Note - we have to
         extract the values this way in order to allow for a
         host whose endian-ness is different from the target.  */
-      datum = bfd_get_32 (ibfd, ptr);
+      datum = bfd_get_32 (ibfd, buffer);
       if (datum != sizeof APUINFO_LABEL)
        goto fail;
 
-      datum = bfd_get_32 (ibfd, ptr + 8);
+      datum = bfd_get_32 (ibfd, buffer + 8);
       if (datum != 0x2)
        goto fail;
 
-      if (strcmp (ptr + 12, APUINFO_LABEL) != 0)
+      if (strcmp (buffer + 12, APUINFO_LABEL) != 0)
        goto fail;
 
       /* Get the number of bytes used for apuinfo entries.  */
-      datum = bfd_get_32 (ibfd, ptr + 4);
+      datum = bfd_get_32 (ibfd, buffer + 4);
       if (datum + 20 != length)
        goto fail;
 
-      /* Make sure that we do not run off the end of the section.  */
-      if (offset + length > output_section_size)
-       goto fail;
-
       /* Scan the apuinfo section, building a list of apuinfo numbers.  */
       for (i = 0; i < datum; i += 4)
-       apuinfo_list_add (bfd_get_32 (ibfd, ptr + 20 + i));
-
-      /* Update the offset.  */
-      offset += length;
+       apuinfo_list_add (bfd_get_32 (ibfd, buffer + 20 + i));
     }
 
   error_message = NULL;
 
   /* Compute the size of the output section.  */
   num_entries = apuinfo_list_length ();
-  output_section_size = 20 + num_entries * 4;
-
-  asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
 
-  if (! bfd_set_section_size (abfd, asec, output_section_size))
-    ibfd = abfd,
-      error_message = _("warning: unable to set size of %s section in %B");
+  if (num_entries)
+    {
+      /* Set the output section size, if it exists.  */
+      asec = bfd_get_section_by_name (abfd, APUINFO_SECTION_NAME);
+      if (asec && ! bfd_set_section_size (abfd, asec, 20 + num_entries * 4))
+       {
+         ibfd = abfd;
+         error_message = _("warning: unable to set size of %s section in %B");
+       }
+    }
 
  fail:
-  free (buffer);
+  if (buffer)
+    free (buffer);
 
   if (error_message)
     (*_bfd_error_handler) (error_message, ibfd, APUINFO_SECTION_NAME);
index e3d20bf..e7c7f64 100644 (file)
@@ -1,10 +1,16 @@
+2010-02-08  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * ld-powerpc/apuinfo-nul.s: New.
+       * ld-powerpc/apuinfo.rd: Add it.
+       * ld-powerpc/powerpc.exp: Likewise.
+
 2010-02-01  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
-        * ld-arm/jump-reloc-veneers-long.d: New test.
-        * ld-arm/jump-reloc-veneers-short1.d: Likewise.
-        * ld-arm/jump-reloc-veneers-short2.d: Likewise.
-        * ld-arm/jump-reloc-veneers.s: Likewise.
-        * ld-arm/arm-elf.exp (armelftests): Run them.
+       * ld-arm/jump-reloc-veneers-long.d: New test.
+       * ld-arm/jump-reloc-veneers-short1.d: Likewise.
+       * ld-arm/jump-reloc-veneers-short2.d: Likewise.
+       * ld-arm/jump-reloc-veneers.s: Likewise.
+       * ld-arm/arm-elf.exp (armelftests): Run them.
 
 2010-01-28  Nick Clifton  <nickc@redhat.com>
 
diff --git a/ld/testsuite/ld-powerpc/apuinfo-nul.s b/ld/testsuite/ld-powerpc/apuinfo-nul.s
new file mode 100644 (file)
index 0000000..6b17142
--- /dev/null
@@ -0,0 +1,10 @@
+       .text
+       nop
+
+       # dummy empty apuinfo
+       # some other tools emit these
+       .section ".PPC.EMB.apuinfo"
+       .long 8
+       .long 0
+       .long 2
+       .asciz "APUinfo"
index e6321cd..7a27bc0 100644 (file)
@@ -1,5 +1,6 @@
 #source: apuinfo1.s
 #source: apuinfo2.s
+#source: apuinfo-nul.s
 #as: -me500
 #readelf: -x2
 #target: powerpc-eabi*
index fce9664..4c0038a 100644 (file)
@@ -101,7 +101,7 @@ set ppcelftests {
     {"Reloc section order" "-melf32ppc -shared -z nocombreloc" "-a32" {reloc.s}
      {{objdump -hw reloc.d}} "reloc.so"}
     {"APUinfo section processing" "-melf32ppc"
-     "-a32 -me500" {apuinfo1.s apuinfo2.s}
+     "-a32 -me500" {apuinfo1.s apuinfo-nul.s apuinfo2.s}
     {{readelf -x2 apuinfo.rd}} "apuinfo"}
     {"TLS32 static exec" "-melf32ppc" "-a32"  {tls32.s tlslib32.s}
      {{objdump -dr tls32.d} {objdump -sj.got tls32.g}