? 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 **** ":" { RTOKEN(':'); } ";" { RTOKEN(';');} "MEMORY" { RTOKEN(MEMORY);} ! "ORIGIN" { RTOKEN(ORIGIN);} "VERSION" { RTOKEN(VERSIONK);} "BLOCK" { RTOKEN(BLOCK);} "BIND" { RTOKEN(BIND);} ! "LENGTH" { RTOKEN(LENGTH);} "ALIGN" { RTOKEN(ALIGN_K);} "DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);} "DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);} --- 242,252 ---- ":" { RTOKEN(':'); } ";" { RTOKEN(';');} "MEMORY" { RTOKEN(MEMORY);} ! "ORIGIN" { RTOKEN(ORIGIN);} "VERSION" { RTOKEN(VERSIONK);} "BLOCK" { RTOKEN(BLOCK);} "BIND" { RTOKEN(BIND);} ! "LENGTH" { RTOKEN(LENGTH);} "ALIGN" { RTOKEN(ALIGN_K);} "DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN);} "DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END);}