Added --identify option to dlltool.
This commit is contained in:
parent
da8bd9a3c5
commit
d4732f7c88
3 changed files with 239 additions and 6 deletions
|
@ -1,3 +1,16 @@
|
|||
2008-11-15 Charles Wilson <cygwin@cwilson.fastmail.fm>
|
||||
|
||||
Added --identify option to dlltool.
|
||||
* binutils/dlltool.c: Add new global variables
|
||||
identify_imp_name and identify_dll_name.
|
||||
(identify_dll_for_implib, identify_search_archive,
|
||||
identify_search_member, identify_process_section_p,
|
||||
identify_search_section): New functions.
|
||||
(usage): Added --identify.
|
||||
(long_options): Added --identify.
|
||||
(main): Handle --identify option.
|
||||
* binutils/doc/binutils.texi: Document --identify.
|
||||
|
||||
2008-11-14 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
Remove outdated mach-o specific tests.
|
||||
|
|
|
@ -352,6 +352,8 @@ static int no_idata4;
|
|||
static int no_idata5;
|
||||
static char *exp_name;
|
||||
static char *imp_name;
|
||||
static char *identify_imp_name;
|
||||
static char *identify_dll_name;
|
||||
static char *head_label;
|
||||
static char *imp_name_lab;
|
||||
static char *dll_name;
|
||||
|
@ -724,6 +726,11 @@ static bfd *make_one_lib_file (export_type *, int);
|
|||
static bfd *make_head (void);
|
||||
static bfd *make_tail (void);
|
||||
static void gen_lib_file (void);
|
||||
static void identify_dll_for_implib (void);
|
||||
static void identify_search_archive (bfd*);
|
||||
static void identify_search_member (bfd*, bfd*);
|
||||
static bfd_boolean identify_process_section_p (asection *);
|
||||
static void identify_search_section (bfd *, asection *, void *);
|
||||
static int pfunc (const void *, const void *);
|
||||
static int nfunc (const void *, const void *);
|
||||
static void remove_null_names (export_type **);
|
||||
|
@ -2918,6 +2925,193 @@ gen_lib_file (void)
|
|||
inform (_("Created lib file"));
|
||||
}
|
||||
|
||||
/* identify_dll_for_implib
|
||||
|
||||
This is the main implementation for the --identify option.
|
||||
Given the name of an import library in identify_imp_name,
|
||||
search all archive members for an .idata$7 section
|
||||
(.idata$6 on PPC). This section will consist of a single
|
||||
char* constant, indicating the name of the DLL represented
|
||||
by the import library.
|
||||
|
||||
It is possible to construct an import library that has
|
||||
two members with a non-empty .idata$7 section, but these
|
||||
are not often seen in normal operation. In this case,
|
||||
an error is flagged.
|
||||
*/
|
||||
static void
|
||||
identify_dll_for_implib (void)
|
||||
{
|
||||
bfd* abfd = NULL;
|
||||
|
||||
bfd_init ();
|
||||
|
||||
abfd = bfd_openr (identify_imp_name, 0);
|
||||
if (abfd == NULL)
|
||||
{
|
||||
bfd_fatal (identify_imp_name);
|
||||
}
|
||||
if (!bfd_check_format (abfd, bfd_archive))
|
||||
{
|
||||
if (!bfd_close (abfd))
|
||||
bfd_fatal (identify_imp_name);
|
||||
|
||||
fatal ("%s is not a library", identify_imp_name);
|
||||
}
|
||||
|
||||
identify_search_archive (abfd);
|
||||
|
||||
if (!bfd_close (abfd))
|
||||
bfd_fatal (identify_imp_name);
|
||||
|
||||
if (identify_dll_name && *identify_dll_name)
|
||||
{
|
||||
printf ("%s\n",identify_dll_name);
|
||||
free (identify_dll_name);
|
||||
identify_dll_name = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal ("Unable to determine dll name for %s (not an import library?)", identify_imp_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* identify_search_archive
|
||||
|
||||
Loop over all members of the archive, inspecting
|
||||
each for the presence of an .idata$7 (.idata$6 on PPC)
|
||||
section with non-empty contents.
|
||||
*/
|
||||
static void
|
||||
identify_search_archive (bfd* abfd)
|
||||
{
|
||||
bfd *arfile = NULL;
|
||||
bfd *last_arfile = NULL;
|
||||
char **matching;
|
||||
|
||||
while (1)
|
||||
{
|
||||
arfile = bfd_openr_next_archived_file (abfd, arfile);
|
||||
|
||||
if (arfile == NULL)
|
||||
{
|
||||
if (bfd_get_error () != bfd_error_no_more_archived_files)
|
||||
bfd_fatal (bfd_get_filename (abfd));
|
||||
break;
|
||||
}
|
||||
if (bfd_check_format_matches (arfile, bfd_object, &matching))
|
||||
{
|
||||
identify_search_member (arfile, abfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_nonfatal (bfd_get_filename (arfile));
|
||||
free (matching);
|
||||
}
|
||||
if (last_arfile != NULL)
|
||||
{
|
||||
bfd_close (last_arfile);
|
||||
}
|
||||
last_arfile = arfile;
|
||||
}
|
||||
|
||||
if (last_arfile != NULL)
|
||||
{
|
||||
bfd_close (last_arfile);
|
||||
}
|
||||
}
|
||||
|
||||
/* identify_search_member
|
||||
|
||||
Search all sections of an archive member for the
|
||||
one with section name of .idata$7 (.idata$6 on PPC)
|
||||
and non-empty contents.
|
||||
*/
|
||||
static void
|
||||
identify_search_member (bfd* abfd, bfd* archive_bfd ATTRIBUTE_UNUSED)
|
||||
{
|
||||
bfd_map_over_sections (abfd, identify_search_section, NULL);
|
||||
}
|
||||
|
||||
/* identify_process_section_p
|
||||
|
||||
This predicate returns true if section->name
|
||||
is .idata$7 (.idata$6 on PPC).
|
||||
*/
|
||||
static bfd_boolean
|
||||
identify_process_section_p (asection * section)
|
||||
{
|
||||
static const char * SECTION_NAME =
|
||||
#ifdef DLLTOOL_PPC
|
||||
/* dllname is stored in idata$6 on PPC */
|
||||
".idata$6";
|
||||
#else
|
||||
".idata$7";
|
||||
#endif
|
||||
|
||||
if (strcmp (SECTION_NAME, section->name) == 0)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* identify_search_section
|
||||
|
||||
If *section has contents and its name is .idata$7
|
||||
(.data$6 on PPC) then store the contents in
|
||||
identify_dll_name as an xmalloc'ed array.
|
||||
|
||||
However, if identify_dll_name already has
|
||||
a value, flag an error. We don't know how to handle
|
||||
import libraries that directly reference more than
|
||||
one DLL. (This is different than forwarded symbols.
|
||||
Such import libraries are not seen in normal operation,
|
||||
and must be specifically constructed.)
|
||||
*/
|
||||
static void
|
||||
identify_search_section (bfd *abfd, asection *section, void *dummy ATTRIBUTE_UNUSED)
|
||||
{
|
||||
bfd_byte *data = 0;
|
||||
bfd_size_type datasize;
|
||||
|
||||
if ((section->flags & SEC_HAS_CONTENTS) == 0)
|
||||
return;
|
||||
|
||||
if (! identify_process_section_p (section))
|
||||
return;
|
||||
|
||||
if ((datasize = bfd_section_size (abfd, section)) == 0)
|
||||
return;
|
||||
|
||||
data = (bfd_byte*) xmalloc (datasize + 1);
|
||||
data[0] = '\0';
|
||||
|
||||
bfd_get_section_contents (abfd, section, data, 0, datasize);
|
||||
data[datasize] = '\0';
|
||||
|
||||
if (data[0] != '\0')
|
||||
{
|
||||
if (identify_dll_name != NULL)
|
||||
{
|
||||
if (*identify_dll_name != '\0')
|
||||
{
|
||||
/* The import library specifies two different DLLs.
|
||||
Treat this as an error. */
|
||||
fatal ("Import library `%s' specifies two or more dlls: `%s' and `%s'",
|
||||
identify_imp_name, identify_dll_name, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For some reason memory was allocated, but the
|
||||
contents were empty. Free the memory and continue. */
|
||||
free (identify_dll_name);
|
||||
}
|
||||
}
|
||||
identify_dll_name = (char*) xstrdup (data);
|
||||
}
|
||||
|
||||
free (data);
|
||||
}
|
||||
|
||||
/* Run through the information gathered from the .o files and the
|
||||
.def file and work out the best stuff. */
|
||||
|
||||
|
@ -3171,6 +3365,7 @@ usage (FILE *file, int status)
|
|||
fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n"));
|
||||
fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n"));
|
||||
fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n"));
|
||||
fprintf (file, _(" -I --identify <implib> Report the name of the DLL associated with <implib>.\n"));
|
||||
fprintf (file, _(" -v --verbose Be verbose.\n"));
|
||||
fprintf (file, _(" -V --version Display the program version.\n"));
|
||||
fprintf (file, _(" -h --help Display this information.\n"));
|
||||
|
@ -3211,6 +3406,7 @@ static const struct option long_options[] =
|
|||
{"kill-at", no_argument, NULL, 'k'},
|
||||
{"add-stdcall-alias", no_argument, NULL, 'A'},
|
||||
{"ext-prefix-alias", required_argument, NULL, 'p'},
|
||||
{"identify", required_argument, NULL, 'I'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
|
@ -3249,9 +3445,9 @@ main (int ac, char **av)
|
|||
|
||||
while ((c = getopt_long (ac, av,
|
||||
#ifdef DLLTOOL_MCORE_ELF
|
||||
"m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHhM:L:F:",
|
||||
"m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHhM:L:F:",
|
||||
#else
|
||||
"m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHh",
|
||||
"m:e:l:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
|
||||
#endif
|
||||
long_options, 0))
|
||||
!= EOF)
|
||||
|
@ -3317,6 +3513,9 @@ main (int ac, char **av)
|
|||
case 'm':
|
||||
mname = optarg;
|
||||
break;
|
||||
case 'I':
|
||||
identify_imp_name = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
|
@ -3440,6 +3639,11 @@ main (int ac, char **av)
|
|||
if (output_def)
|
||||
gen_def_file ();
|
||||
|
||||
if (identify_imp_name)
|
||||
{
|
||||
identify_dll_for_implib ();
|
||||
}
|
||||
|
||||
#ifdef DLLTOOL_MCORE_ELF
|
||||
if (mcore_elf_out_file)
|
||||
mcore_elf_gen_out_file ();
|
||||
|
|
|
@ -3371,7 +3371,8 @@ dlltool [@option{-d}|@option{--input-def} @var{def-file-name}]
|
|||
[@option{-U}|@option{--add-underscore}] [@option{--add-stdcall-underscore}]
|
||||
[@option{-k}|@option{--kill-at}] [@option{-A}|@option{--add-stdcall-alias}]
|
||||
[@option{-p}|@option{--ext-prefix-alias} @var{prefix}]
|
||||
[@option{-x}|@option{--no-idata4}] [@option{-c}|@option{--no-idata5}] [@option{-i}|@option{--interwork}]
|
||||
[@option{-x}|@option{--no-idata4}] [@option{-c}|@option{--no-idata5}]
|
||||
[@option{-I}|@option{--identify} @var{library-file-name}] [@option{-i}|@option{--interwork}]
|
||||
[@option{-n}|@option{--nodelete}] [@option{-t}|@option{--temp-prefix} @var{prefix}]
|
||||
[@option{-v}|@option{--verbose}]
|
||||
[@option{-h}|@option{--help}] [@option{-V}|@option{--version}]
|
||||
|
@ -3421,9 +3422,9 @@ binary file and it can be created by giving the @option{-e} option to
|
|||
@command{dlltool} when it is creating or reading in a @file{.def} file.
|
||||
|
||||
The third file needed for DLL creation is the library file that programs
|
||||
will link with in order to access the functions in the DLL. This file
|
||||
can be created by giving the @option{-l} option to dlltool when it
|
||||
is creating or reading in a @file{.def} file.
|
||||
will link with in order to access the functions in the DLL (an `import
|
||||
library'). This file can be created by giving the @option{-l} option to
|
||||
dlltool when it is creating or reading in a @file{.def} file.
|
||||
|
||||
@command{dlltool} builds the library file by hand, but it builds the
|
||||
exports file by creating temporary files containing assembler statements
|
||||
|
@ -3446,6 +3447,11 @@ that uses that DLL:
|
|||
gcc program.o dll.lib -o program
|
||||
@end smallexample
|
||||
|
||||
|
||||
@command{dlltool} may also be used to query an existing import library
|
||||
to determine the name of the DLL to which it is associated. See the
|
||||
description of the @option{-I} or @option{--identify} option.
|
||||
|
||||
@c man end
|
||||
|
||||
@c man begin OPTIONS dlltool
|
||||
|
@ -3585,6 +3591,16 @@ Specifies that when @command{dlltool} is creating the exports and library
|
|||
files it should omit the @code{.idata5} section. This is for compatibility
|
||||
with certain operating systems.
|
||||
|
||||
@item -I @var{filename}
|
||||
@itemx --identify @var{filename}
|
||||
Specifies that @command{dlltool} should inspect the import library
|
||||
indicated by @var{filename} and report, on @code{stdout}, the name of
|
||||
the associated DLL. This can be performed in addition to any other
|
||||
operations indicated by the other options and arguments. @command{dlltool}
|
||||
@option{--identify} fails if the import library does not exist, is not
|
||||
actually an import library, or (rarely) if the import library somehow
|
||||
specifies more than one associated DLL.
|
||||
|
||||
@item -i
|
||||
@itemx --interwork
|
||||
Specifies that @command{dlltool} should mark the objects in the library
|
||||
|
|
Loading…
Add table
Reference in a new issue