-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain_amd64.go
51 lines (44 loc) · 1.46 KB
/
main_amd64.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Copyright 2012-2018 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"log"
"syscall"
"github.com/linuxboot/voodoo/services"
"github.com/linuxboot/voodoo/trace"
"golang.org/x/arch/x86/x86asm"
"golang.org/x/sys/unix"
)
// halt handles the halt case. Things differ a bit from segv.
// First off, the pc will be one off, having been incrementd. Other issues apply as well.
func halt(p trace.Trace, i *unix.SignalfdSiginfo, inst *x86asm.Inst, r *syscall.PtraceRegs, asm string) error {
addr := uintptr(i.Addr)
nextpc := r.Rip
pc := r.Rip - 1
Debug("HALT@%#x, rip %#x", addr, pc)
if pc == 0xfff0 {
log.Panicf("HALT: system reset")
}
r.Rip = pc
Debug("================={HALT START FUNCTION @ %#x", addr)
if err := services.Dispatch(&services.Fault{Proc: p, Info: i, Inst: inst, Regs: r, Asm: asm}); err != nil {
return fmt.Errorf("Don't know what to do with %v: %v", trace.CallInfo(i, inst, r), err)
}
// Advance to the next instruction. This advance should only happen if the dispatch worked?
r.Rip = nextpc
defer Debug("===========} done HALT @ %#x, rip was %#x, advance to %#x", addr, pc, r.Rip)
return nil
}
func checkConsole(i *x86asm.Inst, r *syscall.PtraceRegs, asm string) {
if asm != "out %al,(%dx)" {
return
}
c := uint8(r.Rax)
if *debug {
Debug("CONSOUT: %c", c)
} else if *handleConsoleIO {
fmt.Printf("%c", c)
}
}