From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28369 invoked by alias); 11 Apr 2011 04:08:39 -0000 Received: (qmail 27554 invoked by uid 22791); 11 Apr 2011 04:08:36 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_FX,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-iw0-f169.google.com (HELO mail-iw0-f169.google.com) (209.85.214.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Apr 2011 04:08:32 +0000 Received: by iwg8 with SMTP id 8so7051882iwg.0 for ; Sun, 10 Apr 2011 21:08:31 -0700 (PDT) Received: by 10.43.54.135 with SMTP id vu7mr7044328icb.68.1302494911624; Sun, 10 Apr 2011 21:08:31 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id t1sm2877901ibm.55.2011.04.10.21.08.29 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 10 Apr 2011 21:08:31 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 1887616DE62A; Mon, 11 Apr 2011 13:38:25 +0930 (CST) Date: Mon, 11 Apr 2011 04:08:00 -0000 From: Alan Modra To: binutils@sourceware.org Subject: rawsize and output sections Message-ID: <20110411040824.GA710@bubble.grove.modra.org> Mail-Followup-To: binutils@sourceware.org References: <20110407010943.GW19002@bubble.grove.modra.org> <20110407085238.GZ19002@bubble.grove.modra.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110407085238.GZ19002@bubble.grove.modra.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes 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-04/txt/msg00150.txt.bz2 On Thu, Apr 07, 2011 at 06:22:38PM +0930, Alan Modra wrote: > rawsize on an output section, if non-zero, is > just a stale size at bfd_final_link. > > Hmm. Which means bfd_get_section_contents is wrong to look at rawsize > on output sections. Seems I have some bugs to fix. Committed. * bfd-in.h (bfd_get_section_limit): Don't use rawsize with output sections. * libbfd.c (_bfd_generic_get_section_contents): Likewise. (_bfd_generic_get_section_contents_in_window): Likewise. * section.c (bfd_get_section_contents): Likewise. * compress.c (bfd_get_full_section_contents): Likewise. * elf32-rx.c (rx_final_link): Ignore rawsize. * elf32-microblaze.c (microblaze_elf_relocate_section): Use correct bfd with bfd_get_section_limit. * elfxx-ia64.c (elfNN_ia64_choose_gp): Add "final" parameter. Use os->size during final link. Update callers. * bfd-in2.h: Regenerate. Index: bfd/bfd-in.h =================================================================== RCS file: /cvs/src/src/bfd/bfd-in.h,v retrieving revision 1.152 diff -u -p -r1.152 bfd-in.h --- bfd/bfd-in.h 8 Nov 2010 02:48:54 -0000 1.152 +++ bfd/bfd-in.h 10 Apr 2011 07:00:24 -0000 @@ -291,8 +291,8 @@ typedef struct bfd_section *sec_ptr; #define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) /* Find the address one past the end of SEC. */ #define bfd_get_section_limit(bfd, sec) \ - (((sec)->rawsize ? (sec)->rawsize : (sec)->size) \ - / bfd_octets_per_byte (bfd)) + (((bfd)->direction != write_direction && (sec)->rawsize != 0 \ + ? (sec)->rawsize : (sec)->size) / bfd_octets_per_byte (bfd)) /* Return TRUE if input section SEC has been discarded. */ #define elf_discarded_section(sec) \ Index: bfd/compress.c =================================================================== RCS file: /cvs/src/src/bfd/compress.c,v retrieving revision 1.8 diff -u -p -r1.8 compress.c --- bfd/compress.c 6 Mar 2011 18:37:07 -0000 1.8 +++ bfd/compress.c 10 Apr 2011 07:00:29 -0000 @@ -158,7 +158,7 @@ DESCRIPTION bfd_boolean bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr) { - bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size; + bfd_size_type sz; bfd_byte *p = *ptr; #ifdef HAVE_ZLIB_H bfd_boolean ret; @@ -169,6 +169,10 @@ bfd_get_full_section_contents (bfd *abfd bfd_byte *uncompressed_buffer; #endif + if (abfd->direction != write_direction && sec->rawsize != 0) + sz = sec->rawsize; + else + sz = sec->size; if (sz == 0) return TRUE; Index: bfd/elf32-rx.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-rx.c,v retrieving revision 1.8 diff -u -p -r1.8 elf32-rx.c --- bfd/elf32-rx.c 18 Jan 2011 14:13:43 -0000 1.8 +++ bfd/elf32-rx.c 10 Apr 2011 07:00:42 -0000 @@ -3305,13 +3305,12 @@ rx_final_link (bfd * abfd, struct bfd_li #endif if (o->flags & SEC_CODE && bfd_big_endian (abfd) - && (o->size % 4 || o->rawsize % 4)) + && o->size % 4) { #ifdef DJDEBUG fprintf (stderr, "adjusting...\n"); #endif o->size += 4 - (o->size % 4); - o->rawsize += 4 - (o->rawsize % 4); } } Index: bfd/elf32-microblaze.c =================================================================== RCS file: /cvs/src/src/bfd/elf32-microblaze.c,v retrieving revision 1.9 diff -u -p -r1.9 elf32-microblaze.c --- bfd/elf32-microblaze.c 4 Oct 2010 14:13:09 -0000 1.9 +++ bfd/elf32-microblaze.c 11 Apr 2011 00:16:47 -0000 @@ -824,7 +824,7 @@ microblaze_elf_relocate_section (bfd *ou } /* Sanity check the address. */ - if (offset > bfd_get_section_limit (output_bfd, input_section)) + if (offset > bfd_get_section_limit (input_bfd, input_section)) { r = bfd_reloc_outofrange; goto check_reloc; Index: bfd/elfxx-ia64.c =================================================================== RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v retrieving revision 1.231 diff -u -p -r1.231 elfxx-ia64.c --- bfd/elfxx-ia64.c 1 Apr 2011 08:38:55 -0000 1.231 +++ bfd/elfxx-ia64.c 11 Apr 2011 02:42:11 -0000 @@ -215,7 +215,7 @@ static bfd_boolean elfNN_ia64_dynamic_sy static bfd_reloc_status_type elfNN_ia64_install_value (bfd_byte *hit_addr, bfd_vma val, unsigned int r_type); static bfd_boolean elfNN_ia64_choose_gp - (bfd *abfd, struct bfd_link_info *info); + (bfd *abfd, struct bfd_link_info *info, bfd_boolean final); static void elfNN_ia64_relax_ldxmov (bfd_byte *contents, bfd_vma off); static void elfNN_ia64_dyn_sym_traverse @@ -1221,7 +1221,7 @@ elfNN_ia64_relax_section (bfd *abfd, ase gp = _bfd_get_gp_value (obfd); if (gp == 0) { - if (!elfNN_ia64_choose_gp (obfd, link_info)) + if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE)) goto error_return; gp = _bfd_get_gp_value (obfd); } @@ -4298,7 +4298,7 @@ elfNN_ia64_unwind_entry_compare (const P /* Make sure we've got ourselves a nice fat __gp value. */ static bfd_boolean -elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info) +elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final) { bfd_vma min_vma = (bfd_vma) -1, max_vma = 0; bfd_vma min_short_vma = min_vma, max_short_vma = 0; @@ -4321,7 +4321,12 @@ elfNN_ia64_choose_gp (bfd *abfd, struct continue; lo = os->vma; - hi = os->vma + (os->rawsize ? os->rawsize : os->size); + /* When this function is called from elfNN_ia64_final_link + the correct value to use is os->size. When called from + elfNN_ia64_relax_section we are in the middle of section + sizing; some sections will already have os->size set, others + will have os->size zero and os->rawsize the previous size. */ + hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size); if (hi < lo) hi = (bfd_vma) -1; @@ -4462,7 +4467,7 @@ elfNN_ia64_final_link (bfd *abfd, struct /* We assume after gp is set, section size will only decrease. We need to adjust gp for it. */ _bfd_set_gp_value (abfd, 0); - if (! elfNN_ia64_choose_gp (abfd, info)) + if (! elfNN_ia64_choose_gp (abfd, info, TRUE)) return FALSE; gp_val = _bfd_get_gp_value (abfd); Index: bfd/libbfd.c =================================================================== RCS file: /cvs/src/src/bfd/libbfd.c,v retrieving revision 1.54 diff -u -p -r1.54 libbfd.c --- bfd/libbfd.c 14 Jan 2011 12:35:55 -0000 1.54 +++ bfd/libbfd.c 10 Apr 2011 07:00:55 -0000 @@ -866,7 +866,15 @@ _bfd_generic_get_section_contents (bfd * return FALSE; } - sz = section->rawsize ? section->rawsize : section->size; + /* We do allow reading of a section after bfd_final_link has + written the contents out to disk. In that situation, rawsize is + just a stale version of size, so ignore it. Otherwise we must be + reading an input section, where rawsize, if different to size, + is the on-disk size. */ + if (abfd->direction != write_direction && section->rawsize != 0) + sz = section->rawsize; + else + sz = section->size; if (offset + count < count || offset + count > sz) { @@ -919,7 +927,10 @@ _bfd_generic_get_section_contents_in_win w->data = w->i->data; return bfd_get_section_contents (abfd, section, w->data, offset, count); } - sz = section->rawsize ? section->rawsize : section->size; + if (abfd->direction != write_direction && section->rawsize != 0) + sz = section->rawsize; + else + sz = section->size; if (offset + count > sz || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, TRUE)) Index: bfd/section.c =================================================================== RCS file: /cvs/src/src/bfd/section.c,v retrieving revision 1.108 diff -u -p -r1.108 section.c --- bfd/section.c 8 Nov 2010 02:48:54 -0000 1.108 +++ bfd/section.c 10 Apr 2011 07:00:56 -0000 @@ -1456,7 +1456,10 @@ bfd_get_section_contents (bfd *abfd, return TRUE; } - sz = section->rawsize ? section->rawsize : section->size; + if (abfd->direction != write_direction && section->rawsize != 0) + sz = section->rawsize; + else + sz = section->size; if ((bfd_size_type) offset > sz || count > sz || offset + count > sz -- Alan Modra Australia Development Lab, IBM