aboutsummaryrefslogtreecommitdiffstats
path: root/prog/encoding.go
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@gmail.com>2016-10-11 20:12:15 +0200
committerGitHub <noreply@github.com>2016-10-11 20:12:15 +0200
commitcb8fcaf84c7386b129ef54d9ee5fd36b6c56bf0d (patch)
tree5ce14a1f0391e34fb97fd317e47ff9a799ccf79e /prog/encoding.go
parent0c1a91b184c3cb0ae4d5d7927ad51c5cde958b22 (diff)
parent2392578fe9881369b980a20fd6f169471b50a565 (diff)
Merge pull request #81 from xairy/better-len
Refactor & improve len type handling
Diffstat (limited to 'prog/encoding.go')
-rw-r--r--prog/encoding.go35
1 files changed, 25 insertions, 10 deletions
diff --git a/prog/encoding.go b/prog/encoding.go
index c9e9c52d4..01438f5b9 100644
--- a/prog/encoding.go
+++ b/prog/encoding.go
@@ -232,7 +232,7 @@ func parseArg(typ sys.Type, p *parser, vars map[string]*Arg) (*Arg, error) {
return nil, fmt.Errorf("& arg is not a pointer: %#v", typ)
}
p.Parse('&')
- page, off, err := parseAddr(p, true)
+ page, off, size, err := parseAddr(p, true)
if err != nil {
return nil, err
}
@@ -241,9 +241,9 @@ func parseArg(typ sys.Type, p *parser, vars map[string]*Arg) (*Arg, error) {
if err != nil {
return nil, err
}
- arg = pointerArg(page, off, inner)
+ arg = pointerArg(page, off, size, inner)
case '(':
- page, off, err := parseAddr(p, false)
+ page, off, _, err := parseAddr(p, false)
if err != nil {
return nil, err
}
@@ -368,22 +368,27 @@ func serializeAddr(a *Arg, base bool) string {
}
soff = fmt.Sprintf("%v0x%x", sign, off)
}
- return fmt.Sprintf("(0x%x%v)", page, soff)
+ ssize := ""
+ if size := a.AddrPagesNum; size != 0 {
+ size *= encodingPageSize
+ ssize = fmt.Sprintf("/0x%x", size)
+ }
+ return fmt.Sprintf("(0x%x%v%v)", page, soff, ssize)
}
-func parseAddr(p *parser, base bool) (uintptr, int, error) {
+func parseAddr(p *parser, base bool) (uintptr, int, uintptr, error) {
p.Parse('(')
pstr := p.Ident()
page, err := strconv.ParseUint(pstr, 0, 64)
if err != nil {
- return 0, 0, fmt.Errorf("failed to parse addr page: '%v'", pstr)
+ return 0, 0, 0, fmt.Errorf("failed to parse addr page: '%v'", pstr)
}
if page%encodingPageSize != 0 {
- return 0, 0, fmt.Errorf("address base is not page size aligned: '%v'", pstr)
+ return 0, 0, 0, fmt.Errorf("address base is not page size aligned: '%v'", pstr)
}
if base {
if page < encodingAddrBase {
- return 0, 0, fmt.Errorf("address without base offset: '%v'", pstr)
+ return 0, 0, 0, fmt.Errorf("address without base offset: '%v'", pstr)
}
page -= encodingAddrBase
}
@@ -399,16 +404,26 @@ func parseAddr(p *parser, base bool) (uintptr, int, error) {
ostr := p.Ident()
off, err = strconv.ParseInt(ostr, 0, 64)
if err != nil {
- return 0, 0, fmt.Errorf("failed to parse addr offset: '%v'", ostr)
+ return 0, 0, 0, fmt.Errorf("failed to parse addr offset: '%v'", ostr)
}
if minus {
page -= encodingPageSize
off = -off
}
}
+ var size uint64
+ if p.Char() == '/' {
+ p.Parse('/')
+ pstr := p.Ident()
+ size, err = strconv.ParseUint(pstr, 0, 64)
+ if err != nil {
+ return 0, 0, 0, fmt.Errorf("failed to parse addr size: '%v'", pstr)
+ }
+ }
p.Parse(')')
page /= encodingPageSize
- return uintptr(page), int(off), nil
+ size /= encodingPageSize
+ return uintptr(page), int(off), uintptr(size), nil
}
type parser struct {