From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22759 invoked by alias); 5 May 2011 05:19:05 -0000 Received: (qmail 22749 invoked by uid 22791); 5 May 2011 05:19:02 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_00,NO_DNS_FOR_FROM,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 05 May 2011 05:18:48 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 04 May 2011 22:18:33 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by orsmga001.jf.intel.com with ESMTP; 04 May 2011 22:18:33 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id C1FA8180997; Wed, 4 May 2011 22:18:32 -0700 (PDT) Date: Thu, 05 May 2011 05:19:00 -0000 From: "H.J. Lu" To: binutils@sourceware.org Subject: PATCH: PR ld/12730: regression] crash when allocating in a static constructor Message-ID: <20110505051832.GA28229@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2011-05/txt/msg00060.txt.bz2 Hi, When we put .ctors into .init_array, we have to reverse copy .ctors secton. Otherwise, constructor function may not work with C++ run-time library correctly. OK for trunk? Thanks. H.J. --- bfd/ 2011-05-04 H.J. Lu PR ld/12730 * elflink.c (elf_link_input_bfd): Reverse copy .ctors section if needed. include/ 2011-05-04 H.J. Lu PR ld/12730 * bfdlink.h (bfd_link_info): Add reverse_copy_ctors. ld/ 2011-05-04 H.J. Lu PR ld/12730 * emultempl/elf32.em (gld${EMULATION_NAME}_after_parse): New. (ld_${EMULATION_NAME}_emulation): Replace after_parse_default with gld${EMULATION_NAME}_after_parse. ld/testsuite/ 2011-05-04 H.J. Lu PR ld/12730 * ld-elf/elf.exp (array_tests): Add pr12730". (array_tests_static): Add "static pr12730". * ld-elf/pr12730.cc: New. * ld-elf/pr12730.out: Likewise. diff --git a/bfd/elflink.c b/bfd/elflink.c index 082355d..41aa16a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -9876,12 +9876,46 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) default: { /* FIXME: octets_per_byte. */ - if (! (o->flags & SEC_EXCLUDE) - && ! bfd_set_section_contents (output_bfd, o->output_section, - contents, - (file_ptr) o->output_offset, - o->size)) - return FALSE; + if (! (o->flags & SEC_EXCLUDE)) + { + bfd_size_type address_size = bed->s->arch_size / 8; + file_ptr offset = (file_ptr) o->output_offset; + bfd_size_type todo = o->size; + if (finfo->info->reverse_copy_ctors + && todo > address_size + && strcmp (o->name, ".ctors") == 0) + { + if ((o->size % address_size) != 0) + { + (*_bfd_error_handler) + (_("error: %B: size of section %A is not " + "multiple of address size"), + input_bfd, o); + bfd_set_error (bfd_error_on_input); + return FALSE; + } + + do + { + todo -= address_size; + if (! bfd_set_section_contents (output_bfd, + o->output_section, + contents + todo, + offset, + address_size)) + return FALSE; + if (todo == 0) + break; + offset += address_size; + } + while (1); + } + else if (! bfd_set_section_contents (output_bfd, + o->output_section, + contents, + offset, todo)) + return FALSE; + } } break; } diff --git a/include/bfdlink.h b/include/bfdlink.h index 50a1423..0139751 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -354,6 +354,9 @@ struct bfd_link_info --dynamic-list command line options. */ unsigned int dynamic: 1; + /* TRUE if BFD should reverse-copy .ctors section. */ + unsigned int reverse_copy_ctors: 1; + /* Non-NULL if .note.gnu.build-id section should be created. */ char *emit_note_gnu_build_id; diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 17fb8bf..562cda4 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -63,6 +63,7 @@ fragment < + +class Hello +{ +public: + Hello () + {} + + ~Hello () + {} + + void act () + { std::cout << "Hello, world!" << std::endl; } +}; + + +template +struct Foo +{ + T* _M_allocate_single_object () + { + return new T; + } +}; + +static void __attribute__ (( constructor )) PWLIB_StaticLoader() { + Foo allocator; + Hello* salut = allocator._M_allocate_single_object (); + salut->act (); +} + + +int +main (int /*argc*/, + char* /*argv*/[]) +{ + return 0; +} diff --git a/ld/testsuite/ld-elf/pr12730.out b/ld/testsuite/ld-elf/pr12730.out new file mode 100644 index 0000000..af5626b --- /dev/null +++ b/ld/testsuite/ld-elf/pr12730.out @@ -0,0 +1 @@ +Hello, world!