Hi Alexandre,

It seems this would fail to ignore a fat Mach-O library that doesn't include the right 32/64 class. For example, a fat i386/ppc library when running 64-bit.

A fat library starts with the struct fat_header defined in /usr/ include/mach-o/fat.h, followed by a number of struct fat_arch-es. Its magic is 0xcafebabe in big-endian order.

This would also fail to ignore a PowerPC-only library because the magic would be big-endian, but I doubt we care about that.

-Ken

On Aug 11, 2009, at 10:47 AM, Alexandre Julliard wrote:

Module: wine
Branch: master
Commit: 99538272d5b4ffc852f950dd3447a7072d6316ff
URL:    
http://source.winehq.org/git/wine.git/?a=commit;h=99538272d5b4ffc852f950dd3447a7072d6316ff

Author: Alexandre Julliard <julli...@winehq.org>
Date:   Tue Aug 11 17:29:07 2009 +0200

libwine: Ignore libraries that are of the wrong 32/64 class.

---

libs/wine/loader.c | 46 +++++++++++++++++++++++++++++++++++++++++++ +--
1 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/libs/wine/loader.c b/libs/wine/loader.c
index d10a6e0..37c603e 100644
--- a/libs/wine/loader.c
+++ b/libs/wine/loader.c
@@ -147,12 +147,54 @@ static void build_dll_path(void)
    }
}

+/* check if the library is the correct architecture */
+/* only returns false for a valid library of the wrong arch */
+static int check_library_arch( int fd )
+{
+#ifdef __APPLE__
+    struct  /* Mach-O header */
+    {
+        unsigned int magic;
+        unsigned int cputype;
+    } header;
+
+ if (read( fd, &header, sizeof(header) ) != sizeof(header)) return 1;
+    if (header.magic != 0xfeedface) return 1;
+ if (sizeof(void *) == sizeof(int)) return !(header.cputype >> 24);
+    else return (header.cputype >> 24) == 1; /* CPU_ARCH_ABI64 */
+#else
+    struct  /* ELF header */
+    {
+        unsigned char magic[4];
+        unsigned char class;
+        unsigned char data;
+        unsigned char version;
+    } header;
+
+ if (read( fd, &header, sizeof(header) ) != sizeof(header)) return 1;
+    if (memcmp( header.magic, "\177ELF", 4 )) return 1;
+    if (header.version != 1 /* EV_CURRENT */) return 1;
+#ifdef WORDS_BIGENDIAN
+    if (header.data != 2 /* ELFDATA2MSB */) return 1;
+#else
+    if (header.data != 1 /* ELFDATA2LSB */) return 1;
+#endif
+ if (sizeof(void *) == sizeof(int)) return header.class == 1; /* ELFCLASS32 */
+    else return header.class == 2; /* ELFCLASS64 */
+#endif
+}
+
/* check if a given file can be opened */
static inline int file_exists( const char *name )
{
+    int ret = 0;
    int fd = open( name, O_RDONLY );
-    if (fd != -1) close( fd );
-    return (fd != -1);
+    if (fd != -1)
+    {
+        ret = check_library_arch( fd );
+        close( fd );
+    }
+    return ret;
}

static inline char *prepend( char *buffer, const char *str, size_t len )






Reply via email to