PR24008, Wrong value of ternary expression in map file
PR 24008 * ldexp.h (lang_phase_type): Add lang_fixed_phase_enum. * ldexp.c (fold_name): Move expld.assign_name check later to avoid an extra lookup. (exp_fold_tree_1): When lang_fixed_phase_enum, don't change symbol values, and don't clear expld.assign_name. * ldlang.c (lang_map): Set expld.phase to lang_fixed_phase_enum. (print_assignment): Resolve entire assignment expression. Don't access symbol u.def unless symbol is defined.
This commit is contained in:
parent
e044973b0c
commit
6a84624340
12
ld/ChangeLog
12
ld/ChangeLog
@ -1,3 +1,15 @@
|
||||
2019-01-28 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 24008
|
||||
* ldexp.h (lang_phase_type): Add lang_fixed_phase_enum.
|
||||
* ldexp.c (fold_name): Move expld.assign_name check later to
|
||||
avoid an extra lookup.
|
||||
(exp_fold_tree_1): When lang_fixed_phase_enum, don't change symbol
|
||||
values, and don't clear expld.assign_name.
|
||||
* ldlang.c (lang_map): Set expld.phase to lang_fixed_phase_enum.
|
||||
(print_assignment): Resolve entire assignment expression.
|
||||
Don't access symbol u.def unless symbol is defined.
|
||||
|
||||
2019-01-25 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* po/bg.po: Updated Bulgarian translation.
|
||||
|
82
ld/ldexp.c
82
ld/ldexp.c
@ -720,23 +720,6 @@ fold_name (etree_type *tree)
|
||||
break;
|
||||
|
||||
case NAME:
|
||||
if (expld.assign_name != NULL
|
||||
&& strcmp (expld.assign_name, tree->name.name) == 0)
|
||||
{
|
||||
/* Self-assignment is only allowed for absolute symbols
|
||||
defined in a linker script. */
|
||||
h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
|
||||
&link_info,
|
||||
tree->name.name,
|
||||
FALSE, FALSE, TRUE);
|
||||
if (!(h != NULL
|
||||
&& (h->type == bfd_link_hash_defined
|
||||
|| h->type == bfd_link_hash_defweak)
|
||||
&& h->u.def.section == bfd_abs_section_ptr
|
||||
&& (def = symbol_defined (tree->name.name)) != NULL
|
||||
&& def->iteration == (lang_statement_iteration & 255)))
|
||||
expld.assign_name = NULL;
|
||||
}
|
||||
if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
|
||||
new_rel_from_abs (expld.dot);
|
||||
else
|
||||
@ -787,6 +770,18 @@ fold_name (etree_type *tree)
|
||||
expld.assign_src = h;
|
||||
else
|
||||
expld.assign_src = (struct bfd_link_hash_entry *) - 1;
|
||||
|
||||
/* Self-assignment is only allowed for absolute symbols
|
||||
defined in a linker script. */
|
||||
if (expld.assign_name != NULL
|
||||
&& strcmp (expld.assign_name, tree->name.name) == 0
|
||||
&& !(h != NULL
|
||||
&& (h->type == bfd_link_hash_defined
|
||||
|| h->type == bfd_link_hash_defweak)
|
||||
&& h->u.def.section == bfd_abs_section_ptr
|
||||
&& (def = symbol_defined (tree->name.name)) != NULL
|
||||
&& def->iteration == (lang_statement_iteration & 255)))
|
||||
expld.assign_name = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1158,7 +1153,8 @@ exp_fold_tree_1 (etree_type *tree)
|
||||
converted to absolute values, as is required by many
|
||||
expressions, until final section sizing is complete. */
|
||||
if (expld.phase == lang_final_phase_enum
|
||||
|| expld.assign_name != NULL)
|
||||
|| expld.phase == lang_fixed_phase_enum
|
||||
|| expld.assign_name != NULL)
|
||||
{
|
||||
if (tree->type.node_class == etree_provide)
|
||||
tree->type.node_class = etree_provided;
|
||||
@ -1199,28 +1195,40 @@ exp_fold_tree_1 (etree_type *tree)
|
||||
(&link_info, h, link_info.output_bfd,
|
||||
expld.result.section, expld.result.value);
|
||||
}
|
||||
h->type = bfd_link_hash_defined;
|
||||
h->u.def.value = expld.result.value;
|
||||
h->u.def.section = expld.result.section;
|
||||
h->linker_def = ! tree->assign.type.lineno;
|
||||
h->ldscript_def = 1;
|
||||
h->rel_from_abs = expld.rel_from_abs;
|
||||
if (tree->assign.hidden)
|
||||
bfd_link_hide_symbol (link_info.output_bfd,
|
||||
&link_info, h);
|
||||
if (expld.phase == lang_fixed_phase_enum)
|
||||
{
|
||||
if (h->type == bfd_link_hash_defined)
|
||||
{
|
||||
expld.result.value = h->u.def.value;
|
||||
expld.result.section = h->u.def.section;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
h->type = bfd_link_hash_defined;
|
||||
h->u.def.value = expld.result.value;
|
||||
h->u.def.section = expld.result.section;
|
||||
h->linker_def = ! tree->assign.type.lineno;
|
||||
h->ldscript_def = 1;
|
||||
h->rel_from_abs = expld.rel_from_abs;
|
||||
if (tree->assign.hidden)
|
||||
bfd_link_hide_symbol (link_info.output_bfd,
|
||||
&link_info, h);
|
||||
|
||||
/* Copy the symbol type if this is an expression only
|
||||
referencing a single symbol. (If the expression
|
||||
contains ternary conditions, ignoring symbols on
|
||||
false branches.) */
|
||||
if (expld.assign_src != NULL
|
||||
&& (expld.assign_src
|
||||
!= (struct bfd_link_hash_entry *) -1))
|
||||
bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
|
||||
expld.assign_src);
|
||||
/* Copy the symbol type if this is an expression only
|
||||
referencing a single symbol. (If the expression
|
||||
contains ternary conditions, ignoring symbols on
|
||||
false branches.) */
|
||||
if (expld.assign_src != NULL
|
||||
&& (expld.assign_src
|
||||
!= (struct bfd_link_hash_entry *) -1))
|
||||
bfd_copy_link_hash_symbol_type (link_info.output_bfd,
|
||||
h, expld.assign_src);
|
||||
}
|
||||
}
|
||||
}
|
||||
expld.assign_name = NULL;
|
||||
if (expld.phase != lang_fixed_phase_enum)
|
||||
expld.assign_name = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -106,7 +106,9 @@ typedef enum
|
||||
/* During assignment of symbol values when relaxation in progress. */
|
||||
lang_assigning_phase_enum,
|
||||
/* Final assignment of symbol values. */
|
||||
lang_final_phase_enum
|
||||
lang_final_phase_enum,
|
||||
/* Run after symbol values have been fixed, for lang_map. */
|
||||
lang_fixed_phase_enum
|
||||
} lang_phase_type;
|
||||
|
||||
union lang_statement_union;
|
||||
|
@ -2315,6 +2315,7 @@ lang_map (void)
|
||||
obstack_begin (&map_obstack, 1000);
|
||||
bfd_link_hash_traverse (link_info.hash, sort_def_symbol, 0);
|
||||
}
|
||||
expld.phase = lang_fixed_phase_enum;
|
||||
lang_statement_iteration++;
|
||||
print_statements ();
|
||||
|
||||
@ -4244,9 +4245,7 @@ print_assignment (lang_assignment_statement_type *assignment,
|
||||
const char *dst = assignment->exp->assign.dst;
|
||||
|
||||
is_dot = (dst[0] == '.' && dst[1] == 0);
|
||||
if (!is_dot)
|
||||
expld.assign_name = dst;
|
||||
tree = assignment->exp->assign.src;
|
||||
tree = assignment->exp;
|
||||
}
|
||||
|
||||
osec = output_section->bfd_section;
|
||||
@ -4281,7 +4280,9 @@ print_assignment (lang_assignment_statement_type *assignment,
|
||||
|
||||
h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst,
|
||||
FALSE, FALSE, TRUE);
|
||||
if (h)
|
||||
if (h != NULL
|
||||
&& (h->type == bfd_link_hash_defined
|
||||
|| h->type == bfd_link_hash_defweak))
|
||||
{
|
||||
value = h->u.def.value;
|
||||
value += h->u.def.section->output_section->vma;
|
||||
|
Loading…
Reference in New Issue
Block a user