<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, May 16, 2013 at 1:28 PM, Greg Clayton <span dir="ltr"><<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">> ModuleList::GetShareModule() fails and reports my exe doesn't contain "x86_64". Modifying the code in ArchSpec to return Linux isn't the correct solution, but what is? Something local here where if OS is Unknown we match any OS?<br>


<br>
</div>Almost! There is "unknown unknown" (OS is unknown only because it wasn't specified), and "specified unknown" (we use this to mean "no OS")).<br>
<br>
My patch used this feature:<br>
<br>
               if (!process_info.GetArchitecture().TripleVendorWasSpecified())<br>
<br>
<br>
If you ask the ArchSpec::GetTriple().getOS(), it might return "llvm::Triple::UnknownOS". If the string was actually specified as "unknown", then "ArchSpec::GetTriple().getOSName()" will return a non-empty string containing "unknown".<br>


<br>
Another way to fix this would be to have a "llvm::Triple::NoOS" enumeration. There isn't one currently, so we currently test to see if the OS string is empty to tell if the OS was specified.<br>
<br>
Does that make sense now?</blockquote></div><br></div><div class="gmail_extra">Getting there. :) I want to be really clear, so I'm going to break this up as this issue involves the ObjectFileELF::GetModuleSpecifications() changes - we can assume GetProcessCPUTypeFromExecutable() and friends don't even exist...<br>

<br></div><div class="gmail_extra">Here is the trace of what is happening right now when it fails.<br></div><div class="gmail_extra"><br>calls TargetList::CreateTarget(), line 63<br>  - platform_arch defaults to unknown/unknown/unknown<br>

  calls ObjectFile::GetModuleSpecifications()<br>    - only one arch, so platform_arch is set to it (x86_64/unknownOS/UnknownEnv)<br>    calls TargetList::CreateTarget, line 187<br>      - specified_arch == platform_arch == (x86_64/unknownOS/UnknownEnv)<br>

      calls Platform::ResolveExecutble()<br>        - exe_arch == (x86_64/unknownOS/UnknownEnv) <br>        - module_spec is intialized with exe_arch<br>        if (exe_arch.IsValid()) is true so:<br>          calls ModuleList::GetSharedModule(module_spec, ...)<br>

<br></div><div class="gmail_extra">Given what you've said, I believe I need to add some code somewhere in that call chain which checks for triple vendor not being specified. My guess is it should be something like the below patch?<br>

<br></div><div class="gmail_extra">Notes:<br> - I'm separating this from the Linux/Host.cpp changes. This will only be a patch to implement ObjectFileELF::GetModuleSpecifications().</div><div class="gmail_extra"> - The TripleVendorWasSpecified() checks whether GetVendorName() is empty and the string "unknown" isn't, so I'm explicitly checking for the Unknown enum in the below code.<br>

</div><div class="gmail_extra"></div><div class="gmail_extra"><br></div><div class="gmail_extra">Thanks Greg.<br></div><div class="gmail_extra"> -Mike<br></div><div class="gmail_extra"><br>Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp<br>

===================================================================<br>--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp    (revision 182038)<br>+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp    (working copy)<br>
@@ -222,6 +222,18 @@<br>
     return NULL;<br> }<br> <br>+bool<br>+ObjectFileELF::MagicBytesMatch (DataBufferSP& data_sp,<br>+                                  lldb::addr_t data_offset,<br>+                                  lldb::addr_t data_length)<br>

+{<br>+    if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))<br>+    {<br>+        const uint8_t *magic = data_sp->GetBytes() + data_offset;<br>+        return ELFHeader::MagicBytesMatch(magic);<br>

+    }<br>+    return false;<br>+}<br> <br> size_t<br> ObjectFileELF::GetModuleSpecifications (const lldb_private::FileSpec& file,<br>@@ -231,7 +243,33 @@<br>                                         lldb::offset_t length,<br>

                                         lldb_private::ModuleSpecList &specs)<br> {<br>-    return 0;<br>+    const size_t initial_count = specs.GetSize();<br>+    <br>+    if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))<br>

+    {<br>+        DataExtractor data;<br>+        data.SetData(data_sp);<br>+        elf::ELFHeader header;<br>+        if (header.Parse(data, &data_offset))<br>+        {<br>+            if (data_sp)<br>+            {<br>

+                ModuleSpec spec;<br>+                spec.GetFileSpec() = file;<br>+                spec.GetArchitecture().SetArchitecture(eArchTypeELF,<br>+                                                       header.e_machine,<br>

+                                                       LLDB_INVALID_CPUTYPE);<br>+                if (spec.GetArchitecture().IsValid())<br>+                {<br>+                    // ObjectFileMachO adds the UUID here also, but that isn't in the elf header<br>

+                    // so we'd have to read the entire file in and calculate the md5sum.<br>+                    // That'd be bad for this routine...<br>+                    specs.Append(spec);<br>+                }<br>

+            }<br>+        }<br>+    }<br>+    return specs.GetSize() - initial_count;<br> }<br> <br> //------------------------------------------------------------------<br>Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.h<br>

===================================================================<br>--- source/Plugins/ObjectFile/ELF/ObjectFileELF.h    (revision 182038)<br>+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.h    (working copy)<br>@@ -65,6 +65,12 @@<br>

                              lldb::offset_t file_offset,<br>                              lldb::offset_t length,<br>                              lldb_private::ModuleSpecList &specs);<br>+<br>+    static bool<br>+    MagicBytesMatch (lldb::DataBufferSP& data_sp,<br>

+                     lldb::addr_t offset, <br>+                     lldb::addr_t length);<br>+<br>     //------------------------------------------------------------------<br>     // PluginInterface protocol<br>     //------------------------------------------------------------------<br>

Index: source/Plugins/Platform/Linux/PlatformLinux.cpp<br>===================================================================<br>--- source/Plugins/Platform/Linux/PlatformLinux.cpp    (revision 182038)<br>+++ source/Plugins/Platform/Linux/PlatformLinux.cpp    (working copy)<br>

@@ -208,6 +208,29 @@<br>                                                  NULL, <br>                                                  NULL,<br>                                                  NULL);<br>+            if (error.Fail())<br>

+            {<br>+                // If we failed, it may be because the vendor and os aren't known. If that is the<br>+                // case, try setting them to the host architecture and give it another try.<br>
+                llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); <br>
+                bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor);<br>+                bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS);<br>+                if (!is_vendor_specified || !is_os_specified)<br>

+                {<br>+                    const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple();<br>+<br>+                    if (!is_vendor_specified)<br>+                        module_triple.setVendorName (host_triple.getVendorName());<br>

+                    if (!is_os_specified)<br>+                        module_triple.setOSName (host_triple.getOSName());<br>+<br>+                    error = ModuleList::GetSharedModule (module_spec, <br>+                                                         exe_module_sp, <br>

+                                                         NULL, <br>+                                                         NULL,<br>+                                                         NULL);<br>+                }<br>

+            }<br>         <br>             // TODO find out why exe_module_sp might be NULL            <br>             if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)<br><br></div></div>