This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Bogus p_memsz for multiple BSS segments
- From: Richard Sandiford <richard at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Thu, 10 May 2007 11:59:51 +0100
- Subject: Bogus p_memsz for multiple BSS segments
assign_file_positions_for_load_sections uses:
if (p->p_type == PT_LOAD
|| p->p_type == PT_TLS)
{
bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_filesz);
to calculate the difference between the current end of a segment and the
load address of its next section. This calculation was originally just
associated with SEC_LOAD sections (where it's correct), but it is now
used for BSS sections too. This leads to quadratic explosion of p_memsz
when there are multiple bss sections. (E.g., the data segment in the
attached testcase would have a p_memsz of 0xca80000 rather than the
expected 0x500000.)
I think the fix is simply to use the memory size rather than the file
size in the calculation above. Tested on x86_64-linux-gnu. OK to install?
Richard
bfd/
* elf.c (assign_file_positions_for_load_sections): Use p_memsz
rather than p_filesz to calculate the LMA of the end of a segment.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.386
diff -u -p -r1.386 elf.c
--- bfd/elf.c 7 May 2007 01:05:46 -0000 1.386
+++ bfd/elf.c 10 May 2007 10:48:18 -0000
@@ -4520,7 +4520,7 @@ assign_file_positions_for_load_sections
if (p->p_type == PT_LOAD
|| p->p_type == PT_TLS)
{
- bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_filesz);
+ bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
if ((flags & SEC_LOAD) != 0
|| ((flags & SEC_ALLOC) != 0
Index: ld/testsuite/ld-elf/multibss1.d
===================================================================
RCS file: ld/testsuite/ld-elf/multibss1.d
diff -N ld/testsuite/ld-elf/multibss1.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/multibss1.d 10 May 2007 10:48:18 -0000
@@ -0,0 +1,9 @@
+#source: multibss1.s
+#ld: -e 0
+#readelf: -l --wide
+#target: *-*-linux*
+
+#...
+ +LOAD +0x[^ ]+ +0x[^ ]+ +0x[^ ]+ +0x[^ ]+ +0x500000 .*
+# p_offset p_vaddr p_paddr p_filesz
+#pass
Index: ld/testsuite/ld-elf/multibss1.s
===================================================================
RCS file: ld/testsuite/ld-elf/multibss1.s
diff -N ld/testsuite/ld-elf/multibss1.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-elf/multibss1.s 10 May 2007 10:48:18 -0000
@@ -0,0 +1,11 @@
+ .macro makebss
+ .section .bss_\@,"aw",@nobits
+ .space 0x10000
+ .endm
+
+ .rept 80
+ makebss
+ .endr
+
+ .text
+ .space 0x10