⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 patch.c

📁 c 语言编译器 源代码- c compiler
💻 C
字号:
/*ident	"@(#)cfront:patch/patch.c	1.3"*//*patch: Patch an a.out to ensure that static constructors are called.Currently this is in good-old-C. This code uses -lld, the Unix system V functions for accessing COFF files.	The program is passed one argument, the name of an executable	C++ program.  It first reads the COFF symbol table, remembering	all symbols of the name __LINK.  	  Each of these symbols points to a structure of the form:		struct __link {			struct __link *next;	//next link in the chain			int (*ctor)();		//ptr to ctor function			int (*dtor)();		//ptr to dtor function		};	cfront puts one of these in each dot-o.  Patch finds them,	and chains them together by writing	(into the actual a.out) values for the "next"	pointers.  A pointer to the start of the chain is written	into the struct __link pointer named __HEAD.	 _main will follow this chain at runtime and 	use the ctor and dtor function pointers to call the static	ctors and dtors.***************************************************************/			#include <stdio.h>#include <filehdr.h>#include  <scnhdr.h>#include <syms.h>#include <ldfcn.h>typedef long PHSADDR;/*char *ldgetname(LDFILE*, SYMENT*);*//*void fatal_error(char *);*/char *ldgetname();void fatal_error();int debug = 0;int found_main = 0;	/*1 iff _main() has been seen*/PHSADDR head = 0;	/*Adress of the __HEAD symbol*/PHSADDR data_infile;	/*offset in file of the data segment*/PHSADDR data_pa;	/*physical adress of start of data segment*/PHSADDR zero = 0;PHSADDR previous;char *file;			/*Name of the file being patched*/#define MAX_FILES 5000PHSADDR addrs[MAX_FILES];	/*array of addresses of __LINK symbols*/PHSADDR *addr_ptr = addrs;main(argc , argv)int argc;char *argv[];{	LDFILE *ldptr;	SCNHDR secthead;	FILE *fptr;	PHSADDR *symbol;	int x_sym;	if (argc == 3 && strcmp(argv[1], "-d")==0 )	{		file = argv[2];		debug = 1;	}	else if (argc == 2)		file = argv[1];	else		fatal_error("usage: patch file");			/*Try to open the file*/	if ( (ldptr = ldopen(file, NULL)) == NULL)		fatal_error("cannot open file");			/*Find  the beginning of the .data section*/	if (ldnshread( ldptr, ".data", &secthead) == FAILURE)		fatal_error("cannot get .data header");				/*remember the start of data section, both the			  physical address at runtime,			  and the offset in the file*/	data_infile = secthead.s_scnptr;	data_pa = secthead.s_paddr;	if (debug)	{		printf("data in file: 0x%x\n", data_infile);		printf("\taddr: 0x%x\n", data_pa);	}			/*seek to the beginning of the symbol table*/	if (ldtbseek(ldptr) == FAILURE)		fatal_error("cannot get symbol table");			/*Find the magic symbols in the a.out*/        for ( x_sym = 0; x_sym < HEADER(ldptr).f_nsyms; ++x_sym)	{		char *str;		SYMENT sym;                        /*read the symbol*/		if ( FREAD( (char *)&sym, SYMESZ, 1, ldptr) != 1)			break;		str = ldgetname(ldptr,&sym);		if (strcmp(str, "__HEAD") == 0)		{			if (debug)				printf("__HEAD found at 0x%x\n", 				sym.n_value);			head = sym.n_value;		}		else if (strcmp(str, "__LINK")==0)		{			if (addr_ptr >= addrs + MAX_FILES)				fatal_error(" too many files");			*addr_ptr++ = sym.n_value;			if (debug)				printf("__LINK found at 0x%x\n",sym.n_value);		}		else if (strcmp(str, "__main") == 0)			found_main++;			/*Skip auxiliary entries*/		if (sym.n_numaux)		{                        x_sym += sym.n_numaux;                        FSEEK(ldptr, sym.n_numaux*SYMESZ, 1);		}	}	if (!head)	{		if (found_main == 0)			fatal_error("_main() not found");		else		fatal_error("Bad _main loaded- libC probably not set up for patch");	}			/*Now we have all of the __LINK pointers.			  close the file, and reopen it for updating to			  write the patches.  All hell will break loose			  if someone writes the file in the meantime.*/	ldclose(ldptr);			/*If no symbols were found, quit*/	if ( addr_ptr == addrs)	{		if(debug)			printf("No __LINKs found\n");		exit(0);	}	if ( (fptr=fopen(file, "r+")) == NULL)		fatal_error(" can't reopen file");			/*patch the first symbol*/			/*seek to: physical adr. of symbol				- physical adr of start of data				+ file offset of start of data*/	previous = head - data_pa + data_infile;			/*Now, go thru the list of symbols. Each is			  a pointer to the next link. Chain them up*/			/*For non-obvious reasons, do this backwards.			  This calls ctors from libraries first.*/	for (symbol = addr_ptr - 1; symbol >= addrs; symbol --)	{			/*Update the previous pointer to point to this one.*/		if(debug)			printf("Write 0x%x at offset 0x%x\n",			*symbol, previous );		if (fseek(fptr, previous , 0))			fatal_error("can't seek");		if( fwrite((char *)symbol, sizeof(PHSADDR), 1, fptr) == 0)			fatal_error("can't write file");		previous = *symbol - data_pa + data_infile;	}			/*Zero out the last symbol*/	if(fseek(fptr, previous , 0))		fatal_error("can't seek");	if (fwrite((char *)&zero, sizeof(PHSADDR), 1, fptr) == 0)		fatal_error("can't write");	if(debug)		printf("Write 0 at offset 0x%x\n", previous );	fclose(fptr);	exit(0);			  }voidfatal_error(message)char * message;{	fprintf(stderr,"patch: file %s: %s\n", file, message);	exit(-1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -