[Lldb-commits] [lldb] r167365 - in /lldb/trunk: include/lldb/Core/ArchSpec.h source/Core/ArchSpec.cpp source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp

Jason Molenda jmolenda at apple.com
Sat Nov 3 20:20:06 PDT 2012


Author: jmolenda
Date: Sat Nov  3 22:20:05 2012
New Revision: 167365

URL: http://llvm.org/viewvc/llvm-project?rev=167365&view=rev
Log:
Add new ArchSpec methods, IsCompatibleMatch() and IsExactMatch().  
The operator== method is a synonym for IsExactMatch().  

The essential difference between these two is that IsCompatibleMatch()
will say that armv7 and armv7s are compatible and return true.
IsExactMatch() will say that armv7 and armv7s are not a match.

An armv7s cpu can run either generic armv7 binaries or armv7s binaries
(the latter being tuned for it).  When we're picking the slice of a 
universal Mach-O file to load in an armv7s Target, we need to be able to
first look for an exact cpu subtype match (armv7s == armv7s) and failing
that, looking for a slice with a compatible architecture.

Update ObjectContainerUniversalMachO::GetObjectFile to prefer an exact
match of the cpu type, falling back to a compatible match if necessary.

<rdar://problem/12593515>



Modified:
    lldb/trunk/include/lldb/Core/ArchSpec.h
    lldb/trunk/source/Core/ArchSpec.cpp
    lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp

Modified: lldb/trunk/include/lldb/Core/ArchSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ArchSpec.h?rev=167365&r1=167364&r2=167365&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ArchSpec.h (original)
+++ lldb/trunk/include/lldb/Core/ArchSpec.h Sat Nov  3 22:20:05 2012
@@ -367,7 +367,30 @@
     lldb::ByteOrder
     GetDefaultEndian () const;
 
+    //------------------------------------------------------------------
+    /// Compare an ArchSpec to another ArchSpec, requiring an exact cpu 
+    /// type match between them.  
+    /// e.g. armv7s is not an exact match with armv7 - this would return false
+    ///
+    /// @return true if the two ArchSpecs match.
+    //------------------------------------------------------------------
+    bool
+    IsExactMatch (const ArchSpec& rhs) const;
+
+    //------------------------------------------------------------------
+    /// Compare an ArchSpec to another ArchSpec, requiring a compatible
+    /// cpu type match between them.  
+    /// e.g. armv7s is compatible with armv7 - this method would return true
+    ///
+    /// @return true if the two ArchSpecs are compatible
+    //------------------------------------------------------------------
+    bool
+    IsCompatibleMatch (const ArchSpec& rhs) const;
+
 protected:
+    bool
+    Compare (const ArchSpec& rhs, bool exact_match) const;
+
     llvm::Triple m_triple;
     Core m_core;
     lldb::ByteOrder m_byte_order;
@@ -388,6 +411,8 @@
 /// @param[in] lhs The Left Hand Side ArchSpec object to compare.
 /// @param[in] rhs The Left Hand Side ArchSpec object to compare.
 ///
+/// Uses the IsExactMatch() method for comparing the cpu types.
+///
 /// @return true if \a lhs is equal to \a rhs
 //------------------------------------------------------------------
 bool operator==(const ArchSpec& lhs, const ArchSpec& rhs);

Modified: lldb/trunk/source/Core/ArchSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ArchSpec.cpp?rev=167365&r1=167364&r2=167365&view=diff
==============================================================================
--- lldb/trunk/source/Core/ArchSpec.cpp (original)
+++ lldb/trunk/source/Core/ArchSpec.cpp Sat Nov  3 22:20:05 2012
@@ -27,6 +27,9 @@
 
 #define ARCH_SPEC_SEPARATOR_CHAR '-'
 
+
+static bool cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match);
+
 namespace lldb_private {
 
     struct CoreDefinition
@@ -711,6 +714,82 @@
     return 0;
 }
 
