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:
parent
2e57b2afce
commit
01554a74b5
10 changed files with 77 additions and 26 deletions
18
ld/ChangeLog
18
ld/ChangeLog
|
@ -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.
|
||||||
|
|
4
ld/ld.h
4
ld/ld.h
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
10
ld/ldemul.c
10
ld/ldemul.c
|
@ -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
|
||||||
|
|
10
ld/ldexp.c
10
ld/ldexp.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
34
ld/ldlang.c
34
ld/ldlang.c
|
@ -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,7 +3249,9 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case lang_assignment_statement_enum:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue