📄 coff.c
字号:
sp++;
}
if (write(pfd,(char *)obase,sdata-obase) != (sdata-obase)) {
perror(packto);
exit(1);
}
close(pfd);
free(ibase);
free(obase);
printf("Total savings of %d bytes\n",savings);
}
zipdata(src,dest,srcsize,mode,verbose)
char *src, *dest, *mode;
int srcsize, verbose;
{
int zfd;
FILE *zout;
char *zoutfile;
struct stat zstat;
zoutfile = "zout";
unlink(zoutfile);
zout = gzopen(zoutfile, mode);
if (zout == NULL) {
fprintf(stderr, "can't gzopen %s\n", zoutfile);
exit(1);
}
if (gzwrite(zout, src, (unsigned)srcsize) != srcsize) {
fprintf(stderr, "gzwrite failed\n");
exit(1);
}
if (gzclose(zout) != Z_OK) {
fprintf(stderr, "gzclose failed\n");
exit(1);
}
stat(zoutfile,&zstat);
if ((zfd = open(zoutfile,O_RDONLY|O_BINARY)) == -1) {
fprintf(stderr, "can't open %s\n",zoutfile);
exit(1);
}
Read(zfd,dest,zstat.st_size);
close(zfd);
unlink(zoutfile);
if (verbose) {
printf("%d%% compression (from %d to %d bytes)\n",
(int)(((double)(zstat.st_size)/
(double)srcsize)*100),srcsize,zstat.st_size);
}
return(zstat.st_size);
}
void
ZipCoffSections(int zlevel)
{
char *ibuf,*obuf, *sdata, *obase, *ibase;
int i, pfd, sno, savings;
char zipto[128], mode[16];
struct stat finfo;
struct filehdr *coffp;
struct scnhdr *sp;
sprintf(mode,"wb%d ",zlevel);
sprintf(zipto,"%s.czip",coffFname);
fprintf(stderr,"Compressing %s into %s \n",coffFname,zipto);
unlink(zipto);
if ((pfd = open(zipto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1) {
perror(zipto);
exit(1);
}
fprintf(stderr,"Zipping %s into %s...\n",coffFname,zipto);
/* First copy the entire COFF file into the input buffer: */
fstat(coffFD,&finfo);
Lseek(coffFD,0,SEEK_SET);
ibuf = Malloc(finfo.st_size+32);
ibase = ibuf;
obuf = Malloc(finfo.st_size+32);
obase = obuf;
coffp = (struct filehdr *)obase;
Read(coffFD,ibuf,finfo.st_size);
/* Now copy the file header and optional header to the out buffer: */
for(i=0;i<sizeof(struct filehdr)+CoffFhdr.f_opthdr;i++)
*obuf++ = *ibuf++;
/* Since the output file will be stripped, modify the new header: */
coffp->f_symptr = 0;
coffp->f_nsyms = 0;
/* At this point ibuf & obuf are at the base of the table of section */
/* headers. The section headers must be adjusted because the size */
/* of the sections will be changing, so for each section, compress */
/* the data and adjust the header information... */
sp = (struct scnhdr *)obuf;
/* Set sdata to point into the new buffer at the point immediately */
/* after the headers. This pointer will be used to write the new */
/* compressed sections. */
sdata = obase + sizeof(struct filehdr) + CoffFhdr.f_opthdr +
(CoffFhdr.f_nscns * sizeof(struct scnhdr));
/* For each section, if the section is loadable, the compress the */
/* data associated with that section... */
savings = 0;
for (sno=0;sno<CoffFhdr.f_nscns;sno++) {
int psize;
/* If the section has data, compress it and adjust the */
/* section header information. */
if (ScnTbl[sno].s_scnptr) {
/* Compress the section: */
printf("Section %s: ",ScnTbl[sno].s_name);
psize = zipdata(ibase+ScnTbl[sno].s_scnptr,sdata,
ScnTbl[sno].s_size,mode,1);
/* Keep track of total space saved: */
savings += (ScnTbl[sno].s_size - psize);
/* Adjust the affected section header members: */
ScnTbl[sno].s_size = psize;
ScnTbl[sno].s_scnptr = (unsigned long)(sdata - obase);
sdata += psize;
}
memcpy(sp->s_name,ScnTbl[sno].s_name,8);
sp->s_paddr = otherEnd32(Ecvt,ScnTbl[sno].s_paddr);
sp->s_vaddr = otherEnd32(Ecvt,ScnTbl[sno].s_vaddr);
sp->s_size = otherEnd32(Ecvt,ScnTbl[sno].s_size);
sp->s_scnptr = otherEnd32(Ecvt,ScnTbl[sno].s_scnptr);
sp->s_relptr = otherEnd32(Ecvt,ScnTbl[sno].s_relptr);
sp->s_lnnoptr = otherEnd32(Ecvt,ScnTbl[sno].s_lnnoptr);
sp->s_nreloc = otherEnd16(Ecvt,ScnTbl[sno].s_nreloc);
sp->s_nlnno = otherEnd16(Ecvt,ScnTbl[sno].s_nlnno);
sp->s_flags = otherEnd32(Ecvt,ScnTbl[sno].s_flags);
sp++;
}
if (write(pfd,(char *)obase,sdata-obase) != (sdata-obase)) {
perror(zipto);
exit(1);
}
close(pfd);
free(ibase);
free(obase);
printf("Total savings of %d bytes\n",savings);
}
void
StripCoffFile(char *stripto,char *append)
{
int size, sfd, afd;
struct filehdr *coffp;
unlink(stripto);
if ((sfd = open(stripto,O_WRONLY|O_BINARY|O_CREAT,0777))==-1)
{
perror(stripto);
exit(1);
}
fprintf(stderr,"Stripping %s into %s...\n",
coffFname,stripto);
Lseek(coffFD,0,SEEK_SET);
size = CoffFhdr.f_symptr;
coffp = (struct filehdr *)Malloc(size+32);
Read(coffFD,(char *)coffp,size);
coffp->f_symptr = 0;
coffp->f_nsyms = 0;
if (write(sfd,(char *)coffp,size) != size) {
perror(stripto);
exit(1);
}
if (append) {
struct stat buf;
char *aspace;
if ((afd = open(append,O_RDONLY|O_BINARY))==-1)
{
perror(append);
exit(1);
}
stat(append,&buf);
aspace = Malloc(buf.st_size+32);
read(afd,aspace,buf.st_size);
write(sfd,aspace,buf.st_size);
free(aspace);
close(afd);
}
close(sfd);
}
char *usage_txt[] = {
"Usage: coff [options] {filename}",
" Options:",
" -a{filename} append file to end of -S file",
" -A print what was appended by -a",
" -B{filename} coff-2-bin to filename",
" -c BE-to-LE convert",
" -f show coff file header",
" -M show coff map with file offsets",
" -m show coff map without file offsets",
" -n no padding with -B option",
" -p{filename} pack to specified file (output file is also stripped)",
" -s show coff section headers",
" -S{filename} strip to specified file",
" -V display version of tool",
" -v verbose mode",
" -z{zlvl} compress sections of filename to 'filename.czip'",
" zlvl can range from 1-9 (typically 6) where...",
" 1 is faster/lighter compression",
" 9 is slower/heavier compression",
0,
};
main(argc,argv)
int argc;
char *argv[];
{
extern int optind;
extern char *optarg;
char fname[128], *append, *stripto, *binto, *packto;
int tot, opt, showstuff, zlevel;
zlevel = verbose = 0;
showstuff = 0;
packto = (char *)0;
stripto = (char *)0;
append = (char *)0;
binto = (char *)0;
noPad = 0;
#ifdef BUILD_WITH_VCC
Ecvt = 1;
#else
Ecvt = 0;
#endif
while ((opt=getopt(argc,argv,"Aa:cB:dfmMnp:sS:vVz:")) != EOF) {
switch(opt) {
case 'a':
append = optarg;
break;
case 'A':
showstuff |= SHOWAPPEND;
break;
case 'B':
binto = optarg;
break;
case 'c':
if (Ecvt)
Ecvt = 0;
else
Ecvt = 1;
break;
case 'f':
showstuff |= SHOWHDR;
break;
case 'M':
showstuff |= SHOWMAPOFFSET;
break;
case 'm':
showstuff |= SHOWMAP;
break;
case 'n':
noPad = 1;
break;
case 'p':
packto = optarg;
break;
case 'S':
stripto = optarg;
break;
case 's':
showstuff |= SHOWSECTIONS;
break;
case 'v':
verbose = 1;
break;
case 'V':
showVersion();
break;
case 'z':
zlevel = atoi(optarg);
if ((zlevel < 1) || (zlevel > 9))
usage("zlvl out of range\n");
break;
default:
usage(0);
}
}
if (argc != (optind+1))
usage("Missing filename");
strcpy(fname,argv[optind]);
if (!fileexists(fname)) {
fprintf(stderr,"No such file: %s\n",fname);
exit(1);
}
if ((coffFD = open(fname,O_RDONLY|O_BINARY)) == -1)
{
perror(fname);
exit(1);
}
if (append && !stripto)
usage("-a requires -S");
tot = 0;
if (binto) tot++;
if (packto) tot++;
if (stripto) tot++;
if (tot > 1)
usage("-S, -B and -p options must be run individually");
coffFname = StrAllocAndCopy(fname);
GetCoffFileHdr();
GetCoffSectionHdrs();
if (binto) {
CoffToBinary(binto);
}
else if (zlevel) {
ZipCoffSections(zlevel);
}
else if (packto) {
PackCoffSections(packto);
}
else if (stripto) {
StripCoffFile(stripto,append);
}
else {
if (showstuff & SHOWAPPEND)
ShowAppend();
if (showstuff & SHOWHDR)
ShowCoffHdr();
if (showstuff & SHOWMAP)
ShowCoffMap();
if (showstuff & SHOWMAPOFFSET)
ShowCoffOffsets();
if (showstuff & SHOWSECTIONS)
ShowCoffSections();
}
exit(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -