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 )