summary refs log tree commit diff stats
path: root/cmd/cetus/main_other.go
blob: d39e66f25e124786263432d362b684ce1c9bf6d3 (plain) (blame)
1
2
3
4
5
6
7
// +build !openbsd

package main

func main() {
	app()
}
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
# Dump a stack trace when you abort.

== code

abort:  # e: (addr array byte)
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    #
    (set-cursor-position-on-real-screen 0 0)
    (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+8) 0xf 0xc)  # 0/real-screen, 0xf/fg=white, 0xc/bg=red
    (dump-call-stack)
    # crash
    {
      eb/jump loop/disp8
    }

# Helpers below this point are not intended to be reused; they assume the
# program will soon crash. In particular, they destroy the heap.

dump-call-stack:
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    51/push-ecx
    52/push-edx
    53/push-ebx
    # var labels/edx: (addr stream {start-address, label-slice} 0x4000)
    # start addresses are in ascending order
    81 5/subop/subtract %esp 0x30000/imm32  # 0x4000 labels * 12 bytes per label
    68/push  0x30000/imm32
    68/push  0/imm32/read
    68/push  0/imm32/write
    89/<- %edx 4/r32/esp
    #
    (load-debug-symbols %edx)  # destroys the heap
    # traverse the linked list of ebp pointers: https://wiki.osdev.org/Stack_Trace
    8b/-> *ebp 3/r32/ebx
    {
      # loop termination check
      81 7/subop/compare %ebx 0/imm32
      0f 84/jump-if-= break/disp32
      # loop body
      (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "\n" 0 0xc)
      (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebx+4) 0xf 0xc)
      (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 " " 0 0xc)
      (containing-function %edx *(ebx+4))  # => eax, ecx
      (draw-slice-wrapping-right-then-down-from-cursor-over-full-screen 0 %eax %ecx 0 0xc)
      # loop update
      8b/-> *ebx 3/r32/ebx
      #
      e9/jump loop/disp32
    }
$dump-call-stack:end:
    # . reclaim locals
    81 0/subop/add %esp 0x100c/imm32
    # . restore registers
    5b/pop-to-ebx
    5a/pop-to-edx
    59/pop-to-ecx
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

load-debug-symbols:  # labels: (addr stream {start-address, label-slice})
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    51/push-ecx
    52/push-edx
    53/push-ebx
    # create space for a stream on the heap, clobbering any existing data
    # var s/ecx: (addr stream byte)
    b9/copy-to-ecx 0x03000000/imm32
    c7 0/subop/copy *ecx 0/imm32  # write index
    c7 0/subop/copy *(ecx+4) 0/imm32  # read index
    c7 0/subop/copy *(ecx+8) 0x01000000/imm32  # stream capacity = 16MB
    # load 0x400 sectors starting from sector 10080 = 0x2760
    (load-sectors Primary-bus-primary-drive 0x2760 0x100 %ecx)
    (load-sectors Primary-bus-primary-drive 0x2860 0x100 %ecx)
    (load-sectors Primary-bus-primary-drive 0x2960 0x100 %ecx)
    (load-sectors Primary-bus-primary-drive 0x2a60 0x100 %ecx)
    # - parse pointers to portions of this stream into labels
    # var curr/ecx: (addr byte) = s->data
    81 0/subop/add %ecx 0xc/imm32
    {
      # loop termination check
      b8/copy-to-eax 0/imm32
      8a/byte-> *ecx 0/r32/eax
      3d/compare-eax-and 0/imm32
      0f 84/jump-if-= break/disp32
      # loop body
      (skip-to-next-space %ecx)  # => edx
      42/increment-edx
      (skip-to-next-newline %edx)  # => ebx
      (parse-hex-int-helper %edx %ebx)  # => eax
      43/increment-ebx
      (label-append *(ebp+8) %eax %ecx %edx)
      # loop update
      89/<- %ecx 3/r32/ebx
      #
      e9/jump loop/disp32
    }
$load-debug-symbols:end:
    # . restore registers
    5b/pop-to-ebx
    5a/pop-to-edx
    59/pop-to-ecx
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

skip-to-next-space:  # curr: (addr byte) -> _/edx: (addr byte)
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    # eax = 0
    b8/copy-to-eax 0/imm32
    #
    8b/-> *(ebp+8) 2/r32/edx
    {
      8a/byte-> *edx 0/r32/eax
      3d/compare-eax-and 0x20/imm32/space
      0f 84/jump-if-= break/disp32
      3d/compare-eax-and 0/imm32
      {
        75/jump-if-!= break/disp8
        (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "done loading" 7 0)
        {
          eb/jump loop/disp8
        }
      }
      3d/compare-eax-and 0xa/imm32/newline
      {
        75/jump-if-!= break/disp8
        (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "unexpected newline" 7 0)
        {
          eb/jump loop/disp8
        }
      }
      42/increment-edx
      e9/jump loop/disp32
    }
$skip-to-next-space:end:
    # . restore registers
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

