1 #define show_allnames 0
3 /* dlltool.c -- tool to generate stuff for PE style DLLs
4 Copyright (C) 1995 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 This program allows you to build the files necessary to create
25 DLLs to run on a system which understands PE format image files.
28 A DLL contains an export table which contains the information
29 which the runtime loader needs to tie up references from a
32 The export table is generated by this program by reading
33 in a .DEF file or scanning the .a and .o files which will be in the
34 DLL. A .o file can contain information in special ".drectve" sections
35 with export information.
37 A DEF file contains any number of the following commands:
40 NAME <name> [ , <base> ]
41 The result is going to be <name>.EXE
43 LIBRARY <name> [ , <base> ]
44 The result is going to be <name>.DLL
46 EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] ) *
47 Declares name1 as an exported symbol from the
48 DLL, with optional ordinal number <integer>
50 IMPORTS ( [ <name> = ] <name> . <name> ) *
51 Ignored for compatibility
54 Puts <string> into output .exp file in the .rdata section
56 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ]
57 Generates --stack|--heap <number-reserve>,<number-commit>
58 in the output .drectve section. The linker will
59 see this and act upon it.
62 SECTIONS ( <sectionname> <attr>+ )*
63 <attr> = READ | WRITE | EXECUTE | SHARED
64 Generates --attr <sectionname> <attr> in the output
65 .drectve section. The linker will see this and act
69 A -export:<name> in a .drectve section in an input .o or .a
70 file to this program is equivalent to a EXPORTS <name>
75 The program generates output files with the prefix supplied
76 on the command line, or in the def file, or taken from the first
79 The .exp.s file contains the information necessary to export
80 the routines in the DLL. The .lib.s file contains the information
81 necessary to use the DLL's routines from a referencing program.
88 asm (".section .drectve");
89 asm (".ascii \"-export:adef\"");
93 printf("hello from the dll %s\n",s);
98 printf("hello from the dll and the other entry point %s\n",s);
102 asm (".section .drectve");
103 asm (".ascii \"-export:cdef\"");
104 asm (".ascii \"-export:ddef\"");
107 printf("hello from the dll %s\n",s);
112 printf("hello from the dll and the other entry point %s\n",s);
130 HEAPSIZE 0x40000, 0x2000
134 SECTIONS donkey READ WRITE
138 # compile up the parts of the dll
143 # put them in a library (you don't have to, you
144 # could name all the .os on the dlltool line)
146 ar qcv thedll.in file1.o file2.o
149 # run this tool over the library and the def file
150 ./dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a
152 # build the dll with the library with file1.o, file2.o and the export table
153 ld -o thedll.dll thedll.o thedll.in
158 # link the executable with the import library
159 ld -e main -Tthemain.ld -o themain.exe themain.o thedll.a
163 #define PAGE_SIZE 4096
164 #define PAGE_MASK (-PAGE_SIZE)
166 #include "libiberty.h"
169 #include "demangle.h"
171 #ifdef HAVE_SYS_WAIT_H
172 #include <sys/wait.h>
175 #define WIFEXITED(w) (((w)&0377) == 0)
178 #define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)
181 #define WTERMSIG(w) ((w) & 0177)
184 #define WEXITSTATUS(w) (((w) >> 8) & 0377)
190 char *as_name = "as";
192 static int no_idata4;
193 static int no_idata5;
194 static char *exp_name;
195 static char *imp_name;
196 static char *head_label;
197 static char *imp_name_lab;
198 static char *dll_name;
200 static int add_indirect = 0;
201 static int add_underscore = 0;
202 static int dontdeltemps = 0;
206 static char *def_file;
208 static char *program_name;
219 static char *mname = "arm";
223 static char *mname = "i386";
227 static char *mname = "ppc";
230 #define PATHMAX 250 /* What's the right name for this ? */
232 /* This bit of assemly does jmp * ....
233 s set how_jtab_roff to mark where the 32bit abs branch should go */
234 unsigned char i386_jtab[] = { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90};
237 unsigned char arm_jtab[] = { 0x00, 0xc0, 0x9f, 0xe5,
238 0x00, 0xf0, 0x9c, 0xe5,
241 /* This is the glue sequence for PowerPC PE. There is a */
242 /* tocrel16-tocdefn reloc against the first instruction. */
243 /* We also need a IMGLUE reloc against the glue function */
244 /* to restore the toc saved by the third instruction in */
246 unsigned char ppc_jtab[] =
248 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */
249 /* Reloc TOCREL16 __imp_xxx */
250 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */
251 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */
252 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */
253 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */
254 0x20, 0x04, 0x80, 0x4E /* bctr */
257 /* the glue instruction, picks up the toc from the stw in */
258 /* the above code: "lwz r2,4(r1)" */
259 bfd_vma ppc_glue_insn = 0x80410004;
262 char outfile[PATHMAX];
274 char *how_align_short;
275 char *how_align_long;
276 char *how_bfd_target;
277 enum bfd_architecture how_bfd_arch;
278 unsigned char *how_jtab;
279 int how_jtab_size; /* size of the jtab entry */
280 int how_jtab_roff; /* offset into it for the ind 32 reloc into idata 5 */
287 "arm", ".byte", ".short", ".long", ".asciz", "@",
288 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long",
289 ".global", ".space", ".align\t2",".align\t4","pe-arm-little", bfd_arch_arm,
290 arm_jtab, sizeof(arm_jtab),8
295 "i386", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-i386",bfd_arch_i386,
296 i386_jtab,sizeof(i386_jtab),2,
301 "ppc", ".byte", ".short", ".long", ".asciz", "#", "jmp *", ".global", ".space", ".align\t2",".align\t4","pe-powerpcle",bfd_arch_powerpc,
302 ppc_jtab,sizeof(ppc_jtab),0,
356 #define ASM_BYTE mtable[machine].how_byte
357 #define ASM_SHORT mtable[machine].how_short
358 #define ASM_LONG mtable[machine].how_long
359 #define ASM_TEXT mtable[machine].how_asciz
360 #define ASM_C mtable[machine].how_comment
361 #define ASM_JUMP mtable[machine].how_jump
362 #define ASM_GLOBAL mtable[machine].how_global
363 #define ASM_SPACE mtable[machine].how_space
364 #define ASM_ALIGN_SHORT mtable[machine].how_align_short
365 #define ASM_RVA_BEFORE rvabefore(machine)
366 #define ASM_RVA_AFTER rvaafter(machine)
367 #define ASM_PREFIX asm_prefix(machine)
368 #define ASM_ALIGN_LONG mtable[machine].how_align_long
369 #define HOW_BFD_TARGET 0 /* always default*/
370 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch
371 #define HOW_JTAB mtable[machine].how_jtab
372 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size
373 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff
377 FILE *yyin; /* communications with flex */
378 extern int linenumber;
380 process_def_file (name)
383 FILE *f = fopen (name, FOPEN_RT);
386 fprintf (stderr, "%s: Can't open def file %s\n", program_name, name);
395 /**********************************************************************/
397 /* Communications with the parser */
407 typedef struct export
419 static char *d_name; /* Arg to NAME or LIBRARY */
420 static int d_nfuncs; /* Number of functions exported */
421 static int d_named_nfuncs; /* Number of named functions exported */
422 static int d_low_ord; /* Lowest ordinal index */
423 static int d_high_ord; /* Highest ordinal index */
424 static export_type *d_exports; /*list of exported functions */
425 static export_type **d_exports_lexically; /* vector of exported functions in alpha order */
426 static dlist_type *d_list; /* Descriptions */
427 static dlist_type *a_list; /* Stuff to go in directives */
435 fprintf (stderr, "%s: Syntax error in def file %s:%d\n",
436 program_name, def_file, linenumber);
441 def_exports (name, internal_name, ordinal, noname, constant)
448 struct export *p = (struct export *) xmalloc (sizeof (*p));
451 p->internal_name = internal_name ? internal_name : name;
452 p->ordinal = ordinal;
453 p->constant = constant;
462 def_name (name, base)
467 fprintf (stderr, "%s NAME %s base %x\n", program_name, name, base);
470 fprintf (stderr, "Can't have LIBRARY and NAME\n");
477 def_library (name, base)
482 printf ("%s: LIBRARY %s base %x\n", program_name, name, base);
485 fprintf (stderr, "%s: Can't have LIBRARY and NAME\n", program_name);
492 def_description (desc)
495 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
496 d->text = strdup (desc);
505 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type));
506 d->text = strdup (dir);
512 def_stacksize (reserve, commit)
518 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit);
520 sprintf (b, "-stack 0x%x ", reserve);
521 new_directive (strdup (b));
525 def_heapsize (reserve, commit)
531 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit);
533 sprintf (b, "-heap 0x%x ", reserve);
534 new_directive (strdup (b));
539 def_import (internal, module, entry)
545 fprintf (stderr, "%s: IMPORTS are ignored", program_name);
549 def_version (major, minor)
553 printf ("VERSION %d.%d\n", major, minor);
558 def_section (name, attr)
575 sprintf (buf, "-attr %s %s", name, atts);
576 new_directive (strdup (buf));
583 def_section ("CODE", attr);
590 def_section ("DATA", attr);
594 /**********************************************************************/
605 extern char **environ;
607 fprintf (stderr, "%s %s\n", what, args);
611 for (s = args; *s; s++)
615 argv = alloca (sizeof (char *) * (i + 3));
622 while (*s != ' ' && *s != 0)
636 fprintf (stderr, "%s: can't exec %s\n", program_name, what);
642 fprintf (stderr, "%s: vfork failed, %d\n", program_name, errno);
648 waitpid (pid, &status, 0);
651 if (WIFSIGNALED (status))
653 fprintf (stderr, "%s: %s %s terminated with signal %d\n",
654 program_name, what, args, WTERMSIG (status));
658 if (WIFEXITED (status))
660 fprintf (stderr, "%s: %s %s terminated with exit status %d\n",
661 program_name, what, args, WEXITSTATUS (status));
668 /* read in and block out the base relocations */
680 scan_open_obj_file (abfd)
683 /* Look for .drectve's */
684 asection *s = bfd_get_section_by_name (abfd, ".drectve");
687 int size = bfd_get_section_size_before_reloc (s);
688 char *buf = xmalloc (size);
691 bfd_get_section_contents (abfd, s, buf, 0, size);
693 fprintf (stderr, "%s: Sucking in info from %s\n",
695 bfd_get_filename (abfd));
697 /* Search for -export: strings */
703 && strncmp (p, "-export:", 8) == 0)
709 while (*p != ' ' && *p != '-' && p < e)
711 c = xmalloc (p - name + 1);
712 memcpy (c, name, p - name);
714 def_exports (c, 0, -1, 0);
725 fprintf (stderr, "%s: Done readin\n",
732 scan_obj_file (filename)
735 bfd *f = bfd_openr (filename, 0);
739 fprintf (stderr, "%s: Unable to open object file %s\n",
744 if (bfd_check_format (f, bfd_archive))
746 bfd *arfile = bfd_openr_next_archived_file (f, 0);
749 if (bfd_check_format (arfile, bfd_object))
750 scan_open_obj_file (arfile);
752 arfile = bfd_openr_next_archived_file (f, arfile);
755 else if (bfd_check_format (f, bfd_object))
757 scan_open_obj_file (f);
763 /**********************************************************************/
773 fprintf (f, "%s ", ASM_C);
774 for (i = 0; oav[i]; i++)
775 fprintf (f, "%s ", oav[i]);
777 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
779 fprintf (f, "%s %d = %s %s @ %d %s%s\n",
785 exp->noname ? "NONAME " : "",
786 exp->constant ? "CONSTANT" : "");
789 /* Generate the .exp file */
802 flush_page (f, need, page_addr, on_page)
810 /* Flush this page */
811 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n",
815 fprintf (f, "\t%s\t0x%x\t%s Size of block\n",
817 (on_page * 2) + (on_page & 1) * 2 + 8,
819 for (i = 0; i < on_page; i++)
821 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, (need[i] - page_addr) | 0x3000);
825 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000);
836 fprintf (output_def, ";");
837 for (i = 0; oav[i]; i++)
838 fprintf (output_def, " %s", oav[i]);
840 fprintf (output_def, "\nEXPORTS\n");
842 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
844 char *quote = strchr (exp->name, '.') ? "\"" : "";
845 fprintf (output_def, "\t%s%s%s @ %d%s ; %s\n",
850 exp->noname ? " NONAME" : "",
851 cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS));
863 sprintf (outfile, "t%s", exp_name);
866 fprintf (stderr, "%s: Generate exp file %s\n",
867 program_name, exp_name);
869 f = fopen (outfile, FOPEN_WT);
872 fprintf (stderr, "%s: Unable to open output file %s\n", program_name, outfile);
877 fprintf (stderr, "%s: Opened file %s\n",
878 program_name, outfile);
884 fprintf (f, "\t.section .edata\n\n");
885 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C);
886 fprintf (f, "\t%s 0x%x %s Time and date\n", ASM_LONG, time(0),ASM_C);
887 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C);
888 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
889 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C);
892 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C);
893 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n",
895 d_named_nfuncs, d_low_ord, d_high_ord);
896 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG,
897 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C);
898 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
900 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n",
901 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
903 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
905 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name);
908 fprintf(f,"%s Export address Table\n", ASM_C);
909 fprintf(f,"\t%s\n", ASM_ALIGN_LONG);
910 fprintf (f, "afuncs:\n");
913 for (exp = d_exports; exp; exp = exp->next)
915 if (exp->ordinal != i)
918 fprintf (f, "\t%s\t%d\t%s %d..%d missing\n",
920 (exp->ordinal - i) * 4,
922 i, exp->ordinal - 1);
925 while (i < exp->ordinal)
927 fprintf(f,"\t%s\t0\n", ASM_LONG);
931 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE,
933 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal);
937 fprintf (f,"%s Export Name Pointer Table\n", ASM_C);
938 fprintf (f, "anames:\n");
940 for (i = 0; (exp = d_exports_lexically[i]); i++)
942 if (!exp->noname || show_allnames)
943 fprintf (f, "\t%sn%d%s\n", ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER);
946 fprintf (f,"%s Export Oridinal Table\n", ASM_C);
947 fprintf (f, "anords:\n");
948 for (i = 0; (exp = d_exports_lexically[i]); i++)
950 if (!exp->noname || show_allnames)
951 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord);
954 fprintf(f,"%s Export Name Table\n", ASM_C);
955 for (i = 0; (exp = d_exports_lexically[i]); i++)
956 if (!exp->noname || show_allnames)
957 fprintf (f, "n%d: %s \"%s\"\n", exp->ordinal, ASM_TEXT, exp->name);
961 fprintf (f, "\t.section .drectve\n");
962 for (dl = a_list; dl; dl = dl->next)
964 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text);
969 fprintf (f, "\t.section .rdata\n");
970 for (dl = d_list; dl; dl = dl->next)
974 /* We dont output as ascii 'cause there can
975 be quote characters in the string */
978 for (p = dl->text; *p; p++)
981 fprintf (f, "\t%s\t", ASM_BYTE);
984 fprintf (f, "%d", *p);
1001 /* Add to the output file a way of getting to the exported names
1002 without using the import library. */
1005 fprintf (f, "\t.section\t.rdata\n");
1006 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1007 if (!exp->noname || show_allnames)
1009 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1010 fprintf (f, "__imp_%s:\n", exp->name);
1011 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name);
1015 /* Dump the reloc section if a base file is provided */
1019 long need[PAGE_SIZE];
1026 fprintf (f, "\t.section\t.init\n");
1027 fprintf (f, "lab:\n");
1029 fseek (base_file, 0, SEEK_END);
1030 numbytes = ftell (base_file);
1031 fseek (base_file, 0, SEEK_SET);
1032 copy = malloc (numbytes);
1033 fread (copy, 1, numbytes, base_file);
1034 num_entries = numbytes / sizeof (long);
1037 fprintf (f, "\t.section\t.reloc\n");
1044 qsort (copy, num_entries, sizeof (long), sfunc);
1045 /* Delete duplcates */
1046 for (src = 0; src < num_entries; src++)
1048 if (last != copy[src])
1049 last = copy[dst++] = copy[src];
1053 page_addr = addr & PAGE_MASK; /* work out the page addr */
1055 for (j = 0; j < num_entries; j++)
1058 if ((addr & PAGE_MASK) != page_addr)
1060 flush_page (f, need, page_addr, on_page);
1062 page_addr = addr & PAGE_MASK;
1064 need[on_page++] = addr;
1066 flush_page (f, need, page_addr, on_page);
1068 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/
1074 /* assemble the file */
1075 sprintf (outfile, "-o %s t%s", exp_name, exp_name);
1076 run (as_name, outfile);
1077 if (dontdeltemps == 0)
1079 sprintf (outfile, "t%s", exp_name);
1089 char *copy = malloc (strlen (name) + 2);
1091 strcpy (copy + 1, name);
1098 p = strchr (name, '@');
1105 /**********************************************************************/
1107 static void dump_iat (f, exp)
1111 if (exp->noname && !show_allnames )
1113 fprintf (f, "\t%s\t0x%08x\n",
1115 exp->ordinal | 0x80000000); /* hint or orindal ?? */
1119 fprintf (f, "\t%sID%d%s\n", ASM_RVA_BEFORE,
1137 unsigned char *data;
1156 static sinfo secdata[NSECS] =
1158 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1159 { DATA, ".data", SEC_DATA, 2},
1160 { BSS, ".bss", 0, 2},
1161 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1162 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1163 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1164 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}
1169 /* Sections numbered to make the order the same as other PowerPC NT */
1170 /* compilers. This also keeps funny alignment thingies from happening. */
1183 static sinfo secdata[NSECS] =
1185 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3},
1186 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2},
1187 { RDATA, ".rdata", SEC_HAS_CONTENTS, 2},
1188 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2},
1189 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2},
1190 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1},
1191 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2},
1192 { DATA, ".data", SEC_DATA, 2},
1193 { BSS, ".bss", 0, 2}
1199 This is what we're trying to make
1202 .global _GetFileVersionInfoSizeW@8
1203 .global __imp_GetFileVersionInfoSizeW@8
1204 _GetFileVersionInfoSizeW@8:
1205 jmp * __imp_GetFileVersionInfoSizeW@8
1206 .section .idata$7 # To force loading of head
1207 .long __version_a_head
1208 # Import Address Table
1210 __imp_GetFileVersionInfoSizeW@8:
1213 # Import Lookup Table
1219 .asciz "GetFileVersionInfoSizeW"
1222 For the PowerPC, here's the variation on the above scheme:
1224 # Rather than a simple "jmp *", the code to get to the dll function
1227 lwz r11,[tocv]__imp_function_name(r2)
1228 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name
1237 make_label (prefix, name)
1241 int len = strlen (ASM_PREFIX) + strlen (prefix) + strlen (name);
1242 char *copy = xmalloc (len +1 );
1243 strcpy (copy, ASM_PREFIX);
1244 strcat (copy, prefix);
1245 strcat (copy, name);
1250 make_one_lib_file (exp, i)
1258 sprintf (outfile, "%ss%d.s", prefix, i);
1259 f = fopen (outfile, FOPEN_WT);
1260 fprintf (f, "\t.text\n");
1261 fprintf (f, "\t%s\t%s%s\n", ASM_GLOBAL, ASM_PREFIX, exp->name);
1262 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name);
1263 fprintf (f, "%s%s:\n\t%s\t__imp_%s\n", ASM_PREFIX,
1264 exp->name, ASM_JUMP, exp->name);
1266 fprintf (f, "\t.section\t.idata$7\t%s To force loading of head\n", ASM_C);
1267 fprintf (f, "\t%s\t%s\n", ASM_LONG, head_label);
1270 fprintf (f,"%s Import Address Table\n", ASM_C);
1272 fprintf (f, "\t.section .idata$5\n");
1273 fprintf (f, "__imp_%s:\n", exp->name);
1277 fprintf (f, "\n%s Import Lookup Table\n", ASM_C);
1278 fprintf (f, "\t.section .idata$4\n");
1282 if(!exp->noname || show_allnames)
1284 fprintf (f, "%s Hint/Name table\n", ASM_C);
1285 fprintf (f, "\t.section .idata$6\n");
1286 fprintf (f, "ID%d:\t%s\t%d\n", exp->ordinal, ASM_SHORT, exp->hint);
1287 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, xlate (exp->name));
1293 sprintf (outfile, "-o %ss%d.o %ss%d.s", prefix, i, prefix, i);
1295 run (as_name, outfile);
1306 asymbol **iname_lab_pp;
1309 /* Extra Symbols for PPC */
1316 asymbol *function_name; /* ".." functionName */
1318 asymbol *toc_symbol; /* The .toc symbol */
1321 /* one symbol for each section, 2 extra + a null */
1322 asymbol *ptrs[NSECS+3+EXTRA+1];
1324 char *outname = xmalloc (10);
1326 sprintf (outname, "ds%d.o", i);
1327 abfd = bfd_openw (outname, HOW_BFD_TARGET);
1330 fprintf (stderr, "%s: bfd_open failed open output file %s\n",
1331 program_name, outname);
1335 bfd_set_format (abfd, bfd_object);
1336 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0);
1339 /* First make symbols for the sections */
1340 for (i = 0; i < NSECS; i++)
1342 sinfo *si = secdata + i;
1345 si->sec = bfd_make_section_old_way (abfd, si->name);
1346 bfd_set_section_flags (abfd,
1350 bfd_set_section_alignment(abfd, si->sec, si->align);
1351 si->sec->output_section = si->sec;
1352 si->sym = bfd_make_empty_symbol(abfd);
1353 si->sym->name = si->sec->name;
1354 si->sym->section = si->sec;
1355 si->sym->flags = BSF_LOCAL;
1357 ptrs[oidx] = si->sym;
1358 si->sympp = ptrs + oidx;
1363 exp_label = bfd_make_empty_symbol(abfd);
1364 exp_label->name = make_label ("",exp->name);
1366 /* On PowerPC, the function name points to a descriptor in the
1367 rdata section, the first element of which is a pointer to the
1368 code (..function_name), and the second points to the .toc
1370 if (machine == MPPC)
1371 exp_label->section = secdata[RDATA].sec;
1373 exp_label->section = secdata[TEXT].sec;
1375 exp_label->flags = BSF_GLOBAL;
1376 exp_label->value = 0;
1378 ptrs[oidx++] = exp_label;
1380 iname = bfd_make_empty_symbol(abfd);
1381 iname->name = make_label ("__imp_", exp->name);
1382 iname->section = secdata[IDATA5].sec;
1383 iname->flags = BSF_GLOBAL;
1387 iname_lab = bfd_make_empty_symbol(abfd);
1389 iname_lab->name = head_label;
1390 iname_lab->section = (asection *)&bfd_und_section;
1391 iname_lab->flags = 0;
1392 iname_lab->value = 0;
1395 iname_pp = ptrs + oidx;
1396 ptrs[oidx++] = iname;
1398 iname_lab_pp = ptrs + oidx;
1399 ptrs[oidx++] = iname_lab;
1402 /* The symbol refering to the code (.text) */
1403 function_name = bfd_make_empty_symbol(abfd);
1404 function_name->name = make_label ("..", exp->name);
1405 function_name->section = secdata[TEXT].sec;
1406 function_name->flags = BSF_GLOBAL;
1407 function_name->value = 0;
1409 fn_pp = ptrs + oidx;
1410 ptrs[oidx++] = function_name;
1412 /* The .toc symbol */
1413 toc_symbol = bfd_make_empty_symbol(abfd);
1414 toc_symbol->name = make_label (".", "toc");
1415 toc_symbol->section = (asection *)&bfd_und_section;
1416 toc_symbol->flags = BSF_GLOBAL;
1417 toc_symbol->value = 0;
1419 toc_pp = ptrs + oidx;
1420 ptrs[oidx++] = toc_symbol;
1425 for (i = 0; i < NSECS; i++)
1427 sinfo *si = secdata + i;
1428 asection *sec = si->sec;
1435 si->size = HOW_JTAB_SIZE;
1436 si->data = xmalloc (HOW_JTAB_SIZE);
1437 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE);
1439 /* add the reloc into idata$5 */
1440 rel = xmalloc (sizeof (arelent));
1441 rpp = xmalloc (sizeof (arelent *) * 2);
1444 rel->address = HOW_JTAB_ROFF;
1447 if (machine == MPPC)
1449 rel->howto = bfd_reloc_type_lookup (abfd,
1450 BFD_RELOC_16_GOTOFF);
1451 rel->sym_ptr_ptr = iname_pp;
1455 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1456 rel->sym_ptr_ptr = secdata[IDATA5].sympp;
1458 sec->orelocation = rpp;
1459 sec->reloc_count = 1;
1463 /* An idata$4 or idata$5 is one word long, and has an
1466 si->data = xmalloc (4);
1471 si->data[0] = exp->ordinal ;
1472 si->data[1] = exp->ordinal >> 8;
1473 si->data[2] = exp->ordinal >> 16;
1478 sec->reloc_count = 1;
1479 memset (si->data, 0, si->size);
1480 rel = xmalloc (sizeof (arelent));
1481 rpp = xmalloc (sizeof (arelent *) * 2);
1486 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA);
1487 rel->sym_ptr_ptr = secdata[IDATA6].sympp;
1488 sec->orelocation = rpp;
1496 int idx = exp->hint + 1;
1497 si->size = strlen (xlate (exp->name)) + 3;
1498 si->data = xmalloc (si->size);
1499 si->data[0] = idx & 0xff;
1500 si->data[1] = idx >> 8;
1501 strcpy (si->data + 2, xlate (exp->name));
1506 si->data =xmalloc(4);
1507 memset (si->data, 0, si->size);
1508 rel = xmalloc (sizeof (arelent));
1509 rpp = xmalloc (sizeof (arelent *) * 2);
1513 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1514 rel->sym_ptr_ptr = iname_lab_pp;
1515 sec->orelocation = rpp;
1516 sec->reloc_count = 1;
1521 /* The .pdata section is 5 words long. */
1522 /* Think of it as: */
1525 /* bfd_vma BeginAddress, [0x00] */
1526 /* EndAddress, [0x04] */
1527 /* ExceptionHandler, [0x08] */
1528 /* HandlerData, [0x0c] */
1529 /* PrologEndAddress; [0x10] */
1532 /* So this pdata section setups up this as a glue linkage to
1533 a dll routine. There are a number of house keeping things
1536 1. In the name of glue trickery, the ADDR32 relocs for 0,
1537 4, and 0x10 are set to point to the same place:
1539 2. There is one more reloc needed in the pdata section.
1540 The actual glue instruction to restore the toc on
1541 return is saved as the offset in an IMGLUE reloc.
1542 So we need a total of four relocs for this section.
1544 3. Lastly, the HandlerData field is set to 0x03, to indicate
1545 that this is a glue routine.
1547 arelent *imglue, *ba_rel, *ea_rel, *pea_rel;
1549 /* alignment must be set to 2**2 or you get extra stuff */
1550 bfd_set_section_alignment(abfd, sec, 2);
1553 si->data =xmalloc(4 * 5);
1554 memset (si->data, 0, si->size);
1555 rpp = xmalloc (sizeof (arelent *) * 5);
1556 rpp[0] = imglue = xmalloc (sizeof (arelent));
1557 rpp[1] = ba_rel = xmalloc (sizeof (arelent));
1558 rpp[2] = ea_rel = xmalloc (sizeof (arelent));
1559 rpp[3] = pea_rel = xmalloc (sizeof (arelent));
1562 /* stick the toc reload instruction in the glue reloc */
1563 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address);
1566 imglue->howto = bfd_reloc_type_lookup (abfd,
1567 BFD_RELOC_32_GOTOFF);
1568 imglue->sym_ptr_ptr = fn_pp;
1570 ba_rel->address = 0;
1572 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1573 ba_rel->sym_ptr_ptr = fn_pp;
1575 bfd_put_32(abfd, 0x18, si->data + 0x04);
1576 ea_rel->address = 4;
1578 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1579 ea_rel->sym_ptr_ptr = fn_pp;
1581 /* mark it as glue */
1582 bfd_put_32(abfd, 0x03, si->data + 0x0c);
1584 /* mark the prolog end address */
1585 bfd_put_32(abfd, 0x0D, si->data + 0x10);
1586 pea_rel->address = 0x10;
1587 pea_rel->addend = 0;
1588 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1589 pea_rel->sym_ptr_ptr = fn_pp;
1591 sec->orelocation = rpp;
1592 sec->reloc_count = 4;
1596 /* Each external function in a PowerPC PE file has a two word
1597 descriptor consisting of:
1598 1. The address of the code.
1599 2. The address of the appropriate .toc
1600 We use relocs to build this.
1604 si->data =xmalloc(8);
1605 memset (si->data, 0, si->size);
1607 rpp = xmalloc (sizeof (arelent *) * 3);
1608 rpp[0] = rel = xmalloc (sizeof (arelent));
1609 rpp[1] = xmalloc (sizeof (arelent));
1614 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1615 rel->sym_ptr_ptr = fn_pp;
1621 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32);
1622 rel->sym_ptr_ptr = toc_pp;
1624 sec->orelocation = rpp;
1625 sec->reloc_count = 2;
1632 /* Size up all the sections */
1633 for (i = 0; i < NSECS; i++)
1635 sinfo *si = secdata + i;
1637 bfd_set_section_size (abfd, si->sec, si->size);
1638 bfd_set_section_vma (abfd, si->sec, vma);
1640 /* vma += si->size;*/
1643 /* Write them out */
1644 for (i = 0; i < NSECS; i++)
1646 sinfo *si = secdata + i;
1648 if (i == IDATA5 && no_idata5)
1651 if (i == IDATA4 && no_idata4)
1654 bfd_set_section_contents (abfd, si->sec,
1659 bfd_set_symtab (abfd, ptrs, oidx);
1661 abfd = bfd_openr (outname, HOW_BFD_TARGET);
1671 FILE * f = fopen ("dh.s", FOPEN_WT);
1673 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C);
1674 fprintf (f, "\t.section .idata$2\n");
1676 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label);
1678 fprintf (f, "%s:\n", head_label);
1680 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n",
1681 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C);
1683 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C);
1684 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C);
1685 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C);
1686 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C);
1687 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n",
1692 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n",
1694 ASM_RVA_AFTER, ASM_C);
1696 fprintf (f, "%sStuff for compatibility\n", ASM_C);
1700 fprintf (f, "\t.section\t.idata$5\n");
1701 fprintf (f, "\t%s\t0\n", ASM_LONG);
1702 fprintf (f, "fthunk:\n");
1706 fprintf (f, "\t.section\t.idata$4\n");
1708 fprintf (f, "\t%s\t0\n", ASM_LONG);
1709 fprintf (f, "\t.section .idata$4\n");
1710 fprintf (f, "hname:\n");
1714 sprintf (outfile, "-o dh.o dh.s");
1715 run (as_name, outfile);
1717 return bfd_openr ("dh.o", HOW_BFD_TARGET);
1723 FILE * f = fopen ("dt.s", FOPEN_WT);
1726 /* Other PowerPC NT compilers use idata$6 for the dllname, so I
1727 do too. Original, huh? */
1728 fprintf (f, "\t.section .idata$6\n");
1730 fprintf (f, "\t.section .idata$7\n");
1733 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab);
1734 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n",
1735 imp_name_lab, ASM_TEXT, dll_name);
1739 fprintf (f, "\t.section .idata$4\n");
1740 fprintf (f, "\t%s\t0\n", ASM_LONG);
1744 fprintf (f, "\t.section .idata$5\n");
1745 fprintf (f, "\t%s\t0\n", ASM_LONG);
1750 /* Normally, we need to see a null descriptor built in idata$3 to
1751 act as the terminator for the list. The ideal way, I suppose,
1752 would be to mark this section as a comdat type 2 section, so
1753 only one would appear in the final .exe (if our linker supported
1754 comdat, that is) or cause it to be inserted by something else (say
1758 fprintf (f, "\t.section .idata$3\n");
1759 fprintf (f, "\t%s\t0\n", ASM_LONG);
1760 fprintf (f, "\t%s\t0\n", ASM_LONG);
1761 fprintf (f, "\t%s\t0\n", ASM_LONG);
1762 fprintf (f, "\t%s\t0\n", ASM_LONG);
1763 fprintf (f, "\t%s\t0\n", ASM_LONG);
1768 sprintf (outfile, "-o dt.o dt.s");
1769 run (as_name, outfile);
1770 return bfd_openr ("dt.o", HOW_BFD_TARGET);
1785 outarch = bfd_openw (imp_name, HOW_BFD_TARGET);
1789 fprintf (stderr, "%s: Can't open .lib file %s\n", program_name, imp_name);
1792 bfd_set_format (outarch, bfd_archive);
1793 outarch->has_armap = 1;
1795 /* Work out a reasonable size of things to put onto one line. */
1799 ar_head = make_head ();
1800 ar_tail = make_tail();
1802 for (i = 0; (exp = d_exports_lexically[i]); i++)
1804 bfd *n = make_one_lib_file (exp, i);
1810 /* Now stick them all into the archive */
1812 ar_head->next = head;
1813 ar_tail->next = ar_head;
1816 bfd_set_archive_head (outarch, head);
1817 bfd_close (outarch);
1819 /* Delete all the temp files */
1821 if (dontdeltemps == 0)
1823 sprintf (outfile, "dh.o");
1825 sprintf (outfile, "dh.s");
1827 sprintf (outfile, "dt.o");
1829 sprintf (outfile, "dt.s");
1833 if (dontdeltemps < 2)
1834 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
1836 sprintf (outfile, "ds%d.o",i);
1841 /**********************************************************************/
1843 /* Run through the information gathered from the .o files and the
1844 .def file and work out the best stuff */
1850 export_type *ap = *(export_type **) a;
1851 export_type *bp = *(export_type **) b;
1852 if (ap->ordinal == bp->ordinal)
1855 /* unset ordinals go to the bottom */
1856 if (ap->ordinal == -1)
1858 if (bp->ordinal == -1)
1860 return (ap->ordinal - bp->ordinal);
1869 export_type *ap = *(export_type **) a;
1870 export_type *bp = *(export_type **) b;
1872 return (strcmp (ap->name, bp->name));
1877 remove_null_names (ptr)
1882 for (dst = src = 0; src < d_nfuncs; src++)
1886 ptr[dst] = ptr[src];
1899 for (i = 0; i < d_nfuncs; i++)
1903 printf ("%d %s @ %d %s%s\n",
1904 i, ptr[i]->name, ptr[i]->ordinal,
1905 ptr[i]->noname ? "NONAME " : "",
1906 ptr[i]->constant ? "CONSTANT" : "");
1915 process_duplicates (d_export_vec)
1916 export_type **d_export_vec;
1924 /* Remove duplicates */
1925 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc);
1927 dtab (d_export_vec);
1928 for (i = 0; i < d_nfuncs - 1; i++)
1930 if (strcmp (d_export_vec[i]->name,
1931 d_export_vec[i + 1]->name) == 0)
1934 export_type *a = d_export_vec[i];
1935 export_type *b = d_export_vec[i + 1];
1939 fprintf (stderr, "Warning, ignoring duplicate EXPORT %s %d,%d\n",
1943 if (a->ordinal != -1
1944 && b->ordinal != -1)
1947 fprintf (stderr, "Error, duplicate EXPORT with oridinals %s\n",
1951 /* Merge attributes */
1952 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal;
1953 b->constant |= a->constant;
1954 b->noname |= a->noname;
1955 d_export_vec[i] = 0;
1958 dtab (d_export_vec);
1959 remove_null_names (d_export_vec);
1960 dtab (d_export_vec);
1965 /* Count the names */
1966 for (i = 0; i < d_nfuncs; i++)
1968 if (!d_export_vec[i]->noname)
1974 fill_ordinals (d_export_vec)
1975 export_type **d_export_vec;
1981 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
1983 /* fill in the unset ordinals with ones from our range */
1985 ptr = (char *) malloc (65536);
1987 memset (ptr, 0, 65536);
1989 /* Mark in our large vector all the numbers that are taken */
1990 for (i = 0; i < d_nfuncs; i++)
1992 if (d_export_vec[i]->ordinal != -1)
1994 ptr[d_export_vec[i]->ordinal] = 1;
1996 lowest = d_export_vec[i]->ordinal;
2000 /* Start at 1 for compatibility with MS toolchain. */
2004 for (i = 0; i < d_nfuncs; i++)
2006 if (d_export_vec[i]->ordinal == -1)
2009 for (j = lowest; j < 65536; j++)
2013 d_export_vec[i]->ordinal = j;
2017 for (j = 1; j < lowest; j++)
2021 d_export_vec[i]->ordinal = j;
2033 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc);
2035 /* Work out the lowest and highest ordinal numbers. */
2038 if (d_export_vec[0])
2039 d_low_ord = d_export_vec[0]->ordinal;
2040 if (d_export_vec[d_nfuncs-1])
2041 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal;
2045 int alphafunc(av,bv)
2049 export_type **a = av;
2050 export_type **b = bv;
2052 return strcmp ((*a)->name, (*b)->name);
2058 /* First work out the minimum ordinal chosen */
2064 export_type **d_export_vec
2065 = (export_type **) xmalloc (sizeof (export_type *) * d_nfuncs);
2067 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2069 d_export_vec[i] = exp;
2072 process_duplicates (d_export_vec);
2073 fill_ordinals (d_export_vec);
2075 /* Put back the list in the new order */
2077 for (i = d_nfuncs - 1; i >= 0; i--)
2079 d_export_vec[i]->next = d_exports;
2080 d_exports = d_export_vec[i];
2083 /* Build list in alpha order */
2084 d_exports_lexically = (export_type **)xmalloc (sizeof(export_type *)*(d_nfuncs+1));
2086 for (i = 0, exp = d_exports; exp; i++, exp = exp->next)
2088 d_exports_lexically[i] = exp;
2090 d_exports_lexically[i] = 0;
2092 qsort (d_exports_lexically, i, sizeof (export_type *), alphafunc);
2094 /* Fill exp entries with their hint values */
2096 for (i = 0; i < d_nfuncs; i++)
2098 if (!d_exports_lexically[i]->noname || show_allnames)
2099 d_exports_lexically[i]->hint = hint++;
2109 /**********************************************************************/
2112 usage (file, status)
2116 fprintf (file, "Usage %s <options> <object-files>\n", program_name);
2117 fprintf (file, " --machine <machine>\n");
2118 fprintf (file, " --output-exp <outname> Generate export file.\n");
2119 fprintf (file, " --output-lib <outname> Generate input library.\n");
2120 fprintf (file, " --add-indirect Add dll indirects to export file.\n");
2121 fprintf (file, " --dllname <name> Name of input dll to put into output lib.\n");
2122 fprintf (file, " --def <deffile> Name input .def file\n");
2123 fprintf (file, " --output-def <deffile> Name output .def file\n");
2124 fprintf (file, " --base-file <basefile> Read linker generated base file\n");
2125 fprintf (file, " --no-idata4 Don't generate idata$4 section\n");
2126 fprintf (file, " --no-idata5 Don't generate idata$5 section\n");
2127 fprintf (file, " -v Verbose\n");
2128 fprintf (file, " -U Add underscores to .lib\n");
2129 fprintf (file, " -k Kill @<n> from exported names\n");
2130 fprintf (file, " --as <name> Use <name> for assembler\n");
2131 fprintf (file, " --nodelete Keep temp files.\n");
2135 #define OPTION_NO_IDATA4 'x'
2136 #define OPTION_NO_IDATA5 'c'
2137 static struct option long_options[] =
2139 {"nodelete", no_argument, NULL, 'n'},
2140 {"dllname", required_argument, NULL, 'D'},
2141 {"no-idata4", no_argument, NULL, OPTION_NO_IDATA4},
2142 {"no-idata5", no_argument, NULL, OPTION_NO_IDATA5},
2143 {"output-exp", required_argument, NULL, 'e'},
2144 {"output-def", required_argument, NULL, 'z'},
2145 {"output-lib", required_argument, NULL, 'l'},
2146 {"def", required_argument, NULL, 'd'},
2147 {"add-underscore", no_argument, NULL, 'U'},
2148 {"killat", no_argument, NULL, 'k'},
2149 {"help", no_argument, NULL, 'h'},
2150 {"machine", required_argument, NULL, 'm'},
2151 {"add-indirect", no_argument, NULL, 'a'},
2152 {"base-file", required_argument, NULL, 'b'},
2153 {"as", required_argument, NULL, 'S'},
2167 program_name = av[0];
2170 while ((c = getopt_long (ac, av, "xcz:S:R:A:puaD:l:e:nkvbUh?m:yd:", long_options, 0))
2175 case OPTION_NO_IDATA4:
2178 case OPTION_NO_IDATA5:
2185 /* ignored for compatibility */
2192 output_def = fopen (optarg, FOPEN_WT);
2229 base_file = fopen (optarg, FOPEN_RB);
2232 fprintf (stderr, "%s: Unable to open base-file %s\n",
2244 for (i = 0; mtable[i].type; i++)
2246 if (strcmp (mtable[i].type, mname) == 0)
2250 if (!mtable[i].type)
2252 fprintf (stderr, "Machine not supported\n");
2258 if (!dll_name && exp_name)
2260 char len = strlen (exp_name) + 5;
2261 dll_name = xmalloc (len);
2262 strcpy (dll_name, exp_name);
2263 strcat (dll_name, ".dll");
2268 process_def_file (def_file);
2273 firstarg = av[optind];
2274 scan_obj_file (av[optind]);
2285 /* Make imp_name safe for use as a label. */
2287 imp_name_lab = strdup (imp_name);
2288 for (p = imp_name_lab; *p; *p++)
2290 if (!isalpha (*p) && !isdigit (*p))
2293 head_label = make_label("_head_", imp_name_lab);