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

📄 obj4lb.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 2 页
字号:

	/* search current entries */
	while(m->fptr)
	{
		m = m->fptr;
		if(!movcmp(sp->e.e_name, strtbl+m->offset))
			return m->offset;
	}

	/* enter string in moved list */
	if(!lmoves) lmoves = &moves;
	lmoves->fptr = xmalloc(sizeof(MOVDAT));
	lmoves = lmoves->fptr;		
	lmoves->offset = strsize+4;

	memcpy(strtbl+lmoves->offset, sp->e.e_name, E_SYMNMLEN);
	strsize += E_SYMNMLEN+1;
	return lmoves->offset;
}
static void
fix_silly_coff_symtbl()
{
COFF_SYMBOL *sp;
int i;
int xtracnt = 0;

	for(i = 0, sp = coff_symtbl; i < nsyms; ++i, ++sp)
	{
		if(sp->e.e.e_zeroes)
		{/* this, 8 char or less symbol may be moved to strtbl */
			xtracnt += E_SYMNMLEN+1;
		}
		if(sp->e_numaux)
		{/* ignore aux records */
			i += sp->e_numaux;
			sp += sp->e_numaux;
		}
	}
	if(xtracnt > 0)
	{
	char *nt;
		nt = calloc(1, strsize + xtracnt + 4);
		memcpy(nt, strtbl, strsize + 4);
		free(strtbl);
		strtbl = nt;

		for(i = 0, sp = coff_symtbl; i < nsyms; ++i, ++sp)
		{
			if(sp->e.e.e_zeroes)
			{/* this, 8 char or less symbol must be moved to strtbl */
				sp->e.e.e_offset = mark_moved(sp);
				sp->e.e.e_zeroes = 0;
			}
			if(sp->e_numaux)
			{/* ignore aux records */
				i += sp->e_numaux;
				sp += sp->e_numaux;
			}
		}
		*((unsigned long *)strtbl) = strsize;
	}
}
static void
coff_read_stuff()
{
PCOFF_HDR p = (PCOFF_HDR)&header;
POXHDR hdr = &xhdr;
int i;
	if(p->f_opthdr)
	{/* optional header is present, wrong file type */
		puts("4lb: coff optional header encountered, wrong file type");
		exit(1);
	}
	/* load section headers */
	hdr->section_headers_size = p->f_nscns * sizeof(SCNHDR);
	s = malloc(hdr->section_headers_size);
	fseek(ifd, sizeof(COFF_HDR), 0);
	fread(s, 1, hdr->section_headers_size, ifd);

	/* scan section headers */
	t = d = b = 0;
	for(i = 0; i < p->f_nscns; ++i)
	{/* find the text, data, and bss sections */
		q = &s[i];
		if(!strcmp(q->s_name, ".text"))
		{
	 		t = q;
			scntype[i+1] = N_TEXT;
		}
		else if(!strcmp(q->s_name, ".data"))
		{
			d = q;
			scntype[i+1] = N_DATA;
		}
		else if(!strcmp(q->s_name, ".bss"))
		{
			b = q;
			scntype[i+1] = N_BSS;
			bss_section = i+1;
		}
	}
	if(!t || !d || !b)
	{
		puts("4lb: missing text data or bss section");
		exit(1);
	}
	hdr->start_addr = 0;
	hdr->text_size = t->s_size;
	hdr->data_size = d->s_size;
	hdr->bss_size = b->s_size;
	hdr->text_fileaddr = t->s_scnptr;
	hdr->data_fileaddr = d->s_scnptr;
	hdr->text_vaddr = t->s_vaddr;
	hdr->data_vaddr = d->s_vaddr;
	hdr->bss_vaddr = b->s_vaddr;
	hdr->image_size = hdr->text_size + hdr->data_size + hdr->bss_size;
	hdr->text_reloc_fileaddr = t->s_relptr;
	hdr->text_reloc_size = t->s_nreloc * COFF_RELOC_SIZE;
	hdr->text_reloc_cnt  = t->s_nreloc;
	hdr->data_reloc_fileaddr = d->s_relptr;
	hdr->data_reloc_size = d->s_nreloc * COFF_RELOC_SIZE;
	hdr->data_reloc_cnt  = d->s_nreloc;
	if(		(hdr->symbols_fileaddr = p->f_symptr)
		&&	(hdr->symbols_cnt = p->f_nsyms)
	  )/* you just can't tell what some utilities will do */
	{
	long temp;

		hdr->symbols_size = p->f_nsyms * COFF_SYMBOL_SIZE;
		hdr->strings_fileaddr = hdr->symbols_fileaddr + hdr->symbols_size;

		fseek(ifd, hdr->strings_fileaddr, 0);
		if(fread(&temp, 1, 4, ifd) != 4)
		{
			puts("4lb: no strings in coff file");
			exit(1);
		}
		hdr->strings_size = strsize = nstrsize = temp;
		nsyms = hdr->symbols_cnt;
	}
	else
	{
		puts("4lb: no symbols in coff file");
		exit(1);
	}
	sbf = calloc(1, p->f_nscns * sizeof(BUFS));
	rbf = calloc(1, p->f_nscns * sizeof(BUFS));
	lbf = calloc(1, p->f_nscns * sizeof(BUFS));

	for(i = 0; i < p->f_nscns; ++i)
	{/* load each of the sections, plus relocs and linenos */
		q = &s[i];
		if(q->s_scnptr)
		{
			sbf[i].size = q->s_size;
 			sbf[i].addr = malloc(sbf[i].size);
			sbf[i].fileptr = q->s_scnptr;
			fseek(ifd, sbf[i].fileptr, 0);
			fread(sbf[i].addr, 1, sbf[i].size, ifd);
			if(q->s_nreloc > 0)
			{
				rbf[i].size = q->s_nreloc*COFF_RELOC_SIZE;
				rbf[i].addr = malloc(rbf[i].size);;
				rbf[i].fileptr = q->s_relptr;
				rbf[i].cnt = q->s_nreloc;
				fseek(ifd, rbf[i].fileptr, 0);
				fread(rbf[i].addr, 1, rbf[i].size, ifd);
			}
			if(q->s_nlnno > 0)
			{
				lbf[i].size = q->s_nlnno*COFF_LINENO_SIZE;
				lbf[i].addr = malloc(lbf[i].size);
				lbf[i].fileptr = q->s_lnnoptr;
				lbf[i].cnt = q->s_nlnno;
				fseek(ifd, lbf[i].fileptr, 0);
				fread(lbf[i].addr, 1, lbf[i].size, ifd);
			}
		}
	}
	/* load the symbols and strings */
	coff_symtbl = malloc(hdr->symbols_size);
	fseek(ifd, hdr->symbols_fileaddr, 0);
	fread(coff_symtbl, 1, hdr->symbols_size, ifd);
	nstrtbl = strtbl = malloc(hdr->strings_size+4);
	fseek(ifd, hdr->strings_fileaddr, 0);
	fread(strtbl, 1, hdr->strings_size+4, ifd);
	lowoffset = 4;
	fix_silly_coff_symtbl();
}
 
