Line 1... |
Line 1... |
/* dlltool.c -- tool to generate stuff for PE style DLLs
|
/* dlltool.c -- tool to generate stuff for PE style DLLs
|
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
2005, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
|
2005, 2006, 2007, 2008, 2009, 2011, 2012 Free Software Foundation, Inc.
|
|
|
This file is part of GNU Binutils.
|
This file is part of GNU Binutils.
|
|
|
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
Line 230... |
Line 230... |
= Array of { short, asciz } entries, one for each imported function.
|
= Array of { short, asciz } entries, one for each imported function.
|
The `short' is the function's ordinal number.
|
The `short' is the function's ordinal number.
|
|
|
.idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
|
.idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */
|
|
|
/* AIX requires this to be the first thing in the file. */
|
|
#ifndef __GNUC__
|
|
# ifdef _AIX
|
|
#pragma alloca
|
|
#endif
|
|
#endif
|
|
|
|
#define show_allnames 0
|
|
|
|
#include "sysdep.h"
|
#include "sysdep.h"
|
#include "bfd.h"
|
#include "bfd.h"
|
#include "libiberty.h"
|
#include "libiberty.h"
|
#include "getopt.h"
|
#include "getopt.h"
|
#include "demangle.h"
|
#include "demangle.h"
|
Line 250... |
Line 241... |
#include "bucomm.h"
|
#include "bucomm.h"
|
#include "dlltool.h"
|
#include "dlltool.h"
|
#include "safe-ctype.h"
|
#include "safe-ctype.h"
|
|
|
#include <time.h>
|
#include <time.h>
|
#include <sys/stat.h>
|
|
#include <stdarg.h>
|
|
#include <assert.h>
|
#include <assert.h>
|
|
|
#ifdef DLLTOOL_ARM
|
#ifdef DLLTOOL_ARM
|
#include "coff/arm.h"
|
#include "coff/arm.h"
|
#include "coff/internal.h"
|
#include "coff/internal.h"
|
Line 317... |
Line 306... |
#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
|
#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)
|
#endif
|
#endif
|
#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
|
#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
|
#endif /* ! HAVE_SYS_WAIT_H */
|
#endif /* ! HAVE_SYS_WAIT_H */
|
|
|
|
#define show_allnames 0
|
|
|
/* ifunc and ihead data structures: ttk@cygnus.com 1997
|
/* ifunc and ihead data structures: ttk@cygnus.com 1997
|
|
|
When IMPORT declarations are encountered in a .def file the
|
When IMPORT declarations are encountered in a .def file the
|
function import information is stored in a structure referenced by
|
function import information is stored in a structure referenced by
|
the global variable IMPORT_LIST. The structure is a linked list
|
the global variable IMPORT_LIST. The structure is a linked list
|
Line 522... |
Line 513... |
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
|
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
|
0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
|
0xB8, 0x00, 0x00, 0x00, 0x00, /* mov eax, offset __imp__function */
|
0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
|
0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
|
};
|
};
|
|
|
|
static const unsigned char i386_x64_dljtab[] =
|
|
{
|
|
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, /* jmp __imp__function */
|
|
0x48, 0x8d, 0x05, /* leaq rax, (__imp__function) */
|
|
0x00, 0x00, 0x00, 0x00,
|
|
0xE9, 0x00, 0x00, 0x00, 0x00 /* jmp __tailMerge__dllname */
|
|
};
|
|
|
static const unsigned char arm_jtab[] =
|
static const unsigned char arm_jtab[] =
|
{
|
{
|
0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
|
0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */
|
0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
|
0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */
|
0, 0, 0, 0
|
0, 0, 0, 0
|
Line 598... |
Line 597... |
"\tcall ___delayLoadHelper2@8\n"
|
"\tcall ___delayLoadHelper2@8\n"
|
"\tpopl %%edx\n"
|
"\tpopl %%edx\n"
|
"\tpopl %%ecx\n"
|
"\tpopl %%ecx\n"
|
"\tjmp *%%eax\n";
|
"\tjmp *%%eax\n";
|
|
|
|
static const char i386_x64_trampoline[] =
|
|
"\tpushq %%rcx\n"
|
|
"\tpushq %%rdx\n"
|
|
"\tpushq %%r8\n"
|
|
"\tpushq %%r9\n"
|
|
"\tsubq $40, %%rsp\n"
|
|
"\tmovq %%rax, %%rdx\n"
|
|
"\tleaq __DELAY_IMPORT_DESCRIPTOR_%s(%%rip), %%rcx\n"
|
|
"\tcall __delayLoadHelper2\n"
|
|
"\taddq $40, %%rsp\n"
|
|
"\tpopq %%r9\n"
|
|
"\tpopq %%r8\n"
|
|
"\tpopq %%rdx\n"
|
|
"\tpopq %%rcx\n"
|
|
"\tjmp *%%rax\n";
|
|
|
struct mac
|
struct mac
|
{
|
{
|
const char *type;
|
const char *type;
|
const char *how_byte;
|
const char *how_byte;
|
const char *how_short;
|
const char *how_short;
|
Line 742... |
Line 757... |
#define MX86 11
|
#define MX86 11
|
"i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
|
"i386:x86-64", ".byte", ".short", ".long", ".asciz", "#",
|
"jmp *", ".global", ".space", ".align\t2",".align\t4", "",
|
"jmp *", ".global", ".space", ".align\t2",".align\t4", "",
|
"pe-x86-64",bfd_arch_i386,
|
"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
|
i386_x64_dljtab, sizeof (i386_x64_dljtab), 2, 9, 14, i386_x64_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, 0, 0, 0, 0, 0, 0 }
|
};
|
};
|
|
|
Line 2616... |
Line 2631... |
rel->sym_ptr_ptr = secdata[IDATA5].sympp;
|
rel->sym_ptr_ptr = secdata[IDATA5].sympp;
|
}
|
}
|
|
|
if (delay)
|
if (delay)
|
{
|
{
|
|
if (machine == MX86)
|
|
rel2->howto = bfd_reloc_type_lookup (abfd,
|
|
BFD_RELOC_32_PCREL);
|
|
else
|
rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
|
rel2->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
|
rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
|
rel2->sym_ptr_ptr = rel->sym_ptr_ptr;
|
rel3->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32_PCREL);
|
rel3->howto = bfd_reloc_type_lookup (abfd,
|
|
BFD_RELOC_32_PCREL);
|
rel3->sym_ptr_ptr = iname_lab_pp;
|
rel3->sym_ptr_ptr = iname_lab_pp;
|
}
|
}
|
|
|
sec->orelocation = rpp;
|
sec->orelocation = rpp;
|
sec->reloc_count = delay ? 3 : 1;
|
sec->reloc_count = delay ? 3 : 1;
|
Line 2630... |
Line 2650... |
break;
|
break;
|
|
|
case IDATA5:
|
case IDATA5:
|
if (delay)
|
if (delay)
|
{
|
{
|
si->data = xmalloc (4);
|
si->size = create_for_pep ? 8 : 4;
|
si->size = 4;
|
si->data = xmalloc (si->size);
|
sec->reloc_count = 1;
|
sec->reloc_count = 1;
|
memset (si->data, 0, si->size);
|
memset (si->data, 0, si->size);
|
|
/* Point after jmp [__imp_...] instruction. */
|
si->data[0] = 6;
|
si->data[0] = 6;
|
rel = xmalloc (sizeof (arelent));
|
rel = xmalloc (sizeof (arelent));
|
rpp = xmalloc (sizeof (arelent *) * 2);
|
rpp = xmalloc (sizeof (arelent *) * 2);
|
rpp[0] = rel;
|
rpp[0] = rel;
|
rpp[1] = 0;
|
rpp[1] = 0;
|
rel->address = 0;
|
rel->address = 0;
|
rel->addend = 0;
|
rel->addend = 0;
|
|
if (create_for_pep)
|
|
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_64);
|
|
else
|
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
|
rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
|
rel->sym_ptr_ptr = secdata[TEXT].sympp;
|
rel->sym_ptr_ptr = secdata[TEXT].sympp;
|
sec->orelocation = rpp;
|
sec->orelocation = rpp;
|
break;
|
break;
|
}
|
}
|
Line 3012... |
Line 3036... |
|
|
/* Output the dll_handle */
|
/* Output the dll_handle */
|
fprintf (f, "\n.section .data\n");
|
fprintf (f, "\n.section .data\n");
|
fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
|
fprintf (f, "__DLL_HANDLE_%s:\n", imp_name_lab);
|
fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
|
fprintf (f, "\t%s\t0\t%s Handle\n", ASM_LONG, ASM_C);
|
|
if (create_for_pep)
|
|
fprintf (f, "\t%s\t0\n", ASM_LONG);
|
fprintf (f, "\n");
|
fprintf (f, "\n");
|
|
|
fprintf (f, "%sStuff for compatibility\n", ASM_C);
|
fprintf (f, "%sStuff for compatibility\n", ASM_C);
|
|
|
if (!no_idata5)
|
if (!no_idata5)
|
{
|
{
|
fprintf (f, "\t.section\t.idata$5\n");
|
fprintf (f, "\t.section\t.idata$5\n");
|
/* NULL terminating list. */
|
/* NULL terminating list. */
|
#ifdef DLLTOOL_MX86_64
|
if (create_for_pep)
|
fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
|
fprintf (f,"\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG);
|
#else
|
else
|
fprintf (f,"\t%s\t0\n", ASM_LONG);
|
fprintf (f,"\t%s\t0\n", ASM_LONG);
|
#endif
|
|
fprintf (f, "__IAT_%s:\n", imp_name_lab);
|
fprintf (f, "__IAT_%s:\n", imp_name_lab);
|
}
|
}
|
|
|
if (!no_idata4)
|
if (!no_idata4)
|
{
|
{
|
fprintf (f, "\t.section\t.idata$4\n");
|
fprintf (f, "\t.section\t.idata$4\n");
|
fprintf (f, "\t%s\t0\n", ASM_LONG);
|
fprintf (f, "\t%s\t0\n", ASM_LONG);
|
|
if (create_for_pep)
|
|
fprintf (f, "\t%s\t0\n", ASM_LONG);
|
fprintf (f, "\t.section\t.idata$4\n");
|
fprintf (f, "\t.section\t.idata$4\n");
|
fprintf (f, "__INT_%s:\n", imp_name_lab);
|
fprintf (f, "__INT_%s:\n", imp_name_lab);
|
}
|
}
|
|
|
fprintf (f, "\t.section\t.idata$2\n");
|
fprintf (f, "\t.section\t.idata$2\n");
|