X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fdlltool.c;h=21045b4e55238caecb97bcdf0e45e1595b28a1c3;hb=12855a36540bd5243595cb36b0841b0675e32368;hp=1a8de3271538853857deb5445220fd41aeab268c;hpb=50c2245bd8d8b406e46e3888df92f2443f76a94f;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/dlltool.c b/binutils/dlltool.c index 1a8de32715..21045b4e55 100644 --- a/binutils/dlltool.c +++ b/binutils/dlltool.c @@ -1,5 +1,5 @@ /* dlltool.c -- tool to generate stuff for PE style DLLs - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -49,7 +49,7 @@ EXPORTS ( ( ( [ = ] ) | ( = . )) - [ @ ] [ NONAME ] [CONSTANT] [DATA] ) * + [ @ ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) * Declares name1 as an exported symbol from the DLL, with optional ordinal number . Or declares name1 as an alias (forward) of the function @@ -261,6 +261,8 @@ #include #endif +#include + #ifdef DLLTOOL_ARM #include "coff/arm.h" #include "coff/internal.h" @@ -382,6 +384,7 @@ extern char * program_name; static int machine; static int killat; static int add_stdcall_alias; +static const char *ext_prefix_alias; static int verbose; static FILE *output_def; static FILE *base_file; @@ -427,7 +430,11 @@ static char * mcore_elf_linker_flags = NULL; #define DRECTVE_SECTION_NAME ".drectve" #endif -#define PATHMAX 250 /* What's the right name for this ? */ +/* What's the right name for this ? */ +#define PATHMAX 250 + +/* External name alias numbering starts here. */ +#define PREFIX_ALIAS_BASE 20000 char *tmp_asm_buf; char *tmp_head_s_buf; @@ -641,9 +648,11 @@ typedef struct export { const char *name; const char *internal_name; + const char *import_name; int ordinal; int constant; - int noname; + int noname; /* Don't put name in image file. */ + int private; /* Don't put reference in import lib. */ int data; int hint; int forward; /* Number of forward label, 0 means no forward. */ @@ -663,7 +672,7 @@ static struct string_list *excludes; static const char *rvaafter (int); static const char *rvabefore (int); -static const char *asm_prefix (int); +static const char *asm_prefix (int, const char *); static void process_def_file (const char *); static void new_directive (char *); static void append_import (const char *, const char *, int); @@ -794,7 +803,7 @@ rvabefore (int machine) } static const char * -asm_prefix (int machine) +asm_prefix (int machine, const char *name) { switch (machine) { @@ -809,7 +818,11 @@ asm_prefix (int machine) case MARM_EPOC: break; case M386: - return "_"; + /* Symbol names starting with ? do not have a leading underscore. */ + if (name && *name == '?') + break; + else + return "_"; default: /* xgettext:c-format */ fatal (_("Internal error: Unknown machine type: %d"), machine); @@ -818,26 +831,26 @@ asm_prefix (int machine) return ""; } -#define ASM_BYTE mtable[machine].how_byte -#define ASM_SHORT mtable[machine].how_short -#define ASM_LONG mtable[machine].how_long -#define ASM_TEXT mtable[machine].how_asciz -#define ASM_C mtable[machine].how_comment -#define ASM_JUMP mtable[machine].how_jump -#define ASM_GLOBAL mtable[machine].how_global -#define ASM_SPACE mtable[machine].how_space -#define ASM_ALIGN_SHORT mtable[machine].how_align_short -#define ASM_RVA_BEFORE rvabefore(machine) -#define ASM_RVA_AFTER rvaafter(machine) -#define ASM_PREFIX asm_prefix(machine) -#define ASM_ALIGN_LONG mtable[machine].how_align_long -#define HOW_BFD_READ_TARGET 0 /* always default*/ -#define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target -#define HOW_BFD_ARCH mtable[machine].how_bfd_arch -#define HOW_JTAB mtable[machine].how_jtab -#define HOW_JTAB_SIZE mtable[machine].how_jtab_size -#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff -#define ASM_SWITCHES mtable[machine].how_default_as_switches +#define ASM_BYTE mtable[machine].how_byte +#define ASM_SHORT mtable[machine].how_short +#define ASM_LONG mtable[machine].how_long +#define ASM_TEXT mtable[machine].how_asciz +#define ASM_C mtable[machine].how_comment +#define ASM_JUMP mtable[machine].how_jump +#define ASM_GLOBAL mtable[machine].how_global +#define ASM_SPACE mtable[machine].how_space +#define ASM_ALIGN_SHORT mtable[machine].how_align_short +#define ASM_RVA_BEFORE rvabefore (machine) +#define ASM_RVA_AFTER rvaafter (machine) +#define ASM_PREFIX(NAME) asm_prefix (machine, (NAME)) +#define ASM_ALIGN_LONG mtable[machine].how_align_long +#define HOW_BFD_READ_TARGET 0 /* Always default. */ +#define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target +#define HOW_BFD_ARCH mtable[machine].how_bfd_arch +#define HOW_JTAB mtable[machine].how_jtab +#define HOW_JTAB_SIZE mtable[machine].how_jtab_size +#define HOW_JTAB_ROFF mtable[machine].how_jtab_roff +#define ASM_SWITCHES mtable[machine].how_default_as_switches static char **oav; @@ -889,15 +902,17 @@ yyerror (const char * err ATTRIBUTE_UNUSED) void def_exports (const char *name, const char *internal_name, int ordinal, - int noname, int constant, int data) + int noname, int constant, int data, int private) { struct export *p = (struct export *) xmalloc (sizeof (*p)); p->name = name; p->internal_name = internal_name ? internal_name : name; + p->import_name = name; p->ordinal = ordinal; p->constant = constant; p->noname = noname; + p->private = private; p->data = data; p->next = d_exports; d_exports = p; @@ -1204,7 +1219,7 @@ scan_drectve_symbols (bfd *abfd) if (s == NULL) return; - size = bfd_get_section_size_before_reloc (s); + size = bfd_get_section_size (s); buf = xmalloc (size); bfd_get_section_contents (abfd, s, buf, 0, size); @@ -1246,7 +1261,7 @@ scan_drectve_symbols (bfd *abfd) /* FIXME: The 5th arg is for the `constant' field. What should it be? Not that it matters since it's not currently useful. */ - def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION)); + def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0); if (add_stdcall_alias && strchr (c, '@')) { @@ -1255,7 +1270,7 @@ scan_drectve_symbols (bfd *abfd) char *atsym = strchr (exported_name, '@'); *atsym = '\0'; /* Note: stdcall alias symbols can never be data. */ - def_exports (exported_name, xstrdup (c), -1, 0, 0, 0); + def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0); } } else @@ -1294,7 +1309,7 @@ scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount, ++symbol_name; def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, - ! (sym->flags & BSF_FUNCTION)); + ! (sym->flags & BSF_FUNCTION), 0); if (add_stdcall_alias && strchr (symbol_name, '@')) { @@ -1303,7 +1318,7 @@ scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount, char *atsym = strchr (exported_name, '@'); *atsym = '\0'; /* Note: stdcall alias symbols can never be data. */ - def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0); + def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0); } } } @@ -1518,13 +1533,14 @@ dump_def_info (FILE *f) fprintf (f, "\n"); for (i = 0, exp = d_exports; exp; i++, exp = exp->next) { - fprintf (f, "%s %d = %s %s @ %d %s%s%s\n", + fprintf (f, "%s %d = %s %s @ %d %s%s%s%s\n", ASM_C, i, exp->name, exp->internal_name, exp->ordinal, exp->noname ? "NONAME " : "", + exp->private ? "PRIVATE " : "", exp->constant ? "CONSTANT" : "", exp->data ? "DATA" : ""); } @@ -1595,20 +1611,20 @@ gen_def_file (void) if (strcmp (exp->name, exp->internal_name) == 0) { - - fprintf (output_def, "\t%s%s%s @ %d%s%s\n", + fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n", quote, exp->name, quote, exp->ordinal, exp->noname ? " NONAME" : "", + exp->private ? "PRIVATE " : "", exp->data ? " DATA" : ""); } else { - char *quote1 = strchr (exp->internal_name, '.') ? "\"" : ""; + char * quote1 = strchr (exp->internal_name, '.') ? "\"" : ""; /* char *alias = */ - fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s\n", + fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n", quote, exp->name, quote, @@ -1617,6 +1633,7 @@ gen_def_file (void) quote1, exp->ordinal, exp->noname ? " NONAME" : "", + exp->private ? "PRIVATE " : "", exp->data ? " DATA" : ""); } } @@ -1812,7 +1829,7 @@ gen_exp_file (void) exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal); else fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE, - ASM_PREFIX, + ASM_PREFIX (exp->internal_name), exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal); } else @@ -1841,14 +1858,14 @@ gen_exp_file (void) fprintf(f,"%s Export Name Table\n", ASM_C); for (i = 0; (exp = d_exports_lexically[i]); i++) - if (!exp->noname || show_allnames) - { + { + if (!exp->noname || show_allnames) fprintf (f, "n%d: %s \"%s\"\n", exp->ordinal, ASM_TEXT, xlate (exp->name)); - if (exp->forward != 0) - fprintf (f, "f%d: %s \"%s\"\n", - exp->forward, ASM_TEXT, exp->internal_name); - } + if (exp->forward != 0) + fprintf (f, "f%d: %s \"%s\"\n", + exp->forward, ASM_TEXT, exp->internal_name); + } if (a_list) { @@ -2146,10 +2163,10 @@ ID2: .short 2 static char * make_label (const char *prefix, const char *name) { - int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name); - char *copy = xmalloc (len +1 ); + int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name); + char *copy = xmalloc (len + 1); - strcpy (copy, ASM_PREFIX); + strcpy (copy, ASM_PREFIX (name)); strcat (copy, prefix); strcat (copy, name); return copy; @@ -2170,10 +2187,10 @@ make_imp_label (const char *prefix, const char *name) } else { - len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name); + len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name); copy = xmalloc (len + 1); strcpy (copy, prefix); - strcat (copy, ASM_PREFIX); + strcat (copy, ASM_PREFIX (name)); strcat (copy, name); } return copy; @@ -2193,12 +2210,12 @@ make_one_lib_file (export_type *exp, int i) sprintf (name, "%ss%05d.s", prefix, i); f = fopen (name, FOPEN_WT); fprintf (f, "\t.text\n"); - fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name); + fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX (exp->name), exp->name); if (create_compat_implib) fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name); fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name); if (create_compat_implib) - fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX, + fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX (exp->name), exp->name, ASM_JUMP, exp->name); fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C); @@ -2252,7 +2269,6 @@ make_one_lib_file (export_type *exp, int i) #endif asymbol * ptrs[NSECS + 4 + EXTRA + 1]; flagword applicable; - char * outname = xmalloc (strlen (TMP_STUB) + 10); int oidx = 0; @@ -2282,6 +2298,7 @@ make_one_lib_file (export_type *exp, int i) for (i = 0; i < NSECS; i++) { sinfo *si = secdata + i; + if (si->id != i) abort(); si->sec = bfd_make_section_old_way (abfd, si->name); @@ -2348,10 +2365,10 @@ make_one_lib_file (export_type *exp, int i) iname2->flags = BSF_GLOBAL; iname2->value = 0; - iname_lab = bfd_make_empty_symbol(abfd); + iname_lab = bfd_make_empty_symbol (abfd); iname_lab->name = head_label; - iname_lab->section = (asection *)&bfd_und_section; + iname_lab->section = (asection *) &bfd_und_section; iname_lab->flags = 0; iname_lab->value = 0; @@ -2475,16 +2492,16 @@ make_one_lib_file (export_type *exp, int i) why it did that, and it does not match what I see in programs compiled with the MS tools. */ int idx = exp->hint; - si->size = strlen (xlate (exp->name)) + 3; + si->size = strlen (xlate (exp->import_name)) + 3; si->data = xmalloc (si->size); si->data[0] = idx & 0xff; si->data[1] = idx >> 8; - strcpy (si->data + 2, xlate (exp->name)); + strcpy (si->data + 2, xlate (exp->import_name)); } break; case IDATA7: si->size = 4; - si->data =xmalloc (4); + si->data = xmalloc (4); memset (si->data, 0, si->size); rel = xmalloc (sizeof (arelent)); rpp = xmalloc (sizeof (arelent *) * 2); @@ -2794,9 +2811,33 @@ gen_lib_file (void) for (i = 0; (exp = d_exports_lexically[i]); i++) { - bfd *n = make_one_lib_file (exp, i); + bfd *n; + /* Don't add PRIVATE entries to import lib. */ + if (exp->private) + continue; + n = make_one_lib_file (exp, i); n->next = head; head = n; + if (ext_prefix_alias) + { + export_type alias_exp; + + assert (i < PREFIX_ALIAS_BASE); + alias_exp.name = make_imp_label (ext_prefix_alias, exp->name); + alias_exp.internal_name = exp->internal_name; + alias_exp.import_name = exp->name; + alias_exp.ordinal = exp->ordinal; + alias_exp.constant = exp->constant; + alias_exp.noname = exp->noname; + alias_exp.private = exp->private; + alias_exp.data = exp->data; + alias_exp.hint = exp->hint; + alias_exp.forward = exp->forward; + alias_exp.next = exp->next; + n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE); + n->next = head; + head = n; + } } /* Now stick them all into the archive. */ @@ -2831,22 +2872,31 @@ gen_lib_file (void) char *name; name = (char *) alloca (strlen (TMP_STUB) + 10); - for (i = 0, exp = d_exports; exp; i++, exp = exp->next) + for (i = 0; (exp = d_exports_lexically[i]); i++) { + /* Don't delete non-existent stubs for PRIVATE entries. */ + if (exp->private) + continue; sprintf (name, "%s%05d.o", TMP_STUB, i); if (unlink (name) < 0) /* xgettext:c-format */ non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); + if (ext_prefix_alias) + { + sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE); + if (unlink (name) < 0) + /* xgettext:c-format */ + non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); + } } } inform (_("Created lib file")); } -/**********************************************************************/ - /* Run through the information gathered from the .o files and the .def file and work out the best stuff. */ + static int pfunc (const void *a, const void *b) { @@ -2890,11 +2940,7 @@ remove_null_names (export_type **ptr) } static void -dtab (export_type **ptr -#ifndef SACDEBUG -ATTRIBUTE_UNUSED -#endif - ) +dtab (export_type **ptr ATTRIBUTE_UNUSED) { #ifdef SACDEBUG int i; @@ -2922,7 +2968,6 @@ process_duplicates (export_type **d_export_vec) while (more) { - more = 0; /* Remove duplicates. */ qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc); @@ -2933,7 +2978,6 @@ process_duplicates (export_type **d_export_vec) if (strcmp (d_export_vec[i]->name, d_export_vec[i + 1]->name) == 0) { - export_type *a = d_export_vec[i]; export_type *b = d_export_vec[i + 1]; @@ -2963,13 +3007,10 @@ process_duplicates (export_type **d_export_vec) } } - /* Count the names. */ for (i = 0; i < d_nfuncs; i++) - { - if (!d_export_vec[i]->noname) - d_named_nfuncs++; - } + if (!d_export_vec[i]->noname) + d_named_nfuncs++; } static void @@ -3008,7 +3049,7 @@ fill_ordinals (export_type **d_export_vec) { if (d_export_vec[i]->ordinal == -1) { - register int j; + int j; /* First try within or after any user supplied range. */ for (j = lowest; j < size; j++) @@ -3063,8 +3104,7 @@ mangle_defs (void) int i; int hint = 0; - export_type **d_export_vec - = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs); + export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs); inform (_("Processing definitions")); @@ -3101,8 +3141,6 @@ mangle_defs (void) inform (_("Processed definitions")); } -/**********************************************************************/ - static void usage (FILE *file, int status) { @@ -3127,10 +3165,12 @@ usage (FILE *file, int status) fprintf (file, _(" -U --add-underscore Add underscores to symbols in interface library.\n")); fprintf (file, _(" -k --kill-at Kill @ from exported names.\n")); fprintf (file, _(" -A --add-stdcall-alias Add aliases without @.\n")); + fprintf (file, _(" -p --ext-prefix-alias Add aliases with .\n")); fprintf (file, _(" -S --as Use for assembler.\n")); fprintf (file, _(" -f --as-flags Pass to the assembler.\n")); fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n")); fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n")); + fprintf (file, _(" -t --temp-prefix Use to construct temp file names.\n")); fprintf (file, _(" -v --verbose Be verbose.\n")); fprintf (file, _(" -V --version Display the program version.\n")); fprintf (file, _(" -h --help Display this information.\n")); @@ -3165,6 +3205,7 @@ static const struct option long_options[] = {"add-underscore", no_argument, NULL, 'U'}, {"kill-at", no_argument, NULL, 'k'}, {"add-stdcall-alias", no_argument, NULL, 'A'}, + {"ext-prefix-alias", required_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'V'}, {"help", no_argument, NULL, 'h'}, @@ -3201,9 +3242,9 @@ main (int ac, char **av) while ((c = getopt_long (ac, av, #ifdef DLLTOOL_MCORE_ELF - "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVHhM:L:F:", + "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHhM:L:F:", #else - "m:e:l:aD:d:z:b:xcCuUkAS:f:nvVHh", + "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHh", #endif long_options, 0)) != EOF) @@ -3238,7 +3279,7 @@ main (int ac, char **av) as_flags = optarg; break; - /* ignored for compatibility */ + /* Ignored for compatibility. */ case 'u': break; case 'a': @@ -3278,6 +3319,9 @@ main (int ac, char **av) case 'A': add_stdcall_alias = 1; break; + case 'p': + ext_prefix_alias = optarg; + break; case 'd': def_file = optarg; break;