diff options
-rw-r--r-- | ld/ChangeLog | 14 | ||||
-rw-r--r-- | ld/ldexp.c | 103 | ||||
-rw-r--r-- | ld/ldexp.h | 2 | ||||
-rw-r--r-- | ld/ldlang.c | 71 | ||||
-rw-r--r-- | ld/ldlang.h | 15 | ||||
-rw-r--r-- | ld/ldmain.c | 2 |
6 files changed, 114 insertions, 93 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index ce90a67..1492b8d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,17 @@ +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" @@ -48,6 +48,19 @@ segment_type *segments; 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. */ @@ -244,6 +257,64 @@ new_rel_from_abs (bfd_vma value) 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) { @@ -578,7 +649,7 @@ fold_name (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, @@ -588,7 +659,7 @@ fold_name (etree_type *tree) && (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))); } @@ -601,7 +672,7 @@ fold_name (etree_type *tree) /* 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, @@ -611,7 +682,7 @@ fold_name (etree_type *tree) && (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; } @@ -817,11 +888,11 @@ static bfd_boolean 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, @@ -1041,7 +1112,7 @@ exp_fold_tree_1 (etree_type *tree) /* 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) @@ -1470,3 +1541,21 @@ align_n (bfd_vma value, bfd_vma align) 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); +} @@ -221,5 +221,7 @@ fill_type *exp_get_fill (etree_type *, fill_type *, char *); bfd_vma exp_get_abs_int (etree_type *, int, char *); +void ldexp_init (void); +void ldexp_finish (void); #endif diff --git a/ld/ldlang.c b/ld/ldlang.c index c4da07f..d65e01a 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -64,7 +64,6 @@ static bfd_vma print_dot; 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; @@ -73,8 +72,6 @@ static struct asneeded_minfo *asneeded_list_head; /* 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 *, @@ -1241,14 +1238,6 @@ lang_init (void) 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; } @@ -1256,7 +1245,6 @@ lang_init (void) void lang_finish (void) { - bfd_hash_table_free (&lang_definedness_table); output_section_statement_table_free (); } @@ -3365,65 +3353,6 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) 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 diff --git a/ld/ldlang.h b/ld/ldlang.h index 5f6faae..87409cf 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -470,17 +470,6 @@ struct unique_sections 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 @@ -683,10 +672,6 @@ extern void lang_add_unique (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 *); diff --git a/ld/ldmain.c b/ld/ldmain.c index bc24957..818d108 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -297,6 +297,7 @@ main (int argc, char **argv) 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); @@ -440,6 +441,7 @@ main (int argc, char **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 |