aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorThomas Preud'homme <thomas.preudhomme@arm.com>2016-07-15 17:49:08 +0100
committerThomas Preud'homme <thomas.preudhomme@arm.com>2016-07-15 17:50:48 +0100
commit76359541825cf36ecd14ab6b5974ee56e1c59eff (patch)
tree2043ac1a958572f267df5fabf168bca70300900b /ld
parentbc7b765ab71f967eb2a9c3da111d7529eec46fbe (diff)
downloadfsf-binutils-gdb-76359541825cf36ecd14ab6b5974ee56e1c59eff.zip
fsf-binutils-gdb-76359541825cf36ecd14ab6b5974ee56e1c59eff.tar.gz
fsf-binutils-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/ChangeLog35
-rw-r--r--ld/NEWS7
-rw-r--r--ld/emultempl/elf32.em14
-rw-r--r--ld/emultempl/pe.em14
-rw-r--r--ld/emultempl/pep.em12
-rw-r--r--ld/ld.h3
-rw-r--r--ld/ld.texinfo20
-rw-r--r--ld/ldexp.c1
-rw-r--r--ld/ldlex.h1
-rw-r--r--ld/lexsup.c5
-rw-r--r--ld/testsuite/ld-elf/elf.exp16
-rw-r--r--ld/testsuite/ld-elf/empty-implib.out2
-rw-r--r--ld/testsuite/ld-elf/implib.rd11
-rw-r--r--ld/testsuite/ld-elf/implib.s22
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
diff --git a/ld/NEWS b/ld/NEWS
index b988df0..2a0b4ac 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -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)
diff --git a/ld/ld.h b/ld/ld.h
index 85a48ad..410ee99 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -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}
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 649954f..68c4bc5 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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;
diff --git a/ld/ldlex.h b/ld/ldlex.h
index cf943e4..52f7198 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -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