[Lldb-commits] [lldb] r366378 - Add support to ProcessMachCore::DoLoadCore to handle an EFI UUID str.

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Wed Jul 17 14:44:07 PDT 2019


Author: jmolenda
Date: Wed Jul 17 14:44:05 2019
New Revision: 366378

URL: http://llvm.org/viewvc/llvm-project?rev=366378&view=rev
Log:
Add support to ProcessMachCore::DoLoadCore to handle an EFI UUID str.

If a core file has an EFI version string which includes a UUID
(similar to what it returns for the kdp KDP_KERNELVERSION packet)
in the LC_IDENT or LC_NOTE 'kern ver str' load command.  In that
case, we should try to find the binary and dSYM for the UUID
listed.  The dSYM may have python code which knows how to relocate
the binary to the correct address in lldb's target section load
list and loads other ancillary binaries.

The test case is a little involved,

1. it compiles an inferior hello world apple (a.out),
2. it compiles a program which can create a corefile manually
   with a specific binary's UUID encoded in it,
3. it gets the UUID of the a.out binary,
4. it creates a shell script, dsym-for-uuid.sh, which will
   return the full path to the a.out + a.out.dSYM when called
   with teh correct UUID,
5. it sets the LLDB_APPLE_DSYMFORUUID_EXECUTABLE env var before
   creating the lldb target, to point to this dsym-for-uuid.sh,
6. runs the create-corefile binary we compiled in step #2,
7. loads the corefile from step #6 into lldb,
8. verifies that lldb loaded a.out by reading the LC_NOTE
   load command from the corefile, calling dsym-for-uuid.sh with
   that UUID, got back the path to a.out and loaded it.

whew!

<rdar://problem/47562911>


Added:
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.mk
    lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c
Modified:
    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp

