* MEMORY commands in link scripts @ 2004-11-05 11:59 Jon Beniston 2004-11-05 12:55 ` Dave Korn 0 siblings, 1 reply; 6+ messages in thread From: Jon Beniston @ 2004-11-05 11:59 UTC (permalink / raw) To: binutils Hi, Is there any way to either use non-constants for the ORIGIN or LENGTH values in a MEMORY command, or some how access these values else where in a link script. What I would like to be able to do is, something like: base = 0x100; size = 0x100; MEMORY { ram (rw) : ORIGIN = base, LENGTH = size; } ... SECTIONS { PROVIDE(_fstack = base + size - 4) } Or, alternatively: SECTIONS { PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4) } To put it another way, I would like to be able to override the size / position of a memory from the command line. Cheers, Jon ^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: MEMORY commands in link scripts 2004-11-05 11:59 MEMORY commands in link scripts Jon Beniston @ 2004-11-05 12:55 ` Dave Korn 2004-11-05 13:26 ` Jon Beniston 0 siblings, 1 reply; 6+ messages in thread From: Dave Korn @ 2004-11-05 12:55 UTC (permalink / raw) To: jbeniston, binutils > -----Original Message----- > From: binutils-owner On Behalf Of Jon Beniston > Sent: 05 November 2004 11:59 > Hi, > > Is there any way to either use non-constants for the ORIGIN > or LENGTH values > in a MEMORY command, or some how access these values else > where in a link script. Alas no. Although the documentation suggests this should be possible, it isn't. See http://sources.redhat.com/ml/binutils/2004-03/msg00540.html http://sources.redhat.com/ml/binutils/2004-03/msg00571.html for detailed explanation. The docs should be updated. I've filed a bugzilla report. Should have done so months ago. Sorry all. http://sources.redhat.com/bugzilla/show_bug.cgi?id=518 Your best bet would be to work around it in your build system, perhaps by building a linker script as a make target, or perhaps you could use multiple -T options, and do something like echo "base = ${BASE}" > ldscript.tmp echo "size = ${SIZE}" >> ldscript.tmp echo "MEMORY {" >> ldscript.tmp echo " ram (rw) : ORIGIN = ${BASE}, LENGTH = ${SIZE};" >> ldscript.tmp echo "}" >>ldscript.tmp then have a main linker script that has all the unchanging parts in it: --------------------ldscript.main-------------------- .... SECTIONS { PROVIDE(_fstack = base + size - 4) } .... --------------------ldscript.main-------------------- and on your link command line, use "-T ldscript.tmp -T ldscript.main" to assemble the two parts into one script. cheers, DaveK -- Can't think of a witty .sigline today.... ^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: MEMORY commands in link scripts 2004-11-05 12:55 ` Dave Korn @ 2004-11-05 13:26 ` Jon Beniston 2004-11-08 8:46 ` Nick Clifton 0 siblings, 1 reply; 6+ messages in thread From: Jon Beniston @ 2004-11-05 13:26 UTC (permalink / raw) To: 'Dave Korn', binutils > > Alas no. Although the documentation suggests this should > be possible, it isn't. See Cheers for that explaination. I still think it might be useful have ORIGIN() and LENGTH() functions. If I were to create a patch to implement this, is it likely to be accepted? Would overloading the ADDR() and SIZEOF() functions be more approriate? Cheers, Jon ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MEMORY commands in link scripts 2004-11-05 13:26 ` Jon Beniston @ 2004-11-08 8:46 ` Nick Clifton 2004-11-08 11:51 ` Jon Beniston 0 siblings, 1 reply; 6+ messages in thread From: Nick Clifton @ 2004-11-08 8:46 UTC (permalink / raw) To: jbeniston; +Cc: 'Dave Korn', binutils Hi Jon, > I still think it might be useful have ORIGIN() and LENGTH() functions. If I > were to create a patch to implement this, is it likely to be accepted? Yes, provided that a) it worked, b) it was tested and c) you had a copyright assignment on file with the FSF. >Would overloading the ADDR() and SIZEOF() functions be more approriate? No, definitely not. Keep things simple. :-) Cheers Nick ^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: MEMORY commands in link scripts 2004-11-08 8:46 ` Nick Clifton @ 2004-11-08 11:51 ` Jon Beniston 2004-11-19 9:31 ` Nick Clifton 0 siblings, 1 reply; 6+ messages in thread From: Jon Beniston @ 2004-11-08 11:51 UTC (permalink / raw) To: binutils [-- Attachment #1: Type: text/plain, Size: 485 bytes --] Hi, > > I still think it might be useful have ORIGIN() and LENGTH() > functions. Attached is a patch that implements these two functions. Cheers, 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. [-- Attachment #2: mem_origin_and_length.patch --] [-- Type: application/octet-stream, Size: 5759 bytes --] ? mem_origin_and_length.patch Index: ld.texinfo =================================================================== RCS file: /cvs/src/src/ld/ld.texinfo,v retrieving revision 1.129 diff -c -p -r1.129 ld.texinfo *** ld.texinfo 26 Oct 2004 18:41:51 -0000 1.129 --- ld.texinfo 8 Nov 2004 11:38:45 -0000 *************** the next available address within the me *** 3881,3886 **** --- 3881,3896 ---- output sections directed to a memory region are too large for the region, the linker will issue an error message. + It is possible to access the origin and length of a memory in an + expression via the @code{ORIGIN(@var{memory})} and @code{LENGTH(@var{memory})} + functions: + + @smallexample + @group + _fstack = ORIGIN(ram) + LENGTH(ram) - 4; + @end group + @end smallexample + @node PHDRS @section PHDRS Command @kindex PHDRS *************** SECTIONS @{ @dots{} *** 4656,4661 **** --- 4666,4675 ---- @end group @end smallexample + @item LENGTH(@var{memory}) + @kindex LENGTH(@var{memory}) + Return the length of the named @var{memory}. + @item LOADADDR(@var{section}) @kindex LOADADDR(@var{section}) @cindex section load address in expression *************** This function is closely related to @cod *** 4680,4685 **** --- 4694,4703 ---- use the @code{MEMORY} command to define discontinuous memory for the output file, the two functions are equivalent. + @item ORIGIN(@var{memory}) + @kindex ORIGIN(@var{memory}) + Return the origin of the named @var{memory}. + @item SEGMENT_START(@var{segment}, @var{default}) @kindex SEGMENT_START(@var{segment}, @var{default}) Return the base address of the named @var{segment}. If an explicit Index: ldexp.c =================================================================== RCS file: /cvs/src/src/ld/ldexp.c,v retrieving revision 1.38 diff -c -p -r1.38 ldexp.c *** ldexp.c 26 Oct 2004 18:41:51 -0000 1.38 --- ldexp.c 8 Nov 2004 11:38:45 -0000 *************** exp_print_token (token_code_type code, i *** 105,111 **** { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" }, { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" }, { DATA_SEGMENT_END, "DATA_SEGMENT_END" }, ! { SEGMENT_START, "SEGMENT_START" } }; unsigned int idx; --- 105,113 ---- { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" }, { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" }, { DATA_SEGMENT_END, "DATA_SEGMENT_END" }, ! { SEGMENT_START, "SEGMENT_START" }, ! { ORIGIN, "ORIGIN" }, ! { LENGTH, "LENGTH" } }; unsigned int idx; *************** fold_name (etree_type *tree, *** 645,650 **** --- 647,678 ---- } break; + case LENGTH: + { + lang_memory_region_type *mem; + + mem = lang_memory_region_lookup (tree->name.name, FALSE); + if (mem != NULL) + result = new_abs (mem->length); + else + einfo (_("%F%S: undefined memory `%s' referenced in expression\n"), + tree->name.name); + } + break; + + case ORIGIN: + { + lang_memory_region_type *mem; + + mem = lang_memory_region_lookup (tree->name.name, FALSE); + if (mem != NULL) + result = new_abs (mem->origin); + else + einfo (_("%F%S: undefined memory `%s' referenced in expression\n"), + tree->name.name); + } + break; + default: FAIL (); break; Index: ldgram.y =================================================================== RCS file: /cvs/src/src/ld/ldgram.y,v retrieving revision 1.37 diff -c -p -r1.37 ldgram.y *** ldgram.y 26 Oct 2004 18:41:51 -0000 1.37 --- ldgram.y 8 Nov 2004 11:38:45 -0000 *************** exp : *** 863,868 **** --- 863,872 ---- { $$ = exp_binop (MIN_K, $3, $5 ); } | ASSERT_K '(' exp ',' NAME ')' { $$ = exp_assert ($3, $5); } + | ORIGIN '(' NAME ')' + { $$ = exp_nameop(ORIGIN, $3); } + | LENGTH '(' NAME ')' + { $$ = exp_nameop(LENGTH, $3); } ; Index: ldlex.l =================================================================== RCS file: /cvs/src/src/ld/ldlex.l,v retrieving revision 1.27 diff -c -p -r1.27 ldlex.l *** ldlex.l 26 Oct 2004 18:41:51 -0000 1.27 --- ldlex.l 8 Nov 2004 11:38:48 -0000 *************** V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([ *** 242,252 **** <BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); } <BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');} <BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);} ! <BOTH,SCRIPT>"ORIGIN" { RTOKEN(ORIGIN);} <BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);} <EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);} <EXPRESSION,BOTH,SCRIPT>"BIND" { RTOKEN(BIND);} ! <BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);} <EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);} <EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);} <EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);} --- 242,252 ---- <BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); } <BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');} <BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);} ! <BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);} <BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);} <EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);} <EXPRESSION,BOTH,SCRIPT>"BIND" { RTOKEN(BIND);} ! <BOTH,SCRIPT,EXPRESSION>"LENGTH" { RTOKEN(LENGTH);} <EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);} <EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);} <EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);} ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: MEMORY commands in link scripts 2004-11-08 11:51 ` Jon Beniston @ 2004-11-19 9:31 ` Nick Clifton 0 siblings, 0 replies; 6+ messages in thread From: Nick Clifton @ 2004-11-19 9:31 UTC (permalink / raw) To: jbeniston; +Cc: binutils [-- Attachment #1: Type: text/plain, Size: 1046 bytes --] 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. [-- Attachment #2: ld.patch --] [-- Type: text/plain, Size: 6091 bytes --] 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); > } ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-11-19 9:31 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-11-05 11:59 MEMORY commands in link scripts Jon Beniston 2004-11-05 12:55 ` Dave Korn 2004-11-05 13:26 ` Jon Beniston 2004-11-08 8:46 ` Nick Clifton 2004-11-08 11:51 ` Jon Beniston 2004-11-19 9:31 ` Nick Clifton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).