* emultempl/pe.em (gld_i386_finish): generate import library
* deffile.h: add hint member. * pe-dll.c (pe_dll_generate_implib): New function with helpers; generates the import library directly from the export table. (fill_edata): remember the actual hint for the import library.
This commit is contained in:
parent
67c72211ac
commit
d3ca9a538c
3 changed files with 497 additions and 7 deletions
|
@ -1,3 +1,11 @@
|
|||
Mon Nov 16 22:14:07 1998 DJ Delorie <dj@cygnus.com>
|
||||
|
||||
* emultempl/pe.em (gld_i386_finish): generate import library
|
||||
* deffile.h: add hint member.
|
||||
* pe-dll.c (pe_dll_generate_implib): New function with helpers;
|
||||
generates the import library directly from the export table.
|
||||
(fill_edata): remember the actual hint for the import library.
|
||||
|
||||
Sat Nov 14 14:36:24 1998 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* ld.1: Some cleanups from NOKUBI Hirotaka <hnokubi@yyy.or.jp>.
|
||||
|
|
|
@ -70,6 +70,7 @@ int pe_dll_do_default_excludes = 1;
|
|||
int pe_dll_kill_ats = 0;
|
||||
int pe_dll_stdcall_aliases = 0;
|
||||
int pe_enable_stdcall_fixup = -1; /* 0=disable 1=enable */
|
||||
static char *pe_implib_filename = 0;
|
||||
|
||||
extern const char *output_filename;
|
||||
|
||||
|
@ -108,6 +109,7 @@ gld_${EMULATION_NAME}_before_parse()
|
|||
#define OPTION_STDCALL_ALIASES (OPTION_KILL_ATS + 1)
|
||||
#define OPTION_ENABLE_STDCALL_FIXUP (OPTION_STDCALL_ALIASES + 1)
|
||||
#define OPTION_DISABLE_STDCALL_FIXUP (OPTION_ENABLE_STDCALL_FIXUP + 1)
|
||||
#define OPTION_IMPLIB_FILENAME (OPTION_DISABLE_STDCALL_FIXUP + 1)
|
||||
|
||||
static struct option longopts[] =
|
||||
{
|
||||
|
@ -127,6 +129,7 @@ static struct option longopts[] =
|
|||
{"stack", required_argument, NULL, OPTION_STACK},
|
||||
{"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
|
||||
{"support-old-code", no_argument, NULL, OPTION_SUPPORT_OLD_CODE},
|
||||
#ifdef TARGET_IS_i386pe
|
||||
/* getopt allows abbreviations, so we do this to stop it from treating -o
|
||||
as an abbreviation for this option */
|
||||
{"output-def", required_argument, NULL, OPTION_OUT_DEF},
|
||||
|
@ -137,6 +140,8 @@ static struct option longopts[] =
|
|||
{"add-stdcall-alias", no_argument, NULL, OPTION_STDCALL_ALIASES},
|
||||
{"enable-stdcall-fixup", no_argument, NULL, OPTION_ENABLE_STDCALL_FIXUP},
|
||||
{"disable-stdcall-fixup", no_argument, NULL, OPTION_DISABLE_STDCALL_FIXUP},
|
||||
{"out-implib", required_argument, NULL, OPTION_IMPLIB_FILENAME},
|
||||
#endif
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -198,13 +203,16 @@ gld_${EMULATION_NAME}_list_options (file)
|
|||
fprintf (file, _(" --stack <size> Set size of the initial stack\n"));
|
||||
fprintf (file, _(" --subsystem <name>[:<version>] Set required OS subsystem [& version]\n"));
|
||||
fprintf (file, _(" --support-old-code Support interworking with old code\n"));
|
||||
fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n"));
|
||||
fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n"));
|
||||
fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"));
|
||||
fprintf (file, _(" --kill-at Remove @nn from exported symbols\n"));
|
||||
#ifdef TARGET_IS_i386pe
|
||||
fprintf (file, _(" --add-stdcall-alias Export symbols with and without @nn\n"));
|
||||
fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"));
|
||||
fprintf (file, _(" --disable-stdcall-fixup Don't link _sym to _sym@nn\n"));
|
||||
fprintf (file, _(" --enable-stdcall-fixup Link _sym to _sym@nn without warnings\n"));
|
||||
fprintf (file, _(" --exclude-symbols sym,sym,... Exclude symbols from automatic export\n"));
|
||||
fprintf (file, _(" --export-all-symbols Automatically export all globals to DLL\n"));
|
||||
fprintf (file, _(" --kill-at Remove @nn from exported symbols\n"));
|
||||
fprintf (file, _(" --out-implib <file> Generate import library\n"));
|
||||
fprintf (file, _(" --output-def <file> Generate a .DEF file for the built DLL\n"));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -424,6 +432,9 @@ gld_${EMULATION_NAME}_parse_args(argc, argv)
|
|||
case OPTION_DISABLE_STDCALL_FIXUP:
|
||||
pe_enable_stdcall_fixup = 0;
|
||||
break;
|
||||
case OPTION_IMPLIB_FILENAME:
|
||||
pe_implib_filename = xstrdup (optarg);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -773,7 +784,11 @@ gld_${EMULATION_NAME}_finish ()
|
|||
{
|
||||
#ifdef TARGET_IS_i386pe
|
||||
if (link_info.shared)
|
||||
pe_dll_fill_sections (output_bfd, &link_info);
|
||||
{
|
||||
pe_dll_fill_sections (output_bfd, &link_info);
|
||||
if (pe_implib_filename)
|
||||
pe_dll_generate_implib (pe_def_file, pe_implib_filename);
|
||||
}
|
||||
if (pe_out_def_filename)
|
||||
pe_dll_generate_def_file (pe_out_def_filename);
|
||||
#endif
|
||||
|
|
469
ld/pe-dll.c
469
ld/pe-dll.c
|
@ -515,7 +515,7 @@ fill_edata (abfd, info)
|
|||
bfd *abfd;
|
||||
struct bfd_link_info *info;
|
||||
{
|
||||
int i;
|
||||
int i, hint;
|
||||
unsigned char *edirectory;
|
||||
unsigned long *eaddresses;
|
||||
unsigned long *enameptrs;
|
||||
|
@ -550,6 +550,7 @@ fill_edata (abfd, info)
|
|||
bfd_put_32 (abfd, ERVA (eordinals), edata_d + 36);
|
||||
|
||||
/* Ok, now for the filling in part */
|
||||
hint = 0;
|
||||
for (i = 0; i < export_table_size; i++)
|
||||
{
|
||||
int s = exported_symbols[i];
|
||||
|
@ -569,6 +570,7 @@ fill_edata (abfd, info)
|
|||
enamestr += strlen (enamestr) + 1;
|
||||
bfd_put_16 (abfd, i, (void *) eordinals);
|
||||
enameptrs++;
|
||||
pe_def_file->exports[s].hint = hint++;
|
||||
}
|
||||
eordinals++;
|
||||
}
|
||||
|
@ -894,6 +896,471 @@ pe_dll_generate_def_file (pe_out_def_filename)
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
||||
Generate the import library
|
||||
|
||||
************************************************************************/
|
||||
|
||||
static asymbol **symtab;
|
||||
static int symptr;
|
||||
static int tmp_seq;
|
||||
static const char *dll_filename;
|
||||
static char *dll_symname;
|
||||
|
||||
static asection *
|
||||
quick_section(abfd, name, flags, align)
|
||||
bfd *abfd;
|
||||
const char *name;
|
||||
int flags;
|
||||
int align;
|
||||
{
|
||||
asection *sec;
|
||||
asymbol *sym;
|
||||
|
||||
sec = bfd_make_section_old_way(abfd, name);
|
||||
sec->output_section = sec;
|
||||
bfd_set_section_flags (abfd, sec, flags);
|
||||
bfd_set_section_alignment (abfd, sec, align);
|
||||
|
||||
sym = bfd_make_empty_symbol(abfd);
|
||||
symtab[symptr++] = sym;
|
||||
sym->name = sec->name;
|
||||
sym->section = sec;
|
||||
sym->flags = BSF_LOCAL;
|
||||
sym->value = 0;
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
static void
|
||||
quick_symbol (abfd, n1, n2, n3, sec, flags, addr)
|
||||
bfd *abfd;
|
||||
char *n1;
|
||||
char *n2;
|
||||
char *n3;
|
||||
asection *sec;
|
||||
int flags;
|
||||
int addr;
|
||||
{
|
||||
asymbol *sym = bfd_make_empty_symbol(abfd);
|
||||
char *name = (char *) xmalloc (strlen(n1) + strlen(n2) + strlen(n3) + 1);
|
||||
strcpy (name, n1);
|
||||
strcat (name, n2);
|
||||
strcat (name, n3);
|
||||
sym->name = name;
|
||||
sym->section = sec;
|
||||
sym->flags = flags;
|
||||
sym->value = addr;
|
||||
symtab[symptr++] = sym;
|
||||
}
|
||||
|
||||
static arelent **reltab = 0;
|
||||
static int relcount = 0, relsize = 0;
|
||||
|
||||
static void
|
||||
quick_reloc (abfd, address, which_howto, symidx)
|
||||
bfd *abfd;
|
||||
int address;
|
||||
int which_howto;
|
||||
int symidx;
|
||||
{
|
||||
if (relcount >= (relsize-1))
|
||||
{
|
||||
relsize += 10;
|
||||
if (reltab)
|
||||
reltab = (arelent **) xrealloc (reltab, relsize * sizeof (arelent *));
|
||||
else
|
||||
reltab = (arelent **) xmalloc (relsize * sizeof (arelent *));
|
||||
}
|
||||
reltab[relcount] = (arelent *) xmalloc (sizeof (arelent));
|
||||
reltab[relcount]->address = address;
|
||||
reltab[relcount]->addend = 0;
|
||||
reltab[relcount]->howto = bfd_reloc_type_lookup (abfd, which_howto);
|
||||
reltab[relcount]->sym_ptr_ptr = symtab + symidx;
|
||||
relcount++;
|
||||
}
|
||||
|
||||
static void
|
||||
save_relocs (asection *sec)
|
||||
{
|
||||
reltab[relcount] = 0;
|
||||
sec->orelocation = reltab;
|
||||
sec->reloc_count = relcount;
|
||||
reltab = 0;
|
||||
relcount = relsize = 0;
|
||||
}
|
||||
|
||||
#define UNDSEC (asection *) &bfd_und_section
|
||||
|
||||
/*
|
||||
* .section .idata$2
|
||||
* .global __head_my_dll
|
||||
* __head_my_dll:
|
||||
* .rva hname
|
||||
* .long 0
|
||||
* .long 0
|
||||
* .rva __my_dll_iname
|
||||
* .rva fthunk
|
||||
*
|
||||
* .section .idata$5
|
||||
* .long 0
|
||||
* fthunk:
|
||||
*
|
||||
* .section .idata$4
|
||||
* .long 0
|
||||
* hname:
|
||||
*/
|
||||
|
||||
#define BFD_OPEN_OLDWAY 0
|
||||
|
||||
bfd *
|
||||
make_head (parent)
|
||||
bfd *parent;
|
||||
{
|
||||
asection *id2, *id5, *id4;
|
||||
unsigned char *d2, *d5, *d4;
|
||||
|
||||
#if BFD_OPEN_OLDWAY
|
||||
bfd *abfd = bfd_openw ("dh.o", 0);
|
||||
#else
|
||||
bfd *abfd = bfd_create ("dh.o", parent);
|
||||
bfd_make_writable (abfd);
|
||||
#endif
|
||||
bfd_set_format (abfd, bfd_object);
|
||||
bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
|
||||
|
||||
symptr = 0;
|
||||
symtab = (asymbol **) xmalloc (6 * sizeof (asymbol *));
|
||||
id2 = quick_section(abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
|
||||
id5 = quick_section(abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
||||
id4 = quick_section(abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
||||
quick_symbol (abfd, "__head_", dll_symname, "", id2, BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "_", dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
|
||||
|
||||
bfd_set_section_size(abfd, id2, 20);
|
||||
d2 = (unsigned char *) xmalloc (20);
|
||||
memset (d2, 0, 20);
|
||||
d2[0] = d2[16] = 4; /* reloc addend */
|
||||
quick_reloc(abfd, 0, BFD_RELOC_RVA, 2);
|
||||
quick_reloc(abfd, 12, BFD_RELOC_RVA, 4);
|
||||
quick_reloc(abfd, 16, BFD_RELOC_RVA, 1);
|
||||
save_relocs(id2);
|
||||
|
||||
bfd_set_section_size (abfd, id5, 4);
|
||||
d5 = (unsigned char *) xmalloc (4);
|
||||
memset (d5, 0, 4);
|
||||
|
||||
bfd_set_section_size (abfd, id4, 4);
|
||||
d4 = (unsigned char *) xmalloc (4);
|
||||
memset (d4, 0, 4);
|
||||
|
||||
bfd_set_symtab(abfd, symtab, symptr);
|
||||
|
||||
bfd_set_section_contents(abfd, id2, d2, 0, 20);
|
||||
bfd_set_section_contents(abfd, id5, d5, 0, 4);
|
||||
bfd_set_section_contents(abfd, id4, d4, 0, 4);
|
||||
|
||||
#if BFD_OPEN_OLDWAY
|
||||
bfd_close (abfd);
|
||||
return bfd_openr("dh.o", 0);
|
||||
#else
|
||||
bfd_make_readable (abfd);
|
||||
return abfd;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* .section .idata$4
|
||||
* .long 0
|
||||
* .section .idata$5
|
||||
* .long 0
|
||||
* .section idata$7
|
||||
* .global __my_dll_iname
|
||||
*__my_dll_iname:
|
||||
* .asciz "my.dll"
|
||||
*/
|
||||
|
||||
bfd *
|
||||
make_tail (parent)
|
||||
bfd *parent;
|
||||
{
|
||||
asection *id4, *id5, *id7;
|
||||
unsigned char *d4, *d5, *d7;
|
||||
int len;
|
||||
|
||||
#if BFD_OPEN_OLDWAY
|
||||
bfd *abfd = bfd_openw ("dt.o", 0);
|
||||
#else
|
||||
bfd *abfd = bfd_create ("dt.o", parent);
|
||||
bfd_make_writable (abfd);
|
||||
#endif
|
||||
bfd_set_format (abfd, bfd_object);
|
||||
bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
|
||||
|
||||
symptr = 0;
|
||||
symtab = (asymbol **) xmalloc (5 * sizeof (asymbol *));
|
||||
id4 = quick_section(abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
||||
id5 = quick_section(abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
||||
id7 = quick_section(abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
|
||||
quick_symbol (abfd, "_", dll_symname, "_iname", id7, BSF_GLOBAL, 0);
|
||||
|
||||
bfd_set_section_size(abfd, id4, 4);
|
||||
d4 = (unsigned char *) xmalloc (4);
|
||||
memset (d4, 0, 4);
|
||||
|
||||
bfd_set_section_size (abfd, id5, 4);
|
||||
d5 = (unsigned char *) xmalloc (4);
|
||||
memset (d5, 0, 4);
|
||||
|
||||
len = strlen(dll_filename)+1;
|
||||
if (len & 1)
|
||||
len ++;
|
||||
bfd_set_section_size (abfd, id7, len);
|
||||
d7 = (unsigned char *) xmalloc (len);
|
||||
strcpy (d7, dll_filename);
|
||||
|
||||
bfd_set_symtab(abfd, symtab, symptr);
|
||||
|
||||
bfd_set_section_contents(abfd, id4, d4, 0, 4);
|
||||
bfd_set_section_contents(abfd, id5, d5, 0, 4);
|
||||
bfd_set_section_contents(abfd, id7, d7, 0, len);
|
||||
|
||||
#if BFD_OPEN_OLDWAY
|
||||
bfd_close (abfd);
|
||||
return bfd_openr ("dt.o", 0);
|
||||
#else
|
||||
bfd_make_readable (abfd);
|
||||
return abfd;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* .text
|
||||
* .global _function
|
||||
* .global ___imp_function
|
||||
* .global __imp__function
|
||||
*_function:
|
||||
* jmp *__imp__function:
|
||||
*
|
||||
* .section idata$7
|
||||
* .long __head_my_dll
|
||||
*
|
||||
* .section .idata$5
|
||||
*___imp_function:
|
||||
*__imp__function:
|
||||
*iat?
|
||||
* .section .idata$4
|
||||
*iat?
|
||||
* .section .idata$6
|
||||
*ID<ordinal>:
|
||||
* .short <hint>
|
||||
* .asciz "function" xlate? (add underscore, kill at)
|
||||
*/
|
||||
|
||||
unsigned char jmp_ix86_bytes[] = {
|
||||
0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90
|
||||
};
|
||||
|
||||
|
||||
bfd *
|
||||
make_one (exp, parent)
|
||||
def_file_export *exp;
|
||||
bfd *parent;
|
||||
{
|
||||
asection *tx, *id7, *id5, *id4, *id6;
|
||||
unsigned char *td, *d7, *d5, *d4, *d6;
|
||||
int len;
|
||||
char *oname;
|
||||
bfd *abfd;
|
||||
|
||||
oname = (char *) xmalloc (20);
|
||||
sprintf(oname, "ds%d.o", tmp_seq);
|
||||
tmp_seq++;
|
||||
#if BFD_OPEN_OLDWAY
|
||||
abfd = bfd_openw (oname, 0);
|
||||
#else
|
||||
abfd = bfd_create (oname, parent);
|
||||
bfd_make_writable (abfd);
|
||||
#endif
|
||||
bfd_set_format (abfd, bfd_object);
|
||||
bfd_set_arch_mach (abfd, bfd_arch_i386, 0);
|
||||
|
||||
symptr = 0;
|
||||
symtab = (asymbol **) xmalloc (10 * sizeof (asymbol *));
|
||||
tx = quick_section(abfd, ".text", SEC_CODE|SEC_HAS_CONTENTS, 2);
|
||||
id7 = quick_section(abfd, ".idata$7", SEC_HAS_CONTENTS, 2);
|
||||
id5 = quick_section(abfd, ".idata$5", SEC_HAS_CONTENTS, 2);
|
||||
id4 = quick_section(abfd, ".idata$4", SEC_HAS_CONTENTS, 2);
|
||||
id6 = quick_section(abfd, ".idata$6", SEC_HAS_CONTENTS, 2);
|
||||
quick_symbol (abfd, "_", exp->name, "", tx, BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "__head_", dll_symname, "", UNDSEC, BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "___imp_", exp->name, "", id5, BSF_GLOBAL, 0);
|
||||
quick_symbol (abfd, "__imp__", exp->name, "", id5, BSF_GLOBAL, 0);
|
||||
|
||||
bfd_set_section_size (abfd, tx, 8);
|
||||
td = (unsigned char *) xmalloc (8);
|
||||
memcpy (td, jmp_ix86_bytes, 8);
|
||||
quick_reloc (abfd, 2, BFD_RELOC_32, 2);
|
||||
save_relocs (tx);
|
||||
|
||||
bfd_set_section_size(abfd, id7, 4);
|
||||
d7 = (unsigned char *) xmalloc (4);
|
||||
memset (d7, 0, 4);
|
||||
quick_reloc (abfd, 0, BFD_RELOC_RVA, 6);
|
||||
save_relocs (id7);
|
||||
|
||||
bfd_set_section_size (abfd, id5, 4);
|
||||
d5 = (unsigned char *) xmalloc (4);
|
||||
memset (d5, 0, 4);
|
||||
if (exp->flag_noname)
|
||||
{
|
||||
d5[0] = exp->ordinal;
|
||||
d5[1] = exp->ordinal >> 8;
|
||||
d5[3] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
|
||||
save_relocs (id5);
|
||||
}
|
||||
|
||||
bfd_set_section_size (abfd, id4, 4);
|
||||
d4 = (unsigned char *) xmalloc (4);
|
||||
memset (d4, 0, 4);
|
||||
if (exp->flag_noname)
|
||||
{
|
||||
d5[0] = exp->ordinal;
|
||||
d5[1] = exp->ordinal >> 8;
|
||||
d5[3] = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
quick_reloc (abfd, 0, BFD_RELOC_RVA, 4);
|
||||
save_relocs (id4);
|
||||
}
|
||||
|
||||
if (exp->flag_noname)
|
||||
{
|
||||
len = 0;
|
||||
bfd_set_section_size(abfd, id6, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = strlen(exp->name) + 3;
|
||||
if (len & 1)
|
||||
len++;
|
||||
bfd_set_section_size(abfd, id6, len);
|
||||
d6 = (unsigned char *) xmalloc (len);
|
||||
memset (d6, 0, len);
|
||||
d6[0] = exp->hint & 0xff;
|
||||
d6[1] = exp->hint >> 8;
|
||||
strcpy(d6+2, exp->name);
|
||||
}
|
||||
|
||||
bfd_set_symtab(abfd, symtab, symptr);
|
||||
|
||||
bfd_set_section_contents(abfd, tx, td, 0, 8);
|
||||
bfd_set_section_contents(abfd, id7, d7, 0, 4);
|
||||
bfd_set_section_contents(abfd, id5, d5, 0, 4);
|
||||
bfd_set_section_contents(abfd, id4, d4, 0, 4);
|
||||
bfd_set_section_contents(abfd, id6, d6, 0, len);
|
||||
|
||||
#if BFD_OPEN_OLDWAY
|
||||
bfd_close(abfd);
|
||||
return bfd_openr(oname, 0);
|
||||
#else
|
||||
bfd_make_readable (abfd);
|
||||
return abfd;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
pe_dll_generate_implib (def, impfilename)
|
||||
def_file *def;
|
||||
char *impfilename;
|
||||
{
|
||||
int i;
|
||||
/*export_type *exp;*/
|
||||
bfd *ar_head;
|
||||
bfd *ar_tail;
|
||||
bfd *outarch;
|
||||
bfd * head = 0;
|
||||
|
||||
dll_filename = def->name;
|
||||
if (dll_filename == 0)
|
||||
{
|
||||
dll_filename = dll_name;
|
||||
for (i=0; impfilename[i]; i++)
|
||||
if (impfilename[i] == '/' || impfilename[i] == '\\')
|
||||
dll_filename = impfilename+1;
|
||||
}
|
||||
dll_symname = xstrdup (dll_filename);
|
||||
for (i=0; dll_symname[i]; i++)
|
||||
if (!isalnum (dll_symname[i]))
|
||||
dll_symname[i] = '_';
|
||||
|
||||
unlink (impfilename);
|
||||
|
||||
outarch = bfd_openw (impfilename, 0);
|
||||
|
||||
if (!outarch)
|
||||
{
|
||||
/* xgettext:c-format */
|
||||
einfo (_("%XCan't open .lib file: %s\n"), impfilename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* xgettext:c-format */
|
||||
einfo (_("Creating library file: %s\n"), impfilename);
|
||||
|
||||
bfd_set_format (outarch, bfd_archive);
|
||||
outarch->has_armap = 1;
|
||||
|
||||
/* Work out a reasonable size of things to put onto one line. */
|
||||
|
||||
ar_head = make_head (outarch);
|
||||
ar_tail = make_tail (outarch);
|
||||
|
||||
if (ar_head == NULL || ar_tail == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i<def->num_exports; i++)
|
||||
{
|
||||
bfd *n = make_one (def->exports+i, outarch);
|
||||
n->next = head;
|
||||
head = n;
|
||||
}
|
||||
|
||||
/* Now stick them all into the archive */
|
||||
|
||||
ar_head->next = head;
|
||||
ar_tail->next = ar_head;
|
||||
head = ar_tail;
|
||||
|
||||
if (! bfd_set_archive_head (outarch, head))
|
||||
einfo ("%Xbfd_set_archive_head: %s\n", bfd_errmsg (bfd_get_error ()));
|
||||
|
||||
if (! bfd_close (outarch))
|
||||
einfo ("%Xbfd_close %s: %s\n", impfilename, bfd_errmsg (bfd_get_error ()));
|
||||
|
||||
while (head != NULL)
|
||||
{
|
||||
bfd *n = head->next;
|
||||
bfd_close (head);
|
||||
head = n;
|
||||
}
|
||||
|
||||
unlink ("dh.o");
|
||||
unlink ("dt.o");
|
||||
for (i=0; i<tmp_seq; i++)
|
||||
{
|
||||
char buf[20];
|
||||
sprintf (buf, "ds%d.o", i);
|
||||
unlink (buf);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
||||
These are the main functions, called from the emulation. The first
|
||||
|
|
Loading…
Reference in a new issue