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

📄 unexconvex.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	}    } else	bss_start = bss_end;    if (data_start > bss_start)	{ /* Can't have negative data size. */	ERROR2 ("unexec: data_start (%x) can't be greater than bss_start (%x)",		data_start, bss_start);    }    /* Salvage as much info from the existing file as possible */    if (a_out < 0) {	ERROR0 ("can't build a COFF file from scratch yet");	/*NOTREACHED*/    }    if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {	PERROR (a_name);    }    block_copy_start += sizeof (f_hdr);    if (f_hdr.h_opthdr > 0) {	if (read (a_out, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {	    PERROR (a_name);	}	block_copy_start += sizeof (f_ohdr);    }    /* Allocate room for scn headers */    stbl = (struct scnhdr *)malloc( sizeof(struct scnhdr) * f_hdr.h_nscns );    if( stbl == NULL ) {	ERROR0( "unexec: malloc of stbl failed" );    }    f_tdhdr = f_tbhdr = NULL;    /* Loop through section headers, copying them in */    for (scns = 0; scns < f_hdr.h_nscns; scns++) {	if( read( a_out, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {	    PERROR (a_name);	}	scntype = stbl[scns].s_flags & S_TYPMASK; /* What type of section */	if( stbl[scns].s_scnptr > 0L) {	    if( block_copy_start < stbl[scns].s_scnptr + stbl[scns].s_size )		block_copy_start = stbl[scns].s_scnptr + stbl[scns].s_size;	}	if( scntype == S_TEXT) {	    f_thdr = &stbl[scns];	} else if( scntype == S_DATA) {	    f_dhdr = &stbl[scns];#ifdef S_TDATA	} else if( scntype == S_TDATA ) {	    f_tdhdr = &stbl[scns];	} else if( scntype == S_TBSS ) {	    f_tbhdr = &stbl[scns];#endif /* S_TDATA (thread stuff) */	} else if( scntype == S_BSS) {	    f_bhdr = &stbl[scns];	}    }    /* We will now convert TEXT and DATA into TEXT, BSS into DATA, and leave     * all thread stuff alone.     */    /* Now we alter the contents of all the f_*hdr variables       to correspond to what we want to dump.  */    f_thdr->s_vaddr = (long) start_of_text ();    f_thdr->s_size = data_start - f_thdr->s_vaddr;    f_thdr->s_scnptr = pagesz;    f_thdr->s_relptr = 0;    f_thdr->s_nrel = 0;    eo_data = f_thdr->s_scnptr + f_thdr->s_size;    if( f_tdhdr ) {		/* Process thread data */	f_tdhdr->s_vaddr = data_start;	f_tdhdr->s_size += f_dhdr->s_size - (data_start - f_dhdr->s_vaddr);	f_tdhdr->s_scnptr = eo_data;	f_tdhdr->s_relptr = 0;	f_tdhdr->s_nrel = 0;	eo_data += f_tdhdr->s_size;	/* And now for DATA */	f_dhdr->s_vaddr = f_bhdr->s_vaddr; /* Take BSS start address */	f_dhdr->s_size = bss_end - f_bhdr->s_vaddr;	f_dhdr->s_scnptr = eo_data;	f_dhdr->s_relptr = 0;	f_dhdr->s_nrel = 0;	eo_data += f_dhdr->s_size;    } else {	f_dhdr->s_vaddr = data_start;	f_dhdr->s_size = bss_start - data_start;	f_dhdr->s_scnptr = eo_data;	f_dhdr->s_relptr = 0;	f_dhdr->s_nrel = 0;	eo_data += f_dhdr->s_size;    }    f_bhdr->s_vaddr = bss_start;    f_bhdr->s_size = bss_end - bss_start + pagesz /* fudge */;    f_bhdr->s_scnptr = 0;    f_bhdr->s_relptr = 0;    f_bhdr->s_nrel = 0;    text_scnptr = f_thdr->s_scnptr;    data_scnptr = f_dhdr->s_scnptr;    bias = eo_data - block_copy_start;    if (f_ohdr.o_symptr > 0L) {	f_ohdr.o_symptr += bias;    }    if (f_hdr.h_strptr > 0) {	f_hdr.h_strptr += bias;    }    if (write (new, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr)) {	PERROR (new_name);    }    if (write (new, &f_ohdr, sizeof (f_ohdr)) != sizeof (f_ohdr)) {	PERROR (new_name);    }    for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {	/* This is a cheesey little loop to write out the section headers	 * in order of increasing virtual address. Dull but effective.	 */	for( i = scns+1; i < f_hdr.h_nscns; i++ ) {	    if( stbl[i].s_vaddr < stbl[scns].s_vaddr ) { /* Swap */		scntemp = stbl[i];		stbl[i] = stbl[scns];		stbl[scns] = scntemp;	    }	}    }    for( scns = 0; scns < f_hdr.h_nscns; scns++ ) {	if( write( new, &stbl[scns], sizeof(*stbl)) != sizeof(*stbl)) {	    PERROR (new_name);	}    }    return (0);}/* **************************************************************** * copy_text_and_data * * Copy the text and data segments from memory to the new a.out */static intcopy_text_and_data (new)int new;{    register int scns;    for( scns = 0; scns < f_hdr.h_nscns; scns++ )	write_segment( new, &stbl[scns] );    return 0;}write_segment( new, sptr )int new;struct scnhdr *sptr;{    register char *ptr, *end;    register int nwrite, ret;    char buf[80];    extern int errno;    char zeros[128];    if( sptr->s_scnptr == 0 )	return;			/* Nothing to do */    if( lseek( new, (long) sptr->s_scnptr, 0 ) == -1 )	PERROR( "unexecing" );    bzero (zeros, sizeof zeros);    ptr = (char *) sptr->s_vaddr;    end = ptr + sptr->s_size;    while( ptr < end ) {	/* distance to next multiple of 128.  */	nwrite = (((int) ptr + 128) & -128) - (int) ptr;	/* But not beyond specified end.  */	if (nwrite > end - ptr) nwrite = end - ptr;	ret = write (new, ptr, nwrite);	/* If write gets a page fault, it means we reached	   a gap between the old text segment and the old data segment.	   This gap has probably been remapped into part of the text segment.	   So write zeros for it.  */	if (ret == -1 && errno == EFAULT)	    write (new, zeros, nwrite);	else if (nwrite != ret) {	    sprintf (buf,		     "unexec write failure: addr 0x%x, fileno %d, size 0x%x, wrote 0x%x, errno %d",		     ptr, new, nwrite, ret, errno);	    PERROR (buf);	}	ptr += nwrite;    }}/* **************************************************************** * copy_sym * * Copy the relocation information and symbol table from the a.out to the new */static intcopy_sym (new, a_out, a_name, new_name)     int new, a_out;     char *a_name, *new_name;{    char page[1024];    int n;    if (a_out < 0)	return 0;    if (SYMS_START == 0L)	return 0;    lseek (a_out, SYMS_START, 0);	/* Position a.out to symtab. */    lseek( new, (long)f_ohdr.o_symptr, 0 );    while ((n = read (a_out, page, sizeof page)) > 0) {	if (write (new, page, n) != n) {	    PERROR (new_name);	}    }    if (n < 0) {	PERROR (a_name);    }    return 0;}/* **************************************************************** * mark_x * * After succesfully building the new a.out, mark it executable */staticmark_x (name)char *name;{    struct stat sbuf;    int um;    int new = 0;  /* for PERROR */    um = umask (777);    umask (um);    if (stat (name, &sbuf) == -1) {	PERROR (name);    }    sbuf.st_mode |= 0111 & ~um;    if (chmod (name, sbuf.st_mode) == -1)	PERROR (name);}/* Find the first pty letter.  This is usually 'p', as in ptyp0, but   is sometimes configured down to 'm', 'n', or 'o' for some reason. */first_pty_letter (){  struct stat buf;  char pty_name[16];  char c;  for (c = 'o'; c >= 'a'; c--)    {      sprintf (pty_name, "/dev/pty%c0", c);      if (stat (pty_name, &buf) < 0)	return c + 1;    }  return 'a';}

⌨️ 快捷键说明

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