827dd4a7fe
One less error that's only in the bootstrap phase. On the other hand, for simplicity I got rid of the ability to override the Entry label. One less special case, but we're also going further from the ability to run subsets of layers. We haven't really been exercising it for a long time, though (commit 7842, March 2021 when we made baremetal the default).
89 lines
4.5 KiB
Plaintext
89 lines
4.5 KiB
Plaintext
# Create a new segment (pool of memory for allocating chunks from) in the form
|
|
# of an *allocation descriptor* that can be passed to the memory allocator
|
|
# (defined in a later layer).
|
|
#
|
|
# Currently an allocation descriptor consists of just the bounds of the pool of
|
|
# available memory:
|
|
#
|
|
# curr: address
|
|
# end: address
|
|
#
|
|
# This isn't enough information to reclaim individual allocations. We can't
|
|
# support arbitrary reclamation yet.
|
|
|
|
== code
|
|
# instruction effective address register displacement immediate
|
|
# . op subop mod rm32 base index scale r32
|
|
# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes
|
|
|
|
#? Entry: # manual test
|
|
#? # var ad/ecx: allocation-descriptor
|
|
#? 68/push 0/imm32/limit
|
|
#? 68/push 0/imm32/curr
|
|
#? 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
|
#? # new-segment(0x1000, ad)
|
|
#? # . . push args
|
|
#? 51/push-ecx
|
|
#? 68/push 0x1000/imm32
|
|
#? # . . call
|
|
#? e8/call new-segment/disp32
|
|
#? # . . discard args
|
|
#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
#? # var eax: (addr _) = ad->curr
|
|
#? 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax
|
|
#? # write to *eax to check that we have access to the newly-allocated segment
|
|
#? c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0x34/imm32 # copy to *eax
|
|
#? # syscall_exit(eax)
|
|
#? 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx
|
|
#? e8/call syscall_exit/disp32
|
|
|
|
new-segment: # len: int, ad: (addr allocation-descriptor)
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# . save registers
|
|
50/push-eax
|
|
53/push-ebx
|
|
# copy len to _mmap-new-segment->len
|
|
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax
|
|
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax $_mmap-new-segment:len/disp32 # copy eax to *$_mmap-new-segment:len
|
|
# mmap(_mmap-new-segment)
|
|
bb/copy-to-ebx _mmap-new-segment/imm32
|
|
e8/call syscall_mmap/disp32
|
|
# copy {eax, eax+len} to *ad
|
|
# . ebx = ad
|
|
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 0xc/disp8 . # copy *(ebp+12) to ebx
|
|
# . ad->curr = eax
|
|
89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx
|
|
# . ad->end = eax+len
|
|
03/add 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # add *(ebp+8) to eax
|
|
89/copy 1/mod/*+disp8 3/rm32/ebx . . . 0/r32/eax 4/disp8 . # copy eax to *(ebx+4)
|
|
$new-segment:end:
|
|
# . restore registers
|
|
5b/pop-to-ebx
|
|
58/pop-to-eax
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
== data
|
|
|
|
# various constants used here were found in the Linux sources (search for file mman-common.h)
|
|
_mmap-new-segment: # mmap_arg_struct
|
|
# addr
|
|
0/imm32
|
|
$_mmap-new-segment:len:
|
|
# len
|
|
0/imm32
|
|
# protection flags
|
|
3/imm32 # PROT_READ | PROT_WRITE
|
|
# sharing flags
|
|
0x22/imm32 # MAP_PRIVATE | MAP_ANONYMOUS
|
|
# fd
|
|
-1/imm32 # since MAP_ANONYMOUS is specified
|
|
# offset
|
|
0/imm32 # since MAP_ANONYMOUS is specified
|
|
|
|
# . . vim:nowrap:textwidth=0
|