Added: lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile?rev=366378&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/Makefile Wed Jul 17 14:44:05 2019
@@ -0,0 +1,15 @@
+LEVEL = ../../../make
+
+MAKE_DSYM := NO
+
+C_SOURCES := main.c
+
+all: a.out create-empty-corefile
+
+create-empty-corefile:
+	$(MAKE) VPATH=$(VPATH) -f $(SRCDIR)/create-empty-corefile.mk
+
+clean::
+	$(MAKE) -f create-empty-corefile.mk clean
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py?rev=366378&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/TestKernVerStrLCNOTE.py Wed Jul 17 14:44:05 2019
@@ -0,0 +1,102 @@
+"""Test that corefiles with an LC_NOTE "kern ver str" load command is used."""
+
+from __future__ import print_function
+
+
+import os
+import re
+import subprocess
+import sys
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestKernVerStrLCNOTE(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
+    @skipIfDarwinEmbedded
+    @skipUnlessDarwin
+    def test_lc_note(self):
+        self.build()
+        self.test_exe = self.getBuildArtifact("a.out")
+        self.create_corefile = self.getBuildArtifact("create-empty-corefile")
+        self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
+        self.corefile = self.getBuildArtifact("core")
+
+        ## We can hook in our dsym-for-uuid shell script to lldb with this env
+        ## var instead of requiring a defaults write.
+        os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = self.dsym_for_uuid
+        self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None))
+
+        dwarfdump_uuid_regex = re.compile(
+            'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
+        dwarfdump_cmd_output = subprocess.check_output(
+                ('/usr/bin/dwarfdump --uuid "%s"' % self.test_exe), shell=True).decode("utf-8")
+        aout_uuid = None
+        for line in dwarfdump_cmd_output.splitlines():
+            match = dwarfdump_uuid_regex.search(line)
+            if match:
+                aout_uuid = match.group(1)
+        self.assertNotEqual(aout_uuid, None, "Could not get uuid of built a.out")
+
+        ###  Create our dsym-for-uuid shell script which returns self.test_exe
+        ###  and its dSYM when given self.test_exe's UUID.
+        shell_cmds = [
+                '#! /bin/sh',
+                'ret=0',
+                'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"',
+                'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"',
+                'date >> /tmp/log',
+                'echo "<plist version=\\"1.0\\">"',
+                '',
+                '# the last arugment is probably the uuid',
+                'while [ $# -gt 1 ]',
+                'do',
+                '  shift',
+                'done',
+                'echo "<dict><key>$1</key><dict>"',
+                '',
+                'if [ "$1" = "%s" ]' % aout_uuid,
+                'then',
+                '  echo "<key>DBGArchitecture</key><string>x86_64</string>"',
+                '  echo "<key>DBGDSYMPath</key><string>%s.dSYM/Contents/Resources/DWARF/%s</string>"' % (self.test_exe, os.path.basename(self.test_exe)),
+                '  echo "<key>DBGSymbolRichExecutable</key><string>%s</string>"' % self.test_exe,
+                'else',
+                '  echo "<key>DBGError</key><string>not found</string>"',
+                '  ret=1',
+                'fi',
+                'echo "</dict></dict></plist>"',
+                'exit $ret'
+                ]
+
+        with open(self.dsym_for_uuid, "w") as writer:
+            for l in shell_cmds:
+                writer.write(l + '\n')
+
+        os.chmod(self.dsym_for_uuid, 0o755)
+
+        ### Create our corefile
+        retcode = call(self.create_corefile + " " +  self.corefile + " " + self.test_exe, shell=True)
+
+        ### Now run lldb on the corefile
+        ### which will give us a UUID
+        ### which we call dsym-for-uuid.sh with
+        ### which gives us a binary and dSYM
+        ### which lldb should load!
+
+
+        self.target = self.dbg.CreateTarget('')
+        err = lldb.SBError()
+        self.process = self.target.LoadCore(self.corefile)
+        self.assertEqual(self.process.IsValid(), True)
+        if self.TraceOn():
+            self.runCmd("image list")
+        self.assertEqual(self.target.GetNumModules(), 1)
+        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
+        filepath = fspec.GetDirectory() + "/" + fspec.GetFilename()
+        self.assertEqual(filepath, self.test_exe)

Added: lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp?rev=366378&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.cpp Wed Jul 17 14:44:05 2019
@@ -0,0 +1,315 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <mach-o/loader.h>
+#include <vector>
+#include <string>
+#include <mach/thread_status.h>
+#include <string.h>
+#include <uuid/uuid.h>
+
+// Create an empty corefile with a "kern ver str" LC_NOTE.
+// If an existing binary is given as an optional 2nd argument on the cmd line,
+// the UUID from that binary will be encoded in the corefile.
+// Otherwise a pre-set UUID will be put in the corefile that
+// is created.
+
+
+union uint32_buf {
+    uint8_t bytebuf[4];
+    uint32_t val;
+};
+
+union uint64_buf {
+    uint8_t bytebuf[8];
+    uint64_t val;
+};
+
+void
+add_uint64(std::vector<uint8_t> &buf, uint64_t val)
+{
+    uint64_buf conv;
+    conv.val = val;
+    for (int i = 0; i < 8; i++)
+        buf.push_back(conv.bytebuf[i]);
+}
+
+void
+add_uint32(std::vector<uint8_t> &buf, uint32_t val)
+{
+    uint32_buf conv;
+    conv.val = val;
+    for (int i = 0; i < 4; i++)
+        buf.push_back(conv.bytebuf[i]);
+}
+
+std::vector<uint8_t>
+x86_lc_thread_load_command ()
+{
+    std::vector<uint8_t> data;
+    add_uint32 (data, LC_THREAD);                // thread_command.cmd
+    add_uint32 (data, 184);                      // thread_command.cmdsize
+    add_uint32 (data, x86_THREAD_STATE64);       // thread_command.flavor
+    add_uint32 (data, x86_THREAD_STATE64_COUNT); // thread_command.count
+    add_uint64 (data, 0x0000000000000000);       // rax
+    add_uint64 (data, 0x0000000000000400);       // rbx
+    add_uint64 (data, 0x0000000000000000);       // rcx
+    add_uint64 (data, 0x0000000000000000);       // rdx
+    add_uint64 (data, 0x0000000000000000);       // rdi
+    add_uint64 (data, 0x0000000000000000);       // rsi
+    add_uint64 (data, 0xffffff9246e2ba20);       // rbp
+    add_uint64 (data, 0xffffff9246e2ba10);       // rsp
+    add_uint64 (data, 0x0000000000000000);       // r8 
+    add_uint64 (data, 0x0000000000000000);       // r9 
+    add_uint64 (data, 0x0000000000000000);       // r10
+    add_uint64 (data, 0x0000000000000000);       // r11
+    add_uint64 (data, 0xffffff7f96ce5fe1);       // r12
+    add_uint64 (data, 0x0000000000000000);       // r13
+    add_uint64 (data, 0x0000000000000000);       // r14
+    add_uint64 (data, 0xffffff9246e2bac0);       // r15
+    add_uint64 (data, 0xffffff8015a8f6d0);       // rip
+    add_uint64 (data, 0x0000000000011111);       // rflags
+    add_uint64 (data, 0x0000000000022222);       // cs
+    add_uint64 (data, 0x0000000000033333);       // fs
+    add_uint64 (data, 0x0000000000044444);       // gs
+    return data;
+}
+
+void
+add_lc_note_kern_ver_str_load_command (std::vector<std::vector<uint8_t> > &loadcmds, 
+                                       std::vector<uint8_t> &payload,
+                                       int payload_file_offset,
+                                       std::string ident)
+{
+    std::vector<uint8_t> loadcmd_data;
+
+    add_uint32 (loadcmd_data, LC_NOTE);          // note_command.cmd
+    add_uint32 (loadcmd_data, 40);               // note_command.cmdsize
+    char lc_note_name[16];
+    memset (lc_note_name, 0, 16);
+    strcpy (lc_note_name, "kern ver str");
+    
+    // lc_note.data_owner
+    for (int i = 0; i < 16; i++)
+        loadcmd_data.push_back (lc_note_name[i]);
+
+    // we start writing the payload at payload_file_offset to leave
+    // room at the start for the header & the load commands.
+    uint64_t current_payload_offset = payload.size() + payload_file_offset;
+
+    add_uint64 (loadcmd_data, current_payload_offset);   // note_command.offset
+    add_uint64 (loadcmd_data, 4 + ident.size() + 1);       // note_command.size
+
+    loadcmds.push_back (loadcmd_data);
+
+    add_uint32 (payload, 1);                 // kerneL_version_string.version
+    for (int i = 0; i < ident.size() + 1; i++)
+    {
+        payload.push_back (ident[i]);
+    }
+}
+
+void
+add_lc_segment (std::vector<std::vector<uint8_t> > &loadcmds,
+                std::vector<uint8_t> &payload,
+                int payload_file_offset)
+{
+    std::vector<uint8_t> loadcmd_data;
+    struct segment_command_64 seg;
+    seg.cmd = LC_SEGMENT_64;
+    seg.cmdsize = sizeof (struct segment_command_64);  // no sections
+    memset (seg.segname, 0, 16);
+    seg.vmaddr = 0xffffff7f96400000;
+    seg.vmsize = 4096;
+    seg.fileoff = payload.size() + payload_file_offset;
+    seg.filesize = 0;
+    seg.maxprot = 1;
+    seg.initprot = 1;
+    seg.nsects = 0;
+    seg.flags = 0;
+
+    uint8_t *p = (uint8_t*) &seg;
+    for (int i = 0; i < sizeof (struct segment_command_64); i++)
+    {
+        loadcmd_data.push_back (*(p + i));
+    }
+    loadcmds.push_back (loadcmd_data);
+}
+
+std::string
+get_uuid_from_binary (const char *fn)
+{
+    FILE *f = fopen(fn, "r");
+    if (f == nullptr)
+    {
+        fprintf (stderr, "Unable to open binary '%s' to get uuid\n", fn);
+        exit(1);
+    }
+		uint32_t num_of_load_cmds = 0;
+		uint32_t size_of_load_cmds = 0;
+		std::string uuid;
+    off_t file_offset = 0;
+
+    uint8_t magic[4];
+    if (::fread (magic, 1, 4, f) != 4)
+    {
+        fprintf (stderr, "Failed to read magic number from input file %s\n", fn);
+        exit (1);
+    }
+    uint8_t magic_32_be[] = {0xfe, 0xed, 0xfa, 0xce};
+    uint8_t magic_32_le[] = {0xce, 0xfa, 0xed, 0xfe};
+    uint8_t magic_64_be[] = {0xfe, 0xed, 0xfa, 0xcf};
+    uint8_t magic_64_le[] = {0xcf, 0xfa, 0xed, 0xfe};
+
+    if (memcmp (magic, magic_32_be, 4) == 0 || memcmp (magic, magic_64_be, 4) == 0)
+    {
+        fprintf (stderr, "big endian corefiles not supported\n");
+        exit (1);
+    }
+
+    ::fseeko (f, 0, SEEK_SET);
+    if (memcmp (magic, magic_32_le, 4) == 0)
+    {
+        struct mach_header mh;
+        if (::fread (&mh, 1, sizeof (mh), f) != sizeof (mh))
+        {
+            fprintf (stderr, "error reading mach header from input file\n");
+            exit (1);
+        }
+        if (mh.cputype != CPU_TYPE_X86_64)
+        {
+            fprintf (stderr, "This tool creates an x86_64 corefile but "
+                     "the supplied binary '%s' is cputype 0x%x\n",
+                     fn, (uint32_t) mh.cputype);
+            exit (1);
+        }
+				num_of_load_cmds = mh.ncmds;
+				size_of_load_cmds = mh.sizeofcmds;
+        file_offset += sizeof (struct mach_header);
+    }
+    else
+    {
+        struct mach_header_64 mh;
+        if (::fread (&mh, 1, sizeof (mh), f) != sizeof (mh))
+        {
+            fprintf (stderr, "error reading mach header from input file\n");
+            exit (1);
+        }
+        if (mh.cputype != CPU_TYPE_X86_64)
+        {
+            fprintf (stderr, "This tool creates an x86_64 corefile but "
+                     "the supplied binary '%s' is cputype 0x%x\n",
+                     fn, (uint32_t) mh.cputype);
+            exit (1);
+        }
+				num_of_load_cmds = mh.ncmds;
+				size_of_load_cmds = mh.sizeofcmds;
+        file_offset += sizeof (struct mach_header_64);
+    }
+
+    off_t load_cmds_offset = file_offset;
+
+    for (int i = 0; i < num_of_load_cmds && (file_offset - load_cmds_offset) < size_of_load_cmds; i++)
+    {
+        ::fseeko (f, file_offset, SEEK_SET);
+        uint32_t cmd;
+        uint32_t cmdsize;
+        ::fread (&cmd, sizeof (uint32_t), 1, f);
+        ::fread (&cmdsize, sizeof (uint32_t), 1, f);
+        if (cmd == LC_UUID)
+        {
+            struct uuid_command uuidcmd;
+            ::fseeko (f, file_offset, SEEK_SET);
+            if (::fread (&uuidcmd, 1, sizeof (uuidcmd), f) != sizeof (uuidcmd))
+            {
+                fprintf (stderr, "Unable to read LC_UUID load command.\n");
+                exit (1);
+            }
+            uuid_string_t uuidstr;
+            uuid_unparse (uuidcmd.uuid, uuidstr);
+            uuid = uuidstr;
+            break;
+        }
+        file_offset += cmdsize;
+    }
+    return uuid;
+}
+
+int main (int argc, char **argv)
+{
+    if (argc != 2 && argc != 3)
+    {
+        fprintf (stderr, "usage: create-empty-corefile <output-core-name> [binary-to-copy-uuid-from]\n");
+        fprintf (stderr, "Create a Mach-O corefile with an LC_NOTE 'kern ver str' load command/payload\n");
+        fprintf (stderr, "If a binary is given as a second argument, the Mach-O UUID of that file will\n");
+        fprintf (stderr, "be read and used in the corefile's LC_NOTE payload.\n");
+        exit (1);
+    }
+
+    std::string ident = "EFI UUID=3F9BA21F-55EA-356A-A349-BBA6F51FE8B1";
+    if (argc == 3)
+    {
+        std::string uuid_from_file = get_uuid_from_binary (argv[2]);
+        if (!uuid_from_file.empty())
+        {
+            ident = "EFI UUID=";
+            ident += uuid_from_file;
+        }
+    }
+
+    // An array of load commands (in the form of byte arrays)
+    std::vector<std::vector<uint8_t> > load_commands;
+
+    // An array of corefile contents (page data, lc_note data, etc)
+    std::vector<uint8_t> payload;
+
+    // First add all the load commands / payload so we can figure out how large
+    // the load commands will actually be.
+    load_commands.push_back (x86_lc_thread_load_command());
+    add_lc_note_kern_ver_str_load_command (load_commands, payload, 0, ident);
+    add_lc_segment (load_commands, payload, 0);
+
+    int size_of_load_commands = 0;
+    for (const auto &lc : load_commands)
+        size_of_load_commands += lc.size();
+
+    int header_and_load_cmd_room = sizeof (struct mach_header_64) + size_of_load_commands;
+
+    // Erease the load commands / payload now that we know how much space is needed,
+    // redo it.
+    load_commands.clear();
+    payload.clear();
+
+    load_commands.push_back (x86_lc_thread_load_command());
+    add_lc_note_kern_ver_str_load_command (load_commands, payload, header_and_load_cmd_room, ident);
+    add_lc_segment (load_commands, payload, header_and_load_cmd_room);
+
+    struct mach_header_64 mh;
+    mh.magic = MH_MAGIC_64;
+    mh.cputype = CPU_TYPE_X86_64;
+    mh.cpusubtype = CPU_SUBTYPE_X86_64_ALL;
+    mh.filetype = MH_CORE;
+    mh.ncmds = load_commands.size();
+    mh.sizeofcmds = size_of_load_commands;
+    mh.flags = 0;
+    mh.reserved = 0;
+
+
+    FILE *f = fopen (argv[1], "w");
+
+    if (f == nullptr)
+    {
+        fprintf (stderr, "Unable to open file %s for writing\n", argv[1]);
+        exit (1);
+    }
+
+    fwrite (&mh, sizeof (struct mach_header_64), 1, f);
+
+    for (const auto &lc : load_commands)
+        fwrite (lc.data(), lc.size(), 1, f);
+
+    fseek (f, header_and_load_cmd_room, SEEK_SET);
+
+    fwrite (payload.data(), payload.size(), 1, f);
+
+    fclose (f);
+}

Added: lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.mk
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.mk?rev=366378&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.mk (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/create-empty-corefile.mk Wed Jul 17 14:44:05 2019
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+
+MAKE_DSYM := NO
+
+CXX_SOURCES := create-empty-corefile.cpp
+EXE = create-empty-corefile
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c?rev=366378&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/macosx/lc-note/kern-ver-str/main.c Wed Jul 17 14:44:05 2019
@@ -0,0 +1,2 @@
+#include <stdio.h>
+int main () { puts ("this is the lc-note test program."); }

Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=366378&r1=366377&r2=366378&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp Wed Jul 17 14:44:05 2019
@@ -19,6 +19,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Target.h"
@@ -323,6 +324,60 @@ Status ProcessMachCore::DoLoadCore() {
             addr, corefile_identifier.c_str());
     }
   }
