remove remaining files in vlib/compiler
							parent
							
								
									8dfb14b1c4
								
							
						
					
					
						commit
						d9af06f2ad
					
				|  | @ -1,159 +0,0 @@ | |||
| // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
 | ||||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| module x64 | ||||
| /* | ||||
| This file is unused right now, since binaries without sections | ||||
| are generated. | ||||
| 
 | ||||
| But it will be necessary once we have dynamic linking. | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
| enum SectionType { | ||||
| 	null = 0 | ||||
| 	progbits = 1 | ||||
| 	symtab = 2 | ||||
| 	strtab = 3 | ||||
| 	rela = 4 | ||||
| } | ||||
| 
 | ||||
| struct SectionConfig { | ||||
| 	name    string | ||||
| 	typ     SectionType | ||||
| 	flags   i64 | ||||
| 	data    voidptr | ||||
| 	is_saa  bool | ||||
| 	datalen i64 | ||||
| 	link    int | ||||
| 	info    int | ||||
| 	align   i64 | ||||
| 	entsize i64 | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) section_header(c SectionConfig) { | ||||
| 	g.write32(g.sect_header_name_pos) | ||||
| 	g.sect_header_name_pos += c.name.len + 1 | ||||
| 	g.write32(int(c.typ)) | ||||
| 	g.write64(c.flags) | ||||
| 	g.write64(0) // sh_addr
 | ||||
| 	g.write64(g.offset) // offset
 | ||||
| 	g.offset += c.datalen + 1 | ||||
| 	g.write64(c.datalen) | ||||
| 	g.write32(c.link) | ||||
| 	g.write32(c.info) | ||||
| 	g.write64(c.align) | ||||
| 	g.write64(c.entsize) | ||||
| } | ||||
| 
 | ||||
| fn genobj() { | ||||
| 	/* | ||||
| 	// SHN_UNDEF
 | ||||
| 	mut g := Gen{} | ||||
| 	nr_sections := 7 | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '' | ||||
| 		typ: .null | ||||
| 		flags:0 | ||||
| 		data: 0 | ||||
| 		is_saa: false | ||||
| 		link: 0 | ||||
| 		info:0 | ||||
| 		align:0 | ||||
| 		entsize: 0 | ||||
| 	}) | ||||
| 
 | ||||
| 		/* | ||||
| 	for sect in sections { | ||||
| 		g.section_header(SectionConfig{ | ||||
| 			name:0 | ||||
| 			typ: sect.typ | ||||
| 			flags: sect.flags | ||||
| 			data: sect.data | ||||
| 			is_saa: true | ||||
| 			datalen: sect.len | ||||
| 			link: 0 | ||||
| 			info: 0 | ||||
| 			align: sect.align | ||||
| 			entsize: sect.entsize | ||||
| 		}) | ||||
| 
 | ||||
| 	} | ||||
| 	*/ | ||||
| 
 | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '.DATA' | ||||
| 		typ: .progbits | ||||
| 		flags: 0x2 | ||||
| 		//data: sect.data
 | ||||
| 		is_saa: true | ||||
| 		datalen: 0xd | ||||
| 		link: 0 | ||||
| 		info: 0 | ||||
| 		align: 1 | ||||
| 		entsize: 0 | ||||
| 	}) | ||||
| 
 | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '.TEXT' | ||||
| 		typ: .progbits | ||||
| 		flags: 0x2 | ||||
| 		//data: sect.data
 | ||||
| 		is_saa: true | ||||
| 		datalen: 0xd | ||||
| 		link: 0 | ||||
| 		info: 0 | ||||
| 		align: 1 | ||||
| 		entsize: 0 | ||||
| 	}) | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '.shstrtab' | ||||
| 		typ: .strtab | ||||
| 		flags: 0x2 | ||||
| 		//data: sect.data
 | ||||
| 		is_saa: true | ||||
| 		datalen: 0x22 | ||||
| 		link: 0 | ||||
| 		info: 0 | ||||
| 		align: 1 | ||||
| 		entsize: 0 | ||||
| 	}) | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '.symtab' | ||||
| 		typ: .symtab | ||||
| 		flags: 0x2 | ||||
| 		//data: sect.data
 | ||||
| 		is_saa: true | ||||
| 		datalen: 0xd | ||||
| 		link: 0 | ||||
| 		info: 0 | ||||
| 		align: 1 | ||||
| 		entsize: 0 | ||||
| 	}) | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '.strtab' | ||||
| 		typ: .symtab | ||||
| 		flags: 0x2 | ||||
| 		//data: sect.data
 | ||||
