mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-11 10:34:03 +08:00
clean up IMPORTS changes
This commit is contained in:
parent
47cbef8df8
commit
c027e8b019
@ -1,9 +1,14 @@
|
||||
Tue Apr 28 10:33:07 1998 Bill Moyer <ttk@cygnus.com>
|
||||
|
||||
* dlltool.c, defparse.y, dlltool.h: added support
|
||||
for parsing IMPORT declarations from input def
|
||||
file correctly, added .idata sections to exp-file
|
||||
object code.
|
||||
|
||||
Add support for IMPORTS:
|
||||
* defparse.y (impline): Add IMPORTS syntaxes.
|
||||
* dlltool.c (ifunctype, iheadtype): New typedefs.
|
||||
(import_list): New static variable.
|
||||
(append_import): New static function.
|
||||
(def_import): Add an entry to import_list.
|
||||
(generate_idata_ofile): New static function.
|
||||
(gen_exp_file): Call generate_idata_ofile.
|
||||
* dlltool.h (def_import): Update declaration.
|
||||
|
||||
Mon Apr 27 16:39:22 1998 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* dlltool.c -- tool to generate stuff for PE style DLLs
|
||||
/* dlltool.c -- tool to generate stuff for PE style DLLs
|
||||
Copyright (C) 1995, 96, 97, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
@ -31,20 +31,20 @@
|
||||
|
||||
A DLL contains an export table which contains the information
|
||||
which the runtime loader needs to tie up references from a
|
||||
referencing program.
|
||||
referencing program.
|
||||
|
||||
The export table is generated by this program by reading
|
||||
in a .DEF file or scanning the .a and .o files which will be in the
|
||||
DLL. A .o file can contain information in special ".drectve" sections
|
||||
with export information.
|
||||
with export information.
|
||||
|
||||
A DEF file contains any number of the following commands:
|
||||
|
||||
|
||||
NAME <name> [ , <base> ]
|
||||
NAME <name> [ , <base> ]
|
||||
The result is going to be <name>.EXE
|
||||
|
||||
LIBRARY <name> [ , <base> ]
|
||||
LIBRARY <name> [ , <base> ]
|
||||
The result is going to be <name>.DLL
|
||||
|
||||
EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) *
|
||||
@ -77,7 +77,7 @@
|
||||
|
||||
|
||||
The program generates output files with the prefix supplied
|
||||
on the command line, or in the def file, or taken from the first
|
||||
on the command line, or in the def file, or taken from the first
|
||||
supplied argument.
|
||||
|
||||
The .exp.s file contains the information necessary to export
|
||||
@ -88,8 +88,8 @@
|
||||
|
||||
Example:
|
||||
|
||||
file1.c:
|
||||
asm (".section .drectve");
|
||||
file1.c:
|
||||
asm (".section .drectve");
|
||||
asm (".ascii \"-export:adef\"");
|
||||
|
||||
adef(char *s)
|
||||
@ -133,7 +133,7 @@
|
||||
LIBRARY thedll
|
||||
HEAPSIZE 0x40000, 0x2000
|
||||
EXPORTS bdef @ 20
|
||||
cdef @ 30 NONAME
|
||||
cdef @ 30 NONAME
|
||||
|
||||
SECTIONS donkey READ WRITE
|
||||
aardvark EXECUTE
|
||||
@ -141,7 +141,7 @@
|
||||
|
||||
# compile up the parts of the dll
|
||||
|
||||
gcc -c file1.c
|
||||
gcc -c file1.c
|
||||
gcc -c file2.c
|
||||
|
||||
# put them in a library (you don't have to, you
|
||||
@ -157,7 +157,7 @@
|
||||
ld -o thedll.dll thedll.o thedll.in
|
||||
|
||||
# build the mainline
|
||||
gcc -c themain.c
|
||||
gcc -c themain.c
|
||||
|
||||
# link the executable with the import library
|
||||
ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
|
||||
@ -254,49 +254,41 @@
|
||||
#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */
|
||||
#endif /* ! HAVE_SYS_WAIT_H */
|
||||
|
||||
/* ifunc and ihead data structures: ttk@cygnus.com 1997
|
||||
When IMPORT declarations are encountered in a .def file the
|
||||
function import information is stored in a structure referenced
|
||||
by the global variable "(iheadtype*) import_list". The struc-
|
||||
ture is a linked list containing the names of the dll files
|
||||
each function is imported from and a linked list of functions
|
||||
being imported from that dll file. This roughly parallels the
|
||||
structure of the .idata section in the PE object file.
|
||||
The contents of .def file are interpreted from within the
|
||||
process__def_file() function. Every time an IMPORT declaration
|
||||
is encountered, it is broken up into its component parts and
|
||||
passed to def_import(). import_list is initialized to NULL in
|
||||
function main().
|
||||
*/
|
||||
|
||||
typedef struct ifunct
|
||||
{
|
||||
char *name; /* name of function being imported */
|
||||
int ord; /* two-byte ordinal value associated with function */
|
||||
struct ifunct *next;
|
||||
}
|
||||
ifunctype;
|
||||
/* ifunc and ihead data structures: ttk@cygnus.com 1997
|
||||
|
||||
typedef struct iheadt
|
||||
{
|
||||
char *dllname; /* name of dll file imported from */
|
||||
long nfuncs; /* number of functions in list */
|
||||
struct ifunct *funchead; /* first function in list */
|
||||
struct ifunct *functail; /* last function in list */
|
||||
struct iheadt *next; /* next dll file in list */
|
||||
}
|
||||
iheadtype;
|
||||
|
||||
/* ignore_imports: if true, IMPORT declarations are ignored
|
||||
and no .import section will be created.
|
||||
import_list: structure containing all import information as
|
||||
defined in .def file (qv "ihead structure").
|
||||
nheads: count of number of dll files recorded in import_list.
|
||||
*/
|
||||
When IMPORT declarations are encountered in a .def file the
|
||||
function import information is stored in a structure referenced by
|
||||
the global variable IMPORT_LIST. The structure is a linked list
|
||||
containing the names of the dll files each function is imported
|
||||
from and a linked list of functions being imported from that dll
|
||||
file. This roughly parallels the structure of the .idata section
|
||||
in the PE object file.
|
||||
|
||||
static boolean ignore_imports = false;
|
||||
static iheadtype *import_list = NULL;
|
||||
static long nheads;
|
||||
The contents of .def file are interpreted from within the
|
||||
process_def_file function. Every time an IMPORT declaration is
|
||||
encountered, it is broken up into its component parts and passed to
|
||||
def_import. IMPORT_LIST is initialized to NULL in function main. */
|
||||
|
||||
typedef struct ifunct
|
||||
{
|
||||
char *name; /* name of function being imported */
|
||||
int ord; /* two-byte ordinal value associated with function */
|
||||
struct ifunct *next;
|
||||
} ifunctype;
|
||||
|
||||
typedef struct iheadt
|
||||
{
|
||||
char *dllname; /* name of dll file imported from */
|
||||
long nfuncs; /* number of functions in list */
|
||||
struct ifunct *funchead; /* first function in list */
|
||||
struct ifunct *functail; /* last function in list */
|
||||
struct iheadt *next; /* next dll file in list */
|
||||
} iheadtype;
|
||||
|
||||
/* Structure containing all import information as defined in .def file
|
||||
(qv "ihead structure"). */
|
||||
|
||||
static iheadtype *import_list = NULL;
|
||||
|
||||
static char *as_name = "as";
|
||||
|
||||
@ -355,8 +347,8 @@ static const unsigned char arm_jtab[] =
|
||||
/* We also need a IMGLUE reloc against the glue function */
|
||||
/* to restore the toc saved by the third instruction in */
|
||||
/* the glue. */
|
||||
static const unsigned char ppc_jtab[] =
|
||||
{
|
||||
static const unsigned char ppc_jtab[] =
|
||||
{
|
||||
0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
|
||||
/* Reloc TOCREL16 __imp_xxx */
|
||||
0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
|
||||
@ -398,7 +390,7 @@ static const struct mac mtable[] =
|
||||
{
|
||||
{
|
||||
#define MARM 0
|
||||
"arm", ".byte", ".short", ".long", ".asciz", "@",
|
||||
"arm", ".byte", ".short", ".long", ".asciz", "@",
|
||||
"ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
|
||||
".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
|
||||
arm_jtab, sizeof(arm_jtab),8
|
||||
@ -442,6 +434,7 @@ export_type;
|
||||
static const char *rvaafter PARAMS ((int));
|
||||
static const char *rvabefore PARAMS ((int));
|
||||
static const char *asm_prefix PARAMS ((int));
|
||||
static void append_import PARAMS ((const char *, const char *, int));
|
||||
static void run PARAMS ((const char *, char *));
|
||||
static void basenames PARAMS ((bfd *));
|
||||
static void scan_open_obj_file PARAMS ((bfd *));
|
||||
@ -450,6 +443,7 @@ static void dump_def_info PARAMS ((FILE *));
|
||||
static int sfunc PARAMS ((const void *, const void *));
|
||||
static void flush_page PARAMS ((FILE *, long *, int, int));
|
||||
static void gen_def_file PARAMS ((void));
|
||||
static void generate_idata_ofile PARAMS ((FILE *));
|
||||
static void gen_exp_file PARAMS ((void));
|
||||
static const char *xlate PARAMS ((const char *));
|
||||
static void dump_iat PARAMS ((FILE *, export_type *));
|
||||
@ -536,9 +530,6 @@ asm_prefix (machine)
|
||||
#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
|
||||
static char **oav;
|
||||
|
||||
FILE *yyin; /* communications with flex */
|
||||
extern int linenumber;
|
||||
|
||||
void
|
||||
process_def_file (name)
|
||||
const char *name;
|
||||
@ -572,7 +563,7 @@ static dlist_type *a_list; /* Stuff to go in directives */
|
||||
static int d_is_dll;
|
||||
static int d_is_exe;
|
||||
|
||||
int
|
||||
int
|
||||
yyerror (err)
|
||||
const char *err;
|
||||
{
|
||||
@ -679,126 +670,105 @@ def_stacksize (reserve, commit)
|
||||
new_directive (xstrdup (b));
|
||||
}
|
||||
|
||||
/* append_import() simply adds the given import definition
|
||||
to the global import_list. It is used by def_import().
|
||||
*/
|
||||
void
|
||||
/* append_import simply adds the given import definition to the global
|
||||
import_list. It is used by def_import. */
|
||||
|
||||
static void
|
||||
append_import (symbol_name, dll_name, func_ordinal)
|
||||
char *symbol_name;
|
||||
char *dll_name;
|
||||
char *func_ordinal;
|
||||
{
|
||||
iheadtype *headptr;
|
||||
const char *symbol_name;
|
||||
const char *dll_name;
|
||||
int func_ordinal;
|
||||
{
|
||||
iheadtype **pq;
|
||||
iheadtype *q;
|
||||
|
||||
if (import_list == NULL)
|
||||
{
|
||||
import_list = xmalloc (sizeof (iheadtype));
|
||||
import_list->dllname = xstrdup (dll_name);
|
||||
import_list->nfuncs = 1;
|
||||
import_list->funchead = xmalloc (sizeof (ifunctype));
|
||||
import_list->functail = import_list->funchead;
|
||||
import_list->next = NULL;
|
||||
import_list->functail->name = xstrdup (symbol_name);
|
||||
import_list->functail->ord = atoi (func_ordinal);
|
||||
import_list->functail->next = NULL;
|
||||
return;
|
||||
} /* END of case import_list == NULL */
|
||||
headptr = import_list;
|
||||
while ((strcmp (headptr->dllname,dll_name))
|
||||
&& (headptr->next != NULL))
|
||||
headptr = headptr->next;
|
||||
if (!strcmp (headptr->dllname, dll_name))
|
||||
{
|
||||
headptr->functail->next = xmalloc (sizeof (ifunctype));
|
||||
headptr->functail = headptr->functail->next;
|
||||
headptr->functail->ord = atoi (func_ordinal);
|
||||
headptr->functail->name = xstrdup (symbol_name);
|
||||
headptr->functail->next = NULL;
|
||||
headptr->nfuncs++;
|
||||
}
|
||||
else
|
||||
{ /* this dll doesn't already have entry */
|
||||
headptr->next = xmalloc (sizeof (iheadtype));
|
||||
headptr = headptr->next;
|
||||
headptr->dllname = xstrdup (dll_name);
|
||||
headptr->nfuncs = 1;
|
||||
headptr->funchead = xmalloc (sizeof (ifunctype));
|
||||
headptr->functail = headptr->funchead;
|
||||
headptr->next = NULL;
|
||||
headptr->functail->name = xstrdup (symbol_name);
|
||||
headptr->functail->ord = atoi (func_ordinal);
|
||||
headptr->functail->next = NULL;
|
||||
} /* END of if..else clause */
|
||||
} /* END of function append_import */
|
||||
for (pq = &import_list; *pq != NULL; pq = &(*pq)->next)
|
||||
{
|
||||
if (strcmp ((*pq)->dllname, dll_name) == 0)
|
||||
{
|
||||
q = *pq;
|
||||
q->functail->next = xmalloc (sizeof (ifunctype));
|
||||
q->functail = q->functail->next;
|
||||
q->functail->ord = func_ordinal;
|
||||
q->functail->name = xstrdup (symbol_name);
|
||||
q->functail->next = NULL;
|
||||
q->nfuncs++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* def_import() is called from within defparse.y when an
|
||||
IMPORT declaration is encountered. Depending on the
|
||||
form of the declaration, the module name may or may not
|
||||
need ".dll" to be appended to it, the name of the func-
|
||||
tion may be stored in internal or entry, and there may
|
||||
or may not be an ordinal value associated with it.
|
||||
The interface between def_import() and append_import()
|
||||
is a bit convoluted because append_import() was written
|
||||
to handle a simpler case of IMPORT declaration and I
|
||||
didn't have the time to rewrite it.
|
||||
*/
|
||||
q = xmalloc (sizeof (iheadtype));
|
||||
q->dllname = xstrdup (dll_name);
|
||||
q->nfuncs = 1;
|
||||
q->funchead = xmalloc (sizeof (ifunctype));
|
||||
q->functail = q->funchead;
|
||||
q->next = NULL;
|
||||
q->functail->name = xstrdup (symbol_name);
|
||||
q->functail->ord = func_ordinal;
|
||||
q->functail->next = NULL;
|
||||
|
||||
*pq = q;
|
||||
}
|
||||
|
||||
/* def_import is called from within defparse.y when an IMPORT
|
||||
declaration is encountered. Depending on the form of the
|
||||
declaration, the module name may or may not need ".dll" to be
|
||||
appended to it, the name of the function may be stored in internal
|
||||
or entry, and there may or may not be an ordinal value associated
|
||||
with it. */
|
||||
|
||||
/* A note regarding the parse modes:
|
||||
In yyparse.y we have to accept import declarations which
|
||||
follow any one of the following forms:
|
||||
In defparse.y we have to accept import declarations which follow
|
||||
any one of the following forms:
|
||||
<func_name_in_app> = <dll_name>.<func_name_in_dll>
|
||||
<func_name_in_app> = <dll_name>.<number>
|
||||
<dll_name>.<func_name_in_dll>
|
||||
<dll_name>.<number>
|
||||
Furthermore, the dll's name may or may not end with ".dll",
|
||||
which complicates the parsing a little. Normally the dll's
|
||||
name is passed to def_import() in the "module" parameter,
|
||||
but when it ends with ".dll" it gets passed in "module" sans
|
||||
".dll" and that needs to be reappended.
|
||||
Furthermore, the dll's name may or may not end with ".dll", which
|
||||
complicates the parsing a little. Normally the dll's name is
|
||||
passed to def_import() in the "module" parameter, but when it ends
|
||||
with ".dll" it gets passed in "module" sans ".dll" and that needs
|
||||
to be reappended.
|
||||
|
||||
def_import() gets five parameters:
|
||||
app_name - the name of the function in the application, if
|
||||
def_import gets five parameters:
|
||||
APP_NAME - the name of the function in the application, if
|
||||
present, or NULL if not present.
|
||||
module - the name of the dll, possibly sans extension (ie, '.dll').
|
||||
dllext - the extension of the dll, if present, NULL if not present.
|
||||
entry - the name of the function in the dll, if present, or NULL.
|
||||
ord_val - the numerical tag of the function in the dll, if present,
|
||||
or NULL. Exactly one of <entry> or <ord_val> must be
|
||||
present (ie, not NULL).
|
||||
*/
|
||||
MODULE - the name of the dll, possibly sans extension (ie, '.dll').
|
||||
DLLEXT - the extension of the dll, if present, NULL if not present.
|
||||
ENTRY - the name of the function in the dll, if present, or NULL.
|
||||
ORD_VAL - the numerical tag of the function in the dll, if present,
|
||||
or NULL. Exactly one of <entry> or <ord_val> must be
|
||||
present (i.e., not NULL). */
|
||||
|
||||
void
|
||||
void
|
||||
def_import (app_name, module, dllext, entry, ord_val)
|
||||
char *app_name;
|
||||
char *module;
|
||||
char *dllext;
|
||||
char *entry;
|
||||
int ord_val; /* two-byte value */
|
||||
{
|
||||
char *application_name;
|
||||
char *module_name;
|
||||
char *entry_name;
|
||||
char ord_string[7];
|
||||
char zero_str[1] = { 0 };
|
||||
|
||||
sprintf (ord_string, "%d", ord_val);
|
||||
if (entry)
|
||||
application_name = entry;
|
||||
else
|
||||
if (app_name)
|
||||
application_name = app_name;
|
||||
const char *app_name;
|
||||
const char *module;
|
||||
const char *dllext;
|
||||
const char *entry;
|
||||
int ord_val;
|
||||
{
|
||||
const char *application_name;
|
||||
char *buf;
|
||||
|
||||
if (entry != NULL)
|
||||
application_name = entry;
|
||||
else
|
||||
{
|
||||
if (app_name != NULL)
|
||||
application_name = app_name;
|
||||
else
|
||||
application_name = zero_str;
|
||||
if (dllext)
|
||||
{
|
||||
module_name = (char*) alloca (strlen (module) + strlen(dllext) + 2);
|
||||
sprintf (module_name, "%s.%s", module, dllext);
|
||||
}
|
||||
else
|
||||
module_name = module;
|
||||
entry_name = ord_string;
|
||||
append_import (application_name, module_name, entry_name);
|
||||
} /* END of function def_import */
|
||||
application_name = "";
|
||||
}
|
||||
if (dllext != NULL)
|
||||
{
|
||||
buf = (char *) alloca (strlen (module) + strlen (dllext) + 2);
|
||||
sprintf (buf, "%s.%s", module, dllext);
|
||||
module = buf;
|
||||
}
|
||||
|
||||
append_import (application_name, module, ord_val);
|
||||
}
|
||||
|
||||
void
|
||||
def_version (major, minor)
|
||||
@ -1099,145 +1069,110 @@ gen_def_file ()
|
||||
}
|
||||
}
|
||||
|
||||
/* generate_idata_ofile() generates the portable assembly source code
|
||||
for the idata sections. It may be passed an open FILE* or a NULL.
|
||||
In the former case it appends the source code to the end of the
|
||||
file and returns NULL. In the latter case it creates a file named
|
||||
doi.s, assembles it to doi.o, opens doi.o as a bfd, and returns the
|
||||
bfd*. generate_idata_ofile() is currently used in the former manner
|
||||
in gen_exp_file().
|
||||
*/
|
||||
|
||||
bfd *
|
||||
generate_idata_ofile ( fd )
|
||||
FILE *fd;
|
||||
{
|
||||
FILE *filvar;
|
||||
int result;
|
||||
iheadtype *headptr;
|
||||
ifunctype *funcptr;
|
||||
int headindex;
|
||||
int funcindex;
|
||||
char as_args[16];
|
||||
|
||||
if (fd != NULL)
|
||||
filvar = fd;
|
||||
else
|
||||
filvar = fopen ("doi.s", "w");
|
||||
if (!filvar)
|
||||
{
|
||||
fprintf (stderr, "%s: Can't open doi.s\n", program_name);
|
||||
return ((bfd*)-1);
|
||||
}
|
||||
fprintf (filvar, "%s Import data sections\n", ASM_C);
|
||||
fprintf (filvar, "\n\t.section\t.idata$2\n");
|
||||
fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
|
||||
fprintf (filvar, "doi_idata:\n");
|
||||
|
||||
nheads = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
/* generate_idata_ofile generates the portable assembly source code
|
||||
for the idata sections. It appends the source code to the end of
|
||||
the file. */
|
||||
|
||||
static void
|
||||
generate_idata_ofile (filvar)
|
||||
FILE *filvar;
|
||||
{
|
||||
iheadtype *headptr;
|
||||
ifunctype *funcptr;
|
||||
int headindex;
|
||||
int funcindex;
|
||||
int nheads;
|
||||
|
||||
if (import_list == NULL)
|
||||
return;
|
||||
|
||||
fprintf (filvar, "%s Import data sections\n", ASM_C);
|
||||
fprintf (filvar, "\n\t.section\t.idata$2\n");
|
||||
fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL);
|
||||
fprintf (filvar, "doi_idata:\n");
|
||||
|
||||
nheads = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
|
||||
ASM_RVA_BEFORE, (int)nheads, ASM_RVA_AFTER,
|
||||
ASM_C, headptr->dllname);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
fprintf (filvar, "\t%sdllname%d%s\n",
|
||||
ASM_RVA_BEFORE, (int)nheads, ASM_RVA_AFTER);
|
||||
fprintf (filvar, "\t%slisttwo%d%s\n\n",
|
||||
ASM_RVA_BEFORE, (int)nheads, ASM_RVA_AFTER);
|
||||
nheads++;
|
||||
} /* END of headptr for-loop */
|
||||
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$4\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar, "listone%d:\n", headindex);
|
||||
for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
|
||||
fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
|
||||
ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
|
||||
fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
|
||||
headindex++;
|
||||
} /* END of headptr for loop */
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$5\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar, "listtwo%d:\n", headindex);
|
||||
for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
|
||||
fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
|
||||
ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
|
||||
fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
|
||||
headindex++;
|
||||
} /* END of headptr for-loop */
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$6\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
funcindex = 0;
|
||||
for (funcptr = headptr->funchead; funcptr != NULL;
|
||||
funcptr = funcptr->next)
|
||||
{
|
||||
fprintf (filvar,"funcptr%d_%d:\n",headindex,funcindex);
|
||||
fprintf (filvar,"\t%s\t%d\n",ASM_SHORT,((funcptr->ord) & 0xFFFF));
|
||||
fprintf (filvar,"\t%s\t%c%s%c\n",ASM_TEXT,'"',funcptr->name,'"');
|
||||
fprintf (filvar,"\t%s\t0\n",ASM_BYTE);
|
||||
funcindex++;
|
||||
} /* END of funcptr for loop */
|
||||
headindex++;
|
||||
} /* END of headptr for loop */
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$7\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar,"dllname%d:\n",headindex);
|
||||
fprintf (filvar,"\t%s\t%c%s%c\n",ASM_TEXT,'"',headptr->dllname,'"');
|
||||
fprintf (filvar,"\t%s\t0\n",ASM_BYTE);
|
||||
headindex++;
|
||||
} /* END of headptr for loop */
|
||||
|
||||
if (fd == NULL)
|
||||
{
|
||||
result = fclose (filvar);
|
||||
if ( result )
|
||||
{
|
||||
fprintf (stderr, "%s: Can't close doi.s\n", program_name);
|
||||
return ((bfd*) -1);
|
||||
} /* END of if clause */
|
||||
sprintf (as_args, "-o doi.o doi.s");
|
||||
run (as_name, as_args);
|
||||
|
||||
if (dontdeltemps == 0)
|
||||
{
|
||||
sprintf (outfile, "doi.s");
|
||||
unlink (outfile);
|
||||
}
|
||||
return (bfd_openr ("doi.o", HOW_BFD_TARGET));
|
||||
} /* END of if clause */
|
||||
else
|
||||
return NULL;
|
||||
} /* END of function generate_idata_ofile() */
|
||||
fprintf (filvar, "\t%slistone%d%s\t%s %s\n",
|
||||
ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER,
|
||||
ASM_C, headptr->dllname);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
fprintf (filvar, "\t%sdllname%d%s\n",
|
||||
ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
|
||||
fprintf (filvar, "\t%slisttwo%d%s\n\n",
|
||||
ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER);
|
||||
nheads++;
|
||||
}
|
||||
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG);
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$4\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar, "listone%d:\n", headindex);
|
||||
for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
|
||||
fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
|
||||
ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
|
||||
fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */
|
||||
headindex++;
|
||||
}
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$5\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar, "listtwo%d:\n", headindex);
|
||||
for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ )
|
||||
fprintf (filvar, "\t%sfuncptr%d_%d%s\n",
|
||||
ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER);
|
||||
fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */
|
||||
headindex++;
|
||||
}
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$6\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
funcindex = 0;
|
||||
for (funcptr = headptr->funchead; funcptr != NULL;
|
||||
funcptr = funcptr->next)
|
||||
{
|
||||
fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex);
|
||||
fprintf (filvar,"\t%s\t%d\n", ASM_SHORT,
|
||||
((funcptr->ord) & 0xFFFF));
|
||||
fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name);
|
||||
fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
|
||||
funcindex++;
|
||||
}
|
||||
headindex++;
|
||||
}
|
||||
|
||||
fprintf (filvar, "\n\t.section\t.idata$7\n");
|
||||
headindex = 0;
|
||||
for (headptr = import_list; headptr != NULL; headptr = headptr->next)
|
||||
{
|
||||
fprintf (filvar,"dllname%d:\n", headindex);
|
||||
fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname);
|
||||
fprintf (filvar,"\t%s\t0\n", ASM_BYTE);
|
||||
headindex++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gen_exp_file ()
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
bfd *result;
|
||||
export_type *exp;
|
||||
dlist_type *dl;
|
||||
|
||||
|
||||
sprintf (outfile, "t%s", exp_name);
|
||||
|
||||
if (verbose)
|
||||
@ -1276,7 +1211,7 @@ gen_exp_file ()
|
||||
show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
|
||||
fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
|
||||
|
||||
fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
|
||||
fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
|
||||
ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
|
||||
|
||||
fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
|
||||
@ -1293,7 +1228,7 @@ gen_exp_file ()
|
||||
{
|
||||
if (exp->ordinal != i)
|
||||
{
|
||||
#if 0
|
||||
#if 0
|
||||
fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
|
||||
ASM_SPACE,
|
||||
(exp->ordinal - i) * 4,
|
||||
@ -1428,7 +1363,7 @@ gen_exp_file ()
|
||||
/* Delete duplcates */
|
||||
for (src = 0; src < num_entries; src++)
|
||||
{
|
||||
if (last != copy[src])
|
||||
if (last != copy[src])
|
||||
last = copy[dst++] = copy[src];
|
||||
}
|
||||
num_entries = dst;
|
||||
@ -1452,13 +1387,7 @@ gen_exp_file ()
|
||||
}
|
||||
}
|
||||
|
||||
result = generate_idata_ofile (f);
|
||||
if ( result != NULL )
|
||||
{
|
||||
fprintf (stderr, "%s: error writing idata section\n",
|
||||
program_name);
|
||||
exit (1);
|
||||
}
|
||||
generate_idata_ofile (f);
|
||||
|
||||
fclose (f);
|
||||
|
||||
@ -1501,7 +1430,7 @@ dump_iat (f, exp)
|
||||
FILE *f;
|
||||
export_type *exp;
|
||||
{
|
||||
if (exp->noname && !show_allnames )
|
||||
if (exp->noname && !show_allnames )
|
||||
{
|
||||
fprintf (f, "\t%s\t0x%08x\n",
|
||||
ASM_LONG,
|
||||
@ -1515,7 +1444,7 @@ dump_iat (f, exp)
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
int id;
|
||||
const char *name;
|
||||
@ -1540,7 +1469,7 @@ typedef struct
|
||||
|
||||
#define NSECS 7
|
||||
|
||||
static sinfo secdata[NSECS] =
|
||||
static sinfo secdata[NSECS] =
|
||||
{
|
||||
{ TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 2},
|
||||
{ DATA, ".data", SEC_DATA, 2},
|
||||
@ -1551,7 +1480,7 @@ static sinfo secdata[NSECS] =
|
||||
{ IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
|
||||
};
|
||||
|
||||
#else
|
||||
#else
|
||||
|
||||
/* Sections numbered to make the order the same as other PowerPC NT */
|
||||
/* compilers. This also keeps funny alignment thingies from happening. */
|
||||
@ -1567,7 +1496,7 @@ static sinfo secdata[NSECS] =
|
||||
|
||||
#define NSECS 9
|
||||
|
||||
static sinfo secdata[NSECS] =
|
||||
static sinfo secdata[NSECS] =
|
||||
{
|
||||
{ TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
|
||||
{ PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
|
||||
@ -1609,7 +1538,7 @@ ID2: .short 2
|
||||
|
||||
For the PowerPC, here's the variation on the above scheme:
|
||||
|
||||
# Rather than a simple "jmp *", the code to get to the dll function
|
||||
# Rather than a simple "jmp *", the code to get to the dll function
|
||||
# looks like:
|
||||
.text
|
||||
lwz r11,[tocv]__imp_function_name(r2)
|
||||
@ -1669,11 +1598,11 @@ make_one_lib_file (exp, i)
|
||||
|
||||
dump_iat (f, exp);
|
||||
|
||||
if(!exp->noname || show_allnames)
|
||||
if(!exp->noname || show_allnames)
|
||||
{
|
||||
fprintf (f, "%s Hint/Name table\n", ASM_C);
|
||||
fprintf (f, "\t.section .idata$6\n");
|
||||
fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
|
||||
fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
|
||||
fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
|
||||
}
|
||||
|
||||
@ -1698,7 +1627,7 @@ make_one_lib_file (exp, i)
|
||||
|
||||
/* Extra Symbols for PPC */
|
||||
#ifdef DLLTOOL_PPC
|
||||
#define EXTRA 2
|
||||
#define EXTRA 2
|
||||
#else
|
||||
#define EXTRA 0
|
||||
#endif
|
||||
@ -1716,7 +1645,7 @@ make_one_lib_file (exp, i)
|
||||
abfd = bfd_openw (outname, HOW_BFD_TARGET);
|
||||
if (!abfd)
|
||||
{
|
||||
fprintf (stderr, _("%s: bfd_open failed open output file %s\n"),
|
||||
fprintf (stderr, _("%s: bfd_open failed open output file %s\n"),
|
||||
program_name, outname);
|
||||
exit (1);
|
||||
}
|
||||
@ -1732,10 +1661,10 @@ make_one_lib_file (exp, i)
|
||||
if (si->id != i)
|
||||
abort();
|
||||
si->sec = bfd_make_section_old_way (abfd, si->name);
|
||||
bfd_set_section_flags (abfd,
|
||||
bfd_set_section_flags (abfd,
|
||||
si->sec,
|
||||
si->flags);
|
||||
|
||||
|
||||
bfd_set_section_alignment(abfd, si->sec, si->align);
|
||||
si->sec->output_section = si->sec;
|
||||
si->sym = bfd_make_empty_symbol(abfd);
|
||||
@ -1842,7 +1771,7 @@ make_one_lib_file (exp, i)
|
||||
arelent *rel;
|
||||
arelent **rpp;
|
||||
|
||||
switch (i)
|
||||
switch (i)
|
||||
{
|
||||
case TEXT:
|
||||
if (! exp->data)
|
||||
@ -1850,7 +1779,7 @@ make_one_lib_file (exp, i)
|
||||
si->size = HOW_JTAB_SIZE;
|
||||
si->data = xmalloc (HOW_JTAB_SIZE);
|
||||
memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
|
||||
|
||||
|
||||
/* add the reloqc into idata$5 */
|
||||
rel = xmalloc (sizeof (arelent));
|
||||
rpp = xmalloc (sizeof (arelent *) * 2);
|
||||
@ -1861,7 +1790,7 @@ make_one_lib_file (exp, i)
|
||||
|
||||
if (machine == MPPC)
|
||||
{
|
||||
rel->howto = bfd_reloc_type_lookup (abfd,
|
||||
rel->howto = bfd_reloc_type_lookup (abfd,
|
||||
BFD_RELOC_16_GOTOFF);
|
||||
rel->sym_ptr_ptr = iname_pp;
|
||||
}
|
||||
@ -1878,7 +1807,7 @@ make_one_lib_file (exp, i)
|
||||
case IDATA5:
|
||||
/* An idata$4 or idata$5 is one word long, and has an
|
||||
rva to idata$6 */
|
||||
|
||||
|
||||
si->data = xmalloc (4);
|
||||
si->size = 4;
|
||||
|
||||
@ -1889,7 +1818,7 @@ make_one_lib_file (exp, i)
|
||||
si->data[2] = exp->ordinal >> 16;
|
||||
si->data[3] = 0x80;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
sec->reloc_count = 1;
|
||||
memset (si->data, 0, si->size);
|
||||
@ -1907,7 +1836,7 @@ make_one_lib_file (exp, i)
|
||||
break;
|
||||
|
||||
case IDATA6:
|
||||
if (!exp->noname)
|
||||
if (!exp->noname)
|
||||
{
|
||||
/* This used to add 1 to exp->hint. I don't know
|
||||
why it did that, and it does not match what I see
|
||||
@ -1953,11 +1882,11 @@ make_one_lib_file (exp, i)
|
||||
a dll routine. There are a number of house keeping things
|
||||
we need to do:
|
||||
|
||||
1. In the name of glue trickery, the ADDR32 relocs for 0,
|
||||
4, and 0x10 are set to point to the same place:
|
||||
"..function_name".
|
||||
2. There is one more reloc needed in the pdata section.
|
||||
The actual glue instruction to restore the toc on
|
||||
1. In the name of glue trickery, the ADDR32 relocs for 0,
|
||||
4, and 0x10 are set to point to the same place:
|
||||
"..function_name".
|
||||
2. There is one more reloc needed in the pdata section.
|
||||
The actual glue instruction to restore the toc on
|
||||
return is saved as the offset in an IMGLUE reloc.
|
||||
So we need a total of four relocs for this section.
|
||||
|
||||
@ -1983,7 +1912,7 @@ make_one_lib_file (exp, i)
|
||||
bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
|
||||
|
||||
imglue->addend = 0;
|
||||
imglue->howto = bfd_reloc_type_lookup (abfd,
|
||||
imglue->howto = bfd_reloc_type_lookup (abfd,
|
||||
BFD_RELOC_32_GOTOFF);
|
||||
imglue->sym_ptr_ptr = fn_pp;
|
||||
|
||||
@ -2072,7 +2001,7 @@ make_one_lib_file (exp, i)
|
||||
if (i == IDATA4 && no_idata4)
|
||||
continue;
|
||||
|
||||
bfd_set_section_contents (abfd, si->sec,
|
||||
bfd_set_section_contents (abfd, si->sec,
|
||||
si->data, 0,
|
||||
si->size);
|
||||
}
|
||||
@ -2115,13 +2044,13 @@ make_head ()
|
||||
|
||||
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%s\t0\n", ASM_LONG);
|
||||
fprintf (f, "fthunk:\n");
|
||||
}
|
||||
if (!no_idata4)
|
||||
if (!no_idata4)
|
||||
{
|
||||
fprintf (f, "\t.section\t.idata$4\n");
|
||||
|
||||
@ -2134,20 +2063,20 @@ make_head ()
|
||||
sprintf (outfile, "-o dh.o dh.s");
|
||||
run (as_name, outfile);
|
||||
|
||||
return bfd_openr ("dh.o", HOW_BFD_TARGET);
|
||||
return bfd_openr ("dh.o", HOW_BFD_TARGET);
|
||||
}
|
||||
|
||||
static bfd *
|
||||
static bfd *
|
||||
make_tail ()
|
||||
{
|
||||
FILE * f = fopen ("dt.s", FOPEN_WT);
|
||||
|
||||
if (!no_idata4)
|
||||
if (!no_idata4)
|
||||
{
|
||||
fprintf (f, "\t.section .idata$4\n");
|
||||
fprintf (f, "\t%s\t0\n", ASM_LONG);
|
||||
}
|
||||
if (!no_idata5)
|
||||
if (!no_idata5)
|
||||
{
|
||||
fprintf (f, "\t.section .idata$5\n");
|
||||
fprintf (f, "\t%s\t0\n", ASM_LONG);
|
||||
@ -2186,7 +2115,7 @@ make_tail ()
|
||||
|
||||
sprintf (outfile, "-o dt.o dt.s");
|
||||
run (as_name, outfile);
|
||||
return bfd_openr ("dt.o", HOW_BFD_TARGET);
|
||||
return bfd_openr ("dt.o", HOW_BFD_TARGET);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2348,7 +2277,7 @@ process_duplicates (d_export_vec)
|
||||
export_type **d_export_vec;
|
||||
{
|
||||
int more = 1;
|
||||
int i;
|
||||
int i;
|
||||
while (more)
|
||||
{
|
||||
|
||||
@ -2472,7 +2401,7 @@ fill_ordinals (d_export_vec)
|
||||
qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
|
||||
|
||||
/* Work out the lowest and highest ordinal numbers. */
|
||||
if (d_nfuncs)
|
||||
if (d_nfuncs)
|
||||
{
|
||||
if (d_export_vec[0])
|
||||
d_low_ord = d_export_vec[0]->ordinal;
|
||||
@ -2532,7 +2461,7 @@ mangle_defs ()
|
||||
qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
|
||||
|
||||
/* Fill exp entries with their hint values */
|
||||
|
||||
|
||||
for (i = 0; i < d_nfuncs; i++)
|
||||
{
|
||||
if (!d_exports_lexically[i]->noname || show_allnames)
|
||||
@ -2604,7 +2533,7 @@ main (ac, av)
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
while ((c = getopt_long (ac, av, "xcz:S:R:A:puaD:l:e:nkvbUh?m:yd:", long_options, 0))
|
||||
while ((c = getopt_long (ac, av, "xcz:S:R:A:puaD:l:e:nkvbUh?m:yd:", long_options, 0))
|
||||
!= EOF)
|
||||
{
|
||||
switch (c)
|
||||
@ -2728,7 +2657,7 @@ main (ac, av)
|
||||
imp_name_lab = xstrdup (imp_name);
|
||||
for (p = imp_name_lab; *p; p++)
|
||||
{
|
||||
if (!isalpha (*p) && !isdigit (*p))
|
||||
if (!isalpha ((unsigned char) *p) && !isdigit ((unsigned char) *p))
|
||||
*p = '_';
|
||||
}
|
||||
head_label = make_label("_head_", imp_name_lab);
|
||||
|
Loading…
Reference in New Issue
Block a user