Skip to content

Commit

Permalink
Break out code (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbirddog authored Jun 15, 2024
1 parent 8ae9932 commit 145c0db
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 121 deletions.
151 changes: 30 additions & 121 deletions blue.asm
Original file line number Diff line number Diff line change
@@ -1,51 +1,18 @@
format elf64 executable 3

segment readable writeable
include "elf.inc"

;
; https://kevinboone.me/elfdemo.html
; compiler entry point
;

output:
elf_header:
db 0x7f, 0x45, 0x4c, 0x46 ; magic number
db 0x02 ; 64 bit
db 0x01 ; little endian
db 0x01 ; elf version
db 0x00 ; target abi
dq 0x00 ; target abi version + 7 bytes undefined
dw 0x02 ; executable binary
dw 0x3e ; amd64 architecture
dd 0x01 ; elf version
dq 0x400078 ; start address
dq 0x40 ; offset to program header
dq 0xc0 ; offset to section header
dd 0x00 ; architecture flags
dw 0x40 ; size of header
dw 0x38 ; size of program header
dw 0x01 ; number of program headers
dw 0x40 ; size of section header
dw 0x03 ; number of section headers
dw 0x02 ; index if strtab section header

.length = $ - elf_header
assert .length = 0x40

program_header:
dd 0x01 ; entry type: loadable segment
dd 0x05 ; segment flags: RX
dq 0x00 ; offset within file
dq 0x400000 ; load position in virtual memory
dq 0x400000 ; load position in physical memory
.sizes:
dq 0x00 ; size of the loaded section (file)
dq 0x00 ; size of the loaded section (memory)
dq 0x200000 ; alignment boundary for sections

.length = $ - program_header
assert .length = 0x38
segment readable writeable

;
; TODO: move to anonymous mmap buffer, compile bytes at runtime
;
program_code:
.entry_offset = $ - program_code
db 0x48, 0xc7, 0xc0 ; mov rax, 1 - sys_write
dd 0x01
db 0x48, 0xc7, 0xc7 ; mov rdi, 1 - stdout fd
Expand All @@ -64,93 +31,23 @@ program_code:
db 0x0a, 0x00

.length = $ - program_code
assert .length = 0x38
assert $ - output = 0xb0

shstrtab:
db ".shstrtab"
db 0x00
db ".text"
db 0x00

.length = $ - shstrtab
assert .length = 0x10

section_0:
dq 0x00, 0x00, 0x00, 0x00 ; 64 bytes of 0s
dq 0x00, 0x00, 0x00, 0x00

.length = $ - section_0
assert .length = 0x40

program_code_section_header:
dd 0x0a ; offset to name in shstrtab
dd 0x01 ; type: program data
dq 0x06 ; flags - executable | in memory
dq 0x400078 ; addr in virtual memory of section
.offset:
dq 0x00 ; offset in the file of this section
.size:
dq 0x00 ; size of this section in the file
dq 0x00 ; sh_link - not used
dq 0x01 ; alignment code (default??)
dq 0x00 ; sh_entsize - not used

.length = $ - program_code_section_header
assert .length = 0x40

shstrtab_section_header:
dd 0x00 ; offset to name in shstrtab
dd 0x03 ; type: string table
dq 0x00 ; flags - none
dq 0x00 ; addr in virtual memory of section - not used
.offset:
dq 0x00 ; offset in the file of this section
.size:
dq 0x00 ; size of this section in the file
dq 0x00 ; sh_link - not used
dq 0x01 ; alignment code (default??)
dq 0x00 ; sh_entsize - not used

.length = $ - shstrtab_section_header
assert .length = 0x40
output_length = $ - output
segment readable executable

output_file:
db "a.out"
db 0x00

;
; compiler entry point
;

segment readable executable

SYS_WRITE = 1
SYS_OPEN = 2
SYS_CLOSE = 3
SYS_EXIT = 60

entry $
;
; calculate variable fields for the elf format
;
mov eax, elf_header.length + program_header.length
mov qword [program_code_section_header.offset], rax
mov qword [program_code_section_header.size], program_code.length
mov eax, program_code.entry_offset
mov ecx, program_code.length
call elf_binary_calculate_fields
add eax, program_code.length
mov rdi, program_header.sizes
stosq
stosq

mov rdi, shstrtab_section_header.offset
stosq

mov eax, shstrtab.length
stosq

;
; write the output to ./a.out
;
Expand All @@ -160,16 +57,28 @@ entry $
mov eax, SYS_OPEN
syscall

push rax
push rax

mov rdi, rax
mov rsi, output
mov rdx, output_length

mov rsi, elf_binary_headers
mov rdx, elf_binary_headers_length
mov eax, SYS_WRITE
syscall

mov rsi, program_code
mov rdx, program_code.length
mov eax, SYS_WRITE
syscall

mov rsi, shstrtab
mov rdx, shstrtab.length
mov eax, SYS_WRITE
syscall

mov rsi, elf_binary_section_headers
mov rdx, elf_binary_section_headers_length
mov eax, SYS_WRITE
syscall

pop rdi
mov eax, SYS_CLOSE
syscall

Expand Down
142 changes: 142 additions & 0 deletions elf.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@

segment readable writeable
;
; adapted from https://kevinboone.me/elfdemo.html
;

elf_binary:
.base_address = 0x400000

elf_binary_headers:
elf_header:
db 0x7f, 0x45, 0x4c, 0x46 ; magic number
db 0x02 ; 64 bit
db 0x01 ; little endian
db 0x01 ; elf version
db 0x00 ; target abi
dq 0x00 ; target abi version + 7 bytes undefined
dw 0x02 ; executable binary
dw 0x3e ; amd64 architecture
dd 0x01 ; elf version
.start_address:
dq -0x01 ; start address
dq 0x40 ; offset to program header
.section_header_offset:
dq -0x01 ; offset to section header
dd 0x00 ; architecture flags
dw 0x40 ; size of header
dw 0x38 ; size of program header
dw 0x01 ; number of program headers
dw 0x40 ; size of section header
dw 0x03 ; number of section headers
dw 0x02 ; index of strtab section header

.length = $ - elf_header
assert .length = 0x40

program_header:
dd 0x01 ; entry type: loadable segment
dd 0x05 ; segment flags: RX
dq 0x00 ; offset within file
dq elf_binary.base_address ; load position in virtual memory
dq elf_binary.base_address ; load position in physical memory
.sizes:
dq -0x01 ; size of the loaded section (file)
dq -0x01 ; size of the loaded section (memory)
dq 0x200000 ; alignment boundary for sections

.length = $ - program_header
assert .length = 0x38

shstrtab:
db ".shstrtab"
db 0x00
db ".text"
db 0x00

.length = $ - shstrtab
assert .length = 0x10

elf_binary_section_headers:
section_header_0:
dq 0x00, 0x00, 0x00, 0x00 ; 64 bytes of 0s
dq 0x00, 0x00, 0x00, 0x00

.length = $ - section_header_0
assert .length = 0x40

program_code_section_header:
dd 0x0a ; offset to name in shstrtab
dd 0x01 ; type: program data
dq 0x06 ; flags - executable | in memory
.address:
dq -0x01 ; addr in virtual memory of section
.offset:
dq -0x01 ; offset in the file of this section
.size:
dq -0x01 ; size of this section in the file
dq 0x00 ; sh_link - not used
dq 0x01 ; alignment code (default??)
dq 0x00 ; sh_entsize - not used

.length = $ - program_code_section_header
assert .length = 0x40

shstrtab_section_header:
dd 0x00 ; offset to name in shstrtab
dd 0x03 ; type: string table
dq 0x00 ; flags - none
dq 0x00 ; addr in virtual memory of section - not used
.offset:
dq -0x01 ; offset in the file of this section
.size:
dq -0x01 ; size of this section in the file
dq 0x00 ; sh_link - not used
dq 0x01 ; alignment code (default??)
dq 0x00 ; sh_entsize - not used

.length = $ - shstrtab_section_header
assert .length = 0x40
elf_binary_length = $ - elf_binary
elf_binary_headers_length = elf_header.length + program_header.length
elf_binary_section_headers_length = elf_binary_length - elf_binary_section_headers

segment readable executable

;
; expects
; - program code entry offset in eax
; - program code length in ecx
;
elf_binary_calculate_fields:
add eax, elf_binary_headers_length
push rax
add eax, elf_binary.base_address
mov qword [elf_header.start_address], rax

pop rax
mov qword [program_code_section_header.offset], rax

mov edi, eax
add edi, elf_binary.base_address
mov qword [program_code_section_header.address], rdi
mov qword [program_code_section_header.size], rcx
add eax, ecx
mov rdi, program_header.sizes
stosq
stosq

mov rdi, shstrtab_section_header.offset
stosq

mov eax, shstrtab.length
stosq

add ecx, elf_header.length + program_header.length
mov qword [elf_header.section_header_offset], rcx

ret

0 comments on commit 145c0db

Please sign in to comment.