diff options
author | Dave Korn <dave.korn@artimi.com> | 2009-01-03 18:04:16 +0000 |
---|---|---|
committer | Dave Korn <dave.korn@artimi.com> | 2009-01-03 18:04:16 +0000 |
commit | e1c37eb57ebf5a431a508918321a1f07fc3025ac (patch) | |
tree | 1c0e7f13e930c5711dedf5f40a7567ebd84ac99c /ld/pe-dll.c | |
parent | b4f8c801a1170949157e08f5d7c8ca5bd4b22804 (diff) | |
download | fsf-binutils-gdb-e1c37eb57ebf5a431a508918321a1f07fc3025ac.zip fsf-binutils-gdb-e1c37eb57ebf5a431a508918321a1f07fc3025ac.tar.gz fsf-binutils-gdb-e1c37eb57ebf5a431a508918321a1f07fc3025ac.tar.bz2 |
* NEWS: Mention new feature --exclude-modules-for-implib.
* ld.texinfo: Document new --exclude-modules-for-implib option.
* pe-dll.c (exclude_list_struct): Change type member from int to
new enumeration exclude_type.
(pe_dll_add_excludes): Accept exclude_type instead of int param.
(auto_export): Replace magic constants by exclude_type values and
handle new choice EXCLUDEFORIMPLIB.
(pe_dll_generate_implib): Accept a pointer to the link_info and
iterate all input BFDs looking for EXCLUDEFORIMPLIB modules; re-open
fresh BFDs for any found and link into import lib archive chain.
* pe-dll.h (exclude_type): Add new enumerated type to replace magic
constants previously used for exclude_list_struct type member.
(pe_dll_add_excludes, pe_dll_generate_implib): Update prototypes.
* pep-dll.h (exclude_type, pe_dll_add_excludes,
pe_dll_generate_implib): Likewise to all the above.
* emultempl/pe.em (OPTION_EXCLUDE_MODULES_FOR_IMPLIB): Define new
getopts long option code for new --exclude-modules-for-implib option.
(gld${EMULATION_NAME}_add_options): Add new entry to xtra_long[].
(gld_${EMULATION_NAME}_list_options): List usage for it.
(gld${EMULATION_NAME}_handle_option): Use exclude_type enumerated
values when calling pe_dll_add_excludes, and handle EXCLUDEFORIMPLIB.
(gld_${EMULATION_NAME}_finish): Pass pointer to link_info when
calling pe_dll_generate_implib.
* emultempl/pep.em (options): Define new enumerated value for getopts
long option code for new --exclude-modules-for-implib option.
(gld${EMULATION_NAME}_add_options, gld_${EMULATION_NAME}_list_options,
gld${EMULATION_NAME}_handle_option, gld_${EMULATION_NAME}_finish):
Again, likewise to all the above.
Diffstat (limited to 'ld/pe-dll.c')
-rw-r--r-- | ld/pe-dll.c | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/ld/pe-dll.c b/ld/pe-dll.c index de43e34..d76d0cf 100644 --- a/ld/pe-dll.c +++ b/ld/pe-dll.c @@ -463,14 +463,14 @@ typedef struct exclude_list_struct { char *string; struct exclude_list_struct *next; - int type; + exclude_type type; } exclude_list_struct; static struct exclude_list_struct *excludes = 0; void -pe_dll_add_excludes (const char *new_excludes, const int type) +pe_dll_add_excludes (const char *new_excludes, const exclude_type type) { char *local_copy; char *exclude_string; @@ -593,13 +593,18 @@ auto_export (bfd *abfd, def_file *d, const char *n) for (ex = excludes; ex; ex = ex->next) { - if (ex->type == 1) /* exclude-libs */ + if (ex->type == EXCLUDELIBS) { if (libname && ((strcmp (libname, ex->string) == 0) || (strcasecmp ("ALL", ex->string) == 0))) return 0; } + else if (ex->type == EXCLUDEFORIMPLIB) + { + if (strcmp (abfd->filename, ex->string) == 0) + return 0; + } else if (strcmp (n, ex->string) == 0) return 0; } @@ -2480,12 +2485,13 @@ pe_create_import_fixup (arelent *rel, asection *s, bfd_vma addend) void -pe_dll_generate_implib (def_file *def, const char *impfilename) +pe_dll_generate_implib (def_file *def, const char *impfilename, struct bfd_link_info *info) { int i; bfd *ar_head; bfd *ar_tail; bfd *outarch; + bfd *ibfd; bfd *head = 0; dll_filename = (def->name) ? def->name : dll_name; @@ -2514,6 +2520,61 @@ pe_dll_generate_implib (def_file *def, const char *impfilename) /* Work out a reasonable size of things to put onto one line. */ ar_head = make_head (outarch); + /* Iterate the input BFDs, looking for exclude-modules-for-implib. */ + for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link_next) + { + /* Iterate the exclude list. */ + struct exclude_list_struct *ex; + char found; + for (ex = excludes, found = 0; ex && !found; ex = ex->next) + { + if (ex->type != EXCLUDEFORIMPLIB) + continue; + found = (strcmp (ex->string, ibfd->filename) == 0); + } + /* If it matched, we must open a fresh BFD for it (the original + input BFD is still needed for the DLL's final link) and add + it into the archive member chain. */ + if (found) + { + bfd *newbfd = bfd_openr (ibfd->my_archive + ? ibfd->my_archive->filename : ibfd->filename, NULL); + if (!newbfd) + { + einfo (_("%Xbfd_openr %s: %E\n"), ibfd->filename); + return; + } + if (ibfd->my_archive) + { + /* Must now iterate through archive until we find the + required member. A minor shame that we'll open the + archive once per member that we require from it, and + leak those archive bfds rather than reuse them. */ + bfd *arbfd = newbfd; + if (!bfd_check_format_matches (arbfd, bfd_archive, NULL)) + { + einfo (_("%X%s(%s): can't find member in non-archive file"), + ibfd->my_archive->filename, ibfd->filename); + return; + } + newbfd = NULL; + while ((newbfd = bfd_openr_next_archived_file (arbfd, newbfd)) != 0) + { + if (strcmp (newbfd->filename, ibfd->filename) == 0) + break; + } + if (!newbfd) + { + einfo (_("%X%s(%s): can't find member in archive"), + ibfd->my_archive->filename, ibfd->filename); + return; + } + } + newbfd->archive_next = head; + head = newbfd; + } + } + for (i = 0; i < def->num_exports; i++) { /* The import library doesn't know about the internal name. */ |