diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index c371f0ed58a3a7e38ba393a3ad8052d16343cd54..d4f422604a3f87ce1eb70c226caf830f6e1a1d83 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -128,7 +128,7 @@ public: } } - + static size_t WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data) { @@ -156,7 +156,7 @@ public: data.PutChar(0); return reg_byte_size; } - + static bool Create_LC_THREAD (Thread *thread, Stream &data) { @@ -357,6 +357,73 @@ public: } } } + + static size_t + WriteRegister (RegisterContext *reg_ctx, const char *name, const char *alt_name, size_t reg_byte_size, Stream &data) + { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name); + if (reg_info == NULL) + reg_info = reg_ctx->GetRegisterInfoByName(alt_name); + if (reg_info) + { + lldb_private::RegisterValue reg_value; + if (reg_ctx->ReadRegister(reg_info, reg_value)) + { + if (reg_info->byte_size >= reg_byte_size) + data.Write(reg_value.GetBytes(), reg_byte_size); + else + { + data.Write(reg_value.GetBytes(), reg_info->byte_size); + for (size_t i=0, n = reg_byte_size - reg_info->byte_size; iGetRegisterContext()); + if (reg_ctx_sp) + { + RegisterContext *reg_ctx = reg_ctx_sp.get(); + + data.PutHex32 (GPRRegSet); // Flavor + data.PutHex32 (sizeof(GPR)/sizeof(uint32_t)); // Number of uint32_t values that follow + WriteRegister (reg_ctx, "eax", NULL, 4, data); + WriteRegister (reg_ctx, "ebx", NULL, 4, data); + WriteRegister (reg_ctx, "ecx", NULL, 4, data); + WriteRegister (reg_ctx, "edx", NULL, 4, data); + WriteRegister (reg_ctx, "edi", NULL, 4, data); + WriteRegister (reg_ctx, "esi", NULL, 4, data); + WriteRegister (reg_ctx, "ebp", NULL, 4, data); + WriteRegister (reg_ctx, "esp", NULL, 4, data); + WriteRegister (reg_ctx, "ss", NULL, 4, data); + WriteRegister (reg_ctx, "eflags", NULL, 4, data); + WriteRegister (reg_ctx, "eip", NULL, 4, data); + WriteRegister (reg_ctx, "cs", NULL, 4, data); + WriteRegister (reg_ctx, "ds", NULL, 4, data); + WriteRegister (reg_ctx, "es", NULL, 4, data); + WriteRegister (reg_ctx, "fs", NULL, 4, data); + WriteRegister (reg_ctx, "gs", NULL, 4, data); + + // Write out the EXC registers + data.PutHex32 (EXCRegSet); + data.PutHex32 (sizeof(EXC)/sizeof(uint32_t)); + WriteRegister (reg_ctx, "trapno", NULL, 4, data); + WriteRegister (reg_ctx, "err", NULL, 4, data); + WriteRegister (reg_ctx, "faultvaddr", NULL, 8, data); + return true; + } + return false; + } + protected: virtual int DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr) @@ -5217,7 +5284,6 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, bool make_core = false; switch (target_arch.GetMachine()) { - case llvm::Triple::arm: case llvm::Triple::x86: case llvm::Triple::x86_64: make_core = true; @@ -5233,6 +5299,8 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, // uint32_t range_info_idx = 0; MemoryRegionInfo range_info; Error range_error = process_sp->GetMemoryRegionInfo(0, range_info); + const uint32_t addr_byte_size = target_arch.GetAddressByteSize(); + const ByteOrder byte_order = target_arch.GetByteOrder(); if (range_error.Success()) { while (range_info.GetRange().GetRangeBase() != LLDB_INVALID_ADDRESS) @@ -5262,14 +5330,21 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, if (prot != 0) { + uint32_t cmd_type = LC_SEGMENT_64; + uint32_t segment_size = sizeof (segment_command_64); + if (addr_byte_size == 4) + { + cmd_type = LC_SEGMENT; + segment_size = sizeof (segment_command); + } segment_command_64 segment = { - LC_SEGMENT_64, // uint32_t cmd; - sizeof(segment), // uint32_t cmdsize; + cmd_type, // uint32_t cmd; + segment_size, // uint32_t cmdsize; {0}, // char segname[16]; - addr, // uint64_t vmaddr; - size, // uint64_t vmsize; - 0, // uint64_t fileoff; - size, // uint64_t filesize; + addr, // uint64_t vmaddr; // uint32_t for 32-bit Mach-O + size, // uint64_t vmsize; // uint32_t for 32-bit Mach-O + 0, // uint64_t fileoff; // uint32_t for 32-bit Mach-O + size, // uint64_t filesize; // uint32_t for 32-bit Mach-O prot, // uint32_t maxprot; prot, // uint32_t initprot; 0, // uint32_t nsects; @@ -5290,14 +5365,19 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, break; } - const uint32_t addr_byte_size = target_arch.GetAddressByteSize(); - const ByteOrder byte_order = target_arch.GetByteOrder(); StreamString buffer (Stream::eBinary, addr_byte_size, byte_order); mach_header_64 mach_header; - mach_header.magic = MH_MAGIC_64; + if (addr_byte_size == 8) + { + mach_header.magic = MH_MAGIC_64; + } + else + { + mach_header.magic = MH_MAGIC; + } mach_header.cputype = target_arch.GetMachOCPUType(); mach_header.cpusubtype = target_arch.GetMachOCPUSubType(); mach_header.filetype = MH_CORE; @@ -5330,7 +5410,7 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, break; case llvm::MachO::CPU_TYPE_I386: - //RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), thread_load_commands); + RegisterContextDarwin_i386_Mach::Create_LC_THREAD (thread_sp.get(), LC_THREAD_datas[thread_idx]); break; case llvm::MachO::CPU_TYPE_X86_64: @@ -5342,7 +5422,14 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, } // The size of the load command is the size of the segments... - mach_header.sizeofcmds = segment_load_commands.size() * segment_load_commands[0].cmdsize; + if (addr_byte_size == 8) + { + mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command_64); + } + else + { + mach_header.sizeofcmds = segment_load_commands.size() * sizeof (struct segment_command); + } // and the size of all LC_THREAD load command for (const auto &LC_THREAD_data : LC_THREAD_datas) @@ -5369,7 +5456,10 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, buffer.PutHex32(mach_header.ncmds); buffer.PutHex32(mach_header.sizeofcmds); buffer.PutHex32(mach_header.flags); - buffer.PutHex32(mach_header.reserved); + if (addr_byte_size == 8) + { + buffer.PutHex32(mach_header.reserved); + } // Skip the mach header and all load commands and align to the next // 0x1000 byte boundary @@ -5413,10 +5503,20 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, buffer.PutHex32(segment.cmd); buffer.PutHex32(segment.cmdsize); buffer.PutRawBytes(segment.segname, sizeof(segment.segname)); - buffer.PutHex64(segment.vmaddr); - buffer.PutHex64(segment.vmsize); - buffer.PutHex64(segment.fileoff); - buffer.PutHex64(segment.filesize); + if (addr_byte_size == 8) + { + buffer.PutHex64(segment.vmaddr); + buffer.PutHex64(segment.vmsize); + buffer.PutHex64(segment.fileoff); + buffer.PutHex64(segment.filesize); + } + else + { + buffer.PutHex32(static_cast(segment.vmaddr)); + buffer.PutHex32(static_cast(segment.vmsize)); + buffer.PutHex32(static_cast(segment.fileoff)); + buffer.PutHex32(static_cast(segment.filesize)); + } buffer.PutHex32(segment.maxprot); buffer.PutHex32(segment.initprot); buffer.PutHex32(segment.nsects); @@ -5447,7 +5547,7 @@ ObjectFileMachO::SaveCore (const lldb::ProcessSP &process_sp, break; } - printf ("Saving data for segment at 0x%" PRIx64 "\n", segment.vmaddr); + printf ("Saving %" PRId64 " bytes of data for memory region at 0x%" PRIx64 "\n", segment.vmsize, segment.vmaddr); addr_t bytes_left = segment.vmsize; addr_t addr = segment.vmaddr; Error memory_read_error;