This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: MEMORY commands in link scripts
- From: Nick Clifton <nickc at redhat dot com>
- To: jbeniston at compxs dot com
- Cc: binutils at sources dot redhat dot com
- Date: Fri, 19 Nov 2004 09:35:09 +0000
- Subject: Re: MEMORY commands in link scripts
- References: <000701c4c589$4574a400$0bbda8c0@Kindrogan>
Hi Jon,
2004-11-08 Jon Beniston <jon@beniston.com>
* ld/ldlex.l: Allow ORIGIN and LENGTH in EXPRESSION.
* ld/ldgram.y: Add ORIGIN and LENGTH expressions.
* ld/ldexp.c (fold_name): Implement LENGTH() and ORIGIN() functions
which return the length and origin of a memory.
* ld/ld.texinfo: Document LENGTH() and ORIGIN() functions.
Approved and applied.
Note - I felt that this patch deserved a mention in the ld/NEWS file
since it implements a new feature and also a testsuite case to check to
make sure that it works. So I have added the attached patch to do these
things.
Cheers
Nick
ld/ChangeLog
* NEWS: Mention support for ORIGIN and LENGTH operators.
ld/testsuite/ChangeLog
2004-11-19 Nick Clifton <nickc@redhat.com>
* ld-scripts/script.exp: Add test of memory linker script.
Reorganize code to remove unnecessary indentation.
Fix target tests to avoid using --image-base with *-nto targets.
* ld-scripts/memory.t: New linker script to test the MEMORY
section and the ORIGIN and LENGTH operators.
Index: ld/NEWS
===================================================================
RCS file: /cvs/src/src/ld/NEWS,v
retrieving revision 1.54
diff -c -3 -p -r1.54 NEWS
*** ld/NEWS 8 Nov 2004 13:17:24 -0000 1.54
--- ld/NEWS 19 Nov 2004 09:24:01 -0000
***************
*** 1,5 ****
--- 1,8 ----
-*- text -*-
+ * New linker script functions: ORIGIN() and LENGTH() which return information
+ about a specified memory region.
+
* Port to MAXQ processor contributed by HCL Tech.
* Added SEGMENT_START to the linker script language to permit the user to
Index: ld/testsuite/ld-scripts/script.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-scripts/script.exp,v
retrieving revision 1.6
diff -c -3 -p -r1.6 script.exp
*** ld/testsuite/ld-scripts/script.exp 18 Nov 2002 08:28:41 -0000 1.6
--- ld/testsuite/ld-scripts/script.exp 19 Nov 2004 09:24:04 -0000
*************** proc check_script { } {
*** 31,77 ****
if ![ld_nm $nm "" tmpdir/script] {
unresolved $testname
} else {
! if {![info exists nm_output(text_start)] \
! || ![info exists nm_output(text_end)] \
! || ![info exists nm_output(data_start)] \
! || ![info exists nm_output(data_end)]} {
! send_log "bad output from nm\n"
! verbose "bad output from nm"
! fail $testname
! } else {
! set text_end 0x104
! set data_end 0x1004
! if [istarget *c4x*-*-*] then {
! set text_end 0x101
! set data_end 0x1001
! }
! if [istarget *c54x*-*-*] then {
! set text_end 0x102
! set data_end 0x1002
! }
! if {$nm_output(text_start) != 0x100} {
! send_log "text_start == $nm_output(text_start)\n"
! verbose "text_start == $nm_output(text_start)"
! fail $testname
! } else { if {$nm_output(text_end) < $text_end \
! || $nm_output(text_end) > 0x110} {
! send_log "text_end == $nm_output(text_end)\n"
! verbose "text_end == $nm_output(text_end)"
! fail $testname
! } else { if {$nm_output(data_start) != 0x1000} {
! send_log "data_start == $nm_output(data_start)\n"
! verbose "data_start == $nm_output(data_start)"
! fail $testname
! } else { if {$nm_output(data_end) < $data_end \
! || $nm_output(data_end) > 0x1010} {
! send_log "data_end == $nm_output(data_end)\n"
! verbose "data_end == $nm_output(data_end)"
! fail $testname
! } else {
! pass $testname
! } } } }
! }
}
}
--- 31,93 ----
if ![ld_nm $nm "" tmpdir/script] {
unresolved $testname
+ return
+ }
+
+ if {![info exists nm_output(text_start)] \
+ || ![info exists nm_output(text_end)] \
+ || ![info exists nm_output(data_start)] \
+ || ![info exists nm_output(data_end)]} {
+ send_log "bad output from nm\n"
+ verbose "bad output from nm"
+ fail $testname
+ return
+ }
+
+ set passes 1
+ set text_end 0x104
+ set data_end 0x1004
+
+ if [istarget *c4x*-*-*] then {
+ set text_end 0x101
+ set data_end 0x1001
+ }
+
+ if [istarget *c54x*-*-*] then {
+ set text_end 0x102
+ set data_end 0x1002
+ }
+
+ if {$nm_output(text_start) != 0x100} {
+ send_log "text_start == $nm_output(text_start)\n"
+ verbose "text_start == $nm_output(text_start)"
+ set passes 0
+ }
+
+ if {$nm_output(text_end) < $text_end \
+ || $nm_output(text_end) > 0x110} {
+ send_log "text_end == $nm_output(text_end)\n"
+ verbose "text_end == $nm_output(text_end)"
+ set passes 0
+ }
+
+ if {$nm_output(data_start) != 0x1000} {
+ send_log "data_start == $nm_output(data_start)\n"
+ verbose "data_start == $nm_output(data_start)"
+ set passes 0
+ }
+
+ if {$nm_output(data_end) < $data_end \
+ || $nm_output(data_end) > 0x1010} {
+ send_log "data_end == $nm_output(data_end)\n"
+ verbose "data_end == $nm_output(data_end)"
+ set passes 0
+ }
+
+ if { $passes } {
+ pass $testname
} else {
! fail $testname
}
}
*************** if {[istarget "*-*-pe*"] \
*** 81,87 ****
|| [istarget "*-*-cygwin*"] \
|| [istarget "*-*-mingw32*"] \
|| [istarget "*-*-winnt*"] \
! || [istarget "*-*-nt*"] \
|| [istarget "*-*-interix*"] } then {
set flags "--image-base 0"
}
--- 97,103 ----
|| [istarget "*-*-cygwin*"] \
|| [istarget "*-*-mingw32*"] \
|| [istarget "*-*-winnt*"] \
! || [istarget "*-*-nt"] \
|| [istarget "*-*-interix*"] } then {
set flags "--image-base 0"
}
*************** if ![ld_simple_link $ld tmpdir/script "$
*** 99,101 ****
--- 115,127 ----
} else {
check_script
}
+
+ set testname "MEMORY"
+
+ if ![ld_simple_link $ld tmpdir/script "$flags -T $srcdir/$subdir/memory.t tmpdir/script.o"] {
+ fail $testname
+ } else {
+ check_script
+ }
+
+
Index: ld/testsuite/ld-scripts/memory.t
===================================================================
0a1,39
> MEMORY
> {
> TEXTMEM (ARX) : ORIGIN = 0x100, LENGTH = 32K
> DATAMEM (AW) : org = 0x1000, l = (64 * 1024)
> }
>
> SECTIONS
> {
> . = 0;
> .text :
> {
> /* The value returned by the ORIGIN operator is a constant.
> However it is being assigned to a symbol declared within
> a section. Therefore the symbol is section-relative and
> its value will include the offset of that section from
> the start of memory. ie the declaration:
> text_start = ORIGIN (TEXTMEM);
> here will result in text_start having a value of 0x200.
> Hence we need to subtract the absolute value of the
> location counter at this point in order to give text_start
> a value that is truely absolute, and which coincidentally
> will allow the tests in script.exp to work. */
>
> text_start = ORIGIN(TEXTMEM) - ABSOLUTE (.);
> *(.text)
> *(.pr)
> text_end = .;
> } > TEXTMEM
>
> data_start = ORIGIN (DATAMEM);
> .data :
> {
> *(.data)
> *(.rw)
> data_end = .;
> } >DATAMEM
>
> fred = ORIGIN(DATAMEM) + LENGTH(DATAMEM);
> }