?? dlltool.c
字號:
/* dlltool.c -- tool to generate stuff for PE style DLLs Copyright 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. This file is part of GNU Binutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* This program allows you to build the files necessary to create DLLs to run on a system which understands PE format image files. (eg, Windows NT) See "Peering Inside the PE: A Tour of the Win32 Portable Executable File Format", MSJ 1994, Volume 9 for more information. Also see "Microsoft Portable Executable and Common Object File Format, Specification 4.1" for more information. A DLL contains an export table which contains the information which the runtime loader needs to tie up references from a referencing program. The export table is generated by this program by reading in a .DEF file or scanning the .a and .o files which will be in the DLL. A .o file can contain information in special ".drectve" sections with export information. A DEF file contains any number of the following commands: NAME <name> [ , <base> ] The result is going to be <name>.EXE LIBRARY <name> [ , <base> ] The result is going to be <name>.DLL EXPORTS ( <name1> [ = <name2> ] [ @ <integer> ] [ NONAME ] [CONSTANT] [DATA] ) * Declares name1 as an exported symbol from the DLL, with optional ordinal number <integer> IMPORTS ( ( <internal-name> = <module-name> . <integer> ) | ( [ <internal-name> = ] <module-name> . <external-name> )) * Declares that <external-name> or the exported function whoes ordinal number is <integer> is to be imported from the file <module-name>. If <internal-name> is specified then this is the name that the imported function will be refered to in the body of the DLL. DESCRIPTION <string> Puts <string> into output .exp file in the .rdata section [STACKSIZE|HEAPSIZE] <number-reserve> [ , <number-commit> ] Generates --stack|--heap <number-reserve>,<number-commit> in the output .drectve section. The linker will see this and act upon it. [CODE|DATA] <attr>+ SECTIONS ( <sectionname> <attr>+ )* <attr> = READ | WRITE | EXECUTE | SHARED Generates --attr <sectionname> <attr> in the output .drectve section. The linker will see this and act upon it. A -export:<name> in a .drectve section in an input .o or .a file to this program is equivalent to a EXPORTS <name> in a .DEF file. The program generates output files with the prefix supplied on the command line, or in the def file, or taken from the first supplied argument. The .exp.s file contains the information necessary to export the routines in the DLL. The .lib.s file contains the information necessary to use the DLL's routines from a referencing program. Example: file1.c: asm (".section .drectve"); asm (".ascii \"-export:adef\""); void adef (char * s) { printf ("hello from the dll %s\n", s); } void bdef (char * s) { printf ("hello from the dll and the other entry point %s\n", s); } file2.c: asm (".section .drectve"); asm (".ascii \"-export:cdef\""); asm (".ascii \"-export:ddef\""); void cdef (char * s) { printf ("hello from the dll %s\n", s); } void ddef (char * s) { printf ("hello from the dll and the other entry point %s\n", s); } int printf (void) { return 9; } themain.c: int main (void) { cdef (); return 0; } thedll.def LIBRARY thedll HEAPSIZE 0x40000, 0x2000 EXPORTS bdef @ 20 cdef @ 30 NONAME SECTIONS donkey READ WRITE aardvark EXECUTE # Compile up the parts of the dll and the program gcc -c file1.c file2.c themain.c # Optional: put the dll objects into a library # (you don't have to, you could name all the object # files on the dlltool line) ar qcv thedll.in file1.o file2.o ranlib thedll.in # Run this tool over the DLL's .def file and generate an exports # file (thedll.o) and an imports file (thedll.a). # (You may have to use -S to tell dlltool where to find the assembler). dlltool --def thedll.def --output-exp thedll.o --output-lib thedll.a # Build the dll with the library and the export table ld -o thedll.dll thedll.o thedll.in # Link the executable with the import library gcc -o themain.exe themain.o thedll.a This example can be extended if relocations are needed in the DLL: # Compile up the parts of the dll and the program gcc -c file1.c file2.c themain.c # Run this tool over the DLL's .def file and generate an imports file. dlltool --def thedll.def --output-lib thedll.lib # Link the executable with the import library and generate a base file # at the same time gcc -o themain.exe themain.o thedll.lib -Wl,--base-file -Wl,themain.base # Run this tool over the DLL's .def file and generate an exports file # which includes the relocations from the base file. dlltool --def thedll.def --base-file themain.base --output-exp thedll.exp # Build the dll with file1.o, file2.o and the export table ld -o thedll.dll thedll.exp file1.o file2.o *//* .idata section description The .idata section is the import table. It is a collection of several subsections used to keep the pieces for each dll together: .idata$[234567]. IE: Each dll's .idata$2's are catenated together, each .idata$3's, etc. .idata$2 = Import Directory Table = array of IMAGE_IMPORT_DESCRIPTOR's. DWORD Import Lookup Table; - pointer to .idata$4 DWORD TimeDateStamp; - currently always 0 DWORD ForwarderChain; - currently always 0 DWORD Name; - pointer to dll's name PIMAGE_THUNK_DATA FirstThunk; - pointer to .idata$5 .idata$3 = null terminating entry for .idata$2. .idata$4 = Import Lookup Table = array of array of pointers to hint name table. There is one for each dll being imported from, and each dll's set is terminated by a trailing NULL. .idata$5 = Import Address Table = array of array of pointers to hint name table. There is one for each dll being imported from, and each dll's set is terminated by a trailing NULL. Initially, this table is identical to the Import Lookup Table. However, at load time, the loader overwrites the entries with the address of the function. .idata$6 = Hint Name Table = Array of { short, asciz } entries, one for each imported function. The `short' is the function's ordinal number. .idata$7 = dll name (eg: "kernel32.dll"). (.idata$6 for ppc)*//* AIX requires this to be the first thing in the file. */#ifndef __GNUC__# ifdef _AIX #pragma alloca#endif#endif#define show_allnames 0#define PAGE_SIZE 4096#define PAGE_MASK (-PAGE_SIZE)#include "bfd.h"#include "libiberty.h"#include "bucomm.h"#include "getopt.h"#include "demangle.h"#include "dyn-string.h"#include "dlltool.h"#include <ctype.h>#include <time.h>#include <sys/stat.h>#ifdef ANSI_PROTOTYPES#include <stdarg.h>#else#include <varargs.h>#endif#ifdef DLLTOOL_ARM#include "coff/arm.h"#include "coff/internal.h"#endif/* Forward references. */static char *look_for_prog PARAMS ((const char *, const char *, int));static char *deduce_name PARAMS ((const char *));#ifdef DLLTOOL_MCORE_ELFstatic void mcore_elf_cache_filename (char *);static void mcore_elf_gen_out_file (void);#endif #ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#else /* ! HAVE_SYS_WAIT_H */#if ! defined (_WIN32) || defined (__CYGWIN32__)#ifndef WIFEXITED#define WIFEXITED(w) (((w)&0377) == 0)#endif#ifndef WIFSIGNALED#define WIFSIGNALED(w) (((w)&0377) != 0177 && ((w)&~0377) == 0)#endif#ifndef WTERMSIG#define WTERMSIG(w) ((w) & 0177)#endif#ifndef WEXITSTATUS#define WEXITSTATUS(w) (((w) >> 8) & 0377)#endif#else /* defined (_WIN32) && ! defined (__CYGWIN32__) */#ifndef WIFEXITED#define WIFEXITED(w) (((w) & 0xff) == 0)#endif#ifndef WIFSIGNALED#define WIFSIGNALED(w) (((w) & 0xff) != 0 && ((w) & 0xff) != 0x7f)#endif#ifndef WTERMSIG#define WTERMSIG(w) ((w) & 0x7f)#endif#ifndef WEXITSTATUS#define WEXITSTATUS(w) (((w) & 0xff00) >> 8)#endif#endif /* defined (_WIN32) && ! defined (__CYGWIN32__) */#endif /* ! HAVE_SYS_WAIT_H *//* ifunc and ihead data structures: ttk@cygnus.com 1997 When IMPORT declarations are encountered in a .def file the function import information is stored in a structure referenced by the global variable IMPORT_LIST. The structure is a linked list containing the names of the dll files each function is imported from and a linked list of functions being imported from that dll file. This roughly parallels the structure of the .idata section in the PE object file. The contents of .def file are interpreted from within the process_def_file function. Every time an IMPORT declaration is encountered, it is broken up into its component parts and passed to def_import. IMPORT_LIST is initialized to NULL in function main. */typedef struct ifunct{ char *name; /* name of function being imported */ int ord; /* two-byte ordinal value associated with function */ struct ifunct *next;} ifunctype;typedef struct iheadt{ char *dllname; /* name of dll file imported from */ long nfuncs; /* number of functions in list */ struct ifunct *funchead; /* first function in list */ struct ifunct *functail; /* last function in list */ struct iheadt *next; /* next dll file in list */} iheadtype;/* Structure containing all import information as defined in .def file (qv "ihead structure"). */static iheadtype *import_list = NULL;static char *as_name = NULL;static char * as_flags = "";static int no_idata4;static int no_idata5;static char *exp_name;static char *imp_name;static char *head_label;static char *imp_name_lab;static char *dll_name;static int add_indirect = 0;static int add_underscore = 0;static int dontdeltemps = 0;/* True if we should export all symbols. Otherwise, we only export symbols listed in .drectve sections or in the def file. */static boolean export_all_symbols;/* True if we should exclude the symbols in DEFAULT_EXCLUDES when exporting all symbols. */static boolean do_default_excludes;/* Default symbols to exclude when exporting all the symbols. */static const char *default_excludes = "DllMain@12,DllEntryPoint@0,impure_ptr";/* True if we should add __imp_<SYMBOL> to import libraries for backward compatibility to old Cygwin releases. */static boolean create_compat_implib;static char *def_file;extern char * program_name;static int machine;static int killat;static int add_stdcall_alias;static int verbose;static FILE *output_def;static FILE *base_file;#ifdef DLLTOOL_ARM#ifdef DLLTOOL_ARM_EPOCstatic const char *mname = "arm-epoc";#elsestatic const char *mname = "arm";#endif#endif#ifdef DLLTOOL_I386static const char *mname = "i386";#endif#ifdef DLLTOOL_PPCstatic const char *mname = "ppc";#endif#ifdef DLLTOOL_SHstatic const char *mname = "sh";#endif#ifdef DLLTOOL_MIPSstatic const char *mname = "mips";#endif#ifdef DLLTOOL_MCOREstatic const char * mname = "mcore-le";#endif#ifdef DLLTOOL_MCORE_ELFstatic const char * mname = "mcore-elf";static char * mcore_elf_out_file = NULL;static char * mcore_elf_linker = NULL;static char * mcore_elf_linker_flags = NULL;#define DRECTVE_SECTION_NAME ((machine == MMCORE_ELF || machine == MMCORE_ELF_LE) ? ".exports" : ".drectve")#endif#ifndef DRECTVE_SECTION_NAME#define DRECTVE_SECTION_NAME ".drectve"#endif#define PATHMAX 250 /* What's the right name for this ? */#define TMP_ASM "dc.s"#define TMP_HEAD_S "dh.s"#define TMP_HEAD_O "dh.o"#define TMP_TAIL_S "dt.s"#define TMP_TAIL_O "dt.o"#define TMP_STUB "ds"/* This bit of assemly does jmp * .... */static const unsigned char i386_jtab[] ={ 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90};static const unsigned char arm_jtab[] ={ 0x00, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ 0x00, 0xf0, 0x9c, 0xe5, /* ldr pc, [ip] */ 0, 0, 0, 0};static const unsigned char arm_interwork_jtab[] ={ 0x04, 0xc0, 0x9f, 0xe5, /* ldr ip, [pc] */ 0x00, 0xc0, 0x9c, 0xe5, /* ldr ip, [ip] */ 0x1c, 0xff, 0x2f, 0xe1, /* bx ip */ 0, 0, 0, 0};static const unsigned char thumb_jtab[] ={ 0x40, 0xb4, /* push {r6} */ 0x02, 0x4e, /* ldr r6, [pc, #8] */ 0x36, 0x68, /* ldr r6, [r6] */ 0xb4, 0x46, /* mov ip, r6 */ 0x40, 0xbc, /* pop {r6} */ 0x60, 0x47, /* bx ip */ 0, 0, 0, 0};static const unsigned char mcore_be_jtab[] ={ 0x71, 0x02, /* lrw r1,2 */ 0x81, 0x01, /* ld.w r1,(r1,0) */ 0x00, 0xC1, /* jmp r1 */ 0x12, 0x00, /* nop */ 0x00, 0x00, 0x00, 0x00 /* <address> */ };static const unsigned char mcore_le_jtab[] ={ 0x02, 0x71, /* lrw r1,2 */ 0x01, 0x81, /* ld.w r1,(r1,0) */ 0xC1, 0x00, /* jmp r1 */ 0x00, 0x12, /* nop */ 0x00, 0x00, 0x00, 0x00 /* <address> */ };/* This is the glue sequence for PowerPC PE. There is a *//* tocrel16-tocdefn reloc against the first instruction. *//* We also need a IMGLUE reloc against the glue function *//* to restore the toc saved by the third instruction in *//* the glue. */static const unsigned char ppc_jtab[] ={ 0x00, 0x00, 0x62, 0x81, /* lwz r11,0(r2) */ /* Reloc TOCREL16 __imp_xxx */ 0x00, 0x00, 0x8B, 0x81, /* lwz r12,0(r11) */ 0x04, 0x00, 0x41, 0x90, /* stw r2,4(r1) */ 0xA6, 0x03, 0x89, 0x7D, /* mtctr r12 */ 0x04, 0x00, 0x4B, 0x80, /* lwz r2,4(r11) */ 0x20, 0x04, 0x80, 0x4E /* bctr */};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -