Home | History | Annotate | Download | only in uts
      1 #
      2 # CDDL HEADER START
      3 #
      4 # The contents of this file are subject to the terms of the
      5 # Common Development and Distribution License (the "License").
      6 # You may not use this file except in compliance with the License.
      7 #
      8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9 # or http://www.opensolaris.org/os/licensing.
     10 # See the License for the specific language governing permissions
     11 # and limitations under the License.
     12 #
     13 # When distributing Covered Code, include this CDDL HEADER in each
     14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15 # If applicable, add the following below this CDDL HEADER, with the
     16 # fields enclosed by brackets "[]" replaced with your own identifying
     17 # information: Portions Copyright [yyyy] [name of copyright owner]
     18 #
     19 # CDDL HEADER END
     20 #
     21 #
     22 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23 # Use is subject to license terms.
     24 #
     25 #	This Makefiles contains the common targets and definitions for
     26 #	all kernels. It is to be included in the Makefiles for specific
     27 #	implementation architectures and processor architecture dependent
     28 #	modules: i.e.: all driving kernel Makefiles.
     29 #
     30 
     31 #
     32 #	Default rule for building the lint library directory:
     33 #
     34 $(LINT_LIB_DIR):
     35 	-@mkdir -p $@ 2> /dev/null
     36 
     37 #
     38 #	All C objects depend on inline files. However, cc(1) doesn't generate
     39 #	the correct dependency info. Also, these Makefiles don't contain a
     40 #	separate list of C-derived object files (but it is light weight to
     41 #	let the assembler files think they depend upon this when they don't).
     42 #	Fortunately, the inline files won't change very often. So, for now,
     43 #	all objects depend on the inline files. Remove this when the inliner
     44 #	is fixed to drop correct dependency information.
     45 #
     46 $(OBJECTS): $(INLINES)
     47 
     48 #
     49 #	Partially link .o files to generate the kmod. The fake dependency
     50 #	on modstubs simplifies things...
     51 #	ELFSIGN_MOD is defined in the individual KCF plug-in modules Makefiles,
     52 #	and will sign the ELF objects using elfsign(1).
     53 #
     54 $(BINARY):		$(OBJECTS)
     55 	$(LD) -r $(LDFLAGS) -o $@ $(OBJECTS)
     56 	$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
     57 	$(POST_PROCESS)
     58 	$(ELFSIGN_MOD)
     59 
     60 #
     61 #	This target checks each kmod for undefined entry points. It does not
     62 #	modify the kmod in any way.
     63 #
     64 $(MODULE).check:	FRC
     65 	@BUILD_TYPE=DBG32 $(MAKE) $(MODULE).check.targ
     66 
     67 $(MODULE).check.targ:	$(BINARY) $(OBJECTS) $(EXTRA_CHECK_OBJS) $(UNIX_O) $(MODSTUBS_O) $(GENLIB)
     68 	$(LD) -o /dev/null $(OBJECTS) $(EXTRA_CHECK_OBJS) $(UNIX_O) $(MODSTUBS_O) $(GENLIB)
     69 
     70 #
     71 #	Module lint library construction targets.
     72 #
     73 MOD_LINT_LIB	= $(LINT_LIB_DIR)/llib-l$(LINT_MODULE).ln
     74 
     75 $(MOD_LINT_LIB):	$(LINT_LIB_DIR) $(LINTS)
     76 	@-$(ECHO) "\n$(OBJS_DIR)/$(MODULE): (library construction):"
     77 	@($(LINT) -o $(LINT_MODULE)-$(OBJS_DIR) \
     78 		$(LINTFLAGS) $(LINTS) $(LTAIL))
     79 	@$(MV) llib-l$(LINT_MODULE)-$(OBJS_DIR).ln $@
     80 
     81 $(LINT_MODULE).lint:	$(MOD_LINT_LIB) $(LINT_LIB) $(GEN_LINT_LIB)
     82 	@-$(ECHO) "\n$(OBJS_DIR)/$(LINT_MODULE): global crosschecks:"
     83 	@($(LINT) $(LINTFLAGS) $(MOD_LINT_LIB) \
     84 		$(LINT_LIB) $(GEN_LINT_LIB) $(LTAIL))
     85 
     86 #
     87 # Since assym.h is a derived file, the dependency must be explicit for
     88 # all files including this file. (This is only actually required in the
     89 # instance when the .nse_depinfo file does not exist.) It may seem that
     90 # the lint targets should also have a similar dependency, but they don't
     91 # since only C headers are included when #defined(lint) is true. The
     92 # actual lists are defined in */Makefile.files.
     93 #
     94 $(ASSYM_DEPS:%=$(OBJS_DIR)/%):	$(DSF_DIR)/$(OBJS_DIR)/assym.h
     95 
     96 #
     97 #	Everybody need to know how to create a modstubs.o built with the
     98 #	appropriate flags and located in the appropriate location.
     99 #
    100 $(MODSTUBS_O):	$(MODSTUBS)
    101 	$(COMPILE.s) -o $@ $(MODSTUBS)
    102 
    103 $(LINTS_DIR)/modstubs.ln:	$(MODSTUBS)
    104 	@($(LHEAD) $(LINT.s) $(MODSTUBS) $(LTAIL))
    105 
    106 #
    107 # Build the source file which contains the kernel's utsname,
    108 # with release, version and machine set as follows:
    109 #
    110 #	release: contents of $(RELEASE) (Spaces replaced by '_')
    111 #	version: contents of $(PATCHID) (Spaces replaced by '_')
    112 #	machine: contents of $(UNAME_M)
    113 #
    114 # Build environment information is only contained in the comment section.
    115 #
    116 # The version string, normally the variable VERSION, is set to display
    117 # environmental information temporarily while in development because
    118 # it provides a little more useful information.
    119 #
    120 VERSION_STRING	= ($(ECHO) $$LOGNAME [\`basename $$CODEMGR_WS\`] \\\c; date +%D)
    121 $(INTERNAL_RELEASE_BUILD)VERSION_STRING = $(ECHO) $(PATCHID)
    122 
    123 $(OBJS_DIR)/vers.o: $(OBJECTS)
    124 	$(COMPILE.c) -DUTS_RELEASE=\"`$(ECHO) $(RELEASE) | sed -e 's/ /_/g'`\" \
    125 	    -DUTS_VERSION=\"`$(VERSION_STRING) | sed -e 's/ /_/g'`\" \
    126 	    -DUTS_PLATFORM=\"$(UNAME_M)\" -o $@ $(SRC)/uts/common/os/vers.c
    127 	$(CTFCONVERT_O)
    128 	$(POST_PROCESS_O)
    129 
    130 $(LINTS_DIR)/vers.ln: $(SRC)/uts/common/os/vers.c
    131 	@($(LHEAD) $(LINT.c) -DUTS_RELEASE=\"\" -DUTS_VERSION=\"\" \
    132 	    -DUTS_PLATFORM=\"\" $(SRC)/uts/common/os/vers.c $(LTAIL))
    133 
    134 #
    135 #	Installation targets and rules:
    136 #
    137 $(ROOT_MOD_DIR) $(USR_MOD_DIR):
    138 	-$(INS.dir)
    139 
    140 $(ROOT_MOD_DIRS_32):	$(ROOT_MOD_DIR)
    141 	-$(INS.dir)
    142 
    143 $(USR_MOD_DIRS_32):	$(USR_MOD_DIR)
    144 	-$(INS.dir)
    145 
    146 $(ROOT_MOD_DIR)/%:	$(OBJS_DIR)/% $(ROOT_MOD_DIR) FRC
    147 	$(INS.file)
    148 
    149 $(ROOT_CPU_DIR)/%:	$(OBJS_DIR)/% $(ROOT_CPU_DIR) FRC
    150 	$(INS.file)
    151 
    152 $(ROOT_DRV_DIR)/%:	$(OBJS_DIR)/% $(ROOT_DRV_DIR) FRC
    153 	$(INS.file)
    154 
    155 $(ROOT_DTRACE_DIR)/%:	$(OBJS_DIR)/% $(ROOT_DTRACE_DIR) FRC
    156 	$(INS.file)
    157 
    158 $(ROOT_EXEC_DIR)/%:	$(OBJS_DIR)/% $(ROOT_EXEC_DIR) FRC
    159 	$(INS.file)
    160 
    161 $(ROOT_FS_DIR)/%:	$(OBJS_DIR)/% $(ROOT_FS_DIR) FRC
    162 	$(INS.file)
    163 
    164 $(ROOT_SCHED_DIR)/%:	$(OBJS_DIR)/% $(ROOT_SCHED_DIR) FRC
    165 	$(INS.file)
    166 
    167 $(ROOT_SOCK_DIR)/%:	$(OBJS_DIR)/% $(ROOT_SOCK_DIR) FRC
    168 	$(INS.file)
    169 
    170 $(ROOT_STRMOD_DIR)/%:	$(OBJS_DIR)/% $(ROOT_STRMOD_DIR) FRC
    171 	$(INS.file)
    172 
    173 $(ROOT_IPP_DIR)/%:	$(OBJS_DIR)/% $(ROOT_IPP_DIR) FRC
    174 	$(INS.file)
    175 
    176 $(ROOT_SYS_DIR)/%:	$(OBJS_DIR)/% $(ROOT_SYS_DIR) FRC
    177 	$(INS.file)
    178 
    179 $(ROOT_MISC_DIR)/%:	$(OBJS_DIR)/% $(ROOT_MISC_DIR) FRC
    180 	$(INS.file)
    181 
    182 $(ROOT_DACF_DIR)/%:	$(OBJS_DIR)/% $(ROOT_DACF_DIR) FRC
    183 	$(INS.file)
    184 
    185 $(ROOT_BRAND_DIR)/%:	$(OBJS_DIR)/% $(ROOT_BRAND_DIR) FRC
    186 	$(INS.file)
    187 
    188 $(ROOT_CRYPTO_DIR)/%:	$(OBJS_DIR)/% $(ROOT_CRYPTO_DIR) FRC
    189 	$(INS.file)
    190 
    191 $(ROOT_KGSS_DIR)/%:	$(OBJS_DIR)/% $(ROOT_KGSS_DIR) FRC
    192 	$(INS.file)
    193 
    194 $(ROOT_SCSI_VHCI_DIR)/%: $(OBJS_DIR)/% $(ROOT_SCSI_VHCI_DIR) FRC
    195 	$(INS.file)
    196 
    197 $(ROOT_PMCS_FW_DIR)/%:	$(OBJS_DIR)/% $(ROOT_PMCS_FW_DIR) FRC
    198 	$(INS.file)
    199 
    200 $(ROOT_QLC_FW_DIR)/%:	$(OBJS_DIR)/% $(ROOT_QLC_FW_DIR) FRC
    201 	$(INS.file)
    202 
    203 $(ROOT_EMLXS_FW_DIR)/%:	$(OBJS_DIR)/% $(ROOT_EMLXS_FW_DIR) FRC
    204 	$(INS.file)
    205 
    206 $(ROOT_MACH_DIR)/%:	$(OBJS_DIR)/% $(ROOT_MACH_DIR) FRC
    207 	$(INS.file)
    208 
    209 $(ROOT_FONT_DIR)/%:	$(OBJS_DIR)/% $(ROOT_MOD_DIR) $(ROOT_FONT_DIR) FRC
    210 	$(INS.file)
    211 
    212 $(ROOT_MAC_DIR)/%:	$(OBJS_DIR)/% $(ROOT_MOD_DIR) $(ROOT_MAC_DIR) FRC
    213 	$(INS.file)
    214 
    215 $(USR_DRV_DIR)/%:	$(OBJS_DIR)/% $(USR_DRV_DIR) FRC
    216 	$(INS.file)
    217 
    218 $(USR_EXEC_DIR)/%:	$(OBJS_DIR)/% $(USR_EXEC_DIR) FRC
    219 	$(INS.file)
    220 
    221 $(USR_FS_DIR)/%:	$(OBJS_DIR)/% $(USR_FS_DIR) FRC
    222 	$(INS.file)
    223 
    224 $(USR_SCHED_DIR)/%:	$(OBJS_DIR)/% $(USR_SCHED_DIR) FRC
    225 	$(INS.file)
    226 
    227 $(USR_SOCK_DIR)/%:	$(OBJS_DIR)/% $(USR_SOCK_DIR) FRC
    228 	$(INS.file)
    229 
    230 $(USR_STRMOD_DIR)/%:	$(OBJS_DIR)/% $(USR_STRMOD_DIR) FRC
    231 	$(INS.file)
    232 
    233 $(USR_SYS_DIR)/%:	$(OBJS_DIR)/% $(USR_SYS_DIR) FRC
    234 	$(INS.file)
    235 
    236 $(USR_MISC_DIR)/%:	$(OBJS_DIR)/% $(USR_MISC_DIR) FRC
    237 	$(INS.file)
    238 
    239 $(USR_DACF_DIR)/%:	$(OBJS_DIR)/% $(USR_DACF_DIR) FRC
    240 	$(INS.file)
    241 
    242 $(USR_PCBE_DIR)/%:	$(OBJS_DIR)/% $(USR_PCBE_DIR) FRC
    243 	$(INS.file)
    244 
    245 $(USR_DTRACE_DIR)/%:	$(OBJS_DIR)/% $(USR_DTRACE_DIR) FRC
    246 	$(INS.file)
    247 
    248 $(USR_BRAND_DIR)/%:	$(OBJS_DIR)/% $(USR_BRAND_DIR) FRC
    249 	$(INS.file)
    250 
    251 $(ROOT_KICONV_DIR)/%:	$(OBJS_DIR)/% $(ROOT_KICONV_DIR) FRC
    252 	$(INS.file)
    253 
    254 include $(SRC)/Makefile.psm.targ
    255 
    256 #
    257 #	Target for 64b modules
    258 #
    259 $(ROOT_KERN_DIR_64):
    260 	-$(INS.dir)
    261 
    262 $(ROOT_KERN_DIR_64)/%:	$(OBJS_DIR)/% $(ROOT_KERN_DIR_64) FRC
    263 	$(INS.file)
    264 
    265 %/$(SUBDIR64):		%
    266 	-$(INS.dir)
    267 
    268 #
    269 #	Targets for '.conf' file installation.
    270 #
    271 $(ROOT_CONFFILE):	$(SRC_CONFFILE)	$(ROOT_CONFFILE:%/$(CONFFILE)=%)
    272 	$(INS.conffile)
    273 
    274 #
    275 #	Targets for creating links between common platforms. ROOT_PLAT_LINKS
    276 #	are are the /platform level while ROOT_PLAT_LINKS_2 are one level
    277 #	down (/platform/`uname -i`/{lib|sbin|kernel}.
    278 #
    279 $(ROOT_PLAT_LINKS):
    280 	$(INS.slink1)
    281 
    282 $(ROOT_PLAT_LINKS_2):
    283 	$(INS.slink2)
    284 
    285 $(USR_PLAT_LINKS):
    286 	$(INS.slink1)
    287 
    288 $(USR_PLAT_LINKS_2):
    289 	$(INS.slink2)
    290 
    291 #
    292 # multiple builds support
    293 #
    294 def $(DEF_DEPS)			:= TARGET = def
    295 all $(ALL_DEPS)			:= TARGET = all
    296 clean $(CLEAN_DEPS)		:= TARGET = clean
    297 clobber $(CLOBBER_DEPS)		:= TARGET = clobber
    298 lint $(LINT_DEPS)		:= TARGET = lint
    299 modlintlib $(MODLINTLIB_DEPS)	:= TARGET = modlintlib
    300 modlist	$(MODLIST_DEPS)		:= TARGET = modlist
    301 modlist	$(MODLIST_DEPS)		:= NO_STATE= -K $$MODSTATE$$$$
    302 clean.lint $(CLEAN_LINT_DEPS)	:= TARGET = clean.lint
    303 install $(INSTALL_DEPS)		:= TARGET = install
    304 symcheck $(SYM_DEPS)		:= TARGET = symcheck
    305 
    306 ALL_TARGS	= def all clean clobber lint modlintlib \
    307 		  clean.lint lintlib install symcheck
    308 
    309 ALL_OBJ32	= $(ALL_TARGS:%=%.obj32)
    310 
    311 $(ALL_OBJ32):	FRC
    312 	@BUILD_TYPE=OBJ32 VERSION='$(VERSION)' $(MAKE) $(NO_STATE) $(TARGET).targ
    313 
    314 ALL_DEBUG32	= $(ALL_TARGS:%=%.debug32)
    315 
    316 $(ALL_DEBUG32):	FRC
    317 	@BUILD_TYPE=DBG32 VERSION='$(VERSION)' $(MAKE) $(NO_STATE) $(TARGET).targ
    318 
    319 ALL_OBJ64	= $(ALL_TARGS:%=%.obj64)
    320 
    321 $(ALL_OBJ64):	FRC
    322 	@BUILD_TYPE=OBJ64 VERSION='$(VERSION)' $(MAKE) $(NO_STATE) $(TARGET).targ
    323 
    324 ALL_DEBUG64	= $(ALL_TARGS:%=%.debug64)
    325 
    326 $(ALL_DEBUG64):	FRC
    327 	@BUILD_TYPE=DBG64 VERSION='$(VERSION)' $(MAKE) $(NO_STATE) $(TARGET).targ
    328 
    329 #
    330 #	Currently only the IP module needs symbol checking on obj64.
    331 #	Other modules have the same global-objs nm output for debug64 and obj64.
    332 #
    333 $(SISCHECK_DEPS):	$(DEF_DEPS)
    334 	@TARG=`$(ECHO) $@ | $(CUT) -d'.' -f2`; \
    335 	MODSYMS=$(MODULE).symbols.$$TARG; \
    336 	if [ -f "$(MODULE).global-objs.$$TARG" ]; then \
    337 		$(GREP) -v '#' $(MODULE).global-objs.$$TARG |$(GREP) . | \
    338 		    $(SORT) -u > $$MODSYMS.tmp; \
    339 		$(NM) $$TARG/$(MODULE) |$(GREP) OBJT |$(GREP) -v UNDEF | \
    340 		    $(CUT) -d'|' -f8 |$(GREP) -v '^___const_' | \
    341 		    $(GREP) -v '\.[0-9]*$$' |$(SORT) -u \
    342 		    > $$MODSYMS.tmp.new; \
    343 		$(DIFF) $$MODSYMS.tmp $$MODSYMS.tmp.new > $$MODSYMS.diff || \
    344 		    ($(ECHO) "warning: $(MODULE) symbol checking:" \
    345 		    "global variable(s) introduced and/or removed."; \
    346 		    $(CAT) $$MODSYMS.diff; exit 1) \
    347 	fi
    348 
    349 $(SISCLEAN_DEPS):
    350 	-TARG=`$(ECHO) $@ | $(CUT) -d'.' -f2`; \
    351 	MODSYMS=$(MODULE).symbols.$$TARG; \
    352 	$(RM) $$MODSYMS.tmp $$MODSYMS.tmp.new $$MODSYMS.diff Nothing_to_remove
    353 
    354 
    355 $(OBJS_DIR):
    356 	-@mkdir -p $@ 2> /dev/null
    357 
    358 def.targ:		$(OBJS_DIR) $(ALL_TARGET)
    359 
    360 all.targ:		$(OBJS_DIR) $(ALL_TARGET)
    361 
    362 lint.targ:		$(OBJS_DIR) $(LINT_TARGET)
    363 
    364 modlintlib.targ:	$(OBJS_DIR) $(MOD_LINT_LIB)
    365 
    366 install.targ:		$(OBJS_DIR) $(INSTALL_TARGET)
    367 
    368 #
    369 # Support for Install.sh.
    370 #
    371 
    372 modlist:	$(MODLIST_DEPS)
    373 
    374 # paths relative to $(ROOT).
    375 RELMODULE = $(ROOTMODULE:$(ROOT)/%=%)
    376 RELCONF = $(ROOT_CONFFILE:$(ROOT)/%=%)
    377 RELLINK = $(ROOTLINK:$(ROOT)/%=%)
    378 RELUNIX = $(UNIX32_LINK:$(ROOT)/%=%)
    379 RELSOFTLINKS = $(ROOTSOFTLINKS:$(ROOT)/%=%)
    380 
    381 MODSRC:sh=		pwd
    382 
    383 #
    384 # Changes to this target may require corresponding changes to
    385 # Install.sh.
    386 # Don't issue a MOD entry if it's not in the install list.
    387 #
    388 $(MODLIST_DEPS): FRC
    389 	@case $@ in \
    390 	*32) \
    391 		class=32; \
    392 		relmodule=`dirname $(RELMODULE)`;; \
    393 	*64) \
    394 		class=64; \
    395 		relmodule=`dirname $(RELMODULE)`/$(SUBDIR64);; \
    396 	esac; \
    397 	if [ -z "$(THISIMPL)" ]; then \
    398 		impl=all; \
    399 	else \
    400 		impl=$(THISIMPL); \
    401 	fi; \
    402 	if [ -n "$(ROOTMODULE)" -a -n "$(INSTALL_TARGET)" ]; then \
    403 		if [ -z "$(MODULE)" ]; then \
    404 			module=`basename $(ROOTMODULE)`; \
    405 		else \
    406 			module=$(MODULE); \
    407 		fi; \
    408 		tinstall="$(INSTALL_TARGET)"; \
    409 		for t in $$tinstall; do \
    410 			if [ "$(ROOTMODULE)" = $$t ]; then \
    411 				echo MOD $$module $$relmodule \
    412 				    $$class $$impl $(MODSRC); \
    413 				break; \
    414 			fi \
    415 		done \
    416 	fi; \
    417 	if [ -n "$(CONF_SRCDIR)" ]; then \
    418 		tinstall="$(INSTALL_TARGET)"; \
    419 		for t in $$tinstall; do \
    420 			if [ $(ROOT_CONFFILE) = $$t ]; then \
    421 				echo CONF $(RELCONF) \
    422 				    $(MODSRC)/$(CONF_SRCDIR) $$impl $$module; \
    423 				break; \
    424 			fi \
    425 		done \
    426 	fi; \
    427 	if [ -n "$(ROOTLINK)" ]; then \
    428 		rellinks="$(RELLINK)"; \
    429 		for r in $$rellinks; do \
    430 		if [ $$class = 32 ]; then \
    431 			linkdir=`dirname $$r`; \
    432 		else \
    433 			linkdir=`dirname $$r`/$(SUBDIR64); \
    434 		fi; \
    435 		echo LINK $$relmodule $$module \
    436 			$$linkdir `basename $$r` $$impl; \
    437 		done \
    438 	fi; \
    439 	if [ -n "$(UNIX32_LINK)" ]; then \
    440 		echo SYMLINK $(SUBDIR64)/$(UNIX) \
    441 		    `dirname $(RELUNIX)` unix $$impl $$module; \
    442 	fi; \
    443 	trelsoftlinks="$(RELSOFTLINKS)"; \
    444 	for t in $$trelsoftlinks; do \
    445 		if [ $$class = 32 ]; then \
    446 			linkdir=`dirname $$t`; \
    447 		else \
    448 			linkdir=`dirname $$t`/$(SUBDIR64); \
    449 		fi; \
    450 		linkname=`basename $$t`; \
    451 		echo SYMLINK $(MODULE) $$linkdir $$linkname \
    452 		    $$impl $$module; \
    453 	done
    454 
    455 #
    456 #	Cleanliness is next to ...
    457 #
    458 clean.targ:
    459 	-$(RM) $(CLEANFILES) Nothing_to_remove
    460 
    461 clobber.targ:
    462 	-$(RM) $(CLOBBERFILES) Nothing_to_remove
    463 
    464 clean.lint.targ:
    465 	-$(RM) $(CLEANLINTFILES) Nothing_to_remove
    466 
    467 #
    468 #	Create fake lintlibs in the 64b dirs so
    469 #	global linting works
    470 #
    471 lint64:
    472 	@$(ECHO) $(MODULE) fake lints
    473 	@for dir in $(LINT64_DIRS); do \
    474 		if [ ! -d $$dir ]; then mkdir $$dir; fi \
    475 	done
    476 	@for file in $(LINT64_FILES); do \
    477 		if [ ! -f $$file ]; then touch $$file; fi \
    478 	done
    479 
    480 #
    481 #	In some places we also need to create fake lintlibs for 32b
    482 #	dirs so global linting works
    483 #
    484 lint32:
    485 	@$(ECHO) $(MODULE) fake lints
    486 	@for dir in $(LINT32_DIRS); do \
    487 		if [ ! -d $$dir ]; then mkdir $$dir; fi \
    488 	done
    489 	@for file in $(LINT32_FILES); do \
    490 		if [ ! -f $$file ]; then touch $$file; fi \
    491 	done
    492 
    493 FRC:
    494