mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-30 13:33:53 +08:00
2011-04-13 Kai Tietz <ktietz@redhat.com>
PR binutils/12658 * deffile.h (def_file_add_export): Add is_dup argument. (def_file_add_import): Likewise. * deffilep.y (are_names_equal): New helper. (cmp_export_elem): New helper. (find_export_in_list): Add search routine for exports. (def_file_add_export): Check for duplicates. (cmp_import_elem): New helper. (find_import_in_list): Add search routine for imports. (def_file_add_import): Check for duplicates. (def_exports): Handle duplicates. (def_imports): Likewise. * pe-dll.c (process_def_file_and_drectve): Likewise. (pe_implied_import_dll): Likewise.
This commit is contained in:
parent
7f880bc3d4
commit
db17156eaa
17
ld/ChangeLog
17
ld/ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
2011-04-13 Kai Tietz <ktietz@redhat.com>
|
||||||
|
|
||||||
|
PR binutils/12658
|
||||||
|
* deffile.h (def_file_add_export): Add is_dup argument.
|
||||||
|
(def_file_add_import): Likewise.
|
||||||
|
* deffilep.y (are_names_equal): New helper.
|
||||||
|
(cmp_export_elem): New helper.
|
||||||
|
(find_export_in_list): Add search routine for exports.
|
||||||
|
(def_file_add_export): Check for duplicates.
|
||||||
|
(cmp_import_elem): New helper.
|
||||||
|
(find_import_in_list): Add search routine for imports.
|
||||||
|
(def_file_add_import): Check for duplicates.
|
||||||
|
(def_exports): Handle duplicates.
|
||||||
|
(def_imports): Likewise.
|
||||||
|
* pe-dll.c (process_def_file_and_drectve): Likewise.
|
||||||
|
(pe_implied_import_dll): Likewise.
|
||||||
|
|
||||||
2011-04-11 Chris Quenelle <chris.quenelle@oracle.com>
|
2011-04-11 Chris Quenelle <chris.quenelle@oracle.com>
|
||||||
|
|
||||||
* scripttempl/elf.sc (.exception_ranges): Add new section.
|
* scripttempl/elf.sc (.exception_ranges): Add new section.
|
||||||
|
@ -105,10 +105,10 @@ extern def_file *def_file_parse (const char *, def_file *);
|
|||||||
extern void def_file_free (def_file *);
|
extern void def_file_free (def_file *);
|
||||||
extern def_file_export *def_file_add_export (def_file *, const char *,
|
extern def_file_export *def_file_add_export (def_file *, const char *,
|
||||||
const char *, int,
|
const char *, int,
|
||||||
const char *);
|
const char *, int *);
|
||||||
extern def_file_import *def_file_add_import (def_file *, const char *,
|
extern def_file_import *def_file_add_import (def_file *, const char *,
|
||||||
const char *, int, const char *,
|
const char *, int, const char *,
|
||||||
const char *);
|
const char *, int *);
|
||||||
extern void def_file_add_directive (def_file *, const char *, int);
|
extern void def_file_add_directive (def_file *, const char *, int);
|
||||||
extern def_file_module *def_get_module (def_file *, const char *);
|
extern def_file_module *def_get_module (def_file *, const char *);
|
||||||
#ifdef DEF_FILE_PRINT
|
#ifdef DEF_FILE_PRINT
|
||||||
|
191
ld/deffilep.y
191
ld/deffilep.y
@ -534,16 +534,105 @@ def_file_print (FILE *file, def_file *fdef)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Helper routine to check for identity of string pointers,
|
||||||
|
which might be NULL. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
are_names_equal (const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
if (!s1 && !s2)
|
||||||
|
return 0;
|
||||||
|
if (!s1 || !s2)
|
||||||
|
return (!s1 ? -1 : 1);
|
||||||
|
return strcmp (s1, s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmp_export_elem (const def_file_export *e, const char *ex_name,
|
||||||
|
const char *in_name, const char *its_name,
|
||||||
|
int ord)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = are_names_equal (ex_name, e->name)) != 0)
|
||||||
|
return r;
|
||||||
|
if ((r = are_names_equal (in_name, e->internal_name)) != 0)
|
||||||
|
return r;
|
||||||
|
if ((r = are_names_equal (its_name, e->its_name)) != 0)
|
||||||
|
return r;
|
||||||
|
return (ord - e->ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search the position of the identical element, or returns the position
|
||||||
|
of the next higher element. If last valid element is smaller, then MAX
|
||||||
|
is returned. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_export_in_list (def_file_export *b, int max,
|
||||||
|
const char *ex_name, const char *in_name,
|
||||||
|
const char *its_name, int ord, int *is_ident)
|
||||||
|
{
|
||||||
|
int e, l, r, p;
|
||||||
|
|
||||||
|
*is_ident = 0;
|
||||||
|
if (!max)
|
||||||
|
return 0;
|
||||||
|
if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
|
||||||
|
return 0;
|
||||||
|
if (max == 1)
|
||||||
|
return 1;
|
||||||
|
if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
|
||||||
|
return max;
|
||||||
|
else if (!e || max == 2)
|
||||||
|
return max - 1;
|
||||||
|
l = 0; r = max - 1;
|
||||||
|
while (l < r)
|
||||||
|
{
|
||||||
|
p = (l + r) / 2;
|
||||||
|
e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
|
||||||
|
if (!e)
|
||||||
|
{
|
||||||
|
*is_ident = 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
else if (e < 0)
|
||||||
|
r = p - 1;
|
||||||
|
else if (e > 0)
|
||||||
|
l = p + 1;
|
||||||
|
}
|
||||||
|
if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
|
||||||
|
++l;
|
||||||
|
else if (!e)
|
||||||
|
*is_ident = 1;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
def_file_export *
|
def_file_export *
|
||||||
def_file_add_export (def_file *fdef,
|
def_file_add_export (def_file *fdef,
|
||||||
const char *external_name,
|
const char *external_name,
|
||||||
const char *internal_name,
|
const char *internal_name,
|
||||||
int ordinal,
|
int ordinal,
|
||||||
const char *its_name)
|
const char *its_name,
|
||||||
|
int *is_dup)
|
||||||
{
|
{
|
||||||
def_file_export *e;
|
def_file_export *e;
|
||||||
|
int pos;
|
||||||
int max_exports = ROUND_UP(fdef->num_exports, 32);
|
int max_exports = ROUND_UP(fdef->num_exports, 32);
|
||||||
|
|
||||||
|
if (internal_name && !external_name)
|
||||||
|
external_name = internal_name;
|
||||||
|
if (external_name && !internal_name)
|
||||||
|
internal_name = external_name;
|
||||||
|
|
||||||
|
/* We need to avoid duplicates. */
|
||||||
|
*is_dup = 0;
|
||||||
|
pos = find_export_in_list (fdef->exports, fdef->num_exports,
|
||||||
|
external_name, internal_name,
|
||||||
|
its_name, ordinal, is_dup);
|
||||||
|
|
||||||
|
if (*is_dup != 0)
|
||||||
|
return (fdef->exports + pos);
|
||||||
|
|
||||||
if (fdef->num_exports >= max_exports)
|
if (fdef->num_exports >= max_exports)
|
||||||
{
|
{
|
||||||
max_exports = ROUND_UP(fdef->num_exports + 1, 32);
|
max_exports = ROUND_UP(fdef->num_exports + 1, 32);
|
||||||
@ -553,12 +642,11 @@ def_file_add_export (def_file *fdef,
|
|||||||
else
|
else
|
||||||
fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
|
fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
|
||||||
}
|
}
|
||||||
e = fdef->exports + fdef->num_exports;
|
|
||||||
|
e = fdef->exports + pos;
|
||||||
|
if (pos != fdef->num_exports)
|
||||||
|
memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
|
||||||
memset (e, 0, sizeof (def_file_export));
|
memset (e, 0, sizeof (def_file_export));
|
||||||
if (internal_name && !external_name)
|
|
||||||
external_name = internal_name;
|
|
||||||
if (external_name && !internal_name)
|
|
||||||
internal_name = external_name;
|
|
||||||
e->name = xstrdup (external_name);
|
e->name = xstrdup (external_name);
|
||||||
e->internal_name = xstrdup (internal_name);
|
e->internal_name = xstrdup (internal_name);
|
||||||
e->its_name = (its_name ? xstrdup (its_name) : NULL);
|
e->its_name = (its_name ? xstrdup (its_name) : NULL);
|
||||||
@ -594,17 +682,88 @@ def_stash_module (def_file *fdef, const char *name)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cmp_import_elem (const def_file_import *e, const char *ex_name,
|
||||||
|
const char *in_name, const char *module,
|
||||||
|
int ord)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if ((r = are_names_equal (ex_name, e->name)) != 0)
|
||||||
|
return r;
|
||||||
|
if ((r = are_names_equal (in_name, e->internal_name)) != 0)
|
||||||
|
return r;
|
||||||
|
if (ord != e->ordinal)
|
||||||
|
return (ord < e->ordinal ? -1 : 1);
|
||||||
|
return are_names_equal (module, (e->module ? e->module->name : NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search the position of the identical element, or returns the position
|
||||||
|
of the next higher element. If last valid element is smaller, then MAX
|
||||||
|
is returned. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_import_in_list (def_file_import *b, int max,
|
||||||
|
const char *ex_name, const char *in_name,
|
||||||
|
const char *module, int ord, int *is_ident)
|
||||||
|
{
|
||||||
|
int e, l, r, p;
|
||||||
|
|
||||||
|
*is_ident = 0;
|
||||||
|
if (!max)
|
||||||
|
return 0;
|
||||||
|
if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
|
||||||
|
return 0;
|
||||||
|
if (max == 1)
|
||||||
|
return 1;
|
||||||
|
if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
|
||||||
|
return max;
|
||||||
|
else if (!e || max == 2)
|
||||||
|
return max - 1;
|
||||||
|
l = 0; r = max - 1;
|
||||||
|
while (l < r)
|
||||||
|
{
|
||||||
|
p = (l + r) / 2;
|
||||||
|
e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
|
||||||
|
if (!e)
|
||||||
|
{
|
||||||
|
*is_ident = 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
else if (e < 0)
|
||||||
|
r = p - 1;
|
||||||
|
else if (e > 0)
|
||||||
|
l = p + 1;
|
||||||
|
}
|
||||||
|
if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
|
||||||
|
++l;
|
||||||
|
else if (!e)
|
||||||
|
*is_ident = 1;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
def_file_import *
|
def_file_import *
|
||||||
def_file_add_import (def_file *fdef,
|
def_file_add_import (def_file *fdef,
|
||||||
const char *name,
|
const char *name,
|
||||||
const char *module,
|
const char *module,
|
||||||
int ordinal,
|
int ordinal,
|
||||||
const char *internal_name,
|
const char *internal_name,
|
||||||
const char *its_name)
|
const char *its_name,
|
||||||
|
int *is_dup)
|
||||||
{
|
{
|
||||||
def_file_import *i;
|
def_file_import *i;
|
||||||
|
int pos;
|
||||||
int max_imports = ROUND_UP (fdef->num_imports, 16);
|
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 ? name : internal_name),
|
||||||
|
module, ordinal, is_dup);
|
||||||
|
if (*is_dup != 0)
|
||||||
|
return fdef->imports + pos;
|
||||||
|
|
||||||
if (fdef->num_imports >= max_imports)
|
if (fdef->num_imports >= max_imports)
|
||||||
{
|
{
|
||||||
max_imports = ROUND_UP (fdef->num_imports+1, 16);
|
max_imports = ROUND_UP (fdef->num_imports+1, 16);
|
||||||
@ -615,7 +774,9 @@ def_file_add_import (def_file *fdef,
|
|||||||
else
|
else
|
||||||
fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
|
fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
|
||||||
}
|
}
|
||||||
i = fdef->imports + fdef->num_imports;
|
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));
|
memset (i, 0, sizeof (def_file_import));
|
||||||
if (name)
|
if (name)
|
||||||
i->name = xstrdup (name);
|
i->name = xstrdup (name);
|
||||||
@ -849,6 +1010,7 @@ def_exports (const char *external_name,
|
|||||||
const char *its_name)
|
const char *its_name)
|
||||||
{
|
{
|
||||||
def_file_export *dfe;
|
def_file_export *dfe;
|
||||||
|
int is_dup = 0;
|
||||||
|
|
||||||
if (!internal_name && external_name)
|
if (!internal_name && external_name)
|
||||||
internal_name = external_name;
|
internal_name = external_name;
|
||||||
@ -857,7 +1019,13 @@ def_exports (const char *external_name,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
dfe = def_file_add_export (def, external_name, internal_name, ordinal,
|
dfe = def_file_add_export (def, external_name, internal_name, ordinal,
|
||||||
its_name);
|
its_name, &is_dup);
|
||||||
|
|
||||||
|
/* We might check here for flag redefinition and warn. For now we
|
||||||
|
ignore duplicates silently. */
|
||||||
|
if (is_dup)
|
||||||
|
return;
|
||||||
|
|
||||||
if (flags & 1)
|
if (flags & 1)
|
||||||
dfe->flag_noname = 1;
|
dfe->flag_noname = 1;
|
||||||
if (flags & 2)
|
if (flags & 2)
|
||||||
@ -878,13 +1046,14 @@ def_import (const char *internal_name,
|
|||||||
{
|
{
|
||||||
char *buf = 0;
|
char *buf = 0;
|
||||||
const char *ext = dllext ? dllext : "dll";
|
const char *ext = dllext ? dllext : "dll";
|
||||||
|
int is_dup = 0;
|
||||||
|
|
||||||
buf = xmalloc (strlen (module) + strlen (ext) + 2);
|
buf = xmalloc (strlen (module) + strlen (ext) + 2);
|
||||||
sprintf (buf, "%s.%s", module, ext);
|
sprintf (buf, "%s.%s", module, ext);
|
||||||
module = buf;
|
module = buf;
|
||||||
|
|
||||||
def_file_add_import (def, name, module, ordinal, internal_name, its_name);
|
def_file_add_import (def, name, module, ordinal, internal_name, its_name,
|
||||||
if (buf)
|
&is_dup);
|
||||||
free (buf);
|
free (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
14
ld/pe-dll.c
14
ld/pe-dll.c
@ -751,9 +751,12 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
|
|||||||
|
|
||||||
if (auto_export (b, pe_def_file, sn))
|
if (auto_export (b, pe_def_file, sn))
|
||||||
{
|
{
|
||||||
|
int is_dup = 0;
|
||||||
def_file_export *p;
|
def_file_export *p;
|
||||||
p=def_file_add_export (pe_def_file, sn, 0, -1, NULL);
|
p = def_file_add_export (pe_def_file, sn, 0, -1,
|
||||||
|
NULL, &is_dup);
|
||||||
/* Fill data flag properly, from dlltool.c. */
|
/* Fill data flag properly, from dlltool.c. */
|
||||||
|
if (!is_dup)
|
||||||
p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
|
p->flag_data = !(symbols[j]->flags & BSF_FUNCTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,6 +804,7 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
|
|||||||
|
|
||||||
if (strchr (pe_def_file->exports[i].name, '@'))
|
if (strchr (pe_def_file->exports[i].name, '@'))
|
||||||
{
|
{
|
||||||
|
int is_dup = 1;
|
||||||
int lead_at = (*pe_def_file->exports[i].name == '@');
|
int lead_at = (*pe_def_file->exports[i].name == '@');
|
||||||
char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
|
char *tmp = xstrdup (pe_def_file->exports[i].name + lead_at);
|
||||||
|
|
||||||
@ -808,8 +812,8 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
|
|||||||
if (auto_export (NULL, pe_def_file, tmp))
|
if (auto_export (NULL, pe_def_file, tmp))
|
||||||
def_file_add_export (pe_def_file, tmp,
|
def_file_add_export (pe_def_file, tmp,
|
||||||
pe_def_file->exports[i].internal_name,
|
pe_def_file->exports[i].internal_name,
|
||||||
-1, NULL);
|
-1, NULL, &is_dup);
|
||||||
else
|
if (is_dup)
|
||||||
free (tmp);
|
free (tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3146,6 +3150,7 @@ pe_implied_import_dll (const char *filename)
|
|||||||
exported in buggy auto-import releases. */
|
exported in buggy auto-import releases. */
|
||||||
if (! CONST_STRNEQ (erva + name_rva, "__nm_"))
|
if (! CONST_STRNEQ (erva + name_rva, "__nm_"))
|
||||||
{
|
{
|
||||||
|
int is_dup = 0;
|
||||||
/* is_data is true if the address is in the data, rdata or bss
|
/* is_data is true if the address is in the data, rdata or bss
|
||||||
segment. */
|
segment. */
|
||||||
is_data =
|
is_data =
|
||||||
@ -3154,8 +3159,9 @@ pe_implied_import_dll (const char *filename)
|
|||||||
|| (func_rva >= bss_start && func_rva < bss_end);
|
|| (func_rva >= bss_start && func_rva < bss_end);
|
||||||
|
|
||||||
imp = def_file_add_import (pe_def_file, erva + name_rva,
|
imp = def_file_add_import (pe_def_file, erva + name_rva,
|
||||||
dllname, i, 0, NULL);
|
dllname, i, 0, NULL, &is_dup);
|
||||||
/* Mark symbol type. */
|
/* Mark symbol type. */
|
||||||
|
if (!is_dup)
|
||||||
imp->data = is_data;
|
imp->data = is_data;
|
||||||
|
|
||||||
if (pe_dll_extra_pe_debug)
|
if (pe_dll_extra_pe_debug)
|
||||||
|
Loading…
Reference in New Issue
Block a user