Skip to content
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

terminal,service: add raw examinemem dump #3721

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Documentation/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ Examine memory:
examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] <address>
examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] -x <expression>

Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal).
Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal) and raw.
Length is the number of bytes (default 1) and must be less than or equal to 1000.
Address is the memory location of the target to examine. Please note '-len' is deprecated by '-count and -size'.
Expression can be an integer expression or pointer value of the memory location to examine.
Expand Down
72 changes: 44 additions & 28 deletions pkg/terminal/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ Examine memory:
examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] <address>
examinemem [-fmt <format>] [-count|-len <count>] [-size <size>] -x <expression>

Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal).
Format represents the data format and the value is one of this list (default hex): bin(binary), oct(octal), dec(decimal), hex(hexadecimal) and raw.
Length is the number of bytes (default 1) and must be less than or equal to 1000.
Address is the memory location of the target to examine. Please note '-len' is deprecated by '-count and -size'.
Expression can be an integer expression or pointer value of the memory location to examine.
Expand Down Expand Up @@ -2057,9 +2057,10 @@ func examineMemoryCmd(t *Term, ctx callContext, argstr string) error {

// Default value
priFmt := byte('x')
count := 1
size := 1
count := int64(1)
size := int64(1)
isExpr := false
rawout := false

// nextArg returns the next argument that is not an empty string, if any, and
// advances the args slice to the position after that.
Expand All @@ -2085,27 +2086,31 @@ loop:
if arg == "" {
return errors.New("expected argument after -fmt")
}
fmtMapToPriFmt := map[string]byte{
"oct": 'o',
"octal": 'o',
"hex": 'x',
"hexadecimal": 'x',
"dec": 'd',
"decimal": 'd',
"bin": 'b',
"binary": 'b',
}
priFmt, ok = fmtMapToPriFmt[arg]
if !ok {
return fmt.Errorf("%q is not a valid format", arg)
if arg == "raw" {
rawout = true
} else {
fmtMapToPriFmt := map[string]byte{
"oct": 'o',
"octal": 'o',
"hex": 'x',
"hexadecimal": 'x',
"dec": 'd',
"decimal": 'd',
"bin": 'b',
"binary": 'b',
}
priFmt, ok = fmtMapToPriFmt[arg]
if !ok {
return fmt.Errorf("%q is not a valid format", arg)
}
}
case "-count", "-len":
arg := nextArg()
if arg == "" {
return errors.New("expected argument after -count/-len")
}
var err error
count, err = strconv.Atoi(arg)
count, err = strconv.ParseInt(arg, 0, 64)
if err != nil || count <= 0 {
return errors.New("count/len must be a positive integer")
}
Expand All @@ -2115,7 +2120,7 @@ loop:
return errors.New("expected argument after -size")
}
var err error
size, err = strconv.Atoi(arg)
size, err = strconv.ParseInt(arg, 0, 64)
if err != nil || size <= 0 || size > 8 {
return errors.New("size must be a positive integer (<=8)")
}
Expand All @@ -2131,11 +2136,6 @@ loop:
}
}

// TODO, maybe configured by user.
if count*size > 1000 {
return errors.New("read memory range (count*size) must be less than or equal to 1000 bytes")
}

if len(args) == 0 {
return errors.New("no address specified")
}
Expand Down Expand Up @@ -2169,12 +2169,28 @@ loop:
}
}

memArea, isLittleEndian, err := t.client.ExamineMemory(address, count*size)
if err != nil {
return err
}
t.stdout.pw.PageMaybe(nil)
fmt.Fprint(t.stdout, api.PrettyExamineMemory(uintptr(address), memArea, isLittleEndian, priFmt, size))

start := address
remsz := int(count * size)

for remsz > 0 {
reqsz := rpc2.ExamineMemoryLengthLimit
if reqsz > remsz {
reqsz = remsz
}
memArea, isLittleEndian, err := t.client.ExamineMemory(start, reqsz)
if err != nil {
return err
}
if rawout {
t.stdout.Write(memArea)
} else {
fmt.Fprint(t.stdout, api.PrettyExamineMemory(uintptr(start), memArea, isLittleEndian, priFmt, int(size)))
}
start += uint64(reqsz)
remsz -= reqsz
}
return nil
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/terminal/starbind/conv.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func (v sliceAsStarlarkValue) Hash() (uint32, error) {
}

func (v sliceAsStarlarkValue) String() string {
if x, ok := v.v.Interface().([]byte); ok {
return string(x)
}
return fmt.Sprintf("%#v", v.v)
}

Expand Down
4 changes: 3 additions & 1 deletion service/rpc2/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -977,8 +977,10 @@ type ExaminedMemoryOut struct {
IsLittleEndian bool
}

const ExamineMemoryLengthLimit = 1 << 16

func (s *RPCServer) ExamineMemory(arg ExamineMemoryIn, out *ExaminedMemoryOut) error {
if arg.Length > 1000 {
if arg.Length > ExamineMemoryLengthLimit {
return errors.New("len must be less than or equal to 1000")
}
Mem, err := s.debugger.ExamineMemory(arg.Address, arg.Length)
Expand Down