diff --git a/DevTools/UserspaceEmulator/Emulator.cpp b/DevTools/UserspaceEmulator/Emulator.cpp index 8aeafd900c..0430367e37 100644 --- a/DevTools/UserspaceEmulator/Emulator.cpp +++ b/DevTools/UserspaceEmulator/Emulator.cpp @@ -219,9 +219,9 @@ void Emulator::dump_backtrace(const Vector& backtrace) auto source_position = m_debug_info->get_source_position(address); new_warn("=={}== {:p} {}", getpid(), address, symbol); if (source_position.has_value()) - warnln(" (\033[34;1m{}\033[0m:{})", LexicalPath(source_position.value().file_path).basename(), source_position.value().line_number); + reportln(" (\033[34;1m{}\033[0m:{})", LexicalPath(source_position.value().file_path).basename(), source_position.value().line_number); else - warnln(" +{:x}", offset); + reportln(" +{:x}", offset); } } @@ -233,7 +233,7 @@ void Emulator::dump_backtrace() u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) { #ifdef DEBUG_SPAM - dbgln("Syscall: {} ({:x})", Syscall::to_string((Syscall::Function)function), function); + reportln("Syscall: {} ({:x})", Syscall::to_string((Syscall::Function)function), function); #endif switch (function) { case SC_chdir: @@ -378,7 +378,7 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3) case SC_fork: return virt$fork(); default: - warnln("\n=={}== \033[31;1mUnimplemented syscall: {}\033[0m, {:p}", getpid(), Syscall::to_string((Syscall::Function)function), function); + reportln("\n=={}== \033[31;1mUnimplemented syscall: {}\033[0m, {:p}", getpid(), Syscall::to_string((Syscall::Function)function), function); dump_backtrace(); TODO(); } @@ -896,7 +896,7 @@ u32 Emulator::virt$read(int fd, FlatPtr buffer, ssize_t size) void Emulator::virt$exit(int status) { - warnln("\n=={}== \033[33;1mSyscall: exit({})\033[0m, shutting down!", getpid(), status); + reportln("\n=={}== \033[33;1mSyscall: exit({})\033[0m, shutting down!", getpid(), status); m_exit_status = status; m_shutdown = true; } @@ -949,7 +949,7 @@ int Emulator::virt$ioctl(int fd, unsigned request, FlatPtr arg) mmu().copy_from_vm(&termios, arg, sizeof(termios)); return syscall(SC_ioctl, fd, request, &termios); } - dbgln("Unsupported ioctl: {}", request); + reportln("Unsupported ioctl: {}", request); dump_backtrace(); TODO(); } @@ -982,16 +982,19 @@ int Emulator::virt$execve(FlatPtr params_addr) copy_string_list(arguments, params.arguments); copy_string_list(environment, params.environment); - warnln("\n=={}== \033[33;1mSyscall:\033[0m execve", getpid()); - warnln("=={}== @ {}", getpid(), path); + reportln("\n=={}== \033[33;1mSyscall:\033[0m execve", getpid()); + reportln("=={}== @ {}", getpid(), path); for (auto& argument : arguments) - warnln("=={}== - {}", getpid(), argument); + reportln("=={}== - {}", getpid(), argument); Vector argv; Vector envp; argv.append(const_cast("/bin/UserspaceEmulator")); argv.append(const_cast(path.characters())); + if (g_report_to_debug) + argv.append(const_cast("--report-to-debug")); + argv.append(const_cast("--")); auto create_string_vector = [](auto& output_vector, auto& input_vector) { for (auto& string : input_vector) @@ -1003,7 +1006,7 @@ int Emulator::virt$execve(FlatPtr params_addr) create_string_vector(envp, environment); // Yoink duplicated program name. - argv.remove(2); + argv.remove(3 + (g_report_to_debug ? 1 : 0)); return execve(argv[0], (char* const*)argv.data(), (char* const*)envp.data()); } @@ -1070,7 +1073,7 @@ void Emulator::register_signal_handlers() int Emulator::virt$sigaction(int signum, FlatPtr act, FlatPtr oldact) { if (signum == SIGKILL) { - dbgln("Attempted to sigaction() with SIGKILL"); + reportln("Attempted to sigaction() with SIGKILL"); return -EINVAL; } @@ -1198,7 +1201,7 @@ void Emulator::dispatch_one_pending_signal() auto action = default_signal_action(signum); if (action == DefaultSignalAction::Ignore) return; - warnln("\n=={}== Got signal {} ({}), no handler registered", getpid(), signum, strsignal(signum)); + reportln("\n=={}== Got signal {} ({}), no handler registered", getpid(), signum, strsignal(signum)); m_shutdown = true; return; } @@ -1208,7 +1211,7 @@ void Emulator::dispatch_one_pending_signal() return; } - warnln("\n=={}== Got signal {} ({}), handler at {:p}", getpid(), signum, strsignal(signum), handler.handler); + reportln("\n=={}== Got signal {} ({}), handler at {:p}", getpid(), signum, strsignal(signum), handler.handler); auto old_esp = m_cpu.esp(); diff --git a/DevTools/UserspaceEmulator/Emulator.h b/DevTools/UserspaceEmulator/Emulator.h index e2f8ff5a20..1b55ebd3c6 100644 --- a/DevTools/UserspaceEmulator/Emulator.h +++ b/DevTools/UserspaceEmulator/Emulator.h @@ -27,6 +27,7 @@ #pragma once #include "MallocTracer.h" +#include "Report.h" #include "SoftCPU.h" #include "SoftMMU.h" #include diff --git a/DevTools/UserspaceEmulator/MallocTracer.cpp b/DevTools/UserspaceEmulator/MallocTracer.cpp index bfafb777a1..48cff29c37 100644 --- a/DevTools/UserspaceEmulator/MallocTracer.cpp +++ b/DevTools/UserspaceEmulator/MallocTracer.cpp @@ -71,8 +71,8 @@ void MallocTracer::target_did_free(Badge, FlatPtr address) for (auto& mallocation : m_mallocations) { if (mallocation.address == address) { if (mallocation.freed) { - warnln("\n=={}== \033[31;1mDouble free()\033[0m, {:p}", getpid(), address); - warnln("=={}== Address {} has already been passed to free()", getpid(), address); + reportln("\n=={}== \033[31;1mDouble free()\033[0m, {:p}", getpid(), address); + reportln("=={}== Address {} has already been passed to free()", getpid(), address); Emulator::the().dump_backtrace(); } else { mallocation.freed = true; @@ -82,8 +82,8 @@ void MallocTracer::target_did_free(Badge, FlatPtr address) } } - warnln("\n=={}== \033[31;1mInvalid free()\033[0m, {:p}", getpid(), address); - warnln("=={}== Address {} has never been returned by malloc()", getpid(), address); + reportln("\n=={}== \033[31;1mInvalid free()\033[0m, {:p}", getpid(), address); + reportln("=={}== Address {} has never been returned by malloc()", getpid(), address); Emulator::the().dump_backtrace(); } @@ -119,11 +119,11 @@ void MallocTracer::audit_read(FlatPtr address, size_t size) auto* mallocation = find_mallocation(address); if (!mallocation) { - warnln("\n=={}== \033[31;1mHeap buffer overflow\033[0m, invalid {}-byte read at address {:p}", getpid(), size, address); + reportln("\n=={}== \033[31;1mHeap buffer overflow\033[0m, invalid {}-byte read at address {:p}", getpid(), size, address); Emulator::the().dump_backtrace(); if ((mallocation = find_mallocation_before(address))) { size_t offset_into_mallocation = address - mallocation->address; - warnln("=={}== Address is {} byte(s) after block of size {}, allocated at:", getpid(), offset_into_mallocation - mallocation->size, mallocation->size); + reportln("=={}== Address is {} byte(s) after block of size {}, allocated at:", getpid(), offset_into_mallocation - mallocation->size, mallocation->size); Emulator::the().dump_backtrace(mallocation->malloc_backtrace); } return; @@ -132,11 +132,11 @@ void MallocTracer::audit_read(FlatPtr address, size_t size) size_t offset_into_mallocation = address - mallocation->address; if (mallocation->freed) { - warnln("\n=={}== \033[31;1mUse-after-free\033[0m, invalid {}-byte read at address {:p}", getpid(), size, address); + reportln("\n=={}== \033[31;1mUse-after-free\033[0m, invalid {}-byte read at address {:p}", getpid(), size, address); Emulator::the().dump_backtrace(); - warnln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); + reportln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->malloc_backtrace); - warnln("=={}== Later freed at:", getpid()); + reportln("=={}== Later freed at:", getpid()); Emulator::the().dump_backtrace(mallocation->free_backtrace); return; } @@ -152,11 +152,11 @@ void MallocTracer::audit_write(FlatPtr address, size_t size) auto* mallocation = find_mallocation(address); if (!mallocation) { - warnln("\n=={}== \033[31;1mHeap buffer overflow\033[0m, invalid {}-byte write at address {:p}", getpid(), size, address); + reportln("\n=={}== \033[31;1mHeap buffer overflow\033[0m, invalid {}-byte write at address {:p}", getpid(), size, address); Emulator::the().dump_backtrace(); if ((mallocation = find_mallocation_before(address))) { size_t offset_into_mallocation = address - mallocation->address; - warnln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); + reportln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->malloc_backtrace); } return; @@ -165,11 +165,11 @@ void MallocTracer::audit_write(FlatPtr address, size_t size) size_t offset_into_mallocation = address - mallocation->address; if (mallocation->freed) { - warnln("\n=={}== \033[31;1mUse-after-free\033[0m, invalid {}-byte write at address {:p}", getpid(), size, address); + reportln("\n=={}== \033[31;1mUse-after-free\033[0m, invalid {}-byte write at address {:p}", getpid(), size, address); Emulator::the().dump_backtrace(); - warnln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); + reportln("=={}== Address is {} byte(s) into block of size {}, allocated at:", getpid(), offset_into_mallocation, mallocation->size); Emulator::the().dump_backtrace(mallocation->malloc_backtrace); - warnln("=={}== Later freed at:", getpid()); + reportln("=={}== Later freed at:", getpid()); Emulator::the().dump_backtrace(mallocation->free_backtrace); return; } @@ -190,7 +190,7 @@ bool MallocTracer::is_reachable(const Mallocation& mallocation) const auto value = Emulator::the().mmu().read32({ 0x20, other_mallocation.address + i * sizeof(u32) }); if (value.value() == mallocation.address && !value.is_uninitialized()) { #ifdef REACHABLE_DEBUG - warnln("mallocation {:p} is reachable from other mallocation {:p}", mallocation.address, other_mallocation.address); + reportln("mallocation {:p} is reachable from other mallocation {:p}", mallocation.address, other_mallocation.address); #endif return true; } @@ -215,7 +215,7 @@ bool MallocTracer::is_reachable(const Mallocation& mallocation) const auto value = region.read32(i * sizeof(u32)); if (value.value() == mallocation.address && !value.is_uninitialized()) { #ifdef REACHABLE_DEBUG - warnln("mallocation {:p} is reachable from region {:p}-{:p}", mallocation.address, region.base(), region.end() - 1); + reportln("mallocation {:p} is reachable from region {:p}-{:p}", mallocation.address, region.base(), region.end() - 1); #endif reachable = true; return IterationDecision::Break; @@ -239,14 +239,14 @@ void MallocTracer::dump_leak_report() continue; ++leaks_found; bytes_leaked += mallocation.size; - warnln("\n=={}== \033[31;1mLeak\033[0m, {}-byte allocation at address {:p}", getpid(), mallocation.size, mallocation.address); + reportln("\n=={}== \033[31;1mLeak\033[0m, {}-byte allocation at address {:p}", getpid(), mallocation.size, mallocation.address); Emulator::the().dump_backtrace(mallocation.malloc_backtrace); } if (!leaks_found) - warnln("\n=={}== \033[32;1mNo leaks found!\033[0m", getpid()); + reportln("\n=={}== \033[32;1mNo leaks found!\033[0m", getpid()); else - warnln("\n=={}== \033[31;1m{} leak(s) found: {} byte(s) leaked\033[0m", getpid(), leaks_found, bytes_leaked); + reportln("\n=={}== \033[31;1m{} leak(s) found: {} byte(s) leaked\033[0m", getpid(), leaks_found, bytes_leaked); } } diff --git a/DevTools/UserspaceEmulator/MmapRegion.cpp b/DevTools/UserspaceEmulator/MmapRegion.cpp index b3123183d8..f0036f729c 100644 --- a/DevTools/UserspaceEmulator/MmapRegion.cpp +++ b/DevTools/UserspaceEmulator/MmapRegion.cpp @@ -68,7 +68,7 @@ MmapRegion::~MmapRegion() ValueWithShadow MmapRegion::read8(FlatPtr offset) { if (!is_readable()) { - warnln("8-bit read from unreadable MmapRegion @ {:p}", base() + offset); + reportln("8-bit read from unreadable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -85,7 +85,7 @@ ValueWithShadow MmapRegion::read8(FlatPtr offset) ValueWithShadow MmapRegion::read16(u32 offset) { if (!is_readable()) { - warnln("16-bit read from unreadable MmapRegion @ {:p}", base() + offset); + reportln("16-bit read from unreadable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -102,7 +102,7 @@ ValueWithShadow MmapRegion::read16(u32 offset) ValueWithShadow MmapRegion::read32(u32 offset) { if (!is_readable()) { - warnln("32-bit read from unreadable MmapRegion @ {:p}", base() + offset); + reportln("32-bit read from unreadable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -119,7 +119,7 @@ ValueWithShadow MmapRegion::read32(u32 offset) ValueWithShadow MmapRegion::read64(u32 offset) { if (!is_readable()) { - warnln("64-bit read from unreadable MmapRegion @ {:p}", base() + offset); + reportln("64-bit read from unreadable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -136,7 +136,7 @@ ValueWithShadow MmapRegion::read64(u32 offset) void MmapRegion::write8(u32 offset, ValueWithShadow value) { if (!is_writable()) { - warnln("8-bit write from unwritable MmapRegion @ {:p}", base() + offset); + reportln("8-bit write from unwritable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -154,7 +154,7 @@ void MmapRegion::write8(u32 offset, ValueWithShadow value) void MmapRegion::write16(u32 offset, ValueWithShadow value) { if (!is_writable()) { - warnln("16-bit write from unwritable MmapRegion @ {:p}", base() + offset); + reportln("16-bit write from unwritable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -172,7 +172,7 @@ void MmapRegion::write16(u32 offset, ValueWithShadow value) void MmapRegion::write32(u32 offset, ValueWithShadow value) { if (!is_writable()) { - warnln("32-bit write from unwritable MmapRegion @ {:p}", base() + offset); + reportln("32-bit write from unwritable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } @@ -191,7 +191,7 @@ void MmapRegion::write32(u32 offset, ValueWithShadow value) void MmapRegion::write64(u32 offset, ValueWithShadow value) { if (!is_writable()) { - warnln("64-bit write from unwritable MmapRegion @ {:p}", base() + offset); + reportln("64-bit write from unwritable MmapRegion @ {:p}", base() + offset); Emulator::the().dump_backtrace(); TODO(); } diff --git a/DevTools/UserspaceEmulator/Report.h b/DevTools/UserspaceEmulator/Report.h new file mode 100644 index 0000000000..97dcf97537 --- /dev/null +++ b/DevTools/UserspaceEmulator/Report.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +extern bool g_report_to_debug; + +template +void reportln(const StringView& format, Ts... args) +{ + if (g_report_to_debug) + dbgln(format, args...); + else + warnln(format, args...); +} diff --git a/DevTools/UserspaceEmulator/SoftCPU.cpp b/DevTools/UserspaceEmulator/SoftCPU.cpp index a72b084607..2c5bb3fdce 100644 --- a/DevTools/UserspaceEmulator/SoftCPU.cpp +++ b/DevTools/UserspaceEmulator/SoftCPU.cpp @@ -34,11 +34,11 @@ # pragma GCC optimize("O3") #endif -#define TODO_INSN() \ - do { \ - warnln("\n=={}== Unimplemented instruction: {}\n", getpid(), __FUNCTION__); \ - m_emulator.dump_backtrace(); \ - _exit(0); \ +#define TODO_INSN() \ + do { \ + reportln("\n=={}== Unimplemented instruction: {}\n", getpid(), __FUNCTION__); \ + m_emulator.dump_backtrace(); \ + _exit(0); \ } while (0) //#define MEMORY_DEBUG @@ -60,7 +60,7 @@ template void warn_if_uninitialized(T value_with_shadow, const char* message) { if (value_with_shadow.is_uninitialized()) { - dbgln("\033[31;1mWarning! Use of uninitialized value: {}\033[0m\n", message); + reportln("\033[31;1mWarning! Use of uninitialized value: {}\033[0m\n", message); Emulator::the().dump_backtrace(); } } @@ -68,7 +68,7 @@ void warn_if_uninitialized(T value_with_shadow, const char* message) void SoftCPU::warn_if_flags_tainted(const char* message) const { if (m_flags_tainted) { - warnln("\n=={}== \033[31;1mConditional depends on uninitialized data\033[0m ({})\n", getpid(), message); + reportln("\n=={}== \033[31;1mConditional depends on uninitialized data\033[0m ({})\n", getpid(), message); Emulator::the().dump_backtrace(); } } @@ -1342,13 +1342,13 @@ void SoftCPU::DIV_RM16(const X86::Instruction& insn) { auto divisor = insn.modrm().read16(*this, insn); if (divisor.value() == 0) { - warnln("Divide by zero"); + reportln("Divide by zero"); TODO(); } u32 dividend = ((u32)dx().value() << 16) | ax().value(); auto quotient = dividend / divisor.value(); if (quotient > NumericLimits::max()) { - warnln("Divide overflow"); + reportln("Divide overflow"); TODO(); } @@ -1363,13 +1363,13 @@ void SoftCPU::DIV_RM32(const X86::Instruction& insn) { auto divisor = insn.modrm().read32(*this, insn); if (divisor.value() == 0) { - warnln("Divide by zero"); + reportln("Divide by zero"); TODO(); } u64 dividend = ((u64)edx().value() << 32) | eax().value(); auto quotient = dividend / divisor.value(); if (quotient > NumericLimits::max()) { - warnln("Divide overflow"); + reportln("Divide overflow"); TODO(); } @@ -1384,13 +1384,13 @@ void SoftCPU::DIV_RM8(const X86::Instruction& insn) { auto divisor = insn.modrm().read8(*this, insn); if (divisor.value() == 0) { - warnln("Divide by zero"); + reportln("Divide by zero"); TODO(); } u16 dividend = ax().value(); auto quotient = dividend / divisor.value(); if (quotient > NumericLimits::max()) { - warnln("Divide overflow"); + reportln("Divide overflow"); TODO(); } @@ -1405,7 +1405,7 @@ void SoftCPU::ENTER32(const X86::Instruction&) { TODO_INSN(); } void SoftCPU::ESCAPE(const X86::Instruction&) { - dbgln("FIXME: x87 floating-point support"); + reportln("FIXME: x87 floating-point support"); m_emulator.dump_backtrace(); TODO(); } @@ -1546,13 +1546,13 @@ void SoftCPU::IDIV_RM16(const X86::Instruction& insn) auto divisor_with_shadow = insn.modrm().read16(*this, insn); auto divisor = (i16)divisor_with_shadow.value(); if (divisor == 0) { - warnln("Divide by zero"); + reportln("Divide by zero"); TODO(); } i32 dividend = (i32)(((u32)dx().value() << 16) | (u32)ax().value()); i32 result = dividend / divisor; if (result > NumericLimits::max() || result < NumericLimits::min()) { - warnln("Divide overflow"); + reportln("Divide overflow"); TODO(); } @@ -1566,13 +1566,13 @@ void SoftCPU::IDIV_RM32(const X86::Instruction& insn) auto divisor_with_shadow = insn.modrm().read32(*this, insn); auto divisor = (i32)divisor_with_shadow.value(); if (divisor == 0) { - warnln("Divide by zero"); + reportln("Divide by zero"); TODO(); } i64 dividend = (i64)(((u64)edx().value() << 32) | (u64)eax().value()); i64 result = dividend / divisor; if (result > NumericLimits::max() || result < NumericLimits::min()) { - warnln("Divide overflow"); + reportln("Divide overflow"); TODO(); } @@ -1586,13 +1586,13 @@ void SoftCPU::IDIV_RM8(const X86::Instruction& insn) auto divisor_with_shadow = insn.modrm().read8(*this, insn); auto divisor = (i8)divisor_with_shadow.value(); if (divisor == 0) { - warnln("Divide by zero"); + reportln("Divide by zero"); TODO(); } i16 dividend = ax().value(); i16 result = dividend / divisor; if (result > NumericLimits::max() || result < NumericLimits::min()) { - warnln("Divide overflow"); + reportln("Divide overflow"); TODO(); } diff --git a/DevTools/UserspaceEmulator/SoftMMU.cpp b/DevTools/UserspaceEmulator/SoftMMU.cpp index 86ea4e8fa1..6f578cdc1a 100644 --- a/DevTools/UserspaceEmulator/SoftMMU.cpp +++ b/DevTools/UserspaceEmulator/SoftMMU.cpp @@ -25,6 +25,7 @@ */ #include "SoftMMU.h" +#include "Report.h" #include "SharedBufferRegion.h" #include @@ -68,7 +69,7 @@ ValueWithShadow SoftMMU::read8(X86::LogicalAddress address) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::read8: No region for @ {:p}", address.offset()); + reportln("SoftMMU::read8: No region for @ {:p}", address.offset()); TODO(); } @@ -79,7 +80,7 @@ ValueWithShadow SoftMMU::read16(X86::LogicalAddress address) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::read16: No region for @ {:p}", address.offset()); + reportln("SoftMMU::read16: No region for @ {:p}", address.offset()); TODO(); } @@ -90,7 +91,7 @@ ValueWithShadow SoftMMU::read32(X86::LogicalAddress address) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::read32: No region for @ {:p}", address.offset()); + reportln("SoftMMU::read32: No region for @ {:p}", address.offset()); TODO(); } @@ -101,7 +102,7 @@ ValueWithShadow SoftMMU::read64(X86::LogicalAddress address) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::read64: No region for @ {:p}", address.offset()); + reportln("SoftMMU::read64: No region for @ {:p}", address.offset()); TODO(); } @@ -112,7 +113,7 @@ void SoftMMU::write8(X86::LogicalAddress address, ValueWithShadow value) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::write8: No region for @ {:p}", address.offset()); + reportln("SoftMMU::write8: No region for @ {:p}", address.offset()); TODO(); } @@ -123,7 +124,7 @@ void SoftMMU::write16(X86::LogicalAddress address, ValueWithShadow value) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::write16: No region for @ {:p}", address.offset()); + reportln("SoftMMU::write16: No region for @ {:p}", address.offset()); TODO(); } @@ -134,7 +135,7 @@ void SoftMMU::write32(X86::LogicalAddress address, ValueWithShadow value) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::write32: No region for @ {:p}", address.offset()); + reportln("SoftMMU::write32: No region for @ {:p}", address.offset()); TODO(); } @@ -145,7 +146,7 @@ void SoftMMU::write64(X86::LogicalAddress address, ValueWithShadow value) { auto* region = find_region(address); if (!region) { - warnln("SoftMMU::write64: No region for @ {:p}", address.offset()); + reportln("SoftMMU::write64: No region for @ {:p}", address.offset()); TODO(); } diff --git a/DevTools/UserspaceEmulator/main.cpp b/DevTools/UserspaceEmulator/main.cpp index 185a233dfa..e88b5d77f9 100644 --- a/DevTools/UserspaceEmulator/main.cpp +++ b/DevTools/UserspaceEmulator/main.cpp @@ -37,11 +37,14 @@ #include #include +bool g_report_to_debug = false; + int main(int argc, char** argv, char** env) { Vector command; Core::ArgsParser parser; + parser.add_option(g_report_to_debug, "Write reports to the debug log", "report-to-debug", 0); parser.add_positional_argument(command, "Command to emulate", "command"); parser.parse(argc, argv); @@ -49,7 +52,7 @@ int main(int argc, char** argv, char** env) MappedFile mapped_file(executable_path); if (!mapped_file.is_valid()) { - warnln("Unable to map {}", executable_path); + reportln("Unable to map {}", executable_path); return 1; } @@ -78,7 +81,7 @@ int main(int argc, char** argv, char** env) } int rc = pthread_setname_np(pthread_self(), builder.to_string().characters()); if (rc != 0) { - warnln("pthread_setname_np: {}", strerror(rc)); + reportln("pthread_setname_np: {}", strerror(rc)); return 1; } return emulator.exec();