/* This module handles expression trees.
-Copyright (C) 1991 Free Software Foundation, Inc.
+Copyright (C) 1991, 1993 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).
This file is part of GLD, the Gnu Linker.
#include "bfd.h"
#include "sysdep.h"
+#include "bfdlink.h"
#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldgram.h"
-#include "ldsym.h"
#include "ldlang.h"
-extern char *output_filename;
-extern unsigned int undefined_global_sym_count;
-extern unsigned int defined_global_sym_count;
-extern bfd *output_bfd;
-extern bfd_size_type largest_section;
-extern lang_statement_list_type file_chain;
-extern args_type command_line;
-extern ld_config_type config;
-
-extern lang_input_statement_type *script_file;
-extern unsigned int defined_global_sym_count;
- extern lang_output_section_statement_type *abs_output_section;
-extern bfd_vma print_dot;
-
+static void exp_print_token PARAMS ((token_code_type code));
+static void make_abs PARAMS ((etree_value_type *ptr));
+static etree_value_type new_abs PARAMS ((bfd_vma value));
+static void check PARAMS ((lang_output_section_statement_type *os,
+ const char *name, const char *op));
+static etree_value_type new_rel
+ PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
+static etree_value_type new_rel_from_section
+ PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
+static etree_value_type fold_binary
+ PARAMS ((etree_type *tree,
+ lang_output_section_statement_type *current_section,
+ lang_phase_type allocation_done,
+ bfd_vma dot, bfd_vma *dotp));
+static etree_value_type fold_name
+ PARAMS ((etree_type *tree,
+ lang_output_section_statement_type *current_section,
+ lang_phase_type allocation_done,
+ bfd_vma dot));
+static etree_value_type exp_fold_tree_no_dot
+ PARAMS ((etree_type *tree,
+ lang_output_section_statement_type *current_section,
+ lang_phase_type allocation_done));
static void
-DEFUN(exp_print_token,( code),
- token_code_type code)
+exp_print_token (code)
+ token_code_type code;
{
- static struct {
- token_code_type code;
- char *name;
- } table[] =
+ static CONST struct
+ {
+ token_code_type code;
+ char *name;
+ } table[] =
{
- INT, "int",
- 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",
- MEMORY,"MEMORY",
-
-
-
-
-
- DEFINED,"DEFINED",
- TARGET_K,"TARGET",
- SEARCH_DIR,"SEARCH_DIR",
- MAP,"MAP",
- LONG,"LONG",
- SHORT,"SHORT",
- BYTE,"BYTE",
- ENTRY,"ENTRY",
- 0,(char *)NULL} ;
-
-
-
+ { 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" },
+ { MEMORY,"MEMORY" },
+ { DEFINED,"DEFINED" },
+ { TARGET_K,"TARGET" },
+ { SEARCH_DIR,"SEARCH_DIR" },
+ { MAP,"MAP" },
+ { QUAD,"QUAD" },
+ { 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);
}
static void
-DEFUN(make_abs,(ptr),
- etree_value_type *ptr)
+make_abs (ptr)
+ etree_value_type *ptr;
{
asection *s = ptr->section->bfd_section;
ptr->value += s->vma;
ptr->section = abs_output_section;
}
-static
-DEFUN(etree_value_type new_abs,(value),
- bfd_vma value)
+static etree_value_type
+new_abs (value)
+ bfd_vma value;
{
-
-
etree_value_type new;
new.valid = true;
new.section = abs_output_section;
}
static void
-DEFUN(check, (os, name, op),
- lang_output_section_statement_type *os AND
- CONST char *name AND
- CONST char *op)
+check (os, name, op)
+ lang_output_section_statement_type *os;
+ CONST char *name;
+ CONST char *op;
{
if (os == (lang_output_section_statement_type *)NULL) {
- einfo("%F%P %s uses undefined section %s\n", op, name);
+ einfo("%F%P: %s uses undefined section %s\n", op, name);
}
if (os->processed == false) {
- einfo("%F%P %s forward reference of section %s\n",op, name);
+ einfo("%F%P: %s forward reference of section %s\n",op, name);
}
}
etree_type *
-DEFUN(exp_intop,(value),
- bfd_vma value)
+exp_intop (value)
+ bfd_vma value;
{
- etree_type *new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->value)));
+ etree_type *new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->value)));
new->type.node_code = INT;
new->value.value = value;
new->type.node_class = etree_value;
}
+/* Build an expression representing an unnamed relocateable value. */
-static
-DEFUN(etree_value_type new_rel,(value, section),
- bfd_vma value AND
- lang_output_section_statement_type *section)
+etree_type *
+exp_relop (section, value)
+ asection *section;
+ bfd_vma value;
+{
+ etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
+ new->type.node_code = REL;
+ new->type.node_class = etree_rel;
+ new->rel.section = section;
+ new->rel.value = value;
+ return new;
+}
+
+static etree_value_type
+new_rel (value, section)
+ bfd_vma value;
+ lang_output_section_statement_type *section;
{
etree_value_type new;
new.valid = true;
return new;
}
-static
-DEFUN(etree_value_type
- new_rel_from_section, (value, section),
- bfd_vma value AND
- lang_output_section_statement_type *section)
+static etree_value_type
+new_rel_from_section (value, section)
+ bfd_vma value;
+ lang_output_section_statement_type *section;
{
etree_value_type new;
new.valid = true;
}
static etree_value_type
-DEFUN(fold_binary,(tree, current_section, allocation_done, dot, dotp),
- etree_type *tree AND
- lang_output_section_statement_type *current_section AND
- lang_phase_type allocation_done AND
- bfd_vma dot AND
- bfd_vma *dotp)
+fold_binary (tree, current_section, allocation_done, dot, dotp)
+ etree_type *tree;
+ lang_output_section_statement_type *current_section;
+ lang_phase_type allocation_done;
+ bfd_vma dot;
+ bfd_vma *dotp;
{
etree_value_type result;
/* Mod, both absolule*/
if (other.value == 0) {
- einfo("%F%S % by zero\n");
+ einfo("%F%S %% by zero\n");
}
result.value = (int)result.value % (int)other.value;
break;
return result;
}
etree_value_type
-DEFUN_VOID(invalid)
+invalid ()
{
etree_value_type new;
new.valid = false;
return new;
}
-etree_value_type
-DEFUN(fold_name, (tree, current_section, allocation_done, dot),
- etree_type *tree AND
- lang_output_section_statement_type *current_section AND
- lang_phase_type allocation_done AND
- bfd_vma dot)
+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;
+ 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_sizeof_headers(output_bfd,
- config.relocateable_output));
-
- }
- else {
- result.valid = false;
- }
+ {
+ result = new_abs ((bfd_vma)
+ bfd_sizeof_headers (output_bfd,
+ link_info.relocateable));
+ }
+ else
+ {
+ result.valid = false;
+ }
break;
case DEFINED:
- result.value =
- ldsym_get_soft(tree->name.name) != (ldsym_type *)NULL;
- result.section = 0;
- result.valid = true;
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, 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_common));
+ result.section = 0;
+ result.valid = true;
+ }
break;
case NAME:
result.valid = 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();
+ 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_final_phase_enum) {
- ldsym_type *sy = ldsym_get_soft(tree->name.name);
-
- if (sy) {
- asymbol **sdefp = sy->sdefs_chain;
+ else if (allocation_done == lang_final_phase_enum)
+ {
+ struct bfd_link_hash_entry *h;
- if (sdefp) {
- asymbol *sdef = *sdefp;
-#if 0
- if (sdef->section == (asection *)NULL) {
- /* This is an absolute symbol */
- result = new_abs(sdef->value);
- }
- else
-#endif
- {
- lang_output_section_statement_type *os =
- lang_output_section_statement_lookup(
- sdef->section->output_section->name);
- /* If the symbol is from a file which we are not
- relocating (-R) then return an absolute for its
- value */
- if (sdef->the_bfd->usrdata &&
- ((lang_input_statement_type*)(sdef->the_bfd->usrdata))->just_syms_flag == true)
- {
- result = new_abs(sdef->value +sdef->section->vma);
-
- }
- else {
- result = new_rel(sdef->value + sdef->section->output_offset, os);
- }
- }
+ h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
+ false, false, true);
+ if (h != (struct bfd_link_hash_entry *) NULL
+ && h->type == bfd_link_hash_defined)
+ {
+ lang_output_section_statement_type *os;
+
+ os = (lang_output_section_statement_lookup
+ (h->u.def.section->output_section->name));
+
+ /* 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);
}
- }
- if (result.valid == false) {
- einfo("%F%S: undefined symbol `%s' referenced in expression.\n",
- tree->name.name);
- }
-
+ if (result.valid == false)
+ einfo("%F%S: undefined symbol `%s' referenced in expression\n",
+ tree->name.name);
}
- }
-
break;
case ADDR:
return result;
}
etree_value_type
-DEFUN(exp_fold_tree,(tree, current_section, allocation_done,
- dot, dotp),
- etree_type *tree AND
- lang_output_section_statement_type *current_section AND
- lang_phase_type allocation_done AND
- bfd_vma dot AND
- bfd_vma *dotp)
+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;
+ bfd_vma dot;
+ bfd_vma *dotp;
{
etree_value_type result;
if (tree == (etree_type *)NULL) {
- result.valid = false;
- }
+ result.valid = false;
+ }
else {
- switch (tree->type.node_class)
+ switch (tree->type.node_class)
+ {
+ case etree_value:
+ result = new_rel(tree->value.value, current_section);
+ break;
+ case etree_rel:
+ if (allocation_done != lang_final_phase_enum)
+ result.valid = false;
+ else
+ result = new_rel ((tree->rel.value
+ + tree->rel.section->output_section->vma
+ + tree->rel.section->output_offset),
+ current_section);
+ break;
+ case etree_unary:
+ result = exp_fold_tree(tree->unary.child,
+ current_section,
+ allocation_done, dot, dotp);
+ if (result.valid == true)
{
- case etree_value:
- result = new_rel(tree->value.value, current_section);
- break;
- case etree_unary:
- result = exp_fold_tree(tree->unary.child,
- current_section,
- allocation_done, dot, dotp);
- if (result.valid == true)
+ switch(tree->type.node_code)
{
- switch(tree->type.node_code)
+ case ALIGN_K:
+ if (allocation_done != lang_first_phase_enum) {
+ result = new_rel_from_section(ALIGN_N(dot,
+ result.value) ,
+ current_section);
+
+ }
+ else {
+ result.valid = false;
+ }
+ break;
+ case ABSOLUTE:
+ if (allocation_done != lang_first_phase_enum)
{
- case ALIGN_K:
- if (allocation_done != lang_first_phase_enum) {
- result = new_rel_from_section(ALIGN(dot,
- result.value) ,
- current_section);
+ if (current_section
+ == (lang_output_section_statement_type*)NULL)
+ {
+ /* Outside a section, so it's all ok */
- }
+ }
else {
- result.valid = false;
- }
- break;
- case '~':
- make_abs(&result);
- result.value = ~result.value;
- break;
- case '!':
- make_abs(&result);
- result.value = !result.value;
- break;
- case '-':
+ /* Inside a section, subtract the base of the section,
+ so when it's added again (in an assignment), everything comes out fine
+ */
+ result.section = abs_output_section;
+ result.value -= current_section->bfd_section->vma;
+ result.valid = true;
+ }
+ }
+ else
+ {
+ result.valid = false;
+ }
+
+ break;
+ case '~':
+ make_abs(&result);
+ result.value = ~result.value;
+ break;
+ case '!':
+ make_abs(&result);
+ result.value = !result.value;
+ break;
+ case '-':
+ make_abs(&result);
+ result.value = -result.value;
+ break;
+ case NEXT:
+ if (allocation_done ==lang_allocating_phase_enum) {
make_abs(&result);
- result.value = -result.value;
- break;
- case NEXT:
- if (allocation_done ==lang_allocating_phase_enum) {
- make_abs(&result);
- result.value = ALIGN(dot, result.value);
- }
- else {
- /* Return next place aligned to value */
- result.valid = false;
- }
- break;
- default:
- FAIL();
+ result.value = ALIGN_N(dot, result.value);
+ }
+ else {
+ /* Return next place aligned to value */
+ result.valid = false;
}
+ break;
+ default:
+ FAIL();
}
+ }
- break;
- case etree_trinary:
+ break;
+ case etree_trinary:
- result = exp_fold_tree(tree->trinary.cond,
+ result = exp_fold_tree(tree->trinary.cond,
+ current_section,
+ allocation_done, dot, dotp);
+ if (result.valid) {
+ result = exp_fold_tree(result.value ?
+ tree->trinary.lhs:tree->trinary.rhs,
current_section,
allocation_done, dot, dotp);
- if (result.valid) {
- result = exp_fold_tree(result.value ?
- tree->trinary.lhs:tree->trinary.rhs,
- current_section,
- allocation_done, dot, dotp);
- }
+ }
- break;
- case etree_binary:
- result = fold_binary(tree, current_section, allocation_done,
- dot, dotp);
- break;
- case etree_assign:
- if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
- /* Assignment to dot can only be done during allocation */
- if (allocation_done == lang_allocating_phase_enum) {
- result = exp_fold_tree(tree->assign.src,
- current_section,
- lang_allocating_phase_enum, dot, dotp);
- if (result.valid == false) {
- einfo("%F%S invalid assignment to location counter\n");
- }
- else {
- if (current_section ==
- (lang_output_section_statement_type *)NULL) {
- einfo("%F%S assignment to location counter invalid outside of SECTION\n");
- }
- else {
- unsigned long nextdot =result.value +
- current_section->bfd_section->vma;
- if (nextdot < dot) {
- einfo("%F%S cannot move location counter backwards");
- }
- else {
- *dotp = nextdot;
- }
- }
- }
- }
+ break;
+ case etree_binary:
+ result = fold_binary(tree, current_section, allocation_done,
+ dot, dotp);
+ break;
+ case etree_assign:
+ case etree_provide:
+ if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0) {
+ /* Assignment to dot can only be done during allocation */
+ if (tree->type.node_class == etree_provide)
+ einfo ("%F%S can not PROVIDE assignment to location counter\n");
+ if (allocation_done == lang_allocating_phase_enum) {
+ result = exp_fold_tree(tree->assign.src,
+ current_section,
+ lang_allocating_phase_enum, dot, dotp);
+ if (result.valid == false) {
+ einfo("%F%S invalid assignment to location counter\n");
}
- else {
- ldsym_type *sy = ldsym_get(tree->assign.dst);
-
- /* If this symbol has just been created then we'll place it into
- * a section of our choice
- */
- result = exp_fold_tree(tree->assign.src,
- current_section, allocation_done,
- dot, dotp);
- if (result.valid)
- {
- asymbol *def;
- asymbol **def_ptr ;
- /* Add this definition to script file */
- if (sy->sdefs_chain)
- {
- def_ptr = sy->sdefs_chain;
- def = *def_ptr;
-
+ else {
+ if (current_section ==
+ (lang_output_section_statement_type *)NULL) {
+ einfo("%F%S assignment to location counter invalid outside of SECTION\n");
+ }
+ else {
+ bfd_vma nextdot =result.value +
+ current_section->bfd_section->vma;
+ if (nextdot < dot) {
+ einfo("%F%S cannot move location counter backwards (from %V to %V)\n", dot, nextdot);
}
- else
- {
- def_ptr = (asymbol **)ldmalloc((bfd_size_type)(sizeof(asymbol **)));
- def = (asymbol *)bfd_make_empty_symbol(script_file->the_bfd);
-
-
- def->flags = 0;
-
- sy->sdefs_chain = def_ptr;
- *def_ptr = def;
+ else {
+ *dotp = nextdot;
}
-
- def->value = result.value;
-
- def->section = result.section->bfd_section;
- def->flags = BSF_GLOBAL | BSF_EXPORT;
-
-
- def->udata = (PTR)NULL;
- def->name = sy->name;
-
- if (sy->sdefs_chain == 0) Q_enter_global_ref(def_ptr);
}
-
}
-
-
- break;
- case etree_name:
- result = fold_name(tree, current_section, allocation_done, dot);
- break;
- default:
- einfo("%F%S Need more of these %d",tree->type.node_class );
-
+ }
}
+ else
+ {
+ result = exp_fold_tree (tree->assign.src,
+ current_section, allocation_done,
+ dot, dotp);
+ if (result.valid)
+ {
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
+ (tree->type.node_class == etree_assign
+ ? true : false),
+ false, false);
+ if (h == (struct bfd_link_hash_entry *) NULL)
+ {
+ if (tree->type.node_class == etree_assign)
+ einfo ("%P%F:%s: hash creation failed\n",
+ tree->assign.dst);
+ }
+ else if (tree->type.node_class == etree_provide
+ && h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common)
+ {
+ /* Do nothing. The symbol was defined by some
+ object. */
+ }
+ else
+ {
+ /* FIXME: Should we worry if the symbol is already
+ defined? */
+ h->type = bfd_link_hash_defined;
+ h->u.def.value = result.value;
+ h->u.def.section = result.section->bfd_section;
+ }
+ }
+ }
+ break;
+ case etree_name:
+ result = fold_name(tree, current_section, allocation_done, dot);
+ break;
+ default:
+ einfo("%F%S need more of these %d\n",tree->type.node_class );
+
}
+ }
return result;
}
-etree_value_type
-DEFUN(exp_fold_tree_no_dot,(tree, current_section, allocation_done),
- etree_type *tree AND
- lang_output_section_statement_type *current_section AND
- lang_phase_type allocation_done)
+static etree_value_type
+exp_fold_tree_no_dot (tree, current_section, allocation_done)
+ etree_type *tree;
+ 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);
}
etree_type *
-DEFUN(exp_binop,(code, lhs, rhs),
- int code AND
- etree_type *lhs AND
- etree_type *rhs)
+exp_binop (code, lhs, rhs)
+ int code;
+ etree_type *lhs;
+ etree_type *rhs;
{
etree_type value, *new;
etree_value_type r;
{
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->binary)));
+ new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->binary)));
memcpy((char *)new, (char *)&value, sizeof(new->binary));
return new;
}
etree_type *
-DEFUN(exp_trinop,(code, cond, lhs, rhs),
- int code AND
- etree_type *cond AND
- etree_type *lhs AND
- etree_type *rhs)
+exp_trinop (code, cond, lhs, rhs)
+ int code;
+ etree_type *cond;
+ etree_type *lhs;
+ etree_type *rhs;
{
etree_type value, *new;
etree_value_type r;
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->trinary)));
+ new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->trinary)));
memcpy((char *)new,(char *) &value, sizeof(new->trinary));
return new;
}
etree_type *
-DEFUN(exp_unop,(code, child),
- int code AND
- etree_type *child)
+exp_unop (code, child)
+ int code;
+ etree_type *child;
{
etree_type value, *new;
value.unary.type.node_code = code;
value.unary.child = child;
value.unary.type.node_class = etree_unary;
- r = exp_fold_tree_no_dot(&value,(lang_output_section_statement_type *)NULL,
+ r = exp_fold_tree_no_dot(&value,abs_output_section,
lang_first_phase_enum);
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->unary)));
+ new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->unary)));
memcpy((char *)new, (char *)&value, sizeof(new->unary));
return new;
}
etree_type *
-DEFUN(exp_nameop,(code, name),
- int code AND
- CONST char *name)
+exp_nameop (code, name)
+ int code;
+ CONST char *name;
{
-
etree_type value, *new;
-
etree_value_type r;
value.name.type.node_code = code;
value.name.name = name;
if (r.valid) {
return exp_intop(r.value);
}
- new = (etree_type *)ldmalloc((bfd_size_type)(sizeof(new->name)));
+ new = (etree_type *)stat_alloc((bfd_size_type)(sizeof(new->name)));
memcpy((char *)new, (char *)&value, sizeof(new->name));
return new;
etree_type *
-DEFUN(exp_assop,(code, dst, src),
- int code AND
- CONST char *dst AND
- etree_type *src)
+exp_assop (code, dst, src)
+ int code;
+ CONST char *dst;
+ etree_type *src;
{
etree_type value, *new;
return exp_intop(result);
}
#endif
- new = (etree_type*)ldmalloc((bfd_size_type)(sizeof(new->assign)));
+ new = (etree_type*)stat_alloc((bfd_size_type)(sizeof(new->assign)));
memcpy((char *)new, (char *)&value, sizeof(new->assign));
return new;
}
+/* Handle PROVIDE. */
+
+etree_type *
+exp_provide (dst, src)
+ const char *dst;
+ etree_type *src;
+{
+ etree_type *n;
+
+ n = (etree_type *) stat_alloc (sizeof (n->assign));
+ n->assign.type.node_code = '=';
+ n->assign.type.node_class = etree_provide;
+ n->assign.src = src;
+ n->assign.dst = dst;
+ return n;
+}
+
void
-DEFUN(exp_print_tree,(tree),
- etree_type *tree)
+exp_print_tree (tree)
+ etree_type *tree;
{
switch (tree->type.node_class) {
case etree_value:
print_address(tree->value.value);
return;
-
+ case etree_rel:
+ if (tree->rel.section->owner != NULL)
+ fprintf (config.map_file, "%s:",
+ bfd_get_filename (tree->rel.section->owner));
+ fprintf (config.map_file, "%s+", tree->rel.section->name);
+ print_address (tree->rel.value);
+ return;
case etree_assign:
#if 0
if (tree->assign.dst->sdefs != (asymbol *)NULL){
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);
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_undef:
fprintf(config.map_file,"????????");
}
else {
exp_print_token(tree->type.node_code);
+ if (tree->name.name)
fprintf(config.map_file,"(%s)", tree->name.name);
}
break;
bfd_vma
-DEFUN(exp_get_vma,(tree, def, name, allocation_done),
- etree_type *tree AND
- bfd_vma def AND
- char *name AND
- lang_phase_type allocation_done)
+exp_get_vma (tree, def, name, allocation_done)
+ etree_type *tree;
+ bfd_vma def;
+ char *name;
+ lang_phase_type allocation_done;
{
etree_value_type r;
if (tree != (etree_type *)NULL) {
r = exp_fold_tree_no_dot(tree,
- (lang_output_section_statement_type *)NULL,
+ abs_output_section,
allocation_done);
if (r.valid == false && name) {
- einfo("%F%S Nonconstant expression for %s\n",name);
+ einfo("%F%S nonconstant expression for %s\n",name);
}
return r.value;
}
}
int
-DEFUN(exp_get_value_int,(tree,def,name, allocation_done),
- etree_type *tree AND
- int def AND
- char *name AND
- lang_phase_type 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);
}