[Compiler] Fix branch targets in disassembly (#379)

* fix diassembly

* update changelog

* fix exit crash

* doc
This commit is contained in:
water111 2021-04-23 15:07:22 -04:00 committed by GitHub
parent 060b125324
commit 0b8a878533
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 28 additions and 18 deletions

View file

@ -134,4 +134,6 @@
- Added support for creating a static bitfield where fields may not be known at compile time.
- Added support for `(size-of <typename>)`
- Fixed a bug where creating a stack array of 0 sized caused a compiler assertion. It is now a normal compiler error.
- Fixed a bug where the repl history was not loaded on compiler start
- Fixed a bug where the repl history was not loaded on compiler start
- Branch target addresses in the disassembly generated by `md`, `asm-file` with `:disassemble` and `(declare (print-asm))` are now correct
- Fixed a segfault when the `goal-library.gc` contains an `(exit)`

View file

@ -45,7 +45,7 @@ std::vector<u8> CodeGenerator::run(const TypeSystem* ts) {
do_function(m_fe->functions().at(i).get(), i);
}
// generate a v3 object. TODO - support for v4 "data" objects.
// generate a v3 object.
return m_gen.generate_data_v3(ts).to_vector();
}

View file

@ -33,7 +33,9 @@ Val* Compiler::compile_exit(const goos::Object& form, const goos::Object& rest,
}
// flag for the REPL.
m_want_exit = true;
m_repl->save_history();
if (m_repl) {
m_repl->save_history();
}
return get_none();
}

View file

@ -1,5 +1,4 @@
#include <utility>
#include <vector>
#include "DebugInfo.h"
#include "third-party/fmt/core.h"
@ -7,17 +6,8 @@ DebugInfo::DebugInfo(std::string obj_name) : m_obj_name(std::move(obj_name)) {}
std::string FunctionDebugInfo::disassemble_debug_info(bool* had_failure) {
std::string result = fmt::format("[{}]\n", name);
std::vector<u8> data;
u8 temp[128];
for (const auto& x : instructions) {
auto count = x.instruction.emit(temp);
for (int i = 0; i < count; i++) {
data.push_back(temp[i]);
}
}
result += disassemble_x86_function(data.data(), data.size(), 0x10000, 0x10000, instructions, irs,
had_failure);
result += disassemble_x86_function(generated_code.data(), generated_code.size(), 0x10000, 0x10000,
instructions, irs, had_failure);
return result;
}

View file

@ -8,6 +8,11 @@
#include "goalc/emitter/Instruction.h"
#include "goalc/debugger/disassemble.h"
/*!
* FunctionDebugInfo stores per-function debugging information.
* For now, it is pretty basic, but it will eventually contain stuff like stack frame info
* and which var is in each register at each instruction.
*/
struct FunctionDebugInfo {
u32 offset_in_seg; // not including type tag.
u32 length;
@ -15,7 +20,10 @@ struct FunctionDebugInfo {
std::string name;
std::vector<std::string> irs;
std::vector<InstructionInfo> instructions;
std::vector<InstructionInfo> instructions; // contains mapping to IRs
// the actual bytes in the object file.
std::vector<u8> generated_code;
std::string disassemble_debug_info(bool* had_failure);
};

View file

@ -95,13 +95,21 @@ ObjectFileData ObjectGenerator::generate_data_v3(const TypeSystem* ts) {
handle_temp_static_ptr_links(seg);
}
// actual linking?
// step 4, generate the link table
for (int seg = N_SEG; seg-- > 0;) {
emit_link_table(seg, ts);
}
// emit header
// step 4.5, collect final result of code/object generation for compiler debugging disassembly
for (int seg = 0; seg < N_SEG; seg++) {
for (auto& function : m_function_data_by_seg.at(seg)) {
auto start = m_data_by_seg.at(seg).begin() + function.instruction_to_byte_in_data.at(0);
auto end = start + function.debug->length;
function.debug->generated_code = {start, end};
}
}
// step 5, build header and combine sections
out.header = generate_header_v3();
out.segment_data = std::move(m_data_by_seg);
out.link_tables = std::move(m_link_by_seg);