static void
usage()
{
  puts("Usage: obj4lb infile");
  puts("  infile must be in a.out or coff format.");
  puts("  outfile will be the suffix .olb");
  puts("  the specification file should have the suffix .4lb");
  exit(0);
}
static void
lose_backslashes(char *p)
{
  while(*p)
  {
    if(*p == '\\')
      *p = '/';
    ++p;
  }
}
static int
proc_infile(char *name)
{
  ifd = fopen(name, "r+b");
  if(!ifd) {
  	printf("4lb: Cannot open input file %s\n", infile);
	exit(1);
  }
  if(fread((char *)&header, sizeof(struct exec), 1, ifd) != 1)
  {
    printf("4lb: cannot read %s\n", name);
	exit(1);
  }
  if(N_MAGIC(header) == OMAGIC)
  {
	aout_read_symbols();
	aout_read_text_and_data();
	aout_read_relocs();
  }
  else if(N_MAGIC(header) == IMAGIC)
  {
	coff_read_stuff();
  }
  else
  {
    printf("4lb: incorrect filetype: %s magic=%x\n", name, N_MAGIC(header));
	exit(1);
  }
  return 1;
}
static void
fix_suffix(char *str, char *suf)
{
char *cp;
	if((cp = strrchr(str, '.')) != NULL)
		 strcpy(cp, suf);
	else strcat(str, suf);
}
static char *
find_sym(char *cp)
{
	while(*cp && (*cp == ':' || isspace(*cp)))
		++cp;

	if(*cp) {
	char *np=cp;	
		
		while(*np && *np != ':' && !isspace(*np))
			++np;
		if(*np)
			*np = '\0';
		return cp;
	}
	return NULL;
}
static int
sym_exists(const char *cp, int len)
{
RENAMES *r = &renames;
char *sp = strtbl;
char *ep = strtbl + strsize;

	while(r->fptr)
	{
		r = r->fptr;
		if(!strcmp(cp, r->newname))
		{
			cp = r->oldname;
			len = r->oldlen;
			break;			
		}
	}
	while(sp < ep)
	{
	int splen = strlen(sp);
		if(splen == len)
		  if(!strcmp(sp,cp))
			return 1;
		sp += splen+1;
	}
	return 0;
}
static void
proc_4lb()
{/* Process the specification file */
char buf[200];
char *cp;

	lexports = &exports;
	lrenames = &renames;
	while(fgets(buf, 190, lb4fd))
	{
		if((cp = strchr(buf, ':')) == NULL)
			continue;
		if(!strncmp(buf, "export", 6))
		{
			if((cp = find_sym(cp)) != NULL)
			{
			int len;
			char *strloc;
				len = strlen(cp);
				if(sym_exists(cp, len))
				{
					strloc = xmalloc(len+1);
					strcpy(strloc, cp);
					lexports->fptr = xmalloc(sizeof(EXPORTS));
					lexports = lexports->fptr;
					lexports->name = strloc;
					lexports->len = len;
				}
			}
		}
		else if(!strncmp(buf, "rename", 6))
		{
			if((cp = find_sym(cp)) != NULL)
			{
			int oldlen;
			char *oldstr;

				oldlen = strlen(cp);
				if(sym_exists(cp, oldlen))
				{
				  oldstr = cp;
				  cp += oldlen+1;
				  if((cp = find_sym(cp)) != NULL)
				  {
				  int newlen = strlen(cp);
				  char *newstr = cp;
				  char *oldloc = xmalloc(oldlen+1);
				  char *newloc = xmalloc(newlen+1);
					strcpy(oldloc, oldstr);
					strcpy(newloc, newstr);
					lrenames->fptr = xmalloc(sizeof(RENAMES));
					lrenames = lrenames->fptr;
					lrenames->oldname = oldloc;
					lrenames->oldlen = oldlen;
					lrenames->newname = newloc;
					lrenames->newlen = newlen; 
					rename_diftot += newlen - oldlen;
				  }
				}
			}
		}
	}
}
static void
coff_proc_outfile(FILE *fd)
{/* write coff format output file */
PCOFF_HDR p = (PCOFF_HDR)&header;
POXHDR hdr = &xhdr;
int i;

	/* rename symbols and set exported symbols to global */
	adjust_strings(0);

	fseek(fd, 0, 0);

	/* header */
	fwrite(p, sizeof(COFF_HDR), 1, fd);

	/* section headers */
	fwrite(s, hdr->section_headers_size, 1, fd);

	/* sections */
	for(i = 0; i < p->f_nscns; ++i)
	{
	PSCNHDR q = &s[i];
		if(q->s_scnptr)
		{/* section has writeable data */
			q->s_scnptr = ftell(fd);	/* new file offset */
			fwrite(sbf[i].addr, sbf[i].size, 1, fd);
		}
	}
	/* relocs */
	for(i = 0; i < p->f_nscns; ++i)
	{
	PSCNHDR q = &s[i];
		if(q->s_nreloc > 0 && rbf[i].size > 0)
		{/* section has relocs */
			q->s_relptr = ftell(fd);
			fwrite(rbf[i].addr, rbf[i].size, 1, fd);
		}
		else
		{
			q->s_nreloc = 0;
			q->s_relptr = 0;
		}
	}
	/* line numbers */
	for(i = 0; i < p->f_nscns; ++i)
	{
	PSCNHDR q = &s[i];
		if(q->s_nlnno > 0 && lbf[i].size > 0)
		{/* section has line numbers */
			q->s_lnnoptr = ftell(fd);
			fwrite(lbf[i].addr, lbf[i].size, 1, fd);
		}
		else
		{
			q->s_nlnno = 0;
			q->s_lnnoptr = 0;
		}
	}
	/* symbols */
	p->f_symptr = ftell(fd);
	fwrite(coff_symtbl, hdr->symbols_size, 1, fd);	

	/* strings */
	fwrite((char *)&nstrsize, sizeof(nstrsize), 1, fd);
	if(nstrsize)
	  fwrite(nstrtbl+sizeof(nstrsize),nstrsize,1,fd);

	/* reset section headers and symbols */
	fflush(fd);
	fseek(fd, 0, 0);
	fwrite(p, sizeof(COFF_HDR), 1, fd);
	fwrite(s, hdr->section_headers_size, 1, fd);
	fflush(fd);
}
static void
aout_proc_outfile(FILE *fd)
{/* write aout format output file */

	/* rename symbols and set exported symbols to global */
	adjust_strings(sizeof(nstrsize));

	fseek(fd, 0, 0);

	/* header */
	fwrite((char *)&header, sizeof(struct exec), 1, fd);

	/* text */
	if(header.a_text)
		fwrite(text, (u_int)header.a_text, 1, fd);

	/* data */
	if(header.a_data)
		fwrite(data, (u_int)header.a_data, 1, fd);

	/* text relocs */
	if(header.a_trsize)
		fwrite((char *)text_relocs, (u_int)header.a_trsize, 1, fd);

	/* data relocs */
	if(header.a_drsize);
		fwrite((char *)data_relocs, (u_int)header.a_drsize, 1, fd);

	/* symbol table */
	if(header.a_syms)
		fwrite((char *)symtbl, (u_int)header.a_syms, 1, fd);

	/* strings */
	fwrite((char *)&nstrsize, sizeof(nstrsize), 1, fd);
	if(nstrsize)
	  fwrite(nstrtbl+sizeof(nstrsize),nstrsize-sizeof(nstrsize),1,fd);
	fflush(fd);
}
#ifdef SKELETON
int obj4lb(int argc, char **argv)
#else
int main(int argc, char **argv)
#endif
{
char *str;
int i, j;
char chr;


  if (argc != 2) usage();
  strcpy(infile,argv[1]);
  lose_backslashes(infile);
  strcpy(outfile,infile);
  strcpy(lb4file,infile);
  fix_suffix(outfile, ".olb");
  fix_suffix(lb4file, ".4lb");

  /* process the input file */
  if(proc_infile(infile))
  {
	  fclose(ifd);
	  /* process the specification file */
	  lb4fd = fopen(lb4file, "r"); 
	  if(lb4fd)
	  {
		proc_4lb();
		fclose(lb4fd);
	  } else {
	  	puts("4lb: warning export file not found");
	  }
	  ofd = fopen(outfile, "w+b");
	  if(N_MAGIC(header) == OMAGIC)
		aout_proc_outfile(ofd);
	  else
	  	coff_proc_outfile(ofd);
	  fclose(ofd);
  }
  return 0;   
}

⌨️ 快捷键说明

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