This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RFC and PATCH - Defining variables in the linker script withoutdefining them as symbols on the file
- From: Guilherme Destefani <gd at helixbrasil dot com dot br>
- To: binutils <binutils at sources dot redhat dot com>
- Date: Thu, 08 Jul 2004 10:25:21 -0300
- Subject: RFC and PATCH - Defining variables in the linker script withoutdefining them as symbols on the file
Hello.
This patch add to the linker a command like PROVIDE(var=value), named
TEMPORARY(var=value) that can be used to define variables just for
temporary use, so those variables won't be sent to the file as a symbol.
I made the linked list that keep those variables in memory based on the
list that keep the memory regions on memory (static
lang_memory_region_type *lang_memory_region_list; @ld/ldlang.c:517)
BUT I didn't find where that linked list is free().
I suppose that it's not free, because is a small amount of memory and
the linker will terminate and that memory will be free by the OS when
the program end anyway, but I'm not sure.
Somebody can please confirm that, or I should free that memory in the
same place (that I didn't find) that the linker free
lang_memory_region_list?
This patch was tested with binutils-2.15.90.0.3, directly on it or after
the other patchs from Fedora Core 2 binutils-2.15.90.0.3-5.src.rpm
Use patch -p0.
Thanks in advance,
--
Guilherme Destefani
Computer Engineer
Helix S.A.
gd _at_ helixbrasil _dot_ com _dot_ br
Brazil - Parana - Curitiba
(+5541) 362-1313
2004-07-07 Guilherme Destefani <gd@helixbrasil.com>
Adding linker script command TEMPORARY
Useful to use a temporary symbol just for calculation,
that's not stored in the bfd backend
--- ld/ld.texinfo 2004-04-12 19:56:35.000000000 +0000
+++ ld/ld.texinfo 2004-07-07 21:59:50.000000000 +0000
@@ -2632,6 +2632,7 @@
@menu
* Simple Assignments:: Simple Assignments
* PROVIDE:: PROVIDE
+* TEMPORARY:: TEMPORARY
@end menu
@node Simple Assignments
@@ -2724,6 +2725,16 @@
If the program references @samp{etext} but does not define it, the
linker will use the definition in the linker script.
+@node TEMPORARY
+@subsection TEMPORARY
+@cindex TEMPORARY
+In some cases, it is desirable for a linker script to use a name
+ just to hold a value without sending a symbol to the bfd backend.
+The @code{TEMPORARY} keyword may be used to define that type of variable.
+The syntax is:
+@code{TEMPORARY(@var{symbol} = @var{expression})}.
+
+
@node SECTIONS
@section SECTIONS Command
@kindex SECTIONS
--- ld/ldexp.c 2004-03-03 20:24:34.000000000 +0000
+++ ld/ldexp.c 2004-07-07 21:59:50.000000000 +0000
@@ -456,7 +456,8 @@
bfd_vma dot)
{
etree_value_type result;
-
+ temporary_variable_list_type *temporary;
+
result.valid_p = FALSE;
switch (tree->type.node_code)
@@ -494,6 +495,10 @@
if (allocation_done != lang_first_phase_enum)
result = new_rel_from_section (dot, current_section);
}
+ else if ( (temporary = lang_temporary_lookup(tree->name.name) ) )
+ {
+ result = new_abs(temporary->value);
+ }
else if (allocation_done != lang_first_phase_enum)
{
struct bfd_link_hash_entry *h;
@@ -657,6 +662,7 @@
case etree_assign:
case etree_provide:
case etree_provided:
+ case etree_temporary:
if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
{
/* Assignment to dot can only be done during allocation. */
@@ -698,6 +704,12 @@
current_section, allocation_done,
dot, dotp);
if (result.valid_p)
+ {
+ if(tree->type.node_class == etree_temporary)
+ {
+ lang_temporary_set(tree->assign.dst,result.value);
+ }
+ else
{
bfd_boolean create;
struct bfd_link_hash_entry *h;
@@ -734,6 +746,7 @@
tree->type.node_class = etree_provided;
}
}
+ }
}
break;
@@ -871,6 +884,21 @@
return n;
}
+/* Handle TEMPORARY. */
+
+etree_type *
+exp_temporary (const char *dst, etree_type *src)
+{
+ etree_type *n;
+
+ n = stat_alloc (sizeof (n->assign));
+ n->assign.type.node_code = '=';
+ n->assign.type.node_class = etree_temporary;
+ n->assign.src = src;
+ n->assign.dst = dst;
+ return n;
+}
+
/* Handle ASSERT. */
etree_type *
--- ld/ldexp.h 2004-01-14 21:07:52.000000000 +0000
+++ ld/ldexp.h 2004-07-07 21:59:50.000000000 +0000
@@ -40,6 +40,7 @@
etree_assign,
etree_provide,
etree_provided,
+ etree_temporary,
etree_undef,
etree_unspec,
etree_value,
@@ -126,6 +127,8 @@
(int, const char *, etree_type *);
etree_type *exp_provide
(const char *, etree_type *);
+etree_type *exp_temporary
+ (const char *, etree_type *);
etree_type *exp_assert
(etree_type *, const char *);
void exp_print_tree
--- ld/ldgram.y 2004-03-03 20:24:34.000000000 +0000
+++ ld/ldgram.y 2004-07-07 22:05:11.183145976 +0000
@@ -147,7 +147,7 @@
%type <name> filename
%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
-%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
+%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START TEMPORARY
%token <name> VERS_TAG VERS_IDENTIFIER
%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
%token KEEP
@@ -611,6 +611,10 @@
{
lang_add_assignment (exp_provide ($3, $5));
}
+ | TEMPORARY '(' NAME '=' mustbe_exp ')'
+ {
+ lang_add_assignment (exp_temporary ($3, $5));
+ }
;
--- ld/ldlang.c 2004-04-12 19:56:36.000000000 +0000
+++ ld/ldlang.c 2004-07-07 21:59:50.000000000 +0000
@@ -643,6 +643,55 @@
return lookup;
}
+/* A temporary variable can be used to store a value without
+ saving it on the bfd backends
+ The syntax to declare a a temporary variable is:
+ TEMPORARAY ( VARNAME = EXPRESSION );
+ Then the value can be used later on like any other symbol.
+ The linker use a liked list to store those values in memory.
+*/
+
+static temporary_variable_list_type *lang_temporary_list = NULL;
+static temporary_variable_list_type **lang_temporary_list_tail = &lang_temporary_list;
+
+temporary_variable_list_type *lang_temporary_lookup(char const *const name)
+{
+ temporary_variable_list_type *temp;
+
+ if (name == NULL)
+ return NULL;
+
+ for (temp = lang_temporary_list; temp != NULL; temp = temp->next)
+ if (strcmp (temp->name, name) == 0)
+ break;
+ return temp;
+}
+
+temporary_variable_list_type *lang_temporary_set(char const *const name, bfd_vma value)
+{
+ temporary_variable_list_type *temp;
+
+ if (! name[0] )
+ return NULL;
+
+ if ( (temp = lang_temporary_lookup (name)) )
+ /*Reuse element already defined*/
+ free (temp->name);
+ else
+ {
+ /*Allocate a new element and link it to list*/
+ temp = xmalloc(sizeof(temporary_variable_list_type));
+ temp->next = NULL;
+
+ *lang_temporary_list_tail = temp;
+ lang_temporary_list_tail = &temp->next;
+ }
+
+ temp->name = xstrdup(name);
+ temp->value = value;
+ return temp;
+}
+
static void
lang_map_flags (flagword flag)
{
--- ld/ldlang.h 2004-04-12 19:56:36.000000000 +0000
+++ ld/ldlang.h 2004-07-07 21:59:50.000000000 +0000
@@ -103,6 +103,14 @@
const char *name;
} lang_output_statement_type;
+/* Used to store temporary link script variables in memory*/
+typedef struct temporary_variable_list_struct
+{
+ struct temporary_variable_list_struct *next;
+ bfd_vma value;
+ char *name;
+} temporary_variable_list_type;
+
/* Section types specified in a linker script. */
enum section_type
@@ -426,6 +434,10 @@
(const char *const, bfd_boolean);
extern lang_memory_region_type *lang_memory_region_default
(asection *);
+extern temporary_variable_list_type *lang_temporary_lookup
+ (char const *const);
+extern temporary_variable_list_type *lang_temporary_set
+ (char const *const, bfd_vma);
extern void lang_map
(void);
extern void lang_set_flags
--- ld/ldlex.l 2004-04-12 19:56:36.000000000 +0000
+++ ld/ldlex.l 2004-07-07 22:08:07.602326184 +0000
@@ -268,6 +268,7 @@
<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);}
<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
+<EXPRESSION,BOTH,SCRIPT>"TEMPORARY" { RTOKEN(TEMPORARY); }
<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
--- ld/ldexp.c 2004-07-07 22:26:51.276778088 -0300
+++ ld/ldexp.c 2004-07-07 22:25:06.401721520 -0300
@@ -989,6 +989,11 @@
exp_print_tree (tree->assign.src);
fprintf (config.map_file, ")");
break;
+ case etree_temporary:
+ fprintf (config.map_file, "TEMPORARY (%s, ", tree->assign.dst);
+ exp_print_tree (tree->assign.src);
+ fprintf (config.map_file, ")");
+ break;
case etree_binary:
fprintf (config.map_file, "(");
exp_print_tree (tree->binary.lhs);