Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,8 @@
*.swp
*.swo
*.un~

*.tab.c
*.tab.h
*.yy.c
out
32 changes: 32 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
SRCDIR=src
OUTDIR=out
OBJDIR=$(OUTDIR)/obj
CC=gcc
CFLAGS=-I$(SRCDIR) -I$(OUTDIR) -w -std=c99
DEPS = ceed.h ceed.tab.h
OBJ = lex.yy.o ceed.tab.o ceedcmpl.o ceedelf.o ceedpe.o ceedrtl.o main.o ceedcmpl64.o ceedpe64.o
OBJS = $(addprefix $(OBJDIR)/,$(OBJ))

all: $(OUTDIR) $(OUTDIR)/ceed

$(OUTDIR):
mkdir $(OUTDIR)
mkdir $(OBJDIR)

$(OUTDIR)/ceed: $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS)

$(OUTDIR)/lex.yy.c $(OUTDIR)/ceed.tab.c $(OUTDIR)/ceed.tab.h: $(SRCDIR)/ceed.l $(SRCDIR)/ceed.y
bison -d $(SRCDIR)/ceed.y -o $(OUTDIR)/ceed.tab.c
flex -o $(OUTDIR)/lex.yy.c $(SRCDIR)/ceed.l

$(OBJDIR)/%.o: $(OUTDIR)/%.c
$(CC) -c $(CFLAGS) -o $@ $<

$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) -c $(CFLAGS) -o $@ $<


clean:
@rm -rf $(OUTDIR)

119 changes: 119 additions & 0 deletions lib/atoi_itoa64.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
BITS 64
GLOBAL _start
SECTION .text
_start:
itoa:

; rax must contain the number that needs to be converted.

; rbx must point to a buffer that would store the converted string.
; The buffer must have at least 12 bytes to contain maximum 4-byte number
; including minus sign.

push rbp
mov rbp, rsp
sub rsp, 8 ; Allocate 4 bytes for string length

add rbx, 11 ; Mov to end of buffer
mov byte [rbx], 0 ; Put \0 or NULL at the end
mov rcx, 10 ; Divisor
mov dword [rbp - 8], 0 ; rbp-8 will contain string length

.checknegative:
xor rdi, rdi
cmp rax, 0
jge .divloop
neg rax
mov rdi, 1

.divloop:
xor rdx, rdx ; Zero out rdx (remainder is in rdx after idiv)
idiv rcx ; Divide rax by rcx
add rdx, 0x30 ; Add 0x30 to the remainder to get ASCII value
dec rbx ; Move the pointer backwards in the buffer
mov byte [rbx], dl ; Move the character into the buffer
inc dword [rbp - 8] ; Increase the length

cmp rax, 0 ; Was the result zero?
jnz .divloop ; No it wasn't, keep looping

.minussign:
cmp rdi, 1
jne .done

dec rbx
mov byte [rbx], 0x2d
inc dword [rbp - 8] ; Increase the length

.done:
mov rcx, rbx ; rcx points to the beginning of the string
mov rdx, [rbp - 8] ; rbp-4 contains the length - move it into rdx

mov rsp, rbp ; Clean up our stack
pop rbp
ret



atoi:

; rbx must point to the input buffer that is NULL terminated.

push rbp
mov rbp, rsp
sub rsp, 8

.init:
; Initialize variables and registers
xor rdi, rdi ; Used as counter
mov rcx, 10 ; Used as multiplier
xor rax, rax ; Returns result
xor rdx, rdx ; Temporary
mov dword [rbp - 8], 0 ; Store result

.checknegative:
xor rsi, rsi ; Used to represent negative numbers
mov dl, [rbx + rdi] ; Select the character
cmp dl, 0x2d ; Check if this is - sign
jne .multiplyLoop
mov rsi, 1 ; rsi = 1 represents negative numers
inc rdi ; mov buffer pointer

.multiplyLoop:
mov rax, [rbp - 8] ; Get saved value
mul rcx ; Make this value 10x
jo .invalid ; Jump in case of overflow
mov dl, [rbx + rdi] ; Select the character
cmp dl, 0x30 ; Validate character between 0-9
jl .invalid
cmp dl, 0x39
jg .invalid
sub dl, 0x30 ; Subtract ASCII 48 to get its actual value
add rax, rdx ; Add new value and 10x old value
mov [rbp - 8], rax ; Save result
inc rdi ; Increase the counter
cmp byte [rbx + rdi], 0 ; Have we reached a null terminator?
je .finish ; If yes, we are done.
cmp byte [rbx + rdi], 0xa ; Have we reached a newline character?
je .finish ; If yes, we are done.
cmp byte [rbx + rdi], 0xd ; Did we reach a carriage return (in windows)?
je .finish ; If yes, we are done.
jmp .multiplyLoop ; Loop back

