make: Port some core build utils to Kuroko

This commit is contained in:
K. Lange 2021-04-28 06:41:55 +09:00
parent 3818df0749
commit b4de7633c3
8 changed files with 132 additions and 107 deletions

1
.gitignore vendored
View File

@ -31,6 +31,7 @@
/util/local /util/local
/util/devtable /util/devtable
/util/tmp-gcc /util/tmp-gcc
/util/kuroko
/kernel/symbols.S /kernel/symbols.S
/base/usr/python /base/usr/python
/base/usr/bin/* /base/usr/bin/*

View File

@ -116,10 +116,10 @@ fatbase/kernel: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} kernel/symbols.o ${EXTRALIB}
# build the kernel as a flat binary or load it with less-capable # build the kernel as a flat binary or load it with less-capable
# multiboot loaders and still get symbols, which we need to # multiboot loaders and still get symbols, which we need to
# load kernel modules and link them properly. # load kernel modules and link them properly.
kernel/symbols.o: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} util/generate_symbols.py ${EXTRALIB} kernel/symbols.o: ${KERNEL_ASMOBJS} ${KERNEL_OBJS} util/generate_symbols.krk ${EXTRALIB} | util/kuroko
-rm -f kernel/symbols.o -rm -f kernel/symbols.o
${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o .toaruos-kernel ${KERNEL_ASMOBJS} ${KERNEL_OBJS} ${LGCC} ${KCC} -T kernel/link.ld ${KCFLAGS} -nostdlib -o .toaruos-kernel ${KERNEL_ASMOBJS} ${KERNEL_OBJS} ${LGCC}
${KNM} .toaruos-kernel -g | util/generate_symbols.py > kernel/symbols.S ${KNM} .toaruos-kernel -g | util/kuroko util/generate_symbols.krk > kernel/symbols.S
${KAS} ${KASFLAGS} kernel/symbols.S -o $@ ${KAS} ${KASFLAGS} kernel/symbols.S -o $@
-rm -f .toaruos-kernel -rm -f .toaruos-kernel
@ -196,11 +196,11 @@ base/lib/libc.so: ${LIBC_OBJS} | dirs crts
base/lib/libm.so: util/lm.c | dirs crts base/lib/libm.so: util/lm.c | dirs crts
$(CC) -nodefaultlibs -o $@ $(CFLAGS) -shared -fPIC $^ -lgcc $(CC) -nodefaultlibs -o $@ $(CFLAGS) -shared -fPIC $^ -lgcc
KUROKO_OBJS=$(patsubst %.c, %.o, $(filter-out kuroko/src/module_% kuroko/src/rline.c kuroko/src/kuroko.c, $(sort $(wildcard kuroko/src/*.c)))) KUROKO_OBJS=$(patsubst %.c, %.o, $(filter-out kuroko/src/kuroko.c,$(sort $(wildcard kuroko/src/*.c))))
kuroko/%.o: kuroko/%.c kuroko/%.o: kuroko/%.c
$(CC) $(CFLAGS) -fPIC -c -o $@ $^ $(CC) $(CFLAGS) -fPIC -c -o $@ $^
KUROKO_CMODS=$(patsubst kuroko/src/module_%.c,%,$(wildcard kuroko/src/module_*.c)) $(patsubst lib/kuroko/%.c,%,$(wildcard lib/kuroko/*.c)) KUROKO_CMODS=$(patsubst kuroko/src/modules/module_%.c,%,$(wildcard kuroko/src/modules/module_*.c)) $(patsubst lib/kuroko/%.c,%,$(wildcard lib/kuroko/*.c))
KUROKO_CMODS_X=$(foreach lib,$(KUROKO_CMODS),base/lib/kuroko/$(lib).so) KUROKO_CMODS_X=$(foreach lib,$(KUROKO_CMODS),base/lib/kuroko/$(lib).so)
KUROKO_CMODS_Y=$(foreach lib,$(KUROKO_CMODS),.make/$(lib).kmak) KUROKO_CMODS_Y=$(foreach lib,$(KUROKO_CMODS),.make/$(lib).kmak)
KUROKO_KRK_MODS=$(patsubst kuroko/modules/%.krk,base/lib/kuroko/%.krk,$(wildcard kuroko/modules/*.krk kuroko/modules/*/*.krk)) KUROKO_KRK_MODS=$(patsubst kuroko/modules/%.krk,base/lib/kuroko/%.krk,$(wildcard kuroko/modules/*.krk kuroko/modules/*/*.krk))
@ -211,11 +211,15 @@ base/lib/kuroko/%.krk: kuroko/modules/%.krk
@mkdir -p `dirname $@` @mkdir -p `dirname $@`
cp $< $@ cp $< $@
.make/%.kmak: kuroko/src/module_%.c util/auto-dep.py | dirs MINIMAL_KUROKO = $(filter-out kuroko/src/modules/module_%,$(sort $(wildcard kuroko/src/*.c)))
util/auto-dep.py --makekurokomod $< > $@ util/kuroko: $(MINIMAL_KUROKO)
gcc -Ikuroko/src -DNO_RLINE -DSTATIC_ONLY -DKRK_DISABLE_THREADS -o $@ $^
.make/%.kmak: lib/kuroko/%.c util/auto-dep.py | dirs .make/%.kmak: kuroko/src/modules/module_%.c util/auto-dep.krk | dirs util/kuroko
util/auto-dep.py --makekurokomod $< > $@ util/kuroko util/auto-dep.krk --makekurokomod $< > $@
.make/%.kmak: lib/kuroko/%.c util/auto-dep.krk | dirs util/kuroko
util/kuroko util/auto-dep.krk --makekurokomod $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS))) ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${KUROKO_CMODS_Y} -include ${KUROKO_CMODS_Y}
@ -230,8 +234,8 @@ base/lib/ld.so: linker/linker.c base/lib/libc.a | dirs
$(CC) -static -Wl,-static $(CFLAGS) -o $@ -Os -T linker/link.ld $< $(CC) -static -Wl,-static $(CFLAGS) -o $@ -Os -T linker/link.ld $<
# Shared Libraries # Shared Libraries
.make/%.lmak: lib/%.c util/auto-dep.py | dirs crts .make/%.lmak: lib/%.c util/auto-dep.krk | dirs crts util/kuroko
util/auto-dep.py --makelib $< > $@ util/kuroko util/auto-dep.krk --makelib $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS))) ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${LIBS_Y} -include ${LIBS_Y}
@ -243,8 +247,8 @@ fatbase/netinit: util/netinit.c base/lib/libc.a | dirs
# Userspace applications # Userspace applications
.make/%.mak: apps/%.c util/auto-dep.py | dirs crts .make/%.mak: apps/%.c util/auto-dep.krk | dirs crts util/kuroko
util/auto-dep.py --make $< > $@ util/kuroko util/auto-dep.krk --make $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS))) ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${APPS_Y} -include ${APPS_Y}
@ -343,8 +347,9 @@ clean:
rm -f base/lib/crt*.o rm -f base/lib/crt*.o
rm -f ${MODULES} rm -f ${MODULES}
rm -f ${APPS_Y} ${LIBS_Y} ${EXT_LIBS_Y} rm -f ${APPS_Y} ${LIBS_Y} ${EXT_LIBS_Y}
rm -f ${KUROKO_FILES} rm -f ${KUROKO_FILES} ${KUROKO_CMODS_Y} ${KUROKO_CMODS_X}
rm -f kuroko/src/*.o rm -f kuroko/src/*.o
rm -f util/kuroko
ifneq (,$(findstring Microsoft,$(shell uname -r))) ifneq (,$(findstring Microsoft,$(shell uname -r)))
QEMU_ARGS=-serial mon:stdio -m 1G -rtc base=localtime -vnc :0 QEMU_ARGS=-serial mon:stdio -m 1G -rtc base=localtime -vnc :0
@ -419,8 +424,8 @@ EXT_LIBS=$(patsubst ext/%.c,%,$(wildcard ext/*.c))
EXT_LIBS_X=$(foreach lib,$(EXT_LIBS),base/lib/libtoaru_$(lib).so) EXT_LIBS_X=$(foreach lib,$(EXT_LIBS),base/lib/libtoaru_$(lib).so)
EXT_LIBS_Y=$(foreach lib,$(EXT_LIBS),.make/$(lib).elmak) EXT_LIBS_Y=$(foreach lib,$(EXT_LIBS),.make/$(lib).elmak)
.make/%.elmak: ext/%.c util/auto-dep.py | dirs .make/%.elmak: ext/%.c util/auto-dep.krk | dirs util/kuroko
util/auto-dep.py --makelib $< > $@ util/kuroko util/auto-dep.krk --makelib $< > $@
ifeq (,$(findstring clean,$(MAKECMDGOALS))) ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include ${EXT_LIBS_Y} -include ${EXT_LIBS_Y}

View File

@ -621,14 +621,39 @@ static void handleSigint(int sigNum) {
krk_currentThread.flags |= KRK_THREAD_SIGNALLED; krk_currentThread.flags |= KRK_THREAD_SIGNALLED;
} }
#ifndef _WIN32
static void handleSigtrap(int sigNum) { static void handleSigtrap(int sigNum) {
if (!krk_currentThread.frameCount) return; if (!krk_currentThread.frameCount) return;
krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP; krk_currentThread.flags |= KRK_THREAD_SINGLE_STEP;
} }
#endif
static void bindSignalHandlers(void) { static void bindSignalHandlers(void) {
#if !defined(_WIN32) && !defined(__toaru__)
struct sigaction sigIntAction;
sigIntAction.sa_handler = handleSigint;
sigemptyset(&sigIntAction.sa_mask);
sigIntAction.sa_flags = 0; /* Do not restore the default, do not restart syscalls, do not pass go, do not collect $500 */
sigaction(
SIGINT, /* ^C for keyboard interrupts */
&sigIntAction,
NULL);
struct sigaction sigTrapAction;
sigTrapAction.sa_handler = handleSigtrap;
sigemptyset(&sigTrapAction.sa_mask);
sigTrapAction.sa_flags = 0;
sigaction(
SIGTRAP,
&sigTrapAction,
NULL);
#else
signal(SIGINT, handleSigint); signal(SIGINT, handleSigint);
# ifndef _WIN32
signal(SIGTRAP, handleSigtrap); signal(SIGTRAP, handleSigtrap);
/* No SIGTRAP on windows? */
# endif
#endif
} }
static void findInterpreter(char * argv[]) { static void findInterpreter(char * argv[]) {

2
kuroko

@ -1 +1 @@
Subproject commit 06a00b4f0d6260000afd386551ef70c3eadfc59f Subproject commit 567a0037319fb8d65a990aa31de3a6051bd91cd4

View File

@ -1,15 +1,12 @@
#!/usr/bin/env python3 #!/bin/kuroko
# coding: utf-8 import os, kuroko, fileio
import os let cflags = "-O2 -g -std=gnu99 -I. -Iapps -pipe -mmmx -msse -msse2 -fplan9-extensions -Wall -Wextra -Wno-unused-parameter"
import sys
import subprocess def basename(path):
return path.strip('/').split('/')[-1]
cflags = "-O2 -g -std=gnu99 -I. -Iapps -pipe -mmmx -msse -msse2 -fplan9-extensions -Wall -Wextra -Wno-unused-parameter"
class Classifier(object):
class Classifier:
dependency_hints = { dependency_hints = {
# Toaru Standard Library # Toaru Standard Library
'<toaru/kbd.h>': (None, '-ltoaru_kbd', []), '<toaru/kbd.h>': (None, '-ltoaru_kbd', []),
@ -53,42 +50,42 @@ class Classifier(object):
for k in new: for k in new:
if not k in depends: if not k in depends:
depends.append(k) depends.append(k)
_, _, other = self.dependency_hints[k] let other = self.dependency_hints[k][2]
depends = self._calculate(depends, other) depends = self._calculate(depends, other)
return depends return depends
def _sort(self, depends): def _sort(self, depends):
"""Sort the list of dependencies so that elements appearing first depend on elements following.""" """Sort the list of dependencies so that elements appearing first depend on elements following."""
satisfied = [] let satisfied = []
a = depends[:] let a = depends[:]
while set(satisfied) != set(depends): while set(satisfied) != set(depends):
b = [] let b = []
for k in a: for k in a:
if all([x in satisfied for x in self.dependency_hints[k][2]]): if all(x in satisfied for x in self.dependency_hints[k][2]):
satisfied.append(k) satisfied.append(k)
else: else:
b.append(k) b.append(k)
a = b[:] a = b[:]
return satisfied[::-1] return reversed(satisfied)
def _depends(self): def _depends(self):
"""Calculate include and library dependencies.""" """Calculate include and library dependencies."""
lines = [] let lines = []
depends = [] let depends = []
with open(self.filename,'r') as f: with fileio.open(self.filename,'r') as f:
lines = f.readlines() lines = f.readlines()
for l in lines: for l in lines:
if l.startswith('#include'): if l.startswith('#include'):
depends.extend([k for k in list(self.dependency_hints.keys()) if l.startswith('#include ' + k)]) depends.extend(k for k in list(self.dependency_hints.keys()) if l.startswith('#include ' + k))
elif l.startswith('/* auto-dep: export-dynamic */'): elif l.startswith('/* auto-dep: export-dynamic */'):
self.export_dynamic_hint = True self.export_dynamic_hint = True
depends = self._calculate([], depends) depends = self._calculate([], depends)
depends = self._sort(depends) depends = self._sort(depends)
includes = [] let includes = []
libraries = [] let libraries = []
for k in depends: for k in depends:
dep = self.dependency_hints[k] let dep = self.dependency_hints[k]
if dep[0]: if dep[0]:
includes.append('-I' + 'base/usr/include/' + dep[0]) includes.append('-I' + 'base/usr/include/' + dep[0])
if dep[1]: if dep[1]:
@ -101,11 +98,11 @@ def todep(name):
if name.startswith("-l"): if name.startswith("-l"):
name = name.replace("-l","",1) name = name.replace("-l","",1)
if name.startswith('toaru'): if name.startswith('toaru'):
return (True, "%s/lib%s.so" % ('base/lib', name)) return (True, "{}/lib{}.so".format('base/lib', name))
elif name.startswith('kuroko'): elif name.startswith('kuroko'):
return (True, "%s/lib%s.so" % ('base/lib', name)) return (True, "{}/lib{}.so".format('base/lib', name))
else: else:
return (True, "%s/lib%s.so" % ('base/usr/lib', name)) return (True, "{}/lib{}.so".format('base/usr/lib', name))
else: else:
return (False, name) return (False, name)
@ -116,37 +113,36 @@ def toheader(name):
return '' return ''
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 3: if len(kuroko.argv) < 3:
print("usage: util/auto-dep.py command filename") print("usage: util/auto-dep.krk command filename")
exit(1) return 1
command = sys.argv[1] let command = kuroko.argv[1]
filename = sys.argv[2] let filename = kuroko.argv[2]
let c = Classifier(filename)
c = Classifier(filename)
if command == "--cflags": if command == "--cflags":
print(" ".join([x for x in c.includes])) print(" ".join([x for x in c.includes]))
elif command == "--libs": elif command == "--libs":
print(" ".join([x for x in c.libs])) print(" ".join([x for x in c.libs]))
elif command == "--deps": elif command == "--deps":
results = [todep(x) for x in c.libs] let results = [todep(x) for x in c.libs]
normal = [x[1] for x in results if not x[0]] let normal = [x[1] for x in results if not x[0]]
order_only = [x[1] for x in results if x[0]] let order_only = [x[1] for x in results if x[0]]
print(" ".join(normal) + " | " + " ".join(order_only)) print(" ".join(normal) + " | " + " ".join(order_only))
elif command == "--build": elif command == "--build":
subprocess.run("gcc {cflags} {extra} {includes} -o {app} {source} {libraries}".format( os.system("gcc {cflags} {extra} {includes} -o {app} {source} {libraries}".format(
cflags=cflags, cflags=cflags,
app=os.path.basename(filename).replace(".c",""), app=basename(filename).replace(".c",""),
source=filename, source=filename,
headers=" ".join([toheader(x) for x in c.libs]), headers=" ".join([toheader(x) for x in c.libs]),
libraries=" ".join([x for x in c.libs]), libraries=" ".join([x for x in c.libs]),
includes=" ".join([x for x in c.includes if x is not None]), includes=" ".join([x for x in c.includes if x is not None]),
extra="-Wl,--export-dynamic" if c.export_dynamic_hint else "", extra="-Wl,--export-dynamic" if c.export_dynamic_hint else "",
), shell=True) ))
elif command == "--buildlib": elif command == "--buildlib":
libname = os.path.basename(filename).replace(".c","") let libname = basename(filename).replace(".c","")
_libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname] let _libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname]
subprocess.run("gcc {cflags} {includes} -shared -fPIC -olibtoaru_{lib}.so {source} {libraries}".format( os.system("gcc {cflags} {includes} -shared -fPIC -olibtoaru_{lib}.so {source} {libraries}".format(
cflags=cflags, cflags=cflags,
lib=libname, lib=libname,
source=filename, source=filename,
@ -154,21 +150,21 @@ if __name__ == "__main__":
libraryfiles=" ".join([todep(x)[1] for x in _libs]), libraryfiles=" ".join([todep(x)[1] for x in _libs]),
libraries=" ".join([x for x in _libs]), libraries=" ".join([x for x in _libs]),
includes=" ".join([x for x in c.includes if x is not None]) includes=" ".join([x for x in c.includes if x is not None])
),shell=True) ))
elif command == "--make": elif command == "--make":
print("base/bin/{app}: {source} {headers} util/auto-dep.py | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) {extra} {includes} -o $@ $< {libraries}".format( print("base/bin/{app}: {source} {headers} util/auto-dep.krk | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) {extra} {includes} -o $@ $< {libraries}".format(
app=os.path.basename(filename).replace(".c",""), app=basename(filename).replace(".c",""),
source=filename, source=filename,
headers=" ".join([toheader(x) for x in c.libs]), headers=" ".join([toheader(x) for x in c.libs]),
libraryfiles=" ".join([todep(x)[1] for x in c.libs]), libraryfiles=" ".join([todep(x)[1] for x in c.libs]),
libraries=" ".join([x for x in c.libs]), libraries=" ".join([x for x in c.libs]),
includes=" ".join([x for x in c.includes if x is not None]), includes=" ".join([x for x in c.includes if x is not None]),
extra="-Wl,--export-dynamic" if c.export_dynamic_hint else "", extra="-Wl,--export-dynamic" if c.export_dynamic_hint else ""
)) ))
elif command == "--makelib": elif command == "--makelib":
libname = os.path.basename(filename).replace(".c","") let libname = basename(filename).replace(".c","")
_libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname] let _libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname]
print("base/lib/libtoaru_{lib}.so: {source} {headers} util/auto-dep.py | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) {includes} -shared -fPIC -o $@ $< {libraries}".format( print("base/lib/libtoaru_{lib}.so: {source} {headers} util/auto-dep.krk | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) {includes} -shared -fPIC -o $@ $< {libraries}".format(
lib=libname, lib=libname,
source=filename, source=filename,
headers=" ".join([toheader(x) for x in c.libs]), headers=" ".join([toheader(x) for x in c.libs]),
@ -177,9 +173,9 @@ if __name__ == "__main__":
includes=" ".join([x for x in c.includes if x is not None]) includes=" ".join([x for x in c.includes if x is not None])
)) ))
elif command == "--makekurokomod": elif command == "--makekurokomod":
libname = os.path.basename(filename).replace(".c","").replace("module_","") let libname = basename(filename).replace(".c","").replace("module_","")
_libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname] let _libs = [x for x in c.libs if not x.startswith('-ltoaru_') or x.replace("-ltoaru_","") != libname]
print("base/lib/kuroko/{lib}.so: {source} {headers} util/auto-dep.py | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) {includes} -shared -fPIC -o $@ $< {libraries}".format( print("base/lib/kuroko/{lib}.so: {source} {headers} util/auto-dep.krk | {libraryfiles} $(LC)\n\t$(CC) $(CFLAGS) {includes} -shared -fPIC -o $@ $< {libraries}".format(
lib=libname, lib=libname,
source=filename, source=filename,
headers=" ".join([toheader(x) for x in c.libs]), headers=" ".join([toheader(x) for x in c.libs]),
@ -188,3 +184,4 @@ if __name__ == "__main__":
includes=" ".join([x for x in c.includes if x is not None]) includes=" ".join([x for x in c.includes if x is not None])
)) ))

