clean up IMPORTS changes

This commit is contained in:
Ian Lance Taylor 1998-04-29 00:04:11 +00:00
parent 47cbef8df8
commit c027e8b019
2 changed files with 280 additions and 346 deletions

View File

@ -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>

View File

@ -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);