diff options
Diffstat (limited to 'ld/deffilep.y')
-rw-r--r-- | ld/deffilep.y | 100 |
1 files changed, 88 insertions, 12 deletions
diff --git a/ld/deffilep.y b/ld/deffilep.y index 1931c00..1aebdf6 100644 --- a/ld/deffilep.y +++ b/ld/deffilep.y @@ -816,6 +816,26 @@ find_import_in_list (def_file_import *b, int max, return l; } +static void +fill_in_import (def_file_import *i, + const char *name, + def_file_module *module, + int ordinal, + const char *internal_name, + const char *its_name) +{ + memset (i, 0, sizeof (def_file_import)); + if (name) + i->name = xstrdup (name); + i->module = module; + i->ordinal = ordinal; + if (internal_name) + i->internal_name = xstrdup (internal_name); + else + i->internal_name = i->name; + i->its_name = (its_name ? xstrdup (its_name) : NULL); +} + def_file_import * def_file_add_import (def_file *fdef, const char *name, @@ -850,18 +870,74 @@ def_file_add_import (def_file *fdef, } i = fdef->imports + pos; if (pos != fdef->num_imports) - memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos))); - memset (i, 0, sizeof (def_file_import)); - if (name) - i->name = xstrdup (name); - if (module) - i->module = def_stash_module (fdef, module); - i->ordinal = ordinal; - if (internal_name) - i->internal_name = xstrdup (internal_name); - else - i->internal_name = i->name; - i->its_name = (its_name ? xstrdup (its_name) : NULL); + memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos)); + + fill_in_import (i, name, def_stash_module (fdef, module), ordinal, + internal_name, its_name); + fdef->num_imports++; + + return i; +} + +int +def_file_add_import_from (def_file *fdef, + int num_imports, + const char *name, + const char *module, + int ordinal, + const char *internal_name, + const char *its_name ATTRIBUTE_UNUSED) +{ + def_file_import *i; + int is_dup; + int pos; + int max_imports = ROUND_UP (fdef->num_imports, 16); + + /* We need to avoid here duplicates. */ + is_dup = 0; + pos = find_import_in_list (fdef->imports, fdef->num_imports, + name, internal_name ? internal_name : name, + module, ordinal, &is_dup); + if (is_dup != 0) + return -1; + if (fdef->imports && pos != fdef->num_imports) + { + i = fdef->imports + pos; + if (i->module && strcmp (i->module->name, module) == 0) + return -1; + } + + if (fdef->num_imports + num_imports - 1 >= max_imports) + { + max_imports = ROUND_UP (fdef->num_imports + num_imports, 16); + + if (fdef->imports) + fdef->imports = xrealloc (fdef->imports, + max_imports * sizeof (def_file_import)); + else + fdef->imports = xmalloc (max_imports * sizeof (def_file_import)); + } + i = fdef->imports + pos; + if (pos != fdef->num_imports) + memmove (i + num_imports, i, + sizeof (def_file_import) * (fdef->num_imports - pos)); + + return pos; +} + +def_file_import * +def_file_add_import_at (def_file *fdef, + int pos, + const char *name, + const char *module, + int ordinal, + const char *internal_name, + const char *its_name) +{ + def_file_import *i = fdef->imports + pos; + + fill_in_import (i, name, def_stash_module (fdef, module), ordinal, + internal_name, its_name); fdef->num_imports++; return i; |