1SubDir HAIKU_TOP src tools gensyscalls ;
2
3
4# What want to do here is analyze the <syscalls.h> header and generate headers
5# and sources containing information about the syscalls (like what parameters
6# of what sizes and types they take, etc.) which will be used in other places
7# (e.g. the kernel code or the strace tool).
8#
9# The strategy to achieve this is:
10# * Preprocess the <syscalls.h> header, so that it is easier to parse.
11# * Feed the preprocessed header to the gensyscallinfos tool. It will generate
12#	a source file, gensyscalls_infos.cpp, which implements a function that
13#	builds a table with all the syscall info information we need. The source
14#	file needs specific infos about sizes of types, which aren't easily
15#	available. That's why gensyscallinfos also generates a source file which
16#	via the CreateAsmStructOffsetsHeader rule is turned into a header with
17#	macro definitions for those type size. The header is included by
18#	gensyscalls_infos.cpp.
19# * gensyscalls.cpp and the generated gensyscalls_infos.cpp are compiled into
20#	the gensyscalls tool.
21# * gensyscalls has options to generate the various output files:
22#	- <syscalls!$(architecture>syscalls.S.inc: Used to define the syscall
23#     functions in libroot.
24#	- <syscalls!$(architecture>syscall_dispatcher.h: Big "switch" statement for
25#     the syscall dispatcher in the kernel.
26#	- <syscalls!$(architecture>syscall_numbers.h: Macro definitions assigning
27#     indices to the syscalls.
28#	- <syscalls!$(architecture>syscall_table.h: An array with syscall
29#     information in the kernel. Used for dispatching syscalls e.g. for x86.
30#	- <syscalls!$(architecture>strace_syscalls.h: Syscall information needed by
31#     strace.
32
33
34rule PreprocessSyscalls preprocessedHeader : header : architecture
35{
36	# PreprocessSyscalls <preprocessedHeader> : <header> : <architecture> ;
37
38	Depends $(preprocessedHeader) : $(header) $(PLATFORM) ;
39
40	local headers = [ on $(preprocessedHeader)
41		return $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
42	local sysHeaders =
43		$(TARGET_PRIVATE_SYSTEM_HEADERS_$(architecture))
44		[ ArchHeaders $(TARGET_ARCH_$(architecture)) ]
45		[ on $(preprocessedHeader) return $(SUBDIRSYSHDRS) $(SYSHDRS) ]
46		[ FStandardHeaders $(architecture) ]
47		$(TARGET_HDRS_$(architecture)) ;
48
49	HDRS on $(preprocessedHeader) = $(headers) ;
50	SYSHDRS on $(preprocessedHeader) = $(sysHeaders) ;
51
52	HDRRULE on $(header) = HdrRule ;
53	HDRSCAN on $(header) = $(HDRPATTERN) ;
54	HDRSEARCH on $(header) = $(headers) $(sysHeaders) $(STDHDRS) ;
55	HDRGRIST on $(header) = $(HDRGRIST) ;
56
57	DEFINES on $(preprocessedHeader) += $(TARGET_DEFINES_$(architecture))
58		$(TARGET_DEFINES) GEN_SYSCALL_INFOS_PROCESSING ;
59
60	CC on $(preprocessedHeader) = $(TARGET_C++_$(architecture)) ;
61	CCFLAGS on $(preprocessedHeader) += $(TARGET_CCFLAGS_$(architecture))
62		$(SUBDIRCCFLAGS) $(OPTIM) ;
63	CCHDRS on $(preprocessedHeader) =
64		[ FIncludes $(headers)
65			: $(TARGET_LOCAL_INCLUDES_OPTION_$(architecture)) ]
66		$(TARGET_INCLUDES_SEPARATOR_$(architecture))
67		[ FSysIncludes $(sysHeaders)
68			: $(TARGET_SYSTEM_INCLUDES_OPTION_$(architecture)) ] ;
69	CCDEFS on $(preprocessedHeader)
70		= [ on $(preprocessedHeader) FDefines $(DEFINES) ] ;
71}
72
73
74actions PreprocessSyscalls
75{
76	$(CC) -xc++ -E "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
77}
78
79
80rule GenSyscallInfos targets : sources : gensyscallinfos
81{
82	Depends $(targets) : $(gensyscallinfos) $(sources) ;
83	GenSyscallInfos1 $(targets) : $(gensyscallinfos) $(sources) ;
84}
85
86
87actions GenSyscallInfos1
88{
89	$(2[1]) $(2[2]) $(1)
90}
91
92
93rule GenSyscallsFile file : gensyscalls : option
94{
95	GENSYSCALLS_FILE_OPTION on $(file) = $(option) ;
96	Depends $(file) : $(gensyscalls) ;
97	GenSyscallsFile1 $(file) : $(gensyscalls) ;
98}
99
100
101actions GenSyscallsFile1
102{
103	$(2[1]) $(GENSYSCALLS_FILE_OPTION) $(1)
104}
105
106
107local syscallsHeader = [ FGristFiles syscalls.h ] ;
108SEARCH on $(syscallsHeader) = [ FDirName $(HAIKU_TOP) headers private system ] ;
109
110local architectureObject ;
111for architectureObject in [ MultiArchSubDirSetup ] {
112	on $(architectureObject) {
113		local architecture = $(TARGET_PACKAGING_ARCH) ;
114
115		# Generate the preprocessed syscalls.h header. It will be parsed by
116		# gensyscallinfos (it contains marker #pragmas).
117		local syscallsHeaderPPParsable
118			= [ FGristFiles syscalls.h.pp.parsable ] ;
119		MakeLocateArch $(syscallsHeaderPPParsable) ;
120		PreprocessSyscalls $(syscallsHeaderPPParsable) : $(syscallsHeader)
121			: $(architecture) ;
122
123		# build gensyscallinfos
124
125		local gensyscallinfos = gensyscallinfos_$(architecture) ;
126		SourceHdrs gensyscallinfos.cpp
127			: [ FDirName $(SUBDIR) arch $(TARGET_ARCH_$(architecture)) ] ;
128		MakeLocate [ FGristFiles gensyscallinfos$(SUFOBJ) ]
129			: [ FDirName $(HOST_DEBUG_$(DEBUG)_LOCATE_TARGET) $(architecture) ] ;
130		BuildPlatformMain $(gensyscallinfos)
131			: gensyscallinfos.cpp
132			: $(HOST_LIBSTDC++) $(HOST_LIBSUPC++)
133			;
134
135		# generate the syscall infos source file and the source for the header
136		# it includes
137
138		local syscallInfos = [ FGristFiles gensyscalls_infos.cpp ] ;
139		local syscallTypesSizesSource
140			= [ FGristFiles syscall_types_sizes.h.cpp ] ;
141		local syscallTypesSizes = [ FGristFiles syscall_types_sizes.h ] ;
142		MakeLocateArch $(syscallInfos) $(syscallTypesSizesSource)
143			$(syscallTypesSizes) ;
144
145		GenSyscallInfos $(syscallInfos) $(syscallTypesSizesSource)
146			: $(syscallsHeaderPPParsable) : $(gensyscallinfos) ;
147
148		TARGET_HDRS_$(architecture) on $(syscallTypesSizes)
149			= [ on $(syscallTypesSizes) return $(TARGET_HDRS_$(architecture)) ]
150				[ FDirName $(SUBDIR) arch $(TARGET_ARCH_$(architecture)) ]
151				$(TARGET_PRIVATE_SYSTEM_HEADERS_$(architecture)) ;
152		CreateAsmStructOffsetsHeader $(syscallTypesSizes)
153			: $(syscallTypesSizesSource) : $(TARGET_PACKAGING_ARCH) ;
154
155		#Includes $(syscallInfos) : $(syscallTypesSizes) ;
156			# explicitly tell jam about the inclusion of the generated header
157		Depends $(syscallInfos:S=$(SUFOBJ)) : $(syscallTypesSizes) ;
158			# NOTE: Jam messes up the "Includes" declaration, so we have to declare
159			# the dependency more directly.
160
161		# build gensyscalls
162
163		local gensyscalls = gensyscalls_$(architecture) ;
164		MakeLocate [ FGristFiles gensyscalls$(SUFOBJ) gensyscalls_infos$(SUFOBJ) ]
165			: [ FDirName $(HOST_DEBUG_$(DEBUG)_LOCATE_TARGET) $(architecture) ] ;
166		BuildPlatformMain $(gensyscalls)
167			: gensyscalls.cpp $(syscallInfos) ;
168		LinkAgainst $(gensyscalls) : $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ;
169
170		# generate the output files
171
172		# place them where they are needed
173		local dir = $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(architecture)) ;
174		MakeLocate <syscalls!$(architecture)>syscalls.S.inc
175			: [ FDirName $(dir) system libroot os ] ;
176		MakeLocate <syscalls!$(architecture)>syscall_dispatcher.h
177			: [ FDirName $(dir) system kernel ] ;
178		MakeLocate <syscalls!$(architecture)>syscall_numbers.h
179			: [ FDirName $(dir) system kernel ] ;
180		MakeLocate <syscalls!$(architecture)>syscall_table.h
181			: [ FDirName $(dir) system kernel ] ;
182		MakeLocate <syscalls!$(architecture)>strace_syscalls.h
183			: [ FDirName $(dir) bin debug strace ] ;
184
185		GenSyscallsFile <syscalls!$(architecture)>syscalls.S.inc
186			: $(gensyscalls) : -c ;
187		GenSyscallsFile <syscalls!$(architecture)>syscall_dispatcher.h
188			: $(gensyscalls) : -d ;
189		GenSyscallsFile <syscalls!$(architecture)>syscall_numbers.h
190			: $(gensyscalls) : -n ;
191		GenSyscallsFile <syscalls!$(architecture)>syscall_table.h
192			: $(gensyscalls) : -t ;
193		GenSyscallsFile <syscalls!$(architecture)>strace_syscalls.h
194			: $(gensyscalls) : -s ;
195	}
196}
197