x/debug: add syntax for getting the value of an arbitrary symbol in the binary.
Putting arbitrary symbol names through the parser won't work in general,
so we add a built-in function lookup("x") which gets the value of the
symbol x.
Change-Id: Ia35163fc93c0fcdf58bdaacefdc5121a61cd3aa1
Reviewed-on: https://go-review.googlesource.com/16855
Reviewed-by: jcd . <jcd@golang.org>
diff --git a/ogle/demo/ogler/ogler_test.go b/ogle/demo/ogler/ogler_test.go
index d825fc9..cab7f94 100644
--- a/ogle/demo/ogler/ogler_test.go
+++ b/ogle/demo/ogler/ogler_test.go
@@ -90,168 +90,267 @@
// expectedEvaluate contains expected results of the program.Evaluate function.
// A nil value indicates that an error is expected.
var expectedEvaluate = map[string]program.Value{
- `x`: int16(42),
- `local_array`: program.Array{42, 42, 5, 8},
- `local_bool_false`: false,
- `local_bool_true`: true,
- `local_channel`: program.Channel{42, 42, 42, 0, 0, 2, 0},
- `local_channel_buffered`: program.Channel{42, 42, 42, 6, 10, 2, 8},
- `local_channel_nil`: program.Channel{42, 0, 0, 0, 0, 2, 0},
- `local_complex128`: complex128(1.987654321 - 2.987654321i),
- `local_complex64`: complex64(1.54321 + 2.54321i),
- `local_float32`: float32(1.54321),
- `local_float64`: float64(1.987654321),
- `local_func_int8_r_int8`: program.Func{42},
- `local_func_int8_r_pint8`: program.Func{42},
- `local_func_bar`: program.Func{42},
- `local_func_nil`: program.Func{0},
- `local_int`: -21,
- `local_int16`: int16(-32321),
- `local_int32`: int32(-1987654321),
- `local_int64`: int64(-9012345678987654321),
- `local_int8`: int8(-121),
- `local_int_typedef`: int16(88),
- `local_interface`: program.Interface{},
- `local_interface_nil`: program.Interface{},
- `local_interface_typed_nil`: program.Interface{},
- `local_map`: program.Map{42, 42, 1},
- `local_map_2`: program.Map{42, 42, 1},
- `local_map_3`: program.Map{42, 42, 2},
- `local_map_empty`: program.Map{42, 42, 0},
- `local_map_nil`: program.Map{42, 42, 0},
- `local_pointer`: program.Pointer{42, 42},
- `local_pointer_nil`: program.Pointer{42, 0},
- `local_slice`: program.Slice{program.Array{42, 42, 5, 8}, 5},
- `local_slice_2`: program.Slice{program.Array{42, 42, 2, 8}, 5},
- `local_slice_nil`: program.Slice{program.Array{42, 0, 0, 8}, 0},
- `local_string`: program.String{12, `I'm a string`},
- `local_struct`: program.Struct{[]program.StructField{{"a", program.Var{}}, {"b", program.Var{}}}},
- `local_uint`: uint(21),
- `local_uint16`: uint16(54321),
- `local_uint32`: uint32(3217654321),
- `local_uint64`: uint64(12345678900987654321),
- `local_uint8`: uint8(231),
- `local_uintptr`: uint(21),
- `local_unsafe_pointer`: program.Pointer{0, 42},
- `local_unsafe_pointer_nil`: program.Pointer{0, 0},
- `x + 5`: int16(47),
- `x - 5`: int16(37),
- `x / 5`: int16(8),
- `x % 5`: int16(2),
- `x & 2`: int16(2),
- `x | 1`: int16(43),
- `x ^ 3`: int16(41),
- `5 + x`: int16(47),
- `5 - x`: int16(-37),
- `100 / x`: int16(2),
- `100 % x`: int16(16),
- `2 & x`: int16(2),
- `1 | x`: int16(43),
- `3 ^ x`: int16(41),
- `12`: 12,
- `+42`: 42,
- `23i`: 23i,
- `34.0`: 34.0,
- `34.5`: 34.5,
- `1e5`: 100000.0,
- `0x42`: 66,
- `'c'`: 'c',
- `"de"`: program.String{2, `de`},
- "`ef`": program.String{2, `ef`},
- `"de" + "fg"`: program.String{4, `defg`},
- `/* comment */ -5`: -5,
- `false`: false,
- `true`: true,
- `!false`: true,
- `!true`: false,
- `5 + 5`: 10,
- `true || false`: true,
- `false || false`: false,
- `true && false`: false,
- `true && true`: true,
- `!(5 > 8)`: true,
- `10 + 'a'`: 'k',
- `10 + 10.5`: 20.5,
- `10 + 10.5i`: 10 + 10.5i,
- `'a' + 10.5`: 107.5,
- `'a' + 10.5i`: 97 + 10.5i,
- `10.5 + 20.5i`: 10.5 + 20.5i,
- `10 * 20`: 200,
- `10.0 - 20.5`: -10.5,
- `(6 + 8i) * 4`: 24 + 32i,
- `(6 + 8i) * (1 + 1i)`: -2 + 14i,
- `(6 + 8i) * (6 - 8i)`: complex128(100),
- `(6 + 8i) / (3 + 4i)`: complex128(2),
- `local_string + "!"`: program.String{13, `I'm a string!`},
- `*local_pointer`: program.Struct{[]program.StructField{{"a", program.Var{}}, {"b", program.Var{}}}},
- `&local_int16`: program.Pointer{42, 42},
- `*&local_int16`: int16(-32321),
- `*&*&*&*&local_int16`: int16(-32321),
- `local_array[2]`: int8(3),
- `local_slice[1]`: uint8(108),
- `local_slice_2[1]`: int8(121),
- `&local_array[1]`: program.Pointer{42, 42},
- `&local_slice[1]`: program.Pointer{42, 42},
- `local_map[-21]`: float32(3.54321),
- `local_map[+21]`: float32(0),
- `local_map_3[1024]`: int8(1),
- `local_map_3[512]`: int8(-1),
- `local_map_empty[21]`: float32(0),
- `local_map_nil[32]`: float32(0),
- `local_string[2]`: uint8('m'),
- `"hello"[2]`: uint8('l'),
- `local_array[1:3][1]`: int8(3),
- `local_array[0:4][2:3][0]`: int8(3),
- `local_array[:]`: program.Slice{program.Array{42, 42, 5, 8}, 5},
- `local_array[:2]`: program.Slice{program.Array{42, 42, 2, 8}, 5},
- `local_array[2:]`: program.Slice{program.Array{42, 42, 3, 8}, 3},
- `local_array[1:3]`: program.Slice{program.Array{42, 42, 2, 8}, 4},
- `local_array[:3:4]`: program.Slice{program.Array{42, 42, 3, 8}, 4},
- `local_array[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
- `local_array[1:][1:][1:]`: program.Slice{program.Array{42, 42, 2, 8}, 2},
- `(&local_array)[:]`: program.Slice{program.Array{42, 42, 5, 8}, 5},
- `(&local_array)[:2]`: program.Slice{program.Array{42, 42, 2, 8}, 5},
- `(&local_array)[2:]`: program.Slice{program.Array{42, 42, 3, 8}, 3},
- `(&local_array)[1:3]`: program.Slice{program.Array{42, 42, 2, 8}, 4},
- `(&local_array)[:3:4]`: program.Slice{program.Array{42, 42, 3, 8}, 4},
- `(&local_array)[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
- `local_slice[1:5][0:3][1]`: uint8('i'),
- `local_slice[:]`: program.Slice{program.Array{42, 42, 5, 8}, 5},
- `local_slice[:2]`: program.Slice{program.Array{42, 42, 2, 8}, 5},
- `local_slice[2:]`: program.Slice{program.Array{42, 42, 3, 8}, 3},
- `local_slice[1:3]`: program.Slice{program.Array{42, 42, 2, 8}, 4},
- `local_slice[:3:4]`: program.Slice{program.Array{42, 42, 3, 8}, 4},
- `local_slice[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
- `local_struct.a`: 21,
- `(&local_struct).a`: 21,
- `(*local_pointer).a`: 21,
- `(&*local_pointer).a`: 21,
- `(*local_pointer).b`: program.String{2, `hi`},
- `local_pointer.a`: 21,
- `local_pointer.b`: program.String{2, `hi`},
- `5 + false`: nil,
- ``: nil,
- `x + ""`: nil,
- `x / 0`: nil,
- `0 / 0`: nil,
- `'a' / ('a'-'a')`: nil,
- `0.0 / 0.0`: nil,
- `3i / 0.0`: nil,
- `x % 0`: nil,
- `0 % 0`: nil,
- `'a' % ('a'-'a')`: nil,
- `local_array[-2] + 1`: nil,
- `local_array[22] + 1`: nil,
- `local_slice[-2] + 1`: nil,
- `local_slice[22] + 1`: nil,
- `local_string[-2]`: nil,
- `local_string[22]`: nil,
- `"hello"[-2]`: nil,
- `"hello"[22]`: nil,
- `local_pointer_nil.a`: nil,
- `(local_struct).c`: nil,
- `(&local_struct).c`: nil,
- `(*local_pointer).c`: nil,
+ `x`: int16(42),
+ `local_array`: program.Array{42, 42, 5, 8},
+ `local_bool_false`: false,
+ `local_bool_true`: true,
+ `local_channel`: program.Channel{42, 42, 42, 0, 0, 2, 0},
+ `local_channel_buffered`: program.Channel{42, 42, 42, 6, 10, 2, 8},
+ `local_channel_nil`: program.Channel{42, 0, 0, 0, 0, 2, 0},
+ `local_complex128`: complex128(1.987654321 - 2.987654321i),
+ `local_complex64`: complex64(1.54321 + 2.54321i),
+ `local_float32`: float32(1.54321),
+ `local_float64`: float64(1.987654321),
+ `local_func_int8_r_int8`: program.Func{42},
+ `local_func_int8_r_pint8`: program.Func{42},
+ `local_func_bar`: program.Func{42},
+ `local_func_nil`: program.Func{0},
+ `local_int`: -21,
+ `local_int16`: int16(-32321),
+ `local_int32`: int32(-1987654321),
+ `local_int64`: int64(-9012345678987654321),
+ `local_int8`: int8(-121),
+ `local_int_typedef`: int16(88),
+ `local_interface`: program.Interface{},
+ `local_interface_nil`: program.Interface{},
+ `local_interface_typed_nil`: program.Interface{},
+ `local_map`: program.Map{42, 42, 1},
+ `local_map_2`: program.Map{42, 42, 1},
+ `local_map_3`: program.Map{42, 42, 2},
+ `local_map_empty`: program.Map{42, 42, 0},
+ `local_map_nil`: program.Map{42, 42, 0},
+ `local_pointer`: program.Pointer{42, 42},
+ `local_pointer_nil`: program.Pointer{42, 0},
+ `local_slice`: program.Slice{program.Array{42, 42, 5, 8}, 5},
+ `local_slice_2`: program.Slice{program.Array{42, 42, 2, 8}, 5},
+ `local_slice_nil`: program.Slice{program.Array{42, 0, 0, 8}, 0},
+ `local_string`: program.String{12, `I'm a string`},
+ `local_struct`: program.Struct{[]program.StructField{{"a", program.Var{}}, {"b", program.Var{}}}},
+ `local_uint`: uint(21),
+ `local_uint16`: uint16(54321),
+ `local_uint32`: uint32(3217654321),
+ `local_uint64`: uint64(12345678900987654321),
+ `local_uint8`: uint8(231),
+ `local_uintptr`: uint(21),
+ `local_unsafe_pointer`: program.Pointer{0, 42},
+ `local_unsafe_pointer_nil`: program.Pointer{0, 0},
+ `x + 5`: int16(47),
+ `x - 5`: int16(37),
+ `x / 5`: int16(8),
+ `x % 5`: int16(2),
+ `x & 2`: int16(2),
+ `x | 1`: int16(43),
+ `x ^ 3`: int16(41),
+ `5 + x`: int16(47),
+ `5 - x`: int16(-37),
+ `100 / x`: int16(2),
+ `100 % x`: int16(16),
+ `2 & x`: int16(2),
+ `1 | x`: int16(43),
+ `3 ^ x`: int16(41),
+ `12`: 12,
+ `+42`: 42,
+ `23i`: 23i,
+ `34.0`: 34.0,
+ `34.5`: 34.5,
+ `1e5`: 100000.0,
+ `0x42`: 66,
+ `'c'`: 'c',
+ `"de"`: program.String{2, `de`},
+ "`ef`": program.String{2, `ef`},
+ `"de" + "fg"`: program.String{4, `defg`},
+ `/* comment */ -5`: -5,
+ `false`: false,
+ `true`: true,
+ `!false`: true,
+ `!true`: false,
+ `5 + 5`: 10,
+ `true || false`: true,
+ `false || false`: false,
+ `true && false`: false,
+ `true && true`: true,
+ `!(5 > 8)`: true,
+ `10 + 'a'`: 'k',
+ `10 + 10.5`: 20.5,
+ `10 + 10.5i`: 10 + 10.5i,
+ `'a' + 10.5`: 107.5,
+ `'a' + 10.5i`: 97 + 10.5i,
+ `10.5 + 20.5i`: 10.5 + 20.5i,
+ `10 * 20`: 200,
+ `10.0 - 20.5`: -10.5,
+ `(6 + 8i) * 4`: 24 + 32i,
+ `(6 + 8i) * (1 + 1i)`: -2 + 14i,
+ `(6 + 8i) * (6 - 8i)`: complex128(100),
+ `(6 + 8i) / (3 + 4i)`: complex128(2),
+ `local_string + "!"`: program.String{13, `I'm a string!`},
+ `*local_pointer`: program.Struct{[]program.StructField{{"a", program.Var{}}, {"b", program.Var{}}}},
+ `&local_int16`: program.Pointer{42, 42},
+ `*&local_int16`: int16(-32321),
+ `*&*&*&*&local_int16`: int16(-32321),
+ `local_array[2]`: int8(3),
+ `local_slice[1]`: uint8(108),
+ `local_slice_2[1]`: int8(121),
+ `&local_array[1]`: program.Pointer{42, 42},
+ `&local_slice[1]`: program.Pointer{42, 42},
+ `local_map[-21]`: float32(3.54321),
+ `local_map[+21]`: float32(0),
+ `local_map_3[1024]`: int8(1),
+ `local_map_3[512]`: int8(-1),
+ `local_map_empty[21]`: float32(0),
+ `local_map_nil[32]`: float32(0),
+ `local_string[2]`: uint8('m'),
+ `"hello"[2]`: uint8('l'),
+ `local_array[1:3][1]`: int8(3),
+ `local_array[0:4][2:3][0]`: int8(3),
+ `local_array[:]`: program.Slice{program.Array{42, 42, 5, 8}, 5},
+ `local_array[:2]`: program.Slice{program.Array{42, 42, 2, 8}, 5},
+ `local_array[2:]`: program.Slice{program.Array{42, 42, 3, 8}, 3},
+ `local_array[1:3]`: program.Slice{program.Array{42, 42, 2, 8}, 4},
+ `local_array[:3:4]`: program.Slice{program.Array{42, 42, 3, 8}, 4},
+ `local_array[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
+ `local_array[1:][1:][1:]`: program.Slice{program.Array{42, 42, 2, 8}, 2},
+ `(&local_array)[:]`: program.Slice{program.Array{42, 42, 5, 8}, 5},
+ `(&local_array)[:2]`: program.Slice{program.Array{42, 42, 2, 8}, 5},
+ `(&local_array)[2:]`: program.Slice{program.Array{42, 42, 3, 8}, 3},
+ `(&local_array)[1:3]`: program.Slice{program.Array{42, 42, 2, 8}, 4},
+ `(&local_array)[:3:4]`: program.Slice{program.Array{42, 42, 3, 8}, 4},
+ `(&local_array)[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
+ `local_slice[1:5][0:3][1]`: uint8('i'),
+ `local_slice[:]`: program.Slice{program.Array{42, 42, 5, 8}, 5},
+ `local_slice[:2]`: program.Slice{program.Array{42, 42, 2, 8}, 5},
+ `local_slice[2:]`: program.Slice{program.Array{42, 42, 3, 8}, 3},
+ `local_slice[1:3]`: program.Slice{program.Array{42, 42, 2, 8}, 4},
+ `local_slice[:3:4]`: program.Slice{program.Array{42, 42, 3, 8}, 4},
+ `local_slice[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
+ `local_struct.a`: 21,
+ `(&local_struct).a`: 21,
+ `(*local_pointer).a`: 21,
+ `(&*local_pointer).a`: 21,
+ `(*local_pointer).b`: program.String{2, `hi`},
+ `local_pointer.a`: 21,
+ `local_pointer.b`: program.String{2, `hi`},
+ `lookup("main.Z_array")`: program.Array{42, 42, 5, 8},
+ `lookup("main.Z_array_empty")`: program.Array{42, 42, 0, 8},
+ `lookup("main.Z_bool_false")`: false,
+ `lookup("main.Z_bool_true")`: true,
+ `lookup("main.Z_channel")`: program.Channel{42, 42, 42, 0, 0, 2, 0},
+ `lookup("main.Z_channel_buffered")`: program.Channel{42, 42, 42, 6, 10, 2, 8},
+ `lookup("main.Z_channel_nil")`: program.Channel{42, 0, 0, 0, 0, 2, 0},
+ `lookup("main.Z_array_of_empties")`: program.Array{42, 42, 2, 0},
+ `lookup("main.Z_complex128")`: complex128(1.987654321 - 2.987654321i),
+ `lookup("main.Z_complex64")`: complex64(1.54321 + 2.54321i),
+ `lookup("main.Z_float32")`: float32(1.54321),
+ `lookup("main.Z_float64")`: float64(1.987654321),
+ `lookup("main.Z_func_int8_r_int8")`: program.Func{42},
+ `lookup("main.Z_func_int8_r_pint8")`: program.Func{42},
+ `lookup("main.Z_func_bar")`: program.Func{42},
+ `lookup("main.Z_func_nil")`: program.Func{0},
+ `lookup("main.Z_int")`: -21,
+ `lookup("main.Z_int16")`: int16(-32321),
+ `lookup("main.Z_int32")`: int32(-1987654321),
+ `lookup("main.Z_int64")`: int64(-9012345678987654321),
+ `lookup("main.Z_int8")`: int8(-121),
+ `lookup("main.Z_int_typedef")`: int16(88),
+ `lookup("main.Z_interface")`: program.Interface{},
+ `lookup("main.Z_interface_nil")`: program.Interface{},
+ `lookup("main.Z_interface_typed_nil")`: program.Interface{},
+ `lookup("main.Z_map")`: program.Map{42, 42, 1},
+ `lookup("main.Z_map_2")`: program.Map{42, 42, 1},
+ `lookup("main.Z_map_3")`: program.Map{42, 42, 2},
+ `lookup("main.Z_map_empty")`: program.Map{42, 42, 0},
+ `lookup("main.Z_map_nil")`: program.Map{42, 42, 0},
+ `lookup("main.Z_pointer")`: program.Pointer{42, 42},
+ `lookup("main.Z_pointer_nil")`: program.Pointer{42, 0},
+ `lookup("main.Z_slice")`: program.Slice{program.Array{42, 42, 5, 8}, 5},
+ `lookup("main.Z_slice_2")`: program.Slice{program.Array{42, 42, 2, 8}, 5},
+ `lookup("main.Z_slice_nil")`: program.Slice{program.Array{42, 0, 0, 8}, 0},
+ `lookup("main.Z_string")`: program.String{12, `I'm a string`},
+ `lookup("main.Z_struct")`: program.Struct{[]program.StructField{{"a", program.Var{}}, {"b", program.Var{}}}},
+ `lookup("main.Z_uint")`: uint(21),
+ `lookup("main.Z_uint16")`: uint16(54321),
+ `lookup("main.Z_uint32")`: uint32(3217654321),
+ `lookup("main.Z_uint64")`: uint64(12345678900987654321),
+ `lookup("main.Z_uint8")`: uint8(231),
+ `lookup("main.Z_uintptr")`: uint(21),
+ `lookup("main.Z_unsafe_pointer")`: program.Pointer{0, 42},
+ `lookup("main.Z_unsafe_pointer_nil")`: program.Pointer{0, 0},
+ `lookup("main.Z_int") + lookup("main.Z_int")`: -42,
+ `lookup("main.Z_int16") < 0`: true,
+ `lookup("main.Z_uint32") + lookup("main.Z_uint32")`: uint32(2140341346),
+ `lookup("main.Z_bool_true") || lookup("main.Z_bool_false")`: true,
+ `lookup("main.Z_bool_true") && lookup("main.Z_bool_false")`: false,
+ `lookup("main.Z_bool_false") || lookup("main.Z_bool_false")`: false,
+ `!lookup("main.Z_bool_true")`: false,
+ `!lookup("main.Z_bool_false")`: true,
+ `lookup("main.Z_array")[2]`: int8(3),
+ `lookup("main.Z_array")[1:3][1]`: int8(3),
+ `lookup("main.Z_array")[0:4][2:3][0]`: int8(3),
+ `lookup("main.Z_array_of_empties")[0]`: program.Struct{},
+ `lookup("main.Z_complex128") * 10.0`: complex128(19.87654321 - 29.87654321i),
+ `lookup("main.Z_complex64") * 0.1`: complex64(0.154321 + 0.254321i),
+ `lookup("main.Z_float32") * 10.0`: float32(15.4321),
+ `lookup("main.Z_float64") * 0.1`: float64(0.1987654321),
+ `lookup("main.Z_int") + 1`: int(-20),
+ `lookup("main.Z_int16") - 10`: int16(-32331),
+ `lookup("main.Z_int32") / 10`: int32(-198765432),
+ `lookup("main.Z_int64") / 10`: int64(-901234567898765432),
+ `lookup("main.Z_int8") + 10`: int8(-111),
+ `lookup("main.Z_map")[-21]`: float32(3.54321),
+ `lookup("main.Z_map")[+21]`: float32(0),
+ `lookup("main.Z_map_empty")[21]`: float32(0),
+ `lookup("main.Z_slice")[1]`: uint8(108),
+ `lookup("main.Z_slice_2")[1]`: int8(121),
+ `lookup("main.Z_slice")[1:5][0:3][1]`: uint8('i'),
+ `lookup("main.Z_array")[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
+ `(&lookup("main.Z_array"))[1:3:4]`: program.Slice{program.Array{42, 42, 2, 8}, 3},
+ `lookup("main.Z_string") + "!"`: program.String{13, `I'm a string!`},
+ `lookup("main.Z_struct").a`: 21,
+ `(&lookup("main.Z_struct")).a`: 21,
+ `lookup("main.Z_uint")/10`: uint(2),
+ `lookup("main.Z_uint16")/10`: uint16(5432),
+ `lookup("main.Z_uint32")/10`: uint32(321765432),
+ `lookup("main.Z_uint64")/10`: uint64(1234567890098765432),
+ `lookup("main.Z_uint8")/10`: uint8(23),
+ `lookup("main.Z_pointer").a`: 21,
+ `(*lookup("main.Z_pointer")).a`: 21,
+ `(&*lookup("main.Z_pointer")).a`: 21,
+ `lookup("main.Z_pointer").b`: program.String{2, `hi`},
+ `(*lookup("main.Z_pointer")).b`: program.String{2, `hi`},
+ `(&*lookup("main.Z_pointer")).b`: program.String{2, `hi`},
+ `lookup("main.Z_map_nil")[32]`: float32(0),
+ `&lookup("main.Z_int16")`: program.Pointer{42, 42},
+ `&lookup("main.Z_array")[1]`: program.Pointer{42, 42},
+ `&lookup("main.Z_slice")[1]`: program.Pointer{42, 42},
+ `*&lookup("main.Z_int16")`: int16(-32321),
+ `*&*&*&*&lookup("main.Z_int16")`: int16(-32321),
+ `lookup("time.Local")`: program.Pointer{42, 42},
+ `5 + false`: nil,
+ ``: nil,
+ `x + ""`: nil,
+ `x / 0`: nil,
+ `0 / 0`: nil,
+ `'a' / ('a'-'a')`: nil,
+ `0.0 / 0.0`: nil,
+ `3i / 0.0`: nil,
+ `x % 0`: nil,
+ `0 % 0`: nil,
+ `'a' % ('a'-'a')`: nil,
+ `local_array[-2] + 1`: nil,
+ `local_array[22] + 1`: nil,
+ `local_slice[-2] + 1`: nil,
+ `local_slice[22] + 1`: nil,
+ `local_string[-2]`: nil,
+ `local_string[22]`: nil,
+ `"hello"[-2]`: nil,
+ `"hello"[22]`: nil,
+ `local_pointer_nil.a`: nil,
+ `(local_struct).c`: nil,
+ `(&local_struct).c`: nil,
+ `(*local_pointer).c`: nil,
+ `lookup("not a real symbol")`: nil,
+ `lookup("x")`: nil,
+ `lookup(x)`: nil,
+ `lookup(42)`: nil,
}
func isHex(r uint8) bool {
diff --git a/ogle/program/server/eval.go b/ogle/program/server/eval.go
index 72c3f56..51e8a28 100644
--- a/ogle/program/server/eval.go
+++ b/ogle/program/server/eval.go
@@ -102,6 +102,13 @@
// the type of the slice's elements, not the type of the slice.
type sliceOf program.Slice
+// ident is a value for representing a special identifier.
+type ident string
+
+// identLookup is a built-in function of the expression evaluator which gets the
+// value of a global symbol.
+var identLookup ident = "lookup"
+
// evalExpression evaluates a Go expression.
// If the program counter and stack pointer are nonzero, they are used to determine
// what local variables are available and where in memory they are.
@@ -234,6 +241,8 @@
return result{nil, true}
case "false":
return result{nil, false}
+ case "lookup":
+ return result{nil, identLookup}
}
return e.err("unknown identifier")
@@ -604,6 +613,29 @@
return e.err("invalid slice expression")
}
+ case *ast.CallExpr:
+ // Only supports lookup("x"), which gets the value of a global symbol x.
+ fun := e.evalNode(n.Fun, false)
+ var args []result
+ for _, a := range n.Args {
+ args = append(args, e.evalNode(a, false))
+ }
+ if fun.v == identLookup {
+ if len(args) != 1 {
+ return e.err("lookup should have one argument")
+ }
+ ident, ok := args[0].v.(untString)
+ if !ok {
+ return e.err("argument for lookup should be a string constant")
+ }
+ if a, t := e.server.findGlobalVar(string(ident)); t == nil {
+ return e.err("symbol not found")
+ } else {
+ return e.resultFrom(a, t, getAddress)
+ }
+ }
+ return e.err("function calls not implemented")
+
case *ast.UnaryExpr:
if n.Op == token.AND {
x := e.evalNode(n.X, true)
diff --git a/ogle/program/server/eval.m4 b/ogle/program/server/eval.m4
index 8540ba5..ec48880 100644
--- a/ogle/program/server/eval.m4
+++ b/ogle/program/server/eval.m4
@@ -102,6 +102,13 @@
// the type of the slice's elements, not the type of the slice.
type sliceOf program.Slice
+// ident is a value for representing a special identifier.
+type ident string
+
+// identLookup is a built-in function of the expression evaluator which gets the
+// value of a global symbol.
+var identLookup ident = "lookup"
+
// evalExpression evaluates a Go expression.
// If the program counter and stack pointer are nonzero, they are used to determine
// what local variables are available and where in memory they are.
@@ -234,6 +241,8 @@
return result{nil, true}
case "false":
return result{nil, false}
+ case "lookup":
+ return result{nil, identLookup}
}
return e.err("unknown identifier")
@@ -604,6 +613,29 @@
return e.err("invalid slice expression")
}
+ case *ast.CallExpr:
+ // Only supports lookup("x"), which gets the value of a global symbol x.
+ fun := e.evalNode(n.Fun, false)
+ var args []result
+ for _, a := range n.Args {
+ args = append(args, e.evalNode(a, false))
+ }
+ if fun.v == identLookup {
+ if len(args) != 1 {
+ return e.err("lookup should have one argument")
+ }
+ ident, ok := args[0].v.(untString)
+ if !ok {
+ return e.err("argument for lookup should be a string constant")
+ }
+ if a, t := e.server.findGlobalVar(string(ident)); t == nil {
+ return e.err("symbol not found")
+ } else {
+ return e.resultFrom(a, t, getAddress)
+ }
+ }
+ return e.err("function calls not implemented")
+
case *ast.UnaryExpr:
if n.Op == token.AND {
x := e.evalNode(n.X, true)