* 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).