dlltool.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,503 行 · 第 1/5 页

C
2,503
字号
/* 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 + =
减小字号Ctrl + -
显示快捷键?