diff options
author | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2016-07-15 17:49:08 +0100 |
---|---|---|
committer | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2016-07-15 17:50:48 +0100 |
commit | 76359541825cf36ecd14ab6b5974ee56e1c59eff (patch) | |
tree | 2043ac1a958572f267df5fabf168bca70300900b /ld | |
parent | bc7b765ab71f967eb2a9c3da111d7529eec46fbe (diff) | |
download | gdb-76359541825cf36ecd14ab6b5974ee56e1c59eff.zip gdb-76359541825cf36ecd14ab6b5974ee56e1c59eff.tar.gz gdb-76359541825cf36ecd14ab6b5974ee56e1c59eff.tar.bz2 |
Add support for creating ELF import libraries
2016-07-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
bfd/
* elf-bfd.h (elf_backend_filter_implib_symbols): Declare backend hook.
(_bfd_elf_filter_global_symbols): Declare.
* elf.c (_bfd_elf_filter_global_symbols): New function.
* elflink.c (elf_filter_global_symbols): Likewise.
(elf_output_implib): Likewise.
(bfd_elf_final_link): Call above function, failing if it does.
* elfxx-target.h (elf_backend_filter_implib_symbols): Define macro and
default it to NULL.
(elf_backend_copy_indirect_symbol): Fix spacing.
(elf_backend_hide_symbol): Likewise.
(elfNN_bed): Initialize elf_backend_filter_implib_symbols backend hook.
include/
* bfdlink.h (struct bfd_link_info): Declare new ldscript_def and
out_implib_bfd fields.
2016-07-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
Nick Clifton <nickc@redhat.com>
ld/
* emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Open import
library file for writing and initialize implib_bfd field of link_info
structure.
* emultempl/pe.em (pe_implib_filename): Remove variable declaration.
(OPTION_IMPLIB_FILENAME): Remove macro definition.
(gld${EMULATION_NAME}_add_options): Remove --out-implib option.
(gld_${EMULATION_NAME}_list_options): Likewise.
(gld${EMULATION_NAME}_handle_option): Likewise.
(gld_${EMULATION_NAME}_finish): Use command_line.out_implib_filename
instead of pe_implib_filename.
* emultempl/pep.em (pep_implib_filename): Remove variable declaration.
(OPTION_IMPLIB_FILENAME): Remove enumerator.
(gld${EMULATION_NAME}_add_options): Remove --out-implib option.
(gld_${EMULATION_NAME}_list_options): Likewise.
(gld${EMULATION_NAME}_handle_option): Likewise.
(gld_${EMULATION_NAME}_finish): Use command_line.out_implib_filename
instead of pep_implib_filename.
* ld.h (args_type): Declare new out_implib_filename field.
* ld.texinfo (--out-implib): Move documentation to arch-independent
part and rephrase to apply to ELF targets.
* ldexp.c (exp_fold_tree_1): Set ldscript_def field to 1 for symbols
defined in linker scripts.
* ldlex.h (enum option_values): Declare new OPTION_OUT_IMPLIB
enumerator.
* lexsup.c (ld_options): Add entry for new --out-implib switch.
(parse_args): Handle OPTION_OUT_IMPLIB case.
* testsuite/ld-elf/elf.exp (Generate empty import library): New test.
(Generate import library): Likewise.
* testsuite/ld-elf/implib.s: Likewise.
* testsuite/ld-elf/implib.rd: New file.
* testsuite/ld-elf/empty-implib.out: Likewise
Diffstat (limited to 'ld')
-rw-r--r-- | ld/ChangeLog | 35 | ||||
-rw-r--r-- | ld/NEWS | 7 | ||||
-rw-r--r-- | ld/emultempl/elf32.em | 14 | ||||
-rw-r--r-- | ld/emultempl/pe.em | 14 | ||||
-rw-r--r-- | ld/emultempl/pep.em | 12 | ||||
-rw-r--r-- | ld/ld.h | 3 | ||||
-rw-r--r-- | ld/ld.texinfo | 20 | ||||
-rw-r--r-- | ld/ldexp.c | 1 | ||||
-rw-r--r-- | ld/ldlex.h | 1 | ||||
-rw-r--r-- | ld/lexsup.c | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/elf.exp | 16 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/empty-implib.out | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/implib.rd | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/implib.s | 22 |
14 files changed, 134 insertions, 29 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index ea44948..70c64c6 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,38 @@ +2016-07-15 Thomas Preud'homme <thomas.preudhomme@arm.com> + Nick Clifton <nickc@redhat.com> + + * emultempl/elf32.em (gld${EMULATION_NAME}_after_open): Open import + library file for writing and initialize implib_bfd field of link_info + structure. + * emultempl/pe.em (pe_implib_filename): Remove variable declaration. + (OPTION_IMPLIB_FILENAME): Remove macro definition. + (gld${EMULATION_NAME}_add_options): Remove --out-implib option. + (gld_${EMULATION_NAME}_list_options): Likewise. + (gld${EMULATION_NAME}_handle_option): Likewise. + (gld_${EMULATION_NAME}_finish): Use command_line.out_implib_filename + instead of pe_implib_filename. + * emultempl/pep.em (pep_implib_filename): Remove variable declaration. + (OPTION_IMPLIB_FILENAME): Remove enumerator. + (gld${EMULATION_NAME}_add_options): Remove --out-implib option. + (gld_${EMULATION_NAME}_list_options): Likewise. + (gld${EMULATION_NAME}_handle_option): Likewise. + (gld_${EMULATION_NAME}_finish): Use command_line.out_implib_filename + instead of pep_implib_filename. + * ld.h (args_type): Declare new out_implib_filename field. + * ld.texinfo (--out-implib): Move documentation to arch-independent + part and rephrase to apply to ELF targets. + * ldexp.c (exp_fold_tree_1): Set ldscript_def field to 1 for symbols + defined in linker scripts. + * ldlex.h (enum option_values): Declare new OPTION_OUT_IMPLIB + enumerator. + * lexsup.c (ld_options): Add entry for new --out-implib switch. + (parse_args): Handle OPTION_OUT_IMPLIB case. + * testsuite/ld-elf/elf.exp (Generate empty import library): New test. + (Generate import library): Likewise. + * testsuite/ld-elf/implib.s: Likewise. + * testsuite/ld-elf/implib.rd: New file. + * testsuite/ld-elf/empty-implib.out: Likewise + 2016-07-15 Nick Clifton <nickc@redhat.com> * testsuite/ld-arc/arc.exp: Always run the sda-relocs test in @@ -1,5 +1,12 @@ -*- text -*- +Changes in 2.28: + +* Extended the --out-implib=<file> option, previously restricted to x86 PE + targets, to any ELF based target. This allows the generation of an import + library for an ELF executable, which can then be used by another application + to link against the executable. + Changes in 2.27: * Add a configure option --enable-relro to decide whether -z relro should diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em index 47fa549..dd4d35a 100644 --- a/ld/emultempl/elf32.em +++ b/ld/emultempl/elf32.em @@ -1027,6 +1027,20 @@ gld${EMULATION_NAME}_after_open (void) if (!is_elf_hash_table (htab)) return; + if (command_line.out_implib_filename) + { + unlink_if_ordinary (command_line.out_implib_filename); + link_info.out_implib_bfd + = bfd_openw (command_line.out_implib_filename, + bfd_get_target (link_info.output_bfd)); + + if (link_info.out_implib_bfd == NULL) + { + einfo ("%F%s: Can't open for writing: %E\n", + command_line.out_implib_filename); + } + } + if (emit_note_gnu_build_id != NULL) { bfd *abfd; diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index c13fa4d..7b8fec7 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -138,7 +138,6 @@ static const char *emit_build_id; #ifdef DLL_SUPPORT static int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable. */ static char *pe_out_def_filename = NULL; -static char *pe_implib_filename = NULL; static int pe_enable_auto_image_base = 0; static unsigned long pe_auto_image_base = 0x61500000; static char *pe_dll_search_prefix = NULL; @@ -228,8 +227,7 @@ fragment <<EOF #define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1) #define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1) #define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1) -#define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_STDCALL_FIXUP + 1) -#define OPTION_THUMB_ENTRY (OPTION_IMPLIB_FILENAME + 1) +#define OPTION_THUMB_ENTRY (OPTION_DISABLE_STDCALL_FIXUP + 1) #define OPTION_WARN_DUPLICATE_EXPORTS (OPTION_THUMB_ENTRY + 1) #define OPTION_IMP_COMPAT (OPTION_WARN_DUPLICATE_EXPORTS + 1) #define OPTION_ENABLE_AUTO_IMAGE_BASE (OPTION_IMP_COMPAT + 1) @@ -323,7 +321,6 @@ gld${EMULATION_NAME}_add_options {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP}, {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP}, - {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME}, {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS}, /* getopt() allows abbreviations, so we do this to stop it from treating -c as an abbreviation for these --compat-implib. */ @@ -461,7 +458,6 @@ gld_${EMULATION_NAME}_list_options (FILE *file) fprintf (file, _(" export, place into import library instead.\n")); fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n")); fprintf (file, _(" --kill-at Remove @nn from exported symbols\n")); - fprintf (file, _(" --out-implib <file> Generate import library\n")); fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n")); fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports\n")); fprintf (file, _(" --compat-implib Create backward compatible import libs;\n\ @@ -804,9 +800,6 @@ gld${EMULATION_NAME}_handle_option (int optc) case OPTION_DISABLE_STDCALL_FIXUP: pe_enable_stdcall_fixup = 0; break; - case OPTION_IMPLIB_FILENAME: - pe_implib_filename = xstrdup (optarg); - break; case OPTION_WARN_DUPLICATE_EXPORTS: pe_dll_warn_dup_exports = 1; break; @@ -2070,8 +2063,9 @@ gld_${EMULATION_NAME}_finish (void) ) { pe_dll_fill_sections (link_info.output_bfd, &link_info); - if (pe_implib_filename) - pe_dll_generate_implib (pe_def_file, pe_implib_filename, &link_info); + if (command_line.out_implib_filename) + pe_dll_generate_implib (pe_def_file, command_line.out_implib_filename, + &link_info); } #if defined(TARGET_IS_shpe) /* ARM doesn't need relocs. */ diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em index ab7c473..60deeed 100644 --- a/ld/emultempl/pep.em +++ b/ld/emultempl/pep.em @@ -153,7 +153,6 @@ static const char *emit_build_id; #ifdef DLL_SUPPORT static int pep_enable_stdcall_fixup = 1; /* 0=disable 1=enable (default). */ static char * pep_out_def_filename = NULL; -static char * pep_implib_filename = NULL; static int pep_enable_auto_image_base = 0; static char * pep_dll_search_prefix = NULL; #endif @@ -217,7 +216,6 @@ enum options OPTION_STDCALL_ALIASES, OPTION_ENABLE_STDCALL_FIXUP, OPTION_DISABLE_STDCALL_FIXUP, - OPTION_IMPLIB_FILENAME, OPTION_WARN_DUPLICATE_EXPORTS, OPTION_IMP_COMPAT, OPTION_ENABLE_AUTO_IMAGE_BASE, @@ -296,7 +294,6 @@ gld${EMULATION_NAME}_add_options {"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES}, {"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP}, {"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP}, - {"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME}, {"warn-duplicate-exports", no_argument, NULL, OPTION_WARN_DUPLICATE_EXPORTS}, /* getopt() allows abbreviations, so we do this to stop it from treating -c as an abbreviation for these --compat-implib. */ @@ -427,7 +424,6 @@ gld_${EMULATION_NAME}_list_options (FILE *file) fprintf (file, _(" export, place into import library instead.\n")); fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n")); fprintf (file, _(" --kill-at Remove @nn from exported symbols\n")); - fprintf (file, _(" --out-implib <file> Generate import library\n")); fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n")); fprintf (file, _(" --warn-duplicate-exports Warn about duplicate exports.\n")); fprintf (file, _(" --compat-implib Create backward compatible import libs;\n\ @@ -761,9 +757,6 @@ gld${EMULATION_NAME}_handle_option (int optc) case OPTION_DISABLE_STDCALL_FIXUP: pep_enable_stdcall_fixup = 0; break; - case OPTION_IMPLIB_FILENAME: - pep_implib_filename = xstrdup (optarg); - break; case OPTION_WARN_DUPLICATE_EXPORTS: pep_dll_warn_dup_exports = 1; break; @@ -1851,8 +1844,9 @@ gld_${EMULATION_NAME}_finish (void) && pep_def_file->num_exports != 0)) { pep_dll_fill_sections (link_info.output_bfd, &link_info); - if (pep_implib_filename) - pep_dll_generate_implib (pep_def_file, pep_implib_filename, &link_info); + if (command_line.out_implib_filename) + pep_dll_generate_implib (pep_def_file, + command_line.out_implib_filename, &link_info); } if (pep_out_def_filename) @@ -163,6 +163,9 @@ typedef struct input files. */ bfd_boolean accept_unknown_input_arch; + /* Name of the import library to generate. */ + char *out_implib_filename; + /* If TRUE we'll just print the default output on stdout. */ bfd_boolean print_output_format; diff --git a/ld/ld.texinfo b/ld/ld.texinfo index bc16764..b2dff10 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -1721,6 +1721,16 @@ command @code{OUTPUT_FORMAT} can also specify the output format, but this option overrides it. @xref{BFD}. @end ifclear +@kindex --out-implib +@item --out-implib @var{file} +Create an import library in @var{file} corresponding to the executable +the linker is generating (eg. a DLL or ELF program). This import +library (which should be called @code{*.dll.a} or @code{*.a} for DLLs) +may be used to link clients against the generated executable; this +behaviour makes it possible to skip a separate import library creation +step (eg. @code{dlltool} for DLLs). This option is only available for +the i386 PE and ELF targetted ports of the linker. + @kindex -pie @kindex --pic-executable @item -pie @@ -2580,16 +2590,6 @@ automatically or implicitly exported symbols. [This option is specific to the i386 PE targeted port of the linker] @cindex DLLs, creating -@kindex --out-implib -@item --out-implib @var{file} -The linker will create the file @var{file} which will contain an -import lib corresponding to the DLL the linker is generating. This -import lib (which should be called @code{*.dll.a} or @code{*.a} -may be used to link clients against the generated DLL; this behaviour -makes it possible to skip a separate @code{dlltool} import library -creation step. -[This option is specific to the i386 PE targeted port of the linker] - @kindex --enable-auto-image-base @item --enable-auto-image-base @itemx --enable-auto-image-base=@var{value} @@ -1183,6 +1183,7 @@ exp_fold_tree_1 (etree_type *tree) h->u.def.value = expld.result.value; h->u.def.section = expld.result.section; h->linker_def = ! tree->assign.type.lineno; + h->ldscript_def = 1; if (tree->type.node_class == etree_provide) tree->type.node_class = etree_provided; @@ -35,6 +35,7 @@ enum option_values OPTION_DYNAMIC_LINKER, OPTION_NO_DYNAMIC_LINKER, OPTION_SYSROOT, + OPTION_OUT_IMPLIB, OPTION_EB, OPTION_EL, OPTION_EMBEDDED_RELOCS, diff --git a/ld/lexsup.c b/ld/lexsup.c index 6d28e91..6e279ae 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -164,6 +164,8 @@ static const struct ld_option ld_options[] = 'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES }, { {NULL, required_argument, NULL, '\0'}, 'O', NULL, N_("Optimize output file"), ONE_DASH }, + { {"out-implib", required_argument, NULL, OPTION_OUT_IMPLIB}, + '\0', N_("FILE"), N_("Generate import library"), TWO_DASHES }, #ifdef ENABLE_PLUGINS { {"plugin", required_argument, NULL, OPTION_PLUGIN}, '\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH }, @@ -1004,6 +1006,9 @@ parse_args (unsigned argc, char **argv) case OPTION_OFORMAT: lang_add_output_format (optarg, NULL, NULL, 0); break; + case OPTION_OUT_IMPLIB: + command_line.out_implib_filename = xstrdup (optarg); + break; case OPTION_PRINT_SYSROOT: if (*ld_sysroot) puts (ld_sysroot); diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp index 2dfd0e8..832f313 100644 --- a/ld/testsuite/ld-elf/elf.exp +++ b/ld/testsuite/ld-elf/elf.exp @@ -136,6 +136,22 @@ foreach t $test_list { run_dump_test [file rootname $t] } +# Check that the --out-implib option work correctly. +run_ld_link_tests { + {"Generate empty import library" + "--out-implib=tmpdir/implib.lib" "" + "--defsym NO_GLOBAL=1" + {implib.s} + {{ld empty-implib.out}} + "implib"} + {"Generate import library" + "-Tdata=0x1000 --out-implib=tmpdir/implib.lib" "" + "" + {implib.s} + {{readelf {-s tmpdir/implib.lib} implib.rd}} + "implib"} +} + if { [istarget *-*-linux*] || [istarget *-*-nacl*] || [istarget *-*-gnu*] } { diff --git a/ld/testsuite/ld-elf/empty-implib.out b/ld/testsuite/ld-elf/empty-implib.out new file mode 100644 index 0000000..b123064 --- /dev/null +++ b/ld/testsuite/ld-elf/empty-implib.out @@ -0,0 +1,2 @@ +.*: .*: no symbol found for import library +.*: .*: failed to generate import library diff --git a/ld/testsuite/ld-elf/implib.rd b/ld/testsuite/ld-elf/implib.rd new file mode 100644 index 0000000..9f854a5 --- /dev/null +++ b/ld/testsuite/ld-elf/implib.rd @@ -0,0 +1,11 @@ +File: tmpdir/implib.lib + +Symbol table '.symtab' contains 3 entries: + Num: Value +Size Type Bind Vis Ndx Name + 0: [0-9a-f]+ 0 NOTYPE LOCAL DEFAULT UND + 1: 0+100[0-3] 1 OBJECT GLOBAL DEFAULT ABS exported1 + 2: 0+100[0-3] 1 OBJECT GLOBAL DEFAULT ABS exported2 + +File: tmpdir/implib + +#... diff --git a/ld/testsuite/ld-elf/implib.s b/ld/testsuite/ld-elf/implib.s new file mode 100644 index 0000000..a86a940 --- /dev/null +++ b/ld/testsuite/ld-elf/implib.s @@ -0,0 +1,22 @@ +.ifndef NO_GLOBAL + .bss + .comm exported1,1 + + .data + .global exported2 + .type exported2, %object + .size exported2, 1 +exported2: + .byte 21 +.endif + + .bss +not_exported1: + .space 1 + .size not_exported1, 1 + + .data + .type not_exported2, %object + .size not_exported2, 1 +not_exported2: + .byte 42 |