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 test_expressions_with_globals(self): """ See if expressions involving global variables can be evaluated """ src = """ module x; var int Xa; var int[10] B; var struct{int g;int f;}[10] C; var int* D; """ obj = c3c([io.StringIO(src)], [], self.arch, debug=True) self.debugger.load_symbols(obj) self.assertEqual(0, self.debugger.eval_c3_str('Xa').value) self.assertEqual(-9, self.debugger.eval_c3_str('Xa + 1 -10').value) self.assertEqual(20, self.debugger.eval_c3_str('(Xa + 1)*20').value) with self.assertRaises(CompilerError): self.debugger.eval_c3_str('(Xa + 1.2)*"hello"') with self.assertRaises(CompilerError): self.debugger.eval_c3_str('Baa') with self.assertRaises(CompilerError): self.debugger.eval_c3_str('B') with self.assertRaises(CompilerError): self.debugger.eval_c3_str('B.d') self.assertEqual(22, self.debugger.eval_c3_str('B[2] + 22').value) with self.assertRaises(CompilerError): self.debugger.eval_c3_str('C[1]') self.assertEqual(32, self.debugger.eval_c3_str('C[2].f+22+0xA').value) self.assertEqual(0, self.debugger.eval_c3_str('D').value) self.assertEqual(0, self.debugger.eval_c3_str('*D').value) self.debugger.eval_c3_str('&D') self.debugger.eval_c3_str('+D') self.debugger.eval_c3_str('-D')
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 generate_code(module): """ Generate code """ march = 'x86_64' obj1 = api.ir_to_object([module], march) obj2 = api.asm('crt0.asm', march) obj3 = api.c3c(['crt0.c3'], [], march) obj = api.link([obj1, obj2, obj3]) with open('test.oj', 'w') as f: obj.save(f)
def setUpClass(cls): src = """ module x; var int Xa; function int sum(int a, int b) { var int sum = 0; sum = sum + a + b + Xa; return a +sum+ b + 1234; } """ cls.obj = c3c([io.StringIO(src)], [], 'arm', debug=True)
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 test_recursive_types(self): """ Test how infinite deep type structures such as linked lists work out """ src = """ module x; type struct { int payload; node_t* next; } node_t; var node_t* root; """ obj = c3c([io.StringIO(src)], [], 'arm', debug=True) # print(obj.debug_info.types) debuginfo.serialize(obj.debug_info)
def test_two_files(self): src1 = """ module x; var int Xa; function int sum(int a, int b) { var int sum = 0; sum = sum + a + b + Xa; return a +sum+ b + 1234; } """ src2 = """ module y; var int Xa; function int sum(int a, int b) { var int sum = 0; sum = sum + a + b + Xa; return a +sum+ b + 1234; } """ layout = """ MEMORY rom LOCATION=0x8000 SIZE=0x3000 { DEFINESYMBOL(codestart) SECTION(code) DEFINESYMBOL(codeend) } MEMORY ram LOCATION=0x2000 SIZE=0x3000 { SECTION(data) } """ obj1 = c3c([io.StringIO(src1)], [], 'arm', debug=True) obj2 = c3c([io.StringIO(src2)], [], 'arm', debug=True) obj = link([obj1, obj2], layout=io.StringIO(layout), debug=True) self.assertTrue(obj.debug_info.locations) self.assertEqual(2, len(obj.debug_info.functions)) self.assertEqual(2, len(obj.debug_info.variables))
def test_export_ldb(self): """ Check the exporting to ldb format """ src = """ module x; var int Xa; function int sum(int a, int b) { var int sum = 0; sum = sum + a + b + Xa; return a +sum+ b + 1234; } """ obj = c3c([io.StringIO(src)], [], 'arm', debug=True) self.assertTrue(obj.debug_info.locations) self.assertTrue(obj.debug_info.functions) self.assertTrue(obj.debug_info.variables) output_file = io.StringIO() write_ldb(obj, output_file) self.assertTrue(output_file.getvalue())
def test_expressions_with_locals(self): """ See if expressions involving local variables can be evaluated """ src = """ module x; var int Xa; function int main() { var int Xa, b; Xa = 2; b = 2; return Xa + b; } """ obj = c3c([io.StringIO(src)], [], self.arch, debug=True) self.debugger.load_symbols(obj) self.assertEqual(0, self.debugger.eval_c3_str('Xa').value) self.assertEqual(-9, self.debugger.eval_c3_str('Xa + 1 -10').value) self.assertEqual(20, self.debugger.eval_c3_str('(Xa + 1)*20').value) self.assertEqual(0, self.debugger.eval_c3_str('b').value) self.debugger.current_function()
""" Takes a web assembly module and turns it into riscv code """ import logging from ppci.api import asm, c3c, link, get_arch, wasmcompile from ppci.binutils.objectfile import merge_memories from ppci.utils.reporting import html_reporter logging.basicConfig(level=logging.INFO) arch = get_arch('riscv') obj1 = asm("start.s", arch) with html_reporter('report.html') as reporter: srcs = ['../src/wasm_fac/main.c3', '../../librt/io.c3', 'c3src/bsp.c3'] obj2 = c3c(srcs, [], arch, reporter=reporter) with open('../src/wasm_fac/fact.wasm', 'rb') as f2: obj3 = wasmcompile(f2, arch) obj = link([obj1, obj2, obj3], "firmware.mmap", use_runtime=True, reporter=reporter, debug=True) size = 0x2000 cimg = obj.get_image('flash') dimg = obj.get_image('ram') img = merge_memories(cimg, dimg, 'img') imgdata = img.data with open("firmware.hex", "w") as f: for i in range(size): if i < len(imgdata) // 4:
if args.debug: obj1 = asm("startdbg.s", arch) else: obj1 = asm("start.s", arch) c3_sources = [ os.path.join("c3src", "bsp.c3"), os.path.join("c3src", "io.c3"), os.path.join("c3src", args.example, "main.c3"), ] if args.debug: c3_sources.append(os.path.join("c3src", "gdbstub.c3")) c3_sources.append(os.path.join("c3src", "irq.c3")) obj2 = c3c( c3_sources, [], "riscv", reporter=reporter, debug=True, opt_level=2 ) obj = link( [obj1, obj2], "firmware.mmap", use_runtime=False, reporter=reporter, debug=True, ) with open("firmware.oj", "w") as of: obj.save(of) objcopy(obj, "flash", "bin", "code.bin") objcopy(obj, "ram", "bin", "data.bin") objcopy(obj, "flash", "elf", "firmware.elf")
lhs = self.emit(ir.Binop(lhs, '*', rhs, 'prod', self.int_type)) product.ir_value = lhs def get_value(self, value): if isinstance(value, int): ir_value = self.emit(ir.Const(value, 'constant', self.int_type)) elif isinstance(value, str): ir_value = self.load_var(value) else: ir_value = value.ir_value return ir_value def load_var(self, var_name): mem_loc = self.variables[var_name] return self.emit(ir.Load(mem_loc, var_name, self.int_type)) tcfCompiler = TcfCompiler() ir_module = tcfCompiler.compile('example.tcf') obj1 = api.ir_to_object([ir_module], 'x86_64') obj2 = api.c3c(['bsp.c3', 'io.c3'], [], 'x86_64') obj3 = api.asm('linux.asm', 'x86_64') obj = api.link([obj1, obj2, obj3], layout='layout.mmap') print(obj) with open('example.oj', 'w') as f: obj.save(f) api.objcopy(obj, 'code', 'elf', 'example')
layout = """ MEMORY flash LOCATION=0x100 SIZE=0x800 { SECTION(reset) SECTION(code) } MEMORY ram LOCATION=0x001000 SIZE=0x800 { SECTION(data) } """ obj1 = api.asm(io.StringIO(boot_src), 'or1k') with html_reporter('report.html') as reporter: obj2 = api.c3c([io.StringIO(src)], [], march='or1k', opt_level=2, reporter=reporter) print('Bootcode:', obj1) print('Program code:', obj2) obj = api.link([obj1, obj2], layout=io.StringIO(layout)) print('Total:', obj) # api.objcopy(obj, 'flash', 'bin', 'baremetal.bin') # Create uboot image: data = obj.get_image('flash').data with open('baremetal.bin', 'wb') as f: write_uboot_image(f, data)
import logging from ppci import api logging.basicConfig(level=logging.INFO) arch = api.get_arch('x86_64:wincc') obj1 = api.c3c( ['../src/hello/hello.c3', '../../librt/io.c3', 'bsp.c3', 'kernel32.c3'], [], arch) with open('kernel32.s', 'r') as f: obj2 = api.asm(f, arch) obj = api.link([obj1, obj2], partial_link=True) print(obj) api.objcopy(obj, 'code', 'exe', 'hello.exe')
coptions.add_define('COMPILER_VERSION', '"ppci {}"'.format(ppci_version)) 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()
product.ir_value = lhs def get_value(self, value): if isinstance(value, int): ir_value = self.emit(ir.Const(value, 'constant', self.int_type)) elif isinstance(value, str): ir_value = self.load_var(value) else: # It must be an expression! ir_value = value.ir_value return ir_value def load_var(self, var_name): mem_loc = self.variables[var_name] return self.emit(ir.Load(mem_loc, var_name, self.int_type)) tcf_compiler = TcfCompiler() ir_module = tcf_compiler.compile('example.tcf') obj1 = api.ir_to_object([ir_module], 'x86_64') obj2 = api.c3c(['bsp.c3', '../../librt/io.c3'], [], 'x86_64') obj3 = api.asm('linux.asm', 'x86_64') obj = api.link([obj1, obj2, obj3], layout='layout.mmap') print(obj) with open('example.oj', 'w') as f: obj.save(f) # Create a linux elf file: api.objcopy(obj, 'code', 'elf', 'example')
layout = """ MEMORY flash LOCATION=0x100 SIZE=0x800 { SECTION(reset) SECTION(code) } MEMORY ram LOCATION=0x001000 SIZE=0x800 { SECTION(data) } """ obj1 = api.asm(io.StringIO(boot_src), 'or1k') with open('report.html', 'w') as f: obj2 = api.c3c([io.StringIO(src)], [], march='or1k', opt_level=2, reporter=HtmlReportGenerator(f)) print('Bootcode:', obj1) print('Program code:', obj2) obj = api.link([obj1, obj2], layout=io.StringIO(layout)) print('Total:', obj) # api.objcopy(obj, 'flash', 'bin', 'baremetal.bin') # Create uboot image: data = obj.get_image('flash').data with open('baremetal.bin', 'wb') as f: write_uboot_image(f, data)
def build(base_filename, src, bsp_c3, crt0_asm, march, opt_level, mmap, lang='c3', bin_format=None, elf_format=None, code_image='code'): """ Construct object file from source snippet """ list_filename = base_filename + '.html' with HtmlReportGenerator(open(list_filename, 'w')) as reporter: o1 = asm(crt0_asm, march) 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 = [o1, o2] elif lang == 'bf': o3 = bfcompile(src, march, reporter=reporter) o2 = c3c([bsp_c3], [], march, reporter=reporter) objs = [o1, 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, reporter=reporter) o4 = cc(io.StringIO(src), march, coptions=coptions, reporter=reporter) objs = [o1, o2, o3, o4] else: raise NotImplementedError('language not implemented') obj = link(objs, layout=mmap, use_runtime=True, reporter=reporter, debug=True) # Save object: obj_file = base_filename + '.oj' with open(obj_file, 'w') as f: obj.save(f) if elf_format: elf_filename = base_filename + '.' + elf_format objcopy(obj, code_image, elf_format, elf_filename) # Export code image to some format: if bin_format: sample_filename = base_filename + '.' + bin_format objcopy(obj, code_image, bin_format, sample_filename) return obj