From 197008ea33f135c7c4f94a67a2f75a9df7b7771d Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 11 Dec 2008 20:42:16 +0000 Subject: [PATCH] dyld-97.1.tar.gz --- dyld.xcodeproj/project.pbxproj | 5 ++ include/mach-o/dyld-interposing.h | 47 +++++++++++ launch-cache/MachOLayout.hpp | 2 +- launch-cache/update_dyld_shared_cache.cpp | 37 ++++++++- src/ImageLoaderPE.cpp | 24 ++++++ src/ImageLoaderPE.h | 25 ++++++ src/dyld.cpp | 22 +++++ src/dyld.h | 1 + .../dlopen-init-dlopen-notify/bar.c | 1 - .../dlopen-init-dlopen-notify/main.cxx | 82 ------------------- unit-tests/test-cases/dlopen-leak/Makefile | 68 --------------- unit-tests/test-cases/dlopen-leak/bar.c | 3 - unit-tests/test-cases/dlopen-leak/foo.c | 3 - .../test-cases/dlopen-notify-bind/main.c | 68 --------------- .../test-cases/dlopen_preflight-leak/Makefile | 65 --------------- .../test-cases/dlopen_preflight-leak/bar.c | 3 - .../test-cases/dlopen_preflight-leak/foo.c | 3 - .../test-cases/framework-fallback/main.c | 6 +- .../Makefile | 31 +++---- .../test-cases/interpose-basic-prebound/foo.c | 12 +++ .../main.c | 32 +++----- .../interpose-basic-prebound/mystrdup.c | 32 ++++++++ .../Makefile | 42 +++------- unit-tests/test-cases/interpose-basic/main.c | 42 ++++++++++ .../test-cases/interpose-basic/mystrdup.c | 32 ++++++++ .../main.c => interpose-basic/wrap.c} | 26 ++---- .../test-cases/interpose-chained/Makefile | 63 ++++++++++++++ unit-tests/test-cases/interpose-chained/foo.c | 32 ++++++++ .../foo.c => interpose-chained/foo.h} | 11 +-- .../foo1.c | 24 +++--- .../foo2.c | 23 +++--- .../test-cases/interpose-chained/foo3.c | 34 ++++++++ .../test-cases/interpose-chained/main.c | 39 +++++++++ .../test-cases/interpose-dlsym/Makefile | 42 ++++++++++ unit-tests/test-cases/interpose-dlsym/main.c | 50 +++++++++++ .../foo.c => interpose-dlsym/myfree.c} | 12 +-- 36 files changed, 613 insertions(+), 431 deletions(-) create mode 100644 include/mach-o/dyld-interposing.h create mode 100644 src/ImageLoaderPE.cpp create mode 100644 src/ImageLoaderPE.h delete mode 100644 unit-tests/test-cases/dlopen-init-dlopen-notify/bar.c delete mode 100644 unit-tests/test-cases/dlopen-init-dlopen-notify/main.cxx delete mode 100644 unit-tests/test-cases/dlopen-leak/Makefile delete mode 100644 unit-tests/test-cases/dlopen-leak/bar.c delete mode 100644 unit-tests/test-cases/dlopen-leak/foo.c delete mode 100644 unit-tests/test-cases/dlopen-notify-bind/main.c delete mode 100644 unit-tests/test-cases/dlopen_preflight-leak/Makefile delete mode 100644 unit-tests/test-cases/dlopen_preflight-leak/bar.c delete mode 100644 unit-tests/test-cases/dlopen_preflight-leak/foo.c rename unit-tests/test-cases/{dlopen-notify-bind => interpose-basic-prebound}/Makefile (64%) create mode 100644 unit-tests/test-cases/interpose-basic-prebound/foo.c rename unit-tests/test-cases/{dlopen-leak => interpose-basic-prebound}/main.c (68%) create mode 100644 unit-tests/test-cases/interpose-basic-prebound/mystrdup.c rename unit-tests/test-cases/{dlopen-init-dlopen-notify => interpose-basic}/Makefile (50%) create mode 100644 unit-tests/test-cases/interpose-basic/main.c create mode 100644 unit-tests/test-cases/interpose-basic/mystrdup.c rename unit-tests/test-cases/{dlopen_preflight-leak/main.c => interpose-basic/wrap.c} (74%) create mode 100644 unit-tests/test-cases/interpose-chained/Makefile create mode 100644 unit-tests/test-cases/interpose-chained/foo.c rename unit-tests/test-cases/{dlopen-init-dlopen-notify/foo.c => interpose-chained/foo.h} (89%) rename unit-tests/test-cases/{dlopen-init-dlopen-notify => interpose-chained}/foo1.c (75%) rename unit-tests/test-cases/{dlopen-init-dlopen-notify => interpose-chained}/foo2.c (77%) create mode 100644 unit-tests/test-cases/interpose-chained/foo3.c create mode 100644 unit-tests/test-cases/interpose-chained/main.c create mode 100644 unit-tests/test-cases/interpose-dlsym/Makefile create mode 100644 unit-tests/test-cases/interpose-dlsym/main.c rename unit-tests/test-cases/{dlopen-notify-bind/foo.c => interpose-dlsym/myfree.c} (86%) diff --git a/dyld.xcodeproj/project.pbxproj b/dyld.xcodeproj/project.pbxproj index ab2b56e..efbfc38 100644 --- a/dyld.xcodeproj/project.pbxproj +++ b/dyld.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ EF79A016070D295200F78484 /* dyld.3 in CopyFiles */ = {isa = PBXBuildFile; fileRef = EF799FF0070D27BB00F78484 /* dyld.3 */; }; F906E2240639E96400B13DB2 /* dyld_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = F906E2230639E96400B13DB2 /* dyld_debug.c */; }; F913FADA0630A8AE00B7AE9D /* dyldAPIsInLibSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F913FAD90630A8AE00B7AE9D /* dyldAPIsInLibSystem.cpp */; }; + F918691608B16D3500E0F9DB /* dyld-interposing.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F918691408B16D2500E0F9DB /* dyld-interposing.h */; }; F919ECB1090455AB002331E3 /* dyld-update-prebinding.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = F919ECAB09045590002331E3 /* dyld-update-prebinding.h */; }; F93075C30BA1FE4D004BCA09 /* dyld_shared_cache_server.c in Sources */ = {isa = PBXBuildFile; fileRef = F93075C10BA1FE4D004BCA09 /* dyld_shared_cache_server.c */; }; F932C2520BC32ABB0018B20D /* com.apple.dyld.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = F93075D30BA204FF004BCA09 /* com.apple.dyld.plist */; }; @@ -164,6 +165,7 @@ dstPath = "/usr/local/include/mach-o"; dstSubfolderSpec = 0; files = ( + F918691608B16D3500E0F9DB /* dyld-interposing.h in CopyFiles */, F919ECB1090455AB002331E3 /* dyld-update-prebinding.h in CopyFiles */, F93AA9A30630AE1E00301D9F /* dyld_gdb.h in CopyFiles */, F93AA9A40630AE1E00301D9F /* dyld_priv.h in CopyFiles */, @@ -229,6 +231,7 @@ EF799FF0070D27BB00F78484 /* dyld.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 30; name = dyld.3; path = doc/man/man3/dyld.3; sourceTree = SOURCE_ROOT; }; F906E2230639E96400B13DB2 /* dyld_debug.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dyld_debug.c; path = src/dyld_debug.c; sourceTree = ""; }; F913FAD90630A8AE00B7AE9D /* dyldAPIsInLibSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = dyldAPIsInLibSystem.cpp; path = src/dyldAPIsInLibSystem.cpp; sourceTree = ""; }; + F918691408B16D2500E0F9DB /* dyld-interposing.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "dyld-interposing.h"; path = "include/mach-o/dyld-interposing.h"; sourceTree = ""; }; F918691708B16D5900E0F9DB /* dyld64.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; name = dyld64.exp; path = src/dyld64.exp; sourceTree = ""; }; F919ECAB09045590002331E3 /* dyld-update-prebinding.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "dyld-update-prebinding.h"; path = "include/mach-o/dyld-update-prebinding.h"; sourceTree = ""; }; F93075C10BA1FE4D004BCA09 /* dyld_shared_cache_server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dyld_shared_cache_server.c; path = generated/dyld_shared_cache_server.c; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -397,6 +400,7 @@ F9AC7E930B7BB67700FEB38B /* version.c */, F9AB70590BA73A11002F6068 /* dyld_shared_cache_user.c */, F9AB705A0BA73A11002F6068 /* dyld_shared_cache_user.h */, + F918691408B16D2500E0F9DB /* dyld-interposing.h */, F906E2230639E96400B13DB2 /* dyld_debug.c */, ); name = src; @@ -503,6 +507,7 @@ productRefGroup = F9ED4C990630A76000DF4E74 /* Products */; projectDirPath = ""; projectRoot = ""; + shouldCheckCompatibility = 1; targets = ( F9ED4C920630A73900DF4E74 /* all */, F9ED4C970630A76000DF4E74 /* dyld */, diff --git a/include/mach-o/dyld-interposing.h b/include/mach-o/dyld-interposing.h new file mode 100644 index 0000000..8584eb9 --- /dev/null +++ b/include/mach-o/dyld-interposing.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#if !defined(_DYLD_INTERPOSING_H_) +#define _DYLD_INTERPOSING_H_ + +/* + * Example: + * + * static + * int + * my_open(const char* path, int flags, mode_t mode) + * { + * int value; + * // do stuff before open (including changing the arguments) + * value = open(path, flags, mode); + * // do stuff after open (including changing the return value(s)) + * return value; + * } + * DYLD_INTERPOSE(my_open, open) + */ + +#define DYLD_INTERPOSE(_replacment,_replacee) \ + __attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \ + __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee }; + +#endif diff --git a/launch-cache/MachOLayout.hpp b/launch-cache/MachOLayout.hpp index f49210d..d5baede 100644 --- a/launch-cache/MachOLayout.hpp +++ b/launch-cache/MachOLayout.hpp @@ -91,7 +91,7 @@ public: void setSize(uint64_t new_size) { fSize = new_size; } void setFileOffset(uint64_t new_off) { fFileOffset = new_off; } void setFileSize(uint64_t new_size) { fFileSize = new_size; } - void setWritable(bool writable) { if (writable) fPermissions |= VM_PROT_WRITE; else fPermissions &= ~VM_PROT_WRITE; } + void setWritable(bool w) { if (w) fPermissions |= VM_PROT_WRITE; else fPermissions &= ~VM_PROT_WRITE; } private: uint64_t fAddress; uint64_t fSize; diff --git a/launch-cache/update_dyld_shared_cache.cpp b/launch-cache/update_dyld_shared_cache.cpp index f437330..b0060d4 100644 --- a/launch-cache/update_dyld_shared_cache.cpp +++ b/launch-cache/update_dyld_shared_cache.cpp @@ -1296,6 +1296,12 @@ bool SharedCache::update(const char* rootPath, const char* cacheDir, bool for throwf("can't open file %s, errnor=%d", it->layout->getID().name, errno); // mark source as "don't cache" (void)fcntl(src, F_NOCACHE, 1); + // verify file has not changed since dependency analysis + struct stat stat_buf; + if ( fstat(src, &stat_buf) == -1) + throwf("can't stat open file %s, errno=%d", path, errno); + if ( (it->layout->getInode() != stat_buf.st_ino) || (it->layout->getLastModTime() != stat_buf.st_mtime) ) + throwf("aborting because OS dylib modified during cache creation: %s", path); if ( verbose ) fprintf(stderr, "update_dyld_shared_cache: copying %s to cache\n", it->layout->getID().name); @@ -1309,8 +1315,33 @@ bool SharedCache::update(const char* rootPath, const char* cacheDir, bool for const uint64_t segmentSrcStartOffset = it->layout->getOffsetInUniversalFile()+seg.fileOffset(); const uint64_t segmentSize = seg.fileSize(); const uint64_t segmentDstStartOffset = cacheFileOffsetForAddress(seg.newAddress()); - if ( ::pread(src, &inMemoryCache[segmentDstStartOffset], segmentSize, segmentSrcStartOffset) != segmentSize ) - throwf("read failure copying dylib errno=%d for %s", errno, it->layout->getID().name); + ssize_t readResult = ::pread(src, &inMemoryCache[segmentDstStartOffset], segmentSize, segmentSrcStartOffset); + if ( readResult != segmentSize ) + if ( readResult == -1 ) + throwf("read failure copying dylib errno=%d for %s", errno, it->layout->getID().name); + else + throwf("read failure copying dylib. Read of %lld bytes at file offset %lld returned %ld for %s", + segmentSize, segmentSrcStartOffset, readResult, it->layout->getID().name); + // verify __TEXT segment has no zeroed out pages + if ( strcmp(seg.name(), "__TEXT") == 0 ) { + // only scan first 128KB. Some OS dylibs have zero filled TEXT pages later in __const... + int scanEnd = segmentSize; + if ( scanEnd > 0x20000 ) + scanEnd = 0x20000; + for (int pageOffset = 0; pageOffset < scanEnd; pageOffset += 4096) { + const uint32_t* page = (uint32_t*)(&inMemoryCache[segmentDstStartOffset+pageOffset]); + bool foundNonZero = false; + for(int p=0; p < 1024; ++p) { + if ( page[p] != 0 ) { + //fprintf(stderr, "found non-zero at pageOffset=0x%08X, p=0x%08X in memory=%p for %s\n", pageOffset, p, page, it->layout->getID().name); + foundNonZero = true; + break; + } + } + if ( !foundNonZero ) + throwf("suspected bad read. Found __TEXT segment page at offset 0x%08X that is all zeros for %s in %s", pageOffset, archName(), it->layout->getID().name); + } + } } } } @@ -1732,6 +1763,8 @@ static kern_return_t do_update_cache(cpu_type_t arch, bool deleteExistingCacheFi fprintf(stderr, "update_dyld_shared_cache[%u] for arch=%s failed: %s\n", getpid(), ArchGraph::archName(arch), msg); return KERN_FAILURE; } + // only build one cache file per life of process + doNothingAndDrainQueue = true; } return KERN_SUCCESS; } diff --git a/src/ImageLoaderPE.cpp b/src/ImageLoaderPE.cpp new file mode 100644 index 0000000..173dda8 --- /dev/null +++ b/src/ImageLoaderPE.cpp @@ -0,0 +1,24 @@ +/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- +* +* Copyright (c) 2007 AppleInc. All rights reserved. +* +* @APPLE_LICENSE_HEADER_START@ +* +* This file contains Original Code and/or Modifications of Original Code +* as defined in and that are subject to the Apple Public Source License +* Version 2.0 (the 'License'). You may not use this file except in +* compliance with the License. Please obtain a copy of the License at +* http://www.opensource.apple.com/apsl/ and read it before using this +* file. +* +* The Original Code and all software distributed under the License are +* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +* Please see the License for the specific language governing rights and +* limitations under the License. +* +* @APPLE_LICENSE_HEADER_END@ +*/ + diff --git a/src/ImageLoaderPE.h b/src/ImageLoaderPE.h new file mode 100644 index 0000000..24812d5 --- /dev/null +++ b/src/ImageLoaderPE.h @@ -0,0 +1,25 @@ +/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- + * + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + + diff --git a/src/dyld.cpp b/src/dyld.cpp index 33a4a03..93cfaaa 100644 --- a/src/dyld.cpp +++ b/src/dyld.cpp @@ -2113,6 +2113,28 @@ static void mapSharedCache() } } else { + // Safe Boot should disable dyld shared cache + // if we are in safe-boot mode and the cache was not made during this boot cycle, + // delete the cache file and let it be regenerated + uint32_t safeBootValue = 0; + size_t safeBootValueSize = sizeof(safeBootValue); + if ( (sysctlbyname("kern.safeboot", &safeBootValue, &safeBootValueSize, NULL, 0) == 0) && (safeBootValue != 0) ) { + // user booted machine in safe-boot mode + struct stat dyldCacheStatInfo; + if ( ::stat(DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &dyldCacheStatInfo) == 0 ) { + struct timeval bootTimeValue; + size_t bootTimeValueSize = sizeof(bootTimeValue); + if ( (sysctlbyname("kern.boottime", &bootTimeValue, &bootTimeValueSize, NULL, 0) == 0) && (bootTimeValue.tv_sec != 0) ) { + // if the cache file was created before this boot, then throw it away and let it rebuild itself + if ( dyldCacheStatInfo.st_mtime < bootTimeValue.tv_sec ) { + ::unlink(DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME); + gLinkContext.sharedRegionMode = ImageLoader::kDontUseSharedRegion; + gSharedCacheNotFound = true; + return; + } + } + } + } // map in shared cache to shared region int fd = openSharedCacheFile(); if ( fd != -1 ) { diff --git a/src/dyld.h b/src/dyld.h index 5ae4796..1c030c3 100644 --- a/src/dyld.h +++ b/src/dyld.h @@ -102,6 +102,7 @@ namespace dyld { extern void registerImageStateSingleChangeHandler(dyld_image_states state, dyld_image_state_change_handler handler); extern void registerImageStateBatchChangeHandler(dyld_image_states state, dyld_image_state_change_handler handler); extern void garbageCollectImages(); + extern void registerWinImageLocator(ImageLocator); extern int openSharedCacheFile(); extern const void* imMemorySharedCacheHeader(); diff --git a/unit-tests/test-cases/dlopen-init-dlopen-notify/bar.c b/unit-tests/test-cases/dlopen-init-dlopen-notify/bar.c deleted file mode 100644 index e425999..0000000 --- a/unit-tests/test-cases/dlopen-init-dlopen-notify/bar.c +++ /dev/null @@ -1 +0,0 @@ -void bar() {} diff --git a/unit-tests/test-cases/dlopen-init-dlopen-notify/main.cxx b/unit-tests/test-cases/dlopen-init-dlopen-notify/main.cxx deleted file mode 100644 index cb916f2..0000000 --- a/unit-tests/test-cases/dlopen-init-dlopen-notify/main.cxx +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include // fprintf(), NULL -#include // exit(), EXIT_SUCCESS -#include -#include -#include - -#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() - - -static void trySO(const char* path) -{ - void* handle = dlopen(path, RTLD_LAZY); - if ( handle == NULL ) { - FAIL("dlopen(\"%s\") failed with: %s", path, dlerror()); - exit(0); - } - - void* sym = dlsym(handle, "foo"); - if ( sym == NULL ) { - FAIL("dlsym(handle, \"foo\") failed"); - exit(0); - } - - int result = dlclose(handle); - if ( result != 0 ) { - if ( result == 1 ) { - // panther dyld returns 1 if you try to dlclose() a dylib - XFAIL("dlclose(handle) returned %d", result); - } - else { - FAIL("dlclose(handle) returned %d", result); - exit(0); - } - } - -} - -static std::set sCurrentImages; - -static void notify(const struct mach_header *mh, intptr_t vmaddr_slide) -{ - //fprintf(stderr, "mh=%p\n", mh); - if ( sCurrentImages.count(mh) != 0 ) { - FAIL("notified twice about %p", mh); - exit(0); - } - sCurrentImages.insert(mh); -} - - - -int main() -{ - _dyld_register_func_for_add_image(¬ify); - - trySO("libfoo.dylib"); - - PASS("dlopen-init-dlopen-notify"); - return EXIT_SUCCESS; -} diff --git a/unit-tests/test-cases/dlopen-leak/Makefile b/unit-tests/test-cases/dlopen-leak/Makefile deleted file mode 100644 index b3a47a3..0000000 --- a/unit-tests/test-cases/dlopen-leak/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -## -# Copyright (c) 2007 Apple Inc. All rights reserved. -# -# @APPLE_LICENSE_HEADER_START@ -# -# This file contains Original Code and/or Modifications of Original Code -# as defined in and that are subject to the Apple Public Source License -# Version 2.0 (the 'License'). You may not use this file except in -# compliance with the License. Please obtain a copy of the License at -# http://www.opensource.apple.com/apsl/ and read it before using this -# file. -# -# The Original Code and all software distributed under the License are -# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -# Please see the License for the specific language governing rights and -# limitations under the License. -# -# @APPLE_LICENSE_HEADER_END@ -## -TESTROOT = ../.. -include ${TESTROOT}/include/common.makefile - - -# -# verify there are no leaks with dlopen/close on success and failure -# - -# leaks does not work on rosetta processes -CHECK = check-real -ifeq "ppc" "$(ARCH)" - MACHINE = $(shell arch) - ifeq "i386" "$(MACHINE)" - CHECK = check-xfail - endif -endif - -all-check: all check - -check: ${CHECK} - -check-real: - ${TESTROOT}/bin/exit-zero-pass.pl "dlopen-leak" "dlopen-leak" "DYLD_LIBRARY_PATH=hide && ./main | grep '0 leaks for 0 total leaked bytes' > /dev/null" - ${TESTROOT}/bin/exit-zero-pass.pl "dlopen-leak" "dlopen-leak" "./main | grep '0 leaks for 0 total leaked bytes' > /dev/null" - -check-xfail: - echo "XFAIL dlopen-leak"; - - -all: main - - -hide/libbar.dylib : bar.c - mkdir -p hide - ${CC} bar.c -dynamiclib -o hide/libbar.dylib -install_name libbar.dylib - -libfoo.dylib : foo.c hide/libbar.dylib - ${CC} foo.c hide/libbar.dylib -dynamiclib -o libfoo.dylib - -main : main.c libfoo.dylib - ${CC} ${CCFLAGS} -I${TESTROOT}/include main.c -o main - - - -clean: - ${RM} ${RMFLAGS} *~ main libfoo.dylib hide diff --git a/unit-tests/test-cases/dlopen-leak/bar.c b/unit-tests/test-cases/dlopen-leak/bar.c deleted file mode 100644 index b72a1a5..0000000 --- a/unit-tests/test-cases/dlopen-leak/bar.c +++ /dev/null @@ -1,3 +0,0 @@ -void bar() -{ -} diff --git a/unit-tests/test-cases/dlopen-leak/foo.c b/unit-tests/test-cases/dlopen-leak/foo.c deleted file mode 100644 index 3695dc9..0000000 --- a/unit-tests/test-cases/dlopen-leak/foo.c +++ /dev/null @@ -1,3 +0,0 @@ -void foo() -{ -} diff --git a/unit-tests/test-cases/dlopen-notify-bind/main.c b/unit-tests/test-cases/dlopen-notify-bind/main.c deleted file mode 100644 index d99436a..0000000 --- a/unit-tests/test-cases/dlopen-notify-bind/main.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#include // fprintf(), NULL -#include // exit(), EXIT_SUCCESS -#include -#include - -#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() - - -typedef void* (*fooProc)(); - - -static void notify(const struct mach_header *mh, intptr_t vmaddr_slide) -{ - //fprintf(stderr, "mh=%p\n", mh); - NSLookupSymbolInImage(mh, "_bar", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); -} - - -int main() -{ - _dyld_register_func_for_add_image(¬ify); - - void* handle = dlopen("libfoo.dylib", RTLD_LAZY); - if ( handle == NULL ) { - FAIL("dlopen(\"%s\") failed with: %s", "libfoo.dylib", dlerror()); - exit(0); - } - - fooProc fooPtr = (fooProc)dlsym(handle, "foo"); - if ( fooPtr == NULL ) { - FAIL("dlsym(handle, \"foo\") failed"); - exit(0); - } - - void* foosMalloc = (*fooPtr)(); - //fprintf(stderr, "foo says &malloc=%p\n", foosMalloc); - //fprintf(stderr, "&malloc=%p\n", &malloc); - - dlclose(handle); - - if ( foosMalloc == &malloc ) - PASS("dlopen-notify-bind"); - else - FAIL("dlopen-notify-bind libfoo.dylib double bound"); - return EXIT_SUCCESS; -} diff --git a/unit-tests/test-cases/dlopen_preflight-leak/Makefile b/unit-tests/test-cases/dlopen_preflight-leak/Makefile deleted file mode 100644 index eff03d8..0000000 --- a/unit-tests/test-cases/dlopen_preflight-leak/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -## -# Copyright (c) 2007 Apple Inc. All rights reserved. -# -# @APPLE_LICENSE_HEADER_START@ -# -# This file contains Original Code and/or Modifications of Original Code -# as defined in and that are subject to the Apple Public Source License -# Version 2.0 (the 'License'). You may not use this file except in -# compliance with the License. Please obtain a copy of the License at -# http://www.opensource.apple.com/apsl/ and read it before using this -# file. -# -# The Original Code and all software distributed under the License are -# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -# Please see the License for the specific language governing rights and -# limitations under the License. -# -# @APPLE_LICENSE_HEADER_END@ -## -TESTROOT = ../.. -include ${TESTROOT}/include/common.makefile - - -# -# verify there are no leaks with dlopen/close on success and failure -# - -# leaks does not work on rosetta processes -CHECK = check-real -ifeq "ppc" "$(ARCH)" - MACHINE = $(shell arch) - ifeq "i386" "$(MACHINE)" - CHECK = check-xfail - endif -endif - -all-check: all check - -check: ${CHECK} - -check-real: - ${TESTROOT}/bin/exit-zero-pass.pl "dlopen_preflight-leak" "dlopen_preflight-leak" "DYLD_LIBRARY_PATH=hide && ./main | grep '0 leaks for 0 total leaked bytes' > /dev/null" - ${TESTROOT}/bin/exit-zero-pass.pl "dlopen_preflight-leak" "dlopen_preflight-leak" "./main | grep '0 leaks for 0 total leaked bytes' > /dev/null" - -check-xfail: - echo "XFAIL dlopen-leak"; - -all: main - -hide/libbar.dylib : bar.c - mkdir -p hide - ${CC} bar.c -dynamiclib -o hide/libbar.dylib -install_name libbar.dylib - -libfoo.dylib : foo.c hide/libbar.dylib - ${CC} foo.c hide/libbar.dylib -dynamiclib -o libfoo.dylib - -main : main.c libfoo.dylib - ${CC} ${CCFLAGS} -I${TESTROOT}/include main.c -o main - - -clean: - ${RM} ${RMFLAGS} *~ main libfoo.dylib hide diff --git a/unit-tests/test-cases/dlopen_preflight-leak/bar.c b/unit-tests/test-cases/dlopen_preflight-leak/bar.c deleted file mode 100644 index b72a1a5..0000000 --- a/unit-tests/test-cases/dlopen_preflight-leak/bar.c +++ /dev/null @@ -1,3 +0,0 @@ -void bar() -{ -} diff --git a/unit-tests/test-cases/dlopen_preflight-leak/foo.c b/unit-tests/test-cases/dlopen_preflight-leak/foo.c deleted file mode 100644 index 3695dc9..0000000 --- a/unit-tests/test-cases/dlopen_preflight-leak/foo.c +++ /dev/null @@ -1,3 +0,0 @@ -void foo() -{ -} diff --git a/unit-tests/test-cases/framework-fallback/main.c b/unit-tests/test-cases/framework-fallback/main.c index 904aeb3..13f8146 100644 --- a/unit-tests/test-cases/framework-fallback/main.c +++ b/unit-tests/test-cases/framework-fallback/main.c @@ -39,12 +39,12 @@ main(int argc, const char* argv[]) { const struct mach_header *image; - image = NSAddImage("AppKit.framework/AppKit", + image = NSAddImage("Carbon.framework/Carbon", NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING); if ( image != NULL ) - PASS("AppKit loaded"); + PASS("Carbon loaded"); else - FAIL("Could not load AppKit"); + FAIL("Could not load Carbon"); return 0; } diff --git a/unit-tests/test-cases/dlopen-notify-bind/Makefile b/unit-tests/test-cases/interpose-basic-prebound/Makefile similarity index 64% rename from unit-tests/test-cases/dlopen-notify-bind/Makefile rename to unit-tests/test-cases/interpose-basic-prebound/Makefile index 5844be2..5c35a89 100644 --- a/unit-tests/test-cases/dlopen-notify-bind/Makefile +++ b/unit-tests/test-cases/interpose-basic-prebound/Makefile @@ -1,5 +1,5 @@ ## -# Copyright (c) 2007 Apple Inc. All rights reserved. +# Copyright (c) 2005 Apple Computer, Inc. All rights reserved. # # @APPLE_LICENSE_HEADER_START@ # @@ -23,29 +23,22 @@ TESTROOT = ../.. include ${TESTROOT}/include/common.makefile +run: all + export DYLD_INSERT_LIBRARIES="libmystrdup.dylib" && ./main -### CFSTRs cause crashes in Leopard -### -### main registers for notification and then dlopens(libfoo). -### In the notification callback, main calls NSLookupSymbolInImage(BIND) -### which double bound libfoo -### +all: main libmystrdup.dylib -all-check: all check +main : main.c libfoo.dylib + ${CC} ${CCFLAGS} -I${TESTROOT}/include -o main main.c libfoo.dylib -check: - ./main - -all: main +libfoo.dylib : foo.c + export MACOSX_DEPLOYMENT_TARGET=10.3 && ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -prebind -seg1addr 20000 -main : main.c libfoo.dylib - ${CC} ${CCFLAGS} -I${TESTROOT}/include -o main main.c -mmacosx-version-min=10.4 +libmystrdup.dylib : mystrdup.c + ${CC} ${CCFLAGS} -dynamiclib mystrdup.c -o libmystrdup.dylib -libfoo.dylib : foo.c - ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib - clean: - ${RM} ${RMFLAGS} *~ main libfoo.dylib - + ${RM} ${RMFLAGS} *~ main libmystrdup.dylib libfoo.dylib + \ No newline at end of file diff --git a/unit-tests/test-cases/interpose-basic-prebound/foo.c b/unit-tests/test-cases/interpose-basic-prebound/foo.c new file mode 100644 index 0000000..3b5f1ff --- /dev/null +++ b/unit-tests/test-cases/interpose-basic-prebound/foo.c @@ -0,0 +1,12 @@ + +#include +#include + +bool check_dylib_interposing() +{ + const char* x = strdup("123"); + const char* y = strdup("456"); + + return ( (strcmp(x, "hello") == 0) && (strcmp(y, "hello") == 0) ); +} + diff --git a/unit-tests/test-cases/dlopen-leak/main.c b/unit-tests/test-cases/interpose-basic-prebound/main.c similarity index 68% rename from unit-tests/test-cases/dlopen-leak/main.c rename to unit-tests/test-cases/interpose-basic-prebound/main.c index 511a140..ba5a95c 100644 --- a/unit-tests/test-cases/dlopen-leak/main.c +++ b/unit-tests/test-cases/interpose-basic-prebound/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,29 +20,21 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include -#include +#include // fprintf(), NULL +#include // exit(), EXIT_SUCCESS +#include +#include #include -#include -#include - -#include "test.h" +#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() +extern bool check_dylib_interposing(); int main() -{ - for (int i=0; i < 100; ++i) { - void* handle = dlopen("libfoo.dylib", RTLD_LAZY); - if ( handle != NULL ) - dlclose(handle); - dlopen("libnotthere.dylib", RTLD_LAZY); - } - - // execute leaks command on myself - char cmd[512]; - sprintf(cmd, "leaks %u\n", getpid()); - system(cmd); - +{ + if ( check_dylib_interposing() ) + PASS("interpose-basic"); + else + FAIL("interpose-basic"); return EXIT_SUCCESS; } diff --git a/unit-tests/test-cases/interpose-basic-prebound/mystrdup.c b/unit-tests/test-cases/interpose-basic-prebound/mystrdup.c new file mode 100644 index 0000000..077a8a2 --- /dev/null +++ b/unit-tests/test-cases/interpose-basic-prebound/mystrdup.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +char* mystrdup(const char* in) +{ + return "hello"; +} + +DYLD_INTERPOSE(mystrdup, strdup) diff --git a/unit-tests/test-cases/dlopen-init-dlopen-notify/Makefile b/unit-tests/test-cases/interpose-basic/Makefile similarity index 50% rename from unit-tests/test-cases/dlopen-init-dlopen-notify/Makefile rename to unit-tests/test-cases/interpose-basic/Makefile index b24fa5f..0bd0312 100644 --- a/unit-tests/test-cases/dlopen-init-dlopen-notify/Makefile +++ b/unit-tests/test-cases/interpose-basic/Makefile @@ -1,7 +1,5 @@ -all-check: all check - -check:## -# Copyright (c) 2007 Apple Inc. All rights reserved. +## +# Copyright (c) 2005-2007 Apple Inc. All rights reserved. # # @APPLE_LICENSE_HEADER_START@ # @@ -25,38 +23,22 @@ check:## TESTROOT = ../.. include ${TESTROOT}/include/common.makefile +run: all + export DYLD_INSERT_LIBRARIES="libmystrdup.dylib" && ./main -### ADOBE: Premiere Pro crashes on quit -### -### libfoo depends on libfoo1 and libfoo2. main dlopens(libfoo). -### libfoo1 has an initializer that calls dlopen(libbar). -### libbar depends on libfoo2 -### - -all-check: all check - -check: - ./main - -all: main - -main : main.cxx libfoo.dylib - ${CXX} ${CCXXFLAGS} -I${TESTROOT}/include -o main main.cxx - +all: main libmystrdup.dylib -libfoo.dylib : foo.c libfoo1.dylib libfoo2.dylib - ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib libfoo1.dylib libfoo2.dylib +main : main.c libwrap.dylib + ${CC} ${CCFLAGS} -I${TESTROOT}/include -o main libwrap.dylib main.c -libfoo1.dylib : foo1.c libbar.dylib - ${CC} ${CCFLAGS} -dynamiclib foo1.c -o libfoo1.dylib +libwrap.dylib: wrap.c + ${CC} ${CCFLAGS} -dynamiclib wrap.c -o libwrap.dylib -libfoo2.dylib : foo2.c - ${CC} ${CCFLAGS} -dynamiclib foo2.c -o libfoo2.dylib +libmystrdup.dylib : mystrdup.c + ${CC} ${CCFLAGS} -dynamiclib mystrdup.c -o libmystrdup.dylib -libbar.dylib : bar.c libfoo2.dylib - ${CC} ${CCFLAGS} -dynamiclib bar.c -o libbar.dylib libfoo2.dylib clean: - ${RM} ${RMFLAGS} *~ main libbar.dylib libfoo.dylib libfoo1.dylib libfoo2.dylib + ${RM} ${RMFLAGS} *~ main libmystrdup.dylib libwrap.dylib diff --git a/unit-tests/test-cases/interpose-basic/main.c b/unit-tests/test-cases/interpose-basic/main.c new file mode 100644 index 0000000..ebcd741 --- /dev/null +++ b/unit-tests/test-cases/interpose-basic/main.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005-2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include // fprintf(), NULL +#include // exit(), EXIT_SUCCESS +#include +#include + +#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() + +extern char* wrap_strdup(const char*); + +int main() +{ + const char* x = strdup("123"); + const char* y = wrap_strdup("456"); + + if ( (strcmp(x, "hello") == 0) && (strcmp(y, "hello") == 0) ) + PASS("interpose-basic"); + else + FAIL("interpose-basic"); + return EXIT_SUCCESS; +} diff --git a/unit-tests/test-cases/interpose-basic/mystrdup.c b/unit-tests/test-cases/interpose-basic/mystrdup.c new file mode 100644 index 0000000..077a8a2 --- /dev/null +++ b/unit-tests/test-cases/interpose-basic/mystrdup.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include + +char* mystrdup(const char* in) +{ + return "hello"; +} + +DYLD_INTERPOSE(mystrdup, strdup) diff --git a/unit-tests/test-cases/dlopen_preflight-leak/main.c b/unit-tests/test-cases/interpose-basic/wrap.c similarity index 74% rename from unit-tests/test-cases/dlopen_preflight-leak/main.c rename to unit-tests/test-cases/interpose-basic/wrap.c index 612e141..f634ab2 100644 --- a/unit-tests/test-cases/dlopen_preflight-leak/main.c +++ b/unit-tests/test-cases/interpose-basic/wrap.c @@ -20,26 +20,16 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#include -#include -#include -#include -#include - -#include "test.h" +#include +// make a pointer statically initiallized to strdup() +// since libwrap.dylib is staticlly linked to main +// this verfies that interposing happens properly +static char* (*proc)(const char*) = strdup; -int main() +char* wrap_strdup(const char* str) { - for (int i=0; i < 100; ++i) { - dlopen_preflight("libfoo.dylib"); - } - - // execute leaks command on myself - char cmd[512]; - sprintf(cmd, "leaks %u\n", getpid()); - system(cmd); - - return EXIT_SUCCESS; + return proc(str); } + diff --git a/unit-tests/test-cases/interpose-chained/Makefile b/unit-tests/test-cases/interpose-chained/Makefile new file mode 100644 index 0000000..dd89247 --- /dev/null +++ b/unit-tests/test-cases/interpose-chained/Makefile @@ -0,0 +1,63 @@ +## +# Copyright (c) 2005 Apple Computer, Inc. All rights reserved. +# +# @APPLE_LICENSE_HEADER_START@ +# +# This file contains Original Code and/or Modifications of Original Code +# as defined in and that are subject to the Apple Public Source License +# Version 2.0 (the 'License'). You may not use this file except in +# compliance with the License. Please obtain a copy of the License at +# http://www.opensource.apple.com/apsl/ and read it before using this +# file. +# +# The Original Code and all software distributed under the License are +# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +# Please see the License for the specific language governing rights and +# limitations under the License. +# +# @APPLE_LICENSE_HEADER_END@ +# + +# +# This unit test verifies that multiple interposing libraries can all +# interpose the same function and the result is that they chain together. +# That is, each one calls through to the next. +# +# On Tiger (10.4.0), this test fails with infinite recursion. +# +# The function foo() does string appends. This allows us to check: +# 1) every interposer was called, and 2) they were called in the +# correct order. +# + +TESTROOT = ../.. +include ${TESTROOT}/include/common.makefile + +run: all + export DYLD_INSERT_LIBRARIES="libfoo1.dylib:libfoo2.dylib:libfoo3.dylib" && ./main + +all: main libfoo1.dylib libfoo2.dylib libfoo3.dylib + +main : main.c libfoo.dylib + ${CC} ${CCFLAGS} -I${TESTROOT}/include main.c libfoo.dylib -o main + +libfoo.dylib : foo.c + ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib + +libfoo1.dylib : foo1.c libfoo.dylib + ${CC} ${CCFLAGS} -dynamiclib foo1.c libfoo.dylib -o libfoo1.dylib + +libfoo2.dylib : foo2.c libfoo.dylib + ${CC} ${CCFLAGS} -dynamiclib foo2.c libfoo.dylib -o libfoo2.dylib + +libfoo3.dylib : foo3.c libfoo.dylib + ${CC} ${CCFLAGS} -dynamiclib foo3.c libfoo.dylib -o libfoo3.dylib + + + +clean: + ${RM} ${RMFLAGS} *~ main libfoo.dylib libfoo1.dylib libfoo2.dylib libfoo3.dylib + diff --git a/unit-tests/test-cases/interpose-chained/foo.c b/unit-tests/test-cases/interpose-chained/foo.c new file mode 100644 index 0000000..681bc29 --- /dev/null +++ b/unit-tests/test-cases/interpose-chained/foo.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include "foo.h" + +const char* foo(const char* str) +{ + char* result; + asprintf(&result, "foo(%s)", str); + return result; +} + diff --git a/unit-tests/test-cases/dlopen-init-dlopen-notify/foo.c b/unit-tests/test-cases/interpose-chained/foo.h similarity index 89% rename from unit-tests/test-cases/dlopen-init-dlopen-notify/foo.c rename to unit-tests/test-cases/interpose-chained/foo.h index edbdbc4..2bb7c94 100644 --- a/unit-tests/test-cases/dlopen-init-dlopen-notify/foo.c +++ b/unit-tests/test-cases/interpose-chained/foo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,11 +21,4 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include - - - -int foo() -{ - return 10; -} +extern const char* foo(const char* str); diff --git a/unit-tests/test-cases/dlopen-init-dlopen-notify/foo1.c b/unit-tests/test-cases/interpose-chained/foo1.c similarity index 75% rename from unit-tests/test-cases/dlopen-init-dlopen-notify/foo1.c rename to unit-tests/test-cases/interpose-chained/foo1.c index c24996b..634cc3b 100644 --- a/unit-tests/test-cases/dlopen-init-dlopen-notify/foo1.c +++ b/unit-tests/test-cases/interpose-chained/foo1.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,19 +20,15 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#include +#include +#include "foo.h" -#include - -static void myInit() __attribute__((constructor)); - -static void myInit() -{ - // call dlopen to verify that initializer lock can be held recursively - dlopen("libbar.dylib", RTLD_LAZY); -} - - -int foo1() +const char* foo1(const char* str) { - return 10; + char* result; + asprintf(&result, "foo1(%s)", foo(str)); + return result; } + +DYLD_INTERPOSE(foo1, foo) diff --git a/unit-tests/test-cases/dlopen-init-dlopen-notify/foo2.c b/unit-tests/test-cases/interpose-chained/foo2.c similarity index 77% rename from unit-tests/test-cases/dlopen-init-dlopen-notify/foo2.c rename to unit-tests/test-cases/interpose-chained/foo2.c index 5dd0a2a..fb21948 100644 --- a/unit-tests/test-cases/dlopen-init-dlopen-notify/foo2.c +++ b/unit-tests/test-cases/interpose-chained/foo2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -20,18 +20,15 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#include +#include +#include "foo.h" -#include - -static void myInit() __attribute__((constructor)); - -static void myInit() -{ - -} - - -int foo2() +const char* foo2(const char* str) { - return 10; + char* result; + asprintf(&result, "foo2(%s)", foo(str)); + return result; } + +DYLD_INTERPOSE(foo2, foo) diff --git a/unit-tests/test-cases/interpose-chained/foo3.c b/unit-tests/test-cases/interpose-chained/foo3.c new file mode 100644 index 0000000..b85392f --- /dev/null +++ b/unit-tests/test-cases/interpose-chained/foo3.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include +#include +#include "foo.h" + +const char* foo3(const char* str) +{ + char* result; + asprintf(&result, "foo3(%s)", foo(str)); + return result; +} + +DYLD_INTERPOSE(foo3, foo) diff --git a/unit-tests/test-cases/interpose-chained/main.c b/unit-tests/test-cases/interpose-chained/main.c new file mode 100644 index 0000000..5209b67 --- /dev/null +++ b/unit-tests/test-cases/interpose-chained/main.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include // fprintf(), NULL +#include // exit(), EXIT_SUCCESS +#include + +#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() +#include "foo.h" + +int main() +{ + const char* x = foo("seed"); + + if ( strcmp(x, "foo3(foo2(foo1(foo(seed))))") == 0 ) + PASS("interpose-chained"); + else + FAIL("interpose-chained %s", x); + return EXIT_SUCCESS; +} diff --git a/unit-tests/test-cases/interpose-dlsym/Makefile b/unit-tests/test-cases/interpose-dlsym/Makefile new file mode 100644 index 0000000..9b9ae73 --- /dev/null +++ b/unit-tests/test-cases/interpose-dlsym/Makefile @@ -0,0 +1,42 @@ +## +# Copyright (c) 2005-2007 Apple Inc. All rights reserved. +# +# @APPLE_LICENSE_HEADER_START@ +# +# This file contains Original Code and/or Modifications of Original Code +# as defined in and that are subject to the Apple Public Source License +# Version 2.0 (the 'License'). You may not use this file except in +# compliance with the License. Please obtain a copy of the License at +# http://www.opensource.apple.com/apsl/ and read it before using this +# file. +# +# The Original Code and all software distributed under the License are +# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER +# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. +# Please see the License for the specific language governing rights and +# limitations under the License. +# +# @APPLE_LICENSE_HEADER_END@ +## +TESTROOT = ../.. +include ${TESTROOT}/include/common.makefile + +run: all + export DYLD_INSERT_LIBRARIES="libmyfree.dylib" && ./main + +all: main libmyfree.dylib + +main : main.c + ${CC} ${CCFLAGS} -I${TESTROOT}/include -o main main.c + + +libmyfree.dylib : myfree.c + ${CC} ${CCFLAGS} -dynamiclib myfree.c -o libmyfree.dylib + + + +clean: + ${RM} ${RMFLAGS} *~ main libmyfree.dylib + diff --git a/unit-tests/test-cases/interpose-dlsym/main.c b/unit-tests/test-cases/interpose-dlsym/main.c new file mode 100644 index 0000000..6857710 --- /dev/null +++ b/unit-tests/test-cases/interpose-dlsym/main.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2007 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +#include // fprintf(), NULL +#include // exit(), EXIT_SUCCESS +#include +#include +#include + +#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL() + + +int main() +{ + void* handle = dlopen("/usr/lib/libSystem.B.dylib", RTLD_LAZY); + if ( handle == NULL ) { + FAIL("interpose-dlsym: dlopen() error: %s", dlerror()); + exit(0); + } + void* dlsym_free = dlsym(handle, "free"); + if ( dlsym_free == NULL ) { + FAIL("interpose-dlsym: dlsym() error: %s", dlerror()); + exit(0); + } + + if ( dlsym_free == &free ) + PASS("interpose-dlsym"); + else + FAIL("interpose-dlsym: %p != %p", dlsym_free, &free); + return EXIT_SUCCESS; +} diff --git a/unit-tests/test-cases/dlopen-notify-bind/foo.c b/unit-tests/test-cases/interpose-dlsym/myfree.c similarity index 86% rename from unit-tests/test-cases/dlopen-notify-bind/foo.c rename to unit-tests/test-cases/interpose-dlsym/myfree.c index 8dab6be..f856475 100644 --- a/unit-tests/test-cases/dlopen-notify-bind/foo.c +++ b/unit-tests/test-cases/interpose-dlsym/myfree.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2007 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,11 +22,11 @@ */ #include +#include - -void* externalRlocToMalloc = &malloc; - -void* foo() +void myfree(void* p) { - return externalRlocToMalloc; + free(p); } + +DYLD_INTERPOSE(myfree, free) -- 2.45.2