This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[RFA:] ld section location mishap. Attention PE, HPPA, PPC64.
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 5 Feb 2002 03:01:43 +0100
- Subject: [RFA:] ld section location mishap. Attention PE, HPPA, PPC64.
When linking with --gc-sections, I noticed the hard way that
sections started at what seemed like a random location when
there was no explicitly set address (--section-start) or with
the elf.sc default for everything at 0 (TEXT_BASE_ADDRESS). It
was actually a left-over value in the (default) memory region
that was used to set the section address, if certain data
(stabs, EH) was successfully GC:ed for ELF. The caller of
lang_size_sections/ lang_do_assignments,
gld${EMULATION_NAME}_finish, did not properly reset memory
regions like lang_process does. Actually there was some
difficulty in doing that since the proper function wasn't
public.
The same problem seems to exist for other callers: pe-dll.c
(twice), emultempl/hppaelf.em and emultempl/ppc64elf.em. I
leave those to the respective maintainer. (Sorry.)
I replaced GPL v1 with GPL v2 in ldlang.h. ISTR this is wanted
when files with GPL v1 are spotted.
Introducing a new .exp driver to simplify GC-testing, partly
because selective.exp didn't support selective testing(!)
(e.g. sel-dump.exp=keepdot0) at all. IMHO future GC/"selective"
tests should go in sel-dump.exp, though run_dump_test needs a
"not"-feature to enable checking for absence of a match.
Tested on i686-pc-linux-gnu and cross to cris-axis-linux-gnu. I
also tweaked sel-dump.exp and checked before and after the fix
on mmix-knuth-mmixware with LDEMULATION=elf64mmix, so see that
the test and particularly the section-start regex patterns
should work for 64-bit ELF targets too.
Ok to commit?
ld:
* ldlang.c (lang_reset_memory_regions): Rename from
reset_memory_regions. Change all callers. Make public.
* ldlang.h (lang_reset_memory_regions): Prototype.
* emultempl/elf32.em (gld${EMULATION_NAME}_finish): Call
lang_reset_memory_regions before lang_size_sections.
ld/testsuite:
* ld-selective/keepdot.d, ld-selective/keepdot.ld,
ld-selective/keepdot.s, ld-selective/keepdot0.d: New tests.
* ld-selective/sel-dump.exp: New, driver for run_dump_test:s.
Index: emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.70
diff -p -c -r1.70 elf32.em
*** elf32.em 2002/01/05 13:14:00 1.70
--- elf32.em 2002/02/05 00:55:47
*************** cat >e${EMULATION_NAME}.c <<EOF
*** 13,19 ****
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
! Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
--- 13,19 ----
/* ${ELFSIZE} bit ELF emulation code for ${EMULATION_NAME}
Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
! 2002 Free Software Foundation, Inc.
Written by Steve Chamberlain <sac@cygnus.com>
ELF support by Ian Lance Taylor <ian@cygnus.com>
*************** gld${EMULATION_NAME}_finish ()
*** 1330,1335 ****
--- 1330,1337 ----
{
if (bfd_elf${ELFSIZE}_discard_info (output_bfd, &link_info))
{
+ lang_reset_memory_regions ();
+
/* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section,
&stat_ptr->head, 0, (bfd_vma) 0, NULL);
Index: ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.70
diff -p -c -r1.70 ldlang.c
*** ldlang.c 2002/01/08 14:56:09 1.70
--- ldlang.c 2002/02/05 00:55:48
*************** static boolean lang_one_common PARAMS ((
*** 132,138 ****
static void lang_place_orphans PARAMS ((void));
static int topower PARAMS ((int));
static void lang_set_startof PARAMS ((void));
- static void reset_memory_regions PARAMS ((void));
static void gc_section_callback
PARAMS ((lang_wild_statement_type *, struct wildcard_list *, asection *,
lang_input_statement_type *, PTR));
--- 132,137 ----
*************** lang_final ()
*** 3972,3979 ****
/* Reset the current counters in the regions. */
! static void
! reset_memory_regions ()
{
lang_memory_region_type *p = lang_memory_region_list;
asection *o;
--- 3971,3978 ----
/* Reset the current counters in the regions. */
! void
! lang_reset_memory_regions ()
{
lang_memory_region_type *p = lang_memory_region_list;
asection *o;
*************** lang_process ()
*** 4160,4166 ****
do
{
! reset_memory_regions ();
relax_again = false;
--- 4159,4165 ----
do
{
! lang_reset_memory_regions ();
relax_again = false;
Index: ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.14
diff -p -c -r1.14 ldlang.h
*** ldlang.h 2001/08/20 02:14:49 1.14
--- ldlang.h 2002/02/05 01:54:35
***************
*** 1,13 ****
/* ldlang.h - linker command language support
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
! 2001
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 1, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
--- 1,13 ----
/* ldlang.h - linker command language support
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
! 2001, 2002
Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
*************** extern void lang_for_each_input_file
*** 402,407 ****
--- 402,408 ----
PARAMS ((void (*dothis) (lang_input_statement_type *)));
extern void lang_for_each_file
PARAMS ((void (*dothis) (lang_input_statement_type *)));
+ extern void lang_reset_memory_regions PARAMS ((void));
extern bfd_vma lang_do_assignments
PARAMS ((lang_statement_union_type * s,
lang_output_section_statement_type *output_section_statement,
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-selective/keepdot.d Tue Feb 5 02:06:21 2002
***************
*** 0 ****
--- 1,9 ----
+ #ld: --gc-sections -Bstatic -e _start -T$srcdir/$subdir/keepdot.ld
+ #name: Preserve default . = 0
+ #objdump: -h
+
+ # Check that GC:ing does not mess up the default value for dot.
+
+ #...
+ [ ]+.[ ]+\.myinit[ ]+0+[48][ ]+0+[ ]+0+ .*
+ #pass
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-selective/keepdot.ld Tue Feb 5 01:13:48 2002
***************
*** 0 ****
--- 1,5 ----
+ SECTIONS
+ {
+ .myinit : { KEEP (*(.myinit)) }
+ .mytext : { *(.mytext*) *(.text*) }
+ }
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-selective/keepdot.s Tue Feb 5 01:04:32 2002
***************
*** 0 ****
--- 1,17 ----
+ .text
+ .stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0
+ .stabs "char:t(0,2)=r(0,2);0;127;",128,0,0,0
+
+ .section .myinit,"ax",@progbits
+ .stabs "barxfoo:F(0,20)",36,0,2,_bar
+ .global _bar
+ .global _start
+ _start:
+ _bar:
+ .long 123
+
+ .section .mytext.baz,"ax",@progbits
+ .stabs "baz:F(0,20)",36,0,6,_baz
+ .global _baz
+ _baz:
+ .long 456
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-selective/keepdot0.d Tue Feb 5 02:06:01 2002
***************
*** 0 ****
--- 1,11 ----
+ #source: keepdot.s
+ #ld: --gc-sections -Bstatic -e _start -T$srcdir/$subdir/keepdot0.ld
+ #name: Preserve explicit . = 0
+ #objdump: -h
+
+ # Check that GC:ing does not mess up the value for dot when specified
+ # as 0.
+
+ #...
+ [ ]+.[ ]+\.myinit[ ]+0+[48][ ]+0+[ ]+0+ .*
+ #pass
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-selective/keepdot0.ld Tue Feb 5 01:13:14 2002
***************
*** 0 ****
--- 1,6 ----
+ SECTIONS
+ {
+ . = 0x0;
+ .myinit : { KEEP (*(.myinit)) }
+ .mytext : { *(.mytext*) *(.text*) }
+ }
*** /dev/null Tue Jan 1 05:00:00 1980
--- ld-selective/sel-dump.exp Tue Feb 5 02:42:19 2002
***************
*** 0 ****
--- 1,34 ----
+ # Expect script for ld selective linking tests running run_dump_test
+ # Copyright 2002 Free Software Foundation, Inc.
+ #
+ # This file is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 2 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ # Test for ELF here, so we don't have to qualify on ELF specifically
+ # in every .d-file.
+
+ if { ![istarget *-*-linux*]
+ && ![istarget *-*-gnu]
+ && ![istarget *-*-elf] } {
+ return
+ }
+
+ load_lib ld-lib.exp
+
+ set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+ for { set i 0 } { $i < [llength $test_list] } { incr i } {
+ # We need to strip the ".d", but can leave the dirname.
+ verbose [file rootname [lindex $test_list $i]]
+ run_dump_test [file rootname [lindex $test_list $i]]
+ }
brgds, H-P