def partial_build(src, lang, bsp_c3, opt_level, march, reporter): """ Compile source and return an object """ if lang == 'c3': srcs = [relpath('..', 'librt', 'io.c3'), bsp_c3, io.StringIO(src)] o2 = c3c(srcs, [], march, opt_level=opt_level, reporter=reporter, debug=True) objs = [o2] elif lang == 'bf': o3 = bfcompile(src, march, reporter=reporter) o2 = c3c([bsp_c3], [], march, reporter=reporter) objs = [o2, o3] elif lang == 'c': o2 = c3c([bsp_c3], [], march, reporter=reporter) coptions = COptions() include_path1 = relpath('..', 'librt', 'libc') coptions.add_include_path(include_path1) with open(relpath('..', 'librt', 'libc', 'lib.c'), 'r') as f: o3 = cc(f, march, coptions=coptions, debug=True, reporter=reporter) o4 = cc(io.StringIO(src), march, coptions=coptions, debug=True, reporter=reporter) objs = [o2, o3, o4] else: raise NotImplementedError('language not implemented') obj = link(objs, partial_link=True, use_runtime=True, reporter=reporter, debug=True) return obj
def perform_test(filename): """ Try to compile the given snippet. """ logger.info("Step 1: Compile %s!", filename) march = "x86_64" html_report = os.path.splitext(filename)[0] + "_report.html" coptions = COptions() root_folder = os.path.join(this_dir, "..", "..", "..") libc_folder = os.path.join(root_folder, "librt", "libc") libc_include = os.path.join(libc_folder, "include") coptions.add_include_path(libc_include) # TODO: this should be injected elsewhere? coptions.add_define('__LP64__', '1') # coptions.enable('freestanding') with html_reporter(html_report) as reporter: with open(filename, "r") as f: try: obj1 = api.cc(f, march, coptions=coptions, reporter=reporter) except CompilerError as ex: ex.print() raise logger.info("Compilation complete, %s", obj1) obj0 = api.asm(io.StringIO(STARTERCODE), march) obj2 = api.c3c([io.StringIO(BSP_C3_SRC)], [], march) with open(os.path.join(libc_include, "lib.c"), "r") as f: obj3 = api.cc(f, march, coptions=coptions) obj = api.link([obj0, obj1, obj2, obj3], layout=io.StringIO(ARCH_MMAP)) logger.info("Step 2: Run it!") exe_filename = os.path.splitext(filename)[0] + "_executable.elf" with open(exe_filename, "wb") as f: write_elf(obj, f, type="executable") api.chmod_x(exe_filename) logger.info("Running %s", exe_filename) test_prog = subprocess.Popen(exe_filename, stdout=subprocess.PIPE) exit_code = test_prog.wait() assert exit_code == 0 captured_stdout = test_prog.stdout.read().decode("ascii") with open(filename + ".expected", "r") as f: expected_stdout = f.read() # Compare stdout: assert captured_stdout == expected_stdout
def do_compile(filename, include_paths, arch, reporter): coptions = COptions() coptions.add_include_paths(include_paths) coptions.add_define("FPM_DEFAULT", "1") with open(filename, "r") as f: obj = cc(f, arch, coptions=coptions, reporter=reporter) return obj
def test_jit_example(self): """ Test loading of C code from jit example """ source = io.StringIO(""" int x(int* a, int* b, int count) { int sum = 0; int i; for (i=0; i < count; i++) sum += a[i] * b[i]; return sum; } """) arch = get_current_arch() html_filename = make_filename(self.id()) + '.html' with open(html_filename, 'w') as f, HtmlReportGenerator(f) as reporter: obj = cc(source, arch, debug=True, reporter=reporter) m = load_obj(obj) # print(m.x.argtypes) T = ctypes.c_int * 6 a = T() # TODO: integers in ctypes are 32 bit, they are 64 bit in ppci? a[:] = 1, 0, 2, 0, 3, 0 # ap = ctypes.cast(a, ctypes.POINTER(ctypes.c_long)) b = T() b[:] = 5, 0, 4, 0, 9, 0 # bp = ctypes.cast(b, ctypes.POINTER(ctypes.c_long)) y = m.x(a, b, 3) self.assertEqual(40, y)
def compile_nos_for_riscv(): """ Compile nOS for riscv architecture. """ logging.basicConfig(level=logging.INFO) murax_folder = os.path.join(this_dir, "..", "examples", "riscvmurax") arch = api.get_arch("riscv") # Gather sources: path = os.path.join(murax_folder, "csrc", "nos") folders, srcs = get_sources(path, "*.c") folders += [os.path.join(murax_folder, "csrc")] print(srcs) coptions = COptions() for folder in folders: coptions.add_include_path(folder) # Build code: o1 = api.asm(os.path.join(murax_folder, "start.s"), arch) o2 = api.asm(os.path.join(murax_folder, "nOSPortasm.s"), arch) objs = [o1, o2] for src in srcs: with open(src) as f: objs.append(api.cc(f, "riscv", coptions=coptions, debug=True)) # Link code: api.link( objs, os.path.join(murax_folder, "firmware.mmap"), use_runtime=True, debug=True, )
def test_jit_example(self): """ Test loading of C code from jit example """ source = io.StringIO(""" int mega_complex_stuff(int* a, int* b, int count) { int sum = 0; int i; for (i=0; i < count; i++) sum += a[i] * b[i]; return sum; } """) arch = get_current_arch() html_filename = make_filename(self.id()) + '.html' with open(html_filename, 'w') as f, HtmlReportGenerator(f) as reporter: obj = cc(source, arch, debug=True, reporter=reporter) m = load_obj(obj) # print(m.x.argtypes) count = 6 T = ctypes.c_int * count a = T() a[:] = 1, 0, 2, 0, 3, 0 b = T() b[:] = 5, 0, 4, 0, 9, 0 y = m.mega_complex_stuff(a, b, count) self.assertEqual(40, y)
def build_sample_to_code(src, lang, bsp_c3, opt_level, march, debug, reporter): """ Turn example sample into code objects. """ if lang == "c3": srcs = [relpath("..", "librt", "io.c3"), bsp_c3, io.StringIO(src)] o2 = api.c3c( srcs, [], march, opt_level=opt_level, reporter=reporter, debug=debug, ) objs = [o2] elif lang == "bf": o3 = api.bfcompile(src, march, reporter=reporter) o2 = api.c3c([bsp_c3], [], march, reporter=reporter) objs = [o2, o3] elif lang == "c": o2 = api.c3c([bsp_c3], [], march, reporter=reporter) coptions = COptions() libc_path = relpath("..", "librt", "libc") include_path1 = os.path.join(libc_path, "include") coptions.add_include_path(include_path1) with open(relpath("..", "librt", "libc", "lib.c"), "r") as f: o3 = api.cc(f, march, coptions=coptions, debug=debug, reporter=reporter) o4 = api.cc( io.StringIO(src), march, coptions=coptions, debug=debug, reporter=reporter, ) objs = [o2, o3, o4] elif lang == "pas": o3 = api.pascal([io.StringIO(src)], march, reporter=reporter, debug=debug) o2 = api.c3c([bsp_c3], [], march, reporter=reporter) objs = [o2, o3] else: raise NotImplementedError("language not implemented") return objs
def test_c(self): """ Test loading of C code """ source = io.StringIO("int x(int a) { return a + 1 ; }") arch = get_current_arch() obj = cc(source, arch, debug=True) m = load_obj(obj) y = m.x(101) self.assertEqual(102, y)
def test_inline_asm(self): """ Test the compilation of inline assembly code. """ src = """ int foo(int a, int b, char c) { asm ( "mov rsi, %0\n" "xor rsi, %1\n" "and rsi, %1\n" : : "r" (a), "r" (c) : "rsi" ); return b; } """ march = get_arch('x86_64') cc(io.StringIO(src), march)
def do_compile(filename): coptions = COptions() include_paths = [ libc_includes, src_folder, ] coptions.add_include_paths(include_paths) with open(filename, 'r') as f: obj = cc(f, arch, coptions=coptions) return obj
def test_static_link(self): arch = 'arm' o1 = cc(io.StringIO(""" static int add(int a, int b) { return a + b; } int voodoo1(int a) { return add(a, 12); } """), arch) o2 = cc(io.StringIO(""" static int add(int a, int b) { return a + b; } int voodoo2(int a) { return add(a, 12); } """), arch) link([o1, o2])
def do_compile(filename): include_paths = [ os.path.join(newlib_folder, 'libc', 'include'), libc_includes, ] coptions = COptions() coptions.add_include_paths(include_paths) coptions.add_define('HAVE_CONFIG_H') coptions.add_define('__MSP430__') with open(filename, 'r') as f: obj = cc(f, arch, coptions=coptions) return obj
def cc(filename): logging.info('Compiling %s', filename) with open(os.path.join(this_dir, filename)) as f: try: obj = api.cc(f, arch, reporter=reporter, coptions=coptions) logging.info('Compiled %s into %s bytes', filename, obj.byte_size) except CompilerError as e: print(e) e.print() obj = None return obj
def do_compile(filename): include_paths = [ os.path.join(musl_folder, 'include'), os.path.join(musl_folder, 'src', 'internal'), os.path.join(musl_folder, 'obj', 'include'), os.path.join(musl_folder, 'arch', 'x86_64'), os.path.join(musl_folder, 'arch', 'generic'), ] coptions = COptions() coptions.add_include_paths(include_paths) with open(filename, 'r') as f: obj = cc(f, 'x86_64', coptions=coptions) return obj
def perform_test(filename): """ Try to compile the given snippet. """ logger.info("Step 1: Compile %s!", filename) march = "x86_64" coptions = COptions() libc_include = os.path.join(this_dir, "..", "..", "..", "librt", "libc") coptions.add_include_path(libc_include) coptions.enable('freestanding') with open(filename, "r") as f: try: obj = api.cc(f, march, coptions=coptions) except CompilerError as ex: ex.print() raise logger.info("Compilation complete, %s", obj) logger.info("Step 2: Run it!") logger.error("Running not yet implemented")
def test_callback_from_c(self): """ Test calling a python function from C code """ source = io.StringIO(""" int add(int x, int y); int x(int a) { return add(a + 1, 13); } """) arch = get_current_arch() obj = cc(source, arch, debug=True) def my_add(x: int, y: int) -> int: return x + y + 2 imports = {'add': my_add} m = load_obj(obj, imports=imports) y = m.x(101) self.assertEqual(117, y)
def compile_8cc(): """ Compile the 8cc compiler. 8cc homepage: https://github.com/rui314/8cc """ home = os.environ['HOME'] _8cc_folder = os.path.join(home, 'GIT', '8cc') libc_includes = os.path.join(this_dir, '..', 'librt', 'libc', 'include') linux_include_dir = '/usr/include' arch = api.get_arch('x86_64') coptions = COptions() include_paths = [ libc_includes, _8cc_folder, linux_include_dir, ] coptions.add_include_paths(include_paths) coptions.add_define('BUILD_DIR', '"{}"'.format(_8cc_folder)) sources = [ 'cpp.c', 'debug.c', 'dict.c', 'gen.c', 'lex.c', 'vector.c', 'parse.c', 'buffer.c', 'map.c', 'error.c', 'path.c', 'file.c', 'set.c', 'encoding.c', ] objs = [] for filename in sources: source_path = os.path.join(_8cc_folder, filename) with open(source_path, 'r') as f: objs.append(api.cc(f, arch, coptions=coptions))
def do_compile(filename, coptions, reporter): with open(filename, 'r') as f: obj = cc(f, arch, coptions=coptions, reporter=reporter) return obj
def do_compile(filename, reporter): with open(filename, 'r') as f: obj = api.cc(f, arch, coptions=coptions, reporter=reporter) print(filename, 'compiled into', obj) return obj
// This will trigger relocations on the data section: double a; double *pa = &a; // idea: link with libc for putchar! int putchar(int); int magic_helper(int x) { putchar(65); // 'A' return x + 1 + *pa; } int barf(int x, double y) { putchar(66); // 'B' return magic_helper(x) - y; } """ obj = api.cc(io.StringIO(c_src), 'x86_64') print(obj) with open('barf.o', 'wb') as f: write_elf(obj, f, type='relocatable')
from ppci.lang.basic.c64 import BasicLine, write_basic_program arch = api.get_arch('mcs6500') print('Using arch', arch) if len(sys.argv) > 1: with open(sys.argv[1], 'r') as f: text_message = f.read() else: text_message = 'you can provide a text file to customize this message' with html_reporter('report.html') reporter: with open('add.c') as f: oj = api.cc(f, arch, reporter=reporter) print(oj) with open('hello.s') as f: oj = api.asm(f, arch) oj = api.link([oj], layout='layout.mmp') print(oj) with open(os.path.join('c64disk', 'hello.prg'), 'wb') as f: # Generate tokenized basic: load_address = 0x801 basic_program = bytes([ 0x01, 0x08, # Load address 0x09, 0x08, # start of the next line 0x0a, 0x00, # line number 10 word in little endianness # 0x9e, 0x20, 0x34, 0x30, 0x39, 0x36, 0x00, # SYS 4096
return((resdirs, resfiles)) with html_reporter('report.html') as reporter: arch = get_arch('riscv:rvf') o1 = asm("src/crt1.s", arch) path = os.path.join('.','src',argv[1]) dirs, srcs = get_sources(path, '*.c') dirs += [os.path.join('.','src')] obj = [] coptions = COptions() for dir in dirs: coptions.add_include_path(dir) for src in srcs: with open(src) as f: obj.append(cc(f, "riscv:rvf", coptions=coptions, debug=True, reporter=reporter)) obj = link([o1] + obj, "firmware.mmap", use_runtime=True, reporter=reporter, debug=True) with open("firmware.oj", "w") as of: obj.save(of) objcopy(obj, "flash", "elf", "firmware.elf") objcopy(obj, "flash", "bin", "code.bin") objcopy(obj, "ram", "bin", "data.bin") size = 0x8000 cimg = obj.get_image('flash') dimg = obj.get_image('ram') img = merge_memories(cimg, dimg, 'img') imgdata = img.data with open("image.bin", "wb") as f:
with open('report.html', 'w') as f: archname = 'riscv:rva' if (len(argv)==4): archname +=':' + argv[3] arch = get_arch(archname) o1 = asm("sw/" + argv[1] + "/src/crt1.s", arch) reporter = HtmlReportGenerator(f) path = os.path.join('.','sw',argv[1],'src',argv[2]) dirs, srcs = get_sources(path, '*.c') dirs += [os.path.join('.','sw',argv[1],'src')] srcs += [os.path.join('.','sw',argv[1],'src','bsp.c')] + [os.path.join('.','sw',argv[1],'src','lib.c')] obj = [] coptions = COptions() for dir in dirs: coptions.add_include_path(dir) for src in srcs: with open(src) as f: obj.append(cc(f, archname, coptions=coptions, debug=True, reporter=reporter)) obj = link([o1] + obj, "./sw/"+argv[1]+"/firmware.mmap", use_runtime=True, reporter=reporter, debug=True) cimg = obj.get_image('flash') dimg = obj.get_image('ram') img = merge_memories(cimg, dimg, 'img') imgdata = img.data with open(argv[1] + ".bin", "wb") as f: f.write(imgdata)
"mov rdi, %1 \n" "mov rsi, %2 \n" "mov rdx, %3 \n" "syscall \n" : : "r" (nr), "r" (a), "r" (b), "r" (c) // input registers, patched into %0 .. %3 : "rax", "rdi", "rsi", "rdx" // clobber registers, handled by the register allocator ); } """ layout = """ ENTRY(main) MEMORY code LOCATION=0x40000 SIZE=0x10000 { SECTION(code) } MEMORY ram LOCATION=0x20000000 SIZE=0xA000 { SECTION(data) } """ obj_glue = cc(io.StringIO(c_glue), 'x86_64') obj = link([obj_py, obj_glue], layout=io.StringIO(layout)) print(obj) objcopy(obj, None, "elf", "mandelbrot")
import io from ppci.api import cc, link, asm from ppci.format.srecord import write_srecord from ppci.format.hunk import write_hunk source = """ int add(int x, int y) { return x + y; } """ obj = cc(io.StringIO(source), 'm68k') obj = link([obj]) print(obj) print(""" Please now open the online disassembler: https://onlinedisassembler.com/odaweb/ Select m68k:68000 and paste: {} """.format(obj.get_section('code').data.hex())) # TODO:
import logging from ppci.api import cc logging.basicConfig(level=logging.DEBUG) with open('main.c', 'r') as f: obj = cc(f, 'x86_64', debug=True) print('Object file created:', obj) with open('hello.oj', 'w') as f: obj.save(f)
coptions.add_define('FLAGS_STR', '"-O{}"'.format(opt_level)) # Prevent malloc / free usage: coptions.add_define('MEM_METHOD', 'MEM_STATIC') # TODO: Hack to enable %f formatting: coptions.add_define('__x86_64__', '1') objs = [] crt0_asm = os.path.join(linux64_folder, 'glue.asm') crt0_c3 = os.path.join(linux64_folder, 'bsp.c3') linker_script = os.path.join(linux64_folder, 'linux64.mmap') objs.append(api.asm(crt0_asm, march)) objs.append(api.c3c([crt0_c3], [], march)) objs.append(api.cc(io.StringIO(hacked_libc_extras), march, coptions=coptions)) sources = list(glob.glob(os.path.join(core_mark_folder, '*.c'))) sources.extend(glob.glob(os.path.join(port_folder, '*.c'))) sources.extend(glob.glob(os.path.join(libc_folder, '*.c'))) for source_file in sources: print(source_file) try: with open(source_file, 'r') as f: obj = api.cc(f, march, coptions=coptions, opt_level=opt_level) except CompilerError as ex: print('ERROR!') print(ex) ex.print() else:
import logging from ppci.api import cc logging.basicConfig(level=logging.DEBUG) with open('main.c', 'r') as f: obj = cc(f, 'x86_64') print('Object file created:', obj) with open('hello.oj', 'w') as f: obj.save(f)
o1 = asm("start.s", arch) o2 = asm("nOSPortasm.s", arch) path = os.path.join('.', 'csrc', argv[1]) dirs, srcs = get_sources(path, '*.c') #srcs += [os.path.join('.','csrc','bsp.c')] + [os.path.join('.','csrc','lib.c')] dirs += [os.path.join('.', 'csrc')] obj = [] coptions = COptions() for dir in dirs: coptions.add_include_path(dir) for src in srcs: with open(src) as f: obj.append( cc(f, "riscv", coptions=coptions, debug=True, reporter=reporter)) obj = link([o1, o2] + obj, "firmware.mmap", use_runtime=True, reporter=reporter, debug=True) with open("firmware.oj", "w") as of: obj.save(of) objcopy(obj, "flash", "elf", "firmware.elf") objcopy(obj, "flash", "bin", "code.bin") objcopy(obj, "ram", "bin", "data.bin") size = 0x8000
def do_compile(filename, coptions): # coptions.add_define('NORETURN') with open(filename, 'r') as f: obj = cc(f, arch, coptions=coptions) return obj