+2014-12-23 Alan Modra <amodra@gmail.com>
+
+ * ldexp.c (struct definedness_hash_entry, definedness_table)
+ (definedness_newfunc, symbol_defined, update_definedness): Move
+ and rename from..
+ * ldlang.h (struct lang_definedness_hash_entry): ..here,..
+ * ldlang.c (lang_definedness_table, lang_definedness_newfunc)
+ (lang_symbol_defined, lang_update_definedness): ..and here.
+ * ldexp.c (ldexp_init, ldexp_finish): New functions, extracted from..
+ * ldlang.c (lang_init, lang_finish): ..here.
+ * ldexp.h (ldexp_init, ldexp_finish): Declare.
+ * ldlang.h (lang_symbol_defined, lang_update_definedness): Delete.
+ * ldmain.c (main): Call ldexp_init and ldexp_finish.
+
2014-12-10 Alan Modra <amodra@gmail.com>
* ldmisc.c: #include "coff-bfd.h"
struct ldexp_control expld;
+/* This structure records symbols for which we need to keep track of
+ definedness for use in the DEFINED () test. */
+
+struct definedness_hash_entry
+{
+ struct bfd_hash_entry root;
+ unsigned int by_object : 1;
+ unsigned int by_script : 1;
+ unsigned int iteration : 1;
+};
+
+static struct bfd_hash_table definedness_table;
+
/* Print the string representation of the given token. Surround it
with spaces if INFIX_P is TRUE. */
expld.result.section = s;
}
+/* New-function for the definedness hash table. */
+
+static struct bfd_hash_entry *
+definedness_newfunc (struct bfd_hash_entry *entry,
+ struct bfd_hash_table *table ATTRIBUTE_UNUSED,
+ const char *name ATTRIBUTE_UNUSED)
+{
+ struct definedness_hash_entry *ret = (struct definedness_hash_entry *) entry;
+
+ if (ret == NULL)
+ ret = (struct definedness_hash_entry *)
+ bfd_hash_allocate (table, sizeof (struct definedness_hash_entry));
+
+ if (ret == NULL)
+ einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name);
+
+ ret->by_object = 0;
+ ret->by_script = 0;
+ ret->iteration = 0;
+ return &ret->root;
+}
+
+/* Called during processing of linker script script expressions.
+ For symbols assigned in a linker script, return a struct describing
+ where the symbol is defined relative to the current expression,
+ otherwise return NULL. */
+
+static struct definedness_hash_entry *
+symbol_defined (const char *name)
+{
+ return ((struct definedness_hash_entry *)
+ bfd_hash_lookup (&definedness_table, name, FALSE, FALSE));
+}
+
+/* Update the definedness state of NAME. */
+
+static void
+update_definedness (const char *name, struct bfd_link_hash_entry *h)
+{
+ struct definedness_hash_entry *defentry
+ = (struct definedness_hash_entry *)
+ bfd_hash_lookup (&definedness_table, name, TRUE, FALSE);
+
+ if (defentry == NULL)
+ einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name);
+
+ /* If the symbol was already defined, and not by a script, then it
+ must be defined by an object file. */
+ if (!defentry->by_script
+ && h->type != bfd_link_hash_undefined
+ && h->type != bfd_link_hash_common
+ && h->type != bfd_link_hash_new)
+ defentry->by_object = 1;
+
+ defentry->by_script = 1;
+ defentry->iteration = lang_statement_iteration;
+}
+
static void
fold_unary (etree_type *tree)
{
if (expld.phase != lang_first_phase_enum)
{
struct bfd_link_hash_entry *h;
- struct lang_definedness_hash_entry *def;
+ struct definedness_hash_entry *def;
h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
&link_info,
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak
|| h->type == bfd_link_hash_common)
- && ((def = lang_symbol_defined (tree->name.name)) == NULL
+ && ((def = symbol_defined (tree->name.name)) == NULL
|| def->by_object
|| def->iteration == (lang_statement_iteration & 1)));
}
/* Self-assignment is only allowed for absolute symbols
defined in a linker script. */
struct bfd_link_hash_entry *h;
- struct lang_definedness_hash_entry *def;
+ struct definedness_hash_entry *def;
h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
&link_info,
&& (h->type == bfd_link_hash_defined
|| h->type == bfd_link_hash_defweak)
&& h->u.def.section == bfd_abs_section_ptr
- && (def = lang_symbol_defined (tree->name.name)) != NULL
+ && (def = symbol_defined (tree->name.name)) != NULL
&& def->iteration == (lang_statement_iteration & 1)))
expld.assign_name = NULL;
}
is_sym_value (const etree_type *tree, bfd_vma val)
{
struct bfd_link_hash_entry *h;
- struct lang_definedness_hash_entry *def;
+ struct definedness_hash_entry *def;
return (tree->type.node_class == etree_name
&& tree->type.node_code == NAME
- && (def = lang_symbol_defined (tree->name.name)) != NULL
+ && (def = symbol_defined (tree->name.name)) != NULL
&& def->by_script
&& def->iteration == (lang_statement_iteration & 1)
&& (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
/* FIXME: Should we worry if the symbol is already
defined? */
- lang_update_definedness (tree->assign.dst, h);
+ update_definedness (tree->assign.dst, h);
h->type = bfd_link_hash_defined;
h->u.def.value = expld.result.value;
if (expld.result.section == NULL)
value = (value + align - 1) / align;
return value * align;
}
+
+void
+ldexp_init (void)
+{
+ /* The value "13" is ad-hoc, somewhat related to the expected number of
+ assignments in a linker script. */
+ if (!bfd_hash_table_init_n (&definedness_table,
+ definedness_newfunc,
+ sizeof (struct definedness_hash_entry),
+ 13))
+ einfo (_("%P%F: can not create hash table: %E\n"));
+}
+
+void
+ldexp_finish (void)
+{
+ bfd_hash_table_free (&definedness_table);
+}
(etree_type *, fill_type *, char *);
bfd_vma exp_get_abs_int
(etree_type *, int, char *);
+void ldexp_init (void);
+void ldexp_finish (void);
#endif
static lang_input_statement_type *first_file;
static const char *current_target;
static lang_statement_list_type statement_list;
-static struct bfd_hash_table lang_definedness_table;
static lang_statement_list_type *stat_save[10];
static lang_statement_list_type **stat_save_ptr = &stat_save[0];
static struct unique_sections *unique_section_list;
/* Forward declarations. */
static void exp_init_os (etree_type *);
static lang_input_statement_type *lookup_name (const char *);
-static struct bfd_hash_entry *lang_definedness_newfunc
- (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
static void insert_undefined (const char *);
static bfd_boolean sort_def_symbol (struct bfd_link_hash_entry *, void *);
static void print_statement (lang_statement_union_type *,
abs_output_section->bfd_section = bfd_abs_section_ptr;
- /* The value "13" is ad-hoc, somewhat related to the expected number of
- assignments in a linker script. */
- if (!bfd_hash_table_init_n (&lang_definedness_table,
- lang_definedness_newfunc,
- sizeof (struct lang_definedness_hash_entry),
- 13))
- einfo (_("%P%F: can not create hash table: %E\n"));
-
asneeded_list_head = NULL;
asneeded_list_tail = &asneeded_list_head;
}
void
lang_finish (void)
{
- bfd_hash_table_free (&lang_definedness_table);
output_section_statement_table_free ();
}
einfo ("%F");
}
-/* New-function for the definedness hash table. */
-
-static struct bfd_hash_entry *
-lang_definedness_newfunc (struct bfd_hash_entry *entry,
- struct bfd_hash_table *table ATTRIBUTE_UNUSED,
- const char *name ATTRIBUTE_UNUSED)
-{
- struct lang_definedness_hash_entry *ret
- = (struct lang_definedness_hash_entry *) entry;
-
- if (ret == NULL)
- ret = (struct lang_definedness_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct lang_definedness_hash_entry));
-
- if (ret == NULL)
- einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name);
-
- ret->by_object = 0;
- ret->by_script = 0;
- ret->iteration = 0;
- return &ret->root;
-}
-
-/* Called during processing of linker script script expressions.
- For symbols assigned in a linker script, return a struct describing
- where the symbol is defined relative to the current expression,
- otherwise return NULL. */
-
-struct lang_definedness_hash_entry *
-lang_symbol_defined (const char *name)
-{
- return ((struct lang_definedness_hash_entry *)
- bfd_hash_lookup (&lang_definedness_table, name, FALSE, FALSE));
-}
-
-/* Update the definedness state of NAME. */
-
-void
-lang_update_definedness (const char *name, struct bfd_link_hash_entry *h)
-{
- struct lang_definedness_hash_entry *defentry
- = (struct lang_definedness_hash_entry *)
- bfd_hash_lookup (&lang_definedness_table, name, TRUE, FALSE);
-
- if (defentry == NULL)
- einfo (_("%P%F: bfd_hash_lookup failed creating symbol %s\n"), name);
-
- /* If the symbol was already defined, and not by a script, then it
- must be defined by an object file. */
- if (!defentry->by_script
- && h->type != bfd_link_hash_undefined
- && h->type != bfd_link_hash_common
- && h->type != bfd_link_hash_new)
- defentry->by_object = 1;
-
- defentry->by_script = 1;
- defentry->iteration = lang_statement_iteration;
-}
-
/* Add the supplied name to the symbol table as an undefined reference.
This is a two step process as the symbol table doesn't even exist at
the time the ld command line is processed. First we put the name
const char *name;
};
-/* This structure records symbols for which we need to keep track of
- definedness for use in the DEFINED () test. */
-
-struct lang_definedness_hash_entry
-{
- struct bfd_hash_entry root;
- unsigned int by_object : 1;
- unsigned int by_script : 1;
- unsigned int iteration : 1;
-};
-
/* Used by place_orphan to keep track of orphan sections and statements. */
struct orphan_save
(const char *);
extern const char *lang_get_output_target
(void);
-extern struct lang_definedness_hash_entry *lang_symbol_defined (const char *);
-extern void lang_update_definedness
- (const char *, struct bfd_link_hash_entry *);
-
extern void add_excluded_libs (const char *);
extern bfd_boolean load_symbols
(lang_input_statement_type *, lang_statement_list_type *);
config.maxpagesize = bfd_emul_get_maxpagesize (default_target);
config.commonpagesize = bfd_emul_get_commonpagesize (default_target);
lang_init ();
+ ldexp_init ();
ldemul_before_parse ();
lang_has_input_file = FALSE;
parse_args (argc, argv);
fprintf (stderr, "lookup = %p val %lx\n", h, h ? h->u.def.value : 1);
}
#endif
+ ldexp_finish ();
lang_finish ();
/* Even if we're producing relocatable output, some non-fatal errors should