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=99538272d5b4ffc852f950dd34...
Author: Alexandre Julliard julliard@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 )