// mapconv - symbolic debugging info generator for VirtualDub // Copyright (C) 2002 Avery Lee, All Rights Reserved // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include #include #include #include #include #define MAX_CNAMBUF (0x20000) #define MAX_FNAMBUF (0x200000) #define MAX_SEGMENTS (64) #define MAX_GROUPS (64) struct RVAEnt { long rva; char *line; }; std::vector rvabuf; char fnambuf[MAX_FNAMBUF]; char *fnamptr = fnambuf; long segbuf[MAX_SEGMENTS][2]; int segcnt=0; int seggrp[MAX_SEGMENTS]; long grpstart[MAX_GROUPS]; char line[8192]; long codeseg_flags = 0; FILE *f, *fo; char *strtack(char *s, const char *t, const char *s_max) { while(s < s_max && (*s = *t)) ++s, ++t; if (s == s_max) return NULL; return s+1; } bool readline() { if (!fgets(line, sizeof line, f)) return false; int l = strlen(line); if (l>0 && line[l-1]=='\n') line[l-1]=0; return true; } bool findline(const char *searchstr) { while(readline()) { if (strstr(line, searchstr)) return true; } return false; } /////////////////////////////////////////////////////////////////////////// void parsename(long rva, char *func_name) { fnamptr = strtack(fnamptr, func_name, fnambuf+MAX_FNAMBUF); if(!fnamptr) throw "Too many func names; increase MAX_FNAMBUF."; } struct RVASorter { bool operator()(const RVAEnt& e1, const RVAEnt& e2) { return e1.rva < e2.rva; } }; int main(int argc, char **argv) { int ver=0; int i; long load_addr; if (argc<3) { printf("mapconv \n"); return 0; } if (f=fopen("version.bin", "rb")) { fread(&ver,4,1,f); fclose(f); } else { printf("can't read version file\n"); return 20; } if (!(f=fopen(argv[1], "r"))) { printf("can't open listing file \"%s\"\n", argv[1]); return 20; } if (!(fo=fopen(argv[2], "wb"))) { printf("can't open output file \"%s\"\n", argv[2]); return 20; } // Begin parsing file try { line[0] = 0; // printf("Looking for segment list.\n"); if (!findline("Start Length")) throw "can't find segment list"; // printf("Reading in segment list.\n"); while(readline()) { long grp, start, len; if (3!=sscanf(line, "%lx:%lx %lx", &grp, &start, &len)) break; if (strstr(line+49, "CODE")) { // printf("%04x:%08lx %08lx type code\n", grp, start, len); codeseg_flags |= 1<::iterator itRVA = rvabuf.begin(), itRVAEnd = rvabuf.end(); std::vector rvaout; long firstrva = (*itRVA++).rva; long lastrva = firstrva; for(; itRVA != itRVAEnd; ++itRVA) { long rvadiff = (*itRVA).rva - lastrva; lastrva += rvadiff; if (rvadiff & 0xF0000000) rvaout.push_back((char)(0x80 | ((rvadiff>>28) & 0x7F))); if (rvadiff & 0xFFE00000) rvaout.push_back((char)(0x80 | ((rvadiff>>21) & 0x7F))); if (rvadiff & 0xFFFFC000) rvaout.push_back((char)(0x80 | ((rvadiff>>14) & 0x7F))); if (rvadiff & 0xFFFFFF80) rvaout.push_back((char)(0x80 | ((rvadiff>> 7) & 0x7F))); rvaout.push_back((char)(rvadiff & 0x7F)); } // printf("%ld bytes\n", rvaout.size()); // dump data static const char header[64]="StepMania symbolic debug information\r\n\x1A"; fwrite(header, 64, 1, fo); long t; t = ver; fwrite(&t, 4, 1, fo); t = rvaout.size() + 4; fwrite(&t, 4, 1, fo); t = fnamptr - fnambuf; fwrite(&t, 4, 1, fo); t = segcnt; fwrite(&t, 4, 1, fo); fwrite(&firstrva, 4, 1, fo); fwrite(&rvaout[0], rvaout.size(), 1, fo); fwrite(fnambuf, fnamptr - fnambuf, 1, fo); fwrite(segbuf, segcnt*8, 1, fo); // really all done if (fclose(fo)) throw "output file close failed"; } catch(const char *s) { fprintf(stderr, "%s: %s\n", argv[1], s); } fclose(f); return 0; }