2009-09-04 Timo Kreuzer <timo.kreuzer@web.de>

* dlltool.c (delayimp_name): Add new global variable
	(usage, long_options, main): Add new option "-y" / "--output-delaylib"
	(struct mac): Add fields how_dljtab_size, how_dljtab_roff1,
	how_dljtab_roff2, how_dljtab, trampoline.
	(i386_dljtab): Add binary stub for x86 delay import.
	(i386_trampoline): Add text assembly stub for x86 delay import.
	(mtable): Add delay import data for M386 and MX86 only.
	(make_delay_head): New function.
	(make_one_lib_file): New arg delay creates delay-load import stub.
	(gen_lib_file): New arg delay likewise.
	(HOW_JTAB, HOW_JTAB_SIZE, HOW_JTAB_ROFF): New arg delay likewise.
	(HOW_JTAB_ROFF2, HOW_JTAB_ROFF3): New macros for delay import.
	(make_tail): Convert hard TABS embedded in strings to "\t" escapes.
	* NEWS: Mention new feature.  Also fix whitespace.
	* doc/binutils.texi: Updated dlltool documentation.
This commit is contained in:
Dave Korn 2009-09-04 01:22:19 +00:00
parent 8f0e5a0604
commit 10e636d21e
4 changed files with 270 additions and 38 deletions

View File

@ -1,3 +1,21 @@
2009-09-04 Timo Kreuzer <timo.kreuzer@web.de>
* dlltool.c (delayimp_name): Add new global variable
(usage, long_options, main): Add new option "-y" / "--output-delaylib"
(struct mac): Add fields how_dljtab_size, how_dljtab_roff1,
how_dljtab_roff2, how_dljtab, trampoline.
(i386_dljtab): Add binary stub for x86 delay import.
(i386_trampoline): Add text assembly stub for x86 delay import.
(mtable): Add delay import data for M386 and MX86 only.
(make_delay_head): New function.
(make_one_lib_file): New arg delay creates delay-load import stub.
(gen_lib_file): New arg delay likewise.
(HOW_JTAB, HOW_JTAB_SIZE, HOW_JTAB_ROFF): New arg delay likewise.
(HOW_JTAB_ROFF2, HOW_JTAB_ROFF3): New macros for delay import.
(make_tail): Convert hard TABS embedded in strings to "\t" escapes.
* NEWS: Mention new feature. Also fix whitespace.
* doc/binutils.texi: Updated dlltool documentation.
2009-09-02 Tristan Gingold <gingold@adacore.com>
* configure.com: Do not copy makefile.vms-in to makefile.vms

View File

@ -1,7 +1,13 @@
-*- text -*-
* Add support for delay importing to dlltool. Use the --output-delaylib <file>
switch to create a delay-import library. The resulting app will load the dll
as soon as the first function is called. It will link to __delayLoadHelper2()
from the static delayimp library, which will import LoadLibraryA and
GetProcAddress from kernel32.
* Add a new command line option, --insn-width=WIDTH, to objdump to specify
number of bytes to be displayed on a single line when disassembling
instructions.
number of bytes to be displayed on a single line when disassembling
instructions.
* Readelf can now display the relocated contents of a section as a sequence
of bytes via the --relocated-dump=<name|number> command line option.

View File

