aboutsummaryrefslogtreecommitdiffstats
path: root/prog/encoding.go
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2016-10-11 14:24:25 +0200
committerAndrey Konovalov <andreyknvl@google.com>2016-10-11 20:09:19 +0200
commit78f79fee9374b8e322a0362a01e1e711ff8b9248 (patch)
tree169d357e024f99ad7e2a5e57f848569a7658c7dc /prog/encoding.go
parent6dd64c7a7036beb5607afbd066b7018aef958de7 (diff)
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 {