You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

123 lines
3.9 KiB

  1. // Copyright 2018 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package dwarf_test
  15. import (
  16. "testing"
  17. . "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf"
  18. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf"
  19. )
  20. var typedefTests = map[string]string{
  21. "t_ptr_volatile_int": "*volatile int",
  22. "t_ptr_const_char": "*const char",
  23. "t_long": "long int",
  24. "t_ushort": "short unsigned int",
  25. "t_func_int_of_float_double": "func(float, double) int",
  26. "t_ptr_func_int_of_float_double": "*func(float, double) int",
  27. "t_ptr_func_int_of_float_complex": "*func(complex float) int",
  28. "t_ptr_func_int_of_double_complex": "*func(complex double) int",
  29. "t_ptr_func_int_of_long_double_complex": "*func(complex long double) int",
  30. "t_func_ptr_int_of_char_schar_uchar": "func(char, signed char, unsigned char) *int",
  31. "t_func_void_of_char": "func(char) void",
  32. "t_func_void_of_void": "func() void",
  33. "t_func_void_of_ptr_char_dots": "func(*char, ...) void",
  34. "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}",
  35. "t_my_struct1": "struct my_struct1 {zz [1]int@0}",
  36. "t_my_union": "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}",
  37. "t_my_enum": "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}",
  38. "t_my_list": "struct list {val short int@0; next *t_my_list@8}",
  39. "t_my_tree": "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}",
  40. }
  41. func elfData(t *testing.T, name string) *Data {
  42. f, err := elf.Open(name)
  43. if err != nil {
  44. t.Fatal(err)
  45. }
  46. d, err := f.DWARF()
  47. if err != nil {
  48. t.Fatal(err)
  49. }
  50. return d
  51. }
  52. func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") }
  53. func TestTypedefsELFDwarf4(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf4"), "elf") }
  54. func testTypedefs(t *testing.T, d *Data, kind string) {
  55. r := d.Reader()
  56. seen := make(map[string]bool)
  57. for {
  58. e, err := r.Next()
  59. if err != nil {
  60. t.Fatal("r.Next:", err)
  61. }
  62. if e == nil {
  63. break
  64. }
  65. if e.Tag == TagTypedef {
  66. typ, err := d.Type(e.Offset)
  67. if err != nil {
  68. t.Fatal("d.Type:", err)
  69. }
  70. t1 := typ.(*TypedefType)
  71. var typstr string
  72. if ts, ok := t1.Type.(*StructType); ok {
  73. typstr = ts.Defn()
  74. } else {
  75. typstr = t1.Type.String()
  76. }
  77. if want, ok := typedefTests[t1.Name]; ok {
  78. if seen[t1.Name] {
  79. t.Errorf("multiple definitions for %s", t1.Name)
  80. }
  81. seen[t1.Name] = true
  82. if typstr != want {
  83. t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want)
  84. }
  85. }
  86. }
  87. if e.Tag != TagCompileUnit {
  88. r.SkipChildren()
  89. }
  90. }
  91. for k := range typedefTests {
  92. if !seen[k] {
  93. t.Errorf("missing %s", k)
  94. }
  95. }
  96. }
  97. func TestTypeForNonTypeEntry(t *testing.T) {
  98. d := elfData(t, "testdata/typedef.elf")
  99. // The returned entry will be a Subprogram.
  100. ent, err := d.LookupFunction("main")
  101. if err != nil {
  102. t.Fatal("d.LookupFunction:", err)
  103. }
  104. _, err = d.Type(ent.Offset)
  105. if err == nil {
  106. t.Fatal("nil error for unreadable entry")
  107. }
  108. }