+  if (found_main_binary_definitively == false 
+      && corefile_identifier.find("EFI ") != std::string::npos) {
+      UUID uuid;
+      if (corefile_identifier.find("UUID=") != std::string::npos) {
+          size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
+          std::string uuid_str = corefile_identifier.substr(p, 36);
+          uuid.SetFromStringRef(uuid_str);
+      }
+      if (uuid.IsValid()) {
+        if (log)
+          log->Printf("ProcessMachCore::DoLoadCore: Using the EFI "
+                      "from LC_IDENT/LC_NOTE 'kern ver str' string: '%s'", 
+                      corefile_identifier.c_str());
+
+          // We're only given a UUID here, not a load address.
+          // But there are python scripts in the EFI binary's dSYM which
+          // know how to relocate the binary to the correct load address.
+          // lldb only needs to locate & load the binary + dSYM.
+          ModuleSpec module_spec;
+          module_spec.GetUUID() = uuid;
+          module_spec.GetArchitecture() = GetTarget().GetArchitecture();
+
+          // Lookup UUID locally, before attempting dsymForUUID like action
+          FileSpecList search_paths =
+              Target::GetDefaultDebugFileSearchPaths();
+          module_spec.GetSymbolFileSpec() =
+              Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
+          if (module_spec.GetSymbolFileSpec()) {
+            ModuleSpec executable_module_spec =
+                Symbols::LocateExecutableObjectFile(module_spec);
+            if (FileSystem::Instance().Exists(executable_module_spec.GetFileSpec())) {
+              module_spec.GetFileSpec() =
+                  executable_module_spec.GetFileSpec();
+            }
+          }
+
+          // Force a a dsymForUUID lookup, if that tool is available.
+          if (!module_spec.GetSymbolFileSpec())
+            Symbols::DownloadObjectAndSymbolFile(module_spec, true);
+
+          if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
+            ModuleSP module_sp(new Module(module_spec));
+            if (module_sp.get() && module_sp->GetObjectFile()) {
+              // Get the current target executable
+              ModuleSP exe_module_sp(GetTarget().GetExecutableModule());
+
+              // Make sure you don't already have the right module loaded
+              // and they will be uniqued
+              if (exe_module_sp.get() != module_sp.get())
+                GetTarget().SetExecutableModule(module_sp, eLoadDependentsNo);
+            }
+          }
+      }
+  }
 
   if (!found_main_binary_definitively &&
       (m_dyld_addr == LLDB_INVALID_ADDRESS ||




More information about the lldb-commits mailing list