📄 obj4lb.c
字号:
/* 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 + -