mirror of
https://github.com/ksherlock/x65.git
synced 2025-01-14 11:29:45 +00:00
Source Debug Export
This commit is contained in:
parent
b75a8325ee
commit
063459efbf
121
x65.cpp
121
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<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); }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user