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.
This commit is contained in:
Alan Modra 2011-01-13 13:29:55 +00:00
parent 2e57b2afce
commit 01554a74b5
10 changed files with 77 additions and 26 deletions

View file

@ -1,5 +1,23 @@
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.

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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:

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);}