From c0968268294ef650e8762d8f966778e7e083231b Mon Sep 17 00:00:00 2001 From: amoisson Date: Thu, 16 Nov 2023 11:11:56 +0100 Subject: [PATCH 01/15] Updated parser but addressing is not correct yet --- lld/ELF/ScriptParser.cpp | 50 ++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index b81812d11821e..27849bf75e8b2 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -512,10 +512,18 @@ std::vector ScriptParser::readOverlay() { // VA and LMA expressions are optional, though for simplicity of // implementation we assume they are not. That is what OVERLAY was designed // for first of all: to allow sections with overlapping VAs at different LMAs. - Expr addrExpr = readExpr(); + Expr addrExpr; + bool hasAddrExpr = false; + if (peek() != ":") { + addrExpr = readExpr(); + hasAddrExpr = true; + } expect(":"); - expect("AT"); - Expr lmaExpr = readParenExpr(); + Expr lmaExpr; + bool hasLmaExpr = false; + if (consume("AT")) { + lmaExpr = readParenExpr(); + } expect("{"); std::vector v; @@ -524,14 +532,34 @@ std::vector ScriptParser::readOverlay() { // VA is the same for all sections. The LMAs are consecutive in memory // starting from the base load address specified. OutputSection *os = readOverlaySectionDescription(); - os->addrExpr = addrExpr; - if (prev) - os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; - else - os->lmaExpr = lmaExpr; + if (hasAddrExpr) + os->addrExpr = addrExpr; + if (hasLmaExpr) { + if (prev) + os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; + else + os->lmaExpr = lmaExpr; + } v.push_back(os); prev = os; } + if (consume(">")) { + std::string memoryRegionName = std::string(next()); + for (BaseCommand *cmd: v) { + OutputSection *os = dyn_cast cmd; + os->memoryRegionName = memoryRegionName; + } + } + + if (consume("AT")) { + expect(">"); + std::string lmaRegionName = std::string(next()); + if (hasLmaExpr) error("overlay can't have both LMA and a load region"); + for (BaseCommand *cmd: v) { + OutputSection *os = dyn_cast cmd; + os->lmaRegionName = lmaRegionName; + } + } // According to the specification, at the end of the overlay, the location // counter should be equal to the overlay base address plus size of the @@ -541,7 +569,11 @@ std::vector ScriptParser::readOverlay() { uint64_t max = 0; for (BaseCommand *cmd : v) max = std::max(max, cast(cmd)->size); - return addrExpr().getValue() + max; + if (hasAddrExpr) { + return addrExpr().getValue() + max; + } else { + return max; // FIXME This should probably be added to dot + } }; v.push_back(make(".", moveDot, getCurrentLocation())); return v; From 610e8ecafe5f239a9de7e4eba58b600caec22b4f Mon Sep 17 00:00:00 2001 From: amoisson Date: Tue, 28 Nov 2023 10:43:07 +0100 Subject: [PATCH 02/15] added __load_start and __load_stop symbol assignments --- lld/ELF/ScriptParser.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 27849bf75e8b2..7f12af9f09425 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -523,6 +523,7 @@ std::vector ScriptParser::readOverlay() { bool hasLmaExpr = false; if (consume("AT")) { lmaExpr = readParenExpr(); + hasLmaExpr = true; } expect("{"); @@ -542,11 +543,15 @@ std::vector ScriptParser::readOverlay() { } v.push_back(os); prev = os; + // TODO : make sure os->name is sanitized ("." -> "_") before being used in symbols + v.push_back(make(saver.save("__load_start_" + os->name), os->lmaExpr, getCurrentLocation())); + Expr load_stop = [=] { return os->getLMA() + prev->size; }; + v.push_back(make(saver.save("__load_stop_" + os->name), load_stop, getCurrentLocation())); } if (consume(">")) { std::string memoryRegionName = std::string(next()); for (BaseCommand *cmd: v) { - OutputSection *os = dyn_cast cmd; + OutputSection *os = dyn_cast(cmd); os->memoryRegionName = memoryRegionName; } } @@ -556,11 +561,12 @@ std::vector ScriptParser::readOverlay() { std::string lmaRegionName = std::string(next()); if (hasLmaExpr) error("overlay can't have both LMA and a load region"); for (BaseCommand *cmd: v) { - OutputSection *os = dyn_cast cmd; + OutputSection *os = dyn_cast(cmd); os->lmaRegionName = lmaRegionName; } } + // According to the specification, at the end of the overlay, the location // counter should be equal to the overlay base address plus size of the // largest section seen in the overlay. From 04bdbd6abdcd7b7f332c52b7b5838fc1a0a03975 Mon Sep 17 00:00:00 2001 From: amoisson Date: Tue, 19 Dec 2023 09:01:49 +0100 Subject: [PATCH 03/15] overlay memory use fix --- lld/ELF/LinkerScript.cpp | 6 +++++- lld/ELF/LinkerScript.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 201f1e48f1fb3..f3681de00ba03 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -856,7 +856,7 @@ void LinkerScript::switchTo(OutputSection *sec) { // ctx->outSec->alignment is the max of ALIGN and the maximum of input // section alignments. ctx->outSec->addr = advance(0, ctx->outSec->alignment); - expandMemoryRegions(ctx->outSec->addr - pos); + expandMemoryRegions(ctx->outSec->addr - pos);// TODO : check if this doesn't require some modification for overlay case } } @@ -908,6 +908,10 @@ void LinkerScript::assignOffsets(OutputSection *sec) { ctx->memRegion = sec->memRegion; ctx->lmaRegion = sec->lmaRegion; + if (sec->inOverlay && ctx->inOverlay && sec->addrExpr().getValue() == ctx->outSec->addrExpr().getValue()) + ctx->memRegion->curPos -= ctx->outSec->size; + ctx->inOverlay = sec->inOverlay; + if (sec->flags & SHF_ALLOC) { if (ctx->memRegion) dot = ctx->memRegion->curPos; diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index efa473f45e308..d54fe8253b222 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -252,6 +252,7 @@ class LinkerScript final { MemoryRegion *memRegion = nullptr; MemoryRegion *lmaRegion = nullptr; uint64_t lmaOffset = 0; + bool inOverlay = false; }; llvm::DenseMap nameToOutputSection; From 0bcf4a98d1d01afeabd21533cc35a8f9c380d165 Mon Sep 17 00:00:00 2001 From: amoisson Date: Wed, 3 Jan 2024 10:47:46 +0100 Subject: [PATCH 04/15] reverted parser modifications --- lld/ELF/ScriptParser.cpp | 51 +++++++--------------------------------- 1 file changed, 9 insertions(+), 42 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 7f12af9f09425..5ceb841bb7ede 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -512,19 +512,10 @@ std::vector ScriptParser::readOverlay() { // VA and LMA expressions are optional, though for simplicity of // implementation we assume they are not. That is what OVERLAY was designed // for first of all: to allow sections with overlapping VAs at different LMAs. - Expr addrExpr; - bool hasAddrExpr = false; - if (peek() != ":") { - addrExpr = readExpr(); - hasAddrExpr = true; - } + Expr addrExpr = readExpr(); expect(":"); - Expr lmaExpr; - bool hasLmaExpr = false; - if (consume("AT")) { - lmaExpr = readParenExpr(); - hasLmaExpr = true; - } + expect("AT"); + Expr lmaExpr = readParenExpr(); expect("{"); std::vector v; @@ -533,14 +524,11 @@ std::vector ScriptParser::readOverlay() { // VA is the same for all sections. The LMAs are consecutive in memory // starting from the base load address specified. OutputSection *os = readOverlaySectionDescription(); - if (hasAddrExpr) - os->addrExpr = addrExpr; - if (hasLmaExpr) { - if (prev) - os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; - else - os->lmaExpr = lmaExpr; - } + os->addrExpr = addrExpr; + if (prev) + os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; + else + os->lmaExpr = lmaExpr; v.push_back(os); prev = os; // TODO : make sure os->name is sanitized ("." -> "_") before being used in symbols @@ -548,23 +536,6 @@ std::vector ScriptParser::readOverlay() { Expr load_stop = [=] { return os->getLMA() + prev->size; }; v.push_back(make(saver.save("__load_stop_" + os->name), load_stop, getCurrentLocation())); } - if (consume(">")) { - std::string memoryRegionName = std::string(next()); - for (BaseCommand *cmd: v) { - OutputSection *os = dyn_cast(cmd); - os->memoryRegionName = memoryRegionName; - } - } - - if (consume("AT")) { - expect(">"); - std::string lmaRegionName = std::string(next()); - if (hasLmaExpr) error("overlay can't have both LMA and a load region"); - for (BaseCommand *cmd: v) { - OutputSection *os = dyn_cast(cmd); - os->lmaRegionName = lmaRegionName; - } - } // According to the specification, at the end of the overlay, the location @@ -575,11 +546,7 @@ std::vector ScriptParser::readOverlay() { uint64_t max = 0; for (BaseCommand *cmd : v) max = std::max(max, cast(cmd)->size); - if (hasAddrExpr) { - return addrExpr().getValue() + max; - } else { - return max; // FIXME This should probably be added to dot - } + return addrExpr().getValue() + max; }; v.push_back(make(".", moveDot, getCurrentLocation())); return v; From f49c55163c6d08414cfd592cf0650b6f74af1a7b Mon Sep 17 00:00:00 2001 From: amoisson Date: Wed, 17 Jan 2024 16:14:03 +0100 Subject: [PATCH 05/15] fixed empty section lma computation --- lld/ELF/ScriptParser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 5ceb841bb7ede..65858bb90a2ab 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -526,14 +526,14 @@ std::vector ScriptParser::readOverlay() { OutputSection *os = readOverlaySectionDescription(); os->addrExpr = addrExpr; if (prev) - os->lmaExpr = [=] { return prev->getLMA() + prev->size; }; + os->lmaExpr = [=] { return prev->size? prev->getLMA() + prev->size : prev->lmaExpr(); }; else os->lmaExpr = lmaExpr; v.push_back(os); prev = os; // TODO : make sure os->name is sanitized ("." -> "_") before being used in symbols v.push_back(make(saver.save("__load_start_" + os->name), os->lmaExpr, getCurrentLocation())); - Expr load_stop = [=] { return os->getLMA() + prev->size; }; + Expr load_stop = [=] { return os->size? os->getLMA() + os->size : os->lmaExpr(); }; v.push_back(make(saver.save("__load_stop_" + os->name), load_stop, getCurrentLocation())); } From eef7f9a9aa9e2fa65fe58021ad23b7ec771df78f Mon Sep 17 00:00:00 2001 From: amoisson Date: Mon, 18 Mar 2024 14:14:20 +0100 Subject: [PATCH 06/15] added address correction when reading code addresses in lldb --- .../source/Plugins/Process/Utility/UnwindDPU.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp index f95186db51602..8f610c0cae7f5 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp @@ -137,6 +137,22 @@ bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, behaves_like_zeroth_frame = frame_idx == 0; cfa = m_frames[frame_idx]->cfa; pc = m_frames[frame_idx]->pc; + + Status error; + lldb::addr_t overlay_start_address; + // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf + if(m_thread.GetProcess()->ReadMemory(0x0000008, &overlay_start_address, 8, error) == 8) { + overlay_start_address <<= 3; + overlay_start_address += 0x80000000; + if (pc >= overlay_start_address && overlay_start_address != 0x80000000) { + uint32_t loaded_group_value; + // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf + if(m_thread.GetProcess()->ReadMemory(0x0000010, &loaded_group_value, 4, error) == 4) { + pc += 0x00100000*(loaded_group_value+1); + } + } + } + return true; } From 718c233ed11162b7789a0473846b6baf9cc65cbf Mon Sep 17 00:00:00 2001 From: amoisson Date: Mon, 13 May 2024 15:00:08 +0200 Subject: [PATCH 07/15] Not yet functional breakpoint function group support implementation --- lldb/source/Plugins/Process/Dpu/Dpu.cpp | 8 ++++ lldb/source/Plugins/Process/Dpu/Dpu.h | 2 + .../source/Plugins/Process/Dpu/ProcessDpu.cpp | 40 ++++++++++++++++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/Dpu.cpp b/lldb/source/Plugins/Process/Dpu/Dpu.cpp index 5e206b7f96a3a..f3ca6d5dd1a1e 100644 --- a/lldb/source/Plugins/Process/Dpu/Dpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/Dpu.cpp @@ -679,6 +679,14 @@ bool Dpu::ReadMRAM(uint32_t offset, void *buf, size_t size) { return ret == DPU_OK; } +bool Dpu::GetSymbol(const char *symbol_name, dpu_symbol_t *symbol) { + dpu_program_t *runtime = dpu_get_program(m_dpu); + if (!runtime) + return false; + if (dpu_get_symbol(runtime, symbol_name, symbol) == DPU_OK) return true; + return false; +} + bool Dpu::AllocIRAMBuffer(uint8_t **iram, uint32_t *iram_size) { dpu_description_t description = dpu_get_description(dpu_get_rank(m_dpu)); uint32_t nb_instructions = description->hw.memories.iram_size; diff --git a/lldb/source/Plugins/Process/Dpu/Dpu.h b/lldb/source/Plugins/Process/Dpu/Dpu.h index c9877093f8d10..e2701e1a2b03a 100644 --- a/lldb/source/Plugins/Process/Dpu/Dpu.h +++ b/lldb/source/Plugins/Process/Dpu/Dpu.h @@ -81,6 +81,8 @@ class Dpu { bool WriteMRAM(uint32_t offset, const void *buf, size_t size); bool ReadMRAM(uint32_t offset, void *buf, size_t size); + bool GetSymbol(const char *symbol_name, dpu_symbol_t *symbol); + bool AllocIRAMBuffer(uint8_t **iram, uint32_t *iram_size); bool FreeIRAMBuffer(uint8_t *iram); bool GenerateSaveCore(const char *exe_path, const char *core_file_path, diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp index 4a33880b36d53..c0b5a98152a28 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp @@ -50,6 +50,10 @@ #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #include "ThreadDpu.h" +extern "C" { +#include +} + #include #include /* TODO only exists on Linux */ #include @@ -355,6 +359,8 @@ ProcessDpu::ProcessDpu(::pid_t pid, int terminal_fd, NativeDelegate &delegate, void ProcessDpu::InterfaceTimerCallback() { unsigned int exit_status; + Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); + LLDB_LOG(log, "========= this is a log test ==========="); StateType current_state = m_dpu->PollStatus(&exit_status); if (current_state != StateType::eStateInvalid) { if (current_state == StateType::eStateExited) { @@ -559,10 +565,40 @@ size_t ProcessDpu::UpdateThreads() { return m_threads.size(); } Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) { + lldb::addr_t overlay_start_address; + lldb::addr_t addr_offset = 0; + size_t bytes_read; + Log *log(GetLogIfAnyCategoriesSet(POSIX_LOG_BREAKPOINTS)); + LLDB_LOGF(log, + "ProcessDpu::SetBreakpoint (addr = %" PRIx64 + ", size = %" PRIu32 + "hw = %s)", + addr, size, hardware ? "true" : "false"); + // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf + struct dpu_symbol_t overlay_start_symbol; + if (m_dpu->GetSymbol("__iram_overlay_start", &overlay_start_symbol)) { + overlay_start_address = overlay_start_symbol.address; + overlay_start_address <<= 3; + overlay_start_address += 0x80000000; + if (addr >= overlay_start_address && overlay_start_address != 0x80000000) { + uint32_t loaded_group_value; + // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf + ReadMemory(0x0000010, &loaded_group_value, 4, bytes_read); + if(bytes_read == 4) { + struct dpu_symbol_t dpu_load_start_symbol; + // FIXME : change symbol name depending on loaded_group_value + if (m_dpu->GetSymbol("__load_start_mram_fg_1", &dpu_load_start_symbol)) { + addr_offset = dpu_load_start_symbol.address - overlay_start_address; + addr_offset -= addr & 0x07f00000; // remove any viram region msb marker + } + } + } + } + // FIXME : also set breakpoint in iram for function groups if (hardware) - return SetHardwareBreakpoint(addr, size); + return SetHardwareBreakpoint(addr+addr_offset, size); else - return SetSoftwareBreakpoint(addr, size); + return SetSoftwareBreakpoint(addr+addr_offset, size); } Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { From f7ebeb62d30ed507d174210423eefe8aa997e7d3 Mon Sep 17 00:00:00 2001 From: amoisson Date: Wed, 22 May 2024 12:55:52 +0200 Subject: [PATCH 08/15] made breakpoints work with magic constants for a specific test case --- lldb/source/Plugins/Process/Dpu/Dpu.cpp | 3 + .../source/Plugins/Process/Dpu/DpuContext.cpp | 16 ++- .../source/Plugins/Process/Dpu/ProcessDpu.cpp | 102 +++++++++++++----- .../Process/Dpu/RegisterContextDpu.cpp | 5 + .../Plugins/Process/Utility/UnwindDPU.cpp | 2 +- 5 files changed, 100 insertions(+), 28 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/Dpu.cpp b/lldb/source/Plugins/Process/Dpu/Dpu.cpp index f3ca6d5dd1a1e..16f980be3d868 100644 --- a/lldb/source/Plugins/Process/Dpu/Dpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/Dpu.cpp @@ -681,6 +681,7 @@ bool Dpu::ReadMRAM(uint32_t offset, void *buf, size_t size) { bool Dpu::GetSymbol(const char *symbol_name, dpu_symbol_t *symbol) { dpu_program_t *runtime = dpu_get_program(m_dpu); + lldbassert(runtime); if (!runtime) return false; if (dpu_get_symbol(runtime, symbol_name, symbol) == DPU_OK) return true; @@ -780,9 +781,11 @@ lldb::StateType Dpu::GetThreadState(uint32_t thread_index, uint32_t dma_fault_thread_index = context->dma_fault_thread_index; uint32_t mem_fault_thread_index = context->mem_fault_thread_index; uint32_t bkp_fault_id = context->bkp_fault_id; + printf("hello from GetThreadState() ===============\n"); if (bkp_fault && bkp_fault_thread_index == thread_index) { if (bkp_fault_id == 0) { stop_reason = eStopReasonBreakpoint; + printf("stop reason is breakpoint. Returning from GetThreadState()\n"); return eStateStopped; } else { description = "fault " + std::to_string(bkp_fault_id) + " (" + diff --git a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp index 1e0d8a9485c27..64249a9972c3f 100644 --- a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp +++ b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp @@ -141,7 +141,21 @@ unsigned int DpuContext::GetExitStatus() { } lldb::addr_t DpuContext::GetPcOfThread(dpu_thread_t thread) { - return InstIdx2InstAddr(m_context->pcs[thread]); + printf("hello from GetPcOfThread() =====\n"); + uint32_t raw_pc = m_context->pcs[thread]; + printf("raw_pc = 0x%x (bytes: 0x%x)\n", raw_pc, InstIdx2InstAddr(raw_pc)); + /* + lldbassert(0); + uint32_t adjusted_pc = raw_pc; + if ((raw_pc<<3) > 0x00001738) + { + adjusted_pc *= sizeof(dpuinstruction_t); + adjusted_pc += 0x08100090 - 0x00001738; + printf("adjusted_pc = 0x%x\n", adjusted_pc); + return adjusted_pc; + } + */ + return InstIdx2InstAddr(raw_pc); } bool DpuContext::ScheduledThread(uint32_t thread) { diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp index c0b5a98152a28..7f461e6822073 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp @@ -81,6 +81,8 @@ extern "C" { extern void set_verbose_output_file(FILE *); } +#define k_dpu_viram_offset 0x00100000 + llvm::Expected> ProcessDpu::Factory::Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, @@ -336,7 +338,7 @@ ProcessDpu::ProcessDpu(::pid_t pid, int terminal_fd, NativeDelegate &delegate, SetState(StateType::eStateStopped, false); m_iram_region.GetRange().SetRangeBase(k_dpu_iram_base); - m_iram_region.GetRange().SetRangeEnd(k_dpu_iram_base + m_iram_size); + m_iram_region.GetRange().SetRangeEnd(k_dpu_iram_base + k_dpu_viram_offset*6 + m_iram_size); m_iram_region.SetReadable(MemoryRegionInfo::eYes); m_iram_region.SetWritable(MemoryRegionInfo::eYes); m_iram_region.SetExecutable(MemoryRegionInfo::eYes); @@ -533,6 +535,7 @@ Status ProcessDpu::GetMemoryRegionInfo(lldb::addr_t load_addr, range_info = m_mram_region; } else if (m_iram_region.GetRange().Contains(load_addr)) { range_info = m_iram_region; + // FIXME : add viram ranges } else { range_info.GetRange().SetRangeBase(load_addr); range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); @@ -569,31 +572,37 @@ Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, lldb::addr_t addr_offset = 0; size_t bytes_read; Log *log(GetLogIfAnyCategoriesSet(POSIX_LOG_BREAKPOINTS)); - LLDB_LOGF(log, - "ProcessDpu::SetBreakpoint (addr = %" PRIx64 + printf("ProcessDpu::SetBreakpoint (addr = %" PRIx64 ", size = %" PRIu32 - "hw = %s)", + ", hw = %s)", addr, size, hardware ? "true" : "false"); - // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf - struct dpu_symbol_t overlay_start_symbol; - if (m_dpu->GetSymbol("__iram_overlay_start", &overlay_start_symbol)) { - overlay_start_address = overlay_start_symbol.address; - overlay_start_address <<= 3; - overlay_start_address += 0x80000000; - if (addr >= overlay_start_address && overlay_start_address != 0x80000000) { - uint32_t loaded_group_value; - // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf - ReadMemory(0x0000010, &loaded_group_value, 4, bytes_read); - if(bytes_read == 4) { - struct dpu_symbol_t dpu_load_start_symbol; - // FIXME : change symbol name depending on loaded_group_value - if (m_dpu->GetSymbol("__load_start_mram_fg_1", &dpu_load_start_symbol)) { - addr_offset = dpu_load_start_symbol.address - overlay_start_address; - addr_offset -= addr & 0x07f00000; // remove any viram region msb marker - } - } - } - } +// // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf +// struct dpu_symbol_t overlay_start_symbol; +// /* +// if (m_dpu->GetSymbol("__iram_overlay_start", &overlay_start_symbol)) { +// overlay_start_address = overlay_start_symbol.address; +// overlay_start_address <<= 3; +// overlay_start_address += 0x80000000; +// */ +// overlay_start_address = 0x80001738; +// if (addr >= overlay_start_address && overlay_start_address != 0x80000000) { +// uint32_t loaded_group_value; +// struct dpu_symbol_t dpu_load_start_symbol; +// // FIXME : change symbol name depending on loaded_group_value +// /* +// if (m_dpu->GetSymbol("__load_start_mram_fg_1", &dpu_load_start_symbol)) { +// addr_offset = dpu_load_start_symbol.address - overlay_start_address; +// */ +// addr_offset = 0x08100090 - overlay_start_address; +// addr_offset -= addr & 0x07f00000; // remove any viram region msb marker +// //} +// } +// //} +// printf("===========\n"); +// printf("addr_offset = %lx\n", addr_offset); +// printf("overlay_start_address = %lx\n", overlay_start_address); +// printf("addr+addr_offset = %lx\n", addr+addr_offset); +// printf("===========\n"); // FIXME : also set breakpoint in iram for function groups if (hardware) return SetHardwareBreakpoint(addr+addr_offset, size); @@ -602,6 +611,24 @@ Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, } Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { + printf("RemoveBreakpoint(addr=%x, hardware=%s)\n", addr, hardware? "true" : "false"); + // addr &= 0xf80fffff; + /* + if (addr & 0xf8000000 == 0x80000000) { + if (addr & 0x07f00000) { + lldb::addr_t mram_addr = (addr & 0xf80fffff) + 0x08100090 - 0x80001738; + printf("removing mram bp : 0x%lx\n", addr); + if (hardware) + RemoveHardwareBreakpoint(mram_addr); + else + NativeProcessProtocol::RemoveBreakpoint(addr); + } else { + // TODO Only remove iram breakpoint if corresponding function group is loaded + addr &= 0xf80fffff; + } + } + printf("removing bp : 0x%lx\n", addr); + */ if (hardware) return RemoveHardwareBreakpoint(addr); else @@ -612,9 +639,15 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); + printf("ReadMemory(addr=%x, ..., size=%u,...)\n", addr, size); bytes_read = 0; - if (addr >= k_dpu_iram_base && + if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & 0xf80fffff) + size) <= (k_dpu_iram_base + m_iram_size)) { + // expected behaviour : if can fetch symbols, read correct mram location. Otherwise, read iram + printf("reading mram at : 0x%lx\n", (addr & 0xf80fffff) + 0x100090 - 0x1738 - k_dpu_iram_base); + if (!m_dpu->ReadMRAM((addr & 0xf80fffff) + 0x100090 - 0x1738 - k_dpu_iram_base, buf, size)) + return Status("ReadMemory: Cannot copy from MRAM"); + } else if (addr >= k_dpu_iram_base && (addr + size) <= (k_dpu_iram_base + m_iram_size)) { if (!m_dpu->ReadIRAM(addr - k_dpu_iram_base, buf, size)) return Status("ReadMemory: Cannot copy from IRAM"); @@ -630,6 +663,11 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, return Status("ReadMemory: Cannot read, unknown address space"); } bytes_read = size; + printf("read at %x : ", addr); + for (size_t i=0; i< bytes_read; i++) { + printf("%0hhX ", ((unsigned char *)buf)[i]); + } + printf("\n"); return Status(); } @@ -638,9 +676,16 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); + printf("WriteMemory(addr=%x, ..., size=%u,...)\n", addr, size); bytes_written = 0; - if (addr >= k_dpu_iram_base && + if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & 0xf80fffff) + size) <= (k_dpu_iram_base + m_iram_size)) { + // expected behaviour : if can fetch symbols, write to correct mram location and if fg is loaded, write to iram. Otherwise, only write to iram + if (!m_dpu->WriteMRAM((addr & 0xf80fffff) + 0x100090 - 0x1738 - k_dpu_iram_base, buf, size)) + return Status("WriteMemory: Cannot copy to MRAM"); + if (!m_dpu->WriteIRAM((addr & 0xf80fffff) - k_dpu_iram_base, buf, size)) + return Status("WriteMemory: Cannot copy to IRAM"); + } else if (addr >= k_dpu_iram_base && (addr + size) <= (k_dpu_iram_base + m_iram_size)) { if (!m_dpu->WriteIRAM(addr - k_dpu_iram_base, buf, size)) return Status("WriteMemory: Cannot copy to IRAM"); @@ -656,6 +701,11 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, return Status("WriteMemory: Cannot write, unknown address space"); } bytes_written = size; + printf("written at %x : ", addr); + for (size_t i=0; i< bytes_written; i++) { + printf("%0hhX ", ((unsigned char *)buf)[i]); + } + printf("\n"); return Status(); } diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp index edbbe7d8f15b9..a604a9cdf5bb8 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp @@ -106,6 +106,11 @@ Status RegisterContextDpu::ReadRegister(const RegisterInfo *info, *m_context_pc * 8 /*sizeof(iram_instruction_t)*/ + k_dpu_iram_base; if (m_thread.GetState() == eStateSuspended) pc++; + if (pc > 0x80001738) + { + printf("ReadRegister fixing pc from %x to %x\n", pc, pc | 0x00200000); + pc |= 0x00200000;// TODO : Use the values stored in memory instead (and remove the fix from UnwindDpu.cpp + } value.SetUInt32(pc); } else if (reg == zf_dpu) value.SetUInt32(*m_context_zf ? 1 : 0); diff --git a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp index 8f610c0cae7f5..9f7c19739a7e6 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp @@ -148,7 +148,7 @@ bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, uint32_t loaded_group_value; // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf if(m_thread.GetProcess()->ReadMemory(0x0000010, &loaded_group_value, 4, error) == 4) { - pc += 0x00100000*(loaded_group_value+1); + pc |= 0x00100000*(loaded_group_value+1); } } } From a79efcb1c73c2ff98edff17660284c43fdc354a8 Mon Sep 17 00:00:00 2001 From: amoisson Date: Wed, 22 May 2024 15:37:45 +0200 Subject: [PATCH 09/15] viram writes are now written to iram only if correct function group is loaded --- .../source/Plugins/Process/Dpu/ProcessDpu.cpp | 113 ++++++++---------- lldb/source/Plugins/Process/Dpu/ProcessDpu.h | 6 + 2 files changed, 58 insertions(+), 61 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp index 7f461e6822073..bf75a347ca4b9 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp @@ -81,8 +81,6 @@ extern "C" { extern void set_verbose_output_file(FILE *); } -#define k_dpu_viram_offset 0x00100000 - llvm::Expected> ProcessDpu::Factory::Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, @@ -568,67 +566,16 @@ size_t ProcessDpu::UpdateThreads() { return m_threads.size(); } Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) { - lldb::addr_t overlay_start_address; - lldb::addr_t addr_offset = 0; size_t bytes_read; Log *log(GetLogIfAnyCategoriesSet(POSIX_LOG_BREAKPOINTS)); - printf("ProcessDpu::SetBreakpoint (addr = %" PRIx64 - ", size = %" PRIu32 - ", hw = %s)", - addr, size, hardware ? "true" : "false"); -// // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf -// struct dpu_symbol_t overlay_start_symbol; -// /* -// if (m_dpu->GetSymbol("__iram_overlay_start", &overlay_start_symbol)) { -// overlay_start_address = overlay_start_symbol.address; -// overlay_start_address <<= 3; -// overlay_start_address += 0x80000000; -// */ -// overlay_start_address = 0x80001738; -// if (addr >= overlay_start_address && overlay_start_address != 0x80000000) { -// uint32_t loaded_group_value; -// struct dpu_symbol_t dpu_load_start_symbol; -// // FIXME : change symbol name depending on loaded_group_value -// /* -// if (m_dpu->GetSymbol("__load_start_mram_fg_1", &dpu_load_start_symbol)) { -// addr_offset = dpu_load_start_symbol.address - overlay_start_address; -// */ -// addr_offset = 0x08100090 - overlay_start_address; -// addr_offset -= addr & 0x07f00000; // remove any viram region msb marker -// //} -// } -// //} -// printf("===========\n"); -// printf("addr_offset = %lx\n", addr_offset); -// printf("overlay_start_address = %lx\n", overlay_start_address); -// printf("addr+addr_offset = %lx\n", addr+addr_offset); -// printf("===========\n"); - // FIXME : also set breakpoint in iram for function groups if (hardware) - return SetHardwareBreakpoint(addr+addr_offset, size); + return SetHardwareBreakpoint(addr, size); else - return SetSoftwareBreakpoint(addr+addr_offset, size); + return SetSoftwareBreakpoint(addr, size); } Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { printf("RemoveBreakpoint(addr=%x, hardware=%s)\n", addr, hardware? "true" : "false"); - // addr &= 0xf80fffff; - /* - if (addr & 0xf8000000 == 0x80000000) { - if (addr & 0x07f00000) { - lldb::addr_t mram_addr = (addr & 0xf80fffff) + 0x08100090 - 0x80001738; - printf("removing mram bp : 0x%lx\n", addr); - if (hardware) - RemoveHardwareBreakpoint(mram_addr); - else - NativeProcessProtocol::RemoveBreakpoint(addr); - } else { - // TODO Only remove iram breakpoint if corresponding function group is loaded - addr &= 0xf80fffff; - } - } - printf("removing bp : 0x%lx\n", addr); - */ if (hardware) return RemoveHardwareBreakpoint(addr); else @@ -638,14 +585,19 @@ Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); + Status error; LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); printf("ReadMemory(addr=%x, ..., size=%u,...)\n", addr, size); bytes_read = 0; - if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & 0xf80fffff) + size) <= (k_dpu_iram_base + m_iram_size)) { + if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { // expected behaviour : if can fetch symbols, read correct mram location. Otherwise, read iram - printf("reading mram at : 0x%lx\n", (addr & 0xf80fffff) + 0x100090 - 0x1738 - k_dpu_iram_base); - if (!m_dpu->ReadMRAM((addr & 0xf80fffff) + 0x100090 - 0x1738 - k_dpu_iram_base, buf, size)) + lldb::addr_t mram_addr; + error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); + if (error.Fail()) + return Status("ReadMemory: cannot convert viram to mram physical address"); + printf("reading mram at : 0x%lx\n", mram_addr - k_dpu_mram_base); + if (!m_dpu->ReadMRAM(mram_addr - k_dpu_mram_base, buf, size)) return Status("ReadMemory: Cannot copy from MRAM"); } else if (addr >= k_dpu_iram_base && (addr + size) <= (k_dpu_iram_base + m_iram_size)) { @@ -675,15 +627,25 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); + Status error; LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); printf("WriteMemory(addr=%x, ..., size=%u,...)\n", addr, size); bytes_written = 0; - if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & 0xf80fffff) + size) <= (k_dpu_iram_base + m_iram_size)) { + if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { // expected behaviour : if can fetch symbols, write to correct mram location and if fg is loaded, write to iram. Otherwise, only write to iram - if (!m_dpu->WriteMRAM((addr & 0xf80fffff) + 0x100090 - 0x1738 - k_dpu_iram_base, buf, size)) + lldb::addr_t mram_addr; + lldb::addr_t iram_addr; + error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); + if (error.Fail()) + return Status("WriteMemory: cannot convert viram to mram physical address"); + if (!m_dpu->WriteMRAM(mram_addr - k_dpu_mram_base, buf, size)) return Status("WriteMemory: Cannot copy to MRAM"); - if (!m_dpu->WriteIRAM((addr & 0xf80fffff) - k_dpu_iram_base, buf, size)) + error = ViramAddressToLoadedIramAddress(addr, &iram_addr); + if (error.Fail()) { + LLDB_LOG(log, "WriteMemory: Could not write viram to iram as this function group is not currently loaded"); + printf("WriteMemory did not write viram to iram\n"); + } else if (!m_dpu->WriteIRAM(iram_addr - k_dpu_iram_base, buf, size)) return Status("WriteMemory: Cannot copy to IRAM"); } else if (addr >= k_dpu_iram_base && (addr + size) <= (k_dpu_iram_base + m_iram_size)) { @@ -710,6 +672,35 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, return Status(); } +Status ProcessDpu::ViramAddressToMramPhysicalAddress(lldb::addr_t viram_addr, lldb::addr_t *mram_addr) { + *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + 0x100090 - 0x1738 - k_dpu_iram_base + k_dpu_mram_base; + return Status(); +} + +Status ProcessDpu::ViramAddressToLoadedIramAddress(lldb::addr_t viram_addr, lldb::addr_t *iram_addr) { + Status error; + size_t bytes_read; + lldb::addr_t overlay_start_address; + // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf + error = ReadMemory(0x0000008, &overlay_start_address, 8, bytes_read); + if(!error.Fail() && bytes_read == 8) { + overlay_start_address <<= 3; + overlay_start_address += 0x80000000; + if (viram_addr >= overlay_start_address && overlay_start_address != 0x80000000) { + uint32_t loaded_group_value; + // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf + error = ReadMemory(0x0000010, &loaded_group_value, 4, bytes_read); + if(!error.Fail() && bytes_read == 4) { + if ((viram_addr & k_dpu_viram_msb_mask) == 0x00100000*(loaded_group_value+1)) { + *iram_addr = viram_addr & ~k_dpu_viram_msb_mask; + return Status(); + } + } + } + } + return Status("This function group is not currently loaded in iram\n"); +} + Status ProcessDpu::GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) { return DpuErrorStatus("GetLoadedModuleFileSpec: Not Implemented"); diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.h b/lldb/source/Plugins/Process/Dpu/ProcessDpu.h index 25265ecd2cb84..66a66c9259ac0 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.h +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.h @@ -39,6 +39,8 @@ const ArchSpec k_dpu_arch("dpu-upmem-dpurte"); constexpr lldb::addr_t k_dpu_wram_base = 0x00000000; constexpr lldb::addr_t k_dpu_mram_base = 0x08000000; constexpr lldb::addr_t k_dpu_iram_base = 0x80000000; +constexpr lldb::addr_t k_dpu_viram_offset = 0x00100000; +constexpr lldb::addr_t k_dpu_viram_msb_mask = k_dpu_viram_offset*0xf; } // namespace dpu namespace process_dpu { @@ -96,6 +98,10 @@ class ProcessDpu : public NativeProcessProtocol { Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; + Status ViramAddressToMramPhysicalAddress(lldb::addr_t viram_addr, lldb::addr_t *mram_addr); + + Status ViramAddressToLoadedIramAddress(lldb::addr_t viram_addr, lldb::addr_t *iram_addr); + virtual llvm::Expected AllocateMemory(size_t size, uint32_t permissions) override; From 5fa2775daebec17473300d9af36f4eba2d70fa7e Mon Sep 17 00:00:00 2001 From: amoisson Date: Wed, 29 May 2024 10:07:08 +0200 Subject: [PATCH 10/15] made breakpoints work properly --- .../source/Plugins/Process/Dpu/DpuContext.cpp | 10 ++-- .../source/Plugins/Process/Dpu/ProcessDpu.cpp | 54 +++++++++++++++---- lldb/source/Plugins/Process/Dpu/ProcessDpu.h | 7 +++ .../Process/Dpu/RegisterContextDpu.cpp | 38 ++++++++++++- .../Plugins/Process/Dpu/RegisterContextDpu.h | 1 + 5 files changed, 91 insertions(+), 19 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp index 64249a9972c3f..82f11f5ce3762 100644 --- a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp +++ b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp @@ -144,17 +144,13 @@ lldb::addr_t DpuContext::GetPcOfThread(dpu_thread_t thread) { printf("hello from GetPcOfThread() =====\n"); uint32_t raw_pc = m_context->pcs[thread]; printf("raw_pc = 0x%x (bytes: 0x%x)\n", raw_pc, InstIdx2InstAddr(raw_pc)); - /* - lldbassert(0); - uint32_t adjusted_pc = raw_pc; - if ((raw_pc<<3) > 0x00001738) + uint32_t adjusted_pc = InstIdx2InstAddr(raw_pc); + if (adjusted_pc >= 0x80001658) { - adjusted_pc *= sizeof(dpuinstruction_t); - adjusted_pc += 0x08100090 - 0x00001738; + adjusted_pc |= 0x00200000; printf("adjusted_pc = 0x%x\n", adjusted_pc); return adjusted_pc; } - */ return InstIdx2InstAddr(raw_pc); } diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp index bf75a347ca4b9..cc54636cce117 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp @@ -575,7 +575,7 @@ Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, } Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { - printf("RemoveBreakpoint(addr=%x, hardware=%s)\n", addr, hardware? "true" : "false"); + printf("RemoveBreakpoint(addr=%lx, hardware=%s)\n", addr, hardware? "true" : "false"); if (hardware) return RemoveHardwareBreakpoint(addr); else @@ -587,7 +587,7 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); Status error; LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); - printf("ReadMemory(addr=%x, ..., size=%u,...)\n", addr, size); + printf("ReadMemory(addr=%lx, ..., size=%u,...)\n", addr, size); bytes_read = 0; if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { @@ -615,9 +615,9 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, return Status("ReadMemory: Cannot read, unknown address space"); } bytes_read = size; - printf("read at %x : ", addr); + printf("read at %lx : ", addr); for (size_t i=0; i< bytes_read; i++) { - printf("%0hhX ", ((unsigned char *)buf)[i]); + printf("%02hhX ", ((unsigned char *)buf)[i]); } printf("\n"); @@ -629,7 +629,7 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); Status error; LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); - printf("WriteMemory(addr=%x, ..., size=%u,...)\n", addr, size); + printf("WriteMemory(addr=%lx, ..., size=%u,...)\n", addr, size); bytes_written = 0; if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { @@ -639,9 +639,11 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); if (error.Fail()) return Status("WriteMemory: cannot convert viram to mram physical address"); + printf("writing to mram at 0x%lx\n", mram_addr); if (!m_dpu->WriteMRAM(mram_addr - k_dpu_mram_base, buf, size)) return Status("WriteMemory: Cannot copy to MRAM"); error = ViramAddressToLoadedIramAddress(addr, &iram_addr); + printf("maybe writing to iram at 0x%lx\n", iram_addr); if (error.Fail()) { LLDB_LOG(log, "WriteMemory: Could not write viram to iram as this function group is not currently loaded"); printf("WriteMemory did not write viram to iram\n"); @@ -663,9 +665,9 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, return Status("WriteMemory: Cannot write, unknown address space"); } bytes_written = size; - printf("written at %x : ", addr); + printf("written at %lx : ", addr); for (size_t i=0; i< bytes_written; i++) { - printf("%0hhX ", ((unsigned char *)buf)[i]); + printf("%02hhX ", ((unsigned char *)buf)[i]); } printf("\n"); @@ -673,7 +675,37 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, } Status ProcessDpu::ViramAddressToMramPhysicalAddress(lldb::addr_t viram_addr, lldb::addr_t *mram_addr) { - *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + 0x100090 - 0x1738 - k_dpu_iram_base + k_dpu_mram_base; + Status error; + size_t bytes_read; + uint64_t magic_value; + lldb::addr_t overlay_start_address = 0; + lldb::addr_t load_starts_table_address = 0; + lldb::addr_t load_start_address = 0; + size_t fg_id = ((viram_addr & k_dpu_viram_msb_mask)/k_dpu_viram_offset) - 1; + error = ReadMemory(ADDR_FG_MAGIC_VALUE, &magic_value, 8, bytes_read); + printf("magic = %lx\n", magic_value); + if(error.Fail() || bytes_read != 8 || magic_value != FG_MAGIC_VALUE) + return Status("could not find fg magic_value\n"); + error = ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); + if(error.Fail() || bytes_read != 4) + return Status("could not read load start address\n"); + overlay_start_address <<= 3; + printf("overlay_start_address = %lx\n", overlay_start_address); + lldbassert(viram_addr >= overlay_start_address); + error = ReadMemory(ADDR_FG_LOAD_STARTS_ADDR, &load_starts_table_address, 4, bytes_read); + printf("load_starts_table_address = %lx\n", load_starts_table_address); + if(error.Fail() || bytes_read != 4) + return Status("could not read load starts table address\n"); + if (load_starts_table_address == 0) + return Status("function groups not properly initialized"); + error = ReadMemory(load_starts_table_address+4*fg_id, &load_start_address, 4, bytes_read); + printf("load_start_address = %lx\n", load_start_address); + if(error.Fail() || bytes_read != 4) + return Status("could not read load start address\n"); + // *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + 0x100090 - 0x1738 - k_dpu_iram_base + k_dpu_mram_base; + *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + load_start_address - overlay_start_address - k_dpu_iram_base + k_dpu_mram_base; + printf("Viram2Mram()\n\tviram_addr=%lx\n\toverlay_start_address = %lx\n\tload start = %lx\n\tmram_addr = %lx\n", viram_addr, overlay_start_address, load_start_address, *mram_addr); + lldbassert(viram_addr != 0x80201600); return Status(); } @@ -682,14 +714,14 @@ Status ProcessDpu::ViramAddressToLoadedIramAddress(lldb::addr_t viram_addr, lldb size_t bytes_read; lldb::addr_t overlay_start_address; // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf - error = ReadMemory(0x0000008, &overlay_start_address, 8, bytes_read); - if(!error.Fail() && bytes_read == 8) { + error = ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); + if(!error.Fail() && bytes_read == 4) { overlay_start_address <<= 3; overlay_start_address += 0x80000000; if (viram_addr >= overlay_start_address && overlay_start_address != 0x80000000) { uint32_t loaded_group_value; // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf - error = ReadMemory(0x0000010, &loaded_group_value, 4, bytes_read); + error = ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &loaded_group_value, 4, bytes_read); if(!error.Fail() && bytes_read == 4) { if ((viram_addr & k_dpu_viram_msb_mask) == 0x00100000*(loaded_group_value+1)) { *iram_addr = viram_addr & ~k_dpu_viram_msb_mask; diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.h b/lldb/source/Plugins/Process/Dpu/ProcessDpu.h index 66a66c9259ac0..88a27845b09fc 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.h +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.h @@ -25,6 +25,13 @@ #include "ThreadDpu.h" #include "lldb/Host/common/NativeProcessProtocol.h" +#define ADDR_FG_IRAM_OVERLAY_START 0x8 +#define ADDR_FG_CURRENTLY_LOADED_GROUP 0x10 +#define ADDR_FG_LOAD_STARTS_ADDR 0x18 +#define ADDR_FG_INITIALIZED 0x20 +#define ADDR_FG_MAGIC_VALUE 0x28 +#define FG_MAGIC_VALUE 0xC0DE0FF10AD70015 + namespace lldb_private { class Status; class Scalar; diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp index a604a9cdf5bb8..a5fbd4bd332b5 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp @@ -28,6 +28,7 @@ using namespace lldb_private::process_dpu; namespace { constexpr lldb::addr_t k_dpu_iram_base = 0x80000000; +constexpr lldb::addr_t k_dpu_viram_offset = 0x00100000; } // end of anonymous namespace @@ -78,6 +79,7 @@ RegisterContextDpu::RegisterContextDpu(ThreadDpu &thread, ProcessDpu &process) process.GetThreadContext(thread.GetIndex(), m_context_reg, m_context_pc, m_context_zf, m_context_cf, m_registers_has_been_modified); + m_process = &process; } uint32_t RegisterContextDpu::GetRegisterSetCount() const { return 1; } @@ -94,6 +96,37 @@ RegisterContextDpu::GetRegisterSet(uint32_t set_index) const { return &g_reg_sets_dpu; } +Status FixPc(ProcessDpu *process, uint32_t *pc) { + Status error; + size_t bytes_read; + uint64_t magic_value; + uint32_t initialized = 0; + lldb::addr_t overlay_start_address = 0; + uint32_t fg_id; + + error = process->ReadMemory(ADDR_FG_MAGIC_VALUE, &magic_value, 8, bytes_read); + printf("magic = %lx\n", magic_value); + if(error.Fail() || bytes_read != 8 || magic_value != FG_MAGIC_VALUE) + return Status("could not find fg magic_value\n"); + error = process->ReadMemory(ADDR_FG_INITIALIZED, &initialized, 4, bytes_read); + printf("initialized = %x\n", initialized); + if(error.Fail() || bytes_read != 4 || initialized == 0) + return Status("fg groups not initialized\n"); + error = process->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); + if(error.Fail() || bytes_read != 4) + return Status("could not read load start address\n"); + overlay_start_address <<= 3; + printf("FixPc(0x%x) : overlay_start_address=0x%lx\n", *pc, overlay_start_address); + if((*pc) < k_dpu_iram_base + overlay_start_address) + return Status("pc below overlay_start_address\n"); + error = process->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &fg_id, 4, bytes_read); + printf("fg_id = %x\n", fg_id); + if(error.Fail() || bytes_read != 4) + return Status("could not read load start address\n"); + *pc |= k_dpu_viram_offset*(1+fg_id); + return Status(); +} + Status RegisterContextDpu::ReadRegister(const RegisterInfo *info, RegisterValue &value) { if (!info) @@ -106,11 +139,14 @@ Status RegisterContextDpu::ReadRegister(const RegisterInfo *info, *m_context_pc * 8 /*sizeof(iram_instruction_t)*/ + k_dpu_iram_base; if (m_thread.GetState() == eStateSuspended) pc++; - if (pc > 0x80001738) + FixPc(m_process, &pc); + /* + if (pc > 0x80001658) // FIXME replace this constant with a memory read { printf("ReadRegister fixing pc from %x to %x\n", pc, pc | 0x00200000); pc |= 0x00200000;// TODO : Use the values stored in memory instead (and remove the fix from UnwindDpu.cpp } + */ value.SetUInt32(pc); } else if (reg == zf_dpu) value.SetUInt32(*m_context_zf ? 1 : 0); diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.h b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.h index 97aeb4caed9b8..6d4f443496283 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.h +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.h @@ -46,6 +46,7 @@ class RegisterContextDpu : public NativeRegisterContextRegisterInfo { bool *m_context_zf; bool *m_context_cf; bool *m_registers_has_been_modified; + ProcessDpu *m_process; }; } // namespace process_dpu From 4e9862b071359371998c86e2d8e6f6a787012320 Mon Sep 17 00:00:00 2001 From: amoisson Date: Thu, 30 May 2024 09:39:24 +0200 Subject: [PATCH 11/15] removed unecessary debug prints --- lldb/source/Plugins/Process/Dpu/Dpu.cpp | 2 -- .../source/Plugins/Process/Dpu/DpuContext.cpp | 3 --- .../source/Plugins/Process/Dpu/ProcessDpu.cpp | 23 ------------------- .../Process/Dpu/RegisterContextDpu.cpp | 11 --------- 4 files changed, 39 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/Dpu.cpp b/lldb/source/Plugins/Process/Dpu/Dpu.cpp index 16f980be3d868..3540b359da3b0 100644 --- a/lldb/source/Plugins/Process/Dpu/Dpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/Dpu.cpp @@ -781,11 +781,9 @@ lldb::StateType Dpu::GetThreadState(uint32_t thread_index, uint32_t dma_fault_thread_index = context->dma_fault_thread_index; uint32_t mem_fault_thread_index = context->mem_fault_thread_index; uint32_t bkp_fault_id = context->bkp_fault_id; - printf("hello from GetThreadState() ===============\n"); if (bkp_fault && bkp_fault_thread_index == thread_index) { if (bkp_fault_id == 0) { stop_reason = eStopReasonBreakpoint; - printf("stop reason is breakpoint. Returning from GetThreadState()\n"); return eStateStopped; } else { description = "fault " + std::to_string(bkp_fault_id) + " (" + diff --git a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp index 82f11f5ce3762..90d94b27bbb8e 100644 --- a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp +++ b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp @@ -141,14 +141,11 @@ unsigned int DpuContext::GetExitStatus() { } lldb::addr_t DpuContext::GetPcOfThread(dpu_thread_t thread) { - printf("hello from GetPcOfThread() =====\n"); uint32_t raw_pc = m_context->pcs[thread]; - printf("raw_pc = 0x%x (bytes: 0x%x)\n", raw_pc, InstIdx2InstAddr(raw_pc)); uint32_t adjusted_pc = InstIdx2InstAddr(raw_pc); if (adjusted_pc >= 0x80001658) { adjusted_pc |= 0x00200000; - printf("adjusted_pc = 0x%x\n", adjusted_pc); return adjusted_pc; } return InstIdx2InstAddr(raw_pc); diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp index cc54636cce117..bfce3c85c1c26 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp @@ -575,7 +575,6 @@ Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, } Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { - printf("RemoveBreakpoint(addr=%lx, hardware=%s)\n", addr, hardware? "true" : "false"); if (hardware) return RemoveHardwareBreakpoint(addr); else @@ -587,7 +586,6 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); Status error; LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); - printf("ReadMemory(addr=%lx, ..., size=%u,...)\n", addr, size); bytes_read = 0; if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { @@ -596,7 +594,6 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); if (error.Fail()) return Status("ReadMemory: cannot convert viram to mram physical address"); - printf("reading mram at : 0x%lx\n", mram_addr - k_dpu_mram_base); if (!m_dpu->ReadMRAM(mram_addr - k_dpu_mram_base, buf, size)) return Status("ReadMemory: Cannot copy from MRAM"); } else if (addr >= k_dpu_iram_base && @@ -615,11 +612,6 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, return Status("ReadMemory: Cannot read, unknown address space"); } bytes_read = size; - printf("read at %lx : ", addr); - for (size_t i=0; i< bytes_read; i++) { - printf("%02hhX ", ((unsigned char *)buf)[i]); - } - printf("\n"); return Status(); } @@ -629,7 +621,6 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); Status error; LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); - printf("WriteMemory(addr=%lx, ..., size=%u,...)\n", addr, size); bytes_written = 0; if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { @@ -639,14 +630,11 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); if (error.Fail()) return Status("WriteMemory: cannot convert viram to mram physical address"); - printf("writing to mram at 0x%lx\n", mram_addr); if (!m_dpu->WriteMRAM(mram_addr - k_dpu_mram_base, buf, size)) return Status("WriteMemory: Cannot copy to MRAM"); error = ViramAddressToLoadedIramAddress(addr, &iram_addr); - printf("maybe writing to iram at 0x%lx\n", iram_addr); if (error.Fail()) { LLDB_LOG(log, "WriteMemory: Could not write viram to iram as this function group is not currently loaded"); - printf("WriteMemory did not write viram to iram\n"); } else if (!m_dpu->WriteIRAM(iram_addr - k_dpu_iram_base, buf, size)) return Status("WriteMemory: Cannot copy to IRAM"); } else if (addr >= k_dpu_iram_base && @@ -665,11 +653,6 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, return Status("WriteMemory: Cannot write, unknown address space"); } bytes_written = size; - printf("written at %lx : ", addr); - for (size_t i=0; i< bytes_written; i++) { - printf("%02hhX ", ((unsigned char *)buf)[i]); - } - printf("\n"); return Status(); } @@ -683,29 +666,23 @@ Status ProcessDpu::ViramAddressToMramPhysicalAddress(lldb::addr_t viram_addr, ll lldb::addr_t load_start_address = 0; size_t fg_id = ((viram_addr & k_dpu_viram_msb_mask)/k_dpu_viram_offset) - 1; error = ReadMemory(ADDR_FG_MAGIC_VALUE, &magic_value, 8, bytes_read); - printf("magic = %lx\n", magic_value); if(error.Fail() || bytes_read != 8 || magic_value != FG_MAGIC_VALUE) return Status("could not find fg magic_value\n"); error = ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); overlay_start_address <<= 3; - printf("overlay_start_address = %lx\n", overlay_start_address); lldbassert(viram_addr >= overlay_start_address); error = ReadMemory(ADDR_FG_LOAD_STARTS_ADDR, &load_starts_table_address, 4, bytes_read); - printf("load_starts_table_address = %lx\n", load_starts_table_address); if(error.Fail() || bytes_read != 4) return Status("could not read load starts table address\n"); if (load_starts_table_address == 0) return Status("function groups not properly initialized"); error = ReadMemory(load_starts_table_address+4*fg_id, &load_start_address, 4, bytes_read); - printf("load_start_address = %lx\n", load_start_address); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); // *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + 0x100090 - 0x1738 - k_dpu_iram_base + k_dpu_mram_base; *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + load_start_address - overlay_start_address - k_dpu_iram_base + k_dpu_mram_base; - printf("Viram2Mram()\n\tviram_addr=%lx\n\toverlay_start_address = %lx\n\tload start = %lx\n\tmram_addr = %lx\n", viram_addr, overlay_start_address, load_start_address, *mram_addr); - lldbassert(viram_addr != 0x80201600); return Status(); } diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp index a5fbd4bd332b5..897511955f34a 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp @@ -105,22 +105,18 @@ Status FixPc(ProcessDpu *process, uint32_t *pc) { uint32_t fg_id; error = process->ReadMemory(ADDR_FG_MAGIC_VALUE, &magic_value, 8, bytes_read); - printf("magic = %lx\n", magic_value); if(error.Fail() || bytes_read != 8 || magic_value != FG_MAGIC_VALUE) return Status("could not find fg magic_value\n"); error = process->ReadMemory(ADDR_FG_INITIALIZED, &initialized, 4, bytes_read); - printf("initialized = %x\n", initialized); if(error.Fail() || bytes_read != 4 || initialized == 0) return Status("fg groups not initialized\n"); error = process->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); overlay_start_address <<= 3; - printf("FixPc(0x%x) : overlay_start_address=0x%lx\n", *pc, overlay_start_address); if((*pc) < k_dpu_iram_base + overlay_start_address) return Status("pc below overlay_start_address\n"); error = process->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &fg_id, 4, bytes_read); - printf("fg_id = %x\n", fg_id); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); *pc |= k_dpu_viram_offset*(1+fg_id); @@ -140,13 +136,6 @@ Status RegisterContextDpu::ReadRegister(const RegisterInfo *info, if (m_thread.GetState() == eStateSuspended) pc++; FixPc(m_process, &pc); - /* - if (pc > 0x80001658) // FIXME replace this constant with a memory read - { - printf("ReadRegister fixing pc from %x to %x\n", pc, pc | 0x00200000); - pc |= 0x00200000;// TODO : Use the values stored in memory instead (and remove the fix from UnwindDpu.cpp - } - */ value.SetUInt32(pc); } else if (reg == zf_dpu) value.SetUInt32(*m_context_zf ? 1 : 0); From 5f4bdd11537c53ba92d83db63497973bea6c506e Mon Sep 17 00:00:00 2001 From: amoisson Date: Mon, 24 Jun 2024 10:47:50 +0200 Subject: [PATCH 12/15] integrated comments from last code review --- lldb/source/Plugins/Process/Utility/UnwindDPU.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp index a492419f3c36f..5b323bba6951f 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp @@ -144,6 +144,7 @@ bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, behaves_like_zeroth_frame = frame_idx == 0; cfa = m_frames[frame_idx]->cfa; pc = m_frames[frame_idx]->pc; + lldb::addr_t viram_bitmask = 0; Status error; // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf @@ -156,11 +157,12 @@ bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, uint32_t loaded_group_value; // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf if(m_thread.GetProcess()->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &loaded_group_value, 4, error) == 4) { - pc |= FG_DPU_VIRAM_OFFSET*(loaded_group_value+1); + viram_bitmask = FG_DPU_VIRAM_OFFSET*(loaded_group_value+1); } } } } + pc |= viram_bitmask; return true; } From 1ccffb0a8d6d2218c90e00d9250c49ec59654b1e Mon Sep 17 00:00:00 2001 From: amoisson Date: Mon, 22 Jul 2024 13:58:24 +0200 Subject: [PATCH 13/15] replaced use of magic value with env variable --- .../source/Plugins/Process/Dpu/ProcessDpu.cpp | 28 ++----------------- lldb/source/Plugins/Process/Dpu/ProcessDpu.h | 10 +++---- .../Process/Dpu/RegisterContextDpu.cpp | 8 +++--- .../Plugins/Process/Utility/UnwindDPU.cpp | 11 +++----- 4 files changed, 15 insertions(+), 42 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp index 607ef4b3c6c43..f4daae2123da8 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.cpp @@ -654,13 +654,6 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, return Status("ReadMemory: Cannot read, unknown address space"); } bytes_read = size; - /* - printf("ReadMemory(0x%lx) : ", addr); - for (int i=0; i= overlay_start_address); error = ReadMemory(ADDR_FG_LOAD_STARTS_ADDR, &load_starts_table_address, 4, bytes_read); - // printf("\tload_start_table = 0x%x\n", load_starts_table_address); if(error.Fail() || bytes_read != 4) return Status("could not read load starts table address\n"); if (load_starts_table_address == 0) return Status("function groups not properly initialized"); error = ReadMemory(load_starts_table_address+4*fg_id, &load_start_address, 4, bytes_read); - // printf("\tload_start = 0x%x\n", load_start_address); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); - // *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + 0x100090 - 0x1738 - k_dpu_iram_base + k_dpu_mram_base; *mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + load_start_address - overlay_start_address - k_dpu_iram_base + k_dpu_mram_base; - // printf("\t = 0x%lx\n", *mram_addr); return Status(); } diff --git a/lldb/source/Plugins/Process/Dpu/ProcessDpu.h b/lldb/source/Plugins/Process/Dpu/ProcessDpu.h index 8faa3cf227ffb..818a86ca75fb1 100644 --- a/lldb/source/Plugins/Process/Dpu/ProcessDpu.h +++ b/lldb/source/Plugins/Process/Dpu/ProcessDpu.h @@ -25,12 +25,10 @@ #include "ThreadDpu.h" #include "lldb/Host/common/NativeProcessProtocol.h" -#define ADDR_FG_MAGIC_VALUE 0x8 -#define ADDR_FG_IRAM_OVERLAY_START 0x10 -#define ADDR_FG_CURRENTLY_LOADED_GROUP 0x18 -#define ADDR_FG_LOAD_STARTS_ADDR 0x20 -#define ADDR_FG_INITIALIZED 0x28 -#define FG_MAGIC_VALUE 0xC0DE0FF10AD70015 +#define ADDR_FG_IRAM_OVERLAY_START 0x8 +#define ADDR_FG_CURRENTLY_LOADED_GROUP 0x10 +#define ADDR_FG_LOAD_STARTS_ADDR 0x18 +#define ADDR_FG_INITIALIZED 0x20 namespace lldb_private { class Status; diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp index 897511955f34a..bfe83651e3d62 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp @@ -99,14 +99,14 @@ RegisterContextDpu::GetRegisterSet(uint32_t set_index) const { Status FixPc(ProcessDpu *process, uint32_t *pc) { Status error; size_t bytes_read; - uint64_t magic_value; + // uint64_t magic_value; uint32_t initialized = 0; lldb::addr_t overlay_start_address = 0; uint32_t fg_id; - error = process->ReadMemory(ADDR_FG_MAGIC_VALUE, &magic_value, 8, bytes_read); - if(error.Fail() || bytes_read != 8 || magic_value != FG_MAGIC_VALUE) - return Status("could not find fg magic_value\n"); + const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); + if (using_function_groups == NULL || using_function_groups[0] == '\0') + return Status("Could not find USING_FUNCTION_GROUPS env variable\n"); error = process->ReadMemory(ADDR_FG_INITIALIZED, &initialized, 4, bytes_read); if(error.Fail() || bytes_read != 4 || initialized == 0) return Status("fg groups not initialized\n"); diff --git a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp index 5b323bba6951f..6ae4ca24d06b1 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp @@ -25,10 +25,8 @@ using namespace lldb; using namespace lldb_private; -#define ADDR_FG_MAGIC_VALUE 0x8 -#define ADDR_FG_IRAM_OVERLAY_START 0x10 -#define ADDR_FG_CURRENTLY_LOADED_GROUP 0x18 -#define FG_MAGIC_VALUE 0xC0DE0FF10AD70015 +#define ADDR_FG_IRAM_OVERLAY_START 0x8 +#define ADDR_FG_CURRENTLY_LOADED_GROUP 0x10 #define DPU_IRAM_BASE 0x80000000 #define FG_DPU_VIRAM_OFFSET 0x00100000 @@ -147,9 +145,8 @@ bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t viram_bitmask = 0; Status error; - // FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf - uint64_t magic_value = 0; - if (m_thread.GetProcess()->ReadMemory(ADDR_FG_MAGIC_VALUE, &magic_value, 8, error) == 8 && magic_value == FG_MAGIC_VALUE) { + const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); + if (using_function_groups != NULL && using_function_groups[0] != '\0') { lldb::addr_t overlay_start_address; if(m_thread.GetProcess()->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 8, error) == 8) { overlay_start_address = FORMAT_PC(overlay_start_address); From efbc616c62be980a236f480cb14fee7128add6aa Mon Sep 17 00:00:00 2001 From: amoisson Date: Tue, 27 Aug 2024 10:36:46 +0200 Subject: [PATCH 14/15] did some reformatting --- .../source/Plugins/Process/Dpu/DpuContext.cpp | 6 --- .../Process/Dpu/RegisterContextDpu.cpp | 2 +- .../Plugins/Process/Utility/UnwindDPU.cpp | 43 +++++++++++-------- .../Plugins/Process/Utility/UnwindDPU.h | 2 + 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp index e4f647057b07f..20ede2803e32d 100644 --- a/lldb/source/Plugins/Process/Dpu/DpuContext.cpp +++ b/lldb/source/Plugins/Process/Dpu/DpuContext.cpp @@ -142,12 +142,6 @@ unsigned int DpuContext::GetExitStatus() { lldb::addr_t DpuContext::GetPcOfThread(dpu_thread_t thread) { uint32_t raw_pc = m_context->pcs[thread]; - uint32_t adjusted_pc = InstIdx2InstAddr(raw_pc); - if (adjusted_pc >= 0x80001658) - { - adjusted_pc |= 0x00200000; - return adjusted_pc; - } return InstIdx2InstAddr(raw_pc); } diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp index bfe83651e3d62..811b358a89b6d 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp @@ -119,7 +119,7 @@ Status FixPc(ProcessDpu *process, uint32_t *pc) { error = process->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &fg_id, 4, bytes_read); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); - *pc |= k_dpu_viram_offset*(1+fg_id); + *pc |= k_dpu_viram_offset * (1 + fg_id); return Status(); } diff --git a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp index 6ae4ca24d06b1..5e61fa6a881c3 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindDPU.cpp @@ -134,6 +134,29 @@ uint32_t UnwindDPU::DoGetFrameCount() { return m_frames.size(); } +bool UnwindDPU::FixPcForOverlay(lldb::addr_t &pc) { + Status error; + lldb::addr_t overlay_start_address; + lldb::addr_t viram_bitmask = 0; + const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); + + if (using_function_groups == NULL || using_function_groups[0] == '\0') + return true; + + if(m_thread.GetProcess()->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 8, error) != 8) + return false; + overlay_start_address = FORMAT_PC(overlay_start_address); + if (pc >= overlay_start_address && overlay_start_address != DPU_IRAM_BASE) { + uint32_t loaded_group_value; + // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf + if(m_thread.GetProcess()->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &loaded_group_value, 4, error) != 4) + return false; + viram_bitmask = FG_DPU_VIRAM_OFFSET*(loaded_group_value+1); + } + pc |= viram_bitmask; + return true; +} + bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t &pc, bool &behaves_like_zeroth_frame) { if (frame_idx >= DoGetFrameCount()) @@ -142,26 +165,8 @@ bool UnwindDPU::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, behaves_like_zeroth_frame = frame_idx == 0; cfa = m_frames[frame_idx]->cfa; pc = m_frames[frame_idx]->pc; - lldb::addr_t viram_bitmask = 0; - - Status error; - const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); - if (using_function_groups != NULL && using_function_groups[0] != '\0') { - lldb::addr_t overlay_start_address; - if(m_thread.GetProcess()->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 8, error) == 8) { - overlay_start_address = FORMAT_PC(overlay_start_address); - if (pc >= overlay_start_address && overlay_start_address != DPU_IRAM_BASE) { - uint32_t loaded_group_value; - // FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf - if(m_thread.GetProcess()->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &loaded_group_value, 4, error) == 4) { - viram_bitmask = FG_DPU_VIRAM_OFFSET*(loaded_group_value+1); - } - } - } - } - pc |= viram_bitmask; - return true; + return FixPcForOverlay(pc); } lldb::RegisterContextSP diff --git a/lldb/source/Plugins/Process/Utility/UnwindDPU.h b/lldb/source/Plugins/Process/Utility/UnwindDPU.h index dd6f622e84964..2a9dfaf9c66ac 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindDPU.h +++ b/lldb/source/Plugins/Process/Utility/UnwindDPU.h @@ -39,6 +39,8 @@ class UnwindDPU : public lldb_private::Unwind { uint32_t DoGetFrameCount() override; + bool FixPcForOverlay(lldb::addr_t &pc); + bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t &pc, bool &behaves_like_zeroth_frame) override; From e5ca72c1ad89df3eb027f4bdde5a99f793b427b8 Mon Sep 17 00:00:00 2001 From: amoisson Date: Thu, 29 Aug 2024 13:31:05 +0200 Subject: [PATCH 15/15] minor syntax change --- lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp index 811b358a89b6d..9c2a9c0de0b39 100644 --- a/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp +++ b/lldb/source/Plugins/Process/Dpu/RegisterContextDpu.cpp @@ -107,18 +107,23 @@ Status FixPc(ProcessDpu *process, uint32_t *pc) { const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); if (using_function_groups == NULL || using_function_groups[0] == '\0') return Status("Could not find USING_FUNCTION_GROUPS env variable\n"); + error = process->ReadMemory(ADDR_FG_INITIALIZED, &initialized, 4, bytes_read); if(error.Fail() || bytes_read != 4 || initialized == 0) return Status("fg groups not initialized\n"); + error = process->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); + overlay_start_address <<= 3; if((*pc) < k_dpu_iram_base + overlay_start_address) return Status("pc below overlay_start_address\n"); + error = process->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &fg_id, 4, bytes_read); if(error.Fail() || bytes_read != 4) return Status("could not read load start address\n"); + *pc |= k_dpu_viram_offset * (1 + fg_id); return Status(); }