1 package btf
2
3 import (
4 "fmt"
5 "io"
6 "math"
7 "reflect"
8 "strings"
9
10 "github.com/cilium/ebpf/asm"
11 )
12
13 const maxTypeDepth = 32
14
15
16 type TypeID uint32
17
18
19 type Type interface {
20
21
22
23
24
25
26
27
28
29 fmt.Formatter
30
31
32
33 TypeName() string
34
35
36 copy() Type
37
38
39
40 walk(*typeDeque)
41 }
42
43 var (
44 _ Type = (*Int)(nil)
45 _ Type = (*Struct)(nil)
46 _ Type = (*Union)(nil)
47 _ Type = (*Enum)(nil)
48 _ Type = (*Fwd)(nil)
49 _ Type = (*Func)(nil)
50 _ Type = (*Typedef)(nil)
51 _ Type = (*Var)(nil)
52 _ Type = (*Datasec)(nil)
53 _ Type = (*Float)(nil)
54 )
55
56
57
58
59 type types []Type
60
61 func (ts types) ByID(id TypeID) (Type, error) {
62 if int(id) > len(ts) {
63 return nil, fmt.Errorf("type ID %d: %w", id, ErrNotFound)
64 }
65 return ts[id], nil
66 }
67
68
69 type Void struct{}
70
71 func (v *Void) Format(fs fmt.State, verb rune) { formatType(fs, verb, v) }
72 func (v *Void) TypeName() string { return "" }
73 func (v *Void) size() uint32 { return 0 }
74 func (v *Void) copy() Type { return (*Void)(nil) }
75 func (v *Void) walk(*typeDeque) {}
76
77 type IntEncoding byte
78
79 const (
80 Signed IntEncoding = 1 << iota
81 Char
82 Bool
83 )
84
85 func (ie IntEncoding) IsSigned() bool {
86 return ie&Signed != 0
87 }
88
89 func (ie IntEncoding) IsChar() bool {
90 return ie&Char != 0
91 }
92
93 func (ie IntEncoding) IsBool() bool {
94 return ie&Bool != 0
95 }
96
97 func (ie IntEncoding) String() string {
98 switch {
99 case ie.IsChar() && ie.IsSigned():
100 return "char"
101 case ie.IsChar() && !ie.IsSigned():
102 return "uchar"
103 case ie.IsBool():
104 return "bool"
105 case ie.IsSigned():
106 return "signed"
107 default:
108 return "unsigned"
109 }
110 }
111
112
113
114
115 type Int struct {
116 Name string
117
118
119 Size uint32
120 Encoding IntEncoding
121 }
122
123 func (i *Int) Format(fs fmt.State, verb rune) {
124 formatType(fs, verb, i, i.Encoding, "size=", i.Size*8)
125 }
126
127 func (i *Int) TypeName() string { return i.Name }
128 func (i *Int) size() uint32 { return i.Size }
129 func (i *Int) walk(*typeDeque) {}
130 func (i *Int) copy() Type {
131 cpy := *i
132 return &cpy
133 }
134
135
136 type Pointer struct {
137 Target Type
138 }
139
140 func (p *Pointer) Format(fs fmt.State, verb rune) {
141 formatType(fs, verb, p, "target=", p.Target)
142 }
143
144 func (p *Pointer) TypeName() string { return "" }
145 func (p *Pointer) size() uint32 { return 8 }
146 func (p *Pointer) walk(tdq *typeDeque) { tdq.push(&p.Target) }
147 func (p *Pointer) copy() Type {
148 cpy := *p
149 return &cpy
150 }
151
152
153 type Array struct {
154 Index Type
155 Type Type
156 Nelems uint32
157 }
158
159 func (arr *Array) Format(fs fmt.State, verb rune) {
160 formatType(fs, verb, arr, "index=", arr.Index, "type=", arr.Type, "n=", arr.Nelems)
161 }
162
163 func (arr *Array) TypeName() string { return "" }
164
165 func (arr *Array) walk(tdq *typeDeque) {
166 tdq.push(&arr.Index)
167 tdq.push(&arr.Type)
168 }
169
170 func (arr *Array) copy() Type {
171 cpy := *arr
172 return &cpy
173 }
174
175
176 type Struct struct {
177 Name string
178
179 Size uint32
180 Members []Member
181 }
182
183 func (s *Struct) Format(fs fmt.State, verb rune) {
184 formatType(fs, verb, s, "fields=", len(s.Members))
185 }
186
187 func (s *Struct) TypeName() string { return s.Name }
188
189 func (s *Struct) size() uint32 { return s.Size }
190
191 func (s *Struct) walk(tdq *typeDeque) {
192 for i := range s.Members {
193 tdq.push(&s.Members[i].Type)
194 }
195 }
196
197 func (s *Struct) copy() Type {
198 cpy := *s
199 cpy.Members = copyMembers(s.Members)
200 return &cpy
201 }
202
203 func (s *Struct) members() []Member {
204 return s.Members
205 }
206
207
208 type Union struct {
209 Name string
210
211 Size uint32
212 Members []Member
213 }
214
215 func (u *Union) Format(fs fmt.State, verb rune) {
216 formatType(fs, verb, u, "fields=", len(u.Members))
217 }
218
219 func (u *Union) TypeName() string { return u.Name }
220
221 func (u *Union) size() uint32 { return u.Size }
222
223 func (u *Union) walk(tdq *typeDeque) {
224 for i := range u.Members {
225 tdq.push(&u.Members[i].Type)
226 }
227 }
228
229 func (u *Union) copy() Type {
230 cpy := *u
231 cpy.Members = copyMembers(u.Members)
232 return &cpy
233 }
234
235 func (u *Union) members() []Member {
236 return u.Members
237 }
238
239 func copyMembers(orig []Member) []Member {
240 cpy := make([]Member, len(orig))
241 copy(cpy, orig)
242 return cpy
243 }
244
245 type composite interface {
246 members() []Member
247 }
248
249 var (
250 _ composite = (*Struct)(nil)
251 _ composite = (*Union)(nil)
252 )
253
254
255 type Bits uint32
256
257
258 func (b Bits) Bytes() uint32 {
259 return uint32(b / 8)
260 }
261
262
263
264
265 type Member struct {
266 Name string
267 Type Type
268 Offset Bits
269 BitfieldSize Bits
270 }
271
272
273 type Enum struct {
274 Name string
275
276 Size uint32
277 Values []EnumValue
278 }
279
280 func (e *Enum) Format(fs fmt.State, verb rune) {
281 formatType(fs, verb, e, "size=", e.Size, "values=", len(e.Values))
282 }
283
284 func (e *Enum) TypeName() string { return e.Name }
285
286
287
288
289 type EnumValue struct {
290 Name string
291 Value int32
292 }
293
294 func (e *Enum) size() uint32 { return e.Size }
295 func (e *Enum) walk(*typeDeque) {}
296 func (e *Enum) copy() Type {
297 cpy := *e
298 cpy.Values = make([]EnumValue, len(e.Values))
299 copy(cpy.Values, e.Values)
300 return &cpy
301 }
302
303
304 type FwdKind int
305
306
307 const (
308 FwdStruct FwdKind = iota
309 FwdUnion
310 )
311
312 func (fk FwdKind) String() string {
313 switch fk {
314 case FwdStruct:
315 return "struct"
316 case FwdUnion:
317 return "union"
318 default:
319 return fmt.Sprintf("%T(%d)", fk, int(fk))
320 }
321 }
322
323
324 type Fwd struct {
325 Name string
326 Kind FwdKind
327 }
328
329 func (f *Fwd) Format(fs fmt.State, verb rune) {
330 formatType(fs, verb, f, f.Kind)
331 }
332
333 func (f *Fwd) TypeName() string { return f.Name }
334
335 func (f *Fwd) walk(*typeDeque) {}
336 func (f *Fwd) copy() Type {
337 cpy := *f
338 return &cpy
339 }
340
341
342 type Typedef struct {
343 Name string
344 Type Type
345 }
346
347 func (td *Typedef) Format(fs fmt.State, verb rune) {
348 formatType(fs, verb, td, td.Type)
349 }
350
351 func (td *Typedef) TypeName() string { return td.Name }
352
353 func (td *Typedef) walk(tdq *typeDeque) { tdq.push(&td.Type) }
354 func (td *Typedef) copy() Type {
355 cpy := *td
356 return &cpy
357 }
358
359
360 type Volatile struct {
361 Type Type
362 }
363
364 func (v *Volatile) Format(fs fmt.State, verb rune) {
365 formatType(fs, verb, v, v.Type)
366 }
367
368 func (v *Volatile) TypeName() string { return "" }
369
370 func (v *Volatile) qualify() Type { return v.Type }
371 func (v *Volatile) walk(tdq *typeDeque) { tdq.push(&v.Type) }
372 func (v *Volatile) copy() Type {
373 cpy := *v
374 return &cpy
375 }
376
377
378 type Const struct {
379 Type Type
380 }
381
382 func (c *Const) Format(fs fmt.State, verb rune) {
383 formatType(fs, verb, c, c.Type)
384 }
385
386 func (c *Const) TypeName() string { return "" }
387
388 func (c *Const) qualify() Type { return c.Type }
389 func (c *Const) walk(tdq *typeDeque) { tdq.push(&c.Type) }
390 func (c *Const) copy() Type {
391 cpy := *c
392 return &cpy
393 }
394
395
396 type Restrict struct {
397 Type Type
398 }
399
400 func (r *Restrict) Format(fs fmt.State, verb rune) {
401 formatType(fs, verb, r, r.Type)
402 }
403
404 func (r *Restrict) TypeName() string { return "" }
405
406 func (r *Restrict) qualify() Type { return r.Type }
407 func (r *Restrict) walk(tdq *typeDeque) { tdq.push(&r.Type) }
408 func (r *Restrict) copy() Type {
409 cpy := *r
410 return &cpy
411 }
412
413
414 type Func struct {
415 Name string
416 Type Type
417 Linkage FuncLinkage
418 }
419
420 func FuncMetadata(ins *asm.Instruction) *Func {
421 fn, _ := ins.Metadata.Get(funcInfoMeta{}).(*Func)
422 return fn
423 }
424
425 func (f *Func) Format(fs fmt.State, verb rune) {
426 formatType(fs, verb, f, f.Linkage, "proto=", f.Type)
427 }
428
429 func (f *Func) TypeName() string { return f.Name }
430
431 func (f *Func) walk(tdq *typeDeque) { tdq.push(&f.Type) }
432 func (f *Func) copy() Type {
433 cpy := *f
434 return &cpy
435 }
436
437
438 type FuncProto struct {
439 Return Type
440 Params []FuncParam
441 }
442
443 func (fp *FuncProto) Format(fs fmt.State, verb rune) {
444 formatType(fs, verb, fp, "args=", len(fp.Params), "return=", fp.Return)
445 }
446
447 func (fp *FuncProto) TypeName() string { return "" }
448
449 func (fp *FuncProto) walk(tdq *typeDeque) {
450 tdq.push(&fp.Return)
451 for i := range fp.Params {
452 tdq.push(&fp.Params[i].Type)
453 }
454 }
455
456 func (fp *FuncProto) copy() Type {
457 cpy := *fp
458 cpy.Params = make([]FuncParam, len(fp.Params))
459 copy(cpy.Params, fp.Params)
460 return &cpy
461 }
462
463 type FuncParam struct {
464 Name string
465 Type Type
466 }
467
468
469 type Var struct {
470 Name string
471 Type Type
472 Linkage VarLinkage
473 }
474
475 func (v *Var) Format(fs fmt.State, verb rune) {
476 formatType(fs, verb, v, v.Linkage)
477 }
478
479 func (v *Var) TypeName() string { return v.Name }
480
481 func (v *Var) walk(tdq *typeDeque) { tdq.push(&v.Type) }
482 func (v *Var) copy() Type {
483 cpy := *v
484 return &cpy
485 }
486
487
488 type Datasec struct {
489 Name string
490 Size uint32
491 Vars []VarSecinfo
492 }
493
494 func (ds *Datasec) Format(fs fmt.State, verb rune) {
495 formatType(fs, verb, ds)
496 }
497
498 func (ds *Datasec) TypeName() string { return ds.Name }
499
500 func (ds *Datasec) size() uint32 { return ds.Size }
501
502 func (ds *Datasec) walk(tdq *typeDeque) {
503 for i := range ds.Vars {
504 tdq.push(&ds.Vars[i].Type)
505 }
506 }
507
508 func (ds *Datasec) copy() Type {
509 cpy := *ds
510 cpy.Vars = make([]VarSecinfo, len(ds.Vars))
511 copy(cpy.Vars, ds.Vars)
512 return &cpy
513 }
514
515
516
517
518 type VarSecinfo struct {
519 Type Type
520 Offset uint32
521 Size uint32
522 }
523
524
525 type Float struct {
526 Name string
527
528
529 Size uint32
530 }
531
532 func (f *Float) Format(fs fmt.State, verb rune) {
533 formatType(fs, verb, f, "size=", f.Size*8)
534 }
535
536 func (f *Float) TypeName() string { return f.Name }
537 func (f *Float) size() uint32 { return f.Size }
538 func (f *Float) walk(*typeDeque) {}
539 func (f *Float) copy() Type {
540 cpy := *f
541 return &cpy
542 }
543
544
545 type cycle struct {
546 root Type
547 }
548
549 func (c *cycle) ID() TypeID { return math.MaxUint32 }
550 func (c *cycle) Format(fs fmt.State, verb rune) { formatType(fs, verb, c, "root=", c.root) }
551 func (c *cycle) TypeName() string { return "" }
552 func (c *cycle) walk(*typeDeque) {}
553 func (c *cycle) copy() Type {
554 cpy := *c
555 return &cpy
556 }
557
558 type sizer interface {
559 size() uint32
560 }
561
562 var (
563 _ sizer = (*Int)(nil)
564 _ sizer = (*Pointer)(nil)
565 _ sizer = (*Struct)(nil)
566 _ sizer = (*Union)(nil)
567 _ sizer = (*Enum)(nil)
568 _ sizer = (*Datasec)(nil)
569 )
570
571 type qualifier interface {
572 qualify() Type
573 }
574
575 var (
576 _ qualifier = (*Const)(nil)
577 _ qualifier = (*Restrict)(nil)
578 _ qualifier = (*Volatile)(nil)
579 )
580
581
582
583
584 func Sizeof(typ Type) (int, error) {
585 var (
586 n = int64(1)
587 elem int64
588 )
589
590 for i := 0; i < maxTypeDepth; i++ {
591 switch v := typ.(type) {
592 case *Array:
593 if n > 0 && int64(v.Nelems) > math.MaxInt64/n {
594 return 0, fmt.Errorf("type %s: overflow", typ)
595 }
596
597
598
599 n *= int64(v.Nelems)
600 typ = v.Type
601 continue
602
603 case sizer:
604 elem = int64(v.size())
605
606 case *Typedef:
607 typ = v.Type
608 continue
609
610 case qualifier:
611 typ = v.qualify()
612 continue
613
614 default:
615 return 0, fmt.Errorf("unsized type %T", typ)
616 }
617
618 if n > 0 && elem > math.MaxInt64/n {
619 return 0, fmt.Errorf("type %s: overflow", typ)
620 }
621
622 size := n * elem
623 if int64(int(size)) != size {
624 return 0, fmt.Errorf("type %s: overflow", typ)
625 }
626
627 return int(size), nil
628 }
629
630 return 0, fmt.Errorf("type %s: exceeded type depth", typ)
631 }
632
633
634
635
636 func alignof(typ Type) (int, error) {
637 switch t := UnderlyingType(typ).(type) {
638 case *Enum:
639 return int(t.size()), nil
640 case *Int:
641 return int(t.Size), nil
642 default:
643 return 0, fmt.Errorf("can't calculate alignment of %T", t)
644 }
645 }
646
647
648
649
650
651 type Transformer func(Type) Type
652
653
654
655
656
657 func Copy(typ Type, transform Transformer) Type {
658 copies := make(copier)
659 copies.copy(&typ, transform)
660 return typ
661 }
662
663
664
665
666 func copyTypes(types []Type, transform Transformer) []Type {
667 result := make([]Type, len(types))
668 copy(result, types)
669
670 copies := make(copier)
671 for i := range result {
672 copies.copy(&result[i], transform)
673 }
674
675 return result
676 }
677
678 type copier map[Type]Type
679
680 func (c copier) copy(typ *Type, transform Transformer) {
681 var work typeDeque
682 for t := typ; t != nil; t = work.pop() {
683
684 if cpy := c[*t]; cpy != nil {
685 *t = cpy
686 continue
687 }
688
689 var cpy Type
690 if transform != nil {
691 cpy = transform(*t).copy()
692 } else {
693 cpy = (*t).copy()
694 }
695
696 c[*t] = cpy
697 *t = cpy
698
699
700 cpy.walk(&work)
701 }
702 }
703
704
705
706 type typeDeque struct {
707 types []*Type
708 read, write uint64
709 mask uint64
710 }
711
712 func (dq *typeDeque) empty() bool {
713 return dq.read == dq.write
714 }
715
716
717 func (dq *typeDeque) push(t *Type) {
718 if dq.write-dq.read < uint64(len(dq.types)) {
719 dq.types[dq.write&dq.mask] = t
720 dq.write++
721 return
722 }
723
724 new := len(dq.types) * 2
725 if new == 0 {
726 new = 8
727 }
728
729 types := make([]*Type, new)
730 pivot := dq.read & dq.mask
731 n := copy(types, dq.types[pivot:])
732 n += copy(types[n:], dq.types[:pivot])
733 types[n] = t
734
735 dq.types = types
736 dq.mask = uint64(new) - 1
737 dq.read, dq.write = 0, uint64(n+1)
738 }
739
740
741 func (dq *typeDeque) shift() *Type {
742 if dq.empty() {
743 return nil
744 }
745
746 index := dq.read & dq.mask
747 t := dq.types[index]
748 dq.types[index] = nil
749 dq.read++
750 return t
751 }
752
753
754 func (dq *typeDeque) pop() *Type {
755 if dq.empty() {
756 return nil
757 }
758
759 dq.write--
760 index := dq.write & dq.mask
761 t := dq.types[index]
762 dq.types[index] = nil
763 return t
764 }
765
766
767
768
769 func (dq *typeDeque) all() []*Type {
770 length := dq.write - dq.read
771 types := make([]*Type, 0, length)
772 for t := dq.shift(); t != nil; t = dq.shift() {
773 types = append(types, t)
774 }
775 return types
776 }
777
778
779
780
781
782
783
784
785
786
787 func inflateRawTypes(rawTypes []rawType, baseTypes types, rawStrings *stringTable) ([]Type, error) {
788 types := make([]Type, 0, len(rawTypes)+1)
789
790 typeIDOffset := TypeID(1)
791
792 if baseTypes == nil {
793
794 types = append(types, (*Void)(nil))
795 } else {
796
797 typeIDOffset = TypeID(len(baseTypes))
798 }
799
800 type fixupDef struct {
801 id TypeID
802 typ *Type
803 }
804
805 var fixups []fixupDef
806 fixup := func(id TypeID, typ *Type) {
807 if id < TypeID(len(baseTypes)) {
808 *typ = baseTypes[id]
809 return
810 }
811
812 idx := id
813 if baseTypes != nil {
814 idx = id - TypeID(len(baseTypes))
815 }
816 if idx < TypeID(len(types)) {
817
818 *typ = types[idx]
819 return
820 }
821 fixups = append(fixups, fixupDef{id, typ})
822 }
823
824 type assertion struct {
825 typ *Type
826 want reflect.Type
827 }
828
829 var assertions []assertion
830 assert := func(typ *Type, want reflect.Type) error {
831 if *typ != nil {
832
833 if reflect.TypeOf(*typ) != want {
834 return fmt.Errorf("expected %s, got %T", want, *typ)
835 }
836 return nil
837 }
838 assertions = append(assertions, assertion{typ, want})
839 return nil
840 }
841
842 type bitfieldFixupDef struct {
843 id TypeID
844 m *Member
845 }
846
847 var (
848 legacyBitfields = make(map[TypeID][2]Bits)
849 bitfieldFixups []bitfieldFixupDef
850 )
851 convertMembers := func(raw []btfMember, kindFlag bool) ([]Member, error) {
852
853
854 members := make([]Member, 0, len(raw))
855 for i, btfMember := range raw {
856 name, err := rawStrings.Lookup(btfMember.NameOff)
857 if err != nil {
858 return nil, fmt.Errorf("can't get name for member %d: %w", i, err)
859 }
860
861 members = append(members, Member{
862 Name: name,
863 Offset: Bits(btfMember.Offset),
864 })
865
866 m := &members[i]
867 fixup(raw[i].Type, &m.Type)
868
869 if kindFlag {
870 m.BitfieldSize = Bits(btfMember.Offset >> 24)
871 m.Offset &= 0xffffff
872
873
874
875
876 continue
877 }
878
879
880 data, ok := legacyBitfields[raw[i].Type]
881 if ok {
882
883 m.Offset += data[0]
884 m.BitfieldSize = data[1]
885 continue
886 }
887
888 if m.Type != nil {
889
890
891
892 continue
893 }
894
895
896
897
898 bitfieldFixups = append(bitfieldFixups, bitfieldFixupDef{
899 raw[i].Type,
900 m,
901 })
902 }
903 return members, nil
904 }
905
906 for i, raw := range rawTypes {
907 var (
908 id = typeIDOffset + TypeID(i)
909 typ Type
910 )
911
912 name, err := rawStrings.Lookup(raw.NameOff)
913 if err != nil {
914 return nil, fmt.Errorf("get name for type id %d: %w", id, err)
915 }
916
917 switch raw.Kind() {
918 case kindInt:
919 size := raw.Size()
920 bi := raw.data.(*btfInt)
921 if bi.Offset() > 0 || bi.Bits().Bytes() != size {
922 legacyBitfields[id] = [2]Bits{bi.Offset(), bi.Bits()}
923 }
924 typ = &Int{name, raw.Size(), bi.Encoding()}
925
926 case kindPointer:
927 ptr := &Pointer{nil}
928 fixup(raw.Type(), &ptr.Target)
929 typ = ptr
930
931 case kindArray:
932 btfArr := raw.data.(*btfArray)
933 arr := &Array{nil, nil, btfArr.Nelems}
934 fixup(btfArr.IndexType, &arr.Index)
935 fixup(btfArr.Type, &arr.Type)
936 typ = arr
937
938 case kindStruct:
939 members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
940 if err != nil {
941 return nil, fmt.Errorf("struct %s (id %d): %w", name, id, err)
942 }
943 typ = &Struct{name, raw.Size(), members}
944
945 case kindUnion:
946 members, err := convertMembers(raw.data.([]btfMember), raw.KindFlag())
947 if err != nil {
948 return nil, fmt.Errorf("union %s (id %d): %w", name, id, err)
949 }
950 typ = &Union{name, raw.Size(), members}
951
952 case kindEnum:
953 rawvals := raw.data.([]btfEnum)
954 vals := make([]EnumValue, 0, len(rawvals))
955 for i, btfVal := range rawvals {
956 name, err := rawStrings.Lookup(btfVal.NameOff)
957 if err != nil {
958 return nil, fmt.Errorf("get name for enum value %d: %s", i, err)
959 }
960 vals = append(vals, EnumValue{
961 Name: name,
962 Value: btfVal.Val,
963 })
964 }
965 typ = &Enum{name, raw.Size(), vals}
966
967 case kindForward:
968 if raw.KindFlag() {
969 typ = &Fwd{name, FwdUnion}
970 } else {
971 typ = &Fwd{name, FwdStruct}
972 }
973
974 case kindTypedef:
975 typedef := &Typedef{name, nil}
976 fixup(raw.Type(), &typedef.Type)
977 typ = typedef
978
979 case kindVolatile:
980 volatile := &Volatile{nil}
981 fixup(raw.Type(), &volatile.Type)
982 typ = volatile
983
984 case kindConst:
985 cnst := &Const{nil}
986 fixup(raw.Type(), &cnst.Type)
987 typ = cnst
988
989 case kindRestrict:
990 restrict := &Restrict{nil}
991 fixup(raw.Type(), &restrict.Type)
992 typ = restrict
993
994 case kindFunc:
995 fn := &Func{name, nil, raw.Linkage()}
996 fixup(raw.Type(), &fn.Type)
997 if err := assert(&fn.Type, reflect.TypeOf((*FuncProto)(nil))); err != nil {
998 return nil, err
999 }
1000 typ = fn
1001
1002 case kindFuncProto:
1003 rawparams := raw.data.([]btfParam)
1004 params := make([]FuncParam, 0, len(rawparams))
1005 for i, param := range rawparams {
1006 name, err := rawStrings.Lookup(param.NameOff)
1007 if err != nil {
1008 return nil, fmt.Errorf("get name for func proto parameter %d: %s", i, err)
1009 }
1010 params = append(params, FuncParam{
1011 Name: name,
1012 })
1013 }
1014 for i := range params {
1015 fixup(rawparams[i].Type, ¶ms[i].Type)
1016 }
1017
1018 fp := &FuncProto{nil, params}
1019 fixup(raw.Type(), &fp.Return)
1020 typ = fp
1021
1022 case kindVar:
1023 variable := raw.data.(*btfVariable)
1024 v := &Var{name, nil, VarLinkage(variable.Linkage)}
1025 fixup(raw.Type(), &v.Type)
1026 typ = v
1027
1028 case kindDatasec:
1029 btfVars := raw.data.([]btfVarSecinfo)
1030 vars := make([]VarSecinfo, 0, len(btfVars))
1031 for _, btfVar := range btfVars {
1032 vars = append(vars, VarSecinfo{
1033 Offset: btfVar.Offset,
1034 Size: btfVar.Size,
1035 })
1036 }
1037 for i := range vars {
1038 fixup(btfVars[i].Type, &vars[i].Type)
1039 if err := assert(&vars[i].Type, reflect.TypeOf((*Var)(nil))); err != nil {
1040 return nil, err
1041 }
1042 }
1043 typ = &Datasec{name, raw.SizeType, vars}
1044
1045 case kindFloat:
1046 typ = &Float{name, raw.Size()}
1047
1048 default:
1049 return nil, fmt.Errorf("type id %d: unknown kind: %v", id, raw.Kind())
1050 }
1051
1052 types = append(types, typ)
1053 }
1054
1055 for _, fixup := range fixups {
1056 i := int(fixup.id)
1057 if i >= len(types)+len(baseTypes) {
1058 return nil, fmt.Errorf("reference to invalid type id: %d", fixup.id)
1059 }
1060 if i < len(baseTypes) {
1061 return nil, fmt.Errorf("fixup for base type id %d is not expected", i)
1062 }
1063
1064 *fixup.typ = types[i-len(baseTypes)]
1065 }
1066
1067 for _, bitfieldFixup := range bitfieldFixups {
1068 if bitfieldFixup.id < TypeID(len(baseTypes)) {
1069 return nil, fmt.Errorf("bitfield fixup from split to base types is not expected")
1070 }
1071
1072 data, ok := legacyBitfields[bitfieldFixup.id]
1073 if ok {
1074
1075 bitfieldFixup.m.Offset += data[0]
1076 bitfieldFixup.m.BitfieldSize = data[1]
1077 }
1078 }
1079
1080 for _, assertion := range assertions {
1081 if reflect.TypeOf(*assertion.typ) != assertion.want {
1082 return nil, fmt.Errorf("expected %s, got %T", assertion.want, *assertion.typ)
1083 }
1084 }
1085
1086 return types, nil
1087 }
1088
1089
1090
1091 type essentialName string
1092
1093
1094
1095
1096
1097
1098
1099 func newEssentialName(name string) essentialName {
1100 if name == "" {
1101 return ""
1102 }
1103 lastIdx := strings.LastIndex(name, "___")
1104 if lastIdx > 0 {
1105 return essentialName(name[:lastIdx])
1106 }
1107 return essentialName(name)
1108 }
1109
1110
1111 func UnderlyingType(typ Type) Type {
1112 result := typ
1113 for depth := 0; depth <= maxTypeDepth; depth++ {
1114 switch v := (result).(type) {
1115 case qualifier:
1116 result = v.qualify()
1117 case *Typedef:
1118 result = v.Type
1119 default:
1120 return result
1121 }
1122 }
1123 return &cycle{typ}
1124 }
1125
1126 type formatState struct {
1127 fmt.State
1128 depth int
1129 }
1130
1131
1132 type formattableType interface {
1133 fmt.Formatter
1134 TypeName() string
1135 }
1136
1137
1138
1139
1140
1141
1142 func formatType(f fmt.State, verb rune, t formattableType, extra ...interface{}) {
1143 if verb != 'v' && verb != 's' {
1144 fmt.Fprintf(f, "{UNRECOGNIZED: %c}", verb)
1145 return
1146 }
1147
1148
1149
1150 goTypeName := reflect.TypeOf(t).Elem().Name()
1151 _, _ = io.WriteString(f, goTypeName)
1152
1153 if name := t.TypeName(); name != "" {
1154
1155 fmt.Fprintf(f, ":%q", name)
1156 }
1157
1158 if f.Flag('+') {
1159
1160 fmt.Fprintf(f, ":%#p", t)
1161 }
1162
1163 if verb == 's' {
1164
1165 return
1166 }
1167
1168 var depth int
1169 if ps, ok := f.(*formatState); ok {
1170 depth = ps.depth
1171 f = ps.State
1172 }
1173
1174 maxDepth, ok := f.Width()
1175 if !ok {
1176 maxDepth = 0
1177 }
1178
1179 if depth > maxDepth {
1180
1181
1182 return
1183 }
1184
1185 if len(extra) == 0 {
1186 return
1187 }
1188
1189 wantSpace := false
1190 _, _ = io.WriteString(f, "[")
1191 for _, arg := range extra {
1192 if wantSpace {
1193 _, _ = io.WriteString(f, " ")
1194 }
1195
1196 switch v := arg.(type) {
1197 case string:
1198 _, _ = io.WriteString(f, v)
1199 wantSpace = len(v) > 0 && v[len(v)-1] != '='
1200 continue
1201
1202 case formattableType:
1203 v.Format(&formatState{f, depth + 1}, verb)
1204
1205 default:
1206 fmt.Fprint(f, arg)
1207 }
1208
1209 wantSpace = true
1210 }
1211 _, _ = io.WriteString(f, "]")
1212 }
1213
View as plain text