Skip to content

Commit

Permalink
Add COM cmd to load MS-DOS COM files
Browse files Browse the repository at this point in the history
Since COM files don't have a header/magic, has a simple memory map, it's
best to have it a separate command.
  • Loading branch information
Grazfather authored and lunixbochs committed May 13, 2017
1 parent 1c9ad5a commit 0ebc22a
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
deps/

/cgc
/com
/fuzz
/imgtrace
/repl
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ trace: .gopath
sh -c "PATH=$(PATHX) $(GOBUILD) -o trace ./go/cmd/trace"
$(FIXRPATH) trace

com: .gopath
sh -c "PATH=$(PATHX) $(GOBUILD) -o com ./go/cmd/com"
$(FIXRPATH) com

get: .gopath
sh -c "PATH=$(PATHX) go get -u ${DEPS}"

Expand Down
7 changes: 1 addition & 6 deletions go/arch/x86_16/dos.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,7 @@ func DosInit(u models.Usercorn, args, env []string) error {
u.RegWrite(enum, uint64(reg.Val))
}
}
u.RegWrite(u.Arch().SP, 0xbaaaaffc)
// TODO: Determine stack address. Right now making it linux x86 32-like
// with the stack ending at 0xC...
if err := u.MapStack(0xA000, 0x2000); err != nil {
return err
}
u.RegWrite(u.Arch().SP, 0x8000)
return nil
}

Expand Down
57 changes: 57 additions & 0 deletions go/cmd/com/com.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package main

import (
"bytes"
"github.com/pkg/errors"
"io/ioutil"
"os"

"github.com/lunixbochs/usercorn/go"
"github.com/lunixbochs/usercorn/go/cmd"
"github.com/lunixbochs/usercorn/go/loader"
"github.com/lunixbochs/usercorn/go/models"
)

func main() {
c := cmd.NewUsercornRawCmd()
c.NoArgs = true

c.MakeUsercorn = func(exe string) (models.Usercorn, error) {
p, err := ioutil.ReadFile(exe)
if err != nil {
return nil, err
}
r := bytes.NewReader(p)
l, err := loader.NewComLoader(r)
if err != nil {
return nil, errors.Wrap(err, "failed to load COM file")
}
u, err := usercorn.NewUsercornRaw(l, c.Config)

// Map in entire 16 bit address space
err = u.MemMapProt(0, 0x10000, 7)
if err != nil {
return nil, errors.Wrap(err, "failed to map in address space")
}

// Write in each segment's data
segments, err := l.Segments()
if err != nil {
return nil, errors.Wrap(err, "failed to get segments from loader")
}
for _, seg := range segments {
data, err := seg.Data()
if err != nil {
return nil, errors.Wrap(err, "failed to read segment data")
}

err = u.MemWrite(seg.Addr, data)
if err != nil {
return nil, errors.Wrap(err, "failed to write segment data")
}
}

return u, nil
}
c.Run(os.Args, os.Environ())
}
2 changes: 1 addition & 1 deletion go/loader/com.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (c *ComLoader) OS() string {
return "DOS"
}

func NewComLoader(r io.ReaderAt, arch string) (models.Loader, error) {
func NewComLoader(r io.ReaderAt) (models.Loader, error) {
// Calculate bin size
// TODO: We could maybe just pass the file, not the reader
buf := make([]byte, 0x1000)
Expand Down
9 changes: 1 addition & 8 deletions go/loader/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ func LoadArch(r io.ReaderAt, arch string) (models.Loader, error) {
} else if MatchCgc(r) {
return NewCgcLoader(r, arch)
} else {
// TODO: Make COM a separate, explicit command
// COM doesn't have a header
loader, err := NewComLoader(r, arch)
if err != nil {
return nil, errors.WithStack(UnknownMagic)
} else {
return loader, err
}
return nil, errors.WithStack(UnknownMagic)
}
}

0 comments on commit 0ebc22a

Please sign in to comment.