mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-06 07:28:44 +08:00
* ldexp.c (fold_name): In case NAME, permit an absolute symbol
in lang_allocating_phase_enum. PR 6259.
This commit is contained in:
11
ld/ChangeLog
11
ld/ChangeLog
@ -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
|
||||||
|
210
ld/ldexp.c
210
ld/ldexp.c
@ -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.
|
||||||
@ -215,72 +215,99 @@ static etree_value_type
|
|||||||
fold_binary (tree, current_section, allocation_done, dot, dotp)
|
fold_binary (tree, current_section, allocation_done, dot, dotp)
|
||||||
etree_type *tree;
|
etree_type *tree;
|
||||||
lang_output_section_statement_type *current_section;
|
lang_output_section_statement_type *current_section;
|
||||||
lang_phase_type allocation_done;
|
lang_phase_type allocation_done;
|
||||||
bfd_vma dot;
|
bfd_vma dot;
|
||||||
bfd_vma *dotp;
|
bfd_vma *dotp;
|
||||||
{
|
{
|
||||||
etree_value_type result;
|
etree_value_type result;
|
||||||
|
|
||||||
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;
|
{
|
||||||
other = exp_fold_tree(tree->binary.rhs,
|
etree_value_type other;
|
||||||
current_section,
|
|
||||||
allocation_done, dot,dotp) ;
|
|
||||||
if (other.valid) {
|
|
||||||
/* If values are from different sections, or this is an */
|
|
||||||
/* absolute expression, make both source args absolute */
|
|
||||||
if (result.section != other.section ||
|
|
||||||
current_section == abs_output_section)
|
|
||||||
{
|
|
||||||
make_abs(&result);
|
|
||||||
make_abs(&other);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tree->type.node_code)
|
other = exp_fold_tree (tree->binary.rhs,
|
||||||
|
current_section,
|
||||||
|
allocation_done, dot,dotp) ;
|
||||||
|
if (other.valid)
|
||||||
{
|
{
|
||||||
case '%':
|
/* If the values are from different sections, or this is an
|
||||||
/* Mod, both absolule*/
|
absolute expression, make both the source arguments
|
||||||
|
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 (other.value == 0) {
|
/* If there is only one absolute term, make sure it is the
|
||||||
einfo("%F%S %% by zero\n");
|
second one. */
|
||||||
}
|
if (result.section == abs_output_section)
|
||||||
result.value = (int)result.value % (int)other.value;
|
{
|
||||||
break;
|
hold = result;
|
||||||
case '/':
|
result = other;
|
||||||
if (other.value == 0) {
|
other = hold;
|
||||||
einfo("%F%S / by zero\n");
|
}
|
||||||
}
|
}
|
||||||
result.value = (int)result.value / (int) other.value;
|
else if (result.section != other.section
|
||||||
break;
|
|| current_section == abs_output_section)
|
||||||
#define BOP(x,y) case x : result.value = result.value y other.value;break;
|
{
|
||||||
BOP('+',+);
|
make_abs(&result);
|
||||||
BOP('*',*);
|
make_abs(&other);
|
||||||
BOP('-',-);
|
}
|
||||||
BOP(LSHIFT,<<);
|
|
||||||
BOP(RSHIFT,>>);
|
switch (tree->type.node_code)
|
||||||
BOP(EQ,==);
|
{
|
||||||
BOP(NE,!=);
|
case '%':
|
||||||
BOP('<',<);
|
if (other.value == 0)
|
||||||
BOP('>',>);
|
einfo ("%F%S %% by zero\n");
|
||||||
BOP(LE,<=);
|
result.value = ((bfd_signed_vma) result.value
|
||||||
BOP(GE,>=);
|
% (bfd_signed_vma) other.value);
|
||||||
BOP('&',&);
|
break;
|
||||||
BOP('^',^);
|
|
||||||
BOP('|',|);
|
case '/':
|
||||||
BOP(ANDAND,&&);
|
if (other.value == 0)
|
||||||
BOP(OROR,||);
|
einfo ("%F%S / by zero\n");
|
||||||
default:
|
result.value = ((bfd_signed_vma) result.value
|
||||||
FAIL();
|
/ (bfd_signed_vma) other.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#define BOP(x,y) case x : result.value = result.value y other.value; break;
|
||||||
|
BOP('+',+);
|
||||||
|
BOP('*',*);
|
||||||
|
BOP('-',-);
|
||||||
|
BOP(LSHIFT,<<);
|
||||||
|
BOP(RSHIFT,>>);
|
||||||
|
BOP(EQ,==);
|
||||||
|
BOP(NE,!=);
|
||||||
|
BOP('<',<);
|
||||||
|
BOP('>',>);
|
||||||
|
BOP(LE,<=);
|
||||||
|
BOP(GE,>=);
|
||||||
|
BOP('&',&);
|
||||||
|
BOP('^',^);
|
||||||
|
BOP('|',|);
|
||||||
|
BOP(ANDAND,&&);
|
||||||
|
BOP(OROR,||);
|
||||||
|
|
||||||
|
default:
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
result.valid = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
etree_value_type
|
etree_value_type
|
||||||
invalid ()
|
invalid ()
|
||||||
{
|
{
|
||||||
@ -312,17 +339,20 @@ fold_name (tree, current_section, allocation_done, dot)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEFINED:
|
case DEFINED:
|
||||||
{
|
if (allocation_done == lang_first_phase_enum)
|
||||||
struct bfd_link_hash_entry *h;
|
result.valid = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
||||||
result.value = (h != (struct bfd_link_hash_entry *) NULL
|
result.value = (h != (struct bfd_link_hash_entry *) NULL
|
||||||
&& (h->type == bfd_link_hash_defined
|
&& (h->type == bfd_link_hash_defined
|
||||||
|| h->type == bfd_link_hash_common));
|
|| h->type == bfd_link_hash_common));
|
||||||
result.section = 0;
|
result.section = 0;
|
||||||
result.valid = true;
|
result.valid = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NAME:
|
case NAME:
|
||||||
result.valid = false;
|
result.valid = false;
|
||||||
@ -333,29 +363,33 @@ 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)
|
|
||||||
{
|
{
|
||||||
lang_output_section_statement_type *os;
|
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;
|
||||||
|
|
||||||
os = (lang_output_section_statement_lookup
|
os = (lang_output_section_statement_lookup
|
||||||
(h->u.def.section->output_section->name));
|
(h->u.def.section->output_section->name));
|
||||||
|
|
||||||
/* FIXME: Is this correct if this section is being
|
/* FIXME: Is this correct if this section is being
|
||||||
linked with -R? */
|
linked with -R? */
|
||||||
result = new_rel ((h->u.def.value
|
result = new_rel ((h->u.def.value
|
||||||
+ 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);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user