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

📄 dyn_arm_emul.cpp

📁 arm的模拟器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	sprintf(filename, "%s/libXcompiled_%u.so", cache_dir, ind);	sprintf(funname, "compiled_%u", ind);	if (showmsg)		fprintf(stderr, "Loading %d for address %x.\n", ind, pblk << shiftval);	/* not sure if the many libc functions below are thread-safe.	 * to save the trouble, use the big lock, many compilation	 * threads can call load_lib, so need to safe guard	 */	pthread_mutex_lock(&srv_mut);	/* in the parallel version, load_lib is called by comm. threads,	 * need to guard with mutex since the main thread may call unload_lib	 * at the same time	 * if the program is not yet running, then it must be setting up cache	 */	if (blk_info[pblk].count != -1u && status != ST_RESET) {		pthread_mutex_unlock(&srv_mut);		return false;	}	/* check if it is already loaded */	map<unsigned, dll_info_t *>::iterator mit = DLL_INFO2->find(ind);	if (mit != DLL_INFO2->end())	{		(*mit).second->rcount++;		blk_info[pblk].dll_fptr = (*mit).second->dll_fptr;		blk_info[pblk].count = 0;		pthread_mutex_unlock(&srv_mut);		return true;	}	void *handle = dlopen(filename, RTLD_LAZY);	if (!handle) {		fputs(dlerror(), stderr);		pthread_mutex_unlock(&srv_mut);		return false;	}	fptr_t fptr = (fptr_t)dlsym(handle, funname);	if ((error = dlerror())!= NULL) {		fputs(error, stderr);										pthread_mutex_unlock(&srv_mut);		return false;	}	dll_info_t *ndll = (dll_info_t *)malloc(sizeof(dll_info_t));	if (ndll==NULL) {		fputs("Out of memory\n", stderr);		exit(1);	}	ndll->rcount = 1;	ndll->handle = handle;	ndll->index  = ind;	ndll->dll_fptr = fptr;	DLL_INFO->insert(pair<fptr_t, dll_info_t *>(fptr, ndll));	DLL_INFO2->insert(pair<unsigned, dll_info_t *>(ind, ndll));	blk_info[pblk].dll_fptr = fptr;	/* clear the count so whatever happens, it can still be interpreted */	blk_info[pblk].count = 0;	pthread_mutex_unlock(&srv_mut);	return true;}bool dyn_arm_emulator::unload_lib(unsigned pblk){	/* clear the block */	pthread_mutex_lock(&srv_mut);	/* the block is still in compilation */	if (blk_info[pblk].count == -1u)	{		blk_info[pblk].count = 0;		pthread_mutex_unlock(&srv_mut);		return true;	}	map<fptr_t, dll_info_t *>::iterator mit =		DLL_INFO->find(blk_info[pblk].dll_fptr);	assert(mit != (DLL_INFO->end()));	/* decrement the reference count */	if (--((*mit).second->rcount) == 0)	{		dlclose((*mit).second->handle);		DLL_INFO2->erase((*mit).second->index);		free((*mit).second);		DLL_INFO->erase(mit);	}	blk_info[pblk].dll_fptr = NULL;	blk_info[pblk].count = 0;	pthread_mutex_unlock(&srv_mut);	return true;}/************************************************************************	convenient routines for socket communication************************************************************************//* send nbytes to socket */static ssize_t sendall(int fd, const void *buf, size_t nbyte){	ssize_t nwrite = 0, n;	do	{		if ((n = send(fd, (const char *)buf + nwrite, nbyte - nwrite, 0)) ==			(ssize_t)-1)		{			if (errno == EINTR)				continue;			else				return -1;		}		nwrite += n;	}	while (nwrite < (ssize_t)nbyte);	return nwrite;}/* receive up to nbytes from socket */static ssize_t recvall(int fd, void *buf, size_t nbyte){	ssize_t nread = 0, n;	do	{		if ((n = recv(fd, (char *)buf + nread, nbyte - nread, 0)) ==			(ssize_t)-1)		{			if (errno == EINTR)				continue;			else				return -1;		}		if (n == 0)			return nread;		nread += n;	}	while (nread < (ssize_t)nbyte);	return nread;}void dyn_arm_emulator::com_thread(){	int my_index = SIMIT_MAX_SERVER; 	unsigned bufsize = 1 << shiftval;	byte_t *buf = (byte_t *)malloc(bufsize);	if (buf == NULL)	{		fprintf(stderr, "Error: Insufficient memory, thread terminates\n");		return;	}	pthread_mutex_lock(&srv_mut);	/* find one spot that is not in use */	for (int ii=0; ii<SIMIT_MAX_SERVER; ii++)	{		if (srv_dir[ii].buf == NULL) 		{			my_index = ii;			srv_dir[ii].buf = buf;			/* don't increment srv_count yet since connection may fail */			break;		}	}	pthread_mutex_unlock(&srv_mut);	/* too many threads, silently quit */	if (my_index == SIMIT_MAX_SERVER) return;	struct sockaddr_in address;	int my_socket;	if ((my_socket = socket(AF_INET,SOCK_STREAM,0))>0)		if (showmsg)		 fprintf(stderr, "The socket was created %d\n",my_socket); 	address.sin_family= AF_INET;	address.sin_port = htons(srv_dir[my_index].portno);	inet_pton(AF_INET, srv_dir[my_index].ipaddr, &address.sin_addr);	if (showmsg)		fprintf(stderr, "Trying to connect with server %s:%d...\n",			srv_dir[my_index].ipaddr, srv_dir[my_index].portno);	if (connect(my_socket, (struct sockaddr*)&address, sizeof(address))==0) {		if (showmsg)			fprintf(stderr, "Connection was accepted by server %s:%d.\n",				srv_dir[my_index].ipaddr, srv_dir[my_index].portno);	}	else {		fprintf(stderr, "Connection was rejected by server %s:%d.\n",			srv_dir[my_index].ipaddr, srv_dir[my_index].portno);		pthread_exit(NULL);	}	srv_dir[my_index].socket = my_socket;	pthread_mutex_lock(&srv_mut);	srv_count++;	pthread_mutex_unlock(&srv_mut);	while (true)	{		unsigned ind; // DLL number		unsigned pblk; // physical address index		get_block_to_compile(&ind, &pblk);		// simulation has finished?		if (com_done) break;		if (showmsg)			fprintf(stderr,"start to compile ...\n");			mem->read_block(buf, pblk << shiftval, bufsize);		unsigned crc;		unsigned dres = lookup_dict(buf, &crc);		if (dres != -1u)		{			load_lib(pblk, dres);			continue;		}		if (showmsg)			fprintf(stderr, "sending the bufsize %d...\n", bufsize);		/* unrecoverable connection error */		if (sendall(my_socket, &bufsize, sizeof(bufsize)) < 0) break;		if (showmsg)			fprintf(stderr, "sending the dll_ind %d...\n", ind);		if (sendall(my_socket, &ind, sizeof(ind)) < 0) break;		if (showmsg)			fprintf(stderr, "sending the user_level %d...\n", user_level);		if (sendall(my_socket, &user_level, sizeof(user_level)) < 0) break;		if (showmsg)			fprintf(stderr, "sending block of size %d...\n", bufsize);		if (sendall(my_socket, buf, bufsize) < 0) break;		int objsize, islinked;		if (recvall(my_socket, &objsize, sizeof(int)) < 0) break;		if (recvall(my_socket, &islinked, sizeof(int)) < 0) break;		/* 0 means error, but still connected */		if (objsize == 0)		{			if (showmsg)				fprintf(stderr, "server error encountered...\n");			continue;		}					srv_dir[my_index].count++;		char pkt[1024];		char fname[1024];		if (islinked)			sprintf(fname, "%s/libXcompiled_%u.so", cache_dir, ind);		else			sprintf(fname, "%s/Xcompiled_%u.o", cache_dir, ind);		FILE* fp = fopen(fname, "w");		int rem = objsize, recd = 1;		while (recd > 0 && rem > 0)		{			recd = recvall(my_socket, pkt, rem<1024?rem:1024);			if (recd > 0)			{				fwrite(pkt, 1, recd, fp);				rem -= recd;			}		}		fclose(fp);		if (recd < 0) break;		if (showmsg)			fprintf(stderr,"%d Compiled code received of size %d\n",				my_index, objsize);		sprintf(fname, "%s/Xcompiled_%u.dat", cache_dir, ind);		fp = fopen(fname, "wb");		fwrite(buf, 1, 1 << shiftval, fp);		fclose(fp);		/* if code is not linked, link it */		if (islinked || ld_lib(ind))		{			pthread_mutex_lock(&srv_mut);			update_dll_dict(ind, crc);			pthread_mutex_unlock(&srv_mut);			if (!com_done && load_lib(pblk, ind))			{				if (showmsg)					fprintf(stderr, "File successfully loaded...\n");			}		}	}	if (!com_done)	{		srv_count--; 		if (showmsg)			fprintf(stderr, "Connection reset, thread %d exits.\n", my_index);	}	pthread_exit(NULL);}/* com_thread2 are local threads, we don't cancel, but join them on exit*/void dyn_arm_emulator::com_thread2(){	int my_index = SIMIT_MAX_SERVER; 	unsigned bufsize = 1 << shiftval;	byte_t *buf = (byte_t *)malloc(bufsize);	if (buf == NULL)	{		fprintf(stderr, "Error: Insufficient memory, thread terminates\n");		return;	}	pthread_mutex_lock(&srv_mut);	/* find one spot that is not in use */	for (int ii=0; ii<SIMIT_MAX_SERVER; ii++)	{		/* donot use entries reserved for remote server */		if (srv_dir[ii].buf == NULL && srv_dir[ii].ipaddr[0] == 0) 		{			my_index = ii;			srv_dir[ii].buf = buf;			srv_count++;			break;		}	}	pthread_mutex_unlock(&srv_mut);	/* too many threads, silently quit */	if (my_index == SIMIT_MAX_SERVER) return;	while (true)	{		unsigned ind; // DLL number		unsigned pblk; // physical address index		get_block_to_compile(&ind, &pblk);		if (com_done) pthread_exit(NULL);		if (showmsg)			fprintf(stderr,"start to compile ...\n");			mem->read_block(buf, pblk << shiftval, bufsize);		unsigned crc;		unsigned dres = lookup_dict(buf, &crc);		if (dres != -1u)		{			load_lib(pblk, dres);		}		else if (compile_block(buf, ind))		{			srv_dir[my_index].count++;			pthread_mutex_lock(&srv_mut);			update_dll_dict(ind, crc);			pthread_mutex_unlock(&srv_mut);			if (!com_done && load_lib(pblk, ind))			{				if (showmsg)					fprintf(stderr, "File successfully loaded...\n");			}		}	}}void dyn_arm_emulator::com_cleanup(){	for (int ii=0; ii<SIMIT_MAX_SERVER; ii++)	{		if (srv_dir[ii].buf) 		{			free(srv_dir[ii].buf);			srv_dir[ii].buf = NULL;		}	}}/* this function reads the config file and populates the server database*/int dyn_arm_emulator::read_servers(const char* fname){	char buf1[64];	int  ii = 0;		if (fname==NULL) return 0;	FILE* fp = fopen(fname,"r");	if (!fp)	{		fprintf(stderr, "Could not open config file %s\n", fname);		return 0;	}	// donot use scanf %s since it is not safe	while (fgets(buf1, 64, fp)!=NULL)	{		char *ptr;		if ((ptr = strtok(buf1, "\n\t "))==NULL) return ii;		strncpy(srv_dir[ii].ipaddr, ptr, 63);		if ((ptr = strtok(NULL, "\n\t "))==NULL) return ii;		srv_dir[ii].portno = atoi(ptr);		/* read as many as I can remember. */		if (++ii==SIMIT_MAX_SERVER) break;	}	fclose(fp);	return ii;}#include "read_elf.h"bool dyn_arm_emulator::setup_cache(const char *filename){	Elf32_Ehdr *hdr;	Elf32_Phdr *phdr;	Elf32_Shdr *shdr;	char *string_table;	Elf32_Shdr *shdr_new_section;	Elf32_Word new_section_size, new_section_type, new_section_flags;	Elf32_Addr new_section_addr;	FILE *fobj;	int i;	if (!read_or_create_dll_dict()) return false;	if (filename == NULL) return true;	fobj = fopen(filename, "rb");	if(fobj == NULL) {		fprintf(stderr, "Can't open executable: %s\n", filename);		exit(1);	}	hdr = ReadElfHeader(fobj);	if(hdr == NULL) {		fprintf(stderr, "Could not read ELF32 header from file: %s.\n",			   	filename);		exit(1);	}#ifndef EM_ARM#define EM_ARM 40#endif	/* check if the file is for ARM */	if (hdr->e_type != ET_EXEC ||		hdr->e_machine != EM_ARM ||		hdr->e_ident[EI_DATA] != ELFDATA2LSB) {		fprintf(stderr, "File is not ARM LSB executable: %s.\n", filename);		exit(1);	}	phdr = ReadProgramHeaders(hdr, fobj);	for(i=0; i<hdr->e_phnum; i++) {		if ( (phdr[i].p_type == PT_LOAD) /* Loadable Program Segment */ &&		 ((phdr->p_flags & PF_X) != 0 /* not text segment => data segment */)) {		data_base = phdr[i].p_vaddr;		data_size = phdr[i].p_memsz;		}	}	prog_base = hdr->e_entry;	shdr = ReadSectionHeaders(hdr, fobj);		if(shdr == NULL) {		fprintf(stderr, "Can't read section headers from executable\n");		exit(1);	}	string_table = LoadStringTable(hdr, shdr, fobj);	for(i = 0; i < hdr->e_shnum; i++)	{		shdr_new_section = &shdr[i];		new_section_type = GetSectionType(shdr_new_section);		new_section_flags = GetSectionFlags(shdr_new_section);		if ((new_section_type == SHT_PROGBITS) &&			(new_section_flags & (SHF_EXECINSTR | SHF_ALLOC)))		{			new_section_size =				shdr_new_section ? GetSectionSize(shdr_new_section) : 0;			new_section_addr = GetSectionAddr(shdr_new_section);			arm_addr_t new_section_end = new_section_addr + new_section_size;			while (new_section_addr < new_section_end)			{				/* align memory address */				arm_addr_t fstart = (new_section_addr >> shiftval) << shiftval;				mem->read_block(temp_buf1, fstart, 1 << shiftval);				/* if not loaded yet */				if (blk_info[fstart >> shiftval].dll_fptr == NULL)				{					unsigned dres = lookup_dict(temp_buf1);					if (dres != -1u)					{						req_num++;						load_lib(fstart >> shiftval, dres);					}				}				new_section_addr = fstart + (1 << shiftval);			}		}	}	free(string_table);	free(phdr);	free(shdr);	free(hdr);	fclose(fobj);	return true;}

⌨️ 快捷键说明

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