.finish:
mov rax, [rbp - 8] ; Result in rax

.minussign:
cmp rsi, 1
jne .done
neg rax
jmp .done

.invalid:
xor rax, rax

.done:
mov rsp, rbp ; clean up our stack
pop rbp
ret

46 changes: 43 additions & 3 deletions src/ceed.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,26 +51,34 @@ typedef struct _sym {

extern int func[26];

u32 emit_code(sym *p);
//u32 emit_code(sym *p);
void emit8(u8 i);
void emit16(u16 i);
void emit32(u32 i);
void emit32at(u32 pos, u32 i);
void emit3(u8 a, u8 b, u8 c);
void emit64(u64 i);
void emit64at(u32 pos, u32 i);

#define round_up(n, r) ((((n) + ((r)-1))/(r))*(r))

u32 add_str(pu8 str);
void cmplr_init();
void elf_init();
void pe_init();
void pe64_init();
void cmplr64_init();
void gen_exe(void);

typedef void (*pfn_gen_exe_file)(pvoid ei);
typedef pvoid (*pfn_set_exe_scn)(pvoid ei, pu8 scn_data, u32 scn_size);
typedef pvoid (*pfn_get_va)(pvoid ei);
typedef void (*pfn_emit_main_init)();
typedef void (*pfn_emit_main_exit)();
typedef void (*pfn_emit_write)(u32 buf_addr, u32 buf_len);
typedef void (*pfn_emit_write)(u64 buf_addr, u32 buf_len);
typedef void (*pfn_emit_write_reg_input)();
typedef void (*pfn_emit_read)(u32 buf_addr, u32 buf_len);
typedef void (*pfn_emit_read)(u64 buf_addr, u32 buf_len);
typedef u32 (*pfn_emit_code)(sym* p);

extern pvoid ei;
extern pfn_gen_exe_file gen_exe_file;
Expand All @@ -84,4 +92,36 @@ extern pfn_emit_main_exit emit_main_exit;
extern pfn_emit_write emit_write;
extern pfn_emit_write_reg_input emit_write_reg_input;
extern pfn_emit_read emit_read;
extern pfn_emit_code emit_code;

extern u8 itoa_code[];
extern u8 atoi_code[];
extern u8 itoa_code64[];
extern u8 atoi_code64[];

extern u32 code_pos;
extern pu8 code;
extern u32 rdata_pos;
extern pu8 rdata;

#define CEED_MAX_CODE_SIZE 0x100000 // 1MB
#define CEED_MAX_RDATA_SIZE 0x100000 // 1MB

#define CEED_OP_ADD 0
#define CEED_OP_SUB 1
#define CEED_OP_GT 0
#define CEED_OP_EQ 1

#define CEED_TYPE_VAL 1
#define CEED_TYPE_ADDR 2

//
// Reserve some temp space needed for itoa or atoi.
//
#define CEED_TEMP_ATOI_ITOA_BUF_ADDR 0x900
//
// Need at least 13 bytes on windows to accomodate: -2,147,483,648 followed
// by CR-LF, which are appended on ReadConsole in Windows. We make length 16
// bytes.
//
#define CEED_TEMP_ATOI_ITOA_BUF_LEN 0x10
32 changes: 4 additions & 28 deletions src/ceed.y
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,11 @@ mk_stmt(int type, int sym_count, ...)
va_list ap;
sym *p;
int i;

if ((p = malloc(sizeof(sym) + (sym_count-1) * sizeof(sym *))) == NULL)
int plen = sizeof(sym) + (sym_count-1) * sizeof(sym *);
if ((p = malloc(plen)) == NULL){
yyerror("out of memory");
exit(0);
}

p->type = sym_typ_stmt;
p->stmt.type = type;
Expand Down Expand Up @@ -188,29 +190,3 @@ yyerror(char *s)
fprintf(stdout, "Line: %d, Error: %s\n", yylineno, s);
}

int
main(int argc, char *argv[])
{
func[0] = -1;

if (argc == 1) {
elf_init();
} else if (argc == 2 && (strcmp(argv[1], "-pe") == 0)) {
pe_init();
} else {
printf("Invalid command line. Valid syntax is:\n");
printf("For ELF output: ceed < input_file\n");
printf("For PE output: ceed -pe < input_file\n");
exit(-1);
}

cmplr_init();

if (yyparse() == 0) {
gen_exe();
return 0;
} else {
return -1;
}
}

Loading