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; }
bool ObjIeeeAscii::GetOffset(const char *buffer, eParseType ParseType) { if (!file) ThrowSyntax(buffer, ParseType); int pos =3 ; char ch = buffer[2]; int index = 0; if (ch != 'G') index = ObjUtil::FromHex(buffer, &pos); if (buffer[pos++] != ',') ThrowSyntax(buffer, ParseType); ObjExpression *exp = GetExpression(buffer, &pos); CheckTerm(buffer + pos); switch(ch) { case 'G': SetStartAddress(file, exp); break; case 'S': { ObjSection *sect = GetSection(index); if (!sect) ThrowSyntax(buffer, ParseType); sect->SetSize(exp); break; } case 'L': { ObjSection *sect = GetSection(index); if (!sect) ThrowSyntax(buffer, ParseType); sect->SetOffset(exp); break; } default: { ObjSymbol *sym = FindSymbol(ch, index); if (!sym) ThrowSyntax(buffer, ParseType); sym->SetOffset(exp); break; } } return false; }
bool Real::ReadSections(ObjFile *file, ObjExpression *start) { size = 0; int base = GetFirstSeg(start); startOffs = start->Eval(0); startSeg = base >> 16; for (ObjFile::SectionIterator it = file->SectionBegin(); it != file->SectionEnd(); ++it) { if ((*it)->GetName() == ".stack") { stackSeg = (*it)->GetOffset()->Eval(0) / 16; stackOffs = (*it)->GetSize()->Eval(0); } else { int n = (*it)->GetOffset()->Eval(0) + (*it)->GetSize()->Eval(0); if (n > size) size = n; } } data = new unsigned char[size]; int ofs = 0; for (ObjFile::SectionIterator it = file->SectionBegin(); it != file->SectionEnd(); ++it) { if ((*it)->GetName() != ".stack") { ObjSection *sect = *it; ObjMemoryManager &m = sect->GetMemoryManager(); for (ObjMemoryManager::MemoryIterator it = m.MemoryBegin(); it != m.MemoryEnd(); ++it) { int msize = (*it)->GetSize(); ObjByte *mdata = (*it)->GetData(); if (msize) { ObjExpression *fixup = (*it)->GetFixup(); if (fixup) { int sbase = sect->GetOffset()->Eval(0); int n = GetFixupOffset(fixup, sbase, ofs); int bigEndian = file->GetBigEndian(); if (n < 0) Utils::fatal("Fixup offset negative"); if (msize == 1) { data[ofs] = n & 0xff; } else if (msize == 2) { if (n >65535) Utils::fatal("16-bit offset outside of segment"); if (bigEndian) { data[ofs] = n >> 8; data[ofs + 1] = n & 0xff; } else { data[ofs] = n & 0xff; data[ofs+1] = n >> 8; } } else // msize == 4 { if (bigEndian) { data[ofs + 0] = n >> 24; data[ofs + 1] = n >> 16; data[ofs + 2] = n >> 8; data[ofs + 3] = n & 0xff; } else { data[ofs] = n & 0xff; data[ofs+1] = n >> 8; data[ofs+2] = n >> 16; data[ofs+3] = n >> 24; } } } else { if ((*it)->IsEnumerated())
bool ObjIeeeAscii::SectionAttributes(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); ObjInt quals = 0; ObjString name; while (buffer[pos]) { switch (buffer[pos++]) { case 'A': quals |= ObjSection::absolute; break; case 'B': quals |= ObjSection::bit; break; case 'C': quals |= ObjSection::common; break; case 'E': quals |= ObjSection::equal; break; case 'M': quals |= ObjSection::max; break; case 'N': quals |= ObjSection::now; break; case 'P': quals |= ObjSection::postpone; break; case 'R': quals |= ObjSection::rom; break; case 'S': quals |= ObjSection::separate; break; case 'U': quals |= ObjSection::unique; break; case 'W': quals |= ObjSection::ram; break; case 'x': quals |= ObjSection::exec; break; case 'Z': quals |= ObjSection::zero; break; default: --pos; name = ParseString(buffer, &pos); break; } if (buffer[pos] != ',') break; pos++; } CheckTerm(buffer + pos); ObjSection *sect = factory->MakeSection(name, index); sect->SetQuals(quals); PutSection(index, sect); return false; }
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; }
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; }
void dlPmMain::GetInputSections(const std::vector<std::string> &names, ObjFile *file, ObjFactory *factory) { for (auto name : names) { ObjSection *s = file->FindSection(name); ObjInt size = s->GetSize()->Eval(0); ObjInt addr = s->GetOffset()->Eval(0); Section *p = new Section(addr, size); p->data = new char[size]; sections.push_back(p); s->ResolveSymbols(factory); ObjMemoryManager &m = s->GetMemoryManager(); int ofs = 0; for (ObjMemoryManager::MemoryIterator it = m.MemoryBegin(); it != m.MemoryEnd(); ++it) { int msize = (*it)->GetSize(); ObjByte *mdata = (*it)->GetData(); if (msize) { ObjExpression *fixup = (*it)->GetFixup(); if (fixup) { int sbase = s->GetOffset()->Eval(0); int n = fixup->Eval(sbase + ofs); int bigEndian = file->GetBigEndian(); if (msize == 1) { p->data[ofs] = n & 0xff; } else if (msize == 2) { if (bigEndian) { p->data[ofs] = n >> 8; p->data[ofs + 1] = n & 0xff; } else { p->data[ofs] = n & 0xff; p->data[ofs+1] = n >> 8; } } else // msize == 4 { if (bigEndian) { p->data[ofs + 0] = n >> 24; p->data[ofs + 1] = n >> 16; p->data[ofs + 2] = n >> 8; p->data[ofs + 3] = n & 0xff; } else { p->data[ofs] = n & 0xff; p->data[ofs+1] = n >> 8; p->data[ofs+2] = n >> 16; p->data[ofs+3] = n >> 24; } } } else { if ((*it)->IsEnumerated())
bool Tiny::ReadSections(ObjFile *file, ObjExpression *start) { startOffs = start->Eval(0); if (startOffs != 0x100) Utils::fatal("Start address for tiny program must be 0100h"); int count = 0; ObjSection *sect; for (ObjFile::SectionIterator it = file->SectionBegin(); it != file->SectionEnd(); ++it) { sect = *it; size = (*it)->GetOffset()->Eval(0) + (*it)->GetSize()->Eval(0); count ++; } if (count != 1 || size < 0x100) return false; data = new unsigned char[size]; ObjMemoryManager &m = sect->GetMemoryManager(); int ofs = 0; for (ObjMemoryManager::MemoryIterator it = m.MemoryBegin(); it != m.MemoryEnd(); ++it) { int msize = (*it)->GetSize(); ObjByte *mdata = (*it)->GetData(); if (msize) { ObjExpression *fixup = (*it)->GetFixup(); if (fixup) { if (fixup->GetOperator() == ObjExpression::eDiv) Utils::fatal("Tiny program cannot have fixups"); int sbase = sect->GetOffset()->Eval(0); int n = fixup->Eval(sbase + ofs); int bigEndian = file->GetBigEndian(); if (msize == 1) { data[ofs] = n & 0xff; } else if (msize == 2) { if (bigEndian) { data[ofs] = n >> 8; data[ofs + 1] = n & 0xff; } else { data[ofs] = n & 0xff; data[ofs+1] = n >> 8; } } else // msize == 4 { if (bigEndian) { data[ofs + 0] = n >> 24; data[ofs + 1] = n >> 16; data[ofs + 2] = n >> 8; data[ofs + 3] = n & 0xff; } else { data[ofs] = n & 0xff; data[ofs+1] = n >> 8; data[ofs+2] = n >> 16; data[ofs+3] = n >> 24; } } }