diff --git a/x65.cpp b/x65.cpp index 368071c..2fdc614 100644 --- a/x65.cpp +++ b/x65.cpp @@ -1839,6 +1839,8 @@ public: // Mimic TASS listing bool ListTassStyle( strref filename ); + bool SourceDebugExport(strref filename); + // Generate source for all valid instructions and addressing modes for current CPU bool AllOpcodes(strref filename); @@ -6932,6 +6934,75 @@ bool Asm::ListTassStyle( strref filename ) { return true; } +bool Asm::SourceDebugExport(strref filename) { + FILE* f = stdout; + bool opened = false; + if (filename) { + f = fopen(strown<512>(filename).c_str(), "w"); + if (!f) { return false; } + opened = true; + } else { + return false; + } + + std::vector source_code; source_code.reserve(source_files.size()); + + fprintf(f, "\n\t\n"); + for (size_t i = 0, n = source_files.size(); i < n; ++i) { + fprintf(f, "\t\t%d,%s\n", (int)i+1, source_files[i]); + + size_t size = 0; + char* src = LoadText(source_files[i], size); + source_code.push_back(strref(src, (strl_t)size)); + } + fprintf(f, "\t\n\n"); + + for (size_t i = 0, n = allSections.size(); i < n; ++i) { + Section& s = allSections[i]; + if (s.pSrcDbg && s.pSrcDbg->size()) { + fprintf(f, "\t\n\t\t\n", + STRREF_ARG(s.name)); + for (size_t d = 0, nd = s.pSrcDbg->size(); d < nd; ++d) { + SourceDebugEntry& e = s.pSrcDbg->at(d); + int line = 0, col0 = 0, col1 = 0; + if (e.source_file_index < source_code.size()) { + strref src = source_code[e.source_file_index]; + if (src.get_len() > strl_t(e.source_file_offset)) { + line = strref(src.get(), e.source_file_offset).count_lines(); + strl_t offs = e.source_file_offset; + while (src.get_at(offs) != 0x0a && src.get_at(offs) != 0x0d && offs) { --offs; ++col0; } + col1 = col0; + offs = e.source_file_offset; + while (src.get_at(offs) != 0x0a && src.get_at(offs) != 0x0d && offs\n\t\n\n"); + } + } + + fprintf(f, "\t\n"); + + for (MapSymbolArray::iterator i = map.begin(); i != map.end(); ++i) { + uint32_t value = (uint32_t)i->value; + strref sectName; + if (size_t(i->section) < allSections.size()) { + value += allSections[i->section].start_address; + sectName = allSections[i->section].name; + } + fprintf(f, "\t\t" STRREF_FMT ",$%04x," STRREF_FMT ",0,0,0,0,0\n", STRREF_ARG(sectName), value, STRREF_ARG(i->name)); + } + fprintf(f, "\t\n"); + + fprintf(f, "\n"); + fclose(f); + + return true; +} + bool Asm::List(strref filename) { FILE *f = stdout; bool opened = false; @@ -7328,7 +7399,7 @@ struct ObjFileSourceList { }; // after that one long array of all sections worth of source references -struct ObjFileSrcRef { +struct ObjFileSrcDbg { uint16_t addr; // relative to section uint16_t src_idx; uint16_t size; @@ -7481,7 +7552,7 @@ StatusCode Asm::WriteObjectFile(strref filename) { } hdr.sections = (int16_t)sect; - struct ObjFileSrcRef* srcLines = srcDbgEntries ? (ObjFileSrcRef*)calloc(1, sizeof(ObjFileSrcRef) * srcDbgEntries) : nullptr; + struct ObjFileSrcDbg* srcLines = srcDbgEntries ? (ObjFileSrcDbg*)calloc(1, sizeof(ObjFileSrcDbg) * srcDbgEntries) : nullptr; if (srcLines) { size_t srcDbgIdx = 0; for (std::vector
::iterator si = allSections.begin(); si != allSections.end(); ++si) { @@ -7489,7 +7560,7 @@ StatusCode Asm::WriteObjectFile(strref filename) { if (si->pSrcDbg && si->pSrcDbg->size()) { for (size_t src = 0, nsrc = si->pSrcDbg->size(); src < nsrc; ++src) { SourceDebugEntry& entry = si->pSrcDbg->at(src); - ObjFileSrcRef& ref = srcLines[srcDbgIdx++]; + ObjFileSrcDbg& ref = srcLines[srcDbgIdx++]; ref.addr = entry.address; ref.src_idx = entry.source_file_index; ref.size = entry.size; @@ -7592,7 +7663,7 @@ StatusCode Asm::WriteObjectFile(strref filename) { } if (sourceList) { fwrite(sourceList, sizeof(ObjFileSourceList) + sizeof(ObjFileStr) * (source_files.size() - 1), 1, f); - fwrite(srcLines, sizeof(ObjFileSrcRef) * srcDbgEntries, 1, f); + fwrite(srcLines, sizeof(ObjFileSrcDbg) * srcDbgEntries, 1, f); } @@ -7624,6 +7695,14 @@ StatusCode Asm::ReadObjectFile(strref filename, int link_to_section) hdr.relocs * sizeof(struct ObjFileReloc) + hdr.labels * sizeof(struct ObjFileLabel) + hdr.late_evals * sizeof(struct ObjFileLateEval) + hdr.map_symbols * sizeof(struct ObjFileMapSymbol) + hdr.stringdata + hdr.bindata; + const struct ObjFileSourceList* pSrcDbgInfo = hdr.srcdebug ? (struct ObjFileSourceList*)(data + sum) : nullptr; + const struct ObjFileSrcDbg* pSrcDbgEntry = pSrcDbgInfo ? (const struct ObjFileSrcDbg*)(pSrcDbgInfo->sourceFile + pSrcDbgInfo->numSources) : nullptr; + + if (pSrcDbgInfo) { + sum += sizeof(ObjFileSourceList) + (pSrcDbgInfo->numSources - 1) * sizeof(ObjFileStr); + sum += sizeof(ObjFileSrcDbg) * hdr.srcdebug; + } + if (hdr.id == 0x7836 && sum == size) { struct ObjFileSection *aSect = (struct ObjFileSection*)(&hdr + 1); struct ObjFileReloc *aReloc = (struct ObjFileReloc*)(aSect + hdr.sections); @@ -7637,6 +7716,25 @@ StatusCode Asm::ReadObjectFile(strref filename, int link_to_section) memcpy(str_pool, str_orig, hdr.stringdata); loadedData.push_back(str_pool); + // source files + std::vector source_file_remap; + if (pSrcDbgInfo) { + source_file_remap.reserve(pSrcDbgInfo->numSources); + for (size_t s = 0, n = pSrcDbgInfo->numSources; s < n; ++s) { + strref source_file(str_pool + pSrcDbgInfo->sourceFile[s].offs); + size_t i = 0, sz = source_files.size(); + for (; i < sz; ++i) { + if (source_file.same_str(source_files[i])) { break; } + } + if (i == sz) { + char* path = (char*)calloc(1, (size_t)source_file.get_len() + 1); + memcpy(path, source_file.get(), source_file.get_len()); + source_files.push_back(path); + } + source_file_remap.push_back(i); + } + } + int prevSection = SectionId(); int16_t *aSctRmp = (int16_t*)malloc(hdr.sections * sizeof(int16_t)); int last_linked_section = link_to_section; @@ -7681,6 +7779,19 @@ StatusCode Asm::ReadObjectFile(strref filename, int link_to_section) s.first_group = allSections[last_linked_section].first_group >=0 ? allSections[last_linked_section].first_group : last_linked_section; last_linked_section = SectionId(); } + // add source debug entries from object file + if (aSect[si].srcdebug_count) { + if (!s.pSrcDbg) { s.pSrcDbg = new SourceDebug; } + for (int sd = 0, nsd = aSect[si].srcdebug_count; sd < nsd; ++sd) { + SourceDebugEntry entry; + entry.address = pSrcDbgEntry->addr; + entry.size = pSrcDbgEntry->size; + entry.source_file_index = (int)source_file_remap[pSrcDbgEntry->src_idx]; + entry.source_file_offset = pSrcDbgEntry->file_offs; + s.pSrcDbg->push_back(entry); + ++pSrcDbgEntry; + } + } } aSctRmp[si] = (int16_t)allSections.size()-1; } @@ -8270,7 +8381,7 @@ int main(int argc, char **argv) { // listing after export since addresses are now resolved if (list_output) { assembler.List(list_file); } - if (srcdebug_file) { } + if (srcdebug_file) { assembler.SourceDebugExport(srcdebug_file); } if (tass_list_output) { assembler.ListTassStyle(tass_list_file); }