-
-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add BPF 'cpu' #299
base: unstable
Are you sure you want to change the base?
Add BPF 'cpu' #299
Conversation
Makefile
Outdated
@echo "$(GOBUILD) -o bpf ./go/cmd/bpf" | ||
@sh -c "PATH=$(PATHX) $(GOBUILD) -o bpf ./go/cmd/bpf" | ||
$(FIXRPATH) bpf | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're ending up with a lot of commands... there must be a better way than just copy pasting this a hundred times :D (I was considering doing a busybox-style combined command for the main binary)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suck at makefiles, but could we do a sub on ALL_TARGETS .to make a phony target, and then
%: %.bla .gopath
@echo "$(GOBUILD) -o $@ ./go/cmd/$@"
@sh -c "PATH=$(PATHX) $(GOBUILD) -o $@ ./go/cmd/$@"+ $(FIXRPATH) $@
"A": bpf.A, | ||
"X": bpf.X, | ||
"PC": bpf.PC, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could totally generate this table with reflection on a Regs struct
go/arch/bpf/arch.go
Outdated
|
||
DefaultRegs: []string{ | ||
"M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", | ||
"M10", "M11", "M12", "M13", "M14", "M15", "A", "X", "PC"}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could default to Regs, it's basically just a list of regs to print while debugging (e.g. potentially everything but PC and SP)
return nil | ||
}, | ||
Interrupt: func(_ models.Usercorn, _ uint32) {}, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, any feedback on the RegisterOS api for weird things that don't really have OS flavors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked into it much. I think for ebpf extensions we may want an OS, but before I considered this, I thought about creating a 'noos' or 'nullos' that basically panics in functions.
"github.com/pkg/errors" | ||
"os" | ||
|
||
usercorn "github.com/lunixbochs/usercorn/go" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this already import as usercorn? Are you just being explicit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vim-go
decided to format it this way when I ran :GoImports
. I can fix it.
go/cmd/bpf/bpf.go
Outdated
} | ||
|
||
c.MakeUsercorn = func(filter string) (models.Usercorn, error) { | ||
// TODO: Why is packet never parsing out (always the default!) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look here: https://github.com/lunixbochs/usercorn/blob/master/go/cmd/cmd.go#L209
Maybe add some debug prints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I've tried. I confirmed it's being called and they are being parsed before reading from it, but no luck. I can dig in more later.
return nil | ||
} | ||
|
||
func (c *BpfCpu) Backend() interface{} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one isn't super important, as there's no backend handle for homemade cpus (it's used elsewhere to pull back the curtain and access unicorn internals)
go/cpu/bpf/bpf.go
Outdated
ins := code[0].(*ins) | ||
fmt.Printf("%04x: %s\n", pc, ins) | ||
|
||
c.OnCode(uint64(pc), uint32(len(ins.bytes))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're missing OnBlock
go/cpu/bpf/dis.go
Outdated
op uint16 | ||
jt uint8 | ||
jf uint8 | ||
k uint32 // Depends on addressing mode? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why store as 32-bit if values can be 64-bit in other addressing modes? mem and regs backends will enforce sizes for you at runtime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is old. K is at most 32 bits.
i.op = binary.LittleEndian.Uint16(i.bytes) | ||
i.jt = i.bytes[2] | ||
i.jf = i.bytes[3] | ||
i.k = binary.LittleEndian.Uint32(i.bytes[4:]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it would be a really good use of struc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned on slack: There might be a bug in struc, but I couldn't get this to work properly without putting these fields into a sub-struct. I think it might have to do with struc bailing out when it first sees a non-exported field.
88a1cbd
to
af44691
Compare
f07e5da
to
10db7b5
Compare
go/cpu/bpf/dis.go
Outdated
case A_A: | ||
arg = ®A{} | ||
case A_LEN: | ||
arg = nil // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this is for BPF extensions which I don't yet support. Will properly note.
go/cpu/bpf/dis.go
Outdated
i.arg = arg | ||
return i | ||
} else { | ||
// TODO: Remove this once we have all legal opcodes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still a TODO? should error/panic if so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converted string to be arg to panic.
Addr: 0x80000000, | ||
Size: uint64(r.codesize), | ||
Prot: cpu.PROT_READ | cpu.PROT_EXEC, | ||
DataFunc: func() ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you file an issue to generalize this usage of DataFunc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you want it generalized?
This change is still a WiP, but it adds a BPF emulator and a command that loads a filter and a packet and runs the filter against it.