diff options
-rw-r--r-- | ld/ChangeLog | 18 | ||||
-rw-r--r-- | ld/ld.h | 4 | ||||
-rw-r--r-- | ld/ld.texinfo | 17 | ||||
-rw-r--r-- | ld/ldemul.c | 10 | ||||
-rw-r--r-- | ld/ldexp.c | 10 | ||||
-rw-r--r-- | ld/ldexp.h | 2 | ||||
-rw-r--r-- | ld/ldgram.y | 3 | ||||
-rw-r--r-- | ld/ldlang.c | 34 | ||||
-rw-r--r-- | ld/ldlang.h | 4 | ||||
-rw-r--r-- | ld/ldlex.l | 1 |
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. @@ -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 @@ -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); } @@ -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 @@ -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);} |