@ -352,6 +352,7 @@ static int no_idata4;
static int no_idata5;
static char *exp_name;
static char *imp_name;
static char *delayimp_name;
static char *identify_imp_name;
static bfd_boolean identify_strict;
@ -499,6 +500,13 @@ static const unsigned char i386_jtab[] =
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
};
static const unsigned char i386_dljtab[] =
{
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
};
static const unsigned char arm_jtab[] =
{
0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
@ -565,6 +573,16 @@ static const unsigned char ppc_jtab[] =
static bfd_vma ppc_glue_insn = 0x80410004;
#endif
static const char i386_trampoline[] =
"\tpushl %%ecx\n"
"\tpushl %%edx\n"
"\tpushl %%eax\n"
"\tpushl $__DELAY_IMPORT_DESCRIPTOR_%s\n"
"\tcall ___delayLoadHelper2@8\n"
"\tpopl %%edx\n"
"\tpopl %%ecx\n"
"\tjmp *%%eax\n";
struct mac
{
const char *type;
@ -584,6 +602,12 @@ struct mac
const unsigned char *how_jtab;
int how_jtab_size; /* Size of the jtab entry. */
int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */
const unsigned char *how_dljtab;
int how_dljtab_size; /* Size of the dljtab entry. */
int how_dljtab_roff1; /* Offset for the ind 32 reloc into idata 5. */
int how_dljtab_roff2; /* Offset for the ind 32 reloc into idata 5. */
int how_dljtab_roff3; /* Offset for the ind 32 reloc into idata 5. */
const char *trampoline;
};
static const struct mac
@ -595,7 +619,8 @@ mtable[] =
"ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
"pe-arm-little", bfd_arch_arm,
arm_jtab, sizeof (arm_jtab), 8
arm_jtab, sizeof (arm_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -603,7 +628,8 @@ mtable[] =
"i386", ".byte", ".short", ".long", ".asciz", "#",
"jmp *", ".global", ".space", ".align\t2",".align\t4", "",
"pe-i386",bfd_arch_i386,
i386_jtab, sizeof (i386_jtab), 2
i386_jtab, sizeof (i386_jtab), 2,
i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
}
,
{
@ -611,7 +637,8 @@ mtable[] =
"ppc", ".byte", ".short", ".long", ".asciz", "#",
"jmp *", ".global", ".space", ".align\t2",".align\t4", "",
"pe-powerpcle",bfd_arch_powerpc,
ppc_jtab, sizeof (ppc_jtab), 0
ppc_jtab, sizeof (ppc_jtab), 0,
0, 0, 0, 0, 0, 0
}
,
{
@ -620,7 +647,8 @@ mtable[] =
"push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip",
".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
"pe-arm-little", bfd_arch_arm,
thumb_jtab, sizeof (thumb_jtab), 12
thumb_jtab, sizeof (thumb_jtab), 12,
0, 0, 0, 0, 0, 0
}
,
#define MARM_INTERWORK 4
@ -629,7 +657,8 @@ mtable[] =
"ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long",
".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork",
"pe-arm-little", bfd_arch_arm,
arm_interwork_jtab, sizeof (arm_interwork_jtab), 12
arm_interwork_jtab, sizeof (arm_interwork_jtab), 12,
0, 0, 0, 0, 0, 0
}
,
{
@ -638,7 +667,8 @@ mtable[] =
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "",
"pe-mcore-big", bfd_arch_mcore,
mcore_be_jtab, sizeof (mcore_be_jtab), 8
mcore_be_jtab, sizeof (mcore_be_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -647,7 +677,8 @@ mtable[] =
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "-EL",
"pe-mcore-little", bfd_arch_mcore,
mcore_le_jtab, sizeof (mcore_le_jtab), 8
mcore_le_jtab, sizeof (mcore_le_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -656,7 +687,8 @@ mtable[] =
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "",
"elf32-mcore-big", bfd_arch_mcore,
mcore_be_jtab, sizeof (mcore_be_jtab), 8
mcore_be_jtab, sizeof (mcore_be_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -665,7 +697,8 @@ mtable[] =
"lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long",
".global", ".space", ".align\t2",".align\t4", "-EL",
"elf32-mcore-little", bfd_arch_mcore,
mcore_le_jtab, sizeof (mcore_le_jtab), 8
mcore_le_jtab, sizeof (mcore_le_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -674,7 +707,8 @@ mtable[] =
"ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
".global", ".space", ".align\t2",".align\t4", "",
"epoc-pe-arm-little", bfd_arch_arm,
arm_jtab, sizeof (arm_jtab), 8
arm_jtab, sizeof (arm_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -683,7 +717,8 @@ mtable[] =
"ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
".global", ".space", ".align\t2",".align\t4", "-mapcs-32",
"pe-arm-wince-little", bfd_arch_arm,
arm_jtab, sizeof (arm_jtab), 8
arm_jtab, sizeof (arm_jtab), 8,
0, 0, 0, 0, 0, 0
}
,
{
@ -691,10 +726,11 @@ mtable[] =
"i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
"jmp *", ".global", ".space", ".align\t2",".align\t4", "",
"pe-x86-64",bfd_arch_i386,
i386_jtab, sizeof (i386_jtab), 2
i386_jtab, sizeof (i386_jtab), 2,
i386_dljtab, sizeof (i386_dljtab), 2, 7, 12, i386_trampoline
}
,
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
typedef struct dlist
@ -756,10 +792,11 @@ static void gen_exp_file (void);
static const char *xlate (const char *);
static char *make_label (const char *, const char *);
static char *make_imp_label (const char *, const char *);
static bfd *make_one_lib_file (export_type *, int);
static bfd *make_one_lib_file (export_type *, int, int);
static bfd *make_head (void);
static bfd *make_tail (void);
static void gen_lib_file (void);
static bfd *make_delay_head (void);
static void gen_lib_file (int);
static void dll_name_list_append (dll_name_list_type *, bfd_byte *);
static int dll_name_list_count (dll_name_list_type *);
static void dll_name_list_print (dll_name_list_type *);
@ -923,9 +960,14 @@ asm_prefix (int machine, const char *name)
#define HOW_BFD_READ_TARGET 0 /* Always default. */
#define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target
#define HOW_BFD_ARCH mtable[machine].how_bfd_arch
#define HOW_JTAB mtable[machine].how_jtab
#define HOW_JTAB_SIZE mtable[machine].how_jtab_size
#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
#define HOW_JTAB (delay ? mtable[machine].how_dljtab \
: mtable[machine].how_jtab)
#define HOW_JTAB_SIZE (delay ? mtable[machine].how_dljtab_size \
: mtable[machine].how_jtab_size)
#define HOW_JTAB_ROFF (delay ? mtable[machine].how_dljtab_roff1 \
: mtable[machine].how_jtab_roff)
#define HOW_JTAB_ROFF2 (delay ? mtable[machine].how_dljtab_roff2 : 0)
#define HOW_JTAB_ROFF3 (delay ? mtable[machine].how_dljtab_roff3 : 0)
#define ASM_SWITCHES mtable[machine].how_default_as_switches
static char **oav;
@ -2296,7 +2338,7 @@ make_imp_label (const char *prefix, const char *name)
}
static bfd *
make_one_lib_file (export_type *exp, int i)
make_one_lib_file (export_type *exp, int i, int delay)
{
bfd * abfd;
asymbol * exp_label;
@ -2462,7 +2504,7 @@ make_one_lib_file (export_type *exp, int i)
{
sinfo *si = secdata + i;
asection *sec = si->sec;
arelent *rel;
arelent *rel, *rel2 = 0, *rel3 = 0;
arelent **rpp;
switch (i)
@ -2477,13 +2519,26 @@ make_one_lib_file (export_type *exp, int i)
/* Add the reloc into idata$5. */
rel = xmalloc (sizeof (arelent));
rpp = xmalloc (sizeof (arelent *) * 2);
rpp = xmalloc (sizeof (arelent *) * (delay ? 4 : 2));
rpp[0] = rel;
rpp[1] = 0;
rel->address = HOW_JTAB_ROFF;
rel->addend = 0;
if (delay)
{
rel2 = xmalloc (sizeof (arelent));
rpp[1] = rel2;
rel2->address = HOW_JTAB_ROFF2;
rel2->addend = 0;
rel3 = xmalloc (sizeof (arelent));
rpp[2] = rel3;
rel3->address = HOW_JTAB_ROFF3;
rel3->addend = 0;
rpp[3] = 0;
}
if (machine == MPPC)
{
rel->howto = bfd_reloc_type_lookup (abfd,
@ -2501,12 +2556,41 @@ make_one_lib_file (export_type *exp, int i)
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
rel->sym_ptr_ptr = secdata[IDATA5].sympp;
}
if (delay)
{
rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
rel3->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32_PCREL);
rel3->sym_ptr_ptr = iname_lab_pp;
}
sec->orelocation = rpp;
sec->reloc_count = 1;
sec->reloc_count = delay ? 3 : 1;
}
break;
case IDATA4:
case IDATA5:
if (delay)
{
si->data = xmalloc (4);
si->size = 4;
sec->reloc_count = 1;
memset (si->data, 0, si->size);
si->data[0] = 6;
rel = xmalloc (sizeof (arelent));
rpp = xmalloc (sizeof (arelent *) * 2);
rpp[0] = rel;
rpp[1] = 0;
rel->address = 0;
rel->addend = 0;
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
rel->sym_ptr_ptr = secdata[TEXT].sympp;
sec->orelocation = rpp;
break;
}
/* else fall through */
case IDATA4:
/* An idata$4 or idata$5 is one word long, and has an
rva to idata$6. */
@ -2584,6 +2668,8 @@ make_one_lib_file (export_type *exp, int i)
}
break;
case IDATA7:
if (delay)
break;
si->size = 4;
si->data = xmalloc (4);
memset (si->data, 0, si->size);
@ -2753,9 +2839,9 @@ make_head (void)
}
fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
fprintf (f, "\t.section .idata$2\n");
fprintf (f, "\t.section\t.idata$2\n");
fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
fprintf (f,"\t%s\t%s\n", ASM_GLOBAL, head_label);
fprintf (f, "%s:\n", head_label);
@ -2810,6 +2896,79 @@ make_head (void)
return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
}
bfd *
make_delay_head (void)
{
FILE *f = fopen (TMP_HEAD_S, FOPEN_WT);
if (f == NULL)
{
fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S);
return NULL;
}
/* Output the __tailMerge__xxx function */
fprintf (f, "%s Import trampoline\n", ASM_C);
fprintf (f, "\t.section\t.text\n");
fprintf(f,"\t%s\t%s\n", ASM_GLOBAL, head_label);
fprintf (f, "%s:\n", head_label);
fprintf (f, mtable[machine].trampoline, imp_name_lab);
/* Output the delay import descriptor */
fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C);
fprintf (f, ".section\t.text$2\n");
fprintf (f,"%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab);
fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab);
fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C);
fprintf (f, "\t%s__%s_iname%s\t%s rvaDLLName\n",
ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s__DLL_HANDLE_%s%s\t%s rvaHmod\n",
ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s__IAT_%s%s\t%s rvaIAT\n",
ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s__INT_%s%s\t%s rvaINT\n",
ASM_RVA_BEFORE, imp_name_lab, ASM_RVA_AFTER, ASM_C);
fprintf (f, "\t%s\t0\t%s rvaBoundIAT\n", ASM_LONG, ASM_C);
fprintf (f, "\t%s\t0\t%s rvaUnloadIAT\n", ASM_LONG, ASM_C);
fprintf (f, "\t%s\t0\t%s dwTimeStamp\n", ASM_LONG, ASM_C);
/* Output the dll_handle */
fprintf (f, "\n.section .data\n");
fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
fprintf (f, "\n");
fprintf (f, "%sStuff for compatibility\n", ASM_C);
if (!no_idata5)
{
fprintf (f, "\t.section\t.idata$5\n");
/* NULL terminating list. */
#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, "__IAT_%s:\n", imp_name_lab);
}
if (!no_idata4)
{
fprintf (f, "\t.section\t.idata$4\n");
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t.section\t.idata$4\n");
fprintf (f, "__INT_%s:\n", imp_name_lab);
}
fprintf (f, "\t.section\t.idata$2\n");
fclose (f);
assemble_file (TMP_HEAD_S, TMP_HEAD_O);
return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET);
}
static bfd *
make_tail (void)
{
@ -2823,7 +2982,7 @@ make_tail (void)
if (!no_idata4)
{
fprintf (f, "\t.section .idata$4\n");
fprintf (f, "\t.section\t.idata$4\n");
if (create_for_pep)
fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
else
@ -2832,7 +2991,7 @@ make_tail (void)
if (!no_idata5)
{
fprintf (f, "\t.section .idata$5\n");
fprintf (f, "\t.section\t.idata$5\n");
if (create_for_pep)
fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
else
@ -2847,7 +3006,7 @@ make_tail (void)
comdat, that is) or cause it to be inserted by something else (say
crt0). */
fprintf (f, "\t.section .idata$3\n");
fprintf (f, "\t.section\t.idata$3\n");
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t%s\t0\n", ASM_LONG);
fprintf (f, "\t%s\t0\n", ASM_LONG);
@ -2858,9 +3017,9 @@ make_tail (void)
#ifdef DLLTOOL_PPC
/* Other PowerPC NT compilers use idata$6 for the dllname, so I
do too. Original, huh? */
fprintf (f, "\t.section .idata$6\n");
fprintf (f, "\t.section\t.idata$6\n");
#else
fprintf (f, "\t.section .idata$7\n");
fprintf (f, "\t.section\t.idata$7\n");
#endif
fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
@ -2875,7 +3034,7 @@ make_tail (void)
}
static void
gen_lib_file (void)
gen_lib_file (int delay)
{
int i;
export_type *exp;
@ -2900,7 +3059,14 @@ gen_lib_file (void)
outarch->is_thin_archive = 0;
/* Work out a reasonable size of things to put onto one line. */
ar_head = make_head ();
if (delay)
{
ar_head = make_delay_head ();
}
else
{
ar_head = make_head ();
}
ar_tail = make_tail();
if (ar_head == NULL || ar_tail == NULL)
@ -2912,7 +3078,7 @@ gen_lib_file (void)
/* Don't add PRIVATE entries to import lib. */
if (exp->private)
continue;
n = make_one_lib_file (exp, i);
n = make_one_lib_file (exp, i, delay);
n->archive_next = head;
head = n;
if (ext_prefix_alias)
@ -2931,7 +3097,7 @@ gen_lib_file (void)
alias_exp.hint = exp->hint;
alias_exp.forward = exp->forward;
alias_exp.next = exp->next;
n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE);
n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE, delay);
n->archive_next = head;
head = n;
}
@ -3628,6 +3794,7 @@ usage (FILE *file, int status)
fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n"));
fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n"));
fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n"));
fprintf (file, _(" -y --output-delaylib <outname> Create a delay-import library.\n"));
fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n"));
fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n"));
fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n"));
@ -3710,6 +3877,7 @@ static const struct option long_options[] =
{"mcore-elf", required_argument, NULL, 'M'},
{"compat-implib", no_argument, NULL, 'C'},
{"temp-prefix", required_argument, NULL, 't'},
{"output-delaylib", required_argument, NULL, 'y'},
{NULL,0,NULL,0}
};
@ -3739,7 +3907,7 @@ main (int ac, char **av)
#ifdef DLLTOOL_MCORE_ELF
"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:nI:vVHh",
"m:e:l:y:aD:d:z:b:xp:cCuUkAS:f:nI:vVHh",
#endif
long_options, 0))
!= EOF)
@ -3860,6 +4028,9 @@ main (int ac, char **av)
case 'C':
create_compat_implib = 1;
break;
case 'y':
delayimp_name = optarg;
break;
default:
usage (stderr, 1);
break;
@ -3934,7 +4105,32 @@ main (int ac, char **av)
*p = '_';
}
head_label = make_label("_head_", imp_name_lab);
gen_lib_file ();
gen_lib_file (0);
}
if (delayimp_name)
{
/* Make delayimp_name safe for use as a label. */
char *p;
if (mtable[machine].how_dljtab == 0)
{
inform (_("Warning, machine type (%d) not supported for "
"delayimport."), machine);
}
else
{
killat = 1;
imp_name = delayimp_name;
imp_name_lab = xstrdup (imp_name);
for (p = imp_name_lab; *p; p++)
{
if (!ISALNUM (*p))
*p = '_';
}
head_label = make_label("__tailMerge_", imp_name_lab);
gen_lib_file (1);
}
}
if (output_def)

