[compiler-rt] [llvm] [ORC][MachO] Register objc protolist, protorefs, nlclslist metadata sections (PR #95144)

Ben Langmuir via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 11 09:52:17 PDT 2024


https://github.com/benlangmuir created https://github.com/llvm/llvm-project/pull/95144

Add missing __DATA sections that the objc runtime expects to register. This fixes running objc code that makes use of `@protocol` references and `__attribute__((objc_nonlazy_class))` classes.

rdar://129368761

>From 0e4f372e55cf0fda48b45ebc8ad070ea8705b5ee Mon Sep 17 00:00:00 2001
From: Ben Langmuir <blangmuir at apple.com>
Date: Tue, 11 Jun 2024 09:20:29 -0700
Subject: [PATCH] [ORC][MachO] Register objc protolist, protorefs, nlclslist
 metadata sections

Add missing __DATA sections that the objc runtime expects to register.
This fixes running objc code that makes use of `@protocol` references and
`__attribute__((objc_nonlazy_class))` classes.

rdar://129368761
---
 .../Darwin/arm64/objc-nonlazy-class.S         | 131 +++++++++++++++++
 .../Darwin/arm64/objc-protocol-ref.S          |  93 ++++++++++++
 .../TestCases/Darwin/arm64/objc-protocol.S    |  82 +++++++++++
 .../Darwin/x86-64/objc-nonlazy-class.S        | 132 ++++++++++++++++++
 .../Darwin/x86-64/objc-protocol-ref.S         |  91 ++++++++++++
 .../TestCases/Darwin/x86-64/objc-protocol.S   |  79 +++++++++++
 .../Orc/Shared/ObjectFormats.h                |   5 +-
 .../lib/ExecutionEngine/Orc/MachOPlatform.cpp |   9 +-
 .../Orc/Shared/ObjectFormats.cpp              |  26 ++--
 9 files changed, 633 insertions(+), 15 deletions(-)
 create mode 100644 compiler-rt/test/orc/TestCases/Darwin/arm64/objc-nonlazy-class.S
 create mode 100644 compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol-ref.S
 create mode 100644 compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol.S
 create mode 100644 compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-nonlazy-class.S
 create mode 100644 compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol-ref.S
 create mode 100644 compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol.S

diff --git a/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-nonlazy-class.S b/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-nonlazy-class.S
new file mode 100644
index 0000000000000..7a385b107a314
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-nonlazy-class.S
@@ -0,0 +1,131 @@
+// Test that we register non-lazy classes by ensuring a +load is called even if
+// the class is never referenced.
+//
+// RUN: %clang -c -o %t.o %s
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
+//
+// REQUIRES: jit-compatible-osx-swift-runtime
+
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 15, 0	sdk_version 15, 0
+	.p2align	2                               ; -- Begin function +[C load]
+"+[C load]":                            ; @"\01+[C load]"
+	.cfi_startproc
+; %bb.0:
+	sub	sp, sp, #16
+	.cfi_def_cfa_offset 16
+	str	x0, [sp, #8]
+	str	x1, [sp]
+	adrp	x9, _x at PAGE
+	mov	w8, #7                          ; =0x7
+	str	w8, [x9, _x at PAGEOFF]
+	add	sp, sp, #16
+	ret
+	.cfi_endproc
+                                        ; -- End function
+	.globl	_main                           ; -- Begin function main
+	.p2align	2
+_main:                                  ; @main
+	.cfi_startproc
+; %bb.0:
+	sub	sp, sp, #16
+	.cfi_def_cfa_offset 16
+	str	wzr, [sp, #12]
+	adrp	x8, _x at PAGE
+	ldr	w8, [x8, _x at PAGEOFF]
+	subs	w8, w8, #7
+	cset	w8, eq
+	and	w8, w8, #0x1
+	ands	w8, w8, #0x1
+	cset	w0, eq
+	add	sp, sp, #16
+	ret
+	.cfi_endproc
+                                        ; -- End function
+	.globl	_x                              ; @x
+.zerofill __DATA,__common,_x,4,2
+	.section	__DATA,__objc_data
+	.globl	_OBJC_CLASS_$_C                 ; @"OBJC_CLASS_$_C"
+	.p2align	3, 0x0
+_OBJC_CLASS_$_C:
+	.quad	_OBJC_METACLASS_$_C
+	.quad	0
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__OBJC_CLASS_RO_$_C
+
+	.globl	_OBJC_METACLASS_$_C             ; @"OBJC_METACLASS_$_C"
+	.p2align	3, 0x0
+_OBJC_METACLASS_$_C:
+	.quad	_OBJC_METACLASS_$_C
+	.quad	_OBJC_CLASS_$_C
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__OBJC_METACLASS_RO_$_C
+
+	.section	__TEXT,__objc_classname,cstring_literals
+l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
+	.asciz	"C"
+
+	.section	__TEXT,__objc_methname,cstring_literals
+l_OBJC_METH_VAR_NAME_:                  ; @OBJC_METH_VAR_NAME_
+	.asciz	"load"
+
+	.section	__TEXT,__objc_methtype,cstring_literals
+l_OBJC_METH_VAR_TYPE_:                  ; @OBJC_METH_VAR_TYPE_
+	.asciz	"v16 at 0:8"
+
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0                          ; @"_OBJC_$_CLASS_METHODS_C"
+__OBJC_$_CLASS_METHODS_C:
+	.long	24                              ; 0x18
+	.long	1                               ; 0x1
+	.quad	l_OBJC_METH_VAR_NAME_
+	.quad	l_OBJC_METH_VAR_TYPE_
+	.quad	"+[C load]"
+
+	.p2align	3, 0x0                          ; @"_OBJC_METACLASS_RO_$_C"
+__OBJC_METACLASS_RO_$_C:
+	.long	3                               ; 0x3
+	.long	40                              ; 0x28
+	.long	40                              ; 0x28
+	.space	4
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_
+	.quad	__OBJC_$_CLASS_METHODS_C
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.p2align	3, 0x0                          ; @"_OBJC_CLASS_RO_$_C"
+__OBJC_CLASS_RO_$_C:
+	.long	2                               ; 0x2
+	.long	0                               ; 0x0
+	.long	0                               ; 0x0
+	.space	4
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.section	__DATA,__objc_classlist,regular,no_dead_strip
+	.p2align	3, 0x0                          ; @"OBJC_LABEL_CLASS_$"
+l_OBJC_LABEL_CLASS_$:
+	.quad	_OBJC_CLASS_$_C
+
+	.section	__DATA,__objc_nlclslist,regular,no_dead_strip
+	.p2align	3, 0x0                          ; @"OBJC_LABEL_NONLAZY_CLASS_$"
+l_OBJC_LABEL_NONLAZY_CLASS_$:
+	.quad	_OBJC_CLASS_$_C
+
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+.subsections_via_symbols
diff --git a/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol-ref.S b/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol-ref.S
new file mode 100644
index 0000000000000..0794c417acc86
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol-ref.S
@@ -0,0 +1,93 @@
+// Test that we register protocol reference metadata. Without registration,
+// protocol pointers will not be uniqued correctly and @protocol(NSObject) will
+// not match the runtime's pointer.
+//
+// RUN: %clang -c -o %t.o %s
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
+//
+// REQUIRES: jit-compatible-osx-swift-runtime
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 15, 0	sdk_version 15, 0
+	.globl	_main                           ; -- Begin function main
+	.p2align	2
+_main:                                  ; @main
+	.cfi_startproc
+; %bb.0:
+	sub	sp, sp, #32
+	stp	x29, x30, [sp, #16]             ; 16-byte Folded Spill
+	add	x29, sp, #16
+	.cfi_def_cfa w29, 16
+	.cfi_offset w30, -8
+	.cfi_offset w29, -16
+	stur	wzr, [x29, #-4]
+	adrp	x8, __OBJC_PROTOCOL_REFERENCE_$_NSObject at PAGE
+	ldr	x8, [x8, __OBJC_PROTOCOL_REFERENCE_$_NSObject at PAGEOFF]
+	str	x8, [sp]                        ; 8-byte Folded Spill
+	adrp	x0, l_.str at PAGE
+	add	x0, x0, l_.str at PAGEOFF
+	bl	_objc_getProtocol
+	ldr	x8, [sp]                        ; 8-byte Folded Reload
+	subs	x8, x8, x0
+	cset	w8, eq
+	and	w8, w8, #0x1
+	ands	w8, w8, #0x1
+	cset	w0, eq
+	ldp	x29, x30, [sp, #16]             ; 16-byte Folded Reload
+	add	sp, sp, #32
+	ret
+	.cfi_endproc
+                                        ; -- End function
+	.section	__TEXT,__objc_classname,cstring_literals
+l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
+	.asciz	"NSObject"
+
+	.private_extern	__OBJC_PROTOCOL_$_NSObject ; @"_OBJC_PROTOCOL_$_NSObject"
+	.section	__DATA,__data
+	.globl	__OBJC_PROTOCOL_$_NSObject
+	.weak_definition	__OBJC_PROTOCOL_$_NSObject
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_$_NSObject:
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.long	96                              ; 0x60
+	.long	0                               ; 0x0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.private_extern	__OBJC_LABEL_PROTOCOL_$_NSObject ; @"_OBJC_LABEL_PROTOCOL_$_NSObject"
+	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
+	.globl	__OBJC_LABEL_PROTOCOL_$_NSObject
+	.weak_definition	__OBJC_LABEL_PROTOCOL_$_NSObject
+	.p2align	3, 0x0
+__OBJC_LABEL_PROTOCOL_$_NSObject:
+	.quad	__OBJC_PROTOCOL_$_NSObject
+
+	.private_extern	__OBJC_PROTOCOL_REFERENCE_$_NSObject ; @"_OBJC_PROTOCOL_REFERENCE_$_NSObject"
+	.section	__DATA,__objc_protorefs,coalesced,no_dead_strip
+	.globl	__OBJC_PROTOCOL_REFERENCE_$_NSObject
+	.weak_definition	__OBJC_PROTOCOL_REFERENCE_$_NSObject
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_REFERENCE_$_NSObject:
+	.quad	__OBJC_PROTOCOL_$_NSObject
+
+	.section	__TEXT,__cstring,cstring_literals
+l_.str:                                 ; @.str
+	.asciz	"NSObject"
+
+	.no_dead_strip	__OBJC_PROTOCOL_$_NSObject
+	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_NSObject
+	.no_dead_strip	__OBJC_PROTOCOL_REFERENCE_$_NSObject
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+.subsections_via_symbols
diff --git a/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol.S b/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol.S
new file mode 100644
index 0000000000000..ab6ababea0f8f
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/arm64/objc-protocol.S
@@ -0,0 +1,82 @@
+// Test that we register protocol metadata. Without registration, messaging
+// a protocol metatype object crashes.
+//
+// RUN: %clang -c -o %t.o %s
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
+//
+// REQUIRES: jit-compatible-osx-swift-runtime
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 15, 0	sdk_version 15, 0
+	.globl	_main                           ; -- Begin function main
+	.p2align	2
+_main:                                  ; @main
+	.cfi_startproc
+; %bb.0:
+	sub	sp, sp, #32
+	stp	x29, x30, [sp, #16]             ; 16-byte Folded Spill
+	add	x29, sp, #16
+	.cfi_def_cfa w29, 16
+	.cfi_offset w30, -8
+	.cfi_offset w29, -16
+	mov	w8, #0                          ; =0x0
+	str	w8, [sp, #8]                    ; 4-byte Folded Spill
+	stur	wzr, [x29, #-4]
+	adrp	x8, __OBJC_PROTOCOL_REFERENCE_$_P at PAGE
+	ldr	x0, [x8, __OBJC_PROTOCOL_REFERENCE_$_P at PAGEOFF]
+	bl	_objc_retain
+	ldr	w0, [sp, #8]                    ; 4-byte Folded Reload
+	ldp	x29, x30, [sp, #16]             ; 16-byte Folded Reload
+	add	sp, sp, #32
+	ret
+	.cfi_endproc
+                                        ; -- End function
+	.section	__TEXT,__objc_classname,cstring_literals
+l_OBJC_CLASS_NAME_:                     ; @OBJC_CLASS_NAME_
+	.asciz	"P"
+
+	.private_extern	__OBJC_PROTOCOL_$_P     ; @"_OBJC_PROTOCOL_$_P"
+	.section	__DATA,__data
+	.globl	__OBJC_PROTOCOL_$_P
+	.weak_definition	__OBJC_PROTOCOL_$_P
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_$_P:
+	.quad	0
+	.quad	l_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.long	96                              ; 0x60
+	.long	0                               ; 0x0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.private_extern	__OBJC_LABEL_PROTOCOL_$_P ; @"_OBJC_LABEL_PROTOCOL_$_P"
+	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
+	.globl	__OBJC_LABEL_PROTOCOL_$_P
+	.weak_definition	__OBJC_LABEL_PROTOCOL_$_P
+	.p2align	3, 0x0
+__OBJC_LABEL_PROTOCOL_$_P:
+	.quad	__OBJC_PROTOCOL_$_P
+
+	.private_extern	__OBJC_PROTOCOL_REFERENCE_$_P ; @"_OBJC_PROTOCOL_REFERENCE_$_P"
+	.section	__DATA,__objc_protorefs,coalesced,no_dead_strip
+	.globl	__OBJC_PROTOCOL_REFERENCE_$_P
+	.weak_definition	__OBJC_PROTOCOL_REFERENCE_$_P
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_REFERENCE_$_P:
+	.quad	__OBJC_PROTOCOL_$_P
+
+	.no_dead_strip	__OBJC_PROTOCOL_$_P
+	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_P
+	.no_dead_strip	__OBJC_PROTOCOL_REFERENCE_$_P
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+.subsections_via_symbols
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-nonlazy-class.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-nonlazy-class.S
new file mode 100644
index 0000000000000..bdc08e896819e
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-nonlazy-class.S
@@ -0,0 +1,132 @@
+// Test that we register non-lazy classes by ensuring a +load is called even if
+// the class is never referenced.
+//
+// RUN: %clang -c -o %t.o %s
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
+//
+// REQUIRES: jit-compatible-osx-swift-runtime
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 15, 0	sdk_version 15, 0
+	.p2align	4, 0x90                         ## -- Begin function +[C load]
+"+[C load]":                            ## @"\01+[C load]"
+	.cfi_startproc
+## %bb.0:
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	movq	%rdi, -8(%rbp)
+	movq	%rsi, -16(%rbp)
+	movl	$7, _x(%rip)
+	popq	%rbp
+	retq
+	.cfi_endproc
+                                        ## -- End function
+	.globl	_main                           ## -- Begin function main
+	.p2align	4, 0x90
+_main:                                  ## @main
+	.cfi_startproc
+## %bb.0:
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	movl	$0, -4(%rbp)
+	movl	_x(%rip), %edx
+	movl	$1, %eax
+	xorl	%ecx, %ecx
+	cmpl	$7, %edx
+	cmovel	%ecx, %eax
+	popq	%rbp
+	retq
+	.cfi_endproc
+                                        ## -- End function
+	.globl	_x                              ## @x
+.zerofill __DATA,__common,_x,4,2
+	.section	__DATA,__objc_data
+	.globl	_OBJC_CLASS_$_C                 ## @"OBJC_CLASS_$_C"
+	.p2align	3, 0x0
+_OBJC_CLASS_$_C:
+	.quad	_OBJC_METACLASS_$_C
+	.quad	0
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__OBJC_CLASS_RO_$_C
+
+	.globl	_OBJC_METACLASS_$_C             ## @"OBJC_METACLASS_$_C"
+	.p2align	3, 0x0
+_OBJC_METACLASS_$_C:
+	.quad	_OBJC_METACLASS_$_C
+	.quad	_OBJC_CLASS_$_C
+	.quad	__objc_empty_cache
+	.quad	0
+	.quad	__OBJC_METACLASS_RO_$_C
+
+	.section	__TEXT,__objc_classname,cstring_literals
+L_OBJC_CLASS_NAME_:                     ## @OBJC_CLASS_NAME_
+	.asciz	"C"
+
+	.section	__TEXT,__objc_methname,cstring_literals
+L_OBJC_METH_VAR_NAME_:                  ## @OBJC_METH_VAR_NAME_
+	.asciz	"load"
+
+	.section	__TEXT,__objc_methtype,cstring_literals
+L_OBJC_METH_VAR_TYPE_:                  ## @OBJC_METH_VAR_TYPE_
+	.asciz	"v16 at 0:8"
+
+	.section	__DATA,__objc_const
+	.p2align	3, 0x0                          ## @"_OBJC_$_CLASS_METHODS_C"
+__OBJC_$_CLASS_METHODS_C:
+	.long	24                              ## 0x18
+	.long	1                               ## 0x1
+	.quad	L_OBJC_METH_VAR_NAME_
+	.quad	L_OBJC_METH_VAR_TYPE_
+	.quad	"+[C load]"
+
+	.p2align	3, 0x0                          ## @"_OBJC_METACLASS_RO_$_C"
+__OBJC_METACLASS_RO_$_C:
+	.long	3                               ## 0x3
+	.long	40                              ## 0x28
+	.long	40                              ## 0x28
+	.space	4
+	.quad	0
+	.quad	L_OBJC_CLASS_NAME_
+	.quad	__OBJC_$_CLASS_METHODS_C
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.p2align	3, 0x0                          ## @"_OBJC_CLASS_RO_$_C"
+__OBJC_CLASS_RO_$_C:
+	.long	2                               ## 0x2
+	.long	0                               ## 0x0
+	.long	0                               ## 0x0
+	.space	4
+	.quad	0
+	.quad	L_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.section	__DATA,__objc_classlist,regular,no_dead_strip
+	.p2align	3, 0x0                          ## @"OBJC_LABEL_CLASS_$"
+l_OBJC_LABEL_CLASS_$:
+	.quad	_OBJC_CLASS_$_C
+
+	.section	__DATA,__objc_nlclslist,regular,no_dead_strip
+	.p2align	3, 0x0                          ## @"OBJC_LABEL_NONLAZY_CLASS_$"
+l_OBJC_LABEL_NONLAZY_CLASS_$:
+	.quad	_OBJC_CLASS_$_C
+
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+.subsections_via_symbols
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol-ref.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol-ref.S
new file mode 100644
index 0000000000000..689af1e529edf
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol-ref.S
@@ -0,0 +1,91 @@
+// Test that we register protocol reference metadata. Without registration,
+// protocol pointers will not be uniqued correctly and @protocol(NSObject) will
+// not match the runtime's pointer.
+//
+// RUN: %clang -c -o %t.o %s
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
+//
+// REQUIRES: jit-compatible-osx-swift-runtime
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 15, 0	sdk_version 15, 0
+	.globl	_main                           ## -- Begin function main
+	.p2align	4, 0x90
+_main:                                  ## @main
+	.cfi_startproc
+## %bb.0:
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	subq	$16, %rsp
+	movl	$0, -4(%rbp)
+	movq	__OBJC_PROTOCOL_REFERENCE_$_NSObject(%rip), %rax
+	movq	%rax, -16(%rbp)                 ## 8-byte Spill
+	leaq	L_.str(%rip), %rdi
+	callq	_objc_getProtocol
+	movq	-16(%rbp), %rdx                 ## 8-byte Reload
+	movq	%rax, %rsi
+	movl	$1, %eax
+	xorl	%ecx, %ecx
+	cmpq	%rsi, %rdx
+	cmovel	%ecx, %eax
+	addq	$16, %rsp
+	popq	%rbp
+	retq
+	.cfi_endproc
+                                        ## -- End function
+	.section	__TEXT,__objc_classname,cstring_literals
+L_OBJC_CLASS_NAME_:                     ## @OBJC_CLASS_NAME_
+	.asciz	"NSObject"
+
+	.private_extern	__OBJC_PROTOCOL_$_NSObject ## @"_OBJC_PROTOCOL_$_NSObject"
+	.section	__DATA,__data
+	.globl	__OBJC_PROTOCOL_$_NSObject
+	.weak_definition	__OBJC_PROTOCOL_$_NSObject
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_$_NSObject:
+	.quad	0
+	.quad	L_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.long	96                              ## 0x60
+	.long	0                               ## 0x0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.private_extern	__OBJC_LABEL_PROTOCOL_$_NSObject ## @"_OBJC_LABEL_PROTOCOL_$_NSObject"
+	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
+	.globl	__OBJC_LABEL_PROTOCOL_$_NSObject
+	.weak_definition	__OBJC_LABEL_PROTOCOL_$_NSObject
+	.p2align	3, 0x0
+__OBJC_LABEL_PROTOCOL_$_NSObject:
+	.quad	__OBJC_PROTOCOL_$_NSObject
+
+	.private_extern	__OBJC_PROTOCOL_REFERENCE_$_NSObject ## @"_OBJC_PROTOCOL_REFERENCE_$_NSObject"
+	.section	__DATA,__objc_protorefs,coalesced,no_dead_strip
+	.globl	__OBJC_PROTOCOL_REFERENCE_$_NSObject
+	.weak_definition	__OBJC_PROTOCOL_REFERENCE_$_NSObject
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_REFERENCE_$_NSObject:
+	.quad	__OBJC_PROTOCOL_$_NSObject
+
+	.section	__TEXT,__cstring,cstring_literals
+L_.str:                                 ## @.str
+	.asciz	"NSObject"
+
+	.no_dead_strip	__OBJC_PROTOCOL_$_NSObject
+	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_NSObject
+	.no_dead_strip	__OBJC_PROTOCOL_REFERENCE_$_NSObject
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+.subsections_via_symbols
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol.S
new file mode 100644
index 0000000000000..3ee9bbe5cee53
--- /dev/null
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/objc-protocol.S
@@ -0,0 +1,79 @@
+// Test that we register protocol metadata. Without registration, messaging
+// a protocol metatype object crashes.
+//
+// RUN: %clang -c -o %t.o %s
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t.o
+//
+// REQUIRES: jit-compatible-osx-swift-runtime
+
+	.section	__TEXT,__text,regular,pure_instructions
+	.build_version macos, 15, 0	sdk_version 15, 0
+	.globl	_main                           ## -- Begin function main
+	.p2align	4, 0x90
+_main:                                  ## @main
+	.cfi_startproc
+## %bb.0:
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset %rbp, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register %rbp
+	subq	$16, %rsp
+	movl	$0, -4(%rbp)
+	movq	__OBJC_PROTOCOL_REFERENCE_$_P(%rip), %rdi
+	callq	*_objc_retain at GOTPCREL(%rip)
+	xorl	%eax, %eax
+	addq	$16, %rsp
+	popq	%rbp
+	retq
+	.cfi_endproc
+                                        ## -- End function
+	.section	__TEXT,__objc_classname,cstring_literals
+L_OBJC_CLASS_NAME_:                     ## @OBJC_CLASS_NAME_
+	.asciz	"P"
+
+	.private_extern	__OBJC_PROTOCOL_$_P     ## @"_OBJC_PROTOCOL_$_P"
+	.section	__DATA,__data
+	.globl	__OBJC_PROTOCOL_$_P
+	.weak_definition	__OBJC_PROTOCOL_$_P
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_$_P:
+	.quad	0
+	.quad	L_OBJC_CLASS_NAME_
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.quad	0
+	.long	96                              ## 0x60
+	.long	0                               ## 0x0
+	.quad	0
+	.quad	0
+	.quad	0
+
+	.private_extern	__OBJC_LABEL_PROTOCOL_$_P ## @"_OBJC_LABEL_PROTOCOL_$_P"
+	.section	__DATA,__objc_protolist,coalesced,no_dead_strip
+	.globl	__OBJC_LABEL_PROTOCOL_$_P
+	.weak_definition	__OBJC_LABEL_PROTOCOL_$_P
+	.p2align	3, 0x0
+__OBJC_LABEL_PROTOCOL_$_P:
+	.quad	__OBJC_PROTOCOL_$_P
+
+	.private_extern	__OBJC_PROTOCOL_REFERENCE_$_P ## @"_OBJC_PROTOCOL_REFERENCE_$_P"
+	.section	__DATA,__objc_protorefs,coalesced,no_dead_strip
+	.globl	__OBJC_PROTOCOL_REFERENCE_$_P
+	.weak_definition	__OBJC_PROTOCOL_REFERENCE_$_P
+	.p2align	3, 0x0
+__OBJC_PROTOCOL_REFERENCE_$_P:
+	.quad	__OBJC_PROTOCOL_$_P
+
+	.no_dead_strip	__OBJC_PROTOCOL_$_P
+	.no_dead_strip	__OBJC_LABEL_PROTOCOL_$_P
+	.no_dead_strip	__OBJC_PROTOCOL_REFERENCE_$_P
+	.section	__DATA,__objc_imageinfo,regular,no_dead_strip
+L_OBJC_IMAGE_INFO:
+	.long	0
+	.long	64
+
+.subsections_via_symbols
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h
index 0e75d16e39510..8602755c13548 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/ObjectFormats.h
@@ -37,6 +37,9 @@ extern StringRef MachOObjCImageInfoSectionName;
 extern StringRef MachOObjCMethNameSectionName;
 extern StringRef MachOObjCMethTypeSectionName;
 extern StringRef MachOObjCNLCatListSectionName;
+extern StringRef MachOObjCNLClassListSectionName;
+extern StringRef MachOObjCProtoListSectionName;
+extern StringRef MachOObjCProtoRefsSectionName;
 extern StringRef MachOObjCSelRefsSectionName;
 extern StringRef MachOSwift5ProtoSectionName;
 extern StringRef MachOSwift5ProtosSectionName;
@@ -48,7 +51,7 @@ extern StringRef MachOThreadBSSSectionName;
 extern StringRef MachOThreadDataSectionName;
 extern StringRef MachOThreadVarsSectionName;
 
-extern StringRef MachOInitSectionNames[19];
+extern StringRef MachOInitSectionNames[22];
 
 // ELF section names.
 extern StringRef ELFEHFrameSectionName;
diff --git a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
index b477a48af2906..0d117f7cf8734 100644
--- a/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp
@@ -206,9 +206,12 @@ class MachOPlatformCompleteBootstrapMaterializationUnit
 };
 
 static StringRef ObjCRuntimeObjectSectionsData[] = {
-    MachOObjCCatListSectionName,   MachOObjCClassListSectionName,
-    MachOObjCClassRefsSectionName, MachOObjCConstSectionName,
-    MachOObjCDataSectionName,      MachOObjCSelRefsSectionName};
+    MachOObjCCatListSectionName,   MachOObjCCatList2SectionName,
+    MachOObjCClassListSectionName, MachOObjCClassRefsSectionName,
+    MachOObjCConstSectionName,     MachOObjCDataSectionName,
+    MachOObjCProtoListSectionName, MachOObjCProtoRefsSectionName,
+    MachOObjCNLCatListSectionName, MachOObjCNLClassListSectionName,
+    MachOObjCSelRefsSectionName};
 
 static StringRef ObjCRuntimeObjectSectionsText[] = {
     MachOObjCClassNameSectionName, MachOObjCMethNameSectionName,
diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/ObjectFormats.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/ObjectFormats.cpp
index a407fcab6ae3e..f94f4832c5409 100644
--- a/llvm/lib/ExecutionEngine/Orc/Shared/ObjectFormats.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/Shared/ObjectFormats.cpp
@@ -32,6 +32,9 @@ StringRef MachOObjCImageInfoSectionName = "__DATA,__objc_imageinfo";
 StringRef MachOObjCMethNameSectionName = "__TEXT,__objc_methname";
 StringRef MachOObjCMethTypeSectionName = "__TEXT,__objc_methtype";
 StringRef MachOObjCNLCatListSectionName = "__DATA,__objc_nlcatlist";
+StringRef MachOObjCNLClassListSectionName = "__DATA,__objc_nlclslist";
+StringRef MachOObjCProtoListSectionName = "__DATA,__objc_protolist";
+StringRef MachOObjCProtoRefsSectionName = "__DATA,__objc_protorefs";
 StringRef MachOObjCSelRefsSectionName = "__DATA,__objc_selrefs";
 StringRef MachOSwift5ProtoSectionName = "__TEXT,__swift5_proto";
 StringRef MachOSwift5ProtosSectionName = "__TEXT,__swift5_protos";
@@ -43,17 +46,18 @@ StringRef MachOThreadBSSSectionName = "__DATA,__thread_bss";
 StringRef MachOThreadDataSectionName = "__DATA,__thread_data";
 StringRef MachOThreadVarsSectionName = "__DATA,__thread_vars";
 
-StringRef MachOInitSectionNames[19] = {
-    MachOModInitFuncSectionName,   MachOObjCCatListSectionName,
-    MachOObjCCatList2SectionName,  MachOObjCClassListSectionName,
-    MachOObjCClassNameSectionName, MachOObjCClassRefsSectionName,
-    MachOObjCConstSectionName,     MachOObjCDataSectionName,
-    MachOObjCImageInfoSectionName, MachOObjCMethNameSectionName,
-    MachOObjCMethTypeSectionName,  MachOObjCNLCatListSectionName,
-    MachOObjCSelRefsSectionName,   MachOSwift5ProtoSectionName,
-    MachOSwift5ProtosSectionName,  MachOSwift5TypesSectionName,
-    MachOSwift5TypeRefSectionName, MachOSwift5FieldMetadataSectionName,
-    MachOSwift5EntrySectionName,
+StringRef MachOInitSectionNames[22] = {
+    MachOModInitFuncSectionName,         MachOObjCCatListSectionName,
+    MachOObjCCatList2SectionName,        MachOObjCClassListSectionName,
+    MachOObjCClassNameSectionName,       MachOObjCClassRefsSectionName,
+    MachOObjCConstSectionName,           MachOObjCDataSectionName,
+    MachOObjCImageInfoSectionName,       MachOObjCMethNameSectionName,
+    MachOObjCMethTypeSectionName,        MachOObjCNLCatListSectionName,
+    MachOObjCNLClassListSectionName,     MachOObjCProtoListSectionName,
+    MachOObjCProtoRefsSectionName,       MachOObjCSelRefsSectionName,
+    MachOSwift5ProtoSectionName,         MachOSwift5ProtosSectionName,
+    MachOSwift5TypesSectionName,         MachOSwift5TypeRefSectionName,
+    MachOSwift5FieldMetadataSectionName, MachOSwift5EntrySectionName,
 };
 
 StringRef ELFEHFrameSectionName = ".eh_frame";



More information about the llvm-commits mailing list