#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
-#include "ldgram.h"
+#include <ldgram.h>
#include "ldlang.h"
#include "libiberty.h"
#include "safe-ctype.h"
-static void exp_print_token PARAMS ((token_code_type code, int infix_p));
-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 void exp_print_token
+ PARAMS ((token_code_type code, int infix_p));
+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, char *, 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_unary
+ 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_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_trinary
+ 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,
struct exp_data_seg exp_data_seg;
/* Print the string representation of the given token. Surround it
- with spaces if INFIX_P is true. */
+ with spaces if INFIX_P is TRUE. */
static void
exp_print_token (code, infix_p)
token_code_type code;
int infix_p;
{
- static CONST struct
+ static const struct
{
token_code_type code;
char * name;
bfd_vma value;
{
etree_value_type new;
- new.valid_p = true;
+ new.valid_p = TRUE;
new.section = abs_output_section;
new.value = value;
return new;
lang_output_section_statement_type *section;
{
etree_value_type new;
- new.valid_p = true;
+ new.valid_p = TRUE;
new.value = value;
new.str = str;
new.section = section;
lang_output_section_statement_type *section;
{
etree_value_type new;
- new.valid_p = true;
+ new.valid_p = TRUE;
new.value = value;
new.str = NULL;
new.section = section;
return new;
}
+static etree_value_type
+fold_unary (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;
+
+ result = exp_fold_tree (tree->unary.child,
+ current_section,
+ allocation_done, dot, dotp);
+ if (result.valid_p)
+ {
+ 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_p = FALSE;
+ break;
+
+ case ABSOLUTE:
+ if (allocation_done != lang_first_phase_enum)
+ {
+ result.value += result.section->bfd_section->vma;
+ result.section = abs_output_section;
+ }
+ else
+ result.valid_p = 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:
+ /* Return next place aligned to value. */
+ if (allocation_done == lang_allocating_phase_enum)
+ {
+ make_abs (&result);
+ result.value = align_n (dot, result.value);
+ }
+ else
+ result.valid_p = FALSE;
+ break;
+
+ case DATA_SEGMENT_END:
+ if (allocation_done != lang_first_phase_enum
+ && current_section == abs_output_section
+ && (exp_data_seg.phase == exp_dataseg_align_seen
+ || exp_data_seg.phase == exp_dataseg_adjust
+ || allocation_done != lang_allocating_phase_enum))
+ {
+ if (exp_data_seg.phase == exp_dataseg_align_seen)
+ {
+ exp_data_seg.phase = exp_dataseg_end_seen;
+ exp_data_seg.end = result.value;
+ }
+ }
+ else
+ result.valid_p = FALSE;
+ break;
+
+ default:
+ FAIL ();
+ break;
+ }
+ }
+
+ return result;
+}
+
static etree_value_type
fold_binary (tree, current_section, allocation_done, dot, dotp)
etree_type *tree;
&& (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 (other.section != abs_output_section)
{
- hold = result;
- result = other;
- other = hold;
+ /* Keep the section of the other term. */
+ if (tree->type.node_code == '+')
+ other.value = result.value + other.value;
+ else
+ other.value = result.value - other.value;
+ return other;
}
}
else if (result.section != other.section
{
bfd_vma maxpage = result.value;
- result.value = ALIGN_N (dot, maxpage);
+ result.value = align_n (dot, maxpage);
if (exp_data_seg.phase != exp_dataseg_adjust)
{
result.value += dot & (maxpage - 1);
& (maxpage - other.value);
}
else
- result.valid_p = false;
+ result.valid_p = FALSE;
break;
default:
}
else
{
- result.valid_p = false;
+ result.valid_p = FALSE;
}
}
return result;
}
+static etree_value_type
+fold_trinary (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;
+
+ result = exp_fold_tree (tree->trinary.cond, current_section,
+ allocation_done, dot, dotp);
+ if (result.valid_p)
+ result = exp_fold_tree ((result.value
+ ? tree->trinary.lhs
+ : tree->trinary.rhs),
+ current_section,
+ allocation_done, dot, dotp);
+
+ return result;
+}
+
etree_value_type
invalid ()
{
etree_value_type new;
- new.valid_p = false;
+ new.valid_p = FALSE;
return new;
}
}
else
{
- result.valid_p = false;
+ result.valid_p = FALSE;
}
break;
case DEFINED:
if (allocation_done == lang_first_phase_enum)
- result.valid_p = false;
+ 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);
+ 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;
+ result.valid_p = TRUE;
}
break;
case NAME:
- result.valid_p = false;
+ result.valid_p = FALSE;
if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
{
if (allocation_done != lang_first_phase_enum)
h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
tree->name.name,
- false, false, true);
+ FALSE, FALSE, TRUE);
if (h != NULL
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak))
if (tree == NULL)
{
- result.valid_p = false;
+ result.valid_p = FALSE;
return result;
}
case etree_rel:
if (allocation_done != lang_final_phase_enum)
- result.valid_p = false;
+ result.valid_p = FALSE;
else
result = new_rel ((tree->rel.value
+ tree->rel.section->output_section->vma
break;
case etree_unary:
- result = exp_fold_tree (tree->unary.child,
- current_section,
- allocation_done, dot, dotp);
- if (result.valid_p)
- {
- 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_p = false;
- break;
-
- case ABSOLUTE:
- if (allocation_done != lang_first_phase_enum && result.valid_p)
- {
- result.value += result.section->bfd_section->vma;
- result.section = abs_output_section;
- }
- else
- result.valid_p = 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:
- /* Return next place aligned to value. */
- if (allocation_done == lang_allocating_phase_enum)
- {
- make_abs (&result);
- result.value = ALIGN_N (dot, result.value);
- }
- else
- result.valid_p = false;
- break;
-
- case DATA_SEGMENT_END:
- if (allocation_done != lang_first_phase_enum
- && current_section == abs_output_section
- && (exp_data_seg.phase == exp_dataseg_align_seen
- || exp_data_seg.phase == exp_dataseg_adjust
- || allocation_done != lang_allocating_phase_enum))
- {
- if (exp_data_seg.phase == exp_dataseg_align_seen)
- {
- exp_data_seg.phase = exp_dataseg_end_seen;
- exp_data_seg.end = result.value;
- }
- }
- else
- result.valid_p = false;
- break;
-
- default:
- FAIL ();
- break;
- }
- }
- break;
-
- case etree_trinary:
- result = exp_fold_tree (tree->trinary.cond, current_section,
- allocation_done, dot, dotp);
- if (result.valid_p)
- result = exp_fold_tree ((result.value
- ? tree->trinary.lhs
- : tree->trinary.rhs),
- current_section,
- allocation_done, dot, dotp);
+ result = fold_unary (tree, current_section, allocation_done,
+ dot, dotp);
break;
case etree_binary:
dot, dotp);
break;
+ case etree_trinary:
+ result = fold_trinary (tree, current_section, allocation_done,
+ dot, dotp);
+ break;
+
case etree_assign:
case etree_provide:
case etree_provided:
dot, dotp);
if (result.valid_p)
{
- boolean create;
+ bfd_boolean create;
struct bfd_link_hash_entry *h;
if (tree->type.node_class == etree_assign)
- create = true;
+ create = TRUE;
else
- create = false;
+ create = FALSE;
h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
- create, false, false);
+ create, FALSE, FALSE);
if (h == (struct bfd_link_hash_entry *) NULL)
{
if (tree->type.node_class == etree_assign)
etree_type *
exp_nameop (code, name)
int code;
- CONST char *name;
+ const char *name;
{
etree_type value, *new;
etree_value_type r;
etree_type *
exp_assop (code, dst, src)
int code;
- CONST char *dst;
+ const char *dst;
etree_type *src;
{
etree_type value, *new;
{
if (config.map_file == NULL)
config.map_file = stderr;
-
+
if (tree == NULL)
{
minfo ("NULL TREE\n");
return;
}
-
+
switch (tree->type.node_class)
{
case etree_value:
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, true);
+ exp_print_token (tree->type.node_code, TRUE);
exp_print_tree (tree->assign.src);
break;
case etree_provide:
case etree_binary:
fprintf (config.map_file, "(");
exp_print_tree (tree->binary.lhs);
- exp_print_token (tree->type.node_code, true);
+ exp_print_token (tree->type.node_code, TRUE);
exp_print_tree (tree->binary.rhs);
fprintf (config.map_file, ")");
break;
exp_print_tree (tree->trinary.rhs);
break;
case etree_unary:
- exp_print_token (tree->unary.type.node_code, false);
+ exp_print_token (tree->unary.type.node_code, FALSE);
if (tree->unary.child)
{
fprintf (config.map_file, " (");
}
else
{
- exp_print_token (tree->type.node_code, false);
+ exp_print_token (tree->type.node_code, FALSE);
if (tree->name.name)
fprintf (config.map_file, " (%s)", tree->name.name);
}
return res.value;
}
+
+bfd_vma align_n (value, align)
+ bfd_vma value;
+ bfd_vma align;
+{
+ if (align <= 1)
+ return value;
+
+ value = (value + align - 1) / align;
+ return value * align;
+}