| 		is_saa: true | ||||
| 		datalen: 0xd | ||||
| 		link: 0 | ||||
| 		info: 0 | ||||
| 		align: 1 | ||||
| 		entsize: 0 | ||||
| 	}) | ||||
| 	g.section_header(SectionConfig{ | ||||
| 		name: '.rela.TEXT' | ||||
| 		typ: .rela | ||||
| 		flags: 0x0 | ||||
| 		//data: sect.data
 | ||||
| 		is_saa: true | ||||
| 		datalen: 0x18 | ||||
| 		link: 4 | ||||
| 		info: 2 | ||||
| 		align: 8 | ||||
| 		entsize: 0x18 | ||||
| 	}) | ||||
| 	*/ | ||||
| } | ||||
| 
 | ||||
|  | @ -1,268 +0,0 @@ | |||
| // Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
 | ||||
| // Use of this source code is governed by an MIT license
 | ||||
| // that can be found in the LICENSE file.
 | ||||
| module x64 | ||||
| 
 | ||||
| pub struct Gen { | ||||
| 	out_name             string | ||||
| mut: | ||||
| 	buf                  []byte | ||||
| 	sect_header_name_pos int | ||||
| 	offset               i64 | ||||
| 	str_pos              []i64 | ||||
| 	strings              []string // TODO use a map and don't duplicate strings
 | ||||
| 	file_size_pos        i64 | ||||
| 	main_fn_addr         i64 | ||||
| 	code_start_pos       i64 // location of the start of the assembly instructions
 | ||||
| 	fn_addr              map[string]i64 | ||||
| 	// string_addr map[string]i64
 | ||||
| } | ||||
| 
 | ||||
| enum Register { | ||||
| 	eax | ||||
| 	edi | ||||
| 	rax | ||||
| 	rdi | ||||
| 	rsi | ||||
| 	edx | ||||
| 	rdx | ||||
| 	r12 | ||||
| } | ||||
| 
 | ||||
| enum Size { | ||||
| 	_8 | ||||
| 	_16 | ||||
| 	_32 | ||||
| 	_64 | ||||
| } | ||||
| 
 | ||||
