This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: PR 12001, --defsym
- From: Alan Modra <amodra at gmail dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>, binutils at sourceware dot org
- Date: Thu, 13 Jan 2011 23:58:07 +1030
- Subject: Re: PR 12001, --defsym
- References: <20101220063057.GK15607@bubble.grove.modra.org> <AANLkTinvt_eT9HGx7syjxh9ow=DF5k9X5EWFaom0SF7N@mail.gmail.com> <20110113130539.GJ11694@bubble.grove.modra.org>
On Thu, Jan 13, 2011 at 11:35:39PM +1030, Alan Modra wrote:
> Given this bug report and Daniel's objections over using a linker
> script assignment to control ld behaviour, I've implemented a new
> LD_FEATURE linker script keyword.
I've kept the new code in open_input_bfds handling early creation of
--defsym symbols, but only handle --defsym assignments there so we
won't get an error if a script defines a symbol that is also defined
in an object file. LD_FEATURE is designed to be extensible; At the
moment we just have LD_FEATURE ("SANE_EXPR").
PR ld/12356
* ld.texinfo (Miscellaneous Commands): Describe LD_FEATURE.
(Expression Section): Update.
* ld.h (ld_config_type): Add sane_expr.
* ldgram.y (ifile_p1): Add LD_FEATURE.
* ldlex.l (LD_FEATYRE): New.
* ldemul.c (after_parse_default): Delete code handling ld_compatibility.
* ldexp.h (struct ldexp_control): Delete uses_defined.
* ldexp.c: Remove all uses of uses_defined.
(fold_name): Test config.sane_expr rather than ld_compatibility.
(exp_fold_tree_1): Likewise. Adjust handling of assignments
during first phase.
* ldlang.h (ld_compatibility): Delete.
(lang_ld_feature): Declare.
* ldlang.c (ld_compatibility): Delete.
(open_input_bfds): Only handle assignments for --defsym.
(lang_ld_feature): New function.
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.269
diff -u -p -r1.269 ld.texinfo
--- ld/ld.texinfo 20 Dec 2010 13:00:12 -0000 1.269
+++ ld/ld.texinfo 13 Jan 2011 13:13:58 -0000
@@ -3344,6 +3344,13 @@ of the names used by the BFD library (@p
architecture of an object file by using the @code{objdump} program with
the @samp{-f} option.
@end ifclear
+
+@item LD_FEATURE(@var{string})
+@kindex LD_FEATURE(@var{string})
+This command may be used to modify @command{ld} behavior. If
+@var{string} is @code{"SANE_EXPR"} then absolute symbols and numbers
+in a script are simply treated as numbers everywhere.
+@xref{Expression Section}.
@end table
@node Assignments
@@ -5503,15 +5510,15 @@ section relative symbols and for builtin
address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and
@code{SEGMENT_START}. Other terms are simply numbers, or are builtin
functions that return a non-address value, such as @code{LENGTH}.
-One complication is that unless you assign @code{__ld_compatibility}
-a value of 221 or larger, numbers and absolute symbols are treated
+One complication is that unless you set @code{LD_FEATURE ("SANE_EXPR")}
+(@pxref{Miscellaneous Commands}), numbers and absolute symbols are treated
differently depending on their location, for compatibility with older
versions of @code{ld}. Expressions appearing outside an output
section definition treat all numbers as absolute addresses.
Expressions appearing inside an output section definition treat
-absolute symbols as numbers. If @code{__ld_compatibility} is assigned
-a value larger than 221, then absolute symbols and numbers are simply
-treated as numbers everywhere.
+absolute symbols as numbers. If @code{LD_FEATURE ("SANE_EXPR")} is
+given, then absolute symbols and numbers are simply treated as numbers
+everywhere.
In the following simple example,
Index: ld/ld.h
===================================================================
RCS file: /cvs/src/src/ld/ld.h,v
retrieving revision 1.47
diff -u -p -r1.47 ld.h
--- ld/ld.h 15 Dec 2010 14:56:37 -0000 1.47
+++ ld/ld.h 13 Jan 2011 13:13:53 -0000
@@ -292,6 +292,10 @@ typedef struct {
on the command line. */
bfd_boolean only_cmd_line_lib_dirs;
+ /* If set, numbers and absolute symbols are simply treated as
+ numbers everywhere. */
+ bfd_boolean sane_expr;
+
/* The rpath separation character. Usually ':'. */
char rpath_separator;
Index: ld/ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.64
diff -u -p -r1.64 ldgram.y
--- ld/ldgram.y 13 Jan 2011 13:06:22 -0000 1.64
+++ ld/ldgram.y 13 Jan 2011 13:14:00 -0000
@@ -134,6 +134,7 @@ static int error_index;
%token INCLUDE
%token MEMORY
%token REGION_ALIAS
+%token LD_FEATURE
%token NOLOAD DSECT COPY INFO OVERLAY
%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
%token <integer> NEXT
@@ -357,6 +358,8 @@ ifile_p1:
{ lang_add_insert ($3, 1); }
| REGION_ALIAS '(' NAME ',' NAME ')'
{ lang_memory_region_alias ($3, $5); }
+ | LD_FEATURE '(' NAME ')'
+ { lang_ld_feature ($3); }
;
input_list:
Index: ld/ldlex.l
===================================================================
RCS file: /cvs/src/src/ld/ldlex.l,v
retrieving revision 1.48
diff -u -p -r1.48 ldlex.l
--- ld/ldlex.l 15 Dec 2010 14:56:37 -0000 1.48
+++ ld/ldlex.l 13 Jan 2011 13:14:06 -0000
@@ -241,6 +241,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([
<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
<BOTH,SCRIPT>"REGION_ALIAS" { RTOKEN(REGION_ALIAS);}
+<BOTH,SCRIPT>"LD_FEATURE" { RTOKEN(LD_FEATURE);}
<BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
Index: ld/ldemul.c
===================================================================
RCS file: /cvs/src/src/ld/ldemul.c,v
retrieving revision 1.35
diff -u -p -r1.35 ldemul.c
--- ld/ldemul.c 20 Dec 2010 13:00:13 -0000 1.35
+++ ld/ldemul.c 13 Jan 2011 13:14:00 -0000
@@ -226,16 +226,6 @@ after_parse_default (void)
void
after_open_default (void)
{
- struct bfd_link_hash_entry *h;
-
- h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
- &link_info,
- "__ld_compatibility",
- FALSE, FALSE, TRUE);
- if (h != NULL
- && (h->type == bfd_link_hash_defined
- || h->type == bfd_link_hash_defweak))
- ld_compatibility = h->u.def.value;
}
void
Index: ld/ldexp.h
===================================================================
RCS file: /cvs/src/src/ld/ldexp.h,v
retrieving revision 1.27
diff -u -p -r1.27 ldexp.h
--- ld/ldexp.h 13 Jan 2011 13:06:22 -0000 1.27
+++ ld/ldexp.h 13 Jan 2011 13:14:00 -0000
@@ -132,8 +132,6 @@ struct ldexp_control {
/* Working results. */
etree_value_type result;
bfd_vma dot;
- /* Set if an expression contains DEFINED(). */
- bfd_boolean uses_defined;
/* Current dot and section passed to ldexp folder. */
bfd_vma *dotp;
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.91
diff -u -p -r1.91 ldexp.c
--- ld/ldexp.c 13 Jan 2011 13:06:22 -0000 1.91
+++ ld/ldexp.c 13 Jan 2011 13:14:00 -0000
@@ -512,7 +512,6 @@ fold_name (etree_type *tree)
break;
case DEFINED:
- expld.uses_defined = TRUE;
if (expld.phase == lang_first_phase_enum)
lang_track_definedness (tree->name.name);
else
@@ -564,7 +563,7 @@ fold_name (etree_type *tree)
}
else if (output_section == bfd_abs_section_ptr
&& (expld.section != bfd_abs_section_ptr
- || ld_compatibility >= 221))
+ || config.sane_expr))
new_number (h->u.def.value + h->u.def.section->output_offset);
else
new_rel (h->u.def.value + h->u.def.section->output_offset,
@@ -712,7 +711,7 @@ exp_fold_tree_1 (etree_type *tree)
{
case etree_value:
if (expld.section == bfd_abs_section_ptr
- && ld_compatibility < 221)
+ && !config.sane_expr)
new_abs (tree->value.value);
else
new_number (tree->value.value);
@@ -819,7 +818,8 @@ exp_fold_tree_1 (etree_type *tree)
exp_fold_tree_1 (tree->assign.src);
if (expld.result.valid_p
|| (expld.phase == lang_first_phase_enum
- && !expld.uses_defined))
+ && tree->type.node_class == etree_assign
+ && tree->assign.hidden))
{
if (h == NULL)
{
@@ -883,7 +883,6 @@ exp_fold_tree (etree_type *tree, asectio
expld.dot = *dotp;
expld.dotp = dotp;
expld.section = current_section;
- expld.uses_defined = FALSE;
exp_fold_tree_1 (tree);
}
@@ -893,7 +892,6 @@ exp_fold_tree_no_dot (etree_type *tree)
expld.dot = 0;
expld.dotp = NULL;
expld.section = bfd_abs_section_ptr;
- expld.uses_defined = FALSE;
exp_fold_tree_1 (tree);
}
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.93
diff -u -p -r1.93 ldlang.h
--- ld/ldlang.h 20 Dec 2010 13:00:14 -0000 1.93
+++ ld/ldlang.h 13 Jan 2011 13:14:03 -0000
@@ -469,7 +469,6 @@ extern bfd_boolean entry_from_cmdline;
extern lang_statement_list_type file_chain;
extern lang_statement_list_type input_file_chain;
-extern int ld_compatibility;
extern int lang_statement_iteration;
extern bfd_boolean missing_file;
@@ -651,4 +650,7 @@ extern bfd_boolean
ldlang_override_segment_assignment
(struct bfd_link_info *, bfd *, asection *, asection *, bfd_boolean);
+extern void
+lang_ld_feature (char *);
+
#endif
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.358
diff -u -p -r1.358 ldlang.c
--- ld/ldlang.c 13 Jan 2011 13:06:22 -0000 1.358
+++ ld/ldlang.c 13 Jan 2011 13:14:03 -0000
@@ -108,7 +108,6 @@ bfd_boolean delete_output_file_on_failur
struct lang_phdr *lang_phdr_list;
struct lang_nocrossrefs *nocrossref_list;
bfd_boolean missing_file = FALSE;
-int ld_compatibility;
/* Functions that traverse the linker script and might evaluate
DEFINED() need to increment this. */
@@ -3250,7 +3249,9 @@ open_input_bfds (lang_statement_union_ty
}
break;
case lang_assignment_statement_enum:
- exp_fold_tree_no_dot (s->assignment_statement.exp);
+ if (s->assignment_statement.exp->assign.hidden)
+ /* This is from a --defsym on the command line. */
+ exp_fold_tree_no_dot (s->assignment_statement.exp);
break;
default:
break;
@@ -7845,3 +7846,32 @@ lang_append_dynamic_list_cpp_new (void)
lang_append_dynamic_list (dynamic);
}
+
+/* Scan a space and/or comma separated string of features. */
+
+void
+lang_ld_feature (char *str)
+{
+ char *p, *q;
+
+ p = str;
+ while (*p)
+ {
+ char sep;
+ while (*p == ',' || ISSPACE (*p))
+ ++p;
+ if (!*p)
+ break;
+ q = p + 1;
+ while (*q && *q != ',' && !ISSPACE (*q))
+ ++q;
+ sep = *q;
+ *q = 0;
+ if (strcasecmp (p, "SANE_EXPR") == 0)
+ config.sane_expr = TRUE;
+ else
+ einfo (_("%X%P: unknown feature `%s'\n"), p);
+ *q = sep;
+ p = q;
+ }
+}
--
Alan Modra
Australia Development Lab, IBM