This is the mail archive of the binutils@sourceware.org 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]

fix bug with loadaddr and load regions


I fell over a problem with using a load region and loadaddr, to create a romable image. With
.data { data_load = LOADADDR(.data); ... } >ram AT>rom
I found that data_load's value became load address + execution address, because it was interpreted as a data-relative value. The same problem didn't manifest with
.data : AT(EXPR) { data_load = LOADADDR(.data); ...} >ram
but of course here I have to calculate EXPR myself.


When using an AT> region, ldlang creates an integer expression for the section's load address. When calculating this later for the map file, it uses exp_get_abs_int to calculate it in an absolute context (so the map file shows the correct load address). However, when it's evaluated as part of a LOADADDR, it's calculated in the current section's context.

This patch fixes things in the simplest way I could find. Namely when evaluating the LOADADDR expression, check whether it came from a load region, and if so explicitly put it in the *ABS* section.

ok?

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2006-08-25  Nathan Sidwell  <nathan@codesourcery.com>

	* ldexp.c (fold_name): Loadaddrs of sections with an lma_region
	are absolute.

	testsuite/
	* ld-elf/loadaddr3.t: New.
	* ld-elf/loadaddr3a.d: New.
	* ld-elf/loadaddr3b.d: New.

Index: ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.63
diff -c -3 -p -r1.63 ldexp.c
*** ldexp.c	23 Aug 2006 01:35:31 -0000	1.63
--- ldexp.c	25 Aug 2006 10:42:22 -0000
*************** fold_name (etree_type *tree)
*** 579,585 ****
  	      if (os->load_base == NULL)
  		new_abs (os->bfd_section->lma);
  	      else
! 		exp_fold_tree_1 (os->load_base);
  	    }
  	}
        break;
--- 579,592 ----
  	      if (os->load_base == NULL)
  		new_abs (os->bfd_section->lma);
  	      else
! 		{
! 		  exp_fold_tree_1 (os->load_base);
! 		  /* If this section has a load region, the expression
! 		     will be absolute.  */
! 		  if (os->lma_region && expld.result.valid_p)
! 		    expld.result.section = bfd_abs_section_ptr;
! 		}
! 	      
  	    }
  	}
        break;
Index: testsuite/ld-elf/loadaddr3.t
===================================================================
RCS file: testsuite/ld-elf/loadaddr3.t
diff -N testsuite/ld-elf/loadaddr3.t
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/ld-elf/loadaddr3.t	25 Aug 2006 10:42:22 -0000
***************
*** 0 ****
--- 1,16 ----
+ 
+ MEMORY
+ {
+   rom (rx) : ORIGIN = 0x100, LENGTH = 0x100
+   ram (rwx) : ORIGIN = 0x200, LENGTH = 0x100
+ 
+ }
+ 
+ SECTIONS
+ {
+   .text : {*(.text .text.*)} >rom
+   .data : {data_load = LOADADDR (.data);
+ 	   data_start = ADDR (.data);
+ 	   *(.data .data.*)} >ram AT>rom
+   /DISCARD/ : { *(.*) }
+ }
Index: testsuite/ld-elf/loadaddr3a.d
===================================================================
RCS file: testsuite/ld-elf/loadaddr3a.d
diff -N testsuite/ld-elf/loadaddr3a.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/ld-elf/loadaddr3a.d	25 Aug 2006 10:42:22 -0000
***************
*** 0 ****
--- 1,9 ----
+ #source: loadaddr.s
+ #ld: -T loadaddr3.t -z max-page-size=0x200000
+ #readelf: -l --wide
+ #target: *-*-elf*
+ 
+ #...
+   LOAD +0x000000 0x0*00000000 0x0*00000000 0x0*0101 0x0*0101 R E 0x.*
+   LOAD +0x000200 0x0*00000200 0x0*00000101 0x0*0001 0x0*0001 RW  0x.*
+ #pass
Index: testsuite/ld-elf/loadaddr3b.d
===================================================================
RCS file: testsuite/ld-elf/loadaddr3b.d
diff -N testsuite/ld-elf/loadaddr3b.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/ld-elf/loadaddr3b.d	25 Aug 2006 10:42:22 -0000
***************
*** 0 ****
--- 1,13 ----
+ #source: loadaddr.s
+ #ld: -T loadaddr3.t -z max-page-size=0x200000
+ #objdump: -t
+ #target: *-*-elf*
+ 
+ #...
+ 0+0000100 l    d  .text	0+0000000 .text
+ 0+0000200 l    d  .data	0+0000000 .data
+ #...
+ 0+0000101 g       \*ABS\*	0+0000000 data_load
+ #...
+ 0+0000200 g       .data	0+0000000 data_start
+ #pass

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