running program and replace existing functions and methods of that
translation unit with with versions of those functions and methods
from the newly compiled translation unit. The new functions access
- the existing static data from the old translation unit, if the data
- existed in the unit to be replaced, and from the new translation
- unit, for new data.
+ the existing static symbols from the old translation unit, if the
+ symbol existed in the unit to be replaced, and from the new
+ translation unit, otherwise.
The changes are to insert 5 nops at the beginning of all functions
- and to use indirection to get at static duration data. The 5 nops
+ and to use indirection to get at static symbols. The 5 nops
are required by consumers of the generated code. Currently, gdb
uses this to patch in a jump to the overriding function, this
allows all uses of the old name to forward to the replacement,
rs6000_emit_prologue for the code that handles the nop insertions.
The added indirection allows gdb to redirect accesses to static
- duration data from the newly loaded translation unit to the
- existing data, if any. @code{static} data is special and is
- handled by setting the second word in the .non_lazy_symbol_pointer
- data structure to the address of the data. See indirect_data for
- the code that handles the extra indirection, and
- machopic_output_indirection and its use of MACHO_SYMBOL_STATIC for
- the code that handles @code{static} data indirection. */
+ symbols from the newly loaded translation unit to the existing
+ symbol, if any. @code{static} symbols are special and are handled by
+ setting the second word in the .non_lazy_symbol_pointer data
+ structure to symbol. See indirect_data for the code that handles
+ the extra indirection, and machopic_output_indirection and its use
+ of MACHO_SYMBOL_STATIC for the code that handles @code{static}
+ symbol indirection. */
int
the non-lazy symbol pointer data structure when they are
defined. This allows the runtime to rebind newer instances
of the translation unit with the original instance of the
- data. */
+ symbol. */
if ((SYMBOL_REF_FLAGS (symbol) & MACHO_SYMBOL_STATIC)
&& machopic_symbol_defined_p (symbol))
&& DECL_INITIAL (decl) != error_mark_node)))
SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_FLAG_DEFINED;
- if (TREE_CODE (decl) == VAR_DECL
- && indirect_data (sym_ref)
- && ! TREE_PUBLIC (decl))
+ if (! TREE_PUBLIC (decl))
SYMBOL_REF_FLAGS (sym_ref) |= MACHO_SYMBOL_STATIC;
}
--- /dev/null
+/* Fix and continue should not interfere with computation of
+ local (static) function addresses. */
+/* Author: Ziemowit Laski <zlaski@apple.com> */
+
+/* { dg-do run { target *-*-darwin* } } */
+/* { dg-options "-mfix-and-continue" } */
+
+#include <objc/Object.h>
+#include <stdlib.h>
+
+@class MyTarget, MySet;
+
+int global_value = 0;
+
+@interface MyTargetBuildContext : Object
+{
+ MyTarget * _target;
+ unsigned _cacheInvalDisableCount;
+ BOOL _cacheInvalidationNeeded;
+ unsigned short _isCreatingDependencies:1;
+ unsigned short _isCreatingHeadermap:1;
+ unsigned short _haveAddedIdleTimeInvoc:1;
+ BOOL _hasSetUpBuildSettings;
+}
+- (id)initWithTarget:(MyTarget *)target;
+- (MyTarget *)target;
+@end
+
+@interface MyTargetBuildContext (PrivateMethods)
++ (MySet *)_headerFileExtensions;
+@end
+
+@interface MyCountedSet: Object {
+@public
+ int cardinality;
+}
+- (id)init;
+- (id)sortedArrayUsingFunction:(int (*)(id, id, void *))comparator with:(int)value;
+@end
+
+@implementation MyCountedSet
+- (id)init {
+ cardinality = 5;
+ global_value = 17;
+ return self;
+}
+- (id)sortedArrayUsingFunction:(int (*)(id, id, void *))comparator with:(int)value {
+ if(value == comparator(self, self, self))
+ return self;
+ return nil;
+}
+@end
+
+@implementation MyTargetBuildContext : Object
+- (id)initWithTarget:(MyTarget *)target
+{
+ self = [super init];
+ return self;
+}
+- (MyTarget *)target
+{
+ return _target;
+}
+
+static int _MyCompareObjectsByDecreasingSetCount (id object1, id object2, MyCountedSet * countedSet)
+{
+ global_value = 5;
+ return countedSet->cardinality;
+}
++ (MySet *)_headerFileExtensions
+{
+ MySet * _headerFileExtensions = 0;
+ return _headerFileExtensions;
+}
+- (void)_recomputeHeadermap
+{
+ MyCountedSet *set = [MyCountedSet new];
+ int (*functionPointer)(id, id, void *) = (int (*)(id, id, void *))_MyCompareObjectsByDecreasingSetCount;
+ id result = [set sortedArrayUsingFunction:functionPointer with:5];
+}
+@end
+
+int main(void) {
+ MyTargetBuildContext *ctx = [MyTargetBuildContext new];
+ [ctx _recomputeHeadermap];
+ if (global_value != 5)
+ abort();
+
+ return 0;
+}