Browse Source

2000-10-03 Kazu Hirata <kazu@hxi.com>

* ldexp.c: Fix formatting.
binutils-2_11-branch
Kazu Hirata 26 years ago
parent
commit
8c95a62eae
  1. 4
      ld/ChangeLog
  2. 666
      ld/ldexp.c

4
ld/ChangeLog

@ -1,3 +1,7 @@
2000-10-03 Kazu Hirata <kazu@hxi.com>
* ldexp.c: Fix formatting.
2000-10-02 DJ Delorie <dj@redhat.com>
* emultempl/pe.em (gld_*_after_open): detect case where there two

666
ld/ldexp.c

@ -1,7 +1,7 @@
/* This module handles expression trees.
Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
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.
@ -20,14 +20,12 @@ along with GLD; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/*
This module is in charge of working out the contents of expressions.
/* This module is in charge of working out the contents of expressions.
It has to keep track of the relative/absness of a symbol etc. This is
done by keeping all values in a struct (an etree_value_type) which
contains a value, a section to which it is relative and a valid bit.
*/
It has to keep track of the relative/absness of a symbol etc. This
is done by keeping all values in a struct (an etree_value_type)
which contains a value, a section to which it is relative and a
valid bit. */
#include "bfd.h"
#include "sysdep.h"
@ -69,70 +67,71 @@ exp_print_token (code)
token_code_type code;
{
static CONST struct
{
token_code_type code;
char *name;
} table[] =
{
{ INT, "int" },
{ REL, "relocateable" },
{ NAME,"NAME" },
{ PLUSEQ,"+=" },
{ MINUSEQ,"-=" },
{ MULTEQ,"*=" },
{ DIVEQ,"/=" },
{ LSHIFTEQ,"<<=" },
{ RSHIFTEQ,">>=" },
{ ANDEQ,"&=" },
{ OREQ,"|=" },
{ OROR,"||" },
{ ANDAND,"&&" },
{ EQ,"==" },
{ NE,"!=" },
{ LE,"<=" },
{ GE,">=" },
{ LSHIFT,"<<" },
{ RSHIFT,">>=" },
{ ALIGN_K,"ALIGN" },
{ BLOCK,"BLOCK" },
{ SECTIONS,"SECTIONS" },
{ SIZEOF_HEADERS,"SIZEOF_HEADERS" },
{ NEXT,"NEXT" },
{ SIZEOF,"SIZEOF" },
{ ADDR,"ADDR" },
{ LOADADDR,"LOADADDR" },
{ MEMORY,"MEMORY" },
{ DEFINED,"DEFINED" },
{ TARGET_K,"TARGET" },
{ SEARCH_DIR,"SEARCH_DIR" },
{ MAP,"MAP" },
{ QUAD,"QUAD" },
{ SQUAD,"SQUAD" },
{ LONG,"LONG" },
{ SHORT,"SHORT" },
{ BYTE,"BYTE" },
{ ENTRY,"ENTRY" },
{ 0,(char *)NULL }
};
{
token_code_type code;
char *name;
} table[] = {
{ INT, "int" },
{ REL, "relocateable" },
{ NAME, "NAME" },
{ PLUSEQ, "+=" },
{ MINUSEQ, "-=" },
{ MULTEQ, "*=" },
{ DIVEQ, "/=" },
{ LSHIFTEQ, "<<=" },
{ RSHIFTEQ, ">>=" },
{ ANDEQ, "&=" },
{ OREQ, "|=" },
{ OROR, "||" },
{ ANDAND, "&&" },
{ EQ, "==" },
{ NE, "!=" },
{ LE, "<=" },
{ GE, ">=" },
{ LSHIFT, "<<" },
{ RSHIFT, ">>=" },
{ ALIGN_K, "ALIGN" },
{ BLOCK, "BLOCK" },
{ SECTIONS, "SECTIONS" },
{ SIZEOF_HEADERS, "SIZEOF_HEADERS" },
{ NEXT, "NEXT" },
{ SIZEOF, "SIZEOF" },
{ ADDR, "ADDR" },
{ LOADADDR, "LOADADDR" },
{ MEMORY, "MEMORY" },
{ DEFINED, "DEFINED" },
{ TARGET_K, "TARGET" },
{ SEARCH_DIR, "SEARCH_DIR" },
{ MAP, "MAP" },
{ QUAD, "QUAD" },
{ SQUAD, "SQUAD" },
{ LONG, "LONG" },
{ SHORT, "SHORT" },
{ BYTE, "BYTE" },
{ ENTRY, "ENTRY" },
{ 0, (char *) NULL }
};
unsigned int idx;
for (idx = 0; table[idx].name != (char*)NULL; idx++) {
if (table[idx].code == code) {
fprintf(config.map_file, "%s", table[idx].name);
return;
for (idx = 0; table[idx].name != (char *) NULL; idx++)
{
if (table[idx].code == code)
{
fprintf (config.map_file, "%s", table[idx].name);
return;
}
}
}
/* Not in table, just print it alone */
fprintf(config.map_file, "%c",code);
fprintf (config.map_file, "%c", code);
}
static void
make_abs (ptr)
etree_value_type *ptr;
{
asection *s = ptr->section->bfd_section;
ptr->value += s->vma;
ptr->section = abs_output_section;
asection *s = ptr->section->bfd_section;
ptr->value += s->vma;
ptr->section = abs_output_section;
}
static etree_value_type
@ -162,7 +161,7 @@ etree_type *
exp_intop (value)
bfd_vma value;
{
etree_type *new = (etree_type *) stat_alloc(sizeof(new->value));
etree_type *new = (etree_type *) stat_alloc (sizeof (new->value));
new->type.node_code = INT;
new->value.value = value;
new->type.node_class = etree_value;
@ -207,7 +206,7 @@ new_rel_from_section (value, section)
new.value = value;
new.section = section;
new.value -= section->bfd_section->vma;
new.value -= section->bfd_section->vma;
return new;
}
@ -230,7 +229,7 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
other = exp_fold_tree (tree->binary.rhs,
current_section,
allocation_done, dot,dotp) ;
allocation_done, dot, dotp);
if (other.valid_p)
{
/* If the values are from different sections, or this is an
@ -259,8 +258,8 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
else if (result.section != other.section
|| current_section == abs_output_section)
{
make_abs(&result);
make_abs(&other);
make_abs (&result);
make_abs (&other);
}
switch (tree->type.node_code)
@ -280,22 +279,22 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
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,||);
BOP ('+', +);
BOP ('*', *);
BOP ('-', -);
BOP (LSHIFT, <<);
BOP (RSHIFT, >>);
BOP (EQ, ==);
BOP (NE, !=);
BOP ('<', <);
BOP ('>', >);
BOP (LE, <=);
BOP (GE, >=);
BOP ('&', &);
BOP ('^', ^);
BOP ('|', |);
BOP (ANDAND, &&);
BOP (OROR, ||);
case MAX_K:
if (result.value < other.value)
@ -308,7 +307,7 @@ fold_binary (tree, current_section, allocation_done, dot, dotp)
break;
default:
FAIL();
FAIL ();
}
}
else
@ -332,152 +331,153 @@ static etree_value_type
fold_name (tree, current_section, allocation_done, dot)
etree_type *tree;
lang_output_section_statement_type *current_section;
lang_phase_type allocation_done;
lang_phase_type allocation_done;
bfd_vma dot;
{
etree_value_type result;
switch (tree->type.node_code)
{
case SIZEOF_HEADERS:
if (allocation_done != lang_first_phase_enum)
{
result = new_abs ((bfd_vma)
bfd_sizeof_headers (output_bfd,
link_info.relocateable));
}
else
{
result.valid_p = false;
}
break;
case DEFINED:
if (allocation_done == lang_first_phase_enum)
{
case SIZEOF_HEADERS:
if (allocation_done != lang_first_phase_enum)
{
result = new_abs ((bfd_vma)
bfd_sizeof_headers (output_bfd,
link_info.relocateable));
}
else
{
result.valid_p = false;
else
{
struct bfd_link_hash_entry *h;
h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
tree->name.name,
false, false, true);
result.value = (h != (struct bfd_link_hash_entry *) NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_common));
result.section = 0;
result.valid_p = true;
}
break;
case NAME:
}
break;
case DEFINED:
if (allocation_done == lang_first_phase_enum)
result.valid_p = false;
if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
{
if (allocation_done != lang_first_phase_enum)
result = new_rel_from_section(dot, current_section);
else
result = invalid();
}
else if (allocation_done != lang_first_phase_enum)
{
struct bfd_link_hash_entry *h;
h = bfd_wrapped_link_hash_lookup (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))
{
if (bfd_is_abs_section (h->u.def.section))
result = new_abs (h->u.def.value);
else if (allocation_done == lang_final_phase_enum
|| allocation_done == lang_allocating_phase_enum)
{
asection *output_section;
output_section = h->u.def.section->output_section;
if (output_section == NULL)
einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
tree->name.name);
else
{
lang_output_section_statement_type *os;
os = (lang_output_section_statement_lookup
(bfd_get_section_name (output_bfd,
output_section)));
/* FIXME: Is this correct if this section is
being linked with -R? */
result = new_rel ((h->u.def.value
+ h->u.def.section->output_offset),
os);
}
}
}
else if (allocation_done == lang_final_phase_enum)
einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
tree->name.name);
}
break;
case ADDR:
if (allocation_done != lang_first_phase_enum)
{
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "ADDR");
else
{
struct bfd_link_hash_entry *h;
h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
tree->name.name,
false, false, true);
result.value = (h != (struct bfd_link_hash_entry *) NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_common));
result.section = 0;
result.valid_p = true;
}
break;
case NAME:
result.valid_p = false;
if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
{
if (allocation_done != lang_first_phase_enum)
result = new_rel_from_section (dot, current_section);
else
result = invalid ();
}
else if (allocation_done != lang_first_phase_enum)
{
struct bfd_link_hash_entry *h;
h = bfd_wrapped_link_hash_lookup (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))
{
if (bfd_is_abs_section (h->u.def.section))
result = new_abs (h->u.def.value);
else if (allocation_done == lang_final_phase_enum
|| allocation_done == lang_allocating_phase_enum)
{
asection *output_section;
output_section = h->u.def.section->output_section;
if (output_section == NULL)
einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
tree->name.name);
else
{
lang_output_section_statement_type *os;
os = (lang_output_section_statement_lookup
(bfd_get_section_name (output_bfd,
output_section)));
/* FIXME: Is this correct if this section is
being linked with -R? */
result = new_rel ((h->u.def.value
+ h->u.def.section->output_offset),
os);
}
}
}
else if (allocation_done == lang_final_phase_enum)
einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
tree->name.name);
}
break;
case ADDR:
if (allocation_done != lang_first_phase_enum)
{
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "ADDR");
result = new_rel (0, os);
}
else
result = invalid ();
break;
case LOADADDR:
if (allocation_done != lang_first_phase_enum)
{
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "LOADADDR");
if (os->load_base == NULL)
result = new_rel (0, os);
}
else
result = invalid ();
break;
case LOADADDR:
if (allocation_done != lang_first_phase_enum)
{
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "LOADADDR");
if (os->load_base == NULL)
result = new_rel (0, os);
else
result = exp_fold_tree_no_dot (os->load_base,
abs_output_section,
allocation_done);
}
else
result = invalid ();
break;
case SIZEOF:
if (allocation_done != lang_first_phase_enum)
{
int opb = bfd_octets_per_byte (output_bfd);
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "SIZEOF");
result = new_abs (os->bfd_section->_raw_size / opb);
}
else
result = invalid ();
break;
default:
FAIL();
break;
}
else
result = exp_fold_tree_no_dot (os->load_base,
abs_output_section,
allocation_done);
}
else
result = invalid ();
break;
case SIZEOF:
if (allocation_done != lang_first_phase_enum)
{
int opb = bfd_octets_per_byte (output_bfd);
lang_output_section_statement_type *os;
os = lang_output_section_find (tree->name.name);
check (os, tree->name.name, "SIZEOF");
result = new_abs (os->bfd_section->_raw_size / opb);
}
else
result = invalid ();
break;
default:
FAIL ();
break;
}
return result;
}
etree_value_type
exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
etree_type *tree;
lang_output_section_statement_type *current_section;
lang_phase_type allocation_done;
lang_phase_type allocation_done;
bfd_vma dot;
bfd_vma *dotp;
{
@ -507,8 +507,8 @@ exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
case etree_assert:
result = exp_fold_tree (tree->assert_s.child,
current_section,
allocation_done, dot, dotp);
current_section,
allocation_done, dot, dotp);
if (result.valid_p)
{
if (! result.value)
@ -690,8 +690,8 @@ exp_fold_tree_no_dot (tree, current_section, allocation_done)
lang_output_section_statement_type *current_section;
lang_phase_type allocation_done;
{
return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
0, (bfd_vma *)NULL);
return exp_fold_tree (tree, current_section, allocation_done,
(bfd_vma) 0, (bfd_vma *) NULL);
}
etree_type *
@ -707,15 +707,15 @@ exp_binop (code, lhs, rhs)
value.binary.lhs = lhs;
value.binary.rhs = rhs;
value.type.node_class = etree_binary;
r = exp_fold_tree_no_dot(&value,
abs_output_section,
lang_first_phase_enum );
r = exp_fold_tree_no_dot (&value,
abs_output_section,
lang_first_phase_enum);
if (r.valid_p)
{
return exp_intop(r.value);
return exp_intop (r.value);
}
new = (etree_type *) stat_alloc (sizeof (new->binary));
memcpy((char *)new, (char *)&value, sizeof(new->binary));
memcpy ((char *) new, (char *) &value, sizeof (new->binary));
return new;
}
@ -733,13 +733,15 @@ exp_trinop (code, cond, lhs, rhs)
value.trinary.cond = cond;
value.trinary.rhs = rhs;
value.type.node_class = etree_trinary;
r= exp_fold_tree_no_dot(&value, (lang_output_section_statement_type
*)NULL,lang_first_phase_enum);
if (r.valid_p) {
return exp_intop(r.value);
}
r = exp_fold_tree_no_dot (&value,
(lang_output_section_statement_type *) NULL,
lang_first_phase_enum);
if (r.valid_p)
{
return exp_intop (r.value);
}
new = (etree_type *) stat_alloc (sizeof (new->trinary));
memcpy((char *)new,(char *) &value, sizeof(new->trinary));
memcpy ((char *) new, (char *) &value, sizeof (new->trinary));
return new;
}
@ -754,13 +756,14 @@ exp_unop (code, child)
value.unary.type.node_code = code;
value.unary.child = child;
value.unary.type.node_class = etree_unary;
r = exp_fold_tree_no_dot(&value,abs_output_section,
lang_first_phase_enum);
if (r.valid_p) {
return exp_intop(r.value);
}
r = exp_fold_tree_no_dot (&value, abs_output_section,
lang_first_phase_enum);
if (r.valid_p)
{
return exp_intop (r.value);
}
new = (etree_type *) stat_alloc (sizeof (new->unary));
memcpy((char *)new, (char *)&value, sizeof(new->unary));
memcpy ((char *) new, (char *) &value, sizeof (new->unary));
return new;
}
@ -775,14 +778,15 @@ exp_nameop (code, name)
value.name.name = name;
value.name.type.node_class = etree_name;
r = exp_fold_tree_no_dot(&value,
(lang_output_section_statement_type *)NULL,
lang_first_phase_enum);
if (r.valid_p) {
return exp_intop(r.value);
}
r = exp_fold_tree_no_dot (&value,
(lang_output_section_statement_type *) NULL,
lang_first_phase_enum);
if (r.valid_p)
{
return exp_intop (r.value);
}
new = (etree_type *) stat_alloc (sizeof (new->name));
memcpy((char *)new, (char *)&value, sizeof(new->name));
memcpy ((char *) new, (char *) &value, sizeof (new->name));
return new;
}
@ -802,12 +806,13 @@ exp_assop (code, dst, src)
value.assign.type.node_class = etree_assign;
#if 0
if (exp_fold_tree_no_dot(&value, &result)) {
return exp_intop(result);
}
if (exp_fold_tree_no_dot (&value, &result))
{
return exp_intop (result);
}
#endif
new = (etree_type*) stat_alloc (sizeof (new->assign));
memcpy((char *)new, (char *)&value, sizeof(new->assign));
new = (etree_type *) stat_alloc (sizeof (new->assign));
memcpy ((char *) new, (char *) &value, sizeof (new->assign));
return new;
}
@ -849,82 +854,86 @@ void
exp_print_tree (tree)
etree_type *tree;
{
switch (tree->type.node_class) {
case etree_value:
minfo ("0x%v", tree->value.value);
return;
case etree_rel:
if (tree->rel.section->owner != NULL)
minfo ("%B:", tree->rel.section->owner);
minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
return;
case etree_assign:
switch (tree->type.node_class)
{
case etree_value:
minfo ("0x%v", tree->value.value);
return;
case etree_rel:
if (tree->rel.section->owner != NULL)
minfo ("%B:", tree->rel.section->owner);
minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
return;
case etree_assign:
#if 0
if (tree->assign.dst->sdefs != (asymbol *)NULL){
fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
tree->assign.dst->sdefs->value);
}
else {
fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
}
if (tree->assign.dst->sdefs != (asymbol *) NULL)
{
fprintf (config.map_file, "%s (%x) ", tree->assign.dst->name,
tree->assign.dst->sdefs->value);
}
else
{
fprintf (config.map_file, "%s (UNDEFINED)", tree->assign.dst->name);
}
#endif
fprintf(config.map_file,"%s",tree->assign.dst);
exp_print_token(tree->type.node_code);
exp_print_tree(tree->assign.src);
break;
case etree_provide:
fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
exp_print_tree (tree->assign.src);
fprintf (config.map_file, ")");
break;
case etree_binary:
fprintf(config.map_file,"(");
exp_print_tree(tree->binary.lhs);
exp_print_token(tree->type.node_code);
exp_print_tree(tree->binary.rhs);
fprintf(config.map_file,")");
break;
case etree_trinary:
exp_print_tree(tree->trinary.cond);
fprintf(config.map_file,"?");
exp_print_tree(tree->trinary.lhs);
fprintf(config.map_file,":");
exp_print_tree(tree->trinary.rhs);
break;
case etree_unary:
exp_print_token(tree->unary.type.node_code);
if (tree->unary.child)
{
fprintf(config.map_file,"(");
exp_print_tree(tree->unary.child);
fprintf(config.map_file,")");
}
break;
case etree_assert:
fprintf (config.map_file, "ASSERT (");
exp_print_tree (tree->assert_s.child);
fprintf (config.map_file, ", %s)", tree->assert_s.message);
break;
case etree_undef:
fprintf(config.map_file,"????????");
break;
case etree_name:
if (tree->type.node_code == NAME) {
fprintf(config.map_file,"%s", tree->name.name);
}
else {
exp_print_token(tree->type.node_code);
if (tree->name.name)
fprintf(config.map_file,"(%s)", tree->name.name);
fprintf (config.map_file, "%s", tree->assign.dst);
exp_print_token (tree->type.node_code);
exp_print_tree (tree->assign.src);
break;
case etree_provide:
fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
exp_print_tree (tree->assign.src);
fprintf (config.map_file, ")");
break;
case etree_binary:
fprintf (config.map_file, "(");
exp_print_tree (tree->binary.lhs);
exp_print_token (tree->type.node_code);
exp_print_tree (tree->binary.rhs);
fprintf (config.map_file, ")");
break;
case etree_trinary:
exp_print_tree (tree->trinary.cond);
fprintf (config.map_file, "?");
exp_print_tree (tree->trinary.lhs);
fprintf (config.map_file, ":");
exp_print_tree (tree->trinary.rhs);
break;
case etree_unary:
exp_print_token (tree->unary.type.node_code);
if (tree->unary.child)
{
fprintf (config.map_file, "(");
exp_print_tree (tree->unary.child);
fprintf (config.map_file, ")");
}
break;
case etree_assert:
fprintf (config.map_file, "ASSERT (");
exp_print_tree (tree->assert_s.child);
fprintf (config.map_file, ", %s)", tree->assert_s.message);
break;
case etree_undef:
fprintf (config.map_file, "????????");
break;
case etree_name:
if (tree->type.node_code == NAME)
{
fprintf (config.map_file, "%s", tree->name.name);
}
else
{
exp_print_token (tree->type.node_code);
if (tree->name.name)
fprintf (config.map_file, "(%s)", tree->name.name);
}
break;
default:
FAIL ();
break;
}
break;
default:
FAIL();
break;
}
}
bfd_vma
@ -948,13 +957,13 @@ exp_get_vma (tree, def, name, allocation_done)
}
int
exp_get_value_int (tree,def,name, allocation_done)
exp_get_value_int (tree, def, name, allocation_done)
etree_type *tree;
int def;
char *name;
lang_phase_type 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);
}
bfd_vma
@ -971,8 +980,9 @@ exp_get_abs_int (tree, def, name, allocation_done)
{
res.value += res.section->bfd_section->vma;
}
else {
einfo (_("%F%S non constant expression for %s\n"),name);
}
else
{
einfo (_("%F%S non constant expression for %s\n"), name);
}
return res.value;
}

Loading…
Cancel
Save