View File

@ -34,6 +34,9 @@ def file_filter(tarinfo):
elif tarinfo.name in restricted_files: elif tarinfo.name in restricted_files:
tarinfo.mode = restricted_files[tarinfo.name] tarinfo.mode = restricted_files[tarinfo.name]
if tarinfo.name.startswith('usr/include/kuroko') and tarinfo.type == tarfile.SYMTYPE:
return None
if tarinfo.name.startswith('src'): if tarinfo.name.startswith('src'):
# Let local own the files here # Let local own the files here
tarinfo.uid = users.get('local') tarinfo.uid = users.get('local')
@ -57,6 +60,7 @@ with tarfile.open('fatbase/ramdisk.img','w') as ramdisk:
ramdisk.add('modules',arcname='/src/modules',filter=file_filter) ramdisk.add('modules',arcname='/src/modules',filter=file_filter)
if os.path.exists('tags'): if os.path.exists('tags'):
ramdisk.add('tags',arcname='/src/tags',filter=file_filter) ramdisk.add('tags',arcname='/src/tags',filter=file_filter)
ramdisk.add('util/build-the-world.py',arcname='/usr/bin/build-the-world.py',filter=file_filter) ramdisk.add('util/auto-dep.krk',arcname='/usr/bin/auto-dep.krk',filter=file_filter)
ramdisk.add('kuroko/src/kuroko',arcname='/usr/include/kuroko',filter=file_filter)

