This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]