bool ObjIeeeAscii::SectionAlignment(const char *buffer, eParseType ParseType) { if (!file) ThrowSyntax(buffer, ParseType); int pos = 2; int index = ObjUtil::FromHex(buffer, &pos); if (buffer[pos++] != ',') ThrowSyntax(buffer, ParseType); int align = ObjUtil::FromHex(buffer, &pos); CheckTerm(buffer + pos); ObjSection *sect = GetSection(index); if (!sect) ThrowSyntax(buffer, ParseType); sect->SetAlignment(align); return false; }
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; }
bool Section::MakeData(ObjFactory &factory, AsmFile *fil) { bool rv = true; int pc = 0; int pos = 0; unsigned char buf[1024]; Fixup f; int n; ObjSection *sect = objectSection; if (sect) { sect->SetAlignment(align); instructionPos = 0; while ((n = GetNext(f, buf+pos, sizeof(buf) - pos)) != 0) { if (n > 0) { pos += n; if (pos == sizeof(buf)) { ObjMemory *mem = factory.MakeData(buf, pos); sect->Add(mem); pos = 0; } pc += n; } else { if (pos) { ObjMemory *mem = factory.MakeData(buf, pos); sect->Add(mem); pos = 0; } ObjExpression *t; try { t = ConvertExpression(f.GetExpr(), fil, factory); SwapSectionIntoPlace(t); } catch (std::runtime_error *e) { Errors::IncrementCount(); std::cout << "Error " << f.GetFileName().c_str() << "(" << f.GetErrorLine() << "):" << e->what() << std::endl; delete e; t = nullptr; rv = false; } if (t && f.IsRel()) { ObjExpression *left = factory.MakeExpression(f.GetRelOffs()); t = factory.MakeExpression(ObjExpression::eSub, t, left); left = factory.MakeExpression(ObjExpression::ePC); t = factory.MakeExpression(ObjExpression::eSub, t, left); } if (t) { ObjMemory *mem = factory.MakeFixup(t, f.GetSize()); if (mem) sect->Add(mem); } pc += f.GetSize(); } } if (pos) { ObjMemory *mem = factory.MakeData(buf, pos); sect->Add(mem); } } return rv; }