Index: src/binutils/dlltool.c =================================================================== --- src.orig/binutils/dlltool.c +++ src/binutils/dlltool.c @@ -371,6 +371,8 @@ static bfd_boolean export_all_symbols; exporting all symbols. */ static bfd_boolean do_default_excludes = TRUE; +static bfd_boolean use_nul_prefixed_import_tables = FALSE; + /* Default symbols to exclude when exporting all the symbols. */ static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr"; @@ -2720,19 +2722,28 @@ make_head (void) if (!no_idata5) { fprintf (f, "\t.section\t.idata$5\n"); + if (use_nul_prefixed_import_tables) + { #ifdef DLLTOOL_MX86_64 - fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); /* NULL terminating list. */ + fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); #else - fprintf (f,"\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ + fprintf (f,"\t%s\t0\n", ASM_LONG); #endif + } fprintf (f, "fthunk:\n"); } if (!no_idata4) { fprintf (f, "\t.section\t.idata$4\n"); - fprintf (f, "\t%s\t0\n", ASM_LONG); - fprintf (f, "\t.section .idata$4\n"); + if (use_nul_prefixed_import_tables) + { +#ifdef DLLTOOL_MX86_64 + fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); +#else + fprintf (f,"\t%s\t0\n", ASM_LONG); +#endif + } fprintf (f, "hname:\n"); } @@ -3356,6 +3367,7 @@ usage (FILE *file, int status) fprintf (file, _(" -b --base-file Read linker generated base file.\n")); fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n")); fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n")); + fprintf (file, _(" --use-nul-prefixed-import-tables Use zero prefixed idata$4 and idata$5.\n")); fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n")); fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n")); fprintf (file, _(" -k --kill-at Kill @ from exported names.\n")); @@ -3386,6 +3398,8 @@ usage (FILE *file, int status) #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1) #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1) #define OPTION_ADD_STDCALL_UNDERSCORE (OPTION_NO_DEFAULT_EXCLUDES + 1) +#define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \ + (OPTION_ADD_STDCALL_UNDERSCORE + 1) static const struct option long_options[] = { @@ -3393,6 +3407,8 @@ static const struct option long_options[ {"dllname", required_argument, NULL, 'D'}, {"no-idata4", no_argument, NULL, 'x'}, {"no-idata5", no_argument, NULL, 'c'}, + {"use-nul-prefixed-import-tables", no_argument, NULL, + OPTION_USE_NUL_PREFIXED_IMPORT_TABLES}, {"output-exp", required_argument, NULL, 'e'}, {"output-def", required_argument, NULL, 'z'}, {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS}, @@ -3467,6 +3483,9 @@ main (int ac, char **av) case OPTION_NO_DEFAULT_EXCLUDES: do_default_excludes = FALSE; break; + case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES: + use_nul_prefixed_import_tables = TRUE; + break; case OPTION_ADD_STDCALL_UNDERSCORE: add_stdcall_underscore = 1; break; Index: src/binutils/doc/binutils.texi =================================================================== --- src.orig/binutils/doc/binutils.texi +++ src/binutils/doc/binutils.texi @@ -3370,6 +3370,7 @@ dlltool [@option{-d}|@option{--input-def [@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{--use-nul-prefixed-import-tables}] [@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}] @@ -3583,6 +3584,12 @@ Specifies that when @command{dlltool} is files it should omit the @code{.idata4} section. This is for compatibility with certain operating systems. +@item --use-nul-prefixed-import-tables +Specifies that when @command{dlltool} is creating the exports and library +files it should prefix the @code{.idata4} and @code{.idata5} by zero an +element. This emulates old gnu import library generation of +@code{dlltool}. By default this option is turned off. + @item -c @itemx --no-idata5 Specifies that when @command{dlltool} is creating the exports and library Index: src/ld/emultempl/pe.em =================================================================== --- src.orig/ld/emultempl/pe.em +++ src/ld/emultempl/pe.em @@ -209,6 +209,8 @@ gld_${EMULATION_NAME}_before_parse (void (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1 + 1) #define OPTION_EXCLUDE_MODULES_FOR_IMPLIB \ (OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2 + 1) +#define OPTION_USE_NUL_PREFIXED_IMPORT_TABLES \ + (OPTION_EXCLUDE_MODULES_FOR_IMPLIB + 1) static void gld${EMULATION_NAME}_add_options @@ -234,6 +236,8 @@ gld${EMULATION_NAME}_add_options {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, {"thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY}, + {"use-nul-prefixed-import-tables", no_argument, NULL, + OPTION_USE_NUL_PREFIXED_IMPORT_TABLES}, #ifdef DLL_SUPPORT /* getopt allows abbreviations, so we do this to stop it from treating -o as an abbreviation for this option */ @@ -596,6 +600,9 @@ gld${EMULATION_NAME}_handle_option (int case OPTION_THUMB_ENTRY: thumb_entry_symbol = optarg; break; + case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES: + pe_use_nul_prefixed_import_tables = TRUE; + break; #ifdef DLL_SUPPORT case OPTION_OUT_DEF: pe_out_def_filename = xstrdup (optarg); Index: src/ld/emultempl/pep.em =================================================================== --- src.orig/ld/emultempl/pep.em +++ src/ld/emultempl/pep.em @@ -176,7 +176,8 @@ enum options OPTION_DLL_DISABLE_RUNTIME_PSEUDO_RELOC, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V1, OPTION_DLL_ENABLE_RUNTIME_PSEUDO_RELOC_V2, - OPTION_EXCLUDE_MODULES_FOR_IMPLIB + OPTION_EXCLUDE_MODULES_FOR_IMPLIB, + OPTION_USE_NUL_PREFIXED_IMPORT_TABLES }; static void @@ -206,6 +207,8 @@ gld${EMULATION_NAME}_add_options {"stack", required_argument, NULL, OPTION_STACK}, {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM}, {"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE}, + {"use-nul-prefixed-import-tables", no_argument, NULL, + OPTION_USE_NUL_PREFIXED_IMPORT_TABLES}, #ifdef DLL_SUPPORT /* getopt allows abbreviations, so we do this to stop it from treating -o as an abbreviation for this option. */ @@ -556,6 +559,9 @@ gld${EMULATION_NAME}_handle_option (int case OPTION_SUPPORT_OLD_CODE: support_old_code = 1; break; + case OPTION_USE_NUL_PREFIXED_IMPORT_TABLES: + pep_use_nul_prefixed_import_tables = TRUE; + break; #ifdef DLL_SUPPORT case OPTION_OUT_DEF: pep_out_def_filename = xstrdup (optarg); Index: src/ld/ld.texinfo =================================================================== --- src.orig/ld/ld.texinfo +++ src/ld/ld.texinfo @@ -5619,6 +5619,13 @@ But it also sets the bottom bit of the a branched to using a BX instruction, and the program will start executing in Thumb mode straight away. +@cindex PE import table prefixing +@kindex --use-nul-prefixed-import-tables +The @samp{--use-nul-prefixed-import-tables} switch is specifying, that +the import tables idata4 and idata5 have to be generated with a zero +elememt prefix for import libraries. This is the old style to generate +import tables. By default this option is turned off. + @cindex BE8 @kindex --be8 The @samp{--be8} switch instructs @command{ld} to generate BE8 format Index: src/ld/pe-dll.c =================================================================== --- src.orig/ld/pe-dll.c +++ src/ld/pe-dll.c @@ -155,6 +155,7 @@ int pe_dll_stdcall_aliases = 0; int pe_dll_warn_dup_exports = 0; int pe_dll_compat_implib = 0; int pe_dll_extra_pe_debug = 0; +int pe_use_nul_prefixed_import_tables = 0; /* Static variables and types. */ @@ -1796,18 +1797,24 @@ make_head (bfd *parent) d2 = xmalloc (20); id2->contents = d2; memset (d2, 0, 20); - d2[0] = d2[16] = PE_IDATA5_SIZE; /* Reloc addend. */ + if (pe_use_nul_prefixed_import_tables) + d2[0] = d2[16] = PE_IDATA5_SIZE; /* Reloc addend. */ quick_reloc (abfd, 0, BFD_RELOC_RVA, 2); quick_reloc (abfd, 12, BFD_RELOC_RVA, 4); quick_reloc (abfd, 16, BFD_RELOC_RVA, 1); save_relocs (id2); - bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE); + if (pe_use_nul_prefixed_import_tables) + bfd_set_section_size (abfd, id5, PE_IDATA5_SIZE); + else + bfd_set_section_size (abfd, id5, 0); d5 = xmalloc (PE_IDATA5_SIZE); id5->contents = d5; memset (d5, 0, PE_IDATA5_SIZE); - - bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE); + if (pe_use_nul_prefixed_import_tables) + bfd_set_section_size (abfd, id4, PE_IDATA4_SIZE); + else + bfd_set_section_size (abfd, id4, 0); d4 = xmalloc (PE_IDATA4_SIZE); id4->contents = d4; memset (d4, 0, PE_IDATA4_SIZE); @@ -1815,8 +1822,16 @@ make_head (bfd *parent) bfd_set_symtab (abfd, symtab, symptr); bfd_set_section_contents (abfd, id2, d2, 0, 20); - bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE); - bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE); + if (pe_use_nul_prefixed_import_tables) + { + bfd_set_section_contents (abfd, id5, d5, 0, PE_IDATA5_SIZE); + bfd_set_section_contents (abfd, id4, d4, 0, PE_IDATA4_SIZE); + } + else + { + bfd_set_section_contents (abfd, id5, d5, 0, 0); + bfd_set_section_contents (abfd, id4, d4, 0, 0); + } bfd_make_readable (abfd); return abfd; @@ -2279,7 +2294,6 @@ make_import_fixup_entry (const char *nam d2 = xmalloc (20); id2->contents = d2; memset (d2, 0, 20); - d2[0] = d2[16] = PE_IDATA5_SIZE; /* Reloc addend. */ quick_reloc (abfd, 0, BFD_RELOC_RVA, 1); quick_reloc (abfd, 12, BFD_RELOC_RVA, 2); Index: src/ld/pe-dll.h =================================================================== --- src.orig/ld/pe-dll.h +++ src/ld/pe-dll.h @@ -35,6 +35,7 @@ extern int pe_dll_stdcall_aliases; extern int pe_dll_warn_dup_exports; extern int pe_dll_compat_implib; extern int pe_dll_extra_pe_debug; +extern int pe_use_nul_prefixed_import_tables; typedef enum { EXCLUDESYMS, EXCLUDELIBS, EXCLUDEFORIMPLIB } exclude_type; Index: src/ld/pep-dll.c =================================================================== --- src.orig/ld/pep-dll.c +++ src/ld/pep-dll.c @@ -33,6 +33,8 @@ #define pe_dll_kill_ats pep_dll_kill_ats #define pe_dll_stdcall_aliases pep_dll_stdcall_aliases #define pe_dll_warn_dup_exports pep_dll_warn_dup_exports +#define pe_use_nul_prefixed_import_tables \ + pep_use_nul_prefixed_import_tables /* External globals. */ #define pe_data_import_dll pep_data_import_dll Index: src/ld/pep-dll.h =================================================================== --- src.orig/ld/pep-dll.h +++ src/ld/pep-dll.h @@ -35,6 +35,7 @@ extern int pep_dll_stdcall_aliases; extern int pep_dll_warn_dup_exports; extern int pep_dll_compat_implib; extern int pep_dll_extra_pe_debug; +extern int pep_use_nul_prefixed_import_tables; typedef enum { EXCLUDESYMS, EXCLUDELIBS, EXCLUDEFORIMPLIB } exclude_type;