[Lldb-commits] [lldb] r221683 - Add support for 32-bit core file dumping. Add support for i386 process core file dumping.

Jason Molenda jmolenda at apple.com
Tue Nov 11 02:59:15 PST 2014


Author: jmolenda
Date: Tue Nov 11 04:59:15 2014
New Revision: 221683

URL: http://llvm.org/viewvc/llvm-project?rev=221683&view=rev
Log:
Add support for 32-bit core file dumping.  Add support for i386 process core file dumping.

Modified:
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=221683&r1=221682&r2=221683&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Tue Nov 11 04:59:15 2014
@@ -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; i<n; ++ i)
+                        data.PutChar(0);
+                }
+                return reg_byte_size;
+            }
+        }
+        // Just write zeros if all else fails
+        for (size_t i=0; i<reg_byte_size; ++ i)
+            data.PutChar(0);
+        return reg_byte_size;
+    }
+
+    static bool
+    Create_LC_THREAD (Thread *thread, Stream &data)
+    {
+        RegisterContextSP reg_ctx_sp (thread->GetRegisterContext());
+        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::P
             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::P
 //                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::P
 
                         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::P
                             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::P
                                     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::P
                     }
                     
                     // 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::P
                     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::P
                         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<uint32_t>(segment.vmaddr));
+                            buffer.PutHex32(static_cast<uint32_t>(segment.vmsize));
+                            buffer.PutHex32(static_cast<uint32_t>(segment.fileoff));
+                            buffer.PutHex32(static_cast<uint32_t>(segment.filesize));
+                        }
                         buffer.PutHex32(segment.maxprot);
                         buffer.PutHex32(segment.initprot);
                         buffer.PutHex32(segment.nsects);
@@ -5447,7 +5547,7 @@ ObjectFileMachO::SaveCore (const lldb::P
                                     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;





More information about the lldb-commits mailing list