void BuildBrowse(ObjFile &file, ObjFactory &factory, ObjLineNo *l) { ObjBrowseInfo *b = factory.MakeBrowseInfo(ObjBrowseInfo::eFuncStart, ObjBrowseInfo::eExternal, l, "hi dave"); file.Add(b); l = factory.MakeLineNo(l->GetFile(), 27); b = factory.MakeBrowseInfo(ObjBrowseInfo::eVariable, ObjBrowseInfo::eStatic, l, "hi dave"); file.Add(b); }
ObjFile *MakeData(ObjFactory &factory) { ObjFile *rv = factory.MakeFile("test.dat"); std::time_t x = std::time(0); rv->SetFileTime(*std::localtime(&x)); ObjSourceFile *sf = factory.MakeSourceFile("test.dat"); rv->Add(sf); ObjSourceFile *sf1 = factory.MakeSourceFile("q.dat"); rv->Add(sf1); ObjSection *sect = factory.MakeSection("code"); codeSection = sect; rv->Add(sect); ObjSymbol *s1 = factory.MakePublicSymbol("public"); rv->Add(s1); ObjSymbol *s1a = factory.MakePublicSymbol("2public"); s1a->SetBaseType(BuildType(*rv, factory)); rv->Add(s1a); ObjSymbol *s2 = factory.MakeLocalSymbol("local"); s2->SetBaseType(factory.MakeType(ObjType::eInt)); rv->Add(s2); ObjSymbol *s3 = factory.MakeAutoSymbol("auto"); s3->SetOffset(factory.MakeExpression(-8)); rv->Add(s3); ObjSymbol *s4 = factory.MakeExternalSymbol("extern"); rv->Add(s4); ObjMemory *mem = factory.MakeData((ObjByte *)"\x44\x22\x33\x11", 4); ObjLineNo *l = factory.MakeLineNo(sf, 3); mem->Add(factory.MakeDebugTag(l)); sect->Add(mem); mem = factory.MakeData((ObjByte *)"\xaa\xbb\x33", 3); mem->Add(factory.MakeDebugTag(s1)); sect->Add(mem); mem = factory.MakeData((ObjByte *)"\xf1\x9a\x33", 3); mem->Add(factory.MakeDebugTag(s2)); l = factory.MakeLineNo(sf1, 4); mem->Add(factory.MakeDebugTag(l)); sect->Add(mem); mem = factory.MakeData((ObjByte *)"\x32\x17\x33", 3); mem->Add(factory.MakeDebugTag(s3)); sect->Add(mem); ObjExpression *left = factory.MakeExpression(s4); ObjExpression *right = factory.MakeExpression(7); mem = factory.MakeFixup(factory.MakeExpression(ObjExpression::eAdd, left, right), 4); sect->Add(mem); mem = factory.MakeData((ObjByte *)"\x55\x44\x33", 3); mem->Add(factory.MakeDebugTag(s4)); mem->Add(factory.MakeDebugTag(s1a)); sect->Add(mem); BuildBrowse(*rv, factory, l); ObjExportSymbol *es = factory.MakeExportSymbol("export"); es->SetExternalName("myexport"); es->SetByOrdinal(false); rv->Add(es); ObjExportSymbol *es1 = factory.MakeExportSymbol("export1"); es1->SetOrdinal(500); es1->SetByOrdinal(true); rv->Add(es1); ObjImportSymbol *is = factory.MakeImportSymbol("import"); is->SetExternalName("myimport"); is->SetDllName("mydll"); rv->Add(is); ObjImportSymbol *is1 = factory.MakeImportSymbol("import1"); is1->SetByOrdinal(true); is1->SetOrdinal(512); is1->SetDllName("mydll"); rv->Add(is1); return rv; }
ObjFile *CoffFile::ConvertToObject(std::string outputName, ObjFactory &factory) { ObjFile *fil = new ObjFile(outputName); std::vector<ObjSection *> objectSections; std::map<int, ObjSymbol *> externalMapping; // Create the sections; for (int i=0; i < header.NumberOfSections; i++) { if (!(sections[i].Characteristics & (IMAGE_SCN_LNK_REMOVE | IMAGE_SCN_LNK_INFO)) && strnicmp(sections[i].Name, ".debug", 6)) { std::string sectname = GetSectionName(i); ObjSection * sect = factory.MakeSection(sectname); CoffSectionAux *aux = (CoffSectionAux *)& sectionSymbols[i][1]; sect->SetSize(new ObjExpression(aux->Length)); sect->SetAlignment(IMAGE_SCN_ALIGN(sections[i].Characteristics)); sect->SetQuals(GetSectionQualifiers(i)); fil->Add(sect); objectSections.push_back(sect); } else { objectSections.push_back(NULL); } } // dump comdefs for (int i=1; i < header.NumberOfSymbols; i+= symbols[i].NumberOfAuxSymbols + 1) { if (symbols[i].SectionNumber > header.NumberOfSections && symbols[i].StorageClass == IMAGE_SYM_CLASS_EXTERNAL && symbols[i].Value) { char *sname = symbols[i].Name; std::string symbolName; if (*(unsigned *)sname == 0) { symbolName = strings + *(unsigned *)(sname + 4); } else { symbolName = symbols[i].Name; if (symbolName.size() > 8) symbolName = symbolName.substr(0, 8); } symbolName = std::string("vsb") + symbolName; ObjSection * sect = factory.MakeSection(symbolName); sect->SetSize(new ObjExpression(symbols[i].Value)); sect->SetAlignment(8); sect->SetQuals(ObjSection::ram | ObjSection::max | ObjSection::virt); fil->Add(sect); objectSections.push_back(sect); } } // create the symbols for (int i=0; i < header.NumberOfSymbols; i+= symbols[i].NumberOfAuxSymbols + 1) { if (symbols[i].StorageClass == IMAGE_SYM_CLASS_EXTERNAL && symbols[i].SectionNumber <= header.NumberOfSections) { if (symbols[i].SectionNumber <= 0 || (((CoffSectionAux *)§ionSymbols[symbols[i].SectionNumber-1][1])->Selection <= 1)) { char *sname = symbols[i].Name; std::string symbolName; if (*(unsigned *)sname == 0) { symbolName = strings + *(unsigned *)(sname + 4); if (symbolName == "_WinMain@16") symbolName = "WinMain"; } else { symbolName = symbols[i].Name; if (symbolName.size() > 8) symbolName = symbolName.substr(0, 8); } if (symbols[i].SectionNumber == -1) { ObjSymbol *symbol = factory.MakePublicSymbol(symbolName); ObjExpression *exp = new ObjExpression(symbols[i].Value); symbol->SetOffset(exp); fil->Add(symbol); } else if (symbols[i].SectionNumber) { ObjSymbol *symbol = factory.MakePublicSymbol(symbolName); ObjExpression *exp = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[i].SectionNumber-1]), new ObjExpression(symbols[i].Value)); symbol->SetOffset(exp); fil->Add(symbol); } else { ObjSymbol *symbol = factory.MakeExternalSymbol(symbolName); externalMapping[i] = symbol; fil->Add(symbol); } } } } // dump data to the sections for (int i=0; i < header.NumberOfSections; i++) { if (objectSections[i]) { int len = sections[i].SizeOfRawData; if (len) { inputFile->seekg(sections[i].PointerToRawData + libOffset); int relocCount = sections[i].NumberOfRelocations; CoffReloc * relocPointer = relocs[i]; if (relocCount == 0xffff && (sections[i].Characteristics & IMAGE_SCN_LNK_NRELOC_OVFL)) { relocCount = relocPointer[0].VirtualAddress; relocPointer++; } unsigned offset = 0; inputFile->clear(); while (offset < sections[i].SizeOfRawData) { if (!relocCount) { ObjByte *data = new ObjByte[sections[i].SizeOfRawData-offset]; inputFile->read((char *)data, sections[i].SizeOfRawData-offset); if (inputFile->fail()) { return NULL; } ObjMemory *newMem = new ObjMemory(data, sections[i].SizeOfRawData-offset); objectSections[i]->Add(newMem); offset = sections[i].SizeOfRawData; } else { unsigned fixupOffset; int n = relocPointer->VirtualAddress - offset; if (n) { ObjByte *data = new ObjByte[n]; inputFile->read((char *)data, n); if (inputFile->fail()) { return NULL; } ObjMemory *newMem = new ObjMemory(data, n); objectSections[i]->Add(newMem); } inputFile->read((char *)&fixupOffset, sizeof(unsigned)); if (inputFile->fail()) { return NULL; } switch (relocPointer->Type) { ObjExpression *fixupExpr; case IMAGE_REL_I386_DIR32: case IMAGE_REL_I386_REL32: if (symbols[relocPointer->SymbolTableIndex].StorageClass == IMAGE_SYM_CLASS_EXTERNAL) { if (symbols[relocPointer->SymbolTableIndex].SectionNumber == 0) { // external fixupExpr = new ObjExpression(externalMapping[relocPointer->SymbolTableIndex]); } else if (symbols[relocPointer->SymbolTableIndex].SectionNumber > header.NumberOfSections) { fixupExpr = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[relocPointer->SymbolTableIndex].SectionNumber-1]), new ObjExpression(0)); } else { // public fixupExpr = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[relocPointer->SymbolTableIndex].SectionNumber-1]), new ObjExpression(symbols[relocPointer->SymbolTableIndex].Value)); } } else { // local static fixupExpr = new ObjExpression(ObjExpression::eAdd, new ObjExpression(objectSections[symbols[relocPointer->SymbolTableIndex].SectionNumber-1]), new ObjExpression(symbols[relocPointer->SymbolTableIndex].Value)); } if (relocPointer->Type == IMAGE_REL_I386_REL32) { fixupExpr = new ObjExpression(ObjExpression::eAdd, fixupExpr, new ObjExpression(fixupOffset - 4)); fixupExpr = new ObjExpression(ObjExpression::eSub, fixupExpr, new ObjExpression(ObjExpression::ePC) ); } else if (fixupOffset) { fixupExpr = new ObjExpression(ObjExpression::eAdd, fixupExpr, new ObjExpression(fixupOffset)); } objectSections[i]->Add(new ObjMemory(fixupExpr, 4)); break; default: std::cout << "Invalid relocation" << std::endl; return NULL; } offset += n + 4; relocPointer++; relocCount--; } } } } } for (int i=1; i < header.NumberOfSymbols; i+= symbols[i].NumberOfAuxSymbols + 1) { if (symbols[i].SectionNumber > header.NumberOfSections && symbols[i].StorageClass == IMAGE_SYM_CLASS_EXTERNAL && symbols[i].Value) { int n = symbols[i].SectionNumber-1; ObjByte *data = new ObjByte[symbols[i].Value]; memset(data,0, symbols[i].Value); ObjMemory *newMem = new ObjMemory(data, symbols[i].Value); objectSections[n]->Add(newMem); } } return fil; }