Skip to content
Browse files

objc4-266, released with OS X v10.4

  • Loading branch information...
1 parent ee118bd commit afeeeea2497eb4e223be932f542087280df21f36 @bavarious committed Apr 29, 2005
View
156 Makefile
@@ -1,10 +1,9 @@
# use LDFLAGS not LFLAGS
-# seg-addr-table, sect-order
#
# Simple makefile for building objc4 on Darwin
#
# These make variables (or environment variables) are used
-# if defined:
+# when defined:
# SRCROOT path location of root of source hierarchy;
# defaults to ".", but must be set to a
# destination path for installsrc target.
@@ -77,6 +76,7 @@ CHOWN = /usr/sbin/chown
TAR = /usr/bin/tar
STRIP = /usr/bin/strip
NMEDIT = /usr/bin/nmedit
+LIPO = /usr/bin/lipo
ifeq "$(PLATFORM)" "Darwin"
WARNING_FLAGS = -Wmost -Wno-precomp -Wno-four-char-constants
@@ -100,13 +100,21 @@ ARCH_FLAGS = $(foreach A, $(ARCH_LIST), $(addprefix -arch , $(A)))
endif
+ifeq "$(ORDERFILE)" ""
+ORDERFILE = $(wildcard /usr/local/lib/OrderFiles/libobjc.order)
+endif
+ifneq "$(ORDERFILE)" ""
+ORDER = -sectorder __TEXT __text $(ORDERFILE)
+else
+ORDER =
+endif
ifeq "$(USER)" ""
USER = unknown
endif
-CFLAGS = -g -fno-common -pipe $(PLATFORM_CFLAGS) $(WARNING_FLAGS) -I$(SYMROOT) -I. -I$(SYMROOT)/ProjectHeaders
-LDFLAGS = -framework CoreFoundation
+CFLAGS = -g -fno-common -fobjc-exceptions -pipe $(PLATFORM_CFLAGS) $(WARNING_FLAGS) -I$(SYMROOT) -I. -I$(SYMROOT)/ProjectHeaders
+LDFLAGS =
LIBRARY_EXT = .dylib
@@ -115,10 +123,10 @@ OTHER_HEADER_INSTALLDIR = usr/local/include/objc
INSTALLDIR = usr/lib
ifeq "$(PLATFORM)" "Darwin"
-CFLAGS += $(ARCH_FLAGS)
-LDFLAGS += $(ARCH_FLAGS) -dynamiclib -dynamic -compatibility_version 1 -current_version $(CURRENT_PROJECT_VERSION)
+LDFLAGS += -dynamiclib -dynamic -compatibility_version 1 -current_version $(CURRENT_PROJECT_VERSION)
endif
+
CFLAGS += $(OTHER_CFLAGS) $(RC_CFLAGS)
LDFLAGS += $(OTHER_LDFLAGS)
@@ -132,18 +140,20 @@ ifndef PROFILE_CFLAGS
PROFILE_CFLAGS = -DPROFILE -pg -Os
endif
-CFLAGS_OPTIMIZED = $(CFLAGS) $(OPTIMIZATION_CFLAGS)
-CFLAGS_DEBUG = $(CFLAGS) $(DEBUG_CFLAGS)
-CFLAGS_PROFILE = $(CFLAGS) $(PROFILE_CFLAGS)
+CFLAGS_OPTIMIZED = $(OPTIMIZATION_CFLAGS) $(CFLAGS)
+CFLAGS_DEBUG = $(DEBUG_CFLAGS) $(CFLAGS)
+CFLAGS_PROFILE = $(PROFILE_CFLAGS) $(CFLAGS)
LDFLAGS_OPTIMIZED = $(LDFLAGS) -g
LDFLAGS_DEBUG = $(LDFLAGS) -g
LDFLAGS_PROFILE = $(LDFLAGS) -g -pg
-SUBDIRS = . runtime runtime/OldClasses.subproj runtime/Messengers.subproj
+SUBDIRS = . runtime runtime/OldClasses.subproj runtime/Messengers.subproj runtime/Auto.subproj
# files to compile
SOURCES=
+# files to compile into separate linker modules
+MODULE_SOURCES=
# files to not compile
OTHER_SOURCES=
# headers to install in /usr/include/objc
@@ -155,17 +165,17 @@ OTHER_HEADERS=
# runtime
SOURCES += $(addprefix runtime/, \
- Object.m Protocol.m hashtable2.m maptable.m objc-class.m objc-errors.m \
- objc-file.m objc-load.m objc-moninit.c objc-runtime.m objc-sel.m \
- objc-sync.m objc-exception.m \
- )
+ Object.m Protocol.m hashtable2.m maptable.m objc-class.m objc-errors.m \
+ objc-file.m objc-load.m objc-moninit.c objc-runtime.m objc-sel.m \
+ objc-sync.m objc-exception.m objc-auto.m objc-sel-set.m objc-rtp.m \
+ )
PUBLIC_HEADERS += $(addprefix runtime/, \
- objc-class.h objc-api.h objc-load.h objc-runtime.h objc.h Object.h \
- objc-sync.h objc-exception.h \
- Protocol.h error.h hashtable2.h \
- )
-PRIVATE_HEADERS += runtime/objc-private.h runtime/objc-config.h runtime/objc-sel-table.h
-OTHER_HEADERS += runtime/maptable.h
+ objc-class.h objc-api.h objc-load.h objc-runtime.h objc.h Object.h \
+ objc-sync.h objc-exception.h objc-auto.h \
+ Protocol.h error.h hashtable2.h \
+ )
+PRIVATE_HEADERS += runtime/objc-private.h runtime/objc-config.h runtime/objc-sel-table.h runtime/objc-sel-set.h runtime/objc-rtp.h
+OTHER_HEADERS += runtime/maptable.h runtime/objc-auto.h
# OldClasses
SOURCES += runtime/OldClasses.subproj/List.m
@@ -175,14 +185,33 @@ PUBLIC_HEADERS += runtime/OldClasses.subproj/List.h
SOURCES += runtime/Messengers.subproj/objc-msg.s
OTHER_SOURCES += runtime/Messengers.subproj/objc-msg-ppc.s runtime/Messengers.subproj/objc-msg-i386.s
+# Auto support
+SOURCES += runtime/Auto.subproj/objc-auto.s
+OTHER_SOURCES += runtime/Auto.subproj/objc-auto-ppc.s runtime/Auto.subproj/objc-auto-i386.s
+
+# RTP symbols for gdb
+# See also $(OBJROOT)/runtime/objc-rtp-sym.ppc.o rule below.
+OTHER_SOURCES += runtime/objc-rtp-sym.s
+
+# Interposing support.
+# This code is built into a second module so dyld's function interposing
+# can manipulate the calls.
+MODULE_SOURCES += runtime/Messengers.subproj/objc-msg-stub.s
+OTHER_SOURCES += runtime/Messengers.subproj/objc-msg-stub-ppc.s runtime/Messengers.subproj/objc-msg-stub-i386.s
+
# project root
-OTHER_SOURCES += Makefile APPLE_LICENSE objc-exports libobjc.order
+OTHER_SOURCES += Makefile APPLE_LICENSE objc-exports
OBJECTS = $(addprefix $(OBJROOT)/, $(addsuffix .o, $(basename $(SOURCES) ) ) )
OBJECTS_OPTIMIZED = $(OBJECTS:.o=.opt.o)
OBJECTS_DEBUG = $(OBJECTS:.o=.debug.o)
OBJECTS_PROFILE = $(OBJECTS:.o=.profile.o)
+MODULE_OBJECTS = $(addprefix $(OBJROOT)/, $(addsuffix .o, $(basename $(MODULE_SOURCES) ) ) )
+MODULE_OBJECTS_OPTIMIZED = $(MODULE_OBJECTS:.o=.opt.o)
+MODULE_OBJECTS_DEBUG = $(MODULE_OBJECTS:.o=.debug.o)
+MODULE_OBJECTS_PROFILE = $(MODULE_OBJECTS:.o=.profile.o)
+
# For simplicity, each object target depends on all objc headers. Most of
# them come close to requiring this anyway, and rebuild from scratch is fast.
DEPEND_HEADERS = $(addprefix $(SRCROOT)/, \
@@ -232,6 +261,36 @@ $(OBJROOT)/runtime/Messengers.subproj/objc-msg.profile.o : \
$(SRCROOT)/runtime/Messengers.subproj/objc-msg-ppc.s \
$(SRCROOT)/runtime/Messengers.subproj/objc-msg-i386.s
+# Additional dependency: objc-msg-sutb.s depends on objc-msg-stub-ppc.s and
+# objc-msg-stub-i386.s, which it includes.
+$(OBJROOT)/runtime/Messengers.subproj/objc-msg-stub.opt.o \
+$(OBJROOT)/runtime/Messengers.subproj/objc-msg-stub.debug.o \
+$(OBJROOT)/runtime/Messengers.subproj/objc-msg-stub.profile.o : \
+ $(SRCROOT)/runtime/Messengers.subproj/objc-msg-stub-ppc.s \
+ $(SRCROOT)/runtime/Messengers.subproj/objc-msg-stub-i386.s
+
+# Additional dependency: objc-auto.s depends on objc-auto-ppc.s and
+# objc-auto-i386.s, which it includes.
+$(OBJROOT)/runtime/Auto.subproj/objc-auto.opt.o \
+$(OBJROOT)/runtime/Auto.subproj/objc-auto.debug.o \
+$(OBJROOT)/runtime/Auto.subproj/objc-auto.profile.o : \
+ $(SRCROOT)/runtime/Auto.subproj/objc-auto-ppc.s \
+ $(SRCROOT)/runtime/Auto.subproj/objc-auto-i386.s
+
+# Additional rules: objc-rtp-sym.s needs to be built with a per-arch seg1addr,
+# and need to be stripped here because stripping the dylib does not remove
+# debug info from the magic sections.
+# objc-rtp-sym.s is not in SOURCES, and objc-rtp-sym.o is not in OBJECTS
+$(OBJROOT)/runtime/objc-rtp-sym.ppc.o: $(SRCROOT)/runtime/objc-rtp-sym.s
+ $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) -arch ppc "$<" -c -o "$@.temp"
+ $(SILENT) $(STRIP) -S "$@.temp"
+ $(SILENT) $(LD) -arch ppc -seg1addr 0xfffec000 "$@.temp" -r -o "$@"
+
+$(OBJROOT)/runtime/objc-rtp-sym.i386.o: $(SRCROOT)/runtime/objc-rtp-sym.s
+ $(SILENT) $(CC) $(CFLAGS_OPTIMIZED) -arch i386 "$<" -c -o "$@.temp"
+ $(SILENT) $(STRIP) -S "$@.temp"
+ $(SILENT) $(LD) -arch i386 -seg1addr 0xfffe8000 "$@.temp" -r -o "$@"
+
# These are the main targets:
# build builds the library to OBJROOT and SYMROOT
@@ -257,7 +316,7 @@ ifeq "$(SRCROOT)" "."
$(SILENT) $(ECHO) "SRCROOT must be defined to be the destination directory; it cannot be '.'"
exit 1
endif
- $(SILENT) $(TAR) -cf $(SRCROOT)/objc4.sources.tar $(SOURCES) $(PUBLIC_HEADERS) $(PRIVATE_HEADERS) $(OTHER_HEADERS) $(OTHER_SOURCES)
+ $(SILENT) $(TAR) -cf $(SRCROOT)/objc4.sources.tar $(SOURCES) $(PUBLIC_HEADERS) $(PRIVATE_HEADERS) $(OTHER_HEADERS) $(OTHER_SOURCES) $(MODULE_SOURCES)
$(SILENT) $(CD) $(SRCROOT) && $(TAR) -xf $(SRCROOT)/objc4.sources.tar
$(SILENT) $(REMOVE) -f $(SRCROOT)/objc4.sources.tar
@@ -325,8 +384,14 @@ install: build installhdrs
clean:
$(SILENT) $(ECHO) "Deleting build products..."
- $(foreach A, $(ARCH_LIST), \
- $(SILENT) $(REMOVE) -f $(OBJROOT)/libobjc_debug.$A.o $(OBJROOT)/libobjc_profile.$A.o $(OBJROOT)/libobjc.$A.o ; )
+ $(SILENT) $(REMOVE) -f \
+ $(foreach A, $(ARCH_LIST), \
+ $(OBJROOT)/libobjc_debug.$A.$(VERSION_NAME)$(LIBRARY_EXT) \
+ $(OBJROOT)/libobjc_profile.$A.$(VERSION_NAME)$(LIBRARY_EXT) \
+ $(OBJROOT)/libobjc.$A.$(VERSION_NAME)$(LIBRARY_EXT) \
+ $(OBJROOT)/runtime/objc-rtp-sym.$A.o \
+ $(OBJROOT)/runtime/objc-rtp-sym.$A.o.temp \
+ )
$(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc.optimized.o
$(SILENT) $(REMOVE) -f $(SYMROOT)/libobjc.debug.o
@@ -340,6 +405,10 @@ clean:
$(SILENT) $(REMOVE) -f $(OBJECTS_DEBUG)
$(SILENT) $(REMOVE) -f $(OBJECTS_PROFILE)
+ $(SILENT) $(REMOVE) -f $(MODULE_OBJECTS_OPTIMIZED)
+ $(SILENT) $(REMOVE) -f $(MODULE_OBJECTS_DEBUG)
+ $(SILENT) $(REMOVE) -f $(MODULE_OBJECTS_PROFILE)
+
$(SILENT) $(REMOVE) -rf $(SYMROOT)/ProjectHeaders
prebuild:
@@ -376,24 +445,33 @@ prebuild-profile:
$(SILENT) $(MKDIRS) $(foreach S, $(SUBDIRS), $(OBJROOT)/$(S) )
-compile-optimized: $(OBJECTS_OPTIMIZED)
-compile-debug: $(OBJECTS_DEBUG)
-compile-profile: $(OBJECTS_PROFILE)
+compile-optimized: $(OBJECTS_OPTIMIZED) $(MODULE_OBJECTS_OPTIMIZED) $(foreach A, $(ARCH_LIST), $(OBJROOT)/runtime/objc-rtp-sym.$A.o )
+compile-debug: $(OBJECTS_DEBUG) $(MODULE_OBJECTS_DEBUG) $(foreach A, $(ARCH_LIST), $(OBJROOT)/runtime/objc-rtp-sym.$A.o )
+compile-profile: $(OBJECTS_PROFILE) $(MODULE_OBJECTS_PROFILE) $(foreach A, $(ARCH_LIST), $(OBJROOT)/runtime/objc-rtp-sym.$A.o )
-# link lib-suffix, LDFLAGS, OBJECTS
+# link lib-suffix, LDFLAGS, OBJECTS, MODULE_OBJECTS
# libsuffix should be "" or _debug or _profile
ifeq "$(PLATFORM)" "Darwin"
define link
- $(SILENT) $(CC) $2 \
- -Wl,-init,__objcInit \
- -Wl,-single_module \
- -Wl,-exported_symbols_list,$(SRCROOT)/objc-exports \
- -Wl,-sectorder,__TEXT,__text,$(SRCROOT)/libobjc.order \
- -install_name /$(INSTALLDIR)/libobjc$1.$(VERSION_NAME)$(LIBRARY_EXT) \
- -o $(SYMROOT)/libobjc$1.$(VERSION_NAME)$(LIBRARY_EXT) \
- $3
+ $(foreach A, $(ARCH_LIST), \
+ $(SILENT) $(LD) -r \
+ -arch $A \
+ -o $(OBJROOT)/libobjc$1.$A.o \
+ $3 ; \
+ $(SILENT) $(CC) $2 \
+ -arch $A \
+ -Wl,-exported_symbols_list,$(SRCROOT)/objc-exports \
+ $(ORDER) \
+ -sectcreate __DATA __commpage $(OBJROOT)/runtime/objc-rtp-sym.$A.o \
+ -install_name /$(INSTALLDIR)/libobjc$1.$(VERSION_NAME)$(LIBRARY_EXT) \
+ -o $(OBJROOT)/libobjc$1.$A.$(VERSION_NAME)$(LIBRARY_EXT) \
+ $(OBJROOT)/libobjc$1.$A.o $4 ; \
+ )
+ $(SILENT) $(LIPO) \
+ -create -output $(SYMROOT)/libobjc$1.$(VERSION_NAME)$(LIBRARY_EXT) \
+ $(foreach A, $(ARCH_LIST), -arch $A $(OBJROOT)/libobjc$1.$A.$(VERSION_NAME)$(LIBRARY_EXT) )
endef
else
@@ -407,15 +485,15 @@ endif
link-optimized:
$(SILENT) $(ECHO) "Linking (optimized)..."
- $(call link,,$(LDFLAGS_OPTIMIZED),$(OBJECTS_OPTIMIZED) )
+ $(call link,,$(LDFLAGS_OPTIMIZED),$(OBJECTS_OPTIMIZED),$(MODULE_OBJECTS_OPTIMIZED) )
link-debug:
$(SILENT) $(ECHO) "Linking (debug)..."
- $(call link,_debug,$(LDFLAGS_DEBUG),$(OBJECTS_DEBUG) )
+ $(call link,_debug,$(LDFLAGS_DEBUG),$(OBJECTS_DEBUG),$(MODULE_OBJECTS_DEBUG) )
link-profile:
$(SILENT) $(ECHO) "Linking (profile)..."
- $(call link,_profile,$(LDFLAGS_PROFILE),$(OBJECTS_PROFILE))
+ $(call link,_profile,$(LDFLAGS_PROFILE),$(OBJECTS_PROFILE),$(MODULE_OBJECTS_PROFILE) )
postbuild:
View
162 libobjc.order
@@ -1,162 +0,0 @@
-# objc4 order file
-# Updated August 2003 (Panther)
-# Start with automatic order file, then:
-# 1. move or add _objc_msgSendNonNil immediately after _objc_msgSend
-# 2. move or add _objc_msgSendNonNil_stret immediately after _objc_msgSend_stret
-# msgSend and msgSendNonNil must not be separated by the linker.
-libobjc.o:_objc_msgSend
-libobjc.o:_objc_msgSendNonNil
-libobjc.o:_objc_msgSend_stret
-libobjc.o:_objc_msgSendNonNil_stret
-libobjc.o:__class_lookupMethodAndLoadCache
-libobjc.o:__cache_fill
-libobjc.o:__internal_object_dispose
-libobjc.o:___sel_registerName
-libobjc.o:__cache_getMethod
-libobjc.o:__internal_class_createInstanceFromZone
-libobjc.o:__cache_getImp
-libobjc.o:_objc_msgSendSuper
-libobjc.o:__objc_search_builtins
-libobjc.o:_sel_registerNameNoCopyNoLock
-libobjc.o:_NXHashGet
-libobjc.o:_class_respondsToMethod
-libobjc.o:_object_getClassName
-libobjc.o:_objc_getClass
-libobjc.o:__objc_getFreedObjectClass
-libobjc.o:__objc_fixup_selector_refs
-libobjc.o:_class_lookupMethod
-libobjc.o:_NXNextHashState
-libobjc.o:_class_poseAs
-libobjc.o:_classIsEqual
-libobjc.o:_classHash
-libobjc.o:__objcTweakMethodListPointerForClass
-libobjc.o:_class_initialize
-libobjc.o:_objc_lookUpClass
-libobjc.o:-[Protocol conformsTo:]
-libobjc.o:__objc_create_zone
-libobjc.o:_NXHashInsert
-libobjc.o:__objc_add_classes_from_image
-libobjc.o:__cache_collect_free
-libobjc.o:__objc_hash_selector
-libobjc.o:__class_install_relationships
-libobjc.o:__objc_register_category
-libobjc.o:__mapStrIsEqual
-libobjc.o:__cache_malloc
-libobjc.o:__cache_expand
-libobjc.o:_objc_msgSendSuper_stret
-libobjc.o:_NXMapInsert
-libobjc.o:__fetchInitializingClassList
-libobjc.o:__NXMapMember
-libobjc.o:_map_method_descs
-libobjc.o:__mapStrHash
-libobjc.o:__objc_call_loads_for_image
-libobjc.o:_objc_getClassList
-libobjc.o:__objc_equal_selector
-libobjc.o:__cache_addForwardEntry
-libobjc.o:_NXMapGet
-libobjc.o:__objc_checkForPendingClassReferences
-libobjc.o:_NXMapRemove
-libobjc.o:_get_base_method_list
-libobjc.o:__objc_resolve_categories_for_class
-libobjc.o:__objc_insertMethods
-libobjc.o:_sel_lock
-libobjc.o:_sel_unlock
-libobjc.o:__cache_create
-libobjc.o:__thisThreadIsInitializingClass
-libobjc.o:__garbage_make_room
-libobjc.o:__objcInit
-libobjc.o:__objc_map_class_refs_for_image
-libobjc.o:_class_lookupNamedMethodInMethodList
-libobjc.o:_sel_registerName
-libobjc.o:__collecting_in_critical
-libobjc.o:__objc_add_categories_from_image
-libobjc.o:+[Object alloc]
-libobjc.o:__setThisThreadIsInitializingClass
-libobjc.o:__setThisThreadIsNotInitializingClass
-libobjc.o:_NXUniqueString
-libobjc.o:_NXStrIsEqual
-libobjc.o:__get_pc_for_thread
-libobjc.o:__objc_map_image
-libobjc.o:__objc_addHeader
-libobjc.o:-[Object init]
-libobjc.o:__objc_fixup_protocol_objects_for_image
-libobjc.o:__objc_bindClassIfNeeded
-libobjc.o:_class_getInstanceMethod
-libobjc.o:_NXStrHash
-libobjc.o:-[Object free]
-libobjc.o:__getObjcModules
-libobjc.o:__getObjcImageInfo
-libobjc.o:_class_getVariable
-libobjc.o:-[Protocol descriptionForInstanceMethod:]
-libobjc.o:__NXMapRehash
-libobjc.o:__internal_object_copyFromZone
-libobjc.o:_NXPtrHash
-libobjc.o:__NXHashRehash
-libobjc.o:__getObjcClassRefs
-libobjc.o:_sel_getName
-libobjc.o:_CopyIntoReadOnly
-libobjc.o:_hashPrototype
-libobjc.o:_lookup_method
-libobjc.o:_class_nextMethodList
-libobjc.o:__objc_addOrigClass
-libobjc.o:_NXHashRemove
-libobjc.o:_objc_msgSendv
-libobjc.o:__objc_msgForward
-libobjc.o:-[Object class]
-libobjc.o:+[Object name]
-libobjc.o:_objc_getOrigClass
-libobjc.o:_object_setInstanceVariable
-libobjc.o:_NXCreateHashTableFromZone
-libobjc.o:_hashPrototype
-libobjc.o:__objc_add_category_flush_caches
-libobjc.o:-[Object perform:with:with:]
-libobjc.o:__objc_defaultClassHandler
-libobjc.o:_class_getInstanceVariable
-libobjc.o:_freeBuckets
-libobjc.o:_freeBucketPairs
-libobjc.o:_NXNoEffectFree
-libobjc.o:__getObjcHeaderData
-libobjc.o:__getObjcMessageRefs
-libobjc.o:_NXCreateMapTableFromZone
-libobjc.o:_flush_caches
-libobjc.o:_objc_msgSendv_stret
-libobjc.o:-[Object respondsTo:]
-libobjc.o:-[Object perform:]
-libobjc.o:-[Object self]
-libobjc.o:+[Object class]
-libobjc.o:-[Object isMemberOf:]
-libobjc.o:__objc_init_class_hash
-libobjc.o:_bootstrap
-libobjc.o:_isEqualPrototype
-libobjc.o:_NXInitHashState
-libobjc.o:_log2
-libobjc.o:_exp2m1
-libobjc.o:_objc_setConfiguration
-libobjc.o:_NXCreateHashTable
-libobjc.o:_log2
-libobjc.o:__objc_fixup_string_objects_for_image
-libobjc.o:__getObjcStringObjects
-libobjc.o:__getObjcProtocols
-libobjc.o:+[Object initialize]
-libobjc.o:+[Protocol _fixup:numElements:]
-libobjc.o:__objc_flush_caches
-libobjc.o:+[Protocol load]
-libobjc.o:__getObjcHeaders
-libobjc.o:_objc_exception_set_functions
-libobjc.o:_isEqualPrototype
-libobjc.o:_objc_getClasses
-libobjc.o:_addClassToOriginalClass
-libobjc.o:__mapPtrHash
-libobjc.o:_objc_setMultithreaded
-libobjc.o:__objc_unmap_image
-libobjc.o:__objc_fatalHeader
-libobjc.o:__objc_headerStart
-libobjc.o:__mapPtrIsEqual
-libobjc.o:_lookup_instance_method
-libobjc.o:_NXCountHashTable
-libobjc.o:_objc_pendClassReference
-libobjc.o:__objc_getNonexistentClass
-libobjc.o:__cache_flush
-libobjc.o:__objc_pthread_destroyspecific
-libobjc.o:__destroyInitializingClassList
-libobjc.o:_objc_loadModule
View
22 objc-exports
@@ -21,6 +21,25 @@ _method_getNumberOfArguments
_method_getSizeOfArguments
_method_getArgumentInfo
_class_nextMethodList
+# objc-auto.h - actually, everything possible for now
+_objc_collect
+_objc_collect_generation
+_objc_numberAllocated
+_objc_isAuto
+_objc_collecting_enabled
+_objc_allocate_object
+_objc_assign_strongCast
+_objc_assign_global
+_objc_assign_ivar
+_objc_assign_strongCast_generic
+_objc_assign_global_generic
+_objc_assign_ivar_generic
+_objc_assign_strongCast_CF
+_objc_assign_ivar_address_CF
+_objc_collect_init
+_objc_is_finalized
+_objc_memmove_collectable
+_objc_collect_if_needed
# objc-exception.h
_objc_exception_throw
_objc_exception_try_enter
@@ -54,6 +73,7 @@ _objc_msgSendv_stret
_objc_getClassList
_objc_getClasses
_objc_lookUpClass
+_objc_getRequiredClass
_objc_addClass
_objc_setClassHandler
_objc_setMultithreaded
@@ -162,4 +182,4 @@ _do_not_remove_this_dummy_function
# used by debugging tools like heap
__objc_debug_class_hash
# used by Foundation's NSAutoreleaseFreedObjectCheckEnabled
-__objc_getFreedObjectClass
+__objc_getFreedObjectClass
View
26 runtime/Auto.subproj/objc-auto-i386.s
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * 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@
+ */
+
+#warning Intel version needs to be implemented.
View
69 runtime/Auto.subproj/objc-auto-ppc.s
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * 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 section includes declarations of routines that will be used to populate
+ ; the runtime pages during auto initialization. Each wb_routine definition
+ ; creates an absolute branch into the rtp plus a non-gc version of code for
+ ; non collecting apps. Note - the blr is necessary at the end of the non-gc
+ ; routine for code copying to behave correctly.
+ ;
+
+#undef OBJC_ASM
+#define OBJC_ASM
+#include "objc-rtp.h"
+
+ .macro wb_routine
+ .globl _$0 ; primary entry name
+; .abs _abs_$0,kRTAddress_$0
+_$0: ; primary entry point
+ ba $1 ; branch to runtime page
+
+ .globl _$0_non_gc ; non_gc entry point name
+_$0_non_gc: ; non_gc entry point
+ .endmacro
+
+ .text
+
+// note - unfortunately ba does not accept constant expressions
+
+ ; non-gc routines
+
+ ; id objc_assign_strongCast(id value, id *dest)
+ wb_routine objc_assign_strongCast,0xfffefea0
+ stw r3,0(r4) ; store value at dest
+ blr ; return
+
+ ; id objc_assign_global(id value, id *dest)
+ wb_routine objc_assign_global,0xfffefeb0
+ stw r3,0(r4) ; store value at dest
+ blr ; return
+
+ ; id objc_assign_ivar(id value, id dest, unsigned int offset)
+ wb_routine objc_assign_ivar,0xfffefec0
+ stwx r3,r4,r5 ; store value at (dest+offset)
+ blr ; return
+
View
32 runtime/Auto.subproj/objc-auto.s
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. 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 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
+ * License at http://www.apple.com/publicsource 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 OR NON- INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+#if defined (__i386__) || defined (i386)
+ #include "objc-auto-i386.s"
+#elif defined (__ppc__) || defined(ppc)
+ #include "objc-auto-ppc.s"
+#else
+ #error Architecture not supported
+#endif
View
126 runtime/Messengers.subproj/objc-msg-i386.s
@@ -36,8 +36,11 @@
// assembler is fixed we have to find another way.
#define NO_MACRO_CONSTS
#ifdef NO_MACRO_CONSTS
+ kOne = 1
kTwo = 2
+ kFour = 4
kEight = 8
+ kTwelve = 12
#endif
/********************************************************************
@@ -77,6 +80,21 @@ _objc_exitPoints:
.long LMsgSendSuperStretExit
.long 0
+
+#if defined(__DYNAMIC__)
+
+/*
+ * Thunk to retrieve PC.
+ * `call 1; 1: pop` sequence breaks any branch-prediction stack.
+ */
+
+.align 4, 0x90
+L_get_pc_thunk.edx:
+ movl (%esp,1), %edx
+ ret
+
+#endif
+
/*
* Handcrafted dyld stubs for each external call.
* They should be converted into a local branch after linking. aB.
@@ -94,15 +112,15 @@ _objc_exitPoints:
.picsymbol_stub ;\
L ## name ## $stub: ;\
.indirect_symbol name ;\
- call L0$ ## name ;\
+ call L_get_pc_thunk.edx ;\
L0$ ## name: ;\
- popl %eax ;\
- movl L ## name ## $lz-L0$ ## name(%eax),%edx ;\
- jmp %edx ;\
+ movl L ## name ## $lz-L0$ ## name(%edx),%ecx ;\
+ jmp %ecx ;\
L ## name ## $stub_binder: ;\
- lea L ## name ## $lz-L0$ ## name(%eax),%eax ;\
+ lea L ## name ## $lz-L0$ ## name(%edx),%eax ;\
pushl %eax ;\
jmp dyld_stub_binding_helper ;\
+ nop ;\
.data ;\
.lazy_symbol_pointer ;\
L ## name ## $lz: ;\
@@ -226,8 +244,8 @@ EXTERNAL_SYMBOL = 1
.macro LOAD_STATIC_WORD
#if defined(__DYNAMIC__)
- call 1f
-1: popl %edx
+ call L_get_pc_thunk.edx
+1:
.if $2 == EXTERNAL_SYMBOL
movl L$1-1b(%edx),$0
movl 0($0),$0
@@ -258,8 +276,8 @@ EXTERNAL_SYMBOL = 1
.macro LEA_STATIC_DATA
#if defined(__DYNAMIC__)
- call 1f
-1: popl %edx
+ call L_get_pc_thunk.edx
+1:
.if $2 == EXTERNAL_SYMBOL
movl L$1-1b(%edx),$0
.elseif $2 == LOCAL_SYMBOL
@@ -410,7 +428,7 @@ CACHE_GET = 2 // first argument is class, search that class
// search the receiver's cache
LMsgSendProbeCache_$0_$1_$2:
#if defined(OBJC_INSTRUMENTED)
- inc %ebx // probeCount += 1
+ addl $kOne, %ebx // probeCount += 1
#endif
andl %esi, %edx // index &= mask
movl (%edi, %edx, 4), %eax // method = buckets[index]
@@ -419,7 +437,7 @@ LMsgSendProbeCache_$0_$1_$2:
je LMsgSendCacheMiss_$0_$1_$2 // go to cache miss code
cmpl method_name(%eax), %ecx // check for method name match
je LMsgSendCacheHit_$0_$1_$2 // go handle cache hit
- inc %edx // bump index ...
+ addl $kOne, %edx // bump index ...
jmp LMsgSendProbeCache_$0_$1_$2 // ... and loop
// not found in cache: restore state and go to callers handler
@@ -431,7 +449,7 @@ LMsgSendCacheMiss_$0_$1_$2:
je LMsgSendMissInstrumentDone_$0_$1_$2 // ... emptyCache, do not record anything
// locate and update the CacheInstrumentation structure
- inc %esi // entryCount = mask + 1
+ addl $kOne, %esi // entryCount = mask + 1
#ifdef NO_MACRO_CONSTS
shll $kTwo, %esi // tableSize = entryCount * sizeof(entry)
#else
@@ -441,7 +459,7 @@ LMsgSendCacheMiss_$0_$1_$2:
addl %edx, %esi // cacheData = &cache->buckets[mask+1]
movl missCount(%esi), %edi //
- inc %edi //
+ addl $kOne, %edi //
movl %edi, missCount(%esi) // cacheData->missCount += 1
movl missProbes(%esi), %edi //
addl %ebx, %edi //
@@ -465,7 +483,7 @@ LMsgSendMissHistoIndexSet_$0_$1_$2:
#endif
addl %ebx, %esi // calculate &CacheMissHistogram[probeCount<<2]
movl 0(%esi), %edi // get current tally
- inc %edi //
+ addl $kOne, %edi //
movl %edi, 0(%esi) // tally += 1
LMsgSendMissInstrumentDone_$0_$1_$2:
popl %ebx // restore non-volatile register
@@ -520,7 +538,7 @@ LMsgSendCacheHit_$0_$1_$2:
je LMsgSendHitInstrumentDone_$0_$1_$2 // ... emptyCache, do not record anything
// locate and update the CacheInstrumentation structure
- inc %esi // entryCount = mask + 1
+ addl $kOne, %esi // entryCount = mask + 1
#ifdef NO_MACRO_CONSTS
shll $kTwo, %esi // tableSize = entryCount * sizeof(entry)
#else
@@ -530,7 +548,7 @@ LMsgSendCacheHit_$0_$1_$2:
addl %edx, %esi // cacheData = &cache->buckets[mask+1]
movl hitCount(%esi), %edi
- inc %edi
+ addl $kOne, %edi
movl %edi, hitCount(%esi) // cacheData->hitCount += 1
movl hitProbes(%esi), %edi
addl %ebx, %edi
@@ -554,7 +572,7 @@ LMsgSendHitHistoIndexSet_$0_$1_$2:
#endif
addl %ebx, %esi // calculate &CacheHitHistogram[probeCount<<2]
movl 0(%esi), %edi // get current tally
- inc %edi //
+ addl $kOne, %edi //
movl %edi, 0(%esi) // tally += 1
LMsgSendHitInstrumentDone_$0_$1_$2:
popl %ebx // restore non-volatile register
@@ -598,21 +616,28 @@ LMsgSendHitInstrumentDone_$0_$1_$2:
// MSG_SEND (first parameter is receiver)
// MSG_SENDSUPER (first parameter is address of objc_super structure)
//
+// Stack must be at 0xXXXXXXXc on entrance.
+//
// On exit: Register parameters restored from CacheLookup
// imp in eax
//
/////////////////////////////////////////////////////////////////////
.macro MethodTableLookup
+#ifdef NO_MACRO_CONSTS
+ subl $kFour, %esp // 16-byte align the stack
+#else
+ subl $4, %esp // 16-byte align the stack
+#endif
// push args (class, selector)
pushl %ecx
pushl %eax
CALL_EXTERN(__class_lookupMethodAndLoadCache)
#ifdef NO_MACRO_CONSTS
- addl $kEight, %esp // pop parameters
+ addl $kTwelve, %esp // pop parameters and alignment
#else
- addl $8, %esp // pop parameters
+ addl $12, %esp // pop parameters and alignment
#endif
.endmacro
@@ -712,9 +737,8 @@ LMsgSendCacheMiss:
// message sent to nil: redirect to nil receiver, if any
LMsgSendNilSelf:
- call 1f // load new receiver
-1: popl %edx
- movl __objc_nilReceiver-1b(%edx),%eax
+ call L_get_pc_thunk.edx // load new receiver
+1: movl __objc_nilReceiver-1b(%edx),%eax
testl %eax, %eax // return nil if no new receiver
je LMsgSendDone
movl %eax, self(%esp) // send to new receiver
@@ -781,9 +805,18 @@ LMsgSendSuperExit:
movl (marg_list+4)(%ebp), %edx
addl $8, %edx // skip self & selector
movl (marg_size+4)(%ebp), %ecx
- subl $5, %ecx // skip self & selector
+ subl $8, %ecx // skip self & selector
shrl $2, %ecx
- jle LMsgSendvArgsOK
+ je LMsgSendvArgsOK
+
+ // %esp = %esp - (16 - ((numVariableArguments && 3) << 2))
+ movl %ecx, %eax // 16-byte align stack
+ andl $3, %eax
+ shll $2, %eax
+ neg %eax
+ addl $16, %eax
+ subl %eax, %esp
+
LMsgSendvArgLoop:
decl %ecx
movl 0(%edx, %ecx, 4), %eax
@@ -841,9 +874,8 @@ LMsgSendStretCacheMiss:
// message sent to nil: redirect to nil receiver, if any
LMsgSendStretNilSelf:
- call 1f // load new receiver
-1: popl %edx
- movl __objc_nilReceiver-1b(%edx),%eax
+ call L_get_pc_thunk.edx // load new receiver
+1: movl __objc_nilReceiver-1b(%edx),%eax
testl %eax, %eax // return nil if no new receiver
je LMsgSendStretDone
movl %eax, self_stret(%esp) // send to new receiver
@@ -928,6 +960,13 @@ LMsgSendSuperStretExit:
subl $5, %ecx // skip self & selector
shrl $2, %ecx
jle LMsgSendvStretArgsOK
+
+ movl %ecx, %eax // 16-byte align stack
+ andl $3, %eax
+ shll $2, %eax
+ subl $12, %esp
+ addl %eax, %esp
+
LMsgSendvStretArgLoop:
decl %ecx
movl 0(%edx, %ecx, 4), %eax
@@ -983,19 +1022,19 @@ LUnkSelStr: .ascii "Does not recognize selector %s\0"
// non-stret version ...
pushl %ebp
movl %esp,%ebp
- movl (selector+4)(%esp), %eax
+ movl (selector+4)(%ebp), %eax
#if defined(__DYNAMIC__)
- call L__objc_msgForward$pic_base
+ call L_get_pc_thunk.edx
L__objc_msgForward$pic_base:
- popl %edx
leal LFwdSel-L__objc_msgForward$pic_base(%edx),%ecx
cmpl %ecx, %eax
#else
cmpl LFwdSel, %eax
#endif
je LMsgForwardError
- leal (self+4)(%esp), %ecx
+ subl $8, %esp // 16-byte align the stack
+ leal (self+4)(%ebp), %ecx
pushl %ecx
pushl %eax
#if defined(__DYNAMIC__)
@@ -1004,7 +1043,7 @@ L__objc_msgForward$pic_base:
movl LFwdSel,%ecx
#endif
pushl %ecx
- pushl (self+16)(%esp)
+ pushl (self+4)(%ebp)
call _objc_msgSend
movl %ebp,%esp
popl %ebp
@@ -1013,6 +1052,7 @@ L__objc_msgForward$pic_base:
// call error handler with unrecognized selector message
.align 4, 0x90
LMsgForwardError:
+ subl $12, %esp // 16-byte align the stack
#if defined(__DYNAMIC__)
leal LFwdSel-L__objc_msgForward$pic_base(%edx),%eax
pushl %eax
@@ -1022,7 +1062,7 @@ LMsgForwardError:
pushl $LFwdSel
pushl $LUnkSelStr
#endif
- pushl (self+12)(%esp)
+ pushl (self+4)(%ebp)
CALL_EXTERN(___objc_error) // volatile, will not return
// ***** Stret version of function below
@@ -1032,20 +1072,20 @@ LMsgForwardError:
LForwardStretVersion:
pushl %ebp
movl %esp,%ebp
- movl (selector_stret+4)(%esp), %eax
+ movl (selector_stret+4)(%ebp), %eax
#if defined(__DYNAMIC__)
- call L__objc_msgForwardStret$pic_base
+ call L_get_pc_thunk.edx
L__objc_msgForwardStret$pic_base:
- popl %edx
leal LFwdSel-L__objc_msgForwardStret$pic_base(%edx),%ecx
cmpl %ecx, %eax
#else
cmpl LFwdSel, %eax
#endif
je LMsgForwardStretError
- leal (self_stret+4)(%esp), %ecx
+ subl $8, %esp // 16-byte align the stack
+ leal (self_stret+4)(%ebp), %ecx
pushl %ecx
pushl %eax
#if defined(__DYNAMIC__)
@@ -1054,7 +1094,7 @@ L__objc_msgForwardStret$pic_base:
movl LFwdSel,%ecx
#endif
pushl %ecx
- pushl (self_stret+16)(%esp)
+ pushl (self_stret+4)(%ebp)
call _objc_msgSend
movl %ebp,%esp
popl %ebp
@@ -1063,6 +1103,7 @@ L__objc_msgForwardStret$pic_base:
// call error handler with unrecognized selector message
.align 4, 0x90
LMsgForwardStretError:
+ subl $12, %esp // 16-byte align the stack
#if defined(__DYNAMIC__)
leal LFwdSel-L__objc_msgForwardStret$pic_base(%edx),%eax
pushl %eax
@@ -1072,9 +1113,16 @@ LMsgForwardStretError:
pushl $LFwdSel
pushl $LUnkSelStr
#endif
- pushl (self_stret+12)(%esp)
+ pushl (self_stret+4)(%ebp)
CALL_EXTERN(___objc_error) // volatile, will not return
#endif /* defined (KERNEL) */
END_ENTRY __objc_msgForward
+
+// Special section containing a function pointer that dyld will call
+// when it loads new images.
+LAZY_PIC_FUNCTION_STUB(__objc_notify_images)
+.data
+.section __DATA,__image_notify
+.long L__objc_notify_images$stub
View
239 runtime/Messengers.subproj/objc-msg-ppc.s
@@ -58,6 +58,10 @@
* 31-Dec-96 Umesh Vaishampayan (umeshv@NeXT.com)
* Created from m98k.
********************************************************************/
+
+#undef OBJC_ASM
+#define OBJC_ASM
+#include "objc-rtp.h"
/********************************************************************
* Data used by the ObjC runtime.
@@ -84,6 +88,7 @@ _objc_entryPoints:
.long _objc_msgSend_stret
.long _objc_msgSendSuper
.long _objc_msgSendSuper_stret
+ .long _objc_msgSend_rtp
.long 0
.globl _objc_exitPoints
@@ -94,6 +99,7 @@ _objc_exitPoints:
.long LMsgSendStretExit
.long LMsgSendSuperExit
.long LMsgSendSuperStretExit
+ .long _objc_msgSend_rtp_exit
.long 0
/*
@@ -199,6 +205,7 @@ LAZY_PIC_FUNCTION_STUB(mcount)
#define kFwdMsgSend 1
#define kFwdMsgSendStret 0
+
/********************************************************************
*
* Useful macros. Macros are used instead of subroutines, for speed.
@@ -362,41 +369,20 @@ $0:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
-; CacheLookup WORD_RETURN | STRUCT_RETURN, MSG_SEND | MSG_SENDSUPER | CACHE_GET, cacheMissLabel
+; CacheLookup selectorRegister, cacheMissLabel
;
; Locate the implementation for a selector in a class method cache.
;
-; Takes: WORD_RETURN (r3 is first parameter)
-; STRUCT_RETURN (r3 is structure return address, r4 is first parameter)
-; MSG_SEND (first parameter is receiver)
-; MSG_SENDSUPER (first parameter is address of objc_super structure)
-; CACHE_GET (first parameter is class; return method triplet)
-;
-; cacheMissLabel = label to branch to iff method is not cached
+; Takes:
+; $0 = register containing selector (r4 or r5 ONLY);
+; cacheMissLabel = label to branch to iff method is not cached
+; r12 = class whose cache is to be searched
;
-; Eats: r0, r11, r12
-; On exit: (found) MSG_SEND and MSG_SENDSUPER: return imp in r12 and ctr
-; (found) CACHE_GET: return method triplet in r12
+; On exit: (found) method triplet in r2, imp in r12, r11 is non-zero
; (not found) jumps to cacheMissLabel
;
-; For MSG_SEND and MSG_SENDSUPER, the messenger jumps to the imp
-; in ctr. The same imp in r12 is used by the method itself for its
-; relative addressing. This saves the usual "jump to next line and
-; fetch link register" construct inside the method.
-;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; Values to specify to method lookup macros whether the return type of
-; the method is an integer or structure.
-#define WORD_RETURN 0
-#define STRUCT_RETURN 1
-
-; Values to specify to method lookup macros whether the return type of
-; the method is an integer or structure.
-#define MSG_SEND 0
-#define MSG_SENDSUPER 1
-#define CACHE_GET 2
-
.macro CacheLookup
#if defined(OBJC_INSTRUMENTED)
@@ -406,55 +392,22 @@ $0:
li r7,0 ; no probes so far!
#endif
-.if $1 == CACHE_GET ; Only WORD_RETURN applies
- lwz r12,CACHE(r3) ; cache = class->cache (class = 1st parameter)
-.else
-
-.if $0 == WORD_RETURN ; WORD_RETURN
-
-.if $1 == MSG_SEND ; MSG_SEND
- lwz r12,ISA(r3) ; class = receiver->isa
-.elseif $1 == MSG_SENDSUPER ; MSG_SENDSUPER
- lwz r12,CLASS(r3) ; class = super->class
-.else
- trap ; Should not happen
-.endif
-
-.else ; STRUCT_RETURN
-
-.if $1 == MSG_SEND ; MSG_SEND
- lwz r12,ISA(r4) ; class = receiver->isa
-.elseif $1 == MSG_SENDSUPER ; MSG_SENDSUPER
- lwz r12,CLASS(r4) ; class = super->class
-.else
- trap ; Should not happen
-.endif
-
-.endif
-
- lwz r12,CACHE(r12) ; cache = class->cache
-
-.endif ; CACHE_GET
-
+ lwz r2,CACHE(r12) ; cache = class->cache
stw r9,48(r1) ; save r9
#if defined(OBJC_INSTRUMENTED)
- mr r6,r12 ; save cache pointer
+ mr r6,r2 ; save cache pointer
#endif
- lwz r11,MASK(r12) ; mask = cache->mask
- addi r9,r12,BUCKETS ; buckets = cache->buckets
+ lwz r11,MASK(r2) ; mask = cache->mask
+ addi r0,r2,BUCKETS ; buckets = cache->buckets
slwi r11,r11,2 ; r11 = mask << 2
-.if $0 == WORD_RETURN ; WORD_RETURN
- and r12,r4,r11 ; bytes = sel & (mask<<2)
-.else ; STRUCT_RETURN
- and r12,r5,r11 ; bytes = sel & (mask<<2)
-.endif
+ and r9,$0,r11 ; bytes = sel & (mask<<2)
#if defined(OBJC_INSTRUMENTED)
- b LLoop_$0_$1_$2
+ b LLoop_$0_$1
-LMiss_$0_$1_$2:
+LMiss_$0_$1:
; r6 = cache, r7 = probeCount
lwz r9,MASK(r6) ; entryCount = mask + 1
addi r9,r9,1 ;
@@ -475,43 +428,32 @@ LMiss_$0_$1_$2:
lwz r6,36(r1) ; restore r6
lwz r7,40(r1) ; restore r7
- b $2 ; goto cacheMissLabel
+ b $1 ; goto cacheMissLabel
#endif
; search the cache
-LLoop_$0_$1_$2:
+LLoop_$0_$1:
#if defined(OBJC_INSTRUMENTED)
addi r7,r7,1 ; probeCount += 1
#endif
- lwzx r2,r9,r12 ; method = buckets[bytes/4]
- addi r12,r12,4 ; bytes += 4
+ lwzx r2,r9,r0 ; method = buckets[bytes/4]
+ addi r9,r9,4 ; bytes += 4
cmplwi r2,0 ; if (method == NULL)
#if defined(OBJC_INSTRUMENTED)
- beq LMiss_$0_$1_$2
+ beq- LMiss_$0_$1
#else
- beq $2 ; goto cacheMissLabel
+ beq- $1 ; goto cacheMissLabel
#endif
- lwz r0,METHOD_NAME(r2) ; name = method->method_name
- and r12,r12,r11 ; bytes &= (mask<<2)
-.if $0 == WORD_RETURN ; WORD_RETURN
- cmplw r0,r4 ; if (name != selector)
-.else ; STRUCT_RETURN
- cmplw r0,r5 ; if (name != selector)
-.endif
- bne LLoop_$0_$1_$2 ; goto loop
+ lwz r12,METHOD_NAME(r2) ; name = method->method_name
+ and r9,r9,r11 ; bytes &= (mask<<2)
+ cmplw r12,$0 ; if (name != selector)
+ bne- LLoop_$0_$1 ; goto loop
; cache hit, r2 == method triplet address
-.if $1 == CACHE_GET
- ; return method triplet in r12
- ; N.B. A better way to do this is have CACHE_GET swap the use of r12 and r2.
- mr r12,r2
-.else
- ; return method imp in ctr and r12
- lwz r12,METHOD_IMP(r2) ; imp = method->method_imp (in r12)
- mtctr r12 ; ctr = imp
-.endif
+; Return triplet in r2 and imp in r12
+ lwz r12,METHOD_IMP(r2) ; imp = method->method_imp
#if defined(OBJC_INSTRUMENTED)
; r6 = cache, r7 = probeCount
@@ -592,6 +534,16 @@ LLoop_$0_$1_$2:
; imp in ctr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Values to specify to method lookup macros whether the return type of
+; the method is an integer or structure.
+#define WORD_RETURN 0
+#define STRUCT_RETURN 1
+
+; Values to specify to method lookup macros whether the return type of
+; the method is an integer or structure.
+#define MSG_SEND 0
+#define MSG_SENDSUPER 1
+
.macro MethodTableLookup
mflr r0 ; save lr
stw r0, 8(r1) ;
@@ -803,12 +755,12 @@ LLoop_$0_$1_$2:
CALL_MCOUNT
; do lookup
- CacheLookup WORD_RETURN, CACHE_GET, LGetMethodMiss
+ mr r12,r3 ; move class to r12 for CacheLookup
+ CacheLookup r4, LGetMethodMiss
-; cache hit, method triplet in r12
- lwz r11, METHOD_IMP(r12) ; get the imp
- cmplw r11, r5 ; check for _objc_msgForward
- mr r3, r12 ; optimistically get the return value
+; cache hit, method triplet in r2 and imp in r12
+ cmplw r12, r5 ; check for _objc_msgForward
+ mr r3, r2 ; optimistically get the return value
bnelr ; Not _objc_msgForward, return the triplet address
LGetMethodMiss:
@@ -834,10 +786,11 @@ LGetMethodExit:
CALL_MCOUNT
; do lookup
- CacheLookup WORD_RETURN, CACHE_GET, LGetImpMiss
+ mr r12,r3 ; move class to r12 for CacheLookup
+ CacheLookup r4, LGetImpMiss
-; cache hit, method triplet in r12
- lwz r3, METHOD_IMP(r12) ; return method imp address
+; cache hit, method triplet in r2 and imp in r12
+ mr r3, r12 ; return method imp address
blr
LGetImpMiss:
@@ -858,10 +811,25 @@ LGetImpExit:
* r4 is the selector
********************************************************************/
+; WARNING - This code may be copied as is to the Objective-C runtime pages.
+; The code is copied by rtp_set_up_objc_msgSend() from the
+; beginning to the blr marker just prior to the cache miss code.
+; Do not add callouts, global variable accesses, or rearrange
+; the code without updating rtp_set_up_objc_msgSend.
+
+; Absolute symbols bounding the runtime page version of objc_msgSend.
+_objc_msgSend_rtp = 0xfffeff00
+_objc_msgSend_rtp_exit = 0xfffeff00+0x100
+
+
ENTRY _objc_msgSend
-; check whether receiver is nil
- cmplwi r3,0 ; receiver nil?
- beq- LMsgSendNilSelf ; if so, call handler or return nil
+; check whether receiver is nil or selector is to be ignored
+ cmplwi r3,0 ; receiver nil?
+ xoris r11,r4,((kIgnore>>16) & 0xffff) ; clear hi if equal to ignored
+ cmplwi cr1,r11,(kIgnore & 0xffff) ; selector is to be ignored?
+ beq- LMsgSendNilSelf ; if nil receiver, call handler or return nil
+ lwz r12,ISA(r3) ; class = receiver->isa
+ beqlr- cr1 ; if ignored selector, return self immediately
; guaranteed non-nil entry point (disabled for now)
; .globl _objc_msgSendNonNil
@@ -872,32 +840,51 @@ LGetImpExit:
; receiver is non-nil: search the cache
LMsgSendReceiverOk:
- CacheLookup WORD_RETURN, MSG_SEND, LMsgSendCacheMiss
+ ; class is already in r12
+ CacheLookup r4, LMsgSendCacheMiss
+ ; CacheLookup placed imp in r12
+ mtctr r12
; r11 guaranteed non-zero on exit from CacheLookup with a hit
// li r11,kFwdMsgSend ; indicate word-return to _objc_msgForward
bctr ; goto *imp;
-; cache miss: go search the method lists
-LMsgSendCacheMiss:
- MethodTableLookup WORD_RETURN, MSG_SEND
- li r11,kFwdMsgSend ; indicate word-return to _objc_msgForward
- bctr ; goto *imp;
+; WARNING - The first six instructions of LMsgSendNilSelf are
+; rewritten when objc_msgSend is copied to the runtime pages.
+; These instructions must be maintained AS IS unless the code in
+; rtp_set_up_objc_msgSend is also updated.
+; * `mflr r0` must not be changed (not even to use a different register)
+; * the load of _objc_nilReceiver value must remain six insns long
+; * the value of _objc_nilReceiver must continue to be loaded into r11
; message sent to nil: redirect to nil receiver, if any
LMsgSendNilSelf:
- mflr r0 ; load new receiver
+ ; DO NOT CHANGE THE NEXT SIX INSTRUCTIONS - see note above
+ mflr r0 ; save return address
bcl 20,31,1f ; 31 is cr7[so]
1: mflr r11
addis r11,r11,ha16(__objc_nilReceiver-1b)
lwz r11,lo16(__objc_nilReceiver-1b)(r11)
- mtlr r0
+ mtlr r0 ; restore return address
+ ; DO NOT CHANGE THE PREVIOUS SIX INSTRUCTIONS - see note above
cmplwi r11,0 ; return nil if no new receiver
beqlr
mr r3,r11 ; send to new receiver
+ lwz r12,ISA(r11) ; class = receiver->isa
b LMsgSendReceiverOk
+; WARNING - This blr marks the end of the copy to the ObjC runtime pages and
+; also marks the beginning of the cache miss code. Do not move
+; around without checking the ObjC runtime pages initialization code.
+ blr
+
+; cache miss: go search the method lists
+LMsgSendCacheMiss:
+ MethodTableLookup WORD_RETURN, MSG_SEND
+ li r11,kFwdMsgSend ; indicate word-return to _objc_msgForward
+ bctr ; goto *imp;
+
LMsgSendExit:
END_ENTRY _objc_msgSend
@@ -930,7 +917,10 @@ LMsgSendExit:
; receiver is non-nil: search the cache
LMsgSendStretReceiverOk:
- CacheLookup STRUCT_RETURN, MSG_SEND, LMsgSendStretCacheMiss
+ lwz r12, ISA(r4) ; class = receiver->isa
+ CacheLookup r5, LMsgSendStretCacheMiss
+ ; CacheLookup placed imp in r12
+ mtctr r12
li r11,kFwdMsgSendStret ; indicate struct-return to _objc_msgForward
bctr ; goto *imp;
@@ -974,8 +964,17 @@ LMsgSendStretExit:
; do profiling when enabled
CALL_MCOUNT
+; check whether selector is to be ignored
+ xoris r11,r4,((kIgnore>>16) & 0xffff) ; clear hi if to be ignored
+ cmplwi r11,(kIgnore & 0xffff) ; selector is to be ignored?
+ lwz r12,CLASS(r3) ; class = super->class
+ beq- LMsgSendSuperIgnored ; if ignored, return self
+
; search the cache
- CacheLookup WORD_RETURN, MSG_SENDSUPER, LMsgSendSuperCacheMiss
+ ; class is already in r12
+ CacheLookup r4, LMsgSendSuperCacheMiss
+ ; CacheLookup placed imp in r12
+ mtctr r12
lwz r3,RECEIVER(r3) ; receiver is the first arg
; r11 guaranteed non-zero after cache hit
; li r11,kFwdMsgSend ; indicate word-return to _objc_msgForward
@@ -988,6 +987,11 @@ LMsgSendSuperCacheMiss:
li r11,kFwdMsgSend ; indicate word-return to _objc_msgForward
bctr ; goto *imp;
+; ignored selector: return self
+LMsgSendSuperIgnored:
+ lwz r3,RECEIVER(r3)
+ blr
+
LMsgSendSuperExit:
END_ENTRY _objc_msgSendSuper
@@ -1017,7 +1021,10 @@ LMsgSendSuperExit:
CALL_MCOUNT
; search the cache
- CacheLookup STRUCT_RETURN, MSG_SENDSUPER, LMsgSendSuperStretCacheMiss
+ lwz r12,CLASS(r4) ; class = super->class
+ CacheLookup r5, LMsgSendSuperStretCacheMiss
+ ; CacheLookup placed imp in r12
+ mtctr r12
lwz r4,RECEIVER(r4) ; receiver is the first arg
li r11,kFwdMsgSendStret ; indicate struct-return to _objc_msgForward
bctr ; goto *imp;
@@ -1385,3 +1392,11 @@ LMsgSendvStretSendIt:
#endif /* !KERNEL */
END_ENTRY _objc_msgSendv_stret
+
+
+// Special section containing a function pointer that dyld will call
+// when it loads new images.
+LAZY_PIC_FUNCTION_STUB(__objc_notify_images)
+.data
+.section __DATA,__image_notify
+.long L__objc_notify_images$stub
View
64 runtime/Messengers.subproj/objc-msg-stub-i386.s
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * 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@
+ */
+
+/*
+ * Interposing support.
+ * When OBJC_ALLOW_INTERPOSING is set, calls to objc_msgSend_rtp
+ * jump to the ordinary messenger via this stub. If objc_msgSend
+ * itself is interposed, dyld will find and change this stub.
+ * This stub must be compiled into a separate linker module.
+ */
+
+ .data
+ .align 4, 0x90
+L_get_pc_thunk.edx:
+ movl (%esp,1), %edx
+ ret
+
+ .data
+ .picsymbol_stub
+L_objc_msgSend$stub:
+ .indirect_symbol _objc_msgSend
+ call L_get_pc_thunk.edx
+1:
+ movl L_objc_msgSend$lz-1b(%edx),%ecx
+ jmp %ecx
+L_objc_msgSend$stub_binder:
+ lea L_objc_msgSend$lz-1b(%edx),%eax
+ pushl %eax
+ jmp dyld_stub_binding_helper
+ nop
+
+ .data
+ .lazy_symbol_pointer
+L_objc_msgSend$lz:
+ .indirect_symbol _objc_msgSend
+ .long L_objc_msgSend$stub_binder
+
+ .text
+ .align 4, 0x90
+ .globl _objc_msgSend_stub
+_objc_msgSend_stub:
+ jmp L_objc_msgSend$stub
View
60 runtime/Messengers.subproj/objc-msg-stub-ppc.s
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * 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@
+ */
+
+/*
+ * Interposing support.
+ * When OBJC_ALLOW_INTERPOSING is set, calls to objc_msgSend_rtp
+ * jump to the ordinary messenger via this stub. If objc_msgSend
+ * itself is interposed, dyld will find and change this stub.
+ * This stub must be compiled into a separate linker module.
+ */
+
+ .data
+ .picsymbol_stub
+L_objc_msgSend$stub:
+ .indirect_symbol _objc_msgSend
+ mflr r0
+ bcl 20,31,1f
+1:
+ mflr r11
+ addis r11,r11,ha16(L_objc_msgSend$lazy_ptr-1b)
+ mtlr r0
+ lwz r12,lo16(L_objc_msgSend$lazy_ptr-1b)(r11)
+ mtctr r12
+ addi r11,r11,lo16(L_objc_msgSend$lazy_ptr-1b)
+ bctr
+
+ .data
+ .lazy_symbol_pointer
+L_objc_msgSend$lazy_ptr:
+ .indirect_symbol _objc_msgSend
+ .long dyld_stub_binding_helper
+
+ .text
+ .align 4
+ .globl _objc_msgSend_stub
+
+_objc_msgSend_stub:
+ b L_objc_msgSend$stub
View
35 runtime/Messengers.subproj/objc-msg-stub.s
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * 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@
+ */
+
+#import "../objc-config.h"
+
+#if defined (__i386__) || defined (i386)
+ #include "objc-msg-stub-i386.s"
+#elif defined (__ppc__) || defined(ppc)
+ #include "objc-msg-stub-ppc.s"
+
+#else
+ #error Architecture not supported
+#endif
View
11 runtime/Object.m
@@ -29,6 +29,7 @@
#import <objc/Object.h>
#import "objc-private.h"
+#import <objc/objc-auto.h>
#import <objc/objc-runtime.h>
#import <objc/Protocol.h>
#import <stdarg.h>
@@ -801,7 +802,7 @@ - (struct objc_method_description *) descriptionForMethod:(SEL)aSelector
void *iterator = 0;
int i;
struct objc_method_list *mlist;
- while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
+ while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
for (i = 0; i < mlist->method_count; i++)
if (mlist->method_list[i].method_name == aSelector) {
struct objc_method_description *m;
@@ -851,7 +852,7 @@ + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSelector
void *iterator = 0;
int i;
struct objc_method_list *mlist;
- while ( (mlist = _class_inlinedNextMethodList( cls, &iterator )) ) {
+ while ( (mlist = class_nextMethodList( cls, &iterator )) ) {
for (i = 0; i < mlist->method_count; i++)
if (mlist->method_list[i].method_name == aSelector) {
struct objc_method_description *m;
@@ -934,6 +935,7 @@ static id _internal_object_copy(Object *anObject, unsigned nBytes)
static id _internal_object_dispose(Object *anObject)
{
if (anObject==nil) return nil;
+ object_cxxDestruct((id)anObject);
anObject->isa = _objc_getFreedObjectClass ();
free(anObject);
return nil;
@@ -1010,11 +1012,8 @@ Ivar object_setInstanceVariable(id obj, const char *name, void *value)
Ivar ivar = 0;
if (obj && name) {
- void **ivaridx;
-
if ((ivar = class_getInstanceVariable(((Object*)obj)->isa, name))) {
- ivaridx = (void **)((char *)obj + ivar->ivar_offset);
- *ivaridx = value;
+ objc_assign_ivar((id)value, obj, ivar->ivar_offset);
}
}
return ivar;
View
16 runtime/hashtable2.m
@@ -99,7 +99,7 @@ static uarith_t hashPrototype (const void *info, const void *data) {
hashPrototype, isEqualPrototype, NXNoEffectFree, 0
};
-static NXHashTable *prototypes = NULL;
+static NXHashTable *prototypes NOBSS = NULL;
/* table of all prototypes */
static void bootstrap (void) {
@@ -289,7 +289,11 @@ int NXHashMember (NXHashTable *table, const void *data) {
return NULL;
}
-static void _NXHashRehash (NXHashTable *table) {
+__private_extern__ unsigned _NXHashCapacity (NXHashTable *table) {
+ return table->nbBuckets;
+ }
+
+__private_extern__ void _NXHashRehashToCapacity (NXHashTable *table, unsigned newCapacity) {
/* Rehash: we create a pseudo table pointing really to the old guys,
extend self, copy the old pairs, and free the pseudo table */
NXHashTable *old;
@@ -300,7 +304,7 @@ static void _NXHashRehash (NXHashTable *table) {
old = ALLOCTABLE(z);
old->prototype = table->prototype; old->count = table->count;
old->nbBuckets = table->nbBuckets; old->buckets = table->buckets;
- table->nbBuckets += table->nbBuckets + 1; /* 2 times + 1 */
+ table->nbBuckets = newCapacity;
table->count = 0; table->buckets = ALLOCBUCKETS(z, table->nbBuckets);
state = NXInitHashState (old);
while (NXNextHashState (old, &state, &aux))
@@ -310,7 +314,11 @@ static void _NXHashRehash (NXHashTable *table) {
_objc_syslog("*** hashtable: count differs after rehashing; probably indicates a broken invariant: there are x and y such as isEqual(x, y) is TRUE but hash(x) != hash (y)\n");
free (old->buckets);
free (old);
- };
+ }
+
+static void _NXHashRehash (NXHashTable *table) {
+ _NXHashRehashToCapacity (table, table->nbBuckets*2 + 1);
+ }
void *NXHashInsert (NXHashTable *table, const void *data) {
HashBucket *bucket = BUCKETOF(table, data);
View
59 runtime/objc-auto.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
+ *
+ * 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@
+ */
+/*
+ * objc-auto.h
+ * Copyright 2004 Apple Computer, Inc.
+ */
+
+#ifndef _OBJC_AUTO_H_
+#define _OBJC_AUTO_H_
+
+#import <objc/objc.h>
+#include <sys/types.h>
+
+/* Collection utilities */
+
+enum {
+ OBJC_GENERATIONAL = (1 << 0)
+};
+
+OBJC_EXPORT void objc_collect_if_needed(unsigned long options);
+OBJC_EXPORT unsigned int objc_numberAllocated(void);
+OBJC_EXPORT BOOL objc_collecting_enabled(void);
+
+/* Memory management */
+OBJC_EXPORT id objc_allocate_object(Class cls, int extra);
+
+/* Write barriers */
+OBJC_EXPORT id objc_assign_strongCast(id val, id *dest);
+OBJC_EXPORT id objc_assign_global(id val, id *dest);
+OBJC_EXPORT id objc_assign_ivar(id value, id dest, unsigned int offset);
+OBJC_EXPORT void *objc_memmove_collectable(void *dst, const void *src, size_t size);
+
+/* Testing tools */
+OBJC_EXPORT BOOL objc_is_finalized(void *ptr);
+
+
+#endif
View
1,840 runtime/objc-auto.m
1,840 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
51 runtime/objc-class.h
@@ -65,47 +65,12 @@ struct objc_class {
#define CLS_JAVA_CLASS 0x400L
// thread-safe +initialize
#define CLS_INITIALIZING 0x800
-
-/*
- * (true as of 2001-9-24)
- * Thread-safety note: changes to these flags are not atomic, so
- * the only thing preventing lost updates is the timing of the changes.
- *
- * As long as the following are isolated from each other for any one class,
- * nearly all flag updates will be safe:
- * - compile-time
- * - loading in one thread (not including +load) without messaging
- * - initializing in one thread with messaging from that thread only
- * - multi-threaded messaging with method caching
- *
- * The current code doesn't protect loading yet.
- *
- * Times when the flags may change:
- * CLS_CLASS: compile-time, hand-built classes
- * CLS_META: compile time, hand-built classes
- * CLS_INITIALIZED: initialize
- * CLS_POSING: unsafe, but posing has other thread-safety problems
- * CLS_MAPPED: compile-time
- * CLS_FLUSH_CACHE: messaging
- * CLS_GROW_CACHE: messaging
- * FLUSH_CACHE and GROW_CACHE are protected from each other by the
- * cacheUpdateLock.
- * CLS_NEED_BIND: load, initialize
- * CLS_METHOD_ARRAY: load
- * CLS_JAVA_HYBRID: hand-built classes
- * CLS_JAVA_CLASS: hand-built classes, initialize
- * CLS_INITIALIZING: initialize
- *
- * The only unsafe updates are:
- * - posing (unsafe anyway)
- * - hand-built classes (including JavaBridge classes)
- * There is a short time between objc_addClass inserts the new class
- * into the class_hash and the builder setting the right flags.
- * A thread looking at the class_hash could send a message to the class
- * and trigger initialization, and the changes to the initialization
- * flags and the hand-adjusted flags could collide.
- * Solution: don't do that.
- */
+// bundle unloading
+#define CLS_FROM_BUNDLE 0x1000L
+// C++ ivar support
+#define CLS_HAS_CXX_STRUCTORS 0x2000L
+// Lazy method list arrays
+#define CLS_NO_METHOD_ARRAY 0x4000L
/*
@@ -169,7 +134,11 @@ struct objc_method_list {
/* Protocol support */
+#ifdef __OBJC__
@class Protocol;
+#else
+typedef struct objc_object Protocol;
+#endif
struct objc_protocol_list {
struct objc_protocol_list *next;
View
1,189 runtime/objc-class.m
946 additions, 243 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
3 runtime/objc-exception.m
@@ -41,9 +41,6 @@
static void set_default_handlers();
-extern void objc_raise_error(const char *);
-
-
/*
* Exported functions
*/
View
89 runtime/objc-file.m
@@ -27,17 +27,12 @@
#import "objc-private.h"
#import <mach-o/ldsyms.h>
#import <mach-o/dyld.h>
+#import <mach-o/getsect.h>
#include <string.h>
#include <stdlib.h>
#import <crt_externs.h>
-/* prototype coming soon to <mach-o/getsect.h> */
-extern char *getsectdatafromheader(
- struct mach_header *mhp,
- char *segname,
- char *sectname,
- int *size);
/* Returns an array of all the objc headers in the executable
* Caller is responsible for freeing.
@@ -51,9 +46,9 @@
return (headerType**)headers;
}
-Module _getObjcModules(headerType *head, int *nmodules)
+Module _getObjcModules(const headerType *head, int *nmodules)
{
- unsigned size;
+ uint32_t size;
void *mods = getsectdatafromheader((headerType *)head,
SEG_OBJC,
SECT_OBJC_MODULES,
@@ -64,7 +59,7 @@ Module _getObjcModules(headerType *head, int *nmodules)
SEL *_getObjcMessageRefs(headerType *head, int *nmess)
{
- unsigned size;
+ uint32_t size;
void *refs = getsectdatafromheader ((headerType *)head,
SEG_OBJC, "__message_refs", &size);
*nmess = size / sizeof(SEL);
@@ -73,7 +68,7 @@ Module _getObjcModules(headerType *head, int *nmodules)
ProtocolTemplate *_getObjcProtocols(headerType *head, int *nprotos)
{
- unsigned size;
+ uint32_t size;
void *protos = getsectdatafromheader ((headerType *)head,
SEG_OBJC, "__protocol", &size);
*nprotos = size / sizeof(ProtocolTemplate);
@@ -88,52 +83,47 @@ Module _getObjcModules(headerType *head, int *nmodules)
Class *_getObjcClassRefs(headerType *head, int *nclasses)
{
- unsigned size;
+ uint32_t size;
void *classes = getsectdatafromheader ((headerType *)head,
SEG_OBJC, "__cls_refs", &size);
*nclasses = size / sizeof(Class);
return (Class *)classes;
}
-objc_image_info *_getObjcImageInfo(headerType *head)
+objc_image_info *_getObjcImageInfo(const headerType *head, uint32_t *sizep)
{
- unsigned size;
- void *info = getsectdatafromheader ((headerType *)head,
- SEG_OBJC, "__image_info", &size);
- return (objc_image_info *)info;
+ objc_image_info *info = (objc_image_info *)
+ getsectdatafromheader(head, SEG_OBJC, "__image_info", sizep);
+ return info;
}
-/* returns start of all objective-c info and the size of the data */
-void *_getObjcHeaderData(const headerType *head, unsigned *size)
+const struct segment_command *getsegbynamefromheader(const headerType *head,
+ const char *segname)
{
- struct segment_command *sgp;
- unsigned long i;
-
- sgp = (struct segment_command *) ((char *)head + sizeof(headerType));
- for(i = 0; i < ((headerType *)head)->ncmds; i++){
- if(sgp->cmd == LC_SEGMENT)
- if(strncmp(sgp->segname, "__OBJC", sizeof(sgp->segname)) == 0) {
- *size = sgp->filesize;
- return (void*)sgp;
- }
- sgp = (struct segment_command *)((char *)sgp + sgp->cmdsize);
- }
- *size = 0;
- return nil;
+ const struct segment_command *sgp;
+ unsigned long i;
+
+ sgp = (const struct segment_command *) ((char *)head + sizeof(headerType));
+ for (i = 0; i < head->ncmds; i++){
+ if (sgp->cmd == LC_SEGMENT) {
+ if (strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0) {
+ return sgp;
+ }
+ }
+ sgp = (const struct segment_command *)((char *)sgp + sgp->cmdsize);
+ }
+ return NULL;
}
static const headerType *_getExecHeader (void)
{
return (const struct mach_header *)_NSGetMachExecuteHeader();
}
-const char *_getObjcHeaderName(headerType *header)
+const char *_getObjcHeaderName(const headerType *header)
{
const headerType *execHeader;
const struct fvmlib_command *libCmd, *endOfCmds;
- char **argv;
- extern char ***_NSGetArgv();
- argv = *_NSGetArgv();
if (header && ((headerType *)header)->filetype == MH_FVMLIB) {
execHeader = _getExecHeader();
@@ -153,7 +143,32 @@ Module _getObjcModules(headerType *head, int *nmodules)
if ( _dyld_get_image_header(i) == header )
return _dyld_get_image_name(i);
}
- return argv[0];
+
+ return (*_NSGetArgv())[0];
}
}
+
+// 1. Find segment with file offset == 0 and file size != 0. This segment's
+// contents span the Mach-O header. (File size of 0 is .bss, for example)
+// 2. Slide is header's address - segment's preferred address
+ptrdiff_t _getImageSlide(const headerType *header)
+{
+ int i;
+ const struct segment_command *sgp =
+ (const struct segment_command *)(header + 1);
+
+ for (i = 0; i < header->ncmds; i++){
+ if (sgp->cmd == LC_SEGMENT) {
+ if (sgp->fileoff == 0 && sgp->filesize != 0) {
+ return (uintptr_t)header - (uintptr_t)sgp->vmaddr;
+ }
+ }
+ sgp = (const struct segment_command *)((char *)sgp + sgp->cmdsize);
+ }
+
+ // uh-oh
+ _objc_fatal("could not calculate VM slide for image '%s'",
+ _getObjcHeaderName(header));
+ return 0; // not reached
+}
View
9 runtime/objc-load.m
@@ -49,15 +49,6 @@
OBJC_EXPORT void (*callbackFunction)( Class, const char * );
-struct objc_method_list **get_base_method_list(Class cls) {
- struct objc_method_list **ptr = ((struct objc_class * )cls)->methodLists;
- if (!*ptr) return NULL;
- while ( *ptr != 0 && *ptr != END_OF_METHODS_LIST ) { ptr++; }
- --ptr;
- return ptr;
-}
-
-
/**********************************************************************************
* objc_loadModule.
*
View
170 runtime/objc-private.h
@@ -37,6 +37,9 @@
#import "objc-config.h"
#import <pthread.h>
+ #import <errno.h>
+ #import <limits.h>
+ #import <unistd.h>
#define mutex_alloc() (pthread_mutex_t*)calloc(1, sizeof(pthread_mutex_t))
#define mutex_init(m) pthread_mutex_init(m, NULL)
#define mutex_lock(m) pthread_mutex_lock(m)
@@ -88,6 +91,9 @@ typedef struct {
// masks for objc_image_info.flags
#define OBJC_IMAGE_IS_REPLACEMENT (1<<0)
+#define OBJC_IMAGE_SUPPORTS_GC (1<<1)
+
+
#define _objcHeaderIsReplacement(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_IS_REPLACEMENT))
/* OBJC_IMAGE_IS_REPLACEMENT:
@@ -96,25 +102,32 @@ typedef struct {
Do fix up selector refs (@selector points to them)
Do fix up class refs (@class and objc_msgSend points to them)
Do fix up protocols (@protocol points to them)
+ Do fix up super_class pointers in classes ([super ...] points to them)
Future: do load new classes?
Future: do load new categories?
Future: do insert new methods on existing classes?
Future: do insert new methods on existing categories?
*/
+#define _objcHeaderSupportsGC(h) ((h)->info && ((h)->info->flags & OBJC_IMAGE_SUPPORTS_GC))
+
+/* OBJC_IMAGE_SUPPORTS_GC:
+ was compiled with -fobjc-gc flag, regardless of whether write-barriers were issued
+ if executable image compiled this way, then all subsequent libraries etc. must also be this way
+*/
// both
OBJC_EXPORT headerType ** _getObjcHeaders();
-OBJC_EXPORT Module _getObjcModules(headerType *head, int *nmodules);
+OBJC_EXPORT Module _getObjcModules(const headerType *head, int *nmodules);
OBJC_EXPORT Class * _getObjcClassRefs(headerType *head, int *nclasses);
-OBJC_EXPORT void * _getObjcHeaderData(const headerType *head, unsigned *size);
-OBJC_EXPORT const char * _getObjcHeaderName(headerType *head);
-OBJC_EXPORT objc_image_info * _getObjcImageInfo(headerType *head);
+OBJC_EXPORT const struct segment_command *getsegbynamefromheader(const headerType *head, const char *segname);
+OBJC_EXPORT const char * _getObjcHeaderName(const headerType *head);
+OBJC_EXPORT objc_image_info * _getObjcImageInfo(const headerType *head, uint32_t *size);
+OBJC_EXPORT ptrdiff_t _getImageSlide(const headerType *header);
+
// internal routines for delaying binding
void _objc_resolve_categories_for_class (struct objc_class * cls);
-void _objc_bindClassIfNeeded(struct objc_class *cls);
-void _objc_bindModuleContainingClass(struct objc_class * cls);
// someday a logging facility
// ObjC is assigned the range 0xb000 - 0xbfff for first parameter
@@ -131,12 +144,11 @@ OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
typedef struct _header_info
{
const headerType * mhdr;
- Module mod_ptr; // NOT adjusted by image_slide
+ Module mod_ptr; // already slid
unsigned int mod_count;
unsigned long image_slide;
- void * objcData; // getObjcHeaderData result
- unsigned objcDataSize; // getObjcHeaderData result
- objc_image_info * info; // IS adjusted by image_slide
+ const struct segment_command * objcSegmentHeader; // already slid
+ objc_image_info * info; // already slid
struct _header_info * next;
} header_info;
OBJC_EXPORT header_info *_objc_headerStart ();
@@ -145,78 +157,25 @@ OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
OBJC_EXPORT const char *_objcModuleNameAtIndex(int i);
OBJC_EXPORT Class objc_getOrigClass (const char *name);
- extern struct objc_method_list **get_base_method_list(Class cls);
-
-
OBJC_EXPORT const char *__S(_nameForHeader) (const headerType*);
- /* initialize */
- OBJC_EXPORT void _sel_resolve_conflicts(headerType * header, unsigned long slide);
- OBJC_EXPORT void _class_install_relationships(Class, long);
- OBJC_EXPORT void *_objc_create_zone(void);
-
- OBJC_EXPORT SEL sel_registerNameNoCopyNoLock(const char *str);
+ OBJC_EXPORT SEL sel_registerNameNoLock(const char *str, BOOL copy);
OBJC_EXPORT void sel_lock(void);
OBJC_EXPORT void sel_unlock(void);
- /* selector fixup in method lists */
-
- #define _OBJC_FIXED_UP ((void *)1771)
-
- static inline struct objc_method_list *_objc_inlined_fixup_selectors_in_method_list(struct objc_method_list *mlist)
- {
- unsigned i, size;
- Method method;
- struct objc_method_list *old_mlist;
-
- if ( ! mlist ) return (struct objc_method_list *)0;
- if ( mlist->obsolete != _OBJC_FIXED_UP ) {
- old_mlist = mlist;
- size = sizeof(struct objc_method_list) - sizeof(struct objc_method) + old_mlist->method_count * sizeof(struct objc_method);
- mlist = malloc_zone_malloc(_objc_create_zone(), size);
- memmove(mlist, old_mlist, size);
- sel_lock();
- for ( i = 0; i < mlist->method_count; i += 1 ) {
- method = &mlist->method_list[i];
- method->method_name =
- sel_registerNameNoCopyNoLock((const char *)method->method_name);
- }
- sel_unlock();
- mlist->obsolete = _OBJC_FIXED_UP;
- }
- return mlist;
- }
-
- /* method lookup */
- /* -- inline version of class_nextMethodList(Class, void **) -- */
-
- static inline struct objc_method_list *_class_inlinedNextMethodList(Class cls, void **it)
- {
- struct objc_method_list ***iterator;
-
- iterator = (struct objc_method_list***)it;
- if (*iterator == NULL) {
- *iterator = &((((struct objc_class *) cls)->methodLists)[0]);
- }
- else (*iterator) += 1;
- // Check for list end
- if ((**iterator == NULL) || (**iterator == END_OF_METHODS_LIST)) {
- *it = nil;
- return NULL;
- }
-
- **iterator = _objc_inlined_fixup_selectors_in_method_list(**iterator);
-
- // Return method list pointer
- return **iterator;
- }
+ /* optional malloc zone for runtime data */
+ OBJC_EXPORT malloc_zone_t *_objc_internal_zone(void);
+ OBJC_EXPORT void *_malloc_internal(size_t size);
+ OBJC_EXPORT void *_calloc_internal(size_t count, size_t size);
+ OBJC_EXPORT void *_realloc_internal(void *ptr, size_t size);
+ OBJC_EXPORT char *_strdup_internal(const char *str);
+ OBJC_EXPORT void _free_internal(void *ptr);
OBJC_EXPORT BOOL class_respondsToMethod(Class, SEL);
OBJC_EXPORT IMP class_lookupMethod(Class, SEL);
- OBJC_EXPORT IMP class_lookupMethodInMethodList(struct objc_method_list *mlist, SEL sel);
- OBJC_EXPORT IMP class_lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name);
- OBJC_EXPORT void _objc_insertMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
- OBJC_EXPORT void _objc_removeMethods( struct objc_method_list *mlist, struct objc_method_list ***list );
+ OBJC_EXPORT IMP lookupNamedMethodInMethodList(struct objc_method_list *mlist, const char *meth_name);
+ OBJC_EXPORT void _objc_insertMethods(struct objc_class *cls, struct objc_method_list *mlist);
+ OBJC_EXPORT void _objc_removeMethods(struct objc_class *cls, struct objc_method_list *mlist);
OBJC_EXPORT IMP _cache_getImp(Class cls, SEL sel);
OBJC_EXPORT Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_imp);
@@ -234,19 +193,56 @@ OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
/* magic */
OBJC_EXPORT Class _objc_getFreedObjectClass (void);
+#ifndef OBJC_INSTRUMENTED
OBJC_EXPORT const struct objc_cache emptyCache;
+#else
+ OBJC_EXPORT struct objc_cache emptyCache;
+#endif
OBJC_EXPORT void _objc_flush_caches (Class cls);
/* locking */
#define MUTEX_TYPE pthread_mutex_t*
#define OBJC_DECLARE_LOCK(MTX) pthread_mutex_t MTX = PTHREAD_MUTEX_INITIALIZER
OBJC_EXPORT pthread_mutex_t classLock;
+ OBJC_EXPORT pthread_mutex_t methodListLock;
/* nil handler object */
OBJC_EXPORT id _objc_nilReceiver;
OBJC_EXPORT id _objc_setNilReceiver(id newNilReceiver);
OBJC_EXPORT id _objc_getNilReceiver(void);
+ /* C++ interoperability */
+ OBJC_EXPORT SEL cxx_construct_sel;
+ OBJC_EXPORT SEL cxx_destruct_sel;
+ OBJC_EXPORT const char *cxx_construct_name;
+ OBJC_EXPORT const char *cxx_destruct_name;
+ OBJC_EXPORT BOOL object_cxxConstruct(id obj);
+ OBJC_EXPORT void object_cxxDestruct(id obj);
+
+ /* GC and RTP startup */
+ OBJC_EXPORT void gc_init(BOOL on);
+ OBJC_EXPORT void rtp_init(void);
+
+ /* Write barrier implementations */
+ OBJC_EXPORT id objc_assign_strongCast_gc(id val, id *dest);
+ OBJC_EXPORT id objc_assign_global_gc(id val, id *dest);
+ OBJC_EXPORT id objc_assign_ivar_gc(id value, id dest, unsigned int offset);
+ OBJC_EXPORT id objc_assign_strongCast_non_gc(id value, id *dest);
+ OBJC_EXPORT id objc_assign_global_non_gc(id value, id *dest);
+ OBJC_EXPORT id objc_assign_ivar_non_gc(id value, id dest, unsigned int offset);
+
+ /* Code modification */
+#if defined(__ppc__)
+ OBJC_EXPORT size_t objc_write_branch(void *entry, void *target);
+#endif
+
+ /* Thread-safe info field */
+ OBJC_EXPORT void _class_setInfo(struct objc_class *cls, long set);
+ OBJC_EXPORT void _class_clearInfo(struct objc_class *cls, long clear);
+ OBJC_EXPORT void _class_changeInfo(struct objc_class *cls, long set, long clear);
+
+ /* Secure /tmp usage */
+ OBJC_EXPORT int secure_open(const char *filename, int flags, uid_t euid);
typedef struct {
long addressOffset;
@@ -266,7 +262,26 @@ OBJC_EXPORT SEL * _getObjcMessageRefs(headerType *head, int *nmess);
#endif
+// Settings from environment variables
+OBJC_EXPORT int PrintImages; // env OBJC_PRINT_IMAGES
+OBJC_EXPORT int PrintLoading; // env OBJC_PRINT_LOAD_METHODS
+OBJC_EXPORT int PrintConnecting; // env OBJC_PRINT_CLASS_CONNECTION
+OBJC_EXPORT int PrintRTP;