From deddc40bec6db30c02fa73f1e83619bc62c87196 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 8 Feb 2010 07:09:39 +0000 Subject: [PATCH] bfd/ * 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 | 6 +++ bfd/elf32-arm.c | 3 +- bfd/elf32-ppc.c | 95 ++++++++++++----------------------- ld/testsuite/ChangeLog | 16 ++++-- ld/testsuite/ld-powerpc/apuinfo-nul.s | 10 ++++ ld/testsuite/ld-powerpc/apuinfo.rd | 1 + ld/testsuite/ld-powerpc/powerpc.exp | 2 +- 7 files changed, 63 insertions(+), 70 deletions(-) create mode 100644 ld/testsuite/ld-powerpc/apuinfo-nul.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0dcad6c..f9ca746 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2010-02-08 Nathan Sidwell + + * 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 * archures.c (bfd_mach_ppc_titan): Define. diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 470e495..8f8d32c 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -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; } } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index c9f22bb..e7a310c 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -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); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index e3d20bf..e7c7f64 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,10 +1,16 @@ +2010-02-08 Nathan Sidwell + + * ld-powerpc/apuinfo-nul.s: New. + * ld-powerpc/apuinfo.rd: Add it. + * ld-powerpc/powerpc.exp: Likewise. + 2010-02-01 Matthew Gretton-Dann - * 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 diff --git a/ld/testsuite/ld-powerpc/apuinfo-nul.s b/ld/testsuite/ld-powerpc/apuinfo-nul.s new file mode 100644 index 0000000..6b17142 --- /dev/null +++ b/ld/testsuite/ld-powerpc/apuinfo-nul.s @@ -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" diff --git a/ld/testsuite/ld-powerpc/apuinfo.rd b/ld/testsuite/ld-powerpc/apuinfo.rd index e6321cd..7a27bc0 100644 --- a/ld/testsuite/ld-powerpc/apuinfo.rd +++ b/ld/testsuite/ld-powerpc/apuinfo.rd @@ -1,5 +1,6 @@ #source: apuinfo1.s #source: apuinfo2.s +#source: apuinfo-nul.s #as: -me500 #readelf: -x2 #target: powerpc-eabi* diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index fce9664..4c0038a 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -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} -- 2.7.4