aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog18
-rw-r--r--ld/ld.h4
-rw-r--r--ld/ld.texinfo17
-rw-r--r--ld/ldemul.c10
-rw-r--r--ld/ldexp.c10
-rw-r--r--ld/ldexp.h2
-rw-r--r--ld/ldgram.y3
-rw-r--r--ld/ldlang.c34
-rw-r--r--ld/ldlang.h4
-rw-r--r--ld/ldlex.l1
10 files changed, 77 insertions, 26 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a6a49f3..8ba97a6 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,6 +1,24 @@
2011-01-13 Alan Modra <amodra@gmail.com>
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.
+
+ PR ld/12356
* ldexp.h (exp_assop): Delete.
(exp_assign, exp_defsym): Declare.
* ldexp.c (exp_assop): Make static, handle all assignment variations.
diff --git a/ld/ld.h b/ld/ld.h
index 21323d8..22fef48 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -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;
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index d4419aa..51569b1 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -3344,6 +3344,13 @@ of the names used by the BFD library (@pxref{BFD}). You can see the
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 functions that return an
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,
diff --git a/ld/ldemul.c b/ld/ldemul.c
index 3c07ceb..f1f3979 100644
--- a/ld/ldemul.c
+++ b/ld/ldemul.c
@@ -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
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 326a0aa..b7dc171 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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, asection *current_section, bfd_vma *dotp)
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);
}
diff --git a/ld/ldexp.h b/ld/ldexp.h
index 2fdb7da..6d98e75 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -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;
diff --git a/ld/ldgram.y b/ld/ldgram.y
index 49d212b..3795ffe 100644
--- a/ld/ldgram.y
+++ b/ld/ldgram.y
@@ -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:
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 2bae4ab..c2a768e 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -108,7 +108,6 @@ bfd_boolean delete_output_file_on_failure = FALSE;
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_type *s, bfd_boolean force)
}
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;
+ }
+}
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 5850fcb..9d4d41f 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -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
diff --git a/ld/ldlex.l b/ld/ldlex.l
index 7560ca2..397a5c6 100644
--- a/ld/ldlex.l
+++ b/ld/ldlex.l
@@ -241,6 +241,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<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);}