| pub fn new_gen(out_name string) &Gen { | ||||
| 	return &Gen{ | ||||
| 		sect_header_name_pos: 0 | ||||
| 		buf: [] | ||||
| 		out_name: out_name | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (g &Gen) pos() i64 { | ||||
| 	return g.buf.len | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) write8(n int) { | ||||
| 	// write 1 byte
 | ||||
| 	g.buf << byte(n) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) write16(n int) { | ||||
| 	// write 2 bytes
 | ||||
| 	g.buf << byte(n) | ||||
| 	g.buf << byte(n>>8) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) write32(n int) { | ||||
| 	// write 4 bytes
 | ||||
| 	g.buf << byte(n) | ||||
| 	g.buf << byte(n>>8) | ||||
| 	g.buf << byte(n>>16) | ||||
| 	g.buf << byte(n>>24) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) write64(n i64) { | ||||
| 	// write 8 bytes
 | ||||
| 	g.buf << byte(n) | ||||
| 	g.buf << byte(n>>8) | ||||
| 	g.buf << byte(n>>16) | ||||
| 	g.buf << byte(n>>24) | ||||
| 	g.buf << byte(n>>32) | ||||
| 	g.buf << byte(n>>40) | ||||
| 	g.buf << byte(n>>48) | ||||
| 	g.buf << byte(n>>56) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) write64_at(n i64, at i64) { | ||||
| 	// write 8 bytes
 | ||||
| 	g.buf[at] = byte(n) | ||||
| 	g.buf[at + 1] = byte(n>>8) | ||||
| 	g.buf[at + 2] = byte(n>>16) | ||||
| 	g.buf[at + 3] = byte(n>>24) | ||||
| 	g.buf[at + 4] = byte(n>>32) | ||||
| 	g.buf[at + 5] = byte(n>>40) | ||||
| 	g.buf[at + 6] = byte(n>>48) | ||||
| 	g.buf[at + 7] = byte(n>>56) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) write_string(s string) { | ||||
| 	for c in s { | ||||
| 		g.write8(int(c)) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) inc(reg Register) { | ||||
| 	g.write16(0xff49) | ||||
| 	match reg { | ||||
| 		.r12 { | ||||
| 			g.write8(0xc4) | ||||
| 		} | ||||
| 		else { | ||||
| 			panic('unhandled inc $reg') | ||||
| 		}} | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) cmp(reg Register, size Size, val i64) { | ||||
| 	g.write8(0x49) | ||||
| 	// Second byte depends on the size of the value
 | ||||
| 	match size { | ||||
| 		._8 { | ||||
| 			g.write8(0x83) | ||||
| 		} | ||||
| 		._32 { | ||||
| 			g.write8(0x81) | ||||
| 		} | ||||
| 		else { | ||||
| 			panic('unhandled cmp') | ||||
| 		}} | ||||
| 	// Third byte depends on the register being compared to
 | ||||
| 	match reg { | ||||
| 		.r12 { | ||||
| 			g.write8(0xfc) | ||||
| 		} | ||||
| 		else { | ||||
| 			panic('unhandled cmp') | ||||
| 		}} | ||||
| 	g.write8(int(val)) | ||||
| } | ||||
| 
 | ||||
| fn abs(a i64) i64 { | ||||
| 	return if a < 0 { -a } else { a } | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) jle(addr i64) { | ||||
| 	// Calculate the relative offset to jump to
 | ||||
| 	// (`addr` is absolute address)
 | ||||
| 	offset := 0xff - int(abs(addr - g.buf.len)) - 1 | ||||
| 	g.write8(0x7e) | ||||
| 	g.write8(offset) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) jl(addr i64) { | ||||
| 	offset := 0xff - int(abs(addr - g.buf.len)) - 1 | ||||
| 	g.write8(0x7c) | ||||
| 	g.write8(offset) | ||||
| } | ||||
| 
 | ||||
| fn (g &Gen) abs_to_rel_addr(addr i64) int { | ||||
| 	return int(abs(addr - g.buf.len)) - 1 | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) jmp(addr i64) { | ||||
| 	offset := 0xff - g.abs_to_rel_addr(addr) | ||||
| 	g.write8(0xe9) | ||||
| 	g.write8(offset) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) mov64(reg Register, val i64) { | ||||
| 	match reg { | ||||
| 		.rsi { | ||||
| 			g.write8(0x48) | ||||
| 			g.write8(0xbe) | ||||
| 		} | ||||
| 		else { | ||||
| 			println('unhandled mov $reg') | ||||
| 		}} | ||||
| 	g.write64(val) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) call(addr int) { | ||||
| 	// rel := g.abs_to_rel_addr(addr)
 | ||||
| 	// rel := 0xffffffff - int(abs(addr - g.buf.len))-1
 | ||||
| 	println('call addr=$addr rel_addr=$addr pos=$g.buf.len') | ||||
| 	g.write8(0xe8) | ||||
| 	g.write32(addr) | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) syscall() { | ||||
| 	// g.write(0x050f)
 | ||||
| 	g.write8(0x0f) | ||||
| 	g.write8(0x05) | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) ret() { | ||||
| 	g.write8(0xc3) | ||||
| } | ||||
| 
 | ||||
| // returns label's relative address
 | ||||
| pub fn (g mut Gen) gen_loop_start(from int) int { | ||||
| 	g.mov(.r12, from) | ||||
| 	label := g.buf.len | ||||
| 	g.inc(.r12) | ||||
| 	return label | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) gen_loop_end(to int, label int) { | ||||
| 	g.cmp(.r12, ._8, to) | ||||
| 	g.jl(label) | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) save_main_fn_addr() { | ||||
| 	g.main_fn_addr = g.buf.len | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) gen_print(s string) { | ||||
| 	g.strings << s + '\n' | ||||
| 	// g.string_addr[s] = str_pos
 | ||||
| 	g.mov(.eax, 1) | ||||
| 	g.mov(.edi, 1) | ||||
| 	str_pos := g.buf.len + 2 | ||||
| 	g.str_pos << str_pos | ||||
| 	g.mov64(.rsi, 0) // segment_start +  0x9f) // str pos // PLACEHOLDER
 | ||||
| 	g.mov(.edx, s.len + 1) // len
 | ||||
| 	g.syscall() | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) gen_exit() { | ||||
| 	// Return 0
 | ||||
| 	g.mov(.edi, 0) // ret value
 | ||||
| 	g.mov(.eax, 60) | ||||
| 	g.syscall() | ||||
| } | ||||
| 
 | ||||
| fn (g mut Gen) mov(reg Register, val int) { | ||||
| 	match reg { | ||||
| 		.eax { | ||||
| 			g.write8(0xb8) | ||||
| 		} | ||||
| 		.edi { | ||||
| 			g.write8(0xbf) | ||||
| 		} | ||||
| 		.edx { | ||||
| 			g.write8(0xba) | ||||
| 		} | ||||
| 		.rsi { | ||||
| 			g.write8(0x48) | ||||
| 			g.write8(0xbe) | ||||
| 		} | ||||
| 		.r12 { | ||||
| 			g.write8(0x41) | ||||
| 			g.write8(0xbc) // r11 is 0xbb etc
 | ||||
| 		} | ||||
| 		else { | ||||
| 			panic('unhandled mov $reg') | ||||
| 		}} | ||||
| 	g.write32(val) | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) register_function_address(name string) { | ||||
| 	addr := g.pos() | ||||
| 	//println('reg fn addr $name $addr')
 | ||||
| 	g.fn_addr[name] = addr | ||||
| } | ||||
| 
 | ||||
| pub fn (g mut Gen) call_fn(name string) { | ||||
| 	if !name.contains('__') { | ||||
| 		return | ||||
| 	} | ||||
| 	addr := g.fn_addr[name] | ||||
| 	g.call(int(addr)) | ||||
| 	println('call $name $addr') | ||||
| } | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue