From 01554a74b59e63cc487533b71d94a7606b76a871 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 13 Jan 2011 13:29:55 +0000 Subject: [PATCH] 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. --- ld/ChangeLog | 18 ++++++++++++++++++ ld/ld.h | 4 ++++ ld/ld.texinfo | 17 ++++++++++++----- ld/ldemul.c | 10 ---------- ld/ldexp.c | 10 ++++------ ld/ldexp.h | 2 -- ld/ldgram.y | 3 +++ ld/ldlang.c | 34 ++++++++++++++++++++++++++++++++-- ld/ldlang.h | 4 +++- ld/ldlex.l | 1 + 10 files changed, 77 insertions(+), 26 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index a6a49f3168c..8ba97a661a9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,23 @@ 2011-01-13 Alan Modra + 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. diff --git a/ld/ld.h b/ld/ld.h index 21323d89f61..22fef483b87 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 d4419aa5b50..51569b11946 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 3c07ceb364d..f1f3979578a 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 326a0aa1f20..b7dc171b85b 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 2fdb7daeb55..6d98e756fdd 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 49d212b170b..3795ffeb8f0 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 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 2bae4abc6ed..c2a768ece39 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 5850fcb31e6..9d4d41f4431 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 7560ca21492..397a5c6903f 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -241,6 +241,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* ";" { RTOKEN(';');} "MEMORY" { RTOKEN(MEMORY);} "REGION_ALIAS" { RTOKEN(REGION_ALIAS);} +"LD_FEATURE" { RTOKEN(LD_FEATURE);} "ORIGIN" { RTOKEN(ORIGIN);} "VERSION" { RTOKEN(VERSIONK);} "BLOCK" { RTOKEN(BLOCK);} -- 2.30.2