View File

@ -3497,6 +3497,7 @@ dlltool [@option{-d}|@option{--input-def} @var{def-file-name}]
[@option{-e}|@option{--output-exp} @var{exports-file-name}]
[@option{-z}|@option{--output-def} @var{def-file-name}]
[@option{-l}|@option{--output-lib} @var{library-file-name}]
[@option{-y}|@option{--output-delaylib} @var{library-file-name}]
[@option{--export-all-symbols}] [@option{--no-export-all-symbols}]
[@option{--exclude-symbols} @var{list}]
[@option{--no-default-excludes}]
@ -3563,6 +3564,13 @@ 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.
If the @option{-y} option is specified, dlltool generates a delay-import
library that can be used instead of the normal import library to allow
a program to link to the dll only as soon as an imported function is
called for the first time. The resulting executable will need to be
linked to the static delayimp library containing __delayLoadHelper2(),
which in turn will import LoadLibraryA and GetProcAddress from kernel32.
@command{dlltool} builds the library file by hand, but it builds the
exports file by creating temporary files containing assembler statements
and then assembling these. The @option{-S} command line option can be
@ -3621,6 +3629,10 @@ Specifies the name of the @file{.def} file to be created by dlltool.
@itemx --output-lib @var{filename}
Specifies the name of the library file to be created by dlltool.
@item -y @var{filename}
@itemx --output-delaylib @var{filename}
Specifies the name of the delay-import library file to be created by dlltool.
@item --export-all-symbols
Treat all global and weak defined symbols found in the input object
files as symbols to be exported. There is a small list of symbols which