* ldexp.c (fold_name): In case NAME, permit an absolute symbol

in lang_allocating_phase_enum.
PR 6259.
This commit is contained in:
Ian Lance Taylor
1995-01-31 17:40:50 +00:00
parent 3e46110757
commit 1abb243d51
2 changed files with 145 additions and 80 deletions

View File

@ -1,3 +1,14 @@
Tue Jan 31 12:37:09 1995 Ian Lance Taylor <ian@cygnus.com>
* ldexp.c (fold_name): In case NAME, permit an absolute symbol
in lang_allocating_phase_enum.
Mon Jan 30 11:33:25 1995 Ian Lance Taylor <ian@cygnus.com>
* Makefile.in (distclean): Depend upon clean. Don't bother to
remove files which will be removed by clean. From patch by
alan@SPRI.Levels.UniSA.Edu.Au (Alan Modra).
Fri Jan 27 16:27:34 1995 Ian Lance Taylor <ian@cygnus.com> Fri Jan 27 16:27:34 1995 Ian Lance Taylor <ian@cygnus.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): For * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): For

View File

@ -1,5 +1,5 @@
/* This module handles expression trees. /* This module handles expression trees.
Copyright (C) 1991, 1993 Free Software Foundation, Inc. Copyright (C) 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com). Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
This file is part of GLD, the Gnu Linker. This file is part of GLD, the Gnu Linker.
@ -223,16 +223,39 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
result = exp_fold_tree (tree->binary.lhs, current_section, result = exp_fold_tree (tree->binary.lhs, current_section,
allocation_done, dot, dotp); allocation_done, dot, dotp);
if (result.valid) { if (result.valid)
{
etree_value_type other; etree_value_type other;
other = exp_fold_tree (tree->binary.rhs, other = exp_fold_tree (tree->binary.rhs,
current_section, current_section,
allocation_done, dot,dotp) ; allocation_done, dot,dotp) ;
if (other.valid) { if (other.valid)
/* If values are from different sections, or this is an */ {
/* absolute expression, make both source args absolute */ /* If the values are from different sections, or this is an
if (result.section != other.section || absolute expression, make both the source arguments
current_section == abs_output_section) absolute. However, adding or subtracting an absolute
value from a relative value is meaningful, and is an
exception. */
if (current_section != abs_output_section
&& (result.section == abs_output_section
|| other.section == abs_output_section)
&& (tree->type.node_code == '+'
|| tree->type.node_code == '-'))
{
etree_value_type hold;
/* If there is only one absolute term, make sure it is the
second one. */
if (result.section == abs_output_section)
{
hold = result;
result = other;
other = hold;
}
}
else if (result.section != other.section
|| current_section == abs_output_section)
{ {
make_abs(&result); make_abs(&result);
make_abs(&other); make_abs(&other);
@ -241,19 +264,19 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
switch (tree->type.node_code) switch (tree->type.node_code)
{ {
case '%': case '%':
/* Mod, both absolule*/ if (other.value == 0)
if (other.value == 0) {
einfo ("%F%S %% by zero\n"); einfo ("%F%S %% by zero\n");
} result.value = ((bfd_signed_vma) result.value
result.value = (int)result.value % (int)other.value; % (bfd_signed_vma) other.value);
break; break;
case '/': case '/':
if (other.value == 0) { if (other.value == 0)
einfo ("%F%S / by zero\n"); einfo ("%F%S / by zero\n");
} result.value = ((bfd_signed_vma) result.value
result.value = (int)result.value / (int) other.value; / (bfd_signed_vma) other.value);
break; break;
#define BOP(x,y) case x : result.value = result.value y other.value; break; #define BOP(x,y) case x : result.value = result.value y other.value; break;
BOP('+',+); BOP('+',+);
BOP('*',*); BOP('*',*);
@ -271,16 +294,20 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
BOP('|',|); BOP('|',|);
BOP(ANDAND,&&); BOP(ANDAND,&&);
BOP(OROR,||); BOP(OROR,||);
default: default:
FAIL(); FAIL();
} }
} }
else { else
{
result.valid = false; result.valid = false;
} }
} }
return result; return result;
} }
etree_value_type etree_value_type
invalid () invalid ()
{ {
@ -312,6 +339,9 @@ fold_name (tree, current_section, allocation_done, dot)
} }
break; break;
case DEFINED: case DEFINED:
if (allocation_done == lang_first_phase_enum)
result.valid = false;
else
{ {
struct bfd_link_hash_entry *h; struct bfd_link_hash_entry *h;
@ -333,14 +363,17 @@ fold_name (tree, current_section, allocation_done, dot)
else else
result = invalid(); result = invalid();
} }
else if (allocation_done == lang_final_phase_enum) else if (allocation_done != lang_first_phase_enum)
{ {
struct bfd_link_hash_entry *h; struct bfd_link_hash_entry *h;
h = bfd_link_hash_lookup (link_info.hash, tree->name.name, h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
false, false, true); false, false, true);
if (h != (struct bfd_link_hash_entry *) NULL if (h != NULL && h->type == bfd_link_hash_defined)
&& h->type == bfd_link_hash_defined) {
if (bfd_is_abs_section (h->u.def.section))
result = new_abs (h->u.def.value);
else if (allocation_done == lang_final_phase_enum)
{ {
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
@ -353,7 +386,8 @@ fold_name (tree, current_section, allocation_done, dot)
+ h->u.def.section->output_offset), + h->u.def.section->output_offset),
os); os);
} }
if (result.valid == false) }
else if (allocation_done == lang_final_phase_enum)
einfo ("%F%S: undefined symbol `%s' referenced in expression\n", einfo ("%F%S: undefined symbol `%s' referenced in expression\n",
tree->name.name); tree->name.name);
} }
@ -852,3 +886,23 @@ exp_get_value_int (tree,def,name, allocation_done)
return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done); return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
} }
int
exp_get_abs_int (tree, def, name, allocation_done)
etree_type *tree;
int def;
char *name;
lang_phase_type allocation_done;
{
etree_value_type res;
res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
if (res.valid)
{
res.value += res.section->bfd_section->vma;
}
else {
einfo ("%F%S non constant expression for %s\n",name);
}
return res.value;
}