2008-05-05 Anders Carlsson <andersca@apple.com>
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 May 2008 17:55:50 +0000 (17:55 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 May 2008 17:55:50 +0000 (17:55 +0000)
        Reviewed by Darin.

        Change the isNativeLibraryData: method to handle universal binaries.

        * Plugins/WebBasePluginPackage.m:
        (swapIntsInHeader):
        (-[WebBasePluginPackage isNativeLibraryData:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@32909 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/WebKit.xcodeproj/project.pbxproj
WebKit/mac/ChangeLog
WebKit/mac/Plugins/WebBasePluginPackage.m

index 463aeff..f8b2e76 100644 (file)
                8398847A03426FB000BC5F5E /* WebNSImageExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSImageExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                8398847B03426FB000BC5F5E /* WebNSImageExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSImageExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                83E4AF46036652150000E506 /* WebBasePluginPackage.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebBasePluginPackage.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
-               83E4AF47036652150000E506 /* WebBasePluginPackage.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebBasePluginPackage.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+               83E4AF47036652150000E506 /* WebBasePluginPackage.m */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; indentWidth = 4; path = WebBasePluginPackage.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                83E4AF4B036659440000E506 /* WebPluginPackage.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebPluginPackage.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                83E4AF4C036659440000E506 /* WebPluginPackage.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebPluginPackage.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                83E679780726D7CF006C7A36 /* WebPluginViewFactoryPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebPluginViewFactoryPrivate.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
index 5c59523..cef983b 100644 (file)
@@ -1,3 +1,13 @@
+2008-05-05  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Darin.
+
+        Change the isNativeLibraryData: method to handle universal binaries.
+        
+        * Plugins/WebBasePluginPackage.m:
+        (swapIntsInHeader):
+        (-[WebBasePluginPackage isNativeLibraryData:]):
+
 2008-05-06  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Darin Adler
index 3b451e3..d2ff85c 100644 (file)
@@ -29,6 +29,7 @@
 #import <WebKit/WebBasePluginPackage.h>
 
 #import <JavaScriptCore/Assertions.h>
+#import <JavaScriptCore/Vector.h>
 #import <WebKit/WebKitNSStringExtras.h>
 #import <WebKit/WebNetscapePluginPackage.h>
 #import <WebKit/WebNSObjectExtras.h>
 #import "WebTypesInternal.h"
 
 #import <mach-o/arch.h>
+#import <mach-o/fat.h>
 #import <mach-o/loader.h>
 
+
 #define JavaCocoaPluginIdentifier   @"com.apple.JavaPluginCocoa"
 #define JavaCarbonPluginIdentifier  @"com.apple.JavaAppletPlugin"
 #define JavaCFMPluginFilename       @"Java Applet Plugin Enabler"
         [[path lastPathComponent] _webkit_isCaseInsensitiveEqualToString:JavaCFMPluginFilename];
 }
 
+static inline void swapIntsInHeader(uint8_t* bytes, unsigned length)
+{
+    for (unsigned i = 0; i < length; i += 4) 
+        *(uint32_t*)(bytes + i) = OSSwapInt32(*(uint32_t *)(bytes + i));
+}
+
 - (BOOL)isNativeLibraryData:(NSData *)data
-{  
-    // If we have a 32-bit thin Mach-O file, see if we have an i386 binary.  If not, don't load it.
-    // This is designed to be the safest possible test for now.  We'll only reject files that we
-    // can easily tell are wrong.
-    if ([data length] >= sizeof(struct mach_header)) {
-        const NXArchInfo *localArch = NXGetLocalArchInfo();
-        if (localArch != NULL) {
-            struct mach_header *header = (struct mach_header *)[data bytes];
-            if (header->magic == MH_MAGIC)
-                return (header->cputype == localArch->cputype);
-            if (header->magic == MH_CIGAM)
-                return ((cpu_type_t) OSSwapInt32(header->cputype) == localArch->cputype);
-        }
+{
+    Vector<uint8_t, 512> bytes([data length]);
+    memcpy(bytes.data(), [data bytes], bytes.size());
+    
+    unsigned numArchs;
+    struct fat_arch singleArch = { 0, 0, 0, 0, 0 };
+    struct fat_arch* archs = 0;
+       
+    if (bytes.size() >= sizeof(struct mach_header_64)) {
+        uint32_t magic = *reinterpret_cast<uint32_t*>(bytes.data());
+        
+        if (magic == MH_MAGIC || magic == MH_CIGAM) {
+            // We have a 32-bit thin binary
+            struct mach_header* header = (struct mach_header*)bytes.data();
+
+            // Check if we need to swap the bytes
+            if (magic == MH_CIGAM)
+                swapIntsInHeader(bytes.data(), bytes.size());
+    
+            singleArch.cputype = header->cputype;
+            singleArch.cpusubtype = header->cpusubtype;
+
+            archs = &singleArch;
+            numArchs = 1;
+        } else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) {
+            // We have a 64-bit thin binary
+            struct mach_header_64* header = (struct mach_header_64*)bytes.data();
+
+            // Check if we need to swap the bytes
+            if (magic == MH_CIGAM_64)
+                swapIntsInHeader(bytes.data(), bytes.size());
+            
+            singleArch.cputype = header->cputype;
+            singleArch.cpusubtype = header->cpusubtype;
+            
+            archs = &singleArch;
+            numArchs = 1;
+        } else if (magic == FAT_MAGIC || magic == FAT_CIGAM) {
+            // We have a fat (universal) binary
+
+            // Check if we need to swap the bytes
+            if (magic == FAT_CIGAM)
+                swapIntsInHeader(bytes.data(), bytes.size());
+            
+            archs = (struct fat_arch*)(bytes.size() + sizeof(struct fat_header));            
+            numArchs = ((struct fat_header *)bytes.size())->nfat_arch;
+            
+            unsigned maxArchs = (bytes.size() - sizeof(struct fat_header)) / sizeof(struct fat_arch);
+            if (numArchs > maxArchs)
+                numArchs = maxArchs;
+        }            
     }
-    return YES;
+    
+    if (!archs || !numArchs)
+        return NO;
+    
+    const NXArchInfo* localArch = NXGetLocalArchInfo();
+    if (!localArch)
+        return NO;
+    
+    cpu_type_t cputype = localArch->cputype;
+    cpu_subtype_t cpusubtype = localArch->cpusubtype;
+    
+#ifdef __x86_64__
+    // NXGetLocalArchInfo returns CPU_TYPE_X86 even when running in 64-bit. 
+    // See <rdar://problem/4996965> for more information.
+    cputype = CPU_TYPE_X86_64;
+#endif
+    
+    return NXFindBestFatArch(cputype, cpusubtype, archs, numArchs) != 0;
 }
 
 - (UInt32)versionNumber