skip-to-next-newline:  # curr: (addr byte) -> _/ebx: (addr byte)
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    # eax = 0
    b8/copy-to-eax 0/imm32
    #
    8b/-> *(ebp+8) 3/r32/ebx
    {
      8a/byte-> *ebx 0/r32/eax
      3d/compare-eax-and 0xa/imm32/newline
      0f 84/jump-if-= break/disp32
      3d/compare-eax-and 0/imm32
      {
        75/jump-if-!= break/disp8
        (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "done loading" 7 0)
        {
          eb/jump loop/disp8
        }
      }
      3d/compare-eax-and 0x20/imm32/space
      {
        75/jump-if-!= break/disp8
        (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "unexpected space" 7 0)
        {
          eb/jump loop/disp8
        }
      }
      43/increment-ebx
      e9/jump loop/disp32
    }
$skip-to-next-newline:end:
    # . restore registers
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

label-append:  # labels: (addr stream {start-address, label-slice}), address: int, start: int, end: int
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    51/push-ecx
    56/push-esi
    # esi = labels
    8b/-> *(ebp+8) 6/r32/esi
    # ecx = labels->write
    8b/-> *esi 1/r32/ecx
    # labels->data[labels->write] = address
    8b/-> *(ebp+0xc) 0/r32/eax
    89/<- *(esi+ecx+0xc) 0/r32/eax
    # labels->data[labels->write+4] = start
    8b/-> *(ebp+0x10) 0/r32/eax
    89/<- *(esi+ecx+0x10) 0/r32/eax
    # labels->data[labels->write+8] = end
    8b/-> *(ebp+0x14) 0/r32/eax
    89/<- *(esi+ecx+0x14) 0/r32/eax
    # labels->write += 12
    81 0/subop/add *esi 0xc/imm32
$label-append:end:
    # . restore registers
    5e/pop-to-esi
    59/pop-to-ecx
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

containing-function:  # labels: (addr stream {start-address, label-slice}), address: int -> start/eax: (addr byte), end/ecx: (addr byte)
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    52/push-edx
    53/push-ebx
    56/push-esi
    # esi = labels
    8b/-> *(ebp+8) 6/r32/esi
    # var curr/ecx: (addr byte) = labels->data
    8d/copy-address *(esi+0xc) 1/r32/ecx
    # var max/edx: (addr byte) = labels->data + labels->write
    8b/-> *esi 2/r32/edx
    01/add-to %edx 1/r32/ecx
    # var previous-function-name/ebx: (addr slice) = 0
    bb/copy-to-ebx 0/imm32
    {
      # abort if not found
      39/compare %ecx 2/r32/edx
      {
        0f 82/jump-if-addr< break/disp32
        (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "failed to find function for address " 7 0)
        (draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0 *(ebp+0xc) 7 0)
        {
          eb/jump loop/disp8
        }
      }
      # if *curr > address, break
      8b/-> *ecx 0/r32/eax
      3b/compare 0/r32/eax *(ebp+0xc)
      0f 87/jump-if-addr> break/disp32
      # if **(curr+4) not '$' or '@', save curr to previous-function-name
      {
        8b/-> *(ecx+4) 0/r32/eax
        8a/byte-> *eax 0/r32/eax
        25/and-with-eax 0xff/imm32
        3d/compare-eax-and 0x24/imm32/$
        74/jump-if-= break/disp8
        3d/compare-eax-and 0x40/imm32/@
        74/jump-if-= break/disp8
        8d/copy-address *(ecx+4) 3/r32/ebx
      }
      # loop update
      81 0/subop/add %ecx 0xc/imm32
      #
      e9/jump loop/disp32
    }
    8b/-> *ebx 0/r32/eax
    8b/-> *(ebx+4) 1/r32/ecx
$containing-function:end:
    # . restore registers
    5e/pop-to-esi
    5b/pop-to-ebx
    5a/pop-to-edx
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return

# unlike variants in .mu files, this only supports ASCII
draw-slice-wrapping-right-then-down-from-cursor-over-full-screen:  # screen: (addr screen), start: (addr byte), end: (addr byte), color: int, background-color: int
    # . prologue
    55/push-ebp
    89/<- %ebp 4/r32/esp
    # . save registers
    50/push-eax
    51/push-ecx
    52/push-edx
    # var curr/ecx: (addr byte) = start
    8b/-> *(ebp+0xc) 1/r32/ecx
    # edx = end
    8b/-> *(ebp+0x10) 2/r32/edx
    # eax = 0
    b8/copy-to-eax 0/imm32
    {
      # if (curr >= end) break
      39/compare %ecx 2/r32/edx
      73/jump-if-addr>= break/disp8
      # print *curr
      8a/byte-> *ecx 0/r32/eax
      (draw-grapheme-at-cursor *(ebp+8) %eax *(ebp+0x14) *(ebp+0x18))
      (move-cursor-rightward-and-downward *(ebp+8))
      #
      41/increment-ecx
      #
      eb/jump loop/disp8
    }
$draw-slice-wrapping-right-then-down-from-cursor-over-full-screen:end:
    # . restore registers
    5a/pop-to-edx
    59/pop-to-ecx
    58/pop-to-eax
    # . epilogue
    89/<- %esp 5/r32/ebp
    5d/pop-to-ebp
    c3/return