1# These are the functions which clang needs when it is targeting a previous
2# version of the OS. The issue is that the backend may use functions which were
3# not present in the libgcc that shipped on the platform. In such cases, we link
4# with a version of the library which contains private_extern definitions of all
5# the extra functions which might be referenced.
6
7Description := Static runtime libraries for clang/Darwin.
8
9# A function that ensures we don't try to build for architectures and SDKs
10# that we don't have working toolchains for. Arguments:
11# (1): List of architectures
12# (2): Library name
13# (3): SDK path
14# The result is a possibly empty subset of the architectures from argument 1.
15CheckArches = \
16  $(shell \
17    result=""; \
18    if [ "X$(3)" != X ]; then \
19      for arch in $(1); do \
20        if $(LD) -v 2>&1 | grep "configured to support" \
21             | tr ' ' '\n' | grep "^$$arch$$" >/dev/null 2>/dev/null; then \
22          if $(CC) -arch $$arch \
23            -integrated-as \
24            $(ProjSrcRoot)/make/platform/clang_darwin_test_input.c \
25            -isysroot $(3) \
26            -o /dev/null > /dev/null 2> /dev/null; then \
27              result="$$result$$arch "; \
28          else \
29            printf 1>&2 \
30             "warning: clang_darwin.mk: dropping arch '$$arch' from lib '$(2)'"; \
31            printf 1>&2 " (clang or system libraries do not support it)\n"; \
32          fi; \
33        else \
34          printf 1>&2 \
35            "warning: clang_darwin.mk: dropping arch '$$arch' from lib '$(2)'";\
36          printf 1>&2 " (ld does not support it)\n"; \
37        fi; \
38      done; \
39    fi; \
40    echo $$result)
41
42XCRun = \
43  $(shell \
44    result=`xcrun -find $(1) 2> /dev/null`; \
45    if [ "$$?" != "0" ]; then result=$(1); fi; \
46    echo $$result)
47# Prefer building with the internal SDKs.
48XCRunSdkPath = \
49  $(shell \
50    result=`xcrun --sdk $(1).internal --show-sdk-path 2> /dev/null`; \
51    if [ "$$?" != "0" ]; then \
52      result=`xcrun --sdk $(1) --show-sdk-path 2> /dev/null`; \
53      if [ "$$?" != "0" ]; then result=""; fi; \
54    fi; \
55    echo $$result)
56###
57
58CC       := $(call XCRun,clang)
59LD       := $(shell $(CC) -print-prog-name=ld)
60AR       := $(call XCRun,ar)
61RANLIB   := $(call XCRun,ranlib)
62STRIP    := $(call XCRun,strip)
63LIPO     := $(call XCRun,lipo)
64DSYMUTIL := $(call XCRun,dsymutil)
65
66OSX_SDK := $(call XCRunSdkPath,macosx)
67IOS_SDK := $(call XCRunSdkPath,iphoneos)
68IOSSIM_SDK := $(call XCRunSdkPath,iphonesimulator)
69
70Configs :=
71UniversalArchs :=
72
73# Configuration solely for providing access to an eprintf symbol, which may
74# still be referenced from Darwin system headers. This symbol is only ever
75# needed on i386.
76Configs += eprintf
77UniversalArchs.eprintf := $(call CheckArches,i386,eprintf,$(OSX_SDK))
78
79# Configuration for targeting 10.4. We need a few functions missing from
80# libgcc_s.10.4.dylib. We only build x86 slices since clang doesn't really
81# support targeting PowerPC.
82Configs += 10.4
83UniversalArchs.10.4 := $(call CheckArches,i386 x86_64,10.4,$(OSX_SDK))
84
85# Configuration for targeting iOS for a couple of functions that didn't
86# make it into libSystem.
87Configs += ios
88UniversalArchs.ios := $(call CheckArches,i386 x86_64,ios,$(IOSSIM_SDK))
89UniversalArchs.ios += $(call CheckArches,armv7 arm64,ios,$(IOS_SDK))
90
91# Configuration for targeting OSX. These functions may not be in libSystem
92# so we should provide our own.
93Configs += osx
94UniversalArchs.osx := $(call CheckArches,i386 x86_64 x86_64h,osx,$(OSX_SDK))
95
96# Configuration for use with kernel/kexts.
97Configs += cc_kext
98UniversalArchs.cc_kext := $(call CheckArches,i386 x86_64 x86_64h,cc_kext,$(OSX_SDK))
99
100# Configuration for use with iOS kernel/kexts
101Configs += cc_kext_ios
102UniversalArchs.cc_kext_ios += $(call CheckArches,armv7,cc_kext_ios,$(IOS_SDK))
103
104# Darwin 10.6 has a bug in cctools that makes it unable to use ranlib on our ARM
105# object files. If we are on that platform, strip out all ARM archs. We still
106# build the libraries themselves so that Clang can find them where it expects
107# them, even though they might not have an expected slice.
108ifneq ($(shell test -x /usr/bin/sw_vers && sw_vers -productVersion | grep 10.6),)
109UniversalArchs.ios := $(filter-out armv7, $(UniversalArchs.ios))
110UniversalArchs.cc_kext_ios := $(filter-out armv7, $(UniversalArchs.cc_kext_ios))
111endif
112
113# If RC_SUPPORTED_ARCHS is defined, treat it as a list of the architectures we
114# are intended to support and limit what we try to build to that.
115ifneq ($(RC_SUPPORTED_ARCHS),)
116$(foreach config,$(Configs),\
117  $(call Set,UniversalArchs.$(config),\
118	$(filter $(RC_SUPPORTED_ARCHS),$(UniversalArchs.$(config)))))
119endif
120
121# Remove empty configs if we end up dropping all the requested
122# archs for a particular config.
123$(foreach config,$(Configs),\
124  $(if $(strip $(UniversalArchs.$(config))),,\
125	$(call Set,Configs,$(filter-out $(config),$(Configs)))))
126
127###
128
129# Forcibly strip off any -arch, as that totally breaks our universal support.
130override CC := $(subst -arch ,-arch_,$(CC))
131override CC := $(patsubst -arch_%,,$(CC))
132
133CFLAGS := -Wall -Werror -O3 -fomit-frame-pointer
134
135# Always set deployment target arguments for every build, these libraries should
136# never depend on the environmental overrides. We simply set them to minimum
137# supported deployment target -- nothing in the compiler-rt libraries should
138# actually depend on the deployment target.
139OSX_DEPLOYMENT_ARGS := -mmacosx-version-min=10.4
140IOS_DEPLOYMENT_ARGS := -mios-version-min=1.0
141IOS6_DEPLOYMENT_ARGS := -mios-version-min=6.0
142IOSSIM_DEPLOYMENT_ARGS := -mios-simulator-version-min=1.0
143
144OSX_DEPLOYMENT_ARGS += -isysroot $(OSX_SDK)
145IOS_DEPLOYMENT_ARGS += -isysroot $(IOS_SDK)
146IOS6_DEPLOYMENT_ARGS += -isysroot $(IOS_SDK)
147IOSSIM_DEPLOYMENT_ARGS += -isysroot $(IOSSIM_SDK)
148
149CFLAGS.eprintf		:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
150CFLAGS.10.4		:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
151
152SANITIZER_MACOSX_DEPLOYMENT_ARGS := -mmacosx-version-min=10.7
153SANITIZER_IOSSIM_DEPLOYMENT_ARGS := -mios-simulator-version-min=7.0 \
154  -isysroot $(IOSSIM_SDK)
155SANITIZER_CFLAGS := -fno-builtin -gline-tables-only -stdlib=libc++
156
157
158CFLAGS.ios.i386		:= $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)
159CFLAGS.ios.x86_64	:= $(CFLAGS) $(IOSSIM_DEPLOYMENT_ARGS)
160CFLAGS.ios.armv7	:= $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)
161CFLAGS.ios.armv7k	:= $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)
162CFLAGS.ios.armv7s	:= $(CFLAGS) $(IOS_DEPLOYMENT_ARGS)
163CFLAGS.ios.arm64	:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)
164CFLAGS.osx.i386		:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
165CFLAGS.osx.x86_64	:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
166CFLAGS.osx.x86_64h	:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
167CFLAGS.cc_kext.i386	:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
168CFLAGS.cc_kext.x86_64	:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
169CFLAGS.cc_kext.x86_64h	:= $(CFLAGS) $(OSX_DEPLOYMENT_ARGS)
170CFLAGS.cc_kext_ios.armv7	:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)
171CFLAGS.cc_kext_ios.armv7k	:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)
172CFLAGS.cc_kext_ios.armv7s	:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)
173CFLAGS.cc_kext_ios.arm64	:= $(CFLAGS) $(IOS6_DEPLOYMENT_ARGS)
174
175SANITIZER_LDFLAGS := -stdlib=libc++ -lc++ -lc++abi
176
177ATOMIC_FUNCTIONS := \
178	atomic_flag_clear \
179	atomic_flag_clear_explicit \
180	atomic_flag_test_and_set \
181	atomic_flag_test_and_set_explicit \
182	atomic_signal_fence \
183	atomic_thread_fence
184
185FP16_FUNCTIONS := \
186	extendhfsf2 \
187	truncdfhf2 \
188	truncsfhf2
189
190FUNCTIONS.eprintf := eprintf
191FUNCTIONS.10.4 := eprintf floatundidf floatundisf floatundixf
192
193FUNCTIONS.ios	    := divmodsi4 udivmodsi4 mulosi4 mulodi4 muloti4 \
194                       $(ATOMIC_FUNCTIONS) $(FP16_FUNCTIONS)
195# On x86, the divmod functions reference divsi.
196FUNCTIONS.ios.i386    := $(FUNCTIONS.ios) \
197                         divsi3 udivsi3
198FUNCTIONS.ios.x86_64  := $(FUNCTIONS.ios.i386)
199FUNCTIONS.ios.arm64   := mulsc3 muldc3 divsc3 divdc3 udivti3 umodti3 \
200                         $(ATOMIC_FUNCTIONS)
201
202FUNCTIONS.osx	:= mulosi4 mulodi4 muloti4 $(ATOMIC_FUNCTIONS) $(FP16_FUNCTIONS)
203
204CCKEXT_PROFILE_FUNCTIONS := \
205	InstrProfiling \
206	InstrProfilingBuffer \
207	InstrProfilingPlatformDarwin
208
209CCKEXT_COMMON_FUNCTIONS := \
210	$(CCKEXT_PROFILE_FUNCTIONS) \
211	absvdi2 \
212	absvsi2 \
213	addvdi3 \
214	addvsi3 \
215	ashldi3 \
216	ashrdi3 \
217	bswapdi2 \
218	bswapsi2 \
219	clzdi2 \
220	clzsi2 \
221	cmpdi2 \
222	ctzdi2 \
223	ctzsi2 \
224	divdc3 \
225	divdi3 \
226	divsc3 \
227	divmodsi4 \
228	udivmodsi4 \
229	do_global_dtors \
230	eprintf \
231	extendhfsf2 \
232	ffsdi2 \
233	fixdfdi \
234	fixsfdi \
235	fixunsdfdi \
236	fixunsdfsi \
237	fixunssfdi \
238	fixunssfsi \
239	floatdidf \
240	floatdisf \
241	floatundidf \
242	floatundisf \
243	gcc_bcmp \
244	lshrdi3 \
245	moddi3 \
246	muldc3 \
247	muldi3 \
248	mulsc3 \
249	mulvdi3 \
250	mulvsi3 \
251	negdi2 \
252	negvdi2 \
253	negvsi2 \
254	paritydi2 \
255	paritysi2 \
256	popcountdi2 \
257	popcountsi2 \
258	powidf2 \
259	powisf2 \
260	subvdi3 \
261	subvsi3 \
262	truncdfhf2 \
263	truncsfhf2 \
264	ucmpdi2 \
265	udiv_w_sdiv \
266	udivdi3 \
267	udivmoddi4 \
268	umoddi3
269
270CCKEXT_ARM_FUNCTIONS := $(CCKEXT_COMMON_FUNCTIONS) \
271	adddf3 \
272	addsf3 \
273	aeabi_cdcmpeq \
274	aeabi_cdrcmple \
275	aeabi_cfcmpeq \
276	aeabi_cfrcmple \
277	aeabi_dcmpeq \
278	aeabi_dcmpge \
279	aeabi_dcmpgt \
280	aeabi_dcmple \
281	aeabi_dcmplt \
282	aeabi_drsub \
283	aeabi_fcmpeq \
284	aeabi_fcmpge \
285	aeabi_fcmpgt \
286	aeabi_fcmple \
287	aeabi_fcmplt \
288	aeabi_frsub \
289	aeabi_idivmod \
290	aeabi_uidivmod \
291	cmpdf2 \
292	cmpsf2 \
293	div0 \
294	divdf3 \
295	divsf3 \
296	divsi3 \
297	extendsfdf2 \
298	ffssi2 \
299	fixdfsi \
300	fixsfsi \
301	floatsidf \
302	floatsisf \
303	floatunsidf \
304	floatunsisf \
305	comparedf2 \
306	comparesf2 \
307	modsi3 \
308	muldf3 \
309	mulsf3 \
310	mulodi4 \
311	negdf2 \
312	negsf2 \
313	subdf3 \
314	subsf3 \
315	switch16 \
316	switch32 \
317	switch8 \
318	switchu8 \
319	truncdfsf2 \
320	udivsi3 \
321	umodsi3 \
322	unorddf2 \
323	unordsf2
324
325CCKEXT_ARMVFP_FUNCTIONS := $(CCKEXT_ARM_FUNCTIONS) \
326	adddf3vfp \
327	addsf3vfp \
328	divdf3vfp \
329	divsf3vfp \
330	eqdf2vfp \
331	eqsf2vfp \
332	extendsfdf2vfp \
333	fixdfsivfp \
334	fixsfsivfp \
335	fixunsdfsivfp \
336	fixunssfsivfp \
337	floatsidfvfp \
338	floatsisfvfp \
339	floatunssidfvfp \
340	floatunssisfvfp \
341	gedf2vfp \
342	gesf2vfp \
343	gtdf2vfp \
344	gtsf2vfp \
345	ledf2vfp \
346	lesf2vfp \
347	ltdf2vfp \
348	ltsf2vfp \
349	muldf3vfp \
350	mulsf3vfp \
351	nedf2vfp \
352	nesf2vfp \
353	subdf3vfp \
354	subsf3vfp \
355	truncdfsf2vfp \
356	unorddf2vfp \
357	unordsf2vfp
358
359CCKEXT_ARM64_FUNCTIONS := \
360	$(CCKEXT_PROFILE_FUNCTIONS) \
361	divdc3 \
362	divsc3 \
363	muldc3 \
364	mulsc3 \
365	udivti3 \
366	umodti3
367
368FUNCTIONS.cc_kext_ios.armv7 := $(CCKEXT_ARMVFP_FUNCTIONS)
369FUNCTIONS.cc_kext_ios.armv7k := $(CCKEXT_ARMVFP_FUNCTIONS)
370FUNCTIONS.cc_kext_ios.armv7s := $(CCKEXT_ARMVFP_FUNCTIONS)
371FUNCTIONS.cc_kext_ios.arm64 := $(CCKEXT_ARM64_FUNCTIONS)
372
373CCKEXT_X86_FUNCTIONS := $(CCKEXT_COMMON_FUNCTIONS) \
374	divxc3 \
375	fixunsxfdi \
376	fixunsxfsi \
377	fixxfdi \
378	floatdixf \
379	floatundixf \
380	mulxc3 \
381	powixf2
382
383FUNCTIONS.cc_kext.i386 := $(CCKEXT_X86_FUNCTIONS) \
384	ffssi2 \
385	i686.get_pc_thunk.eax \
386	i686.get_pc_thunk.ebp \
387	i686.get_pc_thunk.ebx \
388	i686.get_pc_thunk.ecx \
389	i686.get_pc_thunk.edi \
390	i686.get_pc_thunk.edx \
391	i686.get_pc_thunk.esi
392
393FUNCTIONS.cc_kext.x86_64 := $(CCKEXT_X86_FUNCTIONS) \
394	absvti2 \
395	addvti3 \
396	ashlti3 \
397	ashrti3 \
398	clzti2 \
399	cmpti2 \
400	ctzti2 \
401	divti3 \
402	ffsti2 \
403	fixdfti \
404	fixsfti \
405	fixunsdfti \
406	fixunssfti \
407	fixunsxfti \
408	fixxfti \
409	floattidf \
410	floattisf \
411	floattixf \
412	floatuntidf \
413	floatuntisf \
414	floatuntixf \
415	lshrti3 \
416	modti3 \
417	multi3 \
418	mulvti3 \
419	negti2 \
420	negvti2 \
421	parityti2 \
422	popcountti2 \
423	subvti3 \
424	ucmpti2 \
425	udivmodti4 \
426	udivti3 \
427	umodti3
428
429FUNCTIONS.cc_kext.x86_64h := $(FUNCTIONS.cc_kext.x86_64)
430
431# FIXME: Currently, compiler-rt is missing implementations for a number of the
432# functions that need to go into libcc_kext.a. Filter them out for now.
433CCKEXT_MISSING_FUNCTIONS := \
434	cmpdf2 cmpsf2 div0 \
435	ffssi2 \
436	udiv_w_sdiv unorddf2 unordsf2 bswapdi2 \
437	bswapsi2 \
438	gcc_bcmp \
439	do_global_dtors \
440	i686.get_pc_thunk.eax i686.get_pc_thunk.ebp i686.get_pc_thunk.ebx \
441	i686.get_pc_thunk.ecx i686.get_pc_thunk.edi i686.get_pc_thunk.edx \
442	i686.get_pc_thunk.esi \
443	aeabi_cdcmpeq aeabi_cdrcmple aeabi_cfcmpeq aeabi_cfrcmple aeabi_dcmpeq \
444	aeabi_dcmpge aeabi_dcmpgt aeabi_dcmple aeabi_dcmplt aeabi_drsub aeabi_fcmpeq \
445	aeabi_fcmpge aeabi_fcmpgt aeabi_fcmple aeabi_fcmplt aeabi_frsub aeabi_idivmod \
446	aeabi_uidivmod
447
448FUNCTIONS.cc_kext_ios.armv7 := \
449	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.armv7))
450FUNCTIONS.cc_kext_ios.armv7k := \
451	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.armv7k))
452FUNCTIONS.cc_kext_ios.armv7s := \
453	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.armv7s))
454FUNCTIONS.cc_kext_ios.arm64 := \
455	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext_ios.arm64))
456FUNCTIONS.cc_kext.i386 := \
457	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.i386))
458FUNCTIONS.cc_kext.x86_64 := \
459	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.x86_64))
460FUNCTIONS.cc_kext.x86_64h := \
461	$(filter-out $(CCKEXT_MISSING_FUNCTIONS),$(FUNCTIONS.cc_kext.x86_64h))
462
463KERNEL_USE.cc_kext := 1
464KERNEL_USE.cc_kext_ios := 1
465
466VISIBILITY_HIDDEN := 1
467
468SHARED_LIBRARY_SUFFIX := dylib
469