From d6f5f96dd73a9fc1307a46119d767ff3261f0f9c Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 29 Mar 2006 02:30:46 +0000 Subject: [PATCH] dyld-44.4.tar.gz --- dyld.xcodeproj/project.pbxproj | 18 ++--- src/ImageLoaderMachO.cpp | 56 +++++++++++++-- src/ImageLoaderMachO.h | 3 +- src/dyld.cpp | 27 +++++-- src/glue.c | 22 ++++++ src/stub_binding_helper.s | 66 ++++++++++++----- .../lazy-binding-reg-params/Makefile | 18 ++++- .../test-cases/lazy-binding-reg-params/foo.c | 71 ++++++++++++++++++- .../test-cases/lazy-binding-reg-params/foo.h | 22 ++++++ .../test-cases/lazy-binding-reg-params/main.c | 61 ++++++++++++++-- 10 files changed, 314 insertions(+), 50 deletions(-) create mode 100644 unit-tests/test-cases/lazy-binding-reg-params/foo.h diff --git a/dyld.xcodeproj/project.pbxproj b/dyld.xcodeproj/project.pbxproj index 23de088..b5733e7 100644 --- a/dyld.xcodeproj/project.pbxproj +++ b/dyld.xcodeproj/project.pbxproj @@ -594,9 +594,9 @@ LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; - OTHER_LDFLAGS_i386 = "/usr/lib/gcc/i686-apple-darwin8/4.0.0/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; - OTHER_LDFLAGS_ppc = "/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; - OTHER_LDFLAGS_ppc64 = "/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/ppc64/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld64.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_i386 = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_ppc = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_ppc64 = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld64.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; OTHER_REZFLAGS = ""; PER_ARCH_CFLAGS_ppc = ""; PER_ARCH_CFLAGS_ppc64 = "-msoft-float"; @@ -632,9 +632,9 @@ LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; - OTHER_LDFLAGS_i386 = "/usr/lib/gcc/i686-apple-darwin8/4.0.0/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; - OTHER_LDFLAGS_ppc = "/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; - OTHER_LDFLAGS_ppc64 = "/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/ppc64/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld64.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_i386 = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_ppc = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_ppc64 = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld64.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; OTHER_REZFLAGS = ""; PER_ARCH_CFLAGS_ppc = ""; PER_ARCH_CFLAGS_ppc64 = "-msoft-float"; @@ -669,9 +669,9 @@ LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.4; OTHER_CFLAGS = ""; - OTHER_LDFLAGS_i386 = "/usr/lib/gcc/i686-apple-darwin8/4.0.0/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; - OTHER_LDFLAGS_ppc = "/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; - OTHER_LDFLAGS_ppc64 = "/usr/lib/gcc/powerpc-apple-darwin8/4.0.0/ppc64/libstdc++.a -seg1addr 8fe00000 -exported_symbols_list src/dyld64.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_i386 = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_ppc = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; + OTHER_LDFLAGS_ppc64 = "-lstdc++-static -seg1addr 8fe00000 -exported_symbols_list src/dyld64.exp -nostdlib /usr/local/lib/system/libc.a -lgcc_eh -lgcc -Wl,-e,__dyld_start -Wl,-dylinker -Wl,-dylinker_install_name,/usr/lib/dyld"; OTHER_REZFLAGS = ""; PER_ARCH_CFLAGS_ppc = ""; PER_ARCH_CFLAGS_ppc64 = "-msoft-float"; diff --git a/src/ImageLoaderMachO.cpp b/src/ImageLoaderMachO.cpp index 90ffe01..3328e89 100644 --- a/src/ImageLoaderMachO.cpp +++ b/src/ImageLoaderMachO.cpp @@ -1769,6 +1769,34 @@ uintptr_t ImageLoaderMachO::resolveUndefined(const LinkContext& context, const s } } +// returns if 'addr' is within the address range of section 'sectionIndex' +// fSlide is not used. 'addr' is assumed to be a prebound address in this image +bool ImageLoaderMachO::isAddrInSection(uintptr_t addr, uint8_t sectionIndex) +{ + uint8_t currentSectionIndex = 1; + const uint32_t cmd_count = ((macho_header*)fMachOData)->ncmds; + const struct load_command* const cmds = (struct load_command*)&fMachOData[sizeof(macho_header)]; + const struct load_command* cmd = cmds; + for (unsigned long i = 0; i < cmd_count; ++i) { + if ( cmd->cmd == LC_SEGMENT_COMMAND ) { + const struct macho_segment_command* seg = (struct macho_segment_command*)cmd; + if ( (currentSectionIndex <= sectionIndex) && (sectionIndex < currentSectionIndex+seg->nsects) ) { + // 'sectionIndex' is in this segment, get section info + const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command)); + const struct macho_section* const section = §ionsStart[sectionIndex-currentSectionIndex]; + return ( (section->addr <= addr) && (addr < section->addr+section->size) ); + } + else { + // 'sectionIndex' not in this segment, skip to next segment + currentSectionIndex += seg->nsects; + } + } + cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize); + } + + return false; +} + void ImageLoaderMachO::doBindExternalRelocations(const LinkContext& context, bool onlyCoalescedSymbols) { const uintptr_t relocBase = this->getRelocBase(); @@ -1805,10 +1833,24 @@ void ImageLoaderMachO::doBindExternalRelocations(const LinkContext& context, boo #endif if ( prebound ) { // we are doing relocations, so prebinding was not usable - // in a prebound executable, the n_value field is set to the address where the symbol was found when prebound + // in a prebound executable, the n_value field of an undefined symbol is set to the address where the symbol was found when prebound // so, subtracting that gives the initial displacement which we need to add to the newly found symbol address - // if mach-o relocation structs had an "addend" field this would not be necessary. - value -= undefinedSymbol->n_value; + // if mach-o relocation structs had an "addend" field this complication would not be necessary. + if ( ((undefinedSymbol->n_type & N_TYPE) == N_SECT) && ((undefinedSymbol->n_desc & N_WEAK_DEF) != 0) ) { + // weak symbols need special casing, since *location may have been prebound to a definition in another image. + // If *location is currently prebound to somewhere in the same section as the weak definition, we assume + // that we can subtract off the weak symbol address to get the addend. + // If prebound elsewhere, we've lost the addend and have to assume it is zero. + // The prebinding to elsewhere only happens with 10.4+ update_prebinding which only operates on a small set of Apple dylibs + if ( (value == undefinedSymbol->n_value) || this->isAddrInSection(value, undefinedSymbol->n_sect) ) + value -= undefinedSymbol->n_value; + else + value = 0; + } + else { + // is undefined or non-weak symbol, so do subtraction to get addend + value -= undefinedSymbol->n_value; + } } // if undefinedSymbol is same as last time, then symbolAddr and image will resolve to the same too if ( undefinedSymbol != lastUndefinedSymbol ) { @@ -1837,10 +1879,14 @@ void ImageLoaderMachO::doBindExternalRelocations(const LinkContext& context, boo *location = value - ((uintptr_t)location + 4); } else { - *location = value; + // don't dirty page if prebound value was correct + if ( !prebound || (*location != value) ) + *location = value; } #else - *location = value; + // don't dirty page if prebound value was correct + if ( !prebound || (*location != value) ) + *location = value; #endif } break; diff --git a/src/ImageLoaderMachO.h b/src/ImageLoaderMachO.h index 8665c96..b540479 100644 --- a/src/ImageLoaderMachO.h +++ b/src/ImageLoaderMachO.h @@ -128,6 +128,7 @@ private: void initMappingTable(uint64_t offsetInFat, _shared_region_mapping_np *mappingTable); #endif bool needsCoalescing() const; + bool isAddrInSection(uintptr_t addr, uint8_t sectionIndex); static bool symbolRequiresCoalescing(const struct macho_nlist* symbol); static uintptr_t bindLazySymbol(const mach_header*, uintptr_t* lazyPointer); @@ -153,7 +154,7 @@ private: const struct twolevel_hints_command* fTwoLevelHints; const struct dylib_command* fDylibID; const char* fReExportThruFramework; - SegmentMachO* fTextSegmentWithFixups; // NULL unless __TEXT segment has fixups + class SegmentMachO* fTextSegmentWithFixups; // NULL unless __TEXT segment has fixups static uint32_t fgHintedBinaryTreeSearchs; static uint32_t fgUnhintedBinaryTreeSearchs; diff --git a/src/dyld.cpp b/src/dyld.cpp index 28b2cf9..2017ba6 100644 --- a/src/dyld.cpp +++ b/src/dyld.cpp @@ -1221,8 +1221,18 @@ static ImageLoader* loadPhase6(int fd, struct stat& stat_buf, const char* path, // try other file formats... - throwf("unknown file type, first eight bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", - firstPage[0], firstPage[1], firstPage[2], firstPage[3], firstPage[4], firstPage[5], firstPage[6],firstPage[7]); + + // throw error about what was found + switch (*(uint32_t*)firstPage) { + case MH_MAGIC: + case MH_CIGAM: + case MH_MAGIC_64: + case MH_CIGAM_64: + throw "mach-o, but wrong architecture"; + default: + throwf("unknown file type, first eight bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", + firstPage[0], firstPage[1], firstPage[2], firstPage[3], firstPage[4], firstPage[5], firstPage[6],firstPage[7]); + } } @@ -1608,8 +1618,17 @@ ImageLoader* loadFromMemory(const uint8_t* mem, uint64_t len, const char* module // try other file formats... - throwf("unknown file type, first eight bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", - mem[0], mem[1], mem[2], mem[3], mem[4], mem[5], mem[6],mem[7]); + // throw error about what was found + switch (*(uint32_t*)mem) { + case MH_MAGIC: + case MH_CIGAM: + case MH_MAGIC_64: + case MH_CIGAM_64: + throw "mach-o, but wrong architecture"; + default: + throwf("unknown file type, first eight bytes: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X", + mem[0], mem[1], mem[2], mem[3], mem[4], mem[5], mem[6],mem[7]); + } } diff --git a/src/glue.c b/src/glue.c index 813bca9..f627e56 100644 --- a/src/glue.c +++ b/src/glue.c @@ -127,6 +127,28 @@ struct tm* localtime(const time_t* t) return (struct tm*)NULL; } +/* + * On ppc64, the C++ runtime references strftime & wcsftime, but they + * never actually get called, and they try to use all the localtime() + * machinery, so stub them out. + */ + +size_t strftime(char * __restrict p1, size_t p2, const char * __restrict p3, + const struct tm * __restrict p4) +{ + return 0; +} +size_t wcsftime(wchar_t * __restrict p1, size_t p2, + const wchar_t * __restrict p3, + const struct tm * __restrict p4) +{ + return 0; +} + +int __strtopdd (const char* p1, char** p2, double* p3) +{ + return 0; +} char* __ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, char **rve) { diff --git a/src/stub_binding_helper.s b/src/stub_binding_helper.s index 4b315eb..af9c2d5 100644 --- a/src/stub_binding_helper.s +++ b/src/stub_binding_helper.s @@ -33,35 +33,63 @@ * sp+4 address of lazy pointer * sp+0 address of mach header * - * Some inter-image function calls pass parameters in registers EAX, ECX, or EDX. + * Some inter-image function calls pass parameters in registers EAX, ECX, EDX, or XXM0-3, * Therefore those registers need to be preserved during the lazy binding. * * After the symbol has been resolved and the pointer filled in this is to pop * these arguments off the stack and jump to the address of the defined symbol. */ - .text - .align 4,0x90 - .globl _stub_binding_helper_interface +#define MH_PARAM_BP 4 +#define LP_PARAM_BP 8 +#define RESULT_BP 8 /* in order to trash no registers, the target is stored back on the stack then ret it done to it */ + +#define MH_PARAM_OUT 0 +#define LP_PARAM_OUT 4 +#define EAX_SAVE 8 +#define ECX_SAVE 12 +#define EDX_SAVE 16 +#define XMMM0_SAVE 32 /* 16-byte align */ +#define XMMM1_SAVE 48 +#define XMMM2_SAVE 64 +#define XMMM3_SAVE 80 +#define STACK_SIZE 96 /* (XMMM3_SAVE+16) must be 16 byte aligned too */ + + + .text + .align 4,0x90 + .globl _stub_binding_helper_interface _stub_binding_helper_interface: - pushl %eax # save registers that might be trashed by dyld::bindLazySymbol() - pushl %ecx - pushl %edx - subl $8,%esp # reserve space for parameters to dyld::bindLazySymbol() - movl 20(%esp), %eax - movl %eax, 0(%esp) # copy mach header parameter - movl 24(%esp), %eax - movl %eax, 4(%esp) # copy lazy pointer parameter - call __ZN4dyld14bindLazySymbolEPK11mach_headerPm - addl $8,%esp # clean up stack after function call - movl %eax,16(%esp) # store target into stack so ret at end will jump there - popl %edx # restore registers - popl %ecx - popl %eax - addl $4,%esp # remove meta-parameter, other meta-parmaeter now holds target for ret + pushl %ebp + movl %esp,%ebp + subl $STACK_SIZE,%esp # at this point stack is 16-byte aligned because two meta-parameters where pushed + movl %eax,EAX_SAVE(%esp) # save registers that might be used as parameters + movl %ecx,ECX_SAVE(%esp) + movl %edx,EDX_SAVE(%esp) + movdqu %xmm0,XMMM0_SAVE(%esp) + movdqu %xmm1,XMMM1_SAVE(%esp) + movdqu %xmm2,XMMM2_SAVE(%esp) + movdqu %xmm3,XMMM3_SAVE(%esp) + movl MH_PARAM_BP(%ebp),%eax # call dyld::bindLazySymbol(mh, lazy_ptr) + movl %eax,MH_PARAM_OUT(%esp) + movl LP_PARAM_BP(%ebp),%eax + movl %eax,LP_PARAM_OUT(%esp) + call __ZN4dyld14bindLazySymbolEPK11mach_headerPm + movl %eax,RESULT_BP(%ebp) # store target for ret + movdqu XMMM0_SAVE(%esp),%xmm0 # restore registers + movdqu XMMM1_SAVE(%esp),%xmm1 + movdqu XMMM2_SAVE(%esp),%xmm2 + movdqu XMMM3_SAVE(%esp),%xmm3 + movl EAX_SAVE(%esp),%eax + movl ECX_SAVE(%esp),%ecx + movl EDX_SAVE(%esp),%edx + addl $STACK_SIZE,%esp + popl %ebp + addl $4,%esp # remove meta-parameter, other meta-parmaeter now holds target for ret ret #endif /* __i386__ */ + #if __ppc__ || __ppc64__ #include /* diff --git a/unit-tests/test-cases/lazy-binding-reg-params/Makefile b/unit-tests/test-cases/lazy-binding-reg-params/Makefile index 9a7f756..12eb337 100644 --- a/unit-tests/test-cases/lazy-binding-reg-params/Makefile +++ b/unit-tests/test-cases/lazy-binding-reg-params/Makefile @@ -23,17 +23,31 @@ TESTROOT = ../.. include ${TESTROOT}/include/common.makefile +ifeq "-arch ppc" "$(ARCH)" + EXTRA_FLAG = -maltivec -force_cpusubtype_ALL +else + ifeq "-arch ppc64" "$(ARCH)" + EXTRA_FLAG = -maltivec + else + ifeq "-arch i386" "$(ARCH)" + EXTRA_FLAG = "" + endif + endif +endif + + + run: all ./main all: main main : main.c libfoo.dylib - ${CC} ${CCFLAGS} -I${TESTROOT}/include -o main main.c libfoo.dylib + ${CC} ${CCFLAGS} -I${TESTROOT}/include -o main main.c libfoo.dylib ${EXTRA_FLAG} libfoo.dylib : foo.c - ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib + ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib ${EXTRA_FLAG} clean: diff --git a/unit-tests/test-cases/lazy-binding-reg-params/foo.c b/unit-tests/test-cases/lazy-binding-reg-params/foo.c index c136321..7270f66 100644 --- a/unit-tests/test-cases/lazy-binding-reg-params/foo.c +++ b/unit-tests/test-cases/lazy-binding-reg-params/foo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer p1, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,12 +20,14 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include // fprintf(), NULL +#include +#include "foo.h" + #if __i386__ __attribute__((regparm(3))) #endif -bool inttest(int p1, int p2, int p3, int p4, int p5) +bool dointtest(int p1, int p2, int p3, int p4, int p5) { if ( p1 != 123) return false; @@ -40,4 +42,67 @@ bool inttest(int p1, int p2, int p3, int p4, int p5) return true; } +#if __ppc__ || __ppc64__ +bool dofloattest(double p1, double p2, double p3, double p4, double p5, double p6, double p7, + double p8, double p9, double p10, double p11, double p12, double p13) +{ + if ( p1 != 1.0 ) + return false; + if ( p2 != 2.0 ) + return false; + if ( p3 != 3.0 ) + return false; + if ( p4 != 4.0 ) + return false; + if ( p5 != 5.0 ) + return false; + if ( p6 != 6.0 ) + return false; + if ( p7 != 7.0 ) + return false; + if ( p8 != 8.0 ) + return false; + if ( p9 != 9.0 ) + return false; + if ( p10 != 10.0) + return false; + if ( p11 != 11.0) + return false; + if ( p12 != 12.0) + return false; + if ( p13 != 13.0) + return false; + return true; +} +#endif + + +static bool comparevFloat(vFloat p1, vFloat p2) +{ + return (memcmp(&p1, &p2, 16) == 0); +} + +bool dovectortest(vFloat p1, vFloat p2, vFloat p3, vFloat p4, vFloat p5) +{ + vFloat r1 = { 1.1, 1.2, 1.3, 1.4 }; + vFloat r2 = { 2.1, 2.2, 2.3, 2.4 }; + vFloat r3 = { 3.1, 3.2, 3.3, 3.4 }; + vFloat r4 = { 4.1, 4.2, 4.3, 4.4 }; + vFloat r5 = { 5.1, 5.2, 5.3, 5.4 }; + + if ( !comparevFloat(p1, r1) ) + return false; + if ( !comparevFloat(p2, r2) ) + return false; + if ( !comparevFloat(p3, r3) ) + return false; + if ( !comparevFloat(p4, r4) ) + return false; + if ( !comparevFloat(p5, r5) ) + return false; + return true; +} + + + diff --git a/unit-tests/test-cases/lazy-binding-reg-params/foo.h b/unit-tests/test-cases/lazy-binding-reg-params/foo.h new file mode 100644 index 0000000..38f6da8 --- /dev/null +++ b/unit-tests/test-cases/lazy-binding-reg-params/foo.h @@ -0,0 +1,22 @@ +#include // fprintf(), NULL + + +extern +#if __i386__ +__attribute__((regparm(3))) +#endif +bool dointtest(int p1, int p2, int p3, int p4, int p5); + +#if __ppc__ || __ppc64__ +extern bool dofloattest(double,double,double,double,double,double,double,double,double,double,double,double,double); +#endif + + +#if __i386__ + typedef float vFloat __attribute__ ((__vector_size__ (16))); +#elif __ppc__ || __ppc64__ + typedef vector float vFloat; +#endif + +extern bool dovectortest(vFloat, vFloat, vFloat, vFloat, vFloat); + diff --git a/unit-tests/test-cases/lazy-binding-reg-params/main.c b/unit-tests/test-cases/lazy-binding-reg-params/main.c index 8d28735..336d2ca 100644 --- a/unit-tests/test-cases/lazy-binding-reg-params/main.c +++ b/unit-tests/test-cases/lazy-binding-reg-params/main.c @@ -24,6 +24,7 @@ #include // fprintf(), NULL #include // exit(), EXIT_SUCCESS #include +#include #include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() @@ -35,20 +36,66 @@ /// -extern -#if __i386__ -__attribute__((regparm(3))) +#include "foo.h" + + +static bool inttest() +{ + return dointtest(123,456,789,4444,55555); +} + +static bool floattest() +{ +#if __ppc__ || __ppc64__ + return dofloattest(1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0); +#elif __i386__ + return true; +#else + #error unknown architecture #endif -bool inttest(int p1, int p2, int p3, int p4, int p5); +} + +static bool vectorSupport() +{ +#if __ppc__ + uint32_t value; + size_t size=sizeof(uint32_t); + int err = sysctlbyname("hw.optional.altivec", &value, &size, NULL, 0); + //fprintf(stderr, "sysctlbyname() = %d\n", err); + return ( err == 0 ); +#else + return true; +#endif +} + + +static bool vectortest() +{ + vFloat p1 = { 1.1, 1.2, 1.3, 1.4 }; + vFloat p2 = { 2.1, 2.2, 2.3, 2.4 }; + vFloat p3 = { 3.1, 3.2, 3.3, 3.4 }; + vFloat p4 = { 4.1, 4.2, 4.3, 4.4 }; + vFloat p5 = { 5.1, 5.2, 5.3, 5.4 }; + return dovectortest(p1, p2, p3, p4, p5); +} int main() { - - if ( ! inttest(123, 456, 789, 4444, 55555) ) { + if ( ! inttest() ) { FAIL("lazy-binding-reg-params int parameters"); return EXIT_SUCCESS; } - + + if ( ! floattest() ) { + FAIL("lazy-binding-reg-params float parameters"); + return EXIT_SUCCESS; + } + + if ( vectorSupport() && ! vectortest() ) { + FAIL("lazy-binding-reg-params vector parameters"); + return EXIT_SUCCESS; + } + PASS("lazy-binding-reg-params"); return EXIT_SUCCESS; } -- 2.45.2