From 49bf9378fba23765c5db30988865222f8d0da5a2 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Fri, 29 Mar 2019 11:30:06 +0000 Subject: [PATCH] Force linking the protocol classes. We use the existence of the `Protocol` class in a set of loaded objects to determine whether we are mixing ABIs in a safe way (i.e. only mixing a new ABI runtime with old ABI everything else). Unfortunately, in static linking, the Protocol class was not being linked because it is never directly referenced, which made this check fail. Fixes #85 --- Protocol2.m | 7 +++++++ loader.c | 6 ++++++ protocol.h | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/Protocol2.m b/Protocol2.m index 24bab1c..154403b 100644 --- a/Protocol2.m +++ b/Protocol2.m @@ -36,3 +36,10 @@ @implementation ProtocolGCC @end @implementation ProtocolGSv1 @end + +PRIVATE void link_protocol_classes(void) +{ + [Protocol class]; + [ProtocolGCC class]; + [ProtocolGSv1 class]; +} diff --git a/loader.c b/loader.c index 865d4a3..52dfe17 100644 --- a/loader.c +++ b/loader.c @@ -45,6 +45,12 @@ __attribute__((weak)) void (*dispatch_end_thread_4GC)(void); __attribute__((weak)) void *(*_dispatch_begin_NSAutoReleasePool)(void); __attribute__((weak)) void (*_dispatch_end_NSAutoReleasePool)(void *); +__attribute__((used)) +static void link_protos(void) +{ + link_protocol_classes(); +} + static void init_runtime(void) { static BOOL first_run = YES; diff --git a/protocol.h b/protocol.h index 8cb0f4a..d27f68c 100644 --- a/protocol.h +++ b/protocol.h @@ -232,4 +232,12 @@ struct objc_protocol_list }; // end: objc_protocol_list + +/** + * Function that ensures that protocol classes are linked. Calling this + * guarantees that the Protocol classes are linked into a statically linked + * runtime. + */ +void link_protocol_classes(void); + #endif // PROTOCOL_H_INCLUDED