+bool
+ArchSpec::IsExactMatch (const ArchSpec& rhs) const
+{
+    return Compare (rhs, true);
+}
+
+bool
+ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const
+{
+    return Compare (rhs, false);
+}
+
+bool
+ArchSpec::Compare (const ArchSpec& rhs, bool exact_match) const
+{
+    if (GetByteOrder() != rhs.GetByteOrder())
+        return false;
+        
+    const ArchSpec::Core lhs_core = GetCore ();
+    const ArchSpec::Core rhs_core = rhs.GetCore ();
+
+    const bool core_match = cores_match (lhs_core, rhs_core, true, exact_match);
+
+    if (core_match)
+    {
+        const llvm::Triple &lhs_triple = GetTriple();
+        const llvm::Triple &rhs_triple = rhs.GetTriple();
+
+        const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
+        const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
+        if (lhs_triple_vendor != rhs_triple_vendor)
+        {
+            const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
+            const bool lhs_vendor_specified = TripleVendorWasSpecified();
+            // Both architectures had the vendor specified, so if they aren't
+            // equal then we return false
+            if (rhs_vendor_specified && lhs_vendor_specified)
+                return false;
+            
+            // Only fail if both vendor types are not unknown
+            if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
+                rhs_triple_vendor != llvm::Triple::UnknownVendor)
+                return false;
+        }
+        
+        const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
+        const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
+        if (lhs_triple_os != rhs_triple_os)
+        {
+            const bool rhs_os_specified = rhs.TripleOSWasSpecified();
+            const bool lhs_os_specified = TripleOSWasSpecified();
+            // Both architectures had the OS specified, so if they aren't
+            // equal then we return false
+            if (rhs_os_specified && lhs_os_specified)
+                return false;
+            // Only fail if both os types are not unknown
+            if (lhs_triple_os != llvm::Triple::UnknownOS &&
+                rhs_triple_os != llvm::Triple::UnknownOS)
+                return false;
+        }
+
+        const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
+        const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
+            
+        if (lhs_triple_env != rhs_triple_env)
+        {
+            // Only fail if both environment types are not unknown
+            if (lhs_triple_env != llvm::Triple::UnknownEnvironment &&
+                rhs_triple_env != llvm::Triple::UnknownEnvironment)
+                return false;
+        }
+        return true;
+    }
+    return false;
+}
+
 //===----------------------------------------------------------------------===//
 // Helper methods.
 
@@ -736,119 +815,13 @@
 // Operators.
 
 static bool
-cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse)
+cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match)
 {
+    if (core1 == core2)
+        return true;
+
     switch (core1)
     {
-//    case ArchSpec::eCore_arm_armv4:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumb)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv4t:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv4t)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv5:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv5)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv5t:
-//    case ArchSpec::eCore_arm_armv5e:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv5e)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv6:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv6)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv7:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv7)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv7f:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv7f)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv7k:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv7k)
-//            return true;
-//        break;
-//        
-//    case ArchSpec::eCore_arm_armv7s:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_thumbv7s)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumb:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv4)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv4t:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv4t)
-//            return true;
-//        break;
-//    
-//    case ArchSpec::eCore_thumbv5:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv5)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv5e:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv5t || core2 == ArchSpec::eCore_arm_armv5e)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv6:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv6)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv7:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv7)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv7f:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv7f)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv7k:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv7k)
-//            return true;
-//        break;
-//
-//    case ArchSpec::eCore_thumbv7s:
-//        try_inverse = false;
-//        if (core2 == ArchSpec::eCore_arm_armv7s)
-//            return true;
-//        break;
-    
     case ArchSpec::kCore_any:
         return true;
 
@@ -876,87 +849,29 @@
             return true;
         break;
 
-    case ArchSpec::eCore_arm_armv7:
     case ArchSpec::eCore_arm_armv7f:
     case ArchSpec::eCore_arm_armv7k:
     case ArchSpec::eCore_arm_armv7s:
-        try_inverse = false;
-        if (core2 == ArchSpec::eCore_arm_armv7)
-            return true;
+        if (!enforce_exact_match)
+        {
+            try_inverse = false;
+            if (core2 == ArchSpec::eCore_arm_armv7)
+                return true;
+        }
         break;
 
     default:
         break;
     }
     if (try_inverse)
-        return cores_match (core2, core1, false);
+        return cores_match (core2, core1, false, enforce_exact_match);
     return false;
 }
 
 bool
 lldb_private::operator== (const ArchSpec& lhs, const ArchSpec& rhs)
 {
-    if (lhs.GetByteOrder() != rhs.GetByteOrder())
-        return false;
-        
-    const ArchSpec::Core lhs_core = lhs.GetCore ();
-    const ArchSpec::Core rhs_core = rhs.GetCore ();
-
-    // Check if the cores match, or check a little closer watching for wildcard
-    // and equivalent cores
-    const bool core_match = (lhs_core == rhs_core) || cores_match (lhs_core, rhs_core, true);
-
-    if (core_match)
-    {
-        const llvm::Triple &lhs_triple = lhs.GetTriple();
-        const llvm::Triple &rhs_triple = rhs.GetTriple();
-
-        const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
-        const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
-        if (lhs_triple_vendor != rhs_triple_vendor)
-        {
-            const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
-            const bool lhs_vendor_specified = lhs.TripleVendorWasSpecified();
-            // Both architectures had the vendor specified, so if they aren't
-            // equal then we return false
-            if (rhs_vendor_specified && lhs_vendor_specified)
-                return false;
-            
-            // Only fail if both vendor types are not unknown
-            if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
-                rhs_triple_vendor != llvm::Triple::UnknownVendor)
-                return false;
-        }
-        
-        const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
-        const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
-        if (lhs_triple_os != rhs_triple_os)
-        {
-            const bool rhs_os_specified = rhs.TripleOSWasSpecified();
-            const bool lhs_os_specified = lhs.TripleOSWasSpecified();
-            // Both architectures had the OS specified, so if they aren't
-            // equal then we return false
-            if (rhs_os_specified && lhs_os_specified)
-                return false;
-            // Only fail if both os types are not unknown
-            if (lhs_triple_os != llvm::Triple::UnknownOS &&
-                rhs_triple_os != llvm::Triple::UnknownOS)
-                return false;
-        }
-
-        const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
-        const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
-            
-        if (lhs_triple_env != rhs_triple_env)
-        {
-            // Only fail if both environment types are not unknown
-            if (lhs_triple_env != llvm::Triple::UnknownEnvironment &&
-                rhs_triple_env != llvm::Triple::UnknownEnvironment)
-                return false;
-        }
-        return true;
-    }
-    return false;
+    return lhs.IsExactMatch (rhs);
 }
 
 bool

Modified: lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp?rev=167365&r1=167364&r2=167365&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp Sat Nov  3 22:20:05 2012
@@ -203,11 +203,12 @@
             arch = module_sp->GetArchitecture();
             
         ArchSpec curr_arch;
+        // First, try to find an exact match for the Arch of the Target.
         for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
         {
             if (GetArchitectureAtIndex (arch_idx, curr_arch))
             {
-                if (arch == curr_arch)
+                if (arch.IsExactMatch(curr_arch))
                 {
                     return ObjectFile::FindPlugin (module_sp, 
                                                    file, 
@@ -217,6 +218,23 @@
                 }
             }
         }
+
+        // Failing an exact match, try to find a compatible Arch of the Target.
+        for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
+        {
+            if (GetArchitectureAtIndex (arch_idx, curr_arch))
+            {
+                if (arch.IsCompatibleMatch(curr_arch))
+                {
+                    return ObjectFile::FindPlugin (module_sp, 
+                                                   file, 
+                                                   m_offset + m_fat_archs[arch_idx].offset, 
+                                                   m_fat_archs[arch_idx].size,
+                                                   m_data.GetSharedDataBuffer());
+                }
+            }
+        }
+
     }
     return ObjectFileSP();
 }





More information about the lldb-commits mailing list