github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/dwarf/frame/entries.go (about) 1 // The MIT License (MIT) 2 3 // Copyright (c) 2014 Derek Parker 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy of 6 // this software and associated documentation files (the "Software"), to deal in 7 // the Software without restriction, including without limitation the rights to 8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 // the Software, and to permit persons to whom the Software is furnished to do so, 10 // subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 package frame 23 24 import ( 25 "encoding/binary" 26 "fmt" 27 "sort" 28 ) 29 30 31 32 type CommonInformationEntry struct { 33 Length uint32 34 CIE_id uint32 35 Version uint8 36 Augmentation string 37 CodeAlignmentFactor uint64 38 DataAlignmentFactor int64 39 ReturnAddressRegister uint64 40 InitialInstructions []byte 41 staticBase uint64 42 43 44 ptrEncAddr ptrEnc 45 } 46 47 48 49 type FrameDescriptionEntry struct { 50 Length uint32 51 CIE *CommonInformationEntry 52 Instructions []byte 53 begin, size uint64 54 order binary.ByteOrder 55 } 56 57 58 59 func (fde *FrameDescriptionEntry) Cover(addr uint64) bool { 60 return (addr - fde.begin) < fde.size 61 } 62 63 64 func (fde *FrameDescriptionEntry) Begin() uint64 { 65 return fde.begin 66 } 67 68 69 func (fde *FrameDescriptionEntry) End() uint64 { 70 return fde.begin + fde.size 71 } 72 73 74 func (fde *FrameDescriptionEntry) Translate(delta uint64) { 75 fde.begin += delta 76 } 77 78 79 func (fde *FrameDescriptionEntry) EstablishFrame(pc uint64) *FrameContext { 80 return executeDwarfProgramUntilPC(fde, pc) 81 } 82 83 type FrameDescriptionEntries []*FrameDescriptionEntry 84 85 func newFrameIndex() FrameDescriptionEntries { 86 return make(FrameDescriptionEntries, 0, 1000) 87 } 88 89 90 type ErrNoFDEForPC struct { 91 PC uint64 92 } 93 94 func (err *ErrNoFDEForPC) Error() string { 95 return fmt.Sprintf("could not find FDE for PC %#v", err.PC) 96 } 97 98 99 func (fdes FrameDescriptionEntries) FDEForPC(pc uint64) (*FrameDescriptionEntry, error) { 100 idx := sort.Search(len(fdes), func(i int) bool { 101 return fdes[i].Cover(pc) || fdes[i].Begin() >= pc 102 }) 103 if idx == len(fdes) || !fdes[idx].Cover(pc) { 104 return nil, &ErrNoFDEForPC{pc} 105 } 106 return fdes[idx], nil 107 } 108 109 110 func (fdes FrameDescriptionEntries) Append(otherFDEs FrameDescriptionEntries) FrameDescriptionEntries { 111 r := append(fdes, otherFDEs...) 112 sort.SliceStable(r, func(i, j int) bool { 113 return r[i].Begin() < r[j].Begin() 114 }) 115 116 uniqFDEs := fdes[:0] 117 for _, fde := range fdes { 118 if len(uniqFDEs) > 0 { 119 last := uniqFDEs[len(uniqFDEs)-1] 120 if last.Begin() == fde.Begin() && last.End() == fde.End() { 121 continue 122 } 123 } 124 uniqFDEs = append(uniqFDEs, fde) 125 } 126 return r 127 } 128 129 130 131 132 133 134 135 type ptrEnc uint8 136 137 const ( 138 ptrEncAbs ptrEnc = 0x00 139 ptrEncOmit ptrEnc = 0xff 140 ptrEncUleb ptrEnc = 0x01 141 ptrEncUdata2 ptrEnc = 0x02 142 ptrEncUdata4 ptrEnc = 0x03 143 ptrEncUdata8 ptrEnc = 0x04 144 ptrEncSigned ptrEnc = 0x08 145 ptrEncSleb ptrEnc = 0x09 146 ptrEncSdata2 ptrEnc = 0x0a 147 ptrEncSdata4 ptrEnc = 0x0b 148 ptrEncSdata8 ptrEnc = 0x0c 149 150 ptrEncPCRel ptrEnc = 0x10 151 ptrEncTextRel ptrEnc = 0x20 152 ptrEncDataRel ptrEnc = 0x30 153 ptrEncFuncRel ptrEnc = 0x40 154 ptrEncAligned ptrEnc = 0x50 155 ptrEncIndirect ptrEnc = 0x80 156 ) 157 158 159 func (ptrEnc ptrEnc) Supported() bool { 160 if ptrEnc != ptrEncOmit { 161 szenc := ptrEnc & 0x0f 162 if ((szenc > ptrEncUdata8) && (szenc < ptrEncSigned)) || (szenc > ptrEncSdata8) { 163 164 return false 165 } 166 if ptrEnc&0xf0 != ptrEncPCRel { 167 168 return false 169 } 170 } 171 return true 172 }