diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elflink.c | 111 | ||||
-rw-r--r-- | bfd/elflink.h | 8 | ||||
-rw-r--r-- | include/ChangeLog | 12 | ||||
-rw-r--r-- | include/bfdlink.h | 37 |
5 files changed, 96 insertions, 79 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 2a002c166c2..2d47b54ed9e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2003-10-22 Jakub Jelinek <jakub@redhat.com> + + * elflink.c (_bfd_elf_export_symbol): Adjust for globals and locals + field changes. + (_bfd_elf_link_assign_sym_version): Likewise. + * elflink.h (size_dynamic_sections): Likewise. + 2003-10-21 Alexandre Oliva <aoliva@redhat.com>, Michael Snyder <msnyder@redhat.com> diff --git a/bfd/elflink.c b/bfd/elflink.c index 0e06903c4be..19f6d4d7b8b 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1505,22 +1505,18 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) for (t = eif->verdefs; t != NULL; t = t->next) { - if (t->globals != NULL) + if (t->globals.list != NULL) { - for (d = t->globals; d != NULL; d = d->next) - { - if ((*d->match) (d, h->root.root.string)) - goto doit; - } + d = (*t->match) (&t->globals, NULL, h->root.root.string); + if (d != NULL) + goto doit; } - if (t->locals != NULL) + if (t->locals.list != NULL) { - for (d = t->locals ; d != NULL; d = d->next) - { - if ((*d->match) (d, h->root.root.string)) - return TRUE; - } + d = (*t->match) (&t->locals, NULL, h->root.root.string); + if (d != NULL) + return TRUE; } } @@ -1699,31 +1695,19 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) t->used = TRUE; d = NULL; - if (t->globals != NULL) - { - for (d = t->globals; d != NULL; d = d->next) - if ((*d->match) (d, alc)) - break; - } + if (t->globals.list != NULL) + d = (*t->match) (&t->globals, NULL, alc); /* See if there is anything to force this symbol to local scope. */ - if (d == NULL && t->locals != NULL) + if (d == NULL && t->locals.list != NULL) { - for (d = t->locals; d != NULL; d = d->next) - { - if ((*d->match) (d, alc)) - { - if (h->dynindx != -1 - && info->shared - && ! info->export_dynamic) - { - (*bed->elf_backend_hide_symbol) (info, h, TRUE); - } - - break; - } - } + d = (*t->match) (&t->locals, NULL, alc); + if (d != NULL + && h->dynindx != -1 + && info->shared + && ! info->export_dynamic) + (*bed->elf_backend_hide_symbol) (info, h, TRUE); } free (alc); @@ -1744,18 +1728,14 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) return TRUE; amt = sizeof *t; - t = bfd_alloc (sinfo->output_bfd, amt); + t = bfd_zalloc (sinfo->output_bfd, amt); if (t == NULL) { sinfo->failed = TRUE; return FALSE; } - t->next = NULL; t->name = p; - t->globals = NULL; - t->locals = NULL; - t->deps = NULL; t->name_indx = (unsigned int) -1; t->used = TRUE; @@ -1801,30 +1781,26 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) local_ver = NULL; for (t = sinfo->verdefs; t != NULL; t = t->next) { - if (t->globals != NULL) + if (t->globals.list != NULL) { bfd_boolean matched; matched = FALSE; - for (d = t->globals; d != NULL; d = d->next) - { - if ((*d->match) (d, h->root.root.string)) - { - if (d->symver) - matched = TRUE; - else - { - /* There is a version without definition. Make - the symbol the default definition for this - version. */ - h->verinfo.vertree = t; - local_ver = NULL; - d->script = 1; - break; - } - } - } - + d = NULL; + while ((d = (*t->match) (&t->globals, d, + h->root.root.string)) != NULL) + if (d->symver) + matched = TRUE; + else + { + /* There is a version without definition. Make + the symbol the default definition for this + version. */ + h->verinfo.vertree = t; + local_ver = NULL; + d->script = 1; + break; + } if (d != NULL) break; else if (matched) @@ -1833,19 +1809,18 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) (*bed->elf_backend_hide_symbol) (info, h, TRUE); } - if (t->locals != NULL) + if (t->locals.list != NULL) { - for (d = t->locals; d != NULL; d = d->next) + d = NULL; + while ((d = (*t->match) (&t->locals, d, + h->root.root.string)) != NULL) { + local_ver = t; /* If the match is "*", keep looking for a more - explicit, perhaps even global, match. */ - if (d->pattern[0] == '*' && d->pattern[1] == '\0') - local_ver = t; - else if ((*d->match) (d, h->root.root.string)) - { - local_ver = t; - break; - } + explicit, perhaps even global, match. + XXX: Shouldn't this be !d->wildcard instead? */ + if (d->pattern[0] != '*' || d->pattern[1] != '\0') + break; } if (d != NULL) diff --git a/bfd/elflink.h b/bfd/elflink.h index 383cb88b068..e53911df855 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -2058,7 +2058,9 @@ NAME(bfd_elf,size_dynamic_sections) (bfd *output_bfd, /* Make all global versions with definiton. */ for (t = verdefs; t != NULL; t = t->next) - for (d = t->globals; d != NULL; d = d->next) + for (d = t->globals.list; d != NULL; d = d->next) + /* FIXME: Shouldn't this be !d->symver && d->wildcard == 0 + instead? */ if (!d->symver && strchr (d->pattern, '*') == NULL) { const char *verstr, *name; @@ -2124,7 +2126,7 @@ NAME(bfd_elf,size_dynamic_sections) (bfd *output_bfd, /* Check if all global versions have a definiton. */ all_defined = TRUE; for (t = verdefs; t != NULL; t = t->next) - for (d = t->globals; d != NULL; d = d->next) + for (d = t->globals.list; d != NULL; d = d->next) if (!d->symver && !d->script) { (*_bfd_error_handler) @@ -2372,7 +2374,7 @@ NAME(bfd_elf,size_dynamic_sections) (bfd *output_bfd, def.vd_version = VER_DEF_CURRENT; def.vd_flags = 0; - if (t->globals == NULL && t->locals == NULL && ! t->used) + if (t->globals.list == NULL && t->locals.list == NULL && ! t->used) def.vd_flags |= VER_FLG_WEAK; def.vd_ndx = t->vernum + 1; def.vd_cnt = cdeps + 1; diff --git a/include/ChangeLog b/include/ChangeLog index 34f66f05631..d1e9a1df72b 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,15 @@ +2003-10-22 Jakub Jelinek <jakub@redhat.com> + + * bfdlink.h (struct bfd_elf_version_expr): Remove match field. + Add wildcard and mask fields. + (BFD_ELF_VERSION_C_TYPE): Define. + (BFD_ELF_VERSION_CXX_TYPE): Likewise. + (BFD_ELF_VERSION_JAVA_TYPE): Likewise. + (struct bfd_elf_version_expr_head): New. + (struct bfd_elf_version_tree): Add match field. + Change type of globals and locals fields + to struct bfd_elf_version_expr_head. + 2003-10-14 Bob Wilson <bob.wilson@acm.org> * elf/xtensa.h: Formatting. Fix comments about property section diff --git a/include/bfdlink.h b/include/bfdlink.h index c174dcdc698..fd77c294442 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -617,20 +617,37 @@ extern struct bfd_link_order *bfd_new_link_order (bfd *, asection *); BFD, but it would be a pain. Instead, the regular linker sets up these structures, and then passes them into BFD. */ -/* Regular expressions for a version. */ +/* Glob pattern for a version. */ struct bfd_elf_version_expr { - /* Next regular expression for this version. */ + /* Next glob pattern for this version. */ struct bfd_elf_version_expr *next; - /* Regular expression. */ + /* Glob pattern. */ const char *pattern; - /* Matching function. */ - int (*match) (struct bfd_elf_version_expr *, const char *); /* Defined by ".symver". */ - unsigned int symver: 1; + unsigned int symver : 1; /* Defined by version script. */ unsigned int script : 1; + /* Is this a wildcard?. */ + unsigned int wildcard : 1; + /* Pattern type. */ +#define BFD_ELF_VERSION_C_TYPE 1 +#define BFD_ELF_VERSION_CXX_TYPE 2 +#define BFD_ELF_VERSION_JAVA_TYPE 4 + unsigned int mask : 3; +}; + +struct bfd_elf_version_expr_head +{ + /* List of all patterns, both wildcards and non-wildcards. */ + struct bfd_elf_version_expr *list; + /* Hash table for non-wildcards. */ + void *htab; + /* Remaining patterns. */ + struct bfd_elf_version_expr *remaining; + /* What kind of pattern types are present in list (bitmask). */ + unsigned int mask; }; /* Version dependencies. */ @@ -654,15 +671,19 @@ struct bfd_elf_version_tree /* Version number. */ unsigned int vernum; /* Regular expressions for global symbols in this version. */ - struct bfd_elf_version_expr *globals; + struct bfd_elf_version_expr_head globals; /* Regular expressions for local symbols in this version. */ - struct bfd_elf_version_expr *locals; + struct bfd_elf_version_expr_head locals; /* List of versions which this version depends upon. */ struct bfd_elf_version_deps *deps; /* Index of the version name. This is used within BFD. */ unsigned int name_indx; /* Whether this version tree was used. This is used within BFD. */ int used; + /* Matching hook. */ + struct bfd_elf_version_expr *(*match) + (struct bfd_elf_version_expr_head *head, + struct bfd_elf_version_expr *prev, const char *sym); }; #endif |