1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

x64: function calls; http: download_file()

This commit is contained in:
Alexander Medvednikov
2019-11-27 09:01:25 +03:00
parent 208f67132d
commit 52d25336db
9 changed files with 102 additions and 35 deletions

View File

@@ -69,6 +69,8 @@ pub fn (g mut Gen) generate_elf_header() {
g.write64(0x1000) // p_align
// user code starts here at
// address: 00070 and a half
g.code_start_pos = g.buf.len
g.call(0)// call main function, it's not guaranteed to be the first
}
pub fn (g mut Gen) generate_elf_footer() {
@@ -87,6 +89,12 @@ pub fn (g mut Gen) generate_elf_footer() {
file_size := g.buf.len
g.write64_at(file_size, g.file_size_pos) // set file size 64 bit value
g.write64_at(file_size, g.file_size_pos+8)
// call main function, it's not guaranteed to be the first
// we generated call(0) ("e8 0")
// no need to replace "0" with a relative address of the main function
// +1 is for "e8"
// -5 is for "e8 00 00 00 00"
g.write64_at(int(g.main_fn_addr - g.code_start_pos) - 5, g.code_start_pos+1)
// Create the binary
f := os.create(g.out_name) or { panic(err) }
os.chmod(g.out_name, 0775)

View File

@@ -12,8 +12,9 @@ mut:
offset i64
str_pos []i64
strings []string // TODO use a map and don't duplicate strings
//str string
file_size_pos i64
main_fn_addr i64
code_start_pos i64 // location of the start of the assembly instructions
//string_addr map[string]i64
}
@@ -120,11 +121,29 @@ fn (g mut Gen) cmp(reg Register, size Size, val i64) {
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 {
@@ -137,7 +156,9 @@ fn (g mut Gen) mov64(reg Register, val i64) {
}
fn (g mut Gen) call(val int) {
//println('call val=$val')
g.write8(0xe8)
g.write32(val)
}
fn (g mut Gen) syscall() {
@@ -146,7 +167,7 @@ fn (g mut Gen) syscall() {
g.write8(0x05)
}
fn (g mut Gen) ret() {
pub fn (g mut Gen) ret() {
g.write8(0xc3)
}
@@ -163,6 +184,10 @@ pub fn (g mut Gen) gen_loop_end(to int, label int) {
g.jle(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
@@ -175,6 +200,13 @@ pub fn (g mut Gen) gen_print(s string) {
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) }