towards multi-arch
This commit is contained in:
72
Makefile
72
Makefile
@ -1,42 +1,70 @@
|
||||
FAIL_DIR ?= ~/fail
|
||||
FAIL_BIN ?= ${FAIL_DIR}/build/bin
|
||||
BOCHS_RUNNER ?= python ${FAIL_DIR}/tools/bochs-experiment-runner/bochs-experiment-runner.py
|
||||
FAIL_DOWNLOAD_BASE="https://collaborating.tuhh.de/e-exk4/projects/fail/-/jobs/artifacts/feature/sail/download"
|
||||
|
||||
ARCH ?= bochs
|
||||
|
||||
all: help
|
||||
|
||||
BUILD_DIR := build-${ARCH}
|
||||
FAIL_BIN ?= ${BUILD_DIR}/bin
|
||||
BOCHS_RUNNER ?= ${FAIL_BIN}/bochs-experiment-runner
|
||||
FAIL_SERVER ?= ${FAIL_BIN}/generic-experiment-server
|
||||
FAIL_TRACE ?= ${FAIL_BIN}/fail-generic-tracing
|
||||
FAIL_INJECT ?= ${FAIL_BIN}/fail-generic-experiment
|
||||
FAIL_IMPORT ?= ${FAIL_BIN}/import-trace --enable-sanitychecks
|
||||
FAIL_PRUNE ?= ${FAIL_BIN}/prune-trace
|
||||
|
||||
EXPERIMENTS := $(patsubst %.c,%,$(shell echo *.c))
|
||||
|
||||
all: main/system.iso
|
||||
CFLAGS := -I. -include arch/${ARCH}/lib.c -O2 -std=c11
|
||||
|
||||
include arch/${ARCH}.mk
|
||||
|
||||
$(foreach element,$(EXPERIMENTS),$(eval $(call arch-make-targets,$(element))))
|
||||
|
||||
help:
|
||||
@echo "Small Playground for FAIL* Injections"
|
||||
@echo "-------------------------------------"
|
||||
@echo "Architecture Unspecific Targets:"
|
||||
@echo " \e[3mdocker\e[0m Start a Docker container with all dependencies"
|
||||
@echo " \e[3mdownload\e[0m Download Precompiled FAIL* client"
|
||||
@echo ""
|
||||
@echo "Current Configuartion"
|
||||
@echo " ARCH=${ARCH}"
|
||||
|
||||
docker:
|
||||
@echo Starting Docker with ARCH=$(ARCH)
|
||||
docker run \
|
||||
-v ${PWD}:/home/fail/fail \
|
||||
-e ARCH=${ARCH} \
|
||||
-w /home/fail/fail \
|
||||
-it danceos/fail-ci-build
|
||||
|
||||
################################################################
|
||||
# Download
|
||||
download: ${BUILD_DIR}/bin/fail-client
|
||||
|
||||
${BUILD_DIR}/bin/fail-client:
|
||||
mkdir -p ${BUILD_DIR}/bin
|
||||
wget ${FAIL_DOWNLOAD_URL} -O ${BUILD_DIR}/bin/fail.zip
|
||||
cd ${BUILD_DIR}/bin/ && unzip fail.zip && mv build/bin/* . && rm -rf build
|
||||
|
||||
|
||||
%/system.elf: %/system.o startup.o
|
||||
${CC} -Wl,-T linker.ld $^ -m32 -static -nostdlib -Wl,--build-id=none -o $@
|
||||
clean:
|
||||
@rm -rf build
|
||||
|
||||
%/system.o: %.c
|
||||
mkdir -p $(shell dirname $@)
|
||||
${CC} $< -o $@ -O2 -std=c11 -m32 -c -ffunction-sections
|
||||
clean-%:
|
||||
@rm -rf ${BUILD_DIR}/$(patsubst build-%,%,$@)
|
||||
|
||||
startup.o: startup.s
|
||||
${CC} startup.s -m32 -c -o startup.o -ffunction-sections
|
||||
|
||||
%/system.iso: %/system.elf
|
||||
rm -rf $(shell dirname $<)/grub
|
||||
mkdir -p $(shell dirname $<)/grub/boot/grub
|
||||
cp grub.cfg $(shell dirname $<)/grub/boot/grub
|
||||
cp $< $(shell dirname $<)/grub/boot/system.elf
|
||||
grub-mkrescue -o $@ $(shell dirname $<)/grub
|
||||
build-%:
|
||||
@echo "****************************************************************\n\
|
||||
* The next step is to trace a golden run. The golden run executes the\n\
|
||||
* system-under-test (SUT) within the Bochs emulator. A trace file is \n\
|
||||
* produced and saved as main/trace.pb\n\
|
||||
* system-under-test (SUT) within the emulator. A trace file is \n\
|
||||
* produced and saved as: ${BUILD_DIR}/main/trace.pb\n\
|
||||
*\n\
|
||||
* $ make trace-$(shell dirname $<)\n\
|
||||
* $ make trace-$(patsubst build-%,%,$@)\n\
|
||||
****************************************************************"
|
||||
|
||||
|
||||
|
||||
trace-%: %/system.elf %/system.iso
|
||||
${BOCHS_RUNNER} -e $< -i $(shell dirname $<)/system.iso -1 \
|
||||
-V vgabios.bin -b BIOS-bochs-latest \
|
||||
|
||||
30
arch/bochs.mk
Normal file
30
arch/bochs.mk
Normal file
@ -0,0 +1,30 @@
|
||||
FAIL_DOWNLOAD_URL = ${FAIL_DOWNLOAD_BASE}?job=build-bochs-generic-tools
|
||||
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -Wl,-T linker.ld $^ -m32 -static -nostdlib -Wl,--build-id=none
|
||||
|
||||
################################################################
|
||||
# Build Targets
|
||||
${BUILD_DIR}/%/system.o: %.c
|
||||
mkdir -p $(shell dirname $@)
|
||||
${CC} $< -o $@ ${CFLAGS} -c -ffunction-sections
|
||||
|
||||
${BUILD_DIR}/startup.o: arch/bochs/startup.s
|
||||
${CC} $< ${CFLAGS} -c -o $@ -ffunction-sections
|
||||
|
||||
${BUILD_DIR}/%/system.elf: ${BUILD_DIR}/%/system.o ${BUILD_DIR}/startup.o
|
||||
${CC} ${LDFLAGS} -o $@
|
||||
|
||||
${BUILD_DIR}/%/system.iso: ${BUILD_DIR}/%/system.elf
|
||||
rm -rf $(shell dirname $<)/grub
|
||||
mkdir -p $(shell dirname $<)/grub/boot/grub
|
||||
cp grub.cfg $(shell dirname $<)/grub/boot/grub
|
||||
cp $< $(shell dirname $<)/grub/boot/system.elf
|
||||
grub-mkrescue -o $@ $(shell dirname $<)/grub
|
||||
|
||||
define arch-make-targets
|
||||
build-$1: ${BUILD_DIR}/$1/system.iso
|
||||
endef
|
||||
|
||||
|
||||
|
||||
4
arch/bochs/lib.c
Normal file
4
arch/bochs/lib.c
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
#define ARCH_ASM_CLOBBER_ALL "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp"
|
||||
|
||||
33
arch/riscv-common.mk
Normal file
33
arch/riscv-common.mk
Normal file
@ -0,0 +1,33 @@
|
||||
CC := clang-11
|
||||
CFLAGS += -nostdlib -fno-inline-functions -fno-unroll-loops -mcmodel=medium -gdwarf-5
|
||||
LDFLAGS += -nostdlib -nostartfiles -static -fuse-ld=lld -Wl,-nostdlib -Wl,--script=arch/riscv/linker.ld
|
||||
|
||||
|
||||
${BUILD_DIR}/startup.o: arch/riscv/bootcode/${ARCH}.c
|
||||
@mkdir -p $(dir $@)
|
||||
${CC} ${CFLAGS} -o $@ -c $^
|
||||
|
||||
${BUILD_DIR}/%/system.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
${CC} ${CFLAGS} -o $@ -c $^
|
||||
|
||||
${BUILD_DIR}/%/system.elf: ${BUILD_DIR}/startup.o ${BUILD_DIR}/%/system.o
|
||||
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $^
|
||||
|
||||
|
||||
define arch-make-targets
|
||||
build-$1: ${BUILD_DIR}/$1/system.elf
|
||||
|
||||
trace-$1: ${BUILD_DIR}/$1/system.elf
|
||||
${FAIL_TRACE} \
|
||||
-Wf,--elf-file -Wf,$$< \
|
||||
-Wf,--start-symbol -Wf,start_trace \
|
||||
-Wf,--end-symbol -Wf,stop_trace \
|
||||
-Wf,--check-bounds \
|
||||
-Wf,--state-file=$$(dir $$<)/state \
|
||||
-Wf,--trace-file=$$(dir $$<)/trace.pb \
|
||||
$$<
|
||||
|
||||
endef
|
||||
|
||||
|
||||
30
arch/riscv/bootcode/boot.h
Normal file
30
arch/riscv/bootcode/boot.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(__riscv) && !defined(__CHERI__)
|
||||
#define RISCV 1
|
||||
#define ARCH_ASM_CLOBBER_ALL NO_CAP_REGS
|
||||
|
||||
#elif defined(__riscv) && defined(__CHERI__)
|
||||
#define RISCVCHERI 1
|
||||
#define ARCH_ASM_CLOBBER_ALL NO_CAPS_REGS, CAP_REGS
|
||||
|
||||
#else
|
||||
#warning compiling for unknown architecture, using stdlib malloc.
|
||||
#endif
|
||||
|
||||
#define NO_CAP_REGS "ra","sp","gp","tp","t0","t1","t2","t3","t4","t5","t6","s0","s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11","a0","a1","a2","a3","a4","a5","a6","a7"
|
||||
|
||||
#define CAP_REGS "cra","csp","cgp","ctp","ct0","ct1","ct2","ct3","ct4","ct5","ct6","cs0","cs1","cs2","cs3","cs4","cs5","cs6","cs7","cs8","cs9","cs10","cs11","ca0","ca1","ca2","ca3","ca4","ca5","ca6","ca7"
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#if __riscv_xlen == 32
|
||||
typedef unsigned int size_t;
|
||||
#elif __riscv_xlen == 64
|
||||
typedef unsigned long size_t;
|
||||
#elif DEBUG
|
||||
#else
|
||||
#warning Unknown __riscv_xlen value
|
||||
typedef unsigned long size_t;
|
||||
#endif
|
||||
#endif
|
||||
30
arch/riscv/bootcode/cheri32.c
Normal file
30
arch/riscv/bootcode/cheri32.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <cheri_init_globals.h>
|
||||
#include "boot.h"
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".option push" "\n"
|
||||
".option nocapmode" "\n"
|
||||
".global _start" "\n"
|
||||
"_start:" "\n"
|
||||
" lla sp, __sp" "\n"
|
||||
" lla t0, __stack_size" "\n"
|
||||
" cfromptr csp, ddc, sp" "\n"
|
||||
" csetbounds csp, csp, t0" "\n"
|
||||
" cincoffset csp, csp, t0" "\n"
|
||||
" lla t0, _start_purecap" "\n"
|
||||
" cfromptr ct0, ddc, t0" "\n"
|
||||
" li t1, 1" "\n"
|
||||
" csetflags ct0, ct0, t1" "\n"
|
||||
" cjr ct0" "\n"
|
||||
".option pop" "\n"
|
||||
);
|
||||
|
||||
extern void os_main();
|
||||
|
||||
void _start_purecap(void) {
|
||||
cheri_init_globals_3(__builtin_cheri_global_data_get(),
|
||||
__builtin_cheri_program_counter_get(),
|
||||
__builtin_cheri_global_data_get());
|
||||
os_main();
|
||||
}
|
||||
1
arch/riscv/bootcode/cheri64.c
Symbolic link
1
arch/riscv/bootcode/cheri64.c
Symbolic link
@ -0,0 +1 @@
|
||||
cheri32.c
|
||||
12
arch/riscv/bootcode/riscv32.c
Normal file
12
arch/riscv/bootcode/riscv32.c
Normal file
@ -0,0 +1,12 @@
|
||||
#include "boot.h"
|
||||
|
||||
asm (
|
||||
".text" "\n"
|
||||
".global _start" "\n"
|
||||
"_start:" "\n"
|
||||
" la sp, __sp" "\n"
|
||||
" la t0, __stack_size" "\n"
|
||||
" add sp, sp, t0" "\n"
|
||||
" la t0, os_main" "\n"
|
||||
" jr t0" "\n"
|
||||
);
|
||||
1
arch/riscv/bootcode/riscv64.c
Symbolic link
1
arch/riscv/bootcode/riscv64.c
Symbolic link
@ -0,0 +1 @@
|
||||
riscv32.c
|
||||
3
arch/riscv/lib.c
Normal file
3
arch/riscv/lib.c
Normal file
@ -0,0 +1,3 @@
|
||||
#include "arch/riscv/bootcode/boot.h"
|
||||
|
||||
|
||||
254
arch/riscv/linker.ld
Normal file
254
arch/riscv/linker.ld
Normal file
@ -0,0 +1,254 @@
|
||||
|
||||
/*======================================================================*/
|
||||
/* Default maven linker script */
|
||||
/*======================================================================*/
|
||||
/* This is the default linker script for maven. It is based off of the
|
||||
mips idt32.ld linker script. I have added many more comments and
|
||||
tried to clean things up a bit. For more information about standard
|
||||
MIPS sections see Section 9.5 of "See MIPS Run Linux" by Dominic
|
||||
Sweetman. For more generic information about the init, fini, ctors,
|
||||
and dtors sections see the paper titled "ELF From the Programmers
|
||||
Perspective" by Hongiu Lu. */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Setup */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* The OUTPUT_ARCH command specifies the machine architecture where the
|
||||
argument is one of the names used in the BFD library. More
|
||||
specifically one of the entires in bfd/cpu-mips.c */
|
||||
|
||||
OUTPUT_ARCH( "riscv" )
|
||||
|
||||
/* The ENTRY command specifies the entry point (ie. first instruction to
|
||||
execute). The symbol _start is defined in crt0.S */
|
||||
|
||||
ENTRY( _start )
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Sections */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* This is where we specify how the input sections map to output
|
||||
sections. The .= commands set the location counter, and the
|
||||
sections are inserted in increasing address order according to the
|
||||
location counter. The following statement will take all of the .bar
|
||||
input sections and reloate them into the .foo output section which
|
||||
starts at address 0x1000.
|
||||
|
||||
. = 0.x1000;
|
||||
.foo : { *(.bar) }
|
||||
|
||||
If we wrap an input specification with a KEEP command then it
|
||||
prevents it from being eliminted during "link-time garbage
|
||||
collection". I'm not sure what this is, so I just followed what was
|
||||
done in idt32.ld.
|
||||
|
||||
We can also set a global external symbol to a specific address in the
|
||||
output binary with this syntax:
|
||||
|
||||
_etext = .;
|
||||
PROVIDE( etext = . );
|
||||
|
||||
This will set the global symbol _ftext to the current location. If we
|
||||
wrap this in a PROVIDE commad, the symbol will only be set if it is
|
||||
not defined. We do this with symbols which don't begin with an
|
||||
underscore since technically in ansi C someone might have a function
|
||||
with the same name (eg. etext).
|
||||
|
||||
If we need to label the beginning of a section we need to make sure
|
||||
that the linker doesn't insert an orphan section inbetween where we
|
||||
set the symbol and the actual begining of the section. We can do that
|
||||
by assigning the location dot to itself.
|
||||
|
||||
. = .
|
||||
_ftext = .;
|
||||
.text :
|
||||
{ }
|
||||
|
||||
*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Defines for stack and heap size. These are used by the startup code. */
|
||||
__stack_size = 0x800;
|
||||
__heap_size = 0x800;
|
||||
|
||||
/* Define data/bss padding size, defaults to zero but can be override by passing -Wl,--defsym=__padding_size=0x123 */
|
||||
__padding_size = DEFINED(__padding_size) ? __padding_size: 0x0;
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Code and read-only segment */
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
/* Begining of code and text segment */
|
||||
. = 0x80000000;
|
||||
_ftext = .;
|
||||
|
||||
/* text: Program code section */
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
}
|
||||
|
||||
/* init: Code to execute before main (called by crt0.S) */
|
||||
.init :
|
||||
{
|
||||
KEEP( *(.init) )
|
||||
}
|
||||
|
||||
/* fini: Code to execute after main (called by crt0.S) */
|
||||
.fini :
|
||||
{
|
||||
KEEP( *(.fini) )
|
||||
}
|
||||
|
||||
/* rodata: Read-only data */
|
||||
.rodata :
|
||||
{
|
||||
*(.rdata)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
}
|
||||
|
||||
/* End of code and read-only segment */
|
||||
PROVIDE( etext = . );
|
||||
_etext = .;
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Global constructor/destructor segement */
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
}
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array ))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
}
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array ))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Other misc gcc segments (this was in idt32.ld) */
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* I am not quite sure about these sections but it seems they are for
|
||||
C++ exception handling. I think .jcr is for "Java Class
|
||||
Registration" but it seems to end up in C++ binaries as well. */
|
||||
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
.eh_frame : { KEEP( *(.eh_frame) ) }
|
||||
.gcc_except_table : { *(.gcc_except_table) }
|
||||
.jcr : { KEEP (*(.jcr)) }
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Initialized data segment */
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
.padding_before : {
|
||||
. += __padding_size;
|
||||
}
|
||||
|
||||
/* Start of initialized data segment */
|
||||
. = ALIGN(16);
|
||||
_fdata = .;
|
||||
|
||||
/* data: Writable data */
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
}
|
||||
|
||||
/* End of initialized data segment */
|
||||
PROVIDE( edata = . );
|
||||
_edata = .;
|
||||
|
||||
/* Have _gp point to middle of sdata/sbss to maximize displacement range */
|
||||
. = ALIGN(16);
|
||||
_gp = . + 0x800;
|
||||
|
||||
/* Writable small data segment */
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.srodata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Uninitialized data segment */
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
/* Start of uninitialized data segment */
|
||||
. = ALIGN(16);
|
||||
_fbss = .;
|
||||
|
||||
/* Writable uninitialized small data segment */
|
||||
.sbss :
|
||||
{
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
}
|
||||
|
||||
/* bss: Uninitialized writeable data section */
|
||||
. = .;
|
||||
_bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
}
|
||||
|
||||
.padding_after : {
|
||||
. += __padding_size;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* Stack and Heap storage */
|
||||
/*--------------------------------------------------------------------*/
|
||||
.heap : ALIGN(16) {
|
||||
*(.heap)
|
||||
*(.heap.*)
|
||||
}
|
||||
|
||||
.stack : ALIGN(16) {
|
||||
PROVIDE(__sp = .);
|
||||
. += __stack_size;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/* HTIF, isolated on a seperate page. */
|
||||
/*--------------------------------------------------------------------*/
|
||||
.htif (NOLOAD) : ALIGN(0x1000) {
|
||||
tohost = .;
|
||||
PROVIDE(tohost = tohost);
|
||||
. += 8;
|
||||
fromhost = .;
|
||||
PROVIDE(fromhost = fromhost);
|
||||
. += 8;
|
||||
}
|
||||
. = ALIGN(0x1000);
|
||||
}
|
||||
1
arch/riscv32
Symbolic link
1
arch/riscv32
Symbolic link
@ -0,0 +1 @@
|
||||
riscv
|
||||
5
arch/riscv32.mk
Normal file
5
arch/riscv32.mk
Normal file
@ -0,0 +1,5 @@
|
||||
FAIL_DOWNLOAD_URL = ${FAIL_DOWNLOAD_BASE}?job=build-riscv-generic-tools%3A+%5Briscv64%5D
|
||||
|
||||
include arch/riscv-common.mk
|
||||
|
||||
CFLAGS += -march=rv32im -target riscv32-unknown-freebsd
|
||||
1
arch/riscv64
Symbolic link
1
arch/riscv64
Symbolic link
@ -0,0 +1 @@
|
||||
riscv
|
||||
24
lib.c
Normal file
24
lib.c
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#define INLINE __attribute__((always_inline)) inline
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
|
||||
#define __QUOTE(x) #x
|
||||
#define QUOTE(x) __QUOTE(x)
|
||||
|
||||
#define MARKER(str) __asm__ volatile(QUOTE(str) ":" \
|
||||
: /* no inputs */ \
|
||||
: /* no outputs */ \
|
||||
: "memory", ARCH_ASM_CLOBBER_ALL \
|
||||
)
|
||||
|
||||
#ifndef DEBUG
|
||||
#define MAIN() void os_main(void)
|
||||
#define PRINT_DEBUG(...)
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define MARKER(str) printf(QUOTE(str) "\n")
|
||||
#define DEBUG 1
|
||||
#define PRINT_DEBUG(...) printf(__VA_ARGS__)
|
||||
#define MAIN() void main(int argc, char** argv)
|
||||
#endif
|
||||
25
main.c
25
main.c
@ -1,28 +1,21 @@
|
||||
volatile int __dummy;
|
||||
void __attribute__ ((noinline)) fail_marker();
|
||||
void __attribute__ ((noinline)) fail_marker()
|
||||
{
|
||||
__dummy = 100;
|
||||
}
|
||||
|
||||
void __attribute__ ((noinline)) stop_trace();
|
||||
void __attribute__ ((noinline)) stop_trace()
|
||||
{
|
||||
__dummy = 100;
|
||||
}
|
||||
|
||||
#include "lib.c"
|
||||
|
||||
int array[] = {1, 1, 2, 3, 5, 8, 13, 21};
|
||||
int sum;
|
||||
void os_main() {
|
||||
|
||||
MAIN() {
|
||||
MARKER(start_trace);
|
||||
sum = 20;
|
||||
|
||||
for (int i = 0; i < sizeof(array)/sizeof(*array); i++) {
|
||||
sum += (array[i] * 23) + 1;
|
||||
}
|
||||
MARKER(stop_trace);
|
||||
|
||||
|
||||
if (sum != 1270)
|
||||
fail_marker();
|
||||
stop_trace();
|
||||
MARKER(fail_maker);
|
||||
else
|
||||
MARKER(ok_marker);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user