]> git.saurik.com Git - apple/dyld.git/commitdiff
dyld-44.4.tar.gz mac-os-x-1046ppc v44.4
authorApple <opensource@apple.com>
Wed, 29 Mar 2006 02:30:46 +0000 (02:30 +0000)
committerApple <opensource@apple.com>
Wed, 29 Mar 2006 02:30:46 +0000 (02:30 +0000)
dyld.xcodeproj/project.pbxproj
src/ImageLoaderMachO.cpp
src/ImageLoaderMachO.h
src/dyld.cpp
src/glue.c
src/stub_binding_helper.s
unit-tests/test-cases/lazy-binding-reg-params/Makefile
unit-tests/test-cases/lazy-binding-reg-params/foo.c
unit-tests/test-cases/lazy-binding-reg-params/foo.h [new file with mode: 0644]
unit-tests/test-cases/lazy-binding-reg-params/main.c

index 23de0886366ce2b10d679a2758f3c2e8f7db52cb..b5733e7edae255fd3e4d1dada9840652d8e3cc4f 100644 (file)
                                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";
                                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";
                                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";
index 90ffe01e16b98110aebd05d9674d4551d286e8a1..3328e89e20ccac18842ae54ceece00968f14025e 100644 (file)
@@ -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 = &sectionsStart[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;
index 8665c9676c992c438144f0646f410d85911b454e..b5404795df0db67eb3ef07b5f9d1f513937b5783 100644 (file)
@@ -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;
index 28b2cf9f144064f98ca6f19b5b97308a83b46620..2017ba6318b98ae199de6325c63a19c2f675602b 100644 (file)
@@ -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]);
+       }
 }
 
 
index 813bca90081caada67355b80cb1cc91f08dc42de..f627e568458b83b33cd1c5c4b434940986f9387f 100644 (file)
@@ -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)
 {
index 4b315eb7ee91cb94ca7707579d6e0c81f709a836..af9c2d51b0bd89a675ff04bfa5d581f06cc6644a 100644 (file)
  * 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 <architecture/ppc/mode_independent_asm.h>
 /*
index 9a7f756349e104afaa211b0449d76ceacee68a6a..12eb337ad2d50212a79060282a1fc37c4e775724 100644 (file)
 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:
index c136321262b5adc489f598331f33c9a45325d03e..7270f66c7ed606b705d0b0587192d969972258b8 100644 (file)
@@ -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@
  * 
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
-#include <stdbool.h>  // fprintf(), NULL
+#include <string.h>
+#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 (file)
index 0000000..38f6da8
--- /dev/null
@@ -0,0 +1,22 @@
+#include <stdbool.h>  // 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);
+
index 8d28735f43386c26f49994418140cd25e19936c6..336d2ca676dfad84b7bb8d72c422a800aecd6bc5 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdio.h>  // fprintf(), NULL
 #include <stdlib.h> // exit(), EXIT_SUCCESS
 #include <dlfcn.h>
+#include <sys/sysctl.h>
 
 #include "test.h" // PASS(), FAIL(), XPASS(), XFAIL()
 
 ///
 
                                
-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;
 }