32
util/generate_symbols.krk Executable file
View File

@ -0,0 +1,32 @@
#!/usr/bin/env kuroko
'''
@brief Generate symbol table.
'''
import fileio
let size = 'long'
def extern(sym):
print(f'.extern {sym}')
print(f'.type {sym}, @function')
def entry(sym):
print(f'.{size} {sym}')
print(f'.asciz "{sym}"')
let ignore = ['abs','kernel_symbols_start','kernel_symbols_end']
let lines = [x.strip().split(' ')[2] for x in fileio.stdin.readlines() if x not in ignore]
print('.section .symbols')
print()
for name in lines:
extern(name)
print('.global kernel_symbols_start')
print('kernel_symbols_start:')
print()
for name in lines:
entry(name)
print('.global kernel_symbols_end')
print('kernel_symbols_end:')

View File

@ -1,39 +0,0 @@
#!/usr/bin/env python3
"""
Generate a symbol table from nm output.
"""
import sys
# Write extern + type
def extern(name):
print(".extern %s" % (name))
print(".type %s, @function" % (name))
print("")
# Write an entry
def entry(name):
print(".long %s" % (name))
print(".asciz \"%s\"" % (name))
print("")
ignore = [ "abs", "kernel_symbols_start", "kernel_symbols_end" ]
lines = [ x.strip().split(" ")[2] for x in sys.stdin.readlines() if x not in ignore ]
# Generate the assembly
print(".section .symbols")
print("")
for name in lines:
extern(name)
print(".global kernel_symbols_start")
print("kernel_symbols_start:")
print("")
for name in lines:
entry(name)
print(".global kernel_symbols_end")
print("kernel_symbols_end:")