mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
289 lines
5.5 KiB
V
289 lines
5.5 KiB
V
// Copyright (c) 2019-2021 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 native
|
|
|
|
import os
|
|
|
|
const (
|
|
s_attr_some_instructions = 0x00000400
|
|
s_attr_pure_instructions = 0x80000000
|
|
s_attr_ext_reloc = 0x00000200
|
|
s_attr_loc_reloc = 0x00000100
|
|
//
|
|
macho_symcmd_size = 0x18
|
|
macho_d_size = 0x50
|
|
lc_symtab = 0x2
|
|
lc_dymsymtab = 0xB
|
|
)
|
|
|
|
struct Symbol {
|
|
str_entry int
|
|
symbol_typ int
|
|
section int
|
|
desc int
|
|
val i64
|
|
name string
|
|
is_ext bool
|
|
}
|
|
|
|
struct Reloc {
|
|
addr int
|
|
pcrel int
|
|
len int
|
|
ext int
|
|
typ int
|
|
snum int // symbol index (if ext) or infile section number
|
|
}
|
|
|
|
pub fn (mut g Gen) generate_macho_header() {
|
|
if g.pref.arch == .aarch64 {
|
|
g.write32(0xfeedfacf) // MH_MAGIC_64
|
|
g.write32(0x0100000c) // CPU_TYPE_ARM64
|
|
g.write32(0x00000000) // CPU_SUBTYPE_ARM64_ALL
|
|
} else {
|
|
g.write32(0xfeedfacf) // MH_MAGIC_64
|
|
g.write32(0x01000007) // CPU_TYPE_X64
|
|
g.write32(0x00000003) // CPU_SUBTYPE_X64
|
|
}
|
|
g.write32(0x00000001) // MH_OBJECT
|
|
g.write32(0x00000004) // # of load commands
|
|
g.write32(0x118) // size of load commands
|
|
// g.write32(0x00002000) // MH_SUBSECTIONS_VIA_SYMBOLS
|
|
g.write32(0) // MH_SUBSECTIONS_VIA_SYMBOLS
|
|
g.write32(0) // reserved
|
|
////
|
|
g.write32(0x19) // LC_SEGMENT_64
|
|
g.write32(0x98) // command size
|
|
g.zeroes(16) // segment name
|
|
g.write64(0) // VM address
|
|
g.write64(0x25) // VM size
|
|
g.write64(0x138) // file offset
|
|
g.write64(0x25) // file size
|
|
g.write32(0x7) // max vm protection
|
|
g.write32(0x7) // initial vm protection
|
|
g.write32(0x1) // # of sections
|
|
g.write32(0) // flags
|
|
////
|
|
g.write_string_with_padding('__text', 16) // section name
|
|
g.write_string_with_padding('__TEXT', 16) // segment name
|
|
g.write64(0) // address
|
|
g.write64(0x25) // size
|
|
g.write32(0x138) // offset
|
|
g.write32(0x4) // alignment
|
|
g.write32(0x160) // relocation offset
|
|
g.write32(0x1) // # of relocations
|
|
g.write32(native.s_attr_some_instructions | native.s_attr_pure_instructions)
|
|
g.write32(0)
|
|
g.write32(0)
|
|
g.write32(0)
|
|
/// ???
|
|
g.write32(0x32)
|
|
g.write32(0x18)
|
|
|
|
g.write32(0x01)
|
|
g.write32(0x000a0000) // minOS 10.0
|
|
g.write32(0)
|
|
g.write32(0)
|
|
// lc_symtab
|
|
g.sym_table_command()
|
|
//
|
|
g.write32(native.lc_dymsymtab)
|
|
g.write32(native.macho_d_size)
|
|
g.write32(0)
|
|
g.write32(2)
|
|
g.write32(2)
|
|
g.write32(1)
|
|
g.write32(3)
|
|
g.write32(1)
|
|
for _ in 0 .. 12 {
|
|
g.write32(0)
|
|
}
|
|
// ADD THE CODE HERE THIS GOES INTO THE STMTS THING
|
|
// g.write32(0x77777777)
|
|
// assembly
|
|
g.mov_arm(.x0, 1)
|
|
g.adr()
|
|
g.bl()
|
|
g.mov_arm(.x0, 0)
|
|
g.mov_arm(.x16, 1)
|
|
g.svc()
|
|
//
|
|
g.write_string('Hello World!\n')
|
|
g.write8(0) // padding?
|
|
g.write8(0)
|
|
g.write8(0)
|
|
g.write_relocs()
|
|
g.sym_table()
|
|
g.sym_string_table()
|
|
g.write8(0)
|
|
}
|
|
|
|
pub fn (mut g Gen) generate_macho_footer() {
|
|
// Create the binary // should be .o ?
|
|
mut f := os.create(g.out_name) or { panic(err) }
|
|
os.chmod(g.out_name, 0o775) // make it executable
|
|
unsafe { f.write_ptr(g.buf.data, g.buf.len) }
|
|
f.close()
|
|
// println('\narm64 mach-o binary has been successfully generated')
|
|
}
|
|
|
|
fn (mut g Gen) sym_table_command() {
|
|
g.syms << Symbol{
|
|
str_entry: 0x19
|
|
symbol_typ: 0xe
|
|
section: 1
|
|
val: 0
|
|
name: '_start'
|
|
is_ext: true
|
|
}
|
|
g.syms << Symbol{
|
|
str_entry: 0x0e
|
|
symbol_typ: 0xe
|
|
// symbol_typ: SYM_DEF
|
|
section: 1
|
|
val: 0x18
|
|
name: '_puts'
|
|
is_ext: false
|
|
}
|
|
g.syms << Symbol{
|
|
str_entry: 0x01
|
|
symbol_typ: 0xf
|
|
// symbol_typ: SYM_DEF
|
|
section: 1
|
|
// val: 0x27
|
|
val: 0
|
|
name: 'helloworld'
|
|
is_ext: false
|
|
}
|
|
g.syms << Symbol{
|
|
str_entry: 0x08
|
|
symbol_typ: 0x1
|
|
// symbol_typ: SYM_DEF
|
|
section: 0
|
|
// val: 0x27
|
|
val: 0
|
|
name: 'ltmp1'
|
|
is_ext: false
|
|
}
|
|
g.write32(native.lc_symtab)
|
|
g.write32(native.macho_symcmd_size)
|
|
sym_table_offset := 0x168
|
|
g.write32(sym_table_offset)
|
|
g_syms_len := 4
|
|
g.write32(g_syms_len)
|
|
str_offset := 0x1a8
|
|
g.write32(str_offset)
|
|
str_size := 0x20
|
|
g.write32(str_size)
|
|
}
|
|
|
|
pub fn (mut g Gen) zeroes(n int) {
|
|
for _ in 0 .. n {
|
|
g.buf << 0
|
|
}
|
|
}
|
|
|
|
enum Register2 {
|
|
x0
|
|
x1
|
|
x2
|
|
x3
|
|
x4
|
|
x5
|
|
x6
|
|
x7
|
|
x8
|
|
x9
|
|
x10
|
|
x11
|
|
x12
|
|
x13
|
|
x14
|
|
x15
|
|
x16
|
|
}
|
|
|
|
fn (mut g Gen) mov_arm(reg Register2, val u64) {
|
|
// m := u64(0xffff)
|
|
// x := u64(val)
|
|
// println('========')
|
|
// println(x & ~m)
|
|
// println(x & ~(m << 16))
|
|
// g.write32(0x777777)
|
|
r := int(reg)
|
|
if r == 0 && val == 1 {
|
|
g.write32(0xd2800020)
|
|
} else if r == 0 {
|
|
g.write32(0xd2800000)
|
|
} else if r == 16 {
|
|
g.write32(0xd2800030)
|
|
}
|
|
/*
|
|
if 1 ^ (x & ~m) != 0 {
|
|
// println('yep')
|
|
g.write32(int(u64(0x52800000) | u64(r) | x << 5))
|
|
g.write32(0x88888888)
|
|
g.write32(int(u64(0x52800000) | u64(r) | x >> 11))
|
|
} else if 1 ^ (x & ~(m << 16)) != 0 {
|
|
// g.write32(int(u64(0x52800000) | u64(r) | x >> 11))
|
|
// println('yep2')
|
|
// g.write32(0x52a00000 | r | val >> 11)
|
|
}
|
|
*/
|
|
}
|
|
|
|
fn (mut g Gen) adr() {
|
|
g.write32(0x100000a0)
|
|
}
|
|
|
|
fn (mut g Gen) bl() {
|
|
// g.write32(0xa9400000)
|
|
g.write32(0x94000000)
|
|
}
|
|
|
|
fn (mut g Gen) svc() {
|
|
g.write32(0xd4001001)
|
|
}
|
|
|
|
fn (mut g Gen) write_relocs() {
|
|
g.write32(0x8)
|
|
g.write32(0x2d000003)
|
|
}
|
|
|
|
fn (mut g Gen) sym_table() {
|
|
// strings first
|
|
for sym in g.syms {
|
|
// if !sym.is_ext {
|
|
g.write_symbol(sym)
|
|
//}
|
|
}
|
|
// now fns (external syms)
|
|
/*
|
|
for sym in g.syms {
|
|
if sym.is_ext {
|
|
g.write_symbol(sym)
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
fn (mut g Gen) write_symbol(s Symbol) {
|
|
// g.write8(0x77)
|
|
g.write32(s.str_entry)
|
|
g.write8(s.symbol_typ)
|
|
g.write8(s.section)
|
|
g.write8(0)
|
|
g.write8(0)
|
|
g.write64(s.val)
|
|
// g.write16(s.desc)
|
|
}
|
|
|
|
fn (mut g Gen) sym_string_table() {
|
|
g.zeroes(1)
|
|
for sym in g.syms {
|
|
g.write_string(sym.name)
|
|
g.write8(0)
|
|
}
|
|
}
|