rossj@cognos.UUCP (Ross Judson) (02/01/91)
I recently posted asking if anyone was aware of a profiler for MWC v3.
With no response, I still needed to profile some code. This short
program, compiled under version 3, regresses a v3 binary back to v2.
You can then use David Rowley's profiler on it.
This was all done by experimentation, so I don't know if I'm
performing the conversion correctly. If anybody improves it, please
let me know.
The program doesn't check to see that you're actually converting a v3
binary, so use it with caution (convert a backup). You can verify
that the conversion worked with the 'file' command.
#include <stdio.h>
#include <gemout.h>
#include <nout.h>
#include <canon.h>
char buffer[32000];
char other_crap[32000];
main(argc,argv)
int argc;
char *argv[];
{
FILE *in;
struct gemohdr gem_head;
long where_to;
struct ldheader ld_head;
int table_size;
int crap_size;
int i;
if (argc < 2) {
fprintf(stderr,"usage -- v3tov2 <executable>\n");
exit(-1);
}
printf("Opening %s.\n",argv[1]);
in = fopen(argv[1],"rwb");
printf("Reading header.\n");
if (fread(&gem_head,sizeof gem_head, 1, in) != 1) {
fprintf(stderr,"Couldn't read input file.\n");
exit(-1);
}
if (gem_head.g_magic != GEMOMAGIC) {
fprintf(stderr,"Not an executable file.\n");
exit(-1);
}
printf("Text segment=%7ld bytes\n",gem_head.g_ssize[0]);
printf("Data segment=%7ld bytes\n",gem_head.g_ssize[1]);
printf("Bss segment=%7ld bytes\n",gem_head.g_ssize[2]);
printf("Sym segment=%7ld bytes\n",gem_head.g_ssize[3]);
where_to = (long)(sizeof gem_head) +
gem_head.g_ssize[0] +
gem_head.g_ssize[1];
printf("Seeking symbol table at %ld.\n",where_to);
fseek(in,where_to,0);
printf("Reading link header.\n");
if (fread(&ld_head,sizeof ld_head,1,in) != 1) {
fprintf(stderr,"Couldn't read link header.\n");
exit(-1);
}
if (canshort(ld_head.l_magic) != L_MAGIC) {
fprintf(stderr,"Didn't find link header magic number.\n");
/* exit(-1); */
}
printf("Reading symbol table.\n");
table_size = fread(buffer,1,(int)canlong(ld_head.l_ssize[L_SYM]),in);
printf("Symbol table is %d bytes long.\n",table_size);
printf("Reading trailer.\n");
crap_size = fread(other_crap,1,32000,in);
printf("There were %d bytes of trailer.\n",crap_size);
fseek(in,where_to,0);
fwrite(other_crap,1,crap_size,in);
ld_head.l_magic = canshort(ld_head.l_magic);
ld_head.l_flag = canshort(ld_head.l_flag);
ld_head.l_machine = canshort(ld_head.l_machine);
ld_head.l_tbase = canshort(ld_head.l_tbase);
for (i = 0; i < NLSEG; i++)
ld_head.l_ssize[i] = canlong(ld_head.l_ssize[i]);
ld_head.l_entry = canlong(ld_head.l_entry);
fwrite(&ld_head,sizeof ld_head,1,in);
fwrite(buffer,1,table_size,in);
printf("Changing GEM header.\n");
gem_head.g_ssize[GO_SYM] = 0L;
rewind(in);
if (fwrite(&gem_head,sizeof gem_head, 1, in) != 1) {
fprintf(stderr,"Couldn't write to file.\n");
exit(-1);
}
printf("Closing file.\n");
fclose(in);
exit(0);
}
--
Ross Judson ++ uunet!mitel!cunews!cognos!rossj + end of the road i'm travelling
Cognos Inc. ++ rossj@cognos.uucp + i will see jordan beckoning...