Source Debug Export

This commit is contained in:
Carl-Henrik Skårstedt 2021-01-14 16:50:33 +01:00
parent b75a8325ee
commit 063459efbf
1 changed files with 116 additions and 5 deletions

121
x65.cpp
View File

@ -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<strref> source_code; source_code.reserve(source_files.size());
fprintf(f, "<C64debugger version=\"1.0\">\n\t<Sources values=\"INDEX,FILE\">\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</Sources>\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<Segment name=\"" STRREF_FMT "\" dest=\"\" values=\"START,END,FILE_IDX,LINE1,COL1,LINE2,COL2\">\n\t\t<Block name=\"Unnamed\">\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<src.get_len()) { ++offs; ++col1; }
}
}
fprintf(f, "\t\t\t$%04x,$%04x,%d,%d,%d,%d,%d\n",
e.address+s.start_address, e.address+e.size+s.start_address-1, e.source_file_index+1,
line+1, col0 ? (col0-1) : 0, line+1, col1 );
}
fprintf(f, "\t\t</Block>\n\t</Segment>\n\n");
}
}
fprintf(f, "\t<Labels values=\"SEGMENT,ADDRESS,NAME,START,END,FILE_IDX,LINE1,COL1,LINE2,COL2\">\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</Labels>\n");
fprintf(f, "</C64debugger>\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<Section>::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<size_t> 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); }