1 /* dlltool.c -- tool to generate stuff for PE style DLLs 2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 3 2005, 2006 Free Software Foundation, Inc. 4 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 23 /* This program allows you to build the files necessary to create 24 DLLs to run on a system which understands PE format image files. 25 (eg, Windows NT) 26 27 See "Peering Inside the PE: A Tour of the Win32 Portable Executable 28 File Format", MSJ 1994, Volume 9 for more information. 29 Also see "Microsoft Portable Executable and Common Object File Format, 30 Specification 4.1" for more information. 31 32 A DLL contains an export table which contains the information 33 which the runtime loader needs to tie up references from a 34 referencing program. 35 36 The export table is generated by this program by reading 37 in a .DEF file or scanning the .a and .o files which will be in the 38 DLL. A .o file can contain information in special ".drectve" sections 39 with export information. 40 41 A DEF file contains any number of the following commands: 42 43 44 NAME <name> [ , <base> ] 45 The result is going to be <name>.EXE 46 47 LIBRARY <name> [ , <base> ] 48 The result is going to be <name>.DLL 49 50 EXPORTS ( ( ( <name1> [ = <name2> ] ) 51 | ( <name1> = <module-name> . <external-name>)) 52 [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] [PRIVATE] ) * 53 Declares name1 as an exported symbol from the 54 DLL, with optional ordinal number <integer>. 55 Or declares name1 as an alias (forward) of the function <external-name> 56 in the DLL <module-name>. 57 58 IMPORTS ( ( <internal-name> = <module-name> . <integer> ) 59 | ( [ <internal-name> = ] <module-name> . <external-name> )) * 60 Declares that <external-name> or the exported function whose ordinal number 61 is <integer> is to be imported from the file <module-name>. If 62 <internal-name> is specified then this is the name that the imported 63 function will be refereed to in the body of the DLL. 64 65 DESCRIPTION <string> 66 Puts <string> into output .exp file in the .rdata section 67 68 [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ] 69 Generates --stack|--heap <number-reserve>,<number-commit> 70 in the output .drectve section. The linker will 71 see this and act upon it. 72 73 [CODE|DATA] <attr>+ 74 SECTIONS ( <sectionname> <attr>+ )* 75 <attr> = READ | WRITE | EXECUTE | SHARED 76 Generates --attr <sectionname> <attr> in the output 77 .drectve section. The linker will see this and act 78 upon it. 79 80 81 A -export:<name> in a .drectve section in an input .o or .a 82 file to this program is equivalent to a EXPORTS <name> 83 in a .DEF file. 84 85 86 87 The program generates output files with the prefix supplied 88 on the command line, or in the def file, or taken from the first 89 supplied argument. 90 91 The .exp.s file contains the information necessary to export 92 the routines in the DLL. The .lib.s file contains the information 93 necessary to use the DLL's routines from a referencing program. 94 95 96 97 Example: 98 99 file1.c: 100 asm (".section .drectve"); 101 asm (".ascii \"-export:adef\""); 102 103 void adef (char * s) 104 { 105 printf ("hello from the dll %s\n", s); 106 } 107 108 void bdef (char * s) 109 { 110 printf ("hello from the dll and the other entry point %s\n", s); 111 } 112 113 file2.c: 114 asm (".section .drectve"); 115 asm (".ascii \"-export:cdef\""); 116 asm (".ascii \"-export:ddef\""); 117 118 void cdef (char * s) 119 { 120 printf ("hello from the dll %s\n", s); 121 } 122 123 void ddef (char * s) 124 { 125 printf ("hello from the dll and the other entry point %s\n", s); 126 } 127 128 int printf (void) 129 { 130 return 9; 131 } 132 133 themain.c: 134 int main (void) 135 { 136 cdef (); 137 return 0; 138 } 139 140 thedll.def 141 142 LIBRARY thedll 143 HEAPSIZE 0x40000, 0x2000 144 EXPORTS bdef @ 20 145 cdef @ 30 NONAME 146 147 SECTIONS donkey READ WRITE 148 aardvark EXECUTE 149 150 # Compile up the parts of the dll and the program 151 152 gcc -c file1.c file2.c themain.c 153 154 # Optional: put the dll objects into a library 155 # (you don't have to, you could name all the object 156 # files on the dlltool line) 157 158 ar qcv thedll.in file1.o file2.o 159 ranlib thedll.in 160 161 # Run this tool over the DLL's .def file and generate an exports 162 # file (thedll.o) and an imports file (thedll.a). 163 # (You may have to use -S to tell dlltool where to find the assembler). 164 165 dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a 166 167 # Build the dll with the library and the export table 168 169 ld -o thedll.dll thedll.o thedll.in 170 171 # Link the executable with the import library 172 173 gcc -o themain.exe themain.o thedll.a 174 175 This example can be extended if relocations are needed in the DLL: 176 177 # Compile up the parts of the dll and the program 178 179 gcc -c file1.c file2.c themain.c 180 181 # Run this tool over the DLL's .def file and generate an imports file. 182 183 dlltool --def thedll.def --output-lib thedll.lib 184 185 # Link the executable with the import library and generate a base file 186 # at the same time 187 188 gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base 189 190 # Run this tool over the DLL's .def file and generate an exports file 191 # which includes the relocations from the base file. 192 193 dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp 194 195 # Build the dll with file1.o, file2.o and the export table 196 197 ld -o thedll.dll thedll.exp file1.o file2.o */ 198 199 /* .idata section description 200 201 The .idata section is the import table. It is a collection of several 202 subsections used to keep the pieces for each dll together: .idata$[234567]. 203 IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc. 204 205 .idata$2 = Import Directory Table 206 = array of IMAGE_IMPORT_DESCRIPTOR's. 207 208 DWORD Import Lookup Table; - pointer to .idata$4 209 DWORD TimeDateStamp; - currently always 0 210 DWORD ForwarderChain; - currently always 0 211 DWORD Name; - pointer to dll's name 212 PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5 213 214 .idata$3 = null terminating entry for .idata$2. 215 216 .idata$4 = Import Lookup Table 217 = array of array of pointers to hint name table. 218 There is one for each dll being imported from, and each dll's set is 219 terminated by a trailing NULL. 220 221 .idata$5 = Import Address Table 222 = array of array of pointers to hint name table. 223 There is one for each dll being imported from, and each dll's set is 224 terminated by a trailing NULL. 225 Initially, this table is identical to the Import Lookup Table. However, 226 at load time, the loader overwrites the entries with the address of the 227 function. 228 229 .idata$6 = Hint Name Table 230 = Array of { short, asciz } entries, one for each imported function. 231 The `short' is the function's ordinal number. 232 233 .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc). */ 234 235 /* AIX requires this to be the first thing in the file. */ 236 #ifndef __GNUC__ 237 # ifdef _AIX 238 #pragma alloca 239 #endif 240 #endif 241 242 #define show_allnames 0 243 244 #define PAGE_SIZE 4096 245 #define PAGE_MASK (-PAGE_SIZE) 246 #include "bfd.h" 247 #include "libiberty.h" 248 #include "bucomm.h" 249 #include "getopt.h" 250 #include "demangle.h" 251 #include "dyn-string.h" 252 #include "dlltool.h" 253 #include "safe-ctype.h" 254 255 #include <time.h> 256 #include <sys/stat.h> 257 #include <stdarg.h> 258 #include <assert.h> 259 260 #ifdef DLLTOOL_ARM 261 #include "coff/arm.h" 262 #include "coff/internal.h" 263 #endif 264 265 /* Forward references. */ 266 static char *look_for_prog (const char *, const char *, int); 267 static char *deduce_name (const char *); 268 269 #ifdef DLLTOOL_MCORE_ELF 270 static void mcore_elf_cache_filename (char *); 271 static void mcore_elf_gen_out_file (void); 272 #endif 273 274 #ifdef HAVE_SYS_WAIT_H 275 #include <sys/wait.h> 276 #else /* ! HAVE_SYS_WAIT_H */ 277 #if ! defined (_WIN32) || defined (__CYGWIN32__) 278 #ifndef WIFEXITED 279 #define WIFEXITED(w) (((w) & 0377) == 0) 280 #endif 281 #ifndef WIFSIGNALED 282 #define WIFSIGNALED(w) (((w) & 0377) != 0177 && ((w) & ~0377) == 0) 283 #endif 284 #ifndef WTERMSIG 285 #define WTERMSIG(w) ((w) & 0177) 286 #endif 287 #ifndef WEXITSTATUS 288 #define WEXITSTATUS(w) (((w) >> 8) & 0377) 289 #endif 290 #else /* defined (_WIN32) && ! defined (__CYGWIN32__) */ 291 #ifndef WIFEXITED 292 #define WIFEXITED(w) (((w) & 0xff) == 0) 293 #endif 294 #ifndef WIFSIGNALED 295 #define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f) 296 #endif 297 #ifndef WTERMSIG 298 #define WTERMSIG(w) ((w) & 0x7f) 299 #endif 300 #ifndef WEXITSTATUS 301 #define WEXITSTATUS(w) (((w) & 0xff00) >> 8) 302 #endif 303 #endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */ 304 #endif /* ! HAVE_SYS_WAIT_H */ 305 306 /* ifunc and ihead data structures: ttk@cygnus.com 1997 307 308 When IMPORT declarations are encountered in a .def file the 309 function import information is stored in a structure referenced by 310 the global variable IMPORT_LIST. The structure is a linked list 311 containing the names of the dll files each function is imported 312 from and a linked list of functions being imported from that dll 313 file. This roughly parallels the structure of the .idata section 314 in the PE object file. 315 316 The contents of .def file are interpreted from within the 317 process_def_file function. Every time an IMPORT declaration is 318 encountered, it is broken up into its component parts and passed to 319 def_import. IMPORT_LIST is initialized to NULL in function main. */ 320 321 typedef struct ifunct 322 { 323 char * name; /* Name of function being imported. */ 324 int ord; /* Two-byte ordinal value associated with function. */ 325 struct ifunct *next; 326 } ifunctype; 327 328 typedef struct iheadt 329 { 330 char *dllname; /* Name of dll file imported from. */ 331 long nfuncs; /* Number of functions in list. */ 332 struct ifunct *funchead; /* First function in list. */ 333 struct ifunct *functail; /* Last function in list. */ 334 struct iheadt *next; /* Next dll file in list. */ 335 } iheadtype; 336 337 /* Structure containing all import information as defined in .def file 338 (qv "ihead structure"). */ 339 340 static iheadtype *import_list = NULL; 341 342 static char *as_name = NULL; 343 static char * as_flags = ""; 344 345 static char *tmp_prefix; 346 347 static int no_idata4; 348 static int no_idata5; 349 static char *exp_name; 350 static char *imp_name; 351 static char *head_label; 352 static char *imp_name_lab; 353 static char *dll_name; 354 355 static int add_indirect = 0; 356 static int add_underscore = 0; 357 static int add_stdcall_underscore = 0; 358 static int dontdeltemps = 0; 359 360 /* TRUE if we should export all symbols. Otherwise, we only export 361 symbols listed in .drectve sections or in the def file. */ 362 static bfd_boolean export_all_symbols; 363 364 /* TRUE if we should exclude the symbols in DEFAULT_EXCLUDES when 365 exporting all symbols. */ 366 static bfd_boolean do_default_excludes = TRUE; 367 368 /* Default symbols to exclude when exporting all the symbols. */ 369 static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr"; 370 371 /* TRUE if we should add __imp_<SYMBOL> to import libraries for backward 372 compatibility to old Cygwin releases. */ 373 static bfd_boolean create_compat_implib; 374 375 static char *def_file; 376 377 extern char * program_name; 378 379 static int machine; 380 static int killat; 381 static int add_stdcall_alias; 382 static const char *ext_prefix_alias; 383 static int verbose; 384 static FILE *output_def; 385 static FILE *base_file; 386 387 #ifdef DLLTOOL_ARM 388 #ifdef DLLTOOL_ARM_EPOC 389 static const char *mname = "arm-epoc"; 390 #else 391 static const char *mname = "arm"; 392 #endif 393 #endif 394 395 #ifdef DLLTOOL_I386 396 static const char *mname = "i386"; 397 #endif 398 399 #ifdef DLLTOOL_PPC 400 static const char *mname = "ppc"; 401 #endif 402 403 #ifdef DLLTOOL_SH 404 static const char *mname = "sh"; 405 #endif 406 407 #ifdef DLLTOOL_MIPS 408 static const char *mname = "mips"; 409 #endif 410 411 #ifdef DLLTOOL_MCORE 412 static const char * mname = "mcore-le"; 413 #endif 414 415 #ifdef DLLTOOL_MCORE_ELF 416 static const char * mname = "mcore-elf"; 417 static char * mcore_elf_out_file = NULL; 418 static char * mcore_elf_linker = NULL; 419 static char * mcore_elf_linker_flags = NULL; 420 421 #define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve") 422 #endif 423 424 #ifndef DRECTVE_SECTION_NAME 425 #define DRECTVE_SECTION_NAME ".drectve" 426 #endif 427 428 /* What's the right name for this ? */ 429 #define PATHMAX 250 430 431 /* External name alias numbering starts here. */ 432 #define PREFIX_ALIAS_BASE 20000 433 434 char *tmp_asm_buf; 435 char *tmp_head_s_buf; 436 char *tmp_head_o_buf; 437 char *tmp_tail_s_buf; 438 char *tmp_tail_o_buf; 439 char *tmp_stub_buf; 440 441 #define TMP_ASM dlltmp (&tmp_asm_buf, "%sc.s") 442 #define TMP_HEAD_S dlltmp (&tmp_head_s_buf, "%sh.s") 443 #define TMP_HEAD_O dlltmp (&tmp_head_o_buf, "%sh.o") 444 #define TMP_TAIL_S dlltmp (&tmp_tail_s_buf, "%st.s") 445 #define TMP_TAIL_O dlltmp (&tmp_tail_o_buf, "%st.o") 446 #define TMP_STUB dlltmp (&tmp_stub_buf, "%ss") 447 448 /* This bit of assembly does jmp * .... */ 449 static const unsigned char i386_jtab[] = 450 { 451 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90 452 }; 453 454 static const unsigned char arm_jtab[] = 455 { 456 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ 457 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */ 458 0, 0, 0, 0 459 }; 460 461 static const unsigned char arm_interwork_jtab[] = 462 { 463 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ 464 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */ 465 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */ 466 0, 0, 0, 0 467 }; 468 469 static const unsigned char thumb_jtab[] = 470 { 471 0x40, 0xb4, /* push {r6} */ 472 0x02, 0x4e, /* ldr r6, [pc, #8] */ 473 0x36, 0x68, /* ldr r6, [r6] */ 474 0xb4, 0x46, /* mov ip, r6 */ 475 0x40, 0xbc, /* pop {r6} */ 476 0x60, 0x47, /* bx ip */ 477 0, 0, 0, 0 478 }; 479 480 static const unsigned char mcore_be_jtab[] = 481 { 482 0x71, 0x02, /* lrw r1,2 */ 483 0x81, 0x01, /* ld.w r1,(r1,0) */ 484 0x00, 0xC1, /* jmp r1 */ 485 0x12, 0x00, /* nop */ 486 0x00, 0x00, 0x00, 0x00 /* <address> */ 487 }; 488 489 static const unsigned char mcore_le_jtab[] = 490 { 491 0x02, 0x71, /* lrw r1,2 */ 492 0x01, 0x81, /* ld.w r1,(r1,0) */ 493 0xC1, 0x00, /* jmp r1 */ 494 0x00, 0x12, /* nop */ 495 0x00, 0x00, 0x00, 0x00 /* <address> */ 496 }; 497 498 /* This is the glue sequence for PowerPC PE. There is a 499 tocrel16-tocdefn reloc against the first instruction. 500 We also need a IMGLUE reloc against the glue function 501 to restore the toc saved by the third instruction in 502 the glue. */ 503 static const unsigned char ppc_jtab[] = 504 { 505 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */ 506 /* Reloc TOCREL16 __imp_xxx */ 507 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */ 508 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */ 509 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */ 510 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */ 511 0x20, 0x04, 0x80, 0x4E /* bctr */ 512 }; 513 514 #ifdef DLLTOOL_PPC 515 /* The glue instruction, picks up the toc from the stw in 516 the above code: "lwz r2,4(r1)". */ 517 static bfd_vma ppc_glue_insn = 0x80410004; 518 #endif 519 520 struct mac 521 { 522 const char *type; 523 const char *how_byte; 524 const char *how_short; 525 const char *how_long; 526 const char *how_asciz; 527 const char *how_comment; 528 const char *how_jump; 529 const char *how_global; 530 const char *how_space; 531 const char *how_align_short; 532 const char *how_align_long; 533 const char *how_default_as_switches; 534 const char *how_bfd_target; 535 enum bfd_architecture how_bfd_arch; 536 const unsigned char *how_jtab; 537 int how_jtab_size; /* Size of the jtab entry. */ 538 int how_jtab_roff; /* Offset into it for the ind 32 reloc into idata 5. */ 539 }; 540 541 static const struct mac 542 mtable[] = 543 { 544 { 545 #define MARM 0 546 "arm", ".byte", ".short", ".long", ".asciz", "@", 547 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", 548 ".global", ".space", ".align\t2",".align\t4", "-mapcs-32", 549 "pe-arm-little", bfd_arch_arm, 550 arm_jtab, sizeof (arm_jtab), 8 551 } 552 , 553 { 554 #define M386 1 555 "i386", ".byte", ".short", ".long", ".asciz", "#", 556 "jmp *", ".global", ".space", ".align\t2",".align\t4", "", 557 "pe-i386",bfd_arch_i386, 558 i386_jtab, sizeof (i386_jtab), 2 559 } 560 , 561 { 562 #define MPPC 2 563 "ppc", ".byte", ".short", ".long", ".asciz", "#", 564 "jmp *", ".global", ".space", ".align\t2",".align\t4", "", 565 "pe-powerpcle",bfd_arch_powerpc, 566 ppc_jtab, sizeof (ppc_jtab), 0 567 } 568 , 569 { 570 #define MTHUMB 3 571 "thumb", ".byte", ".short", ".long", ".asciz", "@", 572 "push\t{r6}\n\tldr\tr6, [pc, #8]\n\tldr\tr6, [r6]\n\tmov\tip, r6\n\tpop\t{r6}\n\tbx\tip", 573 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork", 574 "pe-arm-little", bfd_arch_arm, 575 thumb_jtab, sizeof (thumb_jtab), 12 576 } 577 , 578 #define MARM_INTERWORK 4 579 { 580 "arm_interwork", ".byte", ".short", ".long", ".asciz", "@", 581 "ldr\tip,[pc]\n\tldr\tip,[ip]\n\tbx\tip\n\t.long", 582 ".global", ".space", ".align\t2",".align\t4", "-mthumb-interwork", 583 "pe-arm-little", bfd_arch_arm, 584 arm_interwork_jtab, sizeof (arm_interwork_jtab), 12 585 } 586 , 587 { 588 #define MMCORE_BE 5 589 "mcore-be", ".byte", ".short", ".long", ".asciz", "//", 590 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 591 ".global", ".space", ".align\t2",".align\t4", "", 592 "pe-mcore-big", bfd_arch_mcore, 593 mcore_be_jtab, sizeof (mcore_be_jtab), 8 594 } 595 , 596 { 597 #define MMCORE_LE 6 598 "mcore-le", ".byte", ".short", ".long", ".asciz", "//", 599 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 600 ".global", ".space", ".align\t2",".align\t4", "-EL", 601 "pe-mcore-little", bfd_arch_mcore, 602 mcore_le_jtab, sizeof (mcore_le_jtab), 8 603 } 604 , 605 { 606 #define MMCORE_ELF 7 607 "mcore-elf-be", ".byte", ".short", ".long", ".asciz", "//", 608 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 609 ".global", ".space", ".align\t2",".align\t4", "", 610 "elf32-mcore-big", bfd_arch_mcore, 611 mcore_be_jtab, sizeof (mcore_be_jtab), 8 612 } 613 , 614 { 615 #define MMCORE_ELF_LE 8 616 "mcore-elf-le", ".byte", ".short", ".long", ".asciz", "//", 617 "lrw r1,[1f]\n\tld.w r1,(r1,0)\n\tjmp r1\n\tnop\n1:.long", 618 ".global", ".space", ".align\t2",".align\t4", "-EL", 619 "elf32-mcore-little", bfd_arch_mcore, 620 mcore_le_jtab, sizeof (mcore_le_jtab), 8 621 } 622 , 623 { 624 #define MARM_EPOC 9 625 "arm-epoc", ".byte", ".short", ".long", ".asciz", "@", 626 "ldr\tip,[pc]\n\tldr\tpc,[ip]\n\t.long", 627 ".global", ".space", ".align\t2",".align\t4", "", 628 "epoc-pe-arm-little", bfd_arch_arm, 629 arm_jtab, sizeof (arm_jtab), 8 630 } 631 , 632 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 633 }; 634 635 typedef struct dlist 636 { 637 char *text; 638 struct dlist *next; 639 } 640 dlist_type; 641 642 typedef struct export 643 { 644 const char *name; 645 const char *internal_name; 646 const char *import_name; 647 int ordinal; 648 int constant; 649 int noname; /* Don't put name in image file. */ 650 int private; /* Don't put reference in import lib. */ 651 int data; 652 int hint; 653 int forward; /* Number of forward label, 0 means no forward. */ 654 struct export *next; 655 } 656 export_type; 657 658 /* A list of symbols which we should not export. */ 659 660 struct string_list 661 { 662 struct string_list *next; 663 char *string; 664 }; 665 666 static struct string_list *excludes; 667 668 static const char *rvaafter (int); 669 static const char *rvabefore (int); 670 static const char *asm_prefix (int, const char *); 671 static void process_def_file (const char *); 672 static void new_directive (char *); 673 static void append_import (const char *, const char *, int); 674 static void run (const char *, char *); 675 static void scan_drectve_symbols (bfd *); 676 static void scan_filtered_symbols (bfd *, void *, long, unsigned int); 677 static void add_excludes (const char *); 678 static bfd_boolean match_exclude (const char *); 679 static void set_default_excludes (void); 680 static long filter_symbols (bfd *, void *, long, unsigned int); 681 static void scan_all_symbols (bfd *); 682 static void scan_open_obj_file (bfd *); 683 static void scan_obj_file (const char *); 684 static void dump_def_info (FILE *); 685 static int sfunc (const void *, const void *); 686 static void flush_page (FILE *, long *, int, int); 687 static void gen_def_file (void); 688 static void generate_idata_ofile (FILE *); 689 static void assemble_file (const char *, const char *); 690 static void gen_exp_file (void); 691 static const char *xlate (const char *); 692 static char *make_label (const char *, const char *); 693 static char *make_imp_label (const char *, const char *); 694 static bfd *make_one_lib_file (export_type *, int); 695 static bfd *make_head (void); 696 static bfd *make_tail (void); 697 static void gen_lib_file (void); 698 static int pfunc (const void *, const void *); 699 static int nfunc (const void *, const void *); 700 static void remove_null_names (export_type **); 701 static void process_duplicates (export_type **); 702 static void fill_ordinals (export_type **); 703 static void mangle_defs (void); 704 static void usage (FILE *, int); 705 static void inform (const char *, ...) ATTRIBUTE_PRINTF_1; 706 static void set_dll_name_from_def (const char *); 707 708 static char * 709 prefix_encode (char *start, unsigned code) 710 { 711 static char alpha[26] = "abcdefghijklmnopqrstuvwxyz"; 712 static char buf[32]; 713 char *p; 714 strcpy (buf, start); 715 p = strchr (buf, '\0'); 716 do 717 *p++ = alpha[code % sizeof (alpha)]; 718 while ((code /= sizeof (alpha)) != 0); 719 *p = '\0'; 720 return buf; 721 } 722 723 static char * 724 dlltmp (char **buf, const char *fmt) 725 { 726 if (!*buf) 727 { 728 *buf = malloc (strlen (tmp_prefix) + 64); 729 sprintf (*buf, fmt, tmp_prefix); 730 } 731 return *buf; 732 } 733 734 static void 735 inform VPARAMS ((const char * message, ...)) 736 { 737 VA_OPEN (args, message); 738 VA_FIXEDARG (args, const char *, message); 739 740 if (!verbose) 741 return; 742 743 report (message, args); 744 745 VA_CLOSE (args); 746 } 747 748 static const char * 749 rvaafter (int machine) 750 { 751 switch (machine) 752 { 753 case MARM: 754 case M386: 755 case MPPC: 756 case MTHUMB: 757 case MARM_INTERWORK: 758 case MMCORE_BE: 759 case MMCORE_LE: 760 case MMCORE_ELF: 761 case MMCORE_ELF_LE: 762 case MARM_EPOC: 763 break; 764 default: 765 /* xgettext:c-format */ 766 fatal (_("Internal error: Unknown machine type: %d"), machine); 767 break; 768 } 769 return ""; 770 } 771 772 static const char * 773 rvabefore (int machine) 774 { 775 switch (machine) 776 { 777 case MARM: 778 case M386: 779 case MPPC: 780 case MTHUMB: 781 case MARM_INTERWORK: 782 case MMCORE_BE: 783 case MMCORE_LE: 784 case MMCORE_ELF: 785 case MMCORE_ELF_LE: 786 case MARM_EPOC: 787 return ".rva\t"; 788 default: 789 /* xgettext:c-format */ 790 fatal (_("Internal error: Unknown machine type: %d"), machine); 791 break; 792 } 793 return ""; 794 } 795 796 static const char * 797 asm_prefix (int machine, const char *name) 798 { 799 switch (machine) 800 { 801 case MARM: 802 case MPPC: 803 case MTHUMB: 804 case MARM_INTERWORK: 805 case MMCORE_BE: 806 case MMCORE_LE: 807 case MMCORE_ELF: 808 case MMCORE_ELF_LE: 809 case MARM_EPOC: 810 break; 811 case M386: 812 /* Symbol names starting with ? do not have a leading underscore. */ 813 if (name && *name == '?') 814 break; 815 else 816 return "_"; 817 default: 818 /* xgettext:c-format */ 819 fatal (_("Internal error: Unknown machine type: %d"), machine); 820 break; 821 } 822 return ""; 823 } 824 825 #define ASM_BYTE mtable[machine].how_byte 826 #define ASM_SHORT mtable[machine].how_short 827 #define ASM_LONG mtable[machine].how_long 828 #define ASM_TEXT mtable[machine].how_asciz 829 #define ASM_C mtable[machine].how_comment 830 #define ASM_JUMP mtable[machine].how_jump 831 #define ASM_GLOBAL mtable[machine].how_global 832 #define ASM_SPACE mtable[machine].how_space 833 #define ASM_ALIGN_SHORT mtable[machine].how_align_short 834 #define ASM_RVA_BEFORE rvabefore (machine) 835 #define ASM_RVA_AFTER rvaafter (machine) 836 #define ASM_PREFIX(NAME) asm_prefix (machine, (NAME)) 837 #define ASM_ALIGN_LONG mtable[machine].how_align_long 838 #define HOW_BFD_READ_TARGET 0 /* Always default. */ 839 #define HOW_BFD_WRITE_TARGET mtable[machine].how_bfd_target 840 #define HOW_BFD_ARCH mtable[machine].how_bfd_arch 841 #define HOW_JTAB mtable[machine].how_jtab 842 #define HOW_JTAB_SIZE mtable[machine].how_jtab_size 843 #define HOW_JTAB_ROFF mtable[machine].how_jtab_roff 844 #define ASM_SWITCHES mtable[machine].how_default_as_switches 845 846 static char **oav; 847 848 static void 849 process_def_file (const char *name) 850 { 851 FILE *f = fopen (name, FOPEN_RT); 852 853 if (!f) 854 /* xgettext:c-format */ 855 fatal (_("Can't open def file: %s"), name); 856 857 yyin = f; 858 859 /* xgettext:c-format */ 860 inform (_("Processing def file: %s"), name); 861 862 yyparse (); 863 864 inform (_("Processed def file")); 865 } 866 867 /**********************************************************************/ 868 869 /* Communications with the parser. */ 870 871 static int d_nfuncs; /* Number of functions exported. */ 872 static int d_named_nfuncs; /* Number of named functions exported. */ 873 static int d_low_ord; /* Lowest ordinal index. */ 874 static int d_high_ord; /* Highest ordinal index. */ 875 static export_type *d_exports; /* List of exported functions. */ 876 static export_type **d_exports_lexically; /* Vector of exported functions in alpha order. */ 877 static dlist_type *d_list; /* Descriptions. */ 878 static dlist_type *a_list; /* Stuff to go in directives. */ 879 static int d_nforwards = 0; /* Number of forwarded exports. */ 880 881 static int d_is_dll; 882 static int d_is_exe; 883 884 int 885 yyerror (const char * err ATTRIBUTE_UNUSED) 886 { 887 /* xgettext:c-format */ 888 non_fatal (_("Syntax error in def file %s:%d"), def_file, linenumber); 889 890 return 0; 891 } 892 893 void 894 def_exports (const char *name, const char *internal_name, int ordinal, 895 int noname, int constant, int data, int private) 896 { 897 struct export *p = (struct export *) xmalloc (sizeof (*p)); 898 899 p->name = name; 900 p->internal_name = internal_name ? internal_name : name; 901 p->import_name = name; 902 p->ordinal = ordinal; 903 p->constant = constant; 904 p->noname = noname; 905 p->private = private; 906 p->data = data; 907 p->next = d_exports; 908 d_exports = p; 909 d_nfuncs++; 910 911 if ((internal_name != NULL) 912 && (strchr (internal_name, '.') != NULL)) 913 p->forward = ++d_nforwards; 914 else 915 p->forward = 0; /* no forward */ 916 } 917 918 static void 919 set_dll_name_from_def (const char * name) 920 { 921 const char* image_basename = lbasename (name); 922 if (image_basename != name) 923 non_fatal (_("%s: Path components stripped from image name, '%s'."), 924 def_file, name); 925 dll_name = xstrdup (image_basename); 926 } 927 928 void 929 def_name (const char *name, int base) 930 { 931 /* xgettext:c-format */ 932 inform (_("NAME: %s base: %x"), name, base); 933 934 if (d_is_dll) 935 non_fatal (_("Can't have LIBRARY and NAME")); 936 937 /* If --dllname not provided, use the one in the DEF file. 938 FIXME: Is this appropriate for executables? */ 939 if (! dll_name) 940 set_dll_name_from_def (name); 941 d_is_exe = 1; 942 } 943 944 void 945 def_library (const char *name, int base) 946 { 947 /* xgettext:c-format */ 948 inform (_("LIBRARY: %s base: %x"), name, base); 949 950 if (d_is_exe) 951 non_fatal (_("Can't have LIBRARY and NAME")); 952 953 /* If --dllname not provided, use the one in the DEF file. */ 954 if (! dll_name) 955 set_dll_name_from_def (name); 956 d_is_dll = 1; 957 } 958 959 void 960 def_description (const char *desc) 961 { 962 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type)); 963 d->text = xstrdup (desc); 964 d->next = d_list; 965 d_list = d; 966 } 967 968 static void 969 new_directive (char *dir) 970 { 971 dlist_type *d = (dlist_type *) xmalloc (sizeof (dlist_type)); 972 d->text = xstrdup (dir); 973 d->next = a_list; 974 a_list = d; 975 } 976 977 void 978 def_heapsize (int reserve, int commit) 979 { 980 char b[200]; 981 if (commit > 0) 982 sprintf (b, "-heap 0x%x,0x%x ", reserve, commit); 983 else 984 sprintf (b, "-heap 0x%x ", reserve); 985 new_directive (xstrdup (b)); 986 } 987 988 void 989 def_stacksize (int reserve, int commit) 990 { 991 char b[200]; 992 if (commit > 0) 993 sprintf (b, "-stack 0x%x,0x%x ", reserve, commit); 994 else 995 sprintf (b, "-stack 0x%x ", reserve); 996 new_directive (xstrdup (b)); 997 } 998 999 /* append_import simply adds the given import definition to the global 1000 import_list. It is used by def_import. */ 1001 1002 static void 1003 append_import (const char *symbol_name, const char *dll_name, int func_ordinal) 1004 { 1005 iheadtype **pq; 1006 iheadtype *q; 1007 1008 for (pq = &import_list; *pq != NULL; pq = &(*pq)->next) 1009 { 1010 if (strcmp ((*pq)->dllname, dll_name) == 0) 1011 { 1012 q = *pq; 1013 q->functail->next = xmalloc (sizeof (ifunctype)); 1014 q->functail = q->functail->next; 1015 q->functail->ord = func_ordinal; 1016 q->functail->name = xstrdup (symbol_name); 1017 q->functail->next = NULL; 1018 q->nfuncs++; 1019 return; 1020 } 1021 } 1022 1023 q = xmalloc (sizeof (iheadtype)); 1024 q->dllname = xstrdup (dll_name); 1025 q->nfuncs = 1; 1026 q->funchead = xmalloc (sizeof (ifunctype)); 1027 q->functail = q->funchead; 1028 q->next = NULL; 1029 q->functail->name = xstrdup (symbol_name); 1030 q->functail->ord = func_ordinal; 1031 q->functail->next = NULL; 1032 1033 *pq = q; 1034 } 1035 1036 /* def_import is called from within defparse.y when an IMPORT 1037 declaration is encountered. Depending on the form of the 1038 declaration, the module name may or may not need ".dll" to be 1039 appended to it, the name of the function may be stored in internal 1040 or entry, and there may or may not be an ordinal value associated 1041 with it. */ 1042 1043 /* A note regarding the parse modes: 1044 In defparse.y we have to accept import declarations which follow 1045 any one of the following forms: 1046 <func_name_in_app> = <dll_name>.<func_name_in_dll> 1047 <func_name_in_app> = <dll_name>.<number> 1048 <dll_name>.<func_name_in_dll> 1049 <dll_name>.<number> 1050 Furthermore, the dll's name may or may not end with ".dll", which 1051 complicates the parsing a little. Normally the dll's name is 1052 passed to def_import() in the "module" parameter, but when it ends 1053 with ".dll" it gets passed in "module" sans ".dll" and that needs 1054 to be reappended. 1055 1056 def_import gets five parameters: 1057 APP_NAME - the name of the function in the application, if 1058 present, or NULL if not present. 1059 MODULE - the name of the dll, possibly sans extension (ie, '.dll'). 1060 DLLEXT - the extension of the dll, if present, NULL if not present. 1061 ENTRY - the name of the function in the dll, if present, or NULL. 1062 ORD_VAL - the numerical tag of the function in the dll, if present, 1063 or NULL. Exactly one of <entry> or <ord_val> must be 1064 present (i.e., not NULL). */ 1065 1066 void 1067 def_import (const char *app_name, const char *module, const char *dllext, 1068 const char *entry, int ord_val) 1069 { 1070 const char *application_name; 1071 char *buf; 1072 1073 if (entry != NULL) 1074 application_name = entry; 1075 else 1076 { 1077 if (app_name != NULL) 1078 application_name = app_name; 1079 else 1080 application_name = ""; 1081 } 1082 1083 if (dllext != NULL) 1084 { 1085 buf = (char *) alloca (strlen (module) + strlen (dllext) + 2); 1086 sprintf (buf, "%s.%s", module, dllext); 1087 module = buf; 1088 } 1089 1090 append_import (application_name, module, ord_val); 1091 } 1092 1093 void 1094 def_version (int major, int minor) 1095 { 1096 printf ("VERSION %d.%d\n", major, minor); 1097 } 1098 1099 void 1100 def_section (const char *name, int attr) 1101 { 1102 char buf[200]; 1103 char atts[5]; 1104 char *d = atts; 1105 if (attr & 1) 1106 *d++ = 'R'; 1107 1108 if (attr & 2) 1109 *d++ = 'W'; 1110 if (attr & 4) 1111 *d++ = 'X'; 1112 if (attr & 8) 1113 *d++ = 'S'; 1114 *d++ = 0; 1115 sprintf (buf, "-attr %s %s", name, atts); 1116 new_directive (xstrdup (buf)); 1117 } 1118 1119 void 1120 def_code (int attr) 1121 { 1122 1123 def_section ("CODE", attr); 1124 } 1125 1126 void 1127 def_data (int attr) 1128 { 1129 def_section ("DATA", attr); 1130 } 1131 1132 /**********************************************************************/ 1133 1134 static void 1135 run (const char *what, char *args) 1136 { 1137 char *s; 1138 int pid, wait_status; 1139 int i; 1140 const char **argv; 1141 char *errmsg_fmt, *errmsg_arg; 1142 #if defined(__MSDOS__) && !defined(__GO32__) 1143 char *temp_base = choose_temp_base (); 1144 #else 1145 char *temp_base = NULL; 1146 #endif 1147 1148 inform ("run: %s %s", what, args); 1149 1150 /* Count the args */ 1151 i = 0; 1152 for (s = args; *s; s++) 1153 if (*s == ' ') 1154 i++; 1155 i++; 1156 argv = alloca (sizeof (char *) * (i + 3)); 1157 i = 0; 1158 argv[i++] = what; 1159 s = args; 1160 while (1) 1161 { 1162 while (*s == ' ') 1163 ++s; 1164 argv[i++] = s; 1165 while (*s != ' ' && *s != 0) 1166 s++; 1167 if (*s == 0) 1168 break; 1169 *s++ = 0; 1170 } 1171 argv[i++] = NULL; 1172 1173 pid = pexecute (argv[0], (char * const *) argv, program_name, temp_base, 1174 &errmsg_fmt, &errmsg_arg, PEXECUTE_ONE | PEXECUTE_SEARCH); 1175 1176 if (pid == -1) 1177 { 1178 inform (strerror (errno)); 1179 1180 fatal (errmsg_fmt, errmsg_arg); 1181 } 1182 1183 pid = pwait (pid, & wait_status, 0); 1184 1185 if (pid == -1) 1186 { 1187 /* xgettext:c-format */ 1188 fatal (_("wait: %s"), strerror (errno)); 1189 } 1190 else if (WIFSIGNALED (wait_status)) 1191 { 1192 /* xgettext:c-format */ 1193 fatal (_("subprocess got fatal signal %d"), WTERMSIG (wait_status)); 1194 } 1195 else if (WIFEXITED (wait_status)) 1196 { 1197 if (WEXITSTATUS (wait_status) != 0) 1198 /* xgettext:c-format */ 1199 non_fatal (_("%s exited with status %d"), 1200 what, WEXITSTATUS (wait_status)); 1201 } 1202 else 1203 abort (); 1204 } 1205 1206 /* Look for a list of symbols to export in the .drectve section of 1207 ABFD. Pass each one to def_exports. */ 1208 1209 static void 1210 scan_drectve_symbols (bfd *abfd) 1211 { 1212 asection * s; 1213 int size; 1214 char * buf; 1215 char * p; 1216 char * e; 1217 1218 /* Look for .drectve's */ 1219 s = bfd_get_section_by_name (abfd, DRECTVE_SECTION_NAME); 1220 1221 if (s == NULL) 1222 return; 1223 1224 size = bfd_get_section_size (s); 1225 buf = xmalloc (size); 1226 1227 bfd_get_section_contents (abfd, s, buf, 0, size); 1228 1229 /* xgettext:c-format */ 1230 inform (_("Sucking in info from %s section in %s"), 1231 DRECTVE_SECTION_NAME, bfd_get_filename (abfd)); 1232 1233 /* Search for -export: strings. The exported symbols can optionally 1234 have type tags (eg., -export:foo,data), so handle those as well. 1235 Currently only data tag is supported. */ 1236 p = buf; 1237 e = buf + size; 1238 while (p < e) 1239 { 1240 if (p[0] == '-' 1241 && strncmp (p, "-export:", 8) == 0) 1242 { 1243 char * name; 1244 char * c; 1245 flagword flags = BSF_FUNCTION; 1246 1247 p += 8; 1248 name = p; 1249 while (p < e && *p != ',' && *p != ' ' && *p != '-') 1250 p++; 1251 c = xmalloc (p - name + 1); 1252 memcpy (c, name, p - name); 1253 c[p - name] = 0; 1254 if (p < e && *p == ',') /* found type tag. */ 1255 { 1256 char *tag_start = ++p; 1257 while (p < e && *p != ' ' && *p != '-') 1258 p++; 1259 if (strncmp (tag_start, "data", 4) == 0) 1260 flags &= ~BSF_FUNCTION; 1261 } 1262 1263 /* FIXME: The 5th arg is for the `constant' field. 1264 What should it be? Not that it matters since it's not 1265 currently useful. */ 1266 def_exports (c, 0, -1, 0, 0, ! (flags & BSF_FUNCTION), 0); 1267 1268 if (add_stdcall_alias && strchr (c, '@')) 1269 { 1270 int lead_at = (*c == '@') ; 1271 char *exported_name = xstrdup (c + lead_at); 1272 char *atsym = strchr (exported_name, '@'); 1273 *atsym = '\0'; 1274 /* Note: stdcall alias symbols can never be data. */ 1275 def_exports (exported_name, xstrdup (c), -1, 0, 0, 0, 0); 1276 } 1277 } 1278 else 1279 p++; 1280 } 1281 free (buf); 1282 } 1283 1284 /* Look through the symbols in MINISYMS, and add each one to list of 1285 symbols to export. */ 1286 1287 static void 1288 scan_filtered_symbols (bfd *abfd, void *minisyms, long symcount, 1289 unsigned int size) 1290 { 1291 asymbol *store; 1292 bfd_byte *from, *fromend; 1293 1294 store = bfd_make_empty_symbol (abfd); 1295 if (store == NULL) 1296 bfd_fatal (bfd_get_filename (abfd)); 1297 1298 from = (bfd_byte *) minisyms; 1299 fromend = from + symcount * size; 1300 for (; from < fromend; from += size) 1301 { 1302 asymbol *sym; 1303 const char *symbol_name; 1304 1305 sym = bfd_minisymbol_to_symbol (abfd, FALSE, from, store); 1306 if (sym == NULL) 1307 bfd_fatal (bfd_get_filename (abfd)); 1308 1309 symbol_name = bfd_asymbol_name (sym); 1310 if (bfd_get_symbol_leading_char (abfd) == symbol_name[0]) 1311 ++symbol_name; 1312 1313 def_exports (xstrdup (symbol_name) , 0, -1, 0, 0, 1314 ! (sym->flags & BSF_FUNCTION), 0); 1315 1316 if (add_stdcall_alias && strchr (symbol_name, '@')) 1317 { 1318 int lead_at = (*symbol_name == '@'); 1319 char *exported_name = xstrdup (symbol_name + lead_at); 1320 char *atsym = strchr (exported_name, '@'); 1321 *atsym = '\0'; 1322 /* Note: stdcall alias symbols can never be data. */ 1323 def_exports (exported_name, xstrdup (symbol_name), -1, 0, 0, 0, 0); 1324 } 1325 } 1326 } 1327 1328 /* Add a list of symbols to exclude. */ 1329 1330 static void 1331 add_excludes (const char *new_excludes) 1332 { 1333 char *local_copy; 1334 char *exclude_string; 1335 1336 local_copy = xstrdup (new_excludes); 1337 1338 exclude_string = strtok (local_copy, ",:"); 1339 for (; exclude_string; exclude_string = strtok (NULL, ",:")) 1340 { 1341 struct string_list *new_exclude; 1342 1343 new_exclude = ((struct string_list *) 1344 xmalloc (sizeof (struct string_list))); 1345 new_exclude->string = (char *) xmalloc (strlen (exclude_string) + 2); 1346 /* Don't add a leading underscore for fastcall symbols. */ 1347 if (*exclude_string == '@') 1348 sprintf (new_exclude->string, "%s", exclude_string); 1349 else 1350 sprintf (new_exclude->string, "_%s", exclude_string); 1351 new_exclude->next = excludes; 1352 excludes = new_exclude; 1353 1354 /* xgettext:c-format */ 1355 inform (_("Excluding symbol: %s"), exclude_string); 1356 } 1357 1358 free (local_copy); 1359 } 1360 1361 /* See if STRING is on the list of symbols to exclude. */ 1362 1363 static bfd_boolean 1364 match_exclude (const char *string) 1365 { 1366 struct string_list *excl_item; 1367 1368 for (excl_item = excludes; excl_item; excl_item = excl_item->next) 1369 if (strcmp (string, excl_item->string) == 0) 1370 return TRUE; 1371 return FALSE; 1372 } 1373 1374 /* Add the default list of symbols to exclude. */ 1375 1376 static void 1377 set_default_excludes (void) 1378 { 1379 add_excludes (default_excludes); 1380 } 1381 1382 /* Choose which symbols to export. */ 1383 1384 static long 1385 filter_symbols (bfd *abfd, void *minisyms, long symcount, unsigned int size) 1386 { 1387 bfd_byte *from, *fromend, *to; 1388 asymbol *store; 1389 1390 store = bfd_make_empty_symbol (abfd); 1391 if (store == NULL) 1392 bfd_fatal (bfd_get_filename (abfd)); 1393 1394 from = (bfd_byte *) minisyms; 1395 fromend = from + symcount * size; 1396 to = (bfd_byte *) minisyms; 1397 1398 for (; from < fromend; from += size) 1399 { 1400 int keep = 0; 1401 asymbol *sym; 1402 1403 sym = bfd_minisymbol_to_symbol (abfd, FALSE, (const void *) from, store); 1404 if (sym == NULL) 1405 bfd_fatal (bfd_get_filename (abfd)); 1406 1407 /* Check for external and defined only symbols. */ 1408 keep = (((sym->flags & BSF_GLOBAL) != 0 1409 || (sym->flags & BSF_WEAK) != 0 1410 || bfd_is_com_section (sym->section)) 1411 && ! bfd_is_und_section (sym->section)); 1412 1413 keep = keep && ! match_exclude (sym->name); 1414 1415 if (keep) 1416 { 1417 memcpy (to, from, size); 1418 to += size; 1419 } 1420 } 1421 1422 return (to - (bfd_byte *) minisyms) / size; 1423 } 1424 1425 /* Export all symbols in ABFD, except for ones we were told not to 1426 export. */ 1427 1428 static void 1429 scan_all_symbols (bfd *abfd) 1430 { 1431 long symcount; 1432 void *minisyms; 1433 unsigned int size; 1434 1435 /* Ignore bfds with an import descriptor table. We assume that any 1436 such BFD contains symbols which are exported from another DLL, 1437 and we don't want to reexport them from here. */ 1438 if (bfd_get_section_by_name (abfd, ".idata$4")) 1439 return; 1440 1441 if (! (bfd_get_file_flags (abfd) & HAS_SYMS)) 1442 { 1443 /* xgettext:c-format */ 1444 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); 1445 return; 1446 } 1447 1448 symcount = bfd_read_minisymbols (abfd, FALSE, &minisyms, &size); 1449 if (symcount < 0) 1450 bfd_fatal (bfd_get_filename (abfd)); 1451 1452 if (symcount == 0) 1453 { 1454 /* xgettext:c-format */ 1455 non_fatal (_("%s: no symbols"), bfd_get_filename (abfd)); 1456 return; 1457 } 1458 1459 /* Discard the symbols we don't want to export. It's OK to do this 1460 in place; we'll free the storage anyway. */ 1461 1462 symcount = filter_symbols (abfd, minisyms, symcount, size); 1463 scan_filtered_symbols (abfd, minisyms, symcount, size); 1464 1465 free (minisyms); 1466 } 1467 1468 /* Look at the object file to decide which symbols to export. */ 1469 1470 static void 1471 scan_open_obj_file (bfd *abfd) 1472 { 1473 if (export_all_symbols) 1474 scan_all_symbols (abfd); 1475 else 1476 scan_drectve_symbols (abfd); 1477 1478 /* FIXME: we ought to read in and block out the base relocations. */ 1479 1480 /* xgettext:c-format */ 1481 inform (_("Done reading %s"), bfd_get_filename (abfd)); 1482 } 1483 1484 static void 1485 scan_obj_file (const char *filename) 1486 { 1487 bfd * f = bfd_openr (filename, 0); 1488 1489 if (!f) 1490 /* xgettext:c-format */ 1491 fatal (_("Unable to open object file: %s"), filename); 1492 1493 /* xgettext:c-format */ 1494 inform (_("Scanning object file %s"), filename); 1495 1496 if (bfd_check_format (f, bfd_archive)) 1497 { 1498 bfd *arfile = bfd_openr_next_archived_file (f, 0); 1499 while (arfile) 1500 { 1501 if (bfd_check_format (arfile, bfd_object)) 1502 scan_open_obj_file (arfile); 1503 bfd_close (arfile); 1504 arfile = bfd_openr_next_archived_file (f, arfile); 1505 } 1506 1507 #ifdef DLLTOOL_MCORE_ELF 1508 if (mcore_elf_out_file) 1509 inform (_("Cannot produce mcore-elf dll from archive file: %s"), filename); 1510 #endif 1511 } 1512 else if (bfd_check_format (f, bfd_object)) 1513 { 1514 scan_open_obj_file (f); 1515 1516 #ifdef DLLTOOL_MCORE_ELF 1517 if (mcore_elf_out_file) 1518 mcore_elf_cache_filename ((char *) filename); 1519 #endif 1520 } 1521 1522 bfd_close (f); 1523 } 1524 1525 /**********************************************************************/ 1526 1527 static void 1528 dump_def_info (FILE *f) 1529 { 1530 int i; 1531 export_type *exp; 1532 fprintf (f, "%s ", ASM_C); 1533 for (i = 0; oav[i]; i++) 1534 fprintf (f, "%s ", oav[i]); 1535 fprintf (f, "\n"); 1536 for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 1537 { 1538 fprintf (f, "%s %d = %s %s @ %d %s%s%s%s\n", 1539 ASM_C, 1540 i, 1541 exp->name, 1542 exp->internal_name, 1543 exp->ordinal, 1544 exp->noname ? "NONAME " : "", 1545 exp->private ? "PRIVATE " : "", 1546 exp->constant ? "CONSTANT" : "", 1547 exp->data ? "DATA" : ""); 1548 } 1549 } 1550 1551 /* Generate the .exp file. */ 1552 1553 static int 1554 sfunc (const void *a, const void *b) 1555 { 1556 return *(const long *) a - *(const long *) b; 1557 } 1558 1559 static void 1560 flush_page (FILE *f, long *need, int page_addr, int on_page) 1561 { 1562 int i; 1563 1564 /* Flush this page. */ 1565 fprintf (f, "\t%s\t0x%08x\t%s Starting RVA for chunk\n", 1566 ASM_LONG, 1567 page_addr, 1568 ASM_C); 1569 fprintf (f, "\t%s\t0x%x\t%s Size of block\n", 1570 ASM_LONG, 1571 (on_page * 2) + (on_page & 1) * 2 + 8, 1572 ASM_C); 1573 1574 for (i = 0; i < on_page; i++) 1575 { 1576 long needed = need[i]; 1577 1578 if (needed) 1579 needed = ((needed - page_addr) | 0x3000) & 0xffff; 1580 1581 fprintf (f, "\t%s\t0x%lx\n", ASM_SHORT, needed); 1582 } 1583 1584 /* And padding */ 1585 if (on_page & 1) 1586 fprintf (f, "\t%s\t0x%x\n", ASM_SHORT, 0 | 0x0000); 1587 } 1588 1589 static void 1590 gen_def_file (void) 1591 { 1592 int i; 1593 export_type *exp; 1594 1595 inform (_("Adding exports to output file")); 1596 1597 fprintf (output_def, ";"); 1598 for (i = 0; oav[i]; i++) 1599 fprintf (output_def, " %s", oav[i]); 1600 1601 fprintf (output_def, "\nEXPORTS\n"); 1602 1603 for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 1604 { 1605 char *quote = strchr (exp->name, '.') ? "\"" : ""; 1606 char *res = cplus_demangle (exp->internal_name, DMGL_ANSI | DMGL_PARAMS); 1607 1608 if (res) 1609 { 1610 fprintf (output_def,";\t%s\n", res); 1611 free (res); 1612 } 1613 1614 if (strcmp (exp->name, exp->internal_name) == 0) 1615 { 1616 fprintf (output_def, "\t%s%s%s @ %d%s%s%s\n", 1617 quote, 1618 exp->name, 1619 quote, 1620 exp->ordinal, 1621 exp->noname ? " NONAME" : "", 1622 exp->private ? "PRIVATE " : "", 1623 exp->data ? " DATA" : ""); 1624 } 1625 else 1626 { 1627 char * quote1 = strchr (exp->internal_name, '.') ? "\"" : ""; 1628 /* char *alias = */ 1629 fprintf (output_def, "\t%s%s%s = %s%s%s @ %d%s%s%s\n", 1630 quote, 1631 exp->name, 1632 quote, 1633 quote1, 1634 exp->internal_name, 1635 quote1, 1636 exp->ordinal, 1637 exp->noname ? " NONAME" : "", 1638 exp->private ? "PRIVATE " : "", 1639 exp->data ? " DATA" : ""); 1640 } 1641 } 1642 1643 inform (_("Added exports to output file")); 1644 } 1645 1646 /* generate_idata_ofile generates the portable assembly source code 1647 for the idata sections. It appends the source code to the end of 1648 the file. */ 1649 1650 static void 1651 generate_idata_ofile (FILE *filvar) 1652 { 1653 iheadtype *headptr; 1654 ifunctype *funcptr; 1655 int headindex; 1656 int funcindex; 1657 int nheads; 1658 1659 if (import_list == NULL) 1660 return; 1661 1662 fprintf (filvar, "%s Import data sections\n", ASM_C); 1663 fprintf (filvar, "\n\t.section\t.idata$2\n"); 1664 fprintf (filvar, "\t%s\tdoi_idata\n", ASM_GLOBAL); 1665 fprintf (filvar, "doi_idata:\n"); 1666 1667 nheads = 0; 1668 for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1669 { 1670 fprintf (filvar, "\t%slistone%d%s\t%s %s\n", 1671 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER, 1672 ASM_C, headptr->dllname); 1673 fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1674 fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1675 fprintf (filvar, "\t%sdllname%d%s\n", 1676 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER); 1677 fprintf (filvar, "\t%slisttwo%d%s\n\n", 1678 ASM_RVA_BEFORE, nheads, ASM_RVA_AFTER); 1679 nheads++; 1680 } 1681 1682 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL record at */ 1683 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* end of idata$2 */ 1684 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* section */ 1685 fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1686 fprintf (filvar, "\t%s\t0\n", ASM_LONG); 1687 1688 fprintf (filvar, "\n\t.section\t.idata$4\n"); 1689 headindex = 0; 1690 for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1691 { 1692 fprintf (filvar, "listone%d:\n", headindex); 1693 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ ) 1694 fprintf (filvar, "\t%sfuncptr%d_%d%s\n", 1695 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER); 1696 fprintf (filvar,"\t%s\t0\n", ASM_LONG); /* NULL terminating list */ 1697 headindex++; 1698 } 1699 1700 fprintf (filvar, "\n\t.section\t.idata$5\n"); 1701 headindex = 0; 1702 for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1703 { 1704 fprintf (filvar, "listtwo%d:\n", headindex); 1705 for ( funcindex = 0; funcindex < headptr->nfuncs; funcindex++ ) 1706 fprintf (filvar, "\t%sfuncptr%d_%d%s\n", 1707 ASM_RVA_BEFORE, headindex, funcindex, ASM_RVA_AFTER); 1708 fprintf (filvar, "\t%s\t0\n", ASM_LONG); /* NULL terminating list */ 1709 headindex++; 1710 } 1711 1712 fprintf (filvar, "\n\t.section\t.idata$6\n"); 1713 headindex = 0; 1714 for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1715 { 1716 funcindex = 0; 1717 for (funcptr = headptr->funchead; funcptr != NULL; 1718 funcptr = funcptr->next) 1719 { 1720 fprintf (filvar,"funcptr%d_%d:\n", headindex, funcindex); 1721 fprintf (filvar,"\t%s\t%d\n", ASM_SHORT, 1722 ((funcptr->ord) & 0xFFFF)); 1723 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, funcptr->name); 1724 fprintf (filvar,"\t%s\t0\n", ASM_BYTE); 1725 funcindex++; 1726 } 1727 headindex++; 1728 } 1729 1730 fprintf (filvar, "\n\t.section\t.idata$7\n"); 1731 headindex = 0; 1732 for (headptr = import_list; headptr != NULL; headptr = headptr->next) 1733 { 1734 fprintf (filvar,"dllname%d:\n", headindex); 1735 fprintf (filvar,"\t%s\t\"%s\"\n", ASM_TEXT, headptr->dllname); 1736 fprintf (filvar,"\t%s\t0\n", ASM_BYTE); 1737 headindex++; 1738 } 1739 } 1740 1741 /* Assemble the specified file. */ 1742 static void 1743 assemble_file (const char * source, const char * dest) 1744 { 1745 char * cmd; 1746 1747 cmd = (char *) alloca (strlen (ASM_SWITCHES) + strlen (as_flags) 1748 + strlen (source) + strlen (dest) + 50); 1749 1750 sprintf (cmd, "%s %s -o %s %s", ASM_SWITCHES, as_flags, dest, source); 1751 1752 run (as_name, cmd); 1753 } 1754 1755 static void 1756 gen_exp_file (void) 1757 { 1758 FILE *f; 1759 int i; 1760 export_type *exp; 1761 dlist_type *dl; 1762 1763 /* xgettext:c-format */ 1764 inform (_("Generating export file: %s"), exp_name); 1765 1766 f = fopen (TMP_ASM, FOPEN_WT); 1767 if (!f) 1768 /* xgettext:c-format */ 1769 fatal (_("Unable to open temporary assembler file: %s"), TMP_ASM); 1770 1771 /* xgettext:c-format */ 1772 inform (_("Opened temporary file: %s"), TMP_ASM); 1773 1774 dump_def_info (f); 1775 1776 if (d_exports) 1777 { 1778 fprintf (f, "\t.section .edata\n\n"); 1779 fprintf (f, "\t%s 0 %s Allways 0\n", ASM_LONG, ASM_C); 1780 fprintf (f, "\t%s 0x%lx %s Time and date\n", ASM_LONG, (long) time(0), 1781 ASM_C); 1782 fprintf (f, "\t%s 0 %s Major and Minor version\n", ASM_LONG, ASM_C); 1783 fprintf (f, "\t%sname%s %s Ptr to name of dll\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1784 fprintf (f, "\t%s %d %s Starting ordinal of exports\n", ASM_LONG, d_low_ord, ASM_C); 1785 1786 1787 fprintf (f, "\t%s %d %s Number of functions\n", ASM_LONG, d_high_ord - d_low_ord + 1, ASM_C); 1788 fprintf(f,"\t%s named funcs %d, low ord %d, high ord %d\n", 1789 ASM_C, 1790 d_named_nfuncs, d_low_ord, d_high_ord); 1791 fprintf (f, "\t%s %d %s Number of names\n", ASM_LONG, 1792 show_allnames ? d_high_ord - d_low_ord + 1 : d_named_nfuncs, ASM_C); 1793 fprintf (f, "\t%safuncs%s %s Address of functions\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1794 1795 fprintf (f, "\t%sanames%s %s Address of Name Pointer Table\n", 1796 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1797 1798 fprintf (f, "\t%sanords%s %s Address of ordinals\n", ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 1799 1800 fprintf (f, "name: %s \"%s\"\n", ASM_TEXT, dll_name); 1801 1802 1803 fprintf(f,"%s Export address Table\n", ASM_C); 1804 fprintf(f,"\t%s\n", ASM_ALIGN_LONG); 1805 fprintf (f, "afuncs:\n"); 1806 i = d_low_ord; 1807 1808 for (exp = d_exports; exp; exp = exp->next) 1809 { 1810 if (exp->ordinal != i) 1811 { 1812 while (i < exp->ordinal) 1813 { 1814 fprintf(f,"\t%s\t0\n", ASM_LONG); 1815 i++; 1816 } 1817 } 1818 1819 if (exp->forward == 0) 1820 { 1821 if (exp->internal_name[0] == '@') 1822 fprintf (f, "\t%s%s%s\t%s %d\n", ASM_RVA_BEFORE, 1823 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal); 1824 else 1825 fprintf (f, "\t%s%s%s%s\t%s %d\n", ASM_RVA_BEFORE, 1826 ASM_PREFIX (exp->internal_name), 1827 exp->internal_name, ASM_RVA_AFTER, ASM_C, exp->ordinal); 1828 } 1829 else 1830 fprintf (f, "\t%sf%d%s\t%s %d\n", ASM_RVA_BEFORE, 1831 exp->forward, ASM_RVA_AFTER, ASM_C, exp->ordinal); 1832 i++; 1833 } 1834 1835 fprintf (f,"%s Export Name Pointer Table\n", ASM_C); 1836 fprintf (f, "anames:\n"); 1837 1838 for (i = 0; (exp = d_exports_lexically[i]); i++) 1839 { 1840 if (!exp->noname || show_allnames) 1841 fprintf (f, "\t%sn%d%s\n", 1842 ASM_RVA_BEFORE, exp->ordinal, ASM_RVA_AFTER); 1843 } 1844 1845 fprintf (f,"%s Export Oridinal Table\n", ASM_C); 1846 fprintf (f, "anords:\n"); 1847 for (i = 0; (exp = d_exports_lexically[i]); i++) 1848 { 1849 if (!exp->noname || show_allnames) 1850 fprintf (f, "\t%s %d\n", ASM_SHORT, exp->ordinal - d_low_ord); 1851 } 1852 1853 fprintf(f,"%s Export Name Table\n", ASM_C); 1854 for (i = 0; (exp = d_exports_lexically[i]); i++) 1855 { 1856 if (!exp->noname || show_allnames) 1857 fprintf (f, "n%d: %s \"%s\"\n", 1858 exp->ordinal, ASM_TEXT, xlate (exp->name)); 1859 if (exp->forward != 0) 1860 fprintf (f, "f%d: %s \"%s\"\n", 1861 exp->forward, ASM_TEXT, exp->internal_name); 1862 } 1863 1864 if (a_list) 1865 { 1866 fprintf (f, "\t.section %s\n", DRECTVE_SECTION_NAME); 1867 for (dl = a_list; dl; dl = dl->next) 1868 { 1869 fprintf (f, "\t%s\t\"%s\"\n", ASM_TEXT, dl->text); 1870 } 1871 } 1872 1873 if (d_list) 1874 { 1875 fprintf (f, "\t.section .rdata\n"); 1876 for (dl = d_list; dl; dl = dl->next) 1877 { 1878 char *p; 1879 int l; 1880 1881 /* We don't output as ascii because there can 1882 be quote characters in the string. */ 1883 l = 0; 1884 for (p = dl->text; *p; p++) 1885 { 1886 if (l == 0) 1887 fprintf (f, "\t%s\t", ASM_BYTE); 1888 else 1889 fprintf (f, ","); 1890 fprintf (f, "%d", *p); 1891 if (p[1] == 0) 1892 { 1893 fprintf (f, ",0\n"); 1894 break; 1895 } 1896 if (++l == 10) 1897 { 1898 fprintf (f, "\n"); 1899 l = 0; 1900 } 1901 } 1902 } 1903 } 1904 } 1905 1906 1907 /* Add to the output file a way of getting to the exported names 1908 without using the import library. */ 1909 if (add_indirect) 1910 { 1911 fprintf (f, "\t.section\t.rdata\n"); 1912 for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 1913 if (!exp->noname || show_allnames) 1914 { 1915 /* We use a single underscore for MS compatibility, and a 1916 double underscore for backward compatibility with old 1917 cygwin releases. */ 1918 if (create_compat_implib) 1919 fprintf (f, "\t%s\t__imp_%s\n", ASM_GLOBAL, exp->name); 1920 fprintf (f, "\t%s\t_imp__%s\n", ASM_GLOBAL, exp->name); 1921 if (create_compat_implib) 1922 fprintf (f, "__imp_%s:\n", exp->name); 1923 fprintf (f, "_imp__%s:\n", exp->name); 1924 fprintf (f, "\t%s\t%s\n", ASM_LONG, exp->name); 1925 } 1926 } 1927 1928 /* Dump the reloc section if a base file is provided. */ 1929 if (base_file) 1930 { 1931 int addr; 1932 long need[PAGE_SIZE]; 1933 long page_addr; 1934 int numbytes; 1935 int num_entries; 1936 long *copy; 1937 int j; 1938 int on_page; 1939 fprintf (f, "\t.section\t.init\n"); 1940 fprintf (f, "lab:\n"); 1941 1942 fseek (base_file, 0, SEEK_END); 1943 numbytes = ftell (base_file); 1944 fseek (base_file, 0, SEEK_SET); 1945 copy = xmalloc (numbytes); 1946 fread (copy, 1, numbytes, base_file); 1947 num_entries = numbytes / sizeof (long); 1948 1949 1950 fprintf (f, "\t.section\t.reloc\n"); 1951 if (num_entries) 1952 { 1953 int src; 1954 int dst = 0; 1955 int last = -1; 1956 qsort (copy, num_entries, sizeof (long), sfunc); 1957 /* Delete duplicates */ 1958 for (src = 0; src < num_entries; src++) 1959 { 1960 if (last != copy[src]) 1961 last = copy[dst++] = copy[src]; 1962 } 1963 num_entries = dst; 1964 addr = copy[0]; 1965 page_addr = addr & PAGE_MASK; /* work out the page addr */ 1966 on_page = 0; 1967 for (j = 0; j < num_entries; j++) 1968 { 1969 addr = copy[j]; 1970 if ((addr & PAGE_MASK) != page_addr) 1971 { 1972 flush_page (f, need, page_addr, on_page); 1973 on_page = 0; 1974 page_addr = addr & PAGE_MASK; 1975 } 1976 need[on_page++] = addr; 1977 } 1978 flush_page (f, need, page_addr, on_page); 1979 1980 /* fprintf (f, "\t%s\t0,0\t%s End\n", ASM_LONG, ASM_C);*/ 1981 } 1982 } 1983 1984 generate_idata_ofile (f); 1985 1986 fclose (f); 1987 1988 /* Assemble the file. */ 1989 assemble_file (TMP_ASM, exp_name); 1990 1991 if (dontdeltemps == 0) 1992 unlink (TMP_ASM); 1993 1994 inform (_("Generated exports file")); 1995 } 1996 1997 static const char * 1998 xlate (const char *name) 1999 { 2000 int lead_at = (*name == '@'); 2001 2002 if (!lead_at && (add_underscore 2003 || (add_stdcall_underscore 2004 && strchr (name, '@')))) 2005 { 2006 char *copy = xmalloc (strlen (name) + 2); 2007 2008 copy[0] = '_'; 2009 strcpy (copy + 1, name); 2010 name = copy; 2011 } 2012 2013 if (killat) 2014 { 2015 char *p; 2016 2017 name += lead_at; 2018 p = strchr (name, '@'); 2019 if (p) 2020 *p = 0; 2021 } 2022 return name; 2023 } 2024 2025 typedef struct 2026 { 2027 int id; 2028 const char *name; 2029 int flags; 2030 int align; 2031 asection *sec; 2032 asymbol *sym; 2033 asymbol **sympp; 2034 int size; 2035 unsigned char *data; 2036 } sinfo; 2037 2038 #ifndef DLLTOOL_PPC 2039 2040 #define TEXT 0 2041 #define DATA 1 2042 #define BSS 2 2043 #define IDATA7 3 2044 #define IDATA5 4 2045 #define IDATA4 5 2046 #define IDATA6 6 2047 2048 #define NSECS 7 2049 2050 #define TEXT_SEC_FLAGS \ 2051 (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_READONLY | SEC_HAS_CONTENTS) 2052 #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA) 2053 #define BSS_SEC_FLAGS SEC_ALLOC 2054 2055 #define INIT_SEC_DATA(id, name, flags, align) \ 2056 { id, name, flags, align, NULL, NULL, NULL, 0, NULL } 2057 static sinfo secdata[NSECS] = 2058 { 2059 INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), 2060 INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), 2061 INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2), 2062 INIT_SEC_DATA (IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2), 2063 INIT_SEC_DATA (IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2), 2064 INIT_SEC_DATA (IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2), 2065 INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1) 2066 }; 2067 2068 #else 2069 2070 /* Sections numbered to make the order the same as other PowerPC NT 2071 compilers. This also keeps funny alignment thingies from happening. */ 2072 #define TEXT 0 2073 #define PDATA 1 2074 #define RDATA 2 2075 #define IDATA5 3 2076 #define IDATA4 4 2077 #define IDATA6 5 2078 #define IDATA7 6 2079 #define DATA 7 2080 #define BSS 8 2081 2082 #define NSECS 9 2083 2084 static sinfo secdata[NSECS] = 2085 { 2086 { TEXT, ".text", SEC_CODE | SEC_HAS_CONTENTS, 3}, 2087 { PDATA, ".pdata", SEC_HAS_CONTENTS, 2}, 2088 { RDATA, ".reldata", SEC_HAS_CONTENTS, 2}, 2089 { IDATA5, ".idata$5", SEC_HAS_CONTENTS, 2}, 2090 { IDATA4, ".idata$4", SEC_HAS_CONTENTS, 2}, 2091 { IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1}, 2092 { IDATA7, ".idata$7", SEC_HAS_CONTENTS, 2}, 2093 { DATA, ".data", SEC_DATA, 2}, 2094 { BSS, ".bss", 0, 2} 2095 }; 2096 2097 #endif 2098 2099 /* This is what we're trying to make. We generate the imp symbols with 2100 both single and double underscores, for compatibility. 2101 2102 .text 2103 .global _GetFileVersionInfoSizeW@8 2104 .global __imp_GetFileVersionInfoSizeW@8 2105 _GetFileVersionInfoSizeW@8: 2106 jmp * __imp_GetFileVersionInfoSizeW@8 2107 .section .idata$7 # To force loading of head 2108 .long __version_a_head 2109 # Import Address Table 2110 .section .idata$5 2111 __imp_GetFileVersionInfoSizeW@8: 2112 .rva ID2 2113 2114 # Import Lookup Table 2115 .section .idata$4 2116 .rva ID2 2117 # Hint/Name table 2118 .section .idata$6 2119 ID2: .short 2 2120 .asciz "GetFileVersionInfoSizeW" 2121 2122 2123 For the PowerPC, here's the variation on the above scheme: 2124 2125 # Rather than a simple "jmp *", the code to get to the dll function 2126 # looks like: 2127 .text 2128 lwz r11,[tocv]__imp_function_name(r2) 2129 # RELOC: 00000000 TOCREL16,TOCDEFN __imp_function_name 2130 lwz r12,0(r11) 2131 stw r2,4(r1) 2132 mtctr r12 2133 lwz r2,4(r11) 2134 bctr */ 2135 2136 static char * 2137 make_label (const char *prefix, const char *name) 2138 { 2139 int len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name); 2140 char *copy = xmalloc (len + 1); 2141 2142 strcpy (copy, ASM_PREFIX (name)); 2143 strcat (copy, prefix); 2144 strcat (copy, name); 2145 return copy; 2146 } 2147 2148 static char * 2149 make_imp_label (const char *prefix, const char *name) 2150 { 2151 int len; 2152 char *copy; 2153 2154 if (name[0] == '@') 2155 { 2156 len = strlen (prefix) + strlen (name); 2157 copy = xmalloc (len + 1); 2158 strcpy (copy, prefix); 2159 strcat (copy, name); 2160 } 2161 else 2162 { 2163 len = strlen (ASM_PREFIX (name)) + strlen (prefix) + strlen (name); 2164 copy = xmalloc (len + 1); 2165 strcpy (copy, prefix); 2166 strcat (copy, ASM_PREFIX (name)); 2167 strcat (copy, name); 2168 } 2169 return copy; 2170 } 2171 2172 static bfd * 2173 make_one_lib_file (export_type *exp, int i) 2174 { 2175 bfd * abfd; 2176 asymbol * exp_label; 2177 asymbol * iname = 0; 2178 asymbol * iname2; 2179 asymbol * iname_lab; 2180 asymbol ** iname_lab_pp; 2181 asymbol ** iname_pp; 2182 #ifdef DLLTOOL_PPC 2183 asymbol ** fn_pp; 2184 asymbol ** toc_pp; 2185 #define EXTRA 2 2186 #endif 2187 #ifndef EXTRA 2188 #define EXTRA 0 2189 #endif 2190 asymbol * ptrs[NSECS + 4 + EXTRA + 1]; 2191 flagword applicable; 2192 char * outname = xmalloc (strlen (TMP_STUB) + 10); 2193 int oidx = 0; 2194 2195 2196 sprintf (outname, "%s%05d.o", TMP_STUB, i); 2197 2198 abfd = bfd_openw (outname, HOW_BFD_WRITE_TARGET); 2199 2200 if (!abfd) 2201 /* xgettext:c-format */ 2202 fatal (_("bfd_open failed open stub file: %s"), outname); 2203 2204 /* xgettext:c-format */ 2205 inform (_("Creating stub file: %s"), outname); 2206 2207 bfd_set_format (abfd, bfd_object); 2208 bfd_set_arch_mach (abfd, HOW_BFD_ARCH, 0); 2209 2210 #ifdef DLLTOOL_ARM 2211 if (machine == MARM_INTERWORK || machine == MTHUMB) 2212 bfd_set_private_flags (abfd, F_INTERWORK); 2213 #endif 2214 2215 applicable = bfd_applicable_section_flags (abfd); 2216 2217 /* First make symbols for the sections. */ 2218 for (i = 0; i < NSECS; i++) 2219 { 2220 sinfo *si = secdata + i; 2221 2222 if (si->id != i) 2223 abort(); 2224 si->sec = bfd_make_section_old_way (abfd, si->name); 2225 bfd_set_section_flags (abfd, 2226 si->sec, 2227 si->flags & applicable); 2228 2229 bfd_set_section_alignment(abfd, si->sec, si->align); 2230 si->sec->output_section = si->sec; 2231 si->sym = bfd_make_empty_symbol(abfd); 2232 si->sym->name = si->sec->name; 2233 si->sym->section = si->sec; 2234 si->sym->flags = BSF_LOCAL; 2235 si->sym->value = 0; 2236 ptrs[oidx] = si->sym; 2237 si->sympp = ptrs + oidx; 2238 si->size = 0; 2239 si->data = NULL; 2240 2241 oidx++; 2242 } 2243 2244 if (! exp->data) 2245 { 2246 exp_label = bfd_make_empty_symbol (abfd); 2247 exp_label->name = make_imp_label ("", exp->name); 2248 2249 /* On PowerPC, the function name points to a descriptor in 2250 the rdata section, the first element of which is a 2251 pointer to the code (..function_name), and the second 2252 points to the .toc. */ 2253 #ifdef DLLTOOL_PPC 2254 if (machine == MPPC) 2255 exp_label->section = secdata[RDATA].sec; 2256 else 2257 #endif 2258 exp_label->section = secdata[TEXT].sec; 2259 2260 exp_label->flags = BSF_GLOBAL; 2261 exp_label->value = 0; 2262 2263 #ifdef DLLTOOL_ARM 2264 if (machine == MTHUMB) 2265 bfd_coff_set_symbol_class (abfd, exp_label, C_THUMBEXTFUNC); 2266 #endif 2267 ptrs[oidx++] = exp_label; 2268 } 2269 2270 /* Generate imp symbols with one underscore for Microsoft 2271 compatibility, and with two underscores for backward 2272 compatibility with old versions of cygwin. */ 2273 if (create_compat_implib) 2274 { 2275 iname = bfd_make_empty_symbol (abfd); 2276 iname->name = make_imp_label ("___imp", exp->name); 2277 iname->section = secdata[IDATA5].sec; 2278 iname->flags = BSF_GLOBAL; 2279 iname->value = 0; 2280 } 2281 2282 iname2 = bfd_make_empty_symbol (abfd); 2283 iname2->name = make_imp_label ("__imp_", exp->name); 2284 iname2->section = secdata[IDATA5].sec; 2285 iname2->flags = BSF_GLOBAL; 2286 iname2->value = 0; 2287 2288 iname_lab = bfd_make_empty_symbol (abfd); 2289 2290 iname_lab->name = head_label; 2291 iname_lab->section = (asection *) &bfd_und_section; 2292 iname_lab->flags = 0; 2293 iname_lab->value = 0; 2294 2295 iname_pp = ptrs + oidx; 2296 if (create_compat_implib) 2297 ptrs[oidx++] = iname; 2298 ptrs[oidx++] = iname2; 2299 2300 iname_lab_pp = ptrs + oidx; 2301 ptrs[oidx++] = iname_lab; 2302 2303 #ifdef DLLTOOL_PPC 2304 /* The symbol referring to the code (.text). */ 2305 { 2306 asymbol *function_name; 2307 2308 function_name = bfd_make_empty_symbol(abfd); 2309 function_name->name = make_label ("..", exp->name); 2310 function_name->section = secdata[TEXT].sec; 2311 function_name->flags = BSF_GLOBAL; 2312 function_name->value = 0; 2313 2314 fn_pp = ptrs + oidx; 2315 ptrs[oidx++] = function_name; 2316 } 2317 2318 /* The .toc symbol. */ 2319 { 2320 asymbol *toc_symbol; 2321 2322 toc_symbol = bfd_make_empty_symbol (abfd); 2323 toc_symbol->name = make_label (".", "toc"); 2324 toc_symbol->section = (asection *)&bfd_und_section; 2325 toc_symbol->flags = BSF_GLOBAL; 2326 toc_symbol->value = 0; 2327 2328 toc_pp = ptrs + oidx; 2329 ptrs[oidx++] = toc_symbol; 2330 } 2331 #endif 2332 2333 ptrs[oidx] = 0; 2334 2335 for (i = 0; i < NSECS; i++) 2336 { 2337 sinfo *si = secdata + i; 2338 asection *sec = si->sec; 2339 arelent *rel; 2340 arelent **rpp; 2341 2342 switch (i) 2343 { 2344 case TEXT: 2345 if (! exp->data) 2346 { 2347 si->size = HOW_JTAB_SIZE; 2348 si->data = xmalloc (HOW_JTAB_SIZE); 2349 memcpy (si->data, HOW_JTAB, HOW_JTAB_SIZE); 2350 2351 /* add the reloc into idata$5 */ 2352 rel = xmalloc (sizeof (arelent)); 2353 2354 rpp = xmalloc (sizeof (arelent *) * 2); 2355 rpp[0] = rel; 2356 rpp[1] = 0; 2357 2358 rel->address = HOW_JTAB_ROFF; 2359 rel->addend = 0; 2360 2361 if (machine == MPPC) 2362 { 2363 rel->howto = bfd_reloc_type_lookup (abfd, 2364 BFD_RELOC_16_GOTOFF); 2365 rel->sym_ptr_ptr = iname_pp; 2366 } 2367 else 2368 { 2369 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2370 rel->sym_ptr_ptr = secdata[IDATA5].sympp; 2371 } 2372 sec->orelocation = rpp; 2373 sec->reloc_count = 1; 2374 } 2375 break; 2376 case IDATA4: 2377 case IDATA5: 2378 /* An idata$4 or idata$5 is one word long, and has an 2379 rva to idata$6. */ 2380 2381 si->data = xmalloc (4); 2382 si->size = 4; 2383 2384 if (exp->noname) 2385 { 2386 si->data[0] = exp->ordinal ; 2387 si->data[1] = exp->ordinal >> 8; 2388 si->data[2] = exp->ordinal >> 16; 2389 si->data[3] = 0x80; 2390 } 2391 else 2392 { 2393 sec->reloc_count = 1; 2394 memset (si->data, 0, si->size); 2395 rel = xmalloc (sizeof (arelent)); 2396 rpp = xmalloc (sizeof (arelent *) * 2); 2397 rpp[0] = rel; 2398 rpp[1] = 0; 2399 rel->address = 0; 2400 rel->addend = 0; 2401 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA); 2402 rel->sym_ptr_ptr = secdata[IDATA6].sympp; 2403 sec->orelocation = rpp; 2404 } 2405 2406 break; 2407 2408 case IDATA6: 2409 if (!exp->noname) 2410 { 2411 /* This used to add 1 to exp->hint. I don't know 2412 why it did that, and it does not match what I see 2413 in programs compiled with the MS tools. */ 2414 int idx = exp->hint; 2415 si->size = strlen (xlate (exp->import_name)) + 3; 2416 si->data = xmalloc (si->size); 2417 si->data[0] = idx & 0xff; 2418 si->data[1] = idx >> 8; 2419 strcpy ((char *) si->data + 2, xlate (exp->import_name)); 2420 } 2421 break; 2422 case IDATA7: 2423 si->size = 4; 2424 si->data = xmalloc (4); 2425 memset (si->data, 0, si->size); 2426 rel = xmalloc (sizeof (arelent)); 2427 rpp = xmalloc (sizeof (arelent *) * 2); 2428 rpp[0] = rel; 2429 rel->address = 0; 2430 rel->addend = 0; 2431 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_RVA); 2432 rel->sym_ptr_ptr = iname_lab_pp; 2433 sec->orelocation = rpp; 2434 sec->reloc_count = 1; 2435 break; 2436 2437 #ifdef DLLTOOL_PPC 2438 case PDATA: 2439 { 2440 /* The .pdata section is 5 words long. 2441 Think of it as: 2442 struct 2443 { 2444 bfd_vma BeginAddress, [0x00] 2445 EndAddress, [0x04] 2446 ExceptionHandler, [0x08] 2447 HandlerData, [0x0c] 2448 PrologEndAddress; [0x10] 2449 }; */ 2450 2451 /* So this pdata section setups up this as a glue linkage to 2452 a dll routine. There are a number of house keeping things 2453 we need to do: 2454 2455 1. In the name of glue trickery, the ADDR32 relocs for 0, 2456 4, and 0x10 are set to point to the same place: 2457 "..function_name". 2458 2. There is one more reloc needed in the pdata section. 2459 The actual glue instruction to restore the toc on 2460 return is saved as the offset in an IMGLUE reloc. 2461 So we need a total of four relocs for this section. 2462 2463 3. Lastly, the HandlerData field is set to 0x03, to indicate 2464 that this is a glue routine. */ 2465 arelent *imglue, *ba_rel, *ea_rel, *pea_rel; 2466 2467 /* Alignment must be set to 2**2 or you get extra stuff. */ 2468 bfd_set_section_alignment(abfd, sec, 2); 2469 2470 si->size = 4 * 5; 2471 si->data = xmalloc (si->size); 2472 memset (si->data, 0, si->size); 2473 rpp = xmalloc (sizeof (arelent *) * 5); 2474 rpp[0] = imglue = xmalloc (sizeof (arelent)); 2475 rpp[1] = ba_rel = xmalloc (sizeof (arelent)); 2476 rpp[2] = ea_rel = xmalloc (sizeof (arelent)); 2477 rpp[3] = pea_rel = xmalloc (sizeof (arelent)); 2478 rpp[4] = 0; 2479 2480 /* Stick the toc reload instruction in the glue reloc. */ 2481 bfd_put_32(abfd, ppc_glue_insn, (char *) &imglue->address); 2482 2483 imglue->addend = 0; 2484 imglue->howto = bfd_reloc_type_lookup (abfd, 2485 BFD_RELOC_32_GOTOFF); 2486 imglue->sym_ptr_ptr = fn_pp; 2487 2488 ba_rel->address = 0; 2489 ba_rel->addend = 0; 2490 ba_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2491 ba_rel->sym_ptr_ptr = fn_pp; 2492 2493 bfd_put_32 (abfd, 0x18, si->data + 0x04); 2494 ea_rel->address = 4; 2495 ea_rel->addend = 0; 2496 ea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2497 ea_rel->sym_ptr_ptr = fn_pp; 2498 2499 /* Mark it as glue. */ 2500 bfd_put_32 (abfd, 0x03, si->data + 0x0c); 2501 2502 /* Mark the prolog end address. */ 2503 bfd_put_32 (abfd, 0x0D, si->data + 0x10); 2504 pea_rel->address = 0x10; 2505 pea_rel->addend = 0; 2506 pea_rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2507 pea_rel->sym_ptr_ptr = fn_pp; 2508 2509 sec->orelocation = rpp; 2510 sec->reloc_count = 4; 2511 break; 2512 } 2513 case RDATA: 2514 /* Each external function in a PowerPC PE file has a two word 2515 descriptor consisting of: 2516 1. The address of the code. 2517 2. The address of the appropriate .toc 2518 We use relocs to build this. */ 2519 si->size = 8; 2520 si->data = xmalloc (8); 2521 memset (si->data, 0, si->size); 2522 2523 rpp = xmalloc (sizeof (arelent *) * 3); 2524 rpp[0] = rel = xmalloc (sizeof (arelent)); 2525 rpp[1] = xmalloc (sizeof (arelent)); 2526 rpp[2] = 0; 2527 2528 rel->address = 0; 2529 rel->addend = 0; 2530 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2531 rel->sym_ptr_ptr = fn_pp; 2532 2533 rel = rpp[1]; 2534 2535 rel->address = 4; 2536 rel->addend = 0; 2537 rel->howto = bfd_reloc_type_lookup (abfd, BFD_RELOC_32); 2538 rel->sym_ptr_ptr = toc_pp; 2539 2540 sec->orelocation = rpp; 2541 sec->reloc_count = 2; 2542 break; 2543 #endif /* DLLTOOL_PPC */ 2544 } 2545 } 2546 2547 { 2548 bfd_vma vma = 0; 2549 /* Size up all the sections. */ 2550 for (i = 0; i < NSECS; i++) 2551 { 2552 sinfo *si = secdata + i; 2553 2554 bfd_set_section_size (abfd, si->sec, si->size); 2555 bfd_set_section_vma (abfd, si->sec, vma); 2556 } 2557 } 2558 /* Write them out. */ 2559 for (i = 0; i < NSECS; i++) 2560 { 2561 sinfo *si = secdata + i; 2562 2563 if (i == IDATA5 && no_idata5) 2564 continue; 2565 2566 if (i == IDATA4 && no_idata4) 2567 continue; 2568 2569 bfd_set_section_contents (abfd, si->sec, 2570 si->data, 0, 2571 si->size); 2572 } 2573 2574 bfd_set_symtab (abfd, ptrs, oidx); 2575 bfd_close (abfd); 2576 abfd = bfd_openr (outname, HOW_BFD_READ_TARGET); 2577 return abfd; 2578 } 2579 2580 static bfd * 2581 make_head (void) 2582 { 2583 FILE *f = fopen (TMP_HEAD_S, FOPEN_WT); 2584 2585 if (f == NULL) 2586 { 2587 fatal (_("failed to open temporary head file: %s"), TMP_HEAD_S); 2588 return NULL; 2589 } 2590 2591 fprintf (f, "%s IMAGE_IMPORT_DESCRIPTOR\n", ASM_C); 2592 fprintf (f, "\t.section .idata$2\n"); 2593 2594 fprintf(f,"\t%s\t%s\n", ASM_GLOBAL,head_label); 2595 2596 fprintf (f, "%s:\n", head_label); 2597 2598 fprintf (f, "\t%shname%s\t%sPtr to image import by name list\n", 2599 ASM_RVA_BEFORE, ASM_RVA_AFTER, ASM_C); 2600 2601 fprintf (f, "\t%sthis should be the timestamp, but NT sometimes\n", ASM_C); 2602 fprintf (f, "\t%sdoesn't load DLLs when this is set.\n", ASM_C); 2603 fprintf (f, "\t%s\t0\t%s loaded time\n", ASM_LONG, ASM_C); 2604 fprintf (f, "\t%s\t0\t%s Forwarder chain\n", ASM_LONG, ASM_C); 2605 fprintf (f, "\t%s__%s_iname%s\t%s imported dll's name\n", 2606 ASM_RVA_BEFORE, 2607 imp_name_lab, 2608 ASM_RVA_AFTER, 2609 ASM_C); 2610 fprintf (f, "\t%sfthunk%s\t%s pointer to firstthunk\n", 2611 ASM_RVA_BEFORE, 2612 ASM_RVA_AFTER, ASM_C); 2613 2614 fprintf (f, "%sStuff for compatibility\n", ASM_C); 2615 2616 if (!no_idata5) 2617 { 2618 fprintf (f, "\t.section\t.idata$5\n"); 2619 fprintf (f, "\t%s\t0\n", ASM_LONG); 2620 fprintf (f, "fthunk:\n"); 2621 } 2622 2623 if (!no_idata4) 2624 { 2625 fprintf (f, "\t.section\t.idata$4\n"); 2626 2627 fprintf (f, "\t%s\t0\n", ASM_LONG); 2628 fprintf (f, "\t.section .idata$4\n"); 2629 fprintf (f, "hname:\n"); 2630 } 2631 2632 fclose (f); 2633 2634 assemble_file (TMP_HEAD_S, TMP_HEAD_O); 2635 2636 return bfd_openr (TMP_HEAD_O, HOW_BFD_READ_TARGET); 2637 } 2638 2639 static bfd * 2640 make_tail (void) 2641 { 2642 FILE *f = fopen (TMP_TAIL_S, FOPEN_WT); 2643 2644 if (f == NULL) 2645 { 2646 fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S); 2647 return NULL; 2648 } 2649 2650 if (!no_idata4) 2651 { 2652 fprintf (f, "\t.section .idata$4\n"); 2653 fprintf (f, "\t%s\t0\n", ASM_LONG); 2654 } 2655 2656 if (!no_idata5) 2657 { 2658 fprintf (f, "\t.section .idata$5\n"); 2659 fprintf (f, "\t%s\t0\n", ASM_LONG); 2660 } 2661 2662 #ifdef DLLTOOL_PPC 2663 /* Normally, we need to see a null descriptor built in idata$3 to 2664 act as the terminator for the list. The ideal way, I suppose, 2665 would be to mark this section as a comdat type 2 section, so 2666 only one would appear in the final .exe (if our linker supported 2667 comdat, that is) or cause it to be inserted by something else (say 2668 crt0). */ 2669 2670 fprintf (f, "\t.section .idata$3\n"); 2671 fprintf (f, "\t%s\t0\n", ASM_LONG); 2672 fprintf (f, "\t%s\t0\n", ASM_LONG); 2673 fprintf (f, "\t%s\t0\n", ASM_LONG); 2674 fprintf (f, "\t%s\t0\n", ASM_LONG); 2675 fprintf (f, "\t%s\t0\n", ASM_LONG); 2676 #endif 2677 2678 #ifdef DLLTOOL_PPC 2679 /* Other PowerPC NT compilers use idata$6 for the dllname, so I 2680 do too. Original, huh? */ 2681 fprintf (f, "\t.section .idata$6\n"); 2682 #else 2683 fprintf (f, "\t.section .idata$7\n"); 2684 #endif 2685 2686 fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab); 2687 fprintf (f, "__%s_iname:\t%s\t\"%s\"\n", 2688 imp_name_lab, ASM_TEXT, dll_name); 2689 2690 fclose (f); 2691 2692 assemble_file (TMP_TAIL_S, TMP_TAIL_O); 2693 2694 return bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET); 2695 } 2696 2697 static void 2698 gen_lib_file (void) 2699 { 2700 int i; 2701 export_type *exp; 2702 bfd *ar_head; 2703 bfd *ar_tail; 2704 bfd *outarch; 2705 bfd * head = 0; 2706 2707 unlink (imp_name); 2708 2709 outarch = bfd_openw (imp_name, HOW_BFD_WRITE_TARGET); 2710 2711 if (!outarch) 2712 /* xgettext:c-format */ 2713 fatal (_("Can't open .lib file: %s"), imp_name); 2714 2715 /* xgettext:c-format */ 2716 inform (_("Creating library file: %s"), imp_name); 2717 2718 bfd_set_format (outarch, bfd_archive); 2719 outarch->has_armap = 1; 2720 2721 /* Work out a reasonable size of things to put onto one line. */ 2722 ar_head = make_head (); 2723 ar_tail = make_tail(); 2724 2725 if (ar_head == NULL || ar_tail == NULL) 2726 return; 2727 2728 for (i = 0; (exp = d_exports_lexically[i]); i++) 2729 { 2730 bfd *n; 2731 /* Don't add PRIVATE entries to import lib. */ 2732 if (exp->private) 2733 continue; 2734 n = make_one_lib_file (exp, i); 2735 n->next = head; 2736 head = n; 2737 if (ext_prefix_alias) 2738 { 2739 export_type alias_exp; 2740 2741 assert (i < PREFIX_ALIAS_BASE); 2742 alias_exp.name = make_imp_label (ext_prefix_alias, exp->name); 2743 alias_exp.internal_name = exp->internal_name; 2744 alias_exp.import_name = exp->name; 2745 alias_exp.ordinal = exp->ordinal; 2746 alias_exp.constant = exp->constant; 2747 alias_exp.noname = exp->noname; 2748 alias_exp.private = exp->private; 2749 alias_exp.data = exp->data; 2750 alias_exp.hint = exp->hint; 2751 alias_exp.forward = exp->forward; 2752 alias_exp.next = exp->next; 2753 n = make_one_lib_file (&alias_exp, i + PREFIX_ALIAS_BASE); 2754 n->next = head; 2755 head = n; 2756 } 2757 } 2758 2759 /* Now stick them all into the archive. */ 2760 ar_head->next = head; 2761 ar_tail->next = ar_head; 2762 head = ar_tail; 2763 2764 if (! bfd_set_archive_head (outarch, head)) 2765 bfd_fatal ("bfd_set_archive_head"); 2766 2767 if (! bfd_close (outarch)) 2768 bfd_fatal (imp_name); 2769 2770 while (head != NULL) 2771 { 2772 bfd *n = head->next; 2773 bfd_close (head); 2774 head = n; 2775 } 2776 2777 /* Delete all the temp files. */ 2778 if (dontdeltemps == 0) 2779 { 2780 unlink (TMP_HEAD_O); 2781 unlink (TMP_HEAD_S); 2782 unlink (TMP_TAIL_O); 2783 unlink (TMP_TAIL_S); 2784 } 2785 2786 if (dontdeltemps < 2) 2787 { 2788 char *name; 2789 2790 name = (char *) alloca (strlen (TMP_STUB) + 10); 2791 for (i = 0; (exp = d_exports_lexically[i]); i++) 2792 { 2793 /* Don't delete non-existent stubs for PRIVATE entries. */ 2794 if (exp->private) 2795 continue; 2796 sprintf (name, "%s%05d.o", TMP_STUB, i); 2797 if (unlink (name) < 0) 2798 /* xgettext:c-format */ 2799 non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); 2800 if (ext_prefix_alias) 2801 { 2802 sprintf (name, "%s%05d.o", TMP_STUB, i + PREFIX_ALIAS_BASE); 2803 if (unlink (name) < 0) 2804 /* xgettext:c-format */ 2805 non_fatal (_("cannot delete %s: %s"), name, strerror (errno)); 2806 } 2807 } 2808 } 2809 2810 inform (_("Created lib file")); 2811 } 2812 2813 /* Run through the information gathered from the .o files and the 2814 .def file and work out the best stuff. */ 2815 2816 static int 2817 pfunc (const void *a, const void *b) 2818 { 2819 export_type *ap = *(export_type **) a; 2820 export_type *bp = *(export_type **) b; 2821 if (ap->ordinal == bp->ordinal) 2822 return 0; 2823 2824 /* Unset ordinals go to the bottom. */ 2825 if (ap->ordinal == -1) 2826 return 1; 2827 if (bp->ordinal == -1) 2828 return -1; 2829 return (ap->ordinal - bp->ordinal); 2830 } 2831 2832 static int 2833 nfunc (const void *a, const void *b) 2834 { 2835 export_type *ap = *(export_type **) a; 2836 export_type *bp = *(export_type **) b; 2837 const char *an = ap->name; 2838 const char *bn = bp->name; 2839 2840 if (killat) 2841 { 2842 an = (an[0] == '@') ? an + 1 : an; 2843 bn = (bn[0] == '@') ? bn + 1 : bn; 2844 } 2845 2846 return (strcmp (an, bn)); 2847 } 2848 2849 static void 2850 remove_null_names (export_type **ptr) 2851 { 2852 int src; 2853 int dst; 2854 2855 for (dst = src = 0; src < d_nfuncs; src++) 2856 { 2857 if (ptr[src]) 2858 { 2859 ptr[dst] = ptr[src]; 2860 dst++; 2861 } 2862 } 2863 d_nfuncs = dst; 2864 } 2865 2866 static void 2867 process_duplicates (export_type **d_export_vec) 2868 { 2869 int more = 1; 2870 int i; 2871 2872 while (more) 2873 { 2874 more = 0; 2875 /* Remove duplicates. */ 2876 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), nfunc); 2877 2878 for (i = 0; i < d_nfuncs - 1; i++) 2879 { 2880 if (strcmp (d_export_vec[i]->name, 2881 d_export_vec[i + 1]->name) == 0) 2882 { 2883 export_type *a = d_export_vec[i]; 2884 export_type *b = d_export_vec[i + 1]; 2885 2886 more = 1; 2887 2888 /* xgettext:c-format */ 2889 inform (_("Warning, ignoring duplicate EXPORT %s %d,%d"), 2890 a->name, a->ordinal, b->ordinal); 2891 2892 if (a->ordinal != -1 2893 && b->ordinal != -1) 2894 /* xgettext:c-format */ 2895 fatal (_("Error, duplicate EXPORT with oridinals: %s"), 2896 a->name); 2897 2898 /* Merge attributes. */ 2899 b->ordinal = a->ordinal > 0 ? a->ordinal : b->ordinal; 2900 b->constant |= a->constant; 2901 b->noname |= a->noname; 2902 b->data |= a->data; 2903 d_export_vec[i] = 0; 2904 } 2905 2906 remove_null_names (d_export_vec); 2907 } 2908 } 2909 2910 /* Count the names. */ 2911 for (i = 0; i < d_nfuncs; i++) 2912 if (!d_export_vec[i]->noname) 2913 d_named_nfuncs++; 2914 } 2915 2916 static void 2917 fill_ordinals (export_type **d_export_vec) 2918 { 2919 int lowest = -1; 2920 int i; 2921 char *ptr; 2922 int size = 65536; 2923 2924 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc); 2925 2926 /* Fill in the unset ordinals with ones from our range. */ 2927 ptr = (char *) xmalloc (size); 2928 2929 memset (ptr, 0, size); 2930 2931 /* Mark in our large vector all the numbers that are taken. */ 2932 for (i = 0; i < d_nfuncs; i++) 2933 { 2934 if (d_export_vec[i]->ordinal != -1) 2935 { 2936 ptr[d_export_vec[i]->ordinal] = 1; 2937 2938 if (lowest == -1 || d_export_vec[i]->ordinal < lowest) 2939 lowest = d_export_vec[i]->ordinal; 2940 } 2941 } 2942 2943 /* Start at 1 for compatibility with MS toolchain. */ 2944 if (lowest == -1) 2945 lowest = 1; 2946 2947 /* Now fill in ordinals where the user wants us to choose. */ 2948 for (i = 0; i < d_nfuncs; i++) 2949 { 2950 if (d_export_vec[i]->ordinal == -1) 2951 { 2952 int j; 2953 2954 /* First try within or after any user supplied range. */ 2955 for (j = lowest; j < size; j++) 2956 if (ptr[j] == 0) 2957 { 2958 ptr[j] = 1; 2959 d_export_vec[i]->ordinal = j; 2960 goto done; 2961 } 2962 2963 /* Then try before the range. */ 2964 for (j = lowest; j >0; j--) 2965 if (ptr[j] == 0) 2966 { 2967 ptr[j] = 1; 2968 d_export_vec[i]->ordinal = j; 2969 goto done; 2970 } 2971 done:; 2972 } 2973 } 2974 2975 free (ptr); 2976 2977 /* And resort. */ 2978 qsort (d_export_vec, d_nfuncs, sizeof (export_type *), pfunc); 2979 2980 /* Work out the lowest and highest ordinal numbers. */ 2981 if (d_nfuncs) 2982 { 2983 if (d_export_vec[0]) 2984 d_low_ord = d_export_vec[0]->ordinal; 2985 if (d_export_vec[d_nfuncs-1]) 2986 d_high_ord = d_export_vec[d_nfuncs-1]->ordinal; 2987 } 2988 } 2989 2990 static void 2991 mangle_defs (void) 2992 { 2993 /* First work out the minimum ordinal chosen. */ 2994 export_type *exp; 2995 2996 int i; 2997 int hint = 0; 2998 export_type **d_export_vec = xmalloc (sizeof (export_type *) * d_nfuncs); 2999 3000 inform (_("Processing definitions")); 3001 3002 for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 3003 d_export_vec[i] = exp; 3004 3005 process_duplicates (d_export_vec); 3006 fill_ordinals (d_export_vec); 3007 3008 /* Put back the list in the new order. */ 3009 d_exports = 0; 3010 for (i = d_nfuncs - 1; i >= 0; i--) 3011 { 3012 d_export_vec[i]->next = d_exports; 3013 d_exports = d_export_vec[i]; 3014 } 3015 3016 /* Build list in alpha order. */ 3017 d_exports_lexically = (export_type **) 3018 xmalloc (sizeof (export_type *) * (d_nfuncs + 1)); 3019 3020 for (i = 0, exp = d_exports; exp; i++, exp = exp->next) 3021 d_exports_lexically[i] = exp; 3022 3023 d_exports_lexically[i] = 0; 3024 3025 qsort (d_exports_lexically, i, sizeof (export_type *), nfunc); 3026 3027 /* Fill exp entries with their hint values. */ 3028 for (i = 0; i < d_nfuncs; i++) 3029 if (!d_exports_lexically[i]->noname || show_allnames) 3030 d_exports_lexically[i]->hint = hint++; 3031 3032 inform (_("Processed definitions")); 3033 } 3034 3035 static void 3036 usage (FILE *file, int status) 3037 { 3038 /* xgetext:c-format */ 3039 fprintf (file, _("Usage %s <option(s)> <object-file(s)>\n"), program_name); 3040 /* xgetext:c-format */ 3041 fprintf (file, _(" -m --machine <machine> Create as DLL for <machine>. [default: %s]\n"), mname); 3042 fprintf (file, _(" possible <machine>: arm[_interwork], i386, mcore[-elf]{-le|-be}, ppc, thumb\n")); 3043 fprintf (file, _(" -e --output-exp <outname> Generate an export file.\n")); 3044 fprintf (file, _(" -l --output-lib <outname> Generate an interface library.\n")); 3045 fprintf (file, _(" -a --add-indirect Add dll indirects to export file.\n")); 3046 fprintf (file, _(" -D --dllname <name> Name of input dll to put into interface lib.\n")); 3047 fprintf (file, _(" -d --input-def <deffile> Name of .def file to be read in.\n")); 3048 fprintf (file, _(" -z --output-def <deffile> Name of .def file to be created.\n")); 3049 fprintf (file, _(" --export-all-symbols Export all symbols to .def\n")); 3050 fprintf (file, _(" --no-export-all-symbols Only export listed symbols\n")); 3051 fprintf (file, _(" --exclude-symbols <list> Don't export <list>\n")); 3052 fprintf (file, _(" --no-default-excludes Clear default exclude symbols\n")); 3053 fprintf (file, _(" -b --base-file <basefile> Read linker generated base file.\n")); 3054 fprintf (file, _(" -x --no-idata4 Don't generate idata$4 section.\n")); 3055 fprintf (file, _(" -c --no-idata5 Don't generate idata$5 section.\n")); 3056 fprintf (file, _(" -U --add-underscore Add underscores to all symbols in interface library.\n")); 3057 fprintf (file, _(" --add-stdcall-underscore Add underscores to stdcall symbols in interface library.\n")); 3058 fprintf (file, _(" -k --kill-at Kill @<n> from exported names.\n")); 3059 fprintf (file, _(" -A --add-stdcall-alias Add aliases without @<n>.\n")); 3060 fprintf (file, _(" -p --ext-prefix-alias <prefix> Add aliases with <prefix>.\n")); 3061 fprintf (file, _(" -S --as <name> Use <name> for assembler.\n")); 3062 fprintf (file, _(" -f --as-flags <flags> Pass <flags> to the assembler.\n")); 3063 fprintf (file, _(" -C --compat-implib Create backward compatible import library.\n")); 3064 fprintf (file, _(" -n --no-delete Keep temp files (repeat for extra preservation).\n")); 3065 fprintf (file, _(" -t --temp-prefix <prefix> Use <prefix> to construct temp file names.\n")); 3066 fprintf (file, _(" -v --verbose Be verbose.\n")); 3067 fprintf (file, _(" -V --version Display the program version.\n")); 3068 fprintf (file, _(" -h --help Display this information.\n")); 3069 fprintf (file, _(" @<file> Read options from <file>.\n")); 3070 #ifdef DLLTOOL_MCORE_ELF 3071 fprintf (file, _(" -M --mcore-elf <outname> Process mcore-elf object files into <outname>.\n")); 3072 fprintf (file, _(" -L --linker <name> Use <name> as the linker.\n")); 3073 fprintf (file, _(" -F --linker-flags <flags> Pass <flags> to the linker.\n")); 3074 #endif 3075 exit (status); 3076 } 3077 3078 #define OPTION_EXPORT_ALL_SYMS 150 3079 #define OPTION_NO_EXPORT_ALL_SYMS (OPTION_EXPORT_ALL_SYMS + 1) 3080 #define OPTION_EXCLUDE_SYMS (OPTION_NO_EXPORT_ALL_SYMS + 1) 3081 #define OPTION_NO_DEFAULT_EXCLUDES (OPTION_EXCLUDE_SYMS + 1) 3082 #define OPTION_ADD_STDCALL_UNDERSCORE (OPTION_NO_DEFAULT_EXCLUDES + 1) 3083 3084 static const struct option long_options[] = 3085 { 3086 {"no-delete", no_argument, NULL, 'n'}, 3087 {"dllname", required_argument, NULL, 'D'}, 3088 {"no-idata4", no_argument, NULL, 'x'}, 3089 {"no-idata5", no_argument, NULL, 'c'}, 3090 {"output-exp", required_argument, NULL, 'e'}, 3091 {"output-def", required_argument, NULL, 'z'}, 3092 {"export-all-symbols", no_argument, NULL, OPTION_EXPORT_ALL_SYMS}, 3093 {"no-export-all-symbols", no_argument, NULL, OPTION_NO_EXPORT_ALL_SYMS}, 3094 {"exclude-symbols", required_argument, NULL, OPTION_EXCLUDE_SYMS}, 3095 {"no-default-excludes", no_argument, NULL, OPTION_NO_DEFAULT_EXCLUDES}, 3096 {"output-lib", required_argument, NULL, 'l'}, 3097 {"def", required_argument, NULL, 'd'}, /* for compatibility with older versions */ 3098 {"input-def", required_argument, NULL, 'd'}, 3099 {"add-underscore", no_argument, NULL, 'U'}, 3100 {"add-stdcall-underscore", no_argument, NULL, OPTION_ADD_STDCALL_UNDERSCORE}, 3101 {"kill-at", no_argument, NULL, 'k'}, 3102 {"add-stdcall-alias", no_argument, NULL, 'A'}, 3103 {"ext-prefix-alias", required_argument, NULL, 'p'}, 3104 {"verbose", no_argument, NULL, 'v'}, 3105 {"version", no_argument, NULL, 'V'}, 3106 {"help", no_argument, NULL, 'h'}, 3107 {"machine", required_argument, NULL, 'm'}, 3108 {"add-indirect", no_argument, NULL, 'a'}, 3109 {"base-file", required_argument, NULL, 'b'}, 3110 {"as", required_argument, NULL, 'S'}, 3111 {"as-flags", required_argument, NULL, 'f'}, 3112 {"mcore-elf", required_argument, NULL, 'M'}, 3113 {"compat-implib", no_argument, NULL, 'C'}, 3114 {"temp-prefix", required_argument, NULL, 't'}, 3115 {NULL,0,NULL,0} 3116 }; 3117 3118 int main (int, char **); 3119 3120 int 3121 main (int ac, char **av) 3122 { 3123 int c; 3124 int i; 3125 char *firstarg = 0; 3126 program_name = av[0]; 3127 oav = av; 3128 3129 #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) 3130 setlocale (LC_MESSAGES, ""); 3131 #endif 3132 #if defined (HAVE_SETLOCALE) 3133 setlocale (LC_CTYPE, ""); 3134 #endif 3135 bindtextdomain (PACKAGE, LOCALEDIR); 3136 textdomain (PACKAGE); 3137 3138 expandargv (&ac, &av); 3139 3140 while ((c = getopt_long (ac, av, 3141 #ifdef DLLTOOL_MCORE_ELF 3142 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHhM:L:F:", 3143 #else 3144 "m:e:l:aD:d:z:b:xp:cCuUkAS:f:nvVHh", 3145 #endif 3146 long_options, 0)) 3147 != EOF) 3148 { 3149 switch (c) 3150 { 3151 case OPTION_EXPORT_ALL_SYMS: 3152 export_all_symbols = TRUE; 3153 break; 3154 case OPTION_NO_EXPORT_ALL_SYMS: 3155 export_all_symbols = FALSE; 3156 break; 3157 case OPTION_EXCLUDE_SYMS: 3158 add_excludes (optarg); 3159 break; 3160 case OPTION_NO_DEFAULT_EXCLUDES: 3161 do_default_excludes = FALSE; 3162 break; 3163 case OPTION_ADD_STDCALL_UNDERSCORE: 3164 add_stdcall_underscore = 1; 3165 break; 3166 case 'x': 3167 no_idata4 = 1; 3168 break; 3169 case 'c': 3170 no_idata5 = 1; 3171 break; 3172 case 'S': 3173 as_name = optarg; 3174 break; 3175 case 't': 3176 tmp_prefix = optarg; 3177 break; 3178 case 'f': 3179 as_flags = optarg; 3180 break; 3181 3182 /* Ignored for compatibility. */ 3183 case 'u': 3184 break; 3185 case 'a': 3186 add_indirect = 1; 3187 break; 3188 case 'z': 3189 output_def = fopen (optarg, FOPEN_WT); 3190 break; 3191 case 'D': 3192 dll_name = (char*) lbasename (optarg); 3193 if (dll_name != optarg) 3194 non_fatal (_("Path components stripped from dllname, '%s'."), 3195 optarg); 3196 break; 3197 case 'l': 3198 imp_name = optarg; 3199 break; 3200 case 'e': 3201 exp_name = optarg; 3202 break; 3203 case 'H': 3204 case 'h': 3205 usage (stdout, 0); 3206 break; 3207 case 'm': 3208 mname = optarg; 3209 break; 3210 case 'v': 3211 verbose = 1; 3212 break; 3213 case 'V': 3214 print_version (program_name); 3215 break; 3216 case 'U': 3217 add_underscore = 1; 3218 break; 3219 case 'k': 3220 killat = 1; 3221 break; 3222 case 'A': 3223 add_stdcall_alias = 1; 3224 break; 3225 case 'p': 3226 ext_prefix_alias = optarg; 3227 break; 3228 case 'd': 3229 def_file = optarg; 3230 break; 3231 case 'n': 3232 dontdeltemps++; 3233 break; 3234 case 'b': 3235 base_file = fopen (optarg, FOPEN_RB); 3236 3237 if (!base_file) 3238 /* xgettext:c-format */ 3239 fatal (_("Unable to open base-file: %s"), optarg); 3240 3241 break; 3242 #ifdef DLLTOOL_MCORE_ELF 3243 case 'M': 3244 mcore_elf_out_file = optarg; 3245 break; 3246 case 'L': 3247 mcore_elf_linker = optarg; 3248 break; 3249 case 'F': 3250 mcore_elf_linker_flags = optarg; 3251 break; 3252 #endif 3253 case 'C': 3254 create_compat_implib = 1; 3255 break; 3256 default: 3257 usage (stderr, 1); 3258 break; 3259 } 3260 } 3261 3262 if (!tmp_prefix) 3263 tmp_prefix = prefix_encode ("d", getpid ()); 3264 3265 for (i = 0; mtable[i].type; i++) 3266 if (strcmp (mtable[i].type, mname) == 0) 3267 break; 3268 3269 if (!mtable[i].type) 3270 /* xgettext:c-format */ 3271 fatal (_("Machine '%s' not supported"), mname); 3272 3273 machine = i; 3274 3275 if (!dll_name && exp_name) 3276 { 3277 /* If we are inferring dll_name from exp_name, 3278 strip off any path components, without emitting 3279 a warning. */ 3280 const char* exp_basename = lbasename (exp_name); 3281 const int len = strlen (exp_basename) + 5; 3282 dll_name = xmalloc (len); 3283 strcpy (dll_name, exp_basename); 3284 strcat (dll_name, ".dll"); 3285 } 3286 3287 if (as_name == NULL) 3288 as_name = deduce_name ("as"); 3289 3290 /* Don't use the default exclude list if we're reading only the 3291 symbols in the .drectve section. The default excludes are meant 3292 to avoid exporting DLL entry point and Cygwin32 impure_ptr. */ 3293 if (! export_all_symbols) 3294 do_default_excludes = FALSE; 3295 3296 if (do_default_excludes) 3297 set_default_excludes (); 3298 3299 if (def_file) 3300 process_def_file (def_file); 3301 3302 while (optind < ac) 3303 { 3304 if (!firstarg) 3305 firstarg = av[optind]; 3306 scan_obj_file (av[optind]); 3307 optind++; 3308 } 3309 3310 mangle_defs (); 3311 3312 if (exp_name) 3313 gen_exp_file (); 3314 3315 if (imp_name) 3316 { 3317 /* Make imp_name safe for use as a label. */ 3318 char *p; 3319 3320 imp_name_lab = xstrdup (imp_name); 3321 for (p = imp_name_lab; *p; p++) 3322 { 3323 if (!ISALNUM (*p)) 3324 *p = '_'; 3325 } 3326 head_label = make_label("_head_", imp_name_lab); 3327 gen_lib_file (); 3328 } 3329 3330 if (output_def) 3331 gen_def_file (); 3332 3333 #ifdef DLLTOOL_MCORE_ELF 3334 if (mcore_elf_out_file) 3335 mcore_elf_gen_out_file (); 3336 #endif 3337 3338 return 0; 3339 } 3340 3341 /* Look for the program formed by concatenating PROG_NAME and the 3342 string running from PREFIX to END_PREFIX. If the concatenated 3343 string contains a '/', try appending EXECUTABLE_SUFFIX if it is 3344 appropriate. */ 3345 3346 static char * 3347 look_for_prog (const char *prog_name, const char *prefix, int end_prefix) 3348 { 3349 struct stat s; 3350 char *cmd; 3351 3352 cmd = xmalloc (strlen (prefix) 3353 + strlen (prog_name) 3354 #ifdef HAVE_EXECUTABLE_SUFFIX 3355 + strlen (EXECUTABLE_SUFFIX) 3356 #endif 3357 + 10); 3358 strcpy (cmd, prefix); 3359 3360 sprintf (cmd + end_prefix, "%s", prog_name); 3361 3362 if (strchr (cmd, '/') != NULL) 3363 { 3364 int found; 3365 3366 found = (stat (cmd, &s) == 0 3367 #ifdef HAVE_EXECUTABLE_SUFFIX 3368 || stat (strcat (cmd, EXECUTABLE_SUFFIX), &s) == 0 3369 #endif 3370 ); 3371 3372 if (! found) 3373 { 3374 /* xgettext:c-format */ 3375 inform (_("Tried file: %s"), cmd); 3376 free (cmd); 3377 return NULL; 3378 } 3379 } 3380 3381 /* xgettext:c-format */ 3382 inform (_("Using file: %s"), cmd); 3383 3384 return cmd; 3385 } 3386 3387 /* Deduce the name of the program we are want to invoke. 3388 PROG_NAME is the basic name of the program we want to run, 3389 eg "as" or "ld". The catch is that we might want actually 3390 run "i386-pe-as" or "ppc-pe-ld". 3391 3392 If argv[0] contains the full path, then try to find the program 3393 in the same place, with and then without a target-like prefix. 3394 3395 Given, argv[0] = /usr/local/bin/i586-cygwin32-dlltool, 3396 deduce_name("as") uses the following search order: 3397 3398 /usr/local/bin/i586-cygwin32-as 3399 /usr/local/bin/as 3400 as 3401 3402 If there's an EXECUTABLE_SUFFIX, it'll use that as well; for each 3403 name, it'll try without and then with EXECUTABLE_SUFFIX. 3404 3405 Given, argv[0] = i586-cygwin32-dlltool, it will not even try "as" 3406 as the fallback, but rather return i586-cygwin32-as. 3407 3408 Oh, and given, argv[0] = dlltool, it'll return "as". 3409 3410 Returns a dynamically allocated string. */ 3411 3412 static char * 3413 deduce_name (const char *prog_name) 3414 { 3415 char *cmd; 3416 char *dash, *slash, *cp; 3417 3418 dash = NULL; 3419 slash = NULL; 3420 for (cp = program_name; *cp != '\0'; ++cp) 3421 { 3422 if (*cp == '-') 3423 dash = cp; 3424 if ( 3425 #if defined(__DJGPP__) || defined (__CYGWIN__) || defined(__WIN32__) 3426 *cp == ':' || *cp == '\\' || 3427 #endif 3428 *cp == '/') 3429 { 3430 slash = cp; 3431 dash = NULL; 3432 } 3433 } 3434 3435 cmd = NULL; 3436 3437 if (dash != NULL) 3438 { 3439 /* First, try looking for a prefixed PROG_NAME in the 3440 PROGRAM_NAME directory, with the same prefix as PROGRAM_NAME. */ 3441 cmd = look_for_prog (prog_name, program_name, dash - program_name + 1); 3442 } 3443 3444 if (slash != NULL && cmd == NULL) 3445 { 3446 /* Next, try looking for a PROG_NAME in the same directory as 3447 that of this program. */ 3448 cmd = look_for_prog (prog_name, program_name, slash - program_name + 1); 3449 } 3450 3451 if (cmd == NULL) 3452 { 3453 /* Just return PROG_NAME as is. */ 3454 cmd = xstrdup (prog_name); 3455 } 3456 3457 return cmd; 3458 } 3459 3460 #ifdef DLLTOOL_MCORE_ELF 3461 typedef struct fname_cache 3462 { 3463 char * filename; 3464 struct fname_cache * next; 3465 } 3466 fname_cache; 3467 3468 static fname_cache fnames; 3469 3470 static void 3471 mcore_elf_cache_filename (char * filename) 3472 { 3473 fname_cache * ptr; 3474 3475 ptr = & fnames; 3476 3477 while (ptr->next != NULL) 3478 ptr = ptr->next; 3479 3480 ptr->filename = filename; 3481 ptr->next = (fname_cache *) malloc (sizeof (fname_cache)); 3482 if (ptr->next != NULL) 3483 ptr->next->next = NULL; 3484 } 3485 3486 #define MCORE_ELF_TMP_OBJ "mcoreelf.o" 3487 #define MCORE_ELF_TMP_EXP "mcoreelf.exp" 3488 #define MCORE_ELF_TMP_LIB "mcoreelf.lib" 3489 3490 static void 3491 mcore_elf_gen_out_file (void) 3492 { 3493 fname_cache * ptr; 3494 dyn_string_t ds; 3495 3496 /* Step one. Run 'ld -r' on the input object files in order to resolve 3497 any internal references and to generate a single .exports section. */ 3498 ptr = & fnames; 3499 3500 ds = dyn_string_new (100); 3501 dyn_string_append_cstr (ds, "-r "); 3502 3503 if (mcore_elf_linker_flags != NULL) 3504 dyn_string_append_cstr (ds, mcore_elf_linker_flags); 3505 3506 while (ptr->next != NULL) 3507 { 3508 dyn_string_append_cstr (ds, ptr->filename); 3509 dyn_string_append_cstr (ds, " "); 3510 3511 ptr = ptr->next; 3512 } 3513 3514 dyn_string_append_cstr (ds, "-o "); 3515 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ); 3516 3517 if (mcore_elf_linker == NULL) 3518 mcore_elf_linker = deduce_name ("ld"); 3519 3520 run (mcore_elf_linker, ds->s); 3521 3522 dyn_string_delete (ds); 3523 3524 /* Step two. Create a .exp file and a .lib file from the temporary file. 3525 Do this by recursively invoking dlltool... */ 3526 ds = dyn_string_new (100); 3527 3528 dyn_string_append_cstr (ds, "-S "); 3529 dyn_string_append_cstr (ds, as_name); 3530 3531 dyn_string_append_cstr (ds, " -e "); 3532 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP); 3533 dyn_string_append_cstr (ds, " -l "); 3534 dyn_string_append_cstr (ds, MCORE_ELF_TMP_LIB); 3535 dyn_string_append_cstr (ds, " " ); 3536 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ); 3537 3538 if (verbose) 3539 dyn_string_append_cstr (ds, " -v"); 3540 3541 if (dontdeltemps) 3542 { 3543 dyn_string_append_cstr (ds, " -n"); 3544 3545 if (dontdeltemps > 1) 3546 dyn_string_append_cstr (ds, " -n"); 3547 } 3548 3549 /* XXX - FIME: ought to check/copy other command line options as well. */ 3550 run (program_name, ds->s); 3551 3552 dyn_string_delete (ds); 3553 3554 /* Step four. Feed the .exp and object files to ld -shared to create the dll. */ 3555 ds = dyn_string_new (100); 3556 3557 dyn_string_append_cstr (ds, "-shared "); 3558 3559 if (mcore_elf_linker_flags) 3560 dyn_string_append_cstr (ds, mcore_elf_linker_flags); 3561 3562 dyn_string_append_cstr (ds, " "); 3563 dyn_string_append_cstr (ds, MCORE_ELF_TMP_EXP); 3564 dyn_string_append_cstr (ds, " "); 3565 dyn_string_append_cstr (ds, MCORE_ELF_TMP_OBJ); 3566 dyn_string_append_cstr (ds, " -o "); 3567 dyn_string_append_cstr (ds, mcore_elf_out_file); 3568 3569 run (mcore_elf_linker, ds->s); 3570 3571 dyn_string_delete (ds); 3572 3573 if (dontdeltemps == 0) 3574 unlink (MCORE_ELF_TMP_EXP); 3575 3576 if (dontdeltemps < 2) 3577 unlink (MCORE_ELF_TMP_OBJ); 3578 } 3579 #endif /* DLLTOOL_MCORE_ELF */ 3580