This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
rawsize and output sections
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