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> 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 PR ld/12356
* ldexp.h (exp_assop): Delete. * ldexp.h (exp_assop): Delete.
(exp_assign, exp_defsym): Declare. (exp_assign, exp_defsym): Declare.

View file

@ -292,6 +292,10 @@ typedef struct {
on the command line. */ on the command line. */
bfd_boolean only_cmd_line_lib_dirs; 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 ':'. */ /* The rpath separation character. Usually ':'. */
char rpath_separator; 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 architecture of an object file by using the @code{objdump} program with
the @samp{-f} option. the @samp{-f} option.
@end ifclear @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 @end table
@node Assignments @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 address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and
@code{SEGMENT_START}. Other terms are simply numbers, or are builtin @code{SEGMENT_START}. Other terms are simply numbers, or are builtin
functions that return a non-address value, such as @code{LENGTH}. functions that return a non-address value, such as @code{LENGTH}.
One complication is that unless you assign @code{__ld_compatibility} One complication is that unless you set @code{LD_FEATURE ("SANE_EXPR")}
a value of 221 or larger, numbers and absolute symbols are treated (@pxref{Miscellaneous Commands}), numbers and absolute symbols are treated
differently depending on their location, for compatibility with older differently depending on their location, for compatibility with older
versions of @code{ld}. Expressions appearing outside an output versions of @code{ld}. Expressions appearing outside an output
section definition treat all numbers as absolute addresses. section definition treat all numbers as absolute addresses.
Expressions appearing inside an output section definition treat Expressions appearing inside an output section definition treat
absolute symbols as numbers. If @code{__ld_compatibility} is assigned absolute symbols as numbers. If @code{LD_FEATURE ("SANE_EXPR")} is
a value larger than 221, then absolute symbols and numbers are simply given, then absolute symbols and numbers are simply treated as numbers
treated as numbers everywhere. everywhere.
In the following simple example, In the following simple example,

View file

@ -226,16 +226,6 @@ after_parse_default (void)
void void
after_open_default (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 void

View file

@ -512,7 +512,6 @@ fold_name (etree_type *tree)
break; break;
case DEFINED: case DEFINED:
expld.uses_defined = TRUE;
if (expld.phase == lang_first_phase_enum) if (expld.phase == lang_first_phase_enum)
lang_track_definedness (tree->name.name); lang_track_definedness (tree->name.name);
else else
@ -564,7 +563,7 @@ fold_name (etree_type *tree)
} }
else if (output_section == bfd_abs_section_ptr else if (output_section == bfd_abs_section_ptr
&& (expld.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); new_number (h->u.def.value + h->u.def.section->output_offset);
else else
new_rel (h->u.def.value + h->u.def.section->output_offset, 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: case etree_value:
if (expld.section == bfd_abs_section_ptr if (expld.section == bfd_abs_section_ptr
&& ld_compatibility < 221) && !config.sane_expr)
new_abs (tree->value.value); new_abs (tree->value.value);
else else
new_number (tree->value.value); new_number (tree->value.value);
@ -819,7 +818,8 @@ exp_fold_tree_1 (etree_type *tree)
exp_fold_tree_1 (tree->assign.src); exp_fold_tree_1 (tree->assign.src);
if (expld.result.valid_p if (expld.result.valid_p
|| (expld.phase == lang_first_phase_enum || (expld.phase == lang_first_phase_enum
&& !expld.uses_defined)) && tree->type.node_class == etree_assign
&& tree->assign.hidden))
{ {
if (h == NULL) if (h == NULL)
{ {
@ -883,7 +883,6 @@ exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp)
expld.dot = *dotp; expld.dot = *dotp;
expld.dotp = dotp; expld.dotp = dotp;
expld.section = current_section; expld.section = current_section;
expld.uses_defined = FALSE;
exp_fold_tree_1 (tree); exp_fold_tree_1 (tree);
} }
@ -893,7 +892,6 @@ exp_fold_tree_no_dot (etree_type *tree)
expld.dot = 0; expld.dot = 0;
expld.dotp = NULL; expld.dotp = NULL;
expld.section = bfd_abs_section_ptr; expld.section = bfd_abs_section_ptr;
expld.uses_defined = FALSE;
exp_fold_tree_1 (tree); exp_fold_tree_1 (tree);
} }

View file

@ -132,8 +132,6 @@ struct ldexp_control {
/* Working results. */ /* Working results. */
etree_value_type result; etree_value_type result;
bfd_vma dot; bfd_vma dot;
/* Set if an expression contains DEFINED(). */
bfd_boolean uses_defined;
/* Current dot and section passed to ldexp folder. */ /* Current dot and section passed to ldexp folder. */
bfd_vma *dotp; bfd_vma *dotp;

View file

@ -134,6 +134,7 @@ static int error_index;
%token INCLUDE %token INCLUDE
%token MEMORY %token MEMORY
%token REGION_ALIAS %token REGION_ALIAS
%token LD_FEATURE
%token NOLOAD DSECT COPY INFO OVERLAY %token NOLOAD DSECT COPY INFO OVERLAY
%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY %token DEFINED TARGET_K SEARCH_DIR MAP ENTRY
%token <integer> NEXT %token <integer> NEXT
@ -357,6 +358,8 @@ ifile_p1:
{ lang_add_insert ($3, 1); } { lang_add_insert ($3, 1); }
| REGION_ALIAS '(' NAME ',' NAME ')' | REGION_ALIAS '(' NAME ',' NAME ')'
{ lang_memory_region_alias ($3, $5); } { lang_memory_region_alias ($3, $5); }
| LD_FEATURE '(' NAME ')'
{ lang_ld_feature ($3); }
; ;
input_list: input_list:

View file

@ -108,7 +108,6 @@ bfd_boolean delete_output_file_on_failure = FALSE;
struct lang_phdr *lang_phdr_list; struct lang_phdr *lang_phdr_list;
struct lang_nocrossrefs *nocrossref_list; struct lang_nocrossrefs *nocrossref_list;
bfd_boolean missing_file = FALSE; bfd_boolean missing_file = FALSE;
int ld_compatibility;
/* Functions that traverse the linker script and might evaluate /* Functions that traverse the linker script and might evaluate
DEFINED() need to increment this. */ DEFINED() need to increment this. */
@ -3250,6 +3249,8 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
} }
break; break;
case lang_assignment_statement_enum: case lang_assignment_statement_enum:
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); exp_fold_tree_no_dot (s->assignment_statement.exp);
break; break;
default: default:
@ -7845,3 +7846,32 @@ lang_append_dynamic_list_cpp_new (void)
lang_append_dynamic_list (dynamic); 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 file_chain;
extern lang_statement_list_type input_file_chain; extern lang_statement_list_type input_file_chain;
extern int ld_compatibility;
extern int lang_statement_iteration; extern int lang_statement_iteration;
extern bfd_boolean missing_file; extern bfd_boolean missing_file;
@ -651,4 +650,7 @@ extern bfd_boolean
ldlang_override_segment_assignment ldlang_override_segment_assignment
(struct bfd_link_info *, bfd *, asection *, asection *, bfd_boolean); (struct bfd_link_info *, bfd *, asection *, asection *, bfd_boolean);
extern void
lang_ld_feature (char *);
#endif #endif

View file

@ -241,6 +241,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');} <BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);} <BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
<BOTH,SCRIPT>"REGION_ALIAS" { RTOKEN(REGION_ALIAS);} <BOTH,SCRIPT>"REGION_ALIAS" { RTOKEN(REGION_ALIAS);}
<BOTH,SCRIPT>"LD_FEATURE" { RTOKEN(LD_FEATURE);}
<BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);} <BOTH,SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN);}
<BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);} <BOTH,SCRIPT>"VERSION" { RTOKEN(VERSIONK);}
<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);} <EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}