dwarfget.c (2954B)
1 /* 2 * Dwarf data format parsing routines. 3 */ 4 5 #include <u.h> 6 #include <libc.h> 7 #include <bio.h> 8 #include "elf.h" 9 #include "dwarf.h" 10 11 ulong 12 dwarfget1(DwarfBuf *b) 13 { 14 if(b->p==nil || b->p+1 > b->ep){ 15 b->p = nil; 16 return 0; 17 } 18 return *b->p++; 19 } 20 21 int 22 dwarfgetn(DwarfBuf *b, uchar *a, int n) 23 { 24 if(b->p==nil || b->p+n > b->ep){ 25 b->p = nil; 26 memset(a, 0, n); 27 return -1; 28 } 29 memmove(a, b->p, n); 30 b->p += n; 31 return 0; 32 } 33 34 uchar* 35 dwarfgetnref(DwarfBuf *b, ulong n) 36 { 37 uchar *p; 38 39 if(b->p==nil || b->p+n > b->ep){ 40 b->p = nil; 41 return nil; 42 } 43 p = b->p; 44 b->p += n; 45 return p; 46 } 47 48 char* 49 dwarfgetstring(DwarfBuf *b) 50 { 51 char *s; 52 53 if(b->p == nil) 54 return nil; 55 s = (char*)b->p; 56 while(b->p < b->ep && *b->p) 57 b->p++; 58 if(b->p >= b->ep){ 59 b->p = nil; 60 return nil; 61 } 62 b->p++; 63 return s; 64 } 65 66 void 67 dwarfskip(DwarfBuf *b, int n) 68 { 69 if(b->p==nil || b->p+n > b->ep) 70 b->p = nil; 71 else 72 b->p += n; 73 } 74 75 ulong 76 dwarfget2(DwarfBuf *b) 77 { 78 ulong v; 79 80 if(b->p==nil || b->p+2 > b->ep){ 81 b->p = nil; 82 return 0; 83 } 84 v = b->d->elf->hdr.e2(b->p); 85 b->p += 2; 86 return v; 87 } 88 89 ulong 90 dwarfget4(DwarfBuf *b) 91 { 92 ulong v; 93 94 if(b->p==nil || b->p+4 > b->ep){ 95 b->p = nil; 96 return 0; 97 } 98 v = b->d->elf->hdr.e4(b->p); 99 b->p += 4; 100 return v; 101 } 102 103 uvlong 104 dwarfget8(DwarfBuf *b) 105 { 106 uvlong v; 107 108 if(b->p==nil || b->p+8 > b->ep){ 109 b->p = nil; 110 return 0; 111 } 112 v = b->d->elf->hdr.e8(b->p); 113 b->p += 8; 114 return v; 115 } 116 117 ulong 118 dwarfgetaddr(DwarfBuf *b) 119 { 120 static int nbad; 121 122 if(b->addrsize == 0) 123 b->addrsize = b->d->addrsize; 124 125 switch(b->addrsize){ 126 case 1: 127 return dwarfget1(b); 128 case 2: 129 return dwarfget2(b); 130 case 4: 131 return dwarfget4(b); 132 case 8: 133 return dwarfget8(b); 134 default: 135 if(++nbad == 1) 136 fprint(2, "dwarf: unexpected address size %lud in dwarfgetaddr\n", b->addrsize); 137 b->p = nil; 138 return 0; 139 } 140 } 141 142 int n1, n2, n3, n4, n5; 143 144 /* An inline function picks off the calls to dwarfget128 for 1-byte encodings, 145 * more than by far the common case (99.999% on most binaries!). */ 146 ulong 147 dwarfget128(DwarfBuf *b) 148 { 149 static int nbad; 150 ulong c, d; 151 152 if(b->p == nil) 153 return 0; 154 c = *b->p++; 155 if(!(c&0x80)) 156 {n1++; 157 return c; 158 } 159 c &= ~0x80; 160 d = *b->p++; 161 c |= (d&0x7F)<<7; 162 if(!(d&0x80)) 163 {n2++; 164 return c; 165 } 166 d = *b->p++; 167 c |= (d&0x7F)<<14; 168 if(!(d&0x80)) 169 {n3++; 170 return c; 171 } 172 d = *b->p++; 173 c |= (d&0x7F)<<21; 174 if(!(d&0x80)) 175 {n4++; 176 return c; 177 } 178 d = *b->p++; 179 c |= (d&0x7F)<<28; 180 if(!(d&0x80)) 181 {n5++; 182 return c; 183 } 184 while(b->p<b->ep && *b->p&0x80) 185 b->p++; 186 if(++nbad == 1) 187 fprint(2, "dwarf: overflow during parsing of uleb128 integer\n"); 188 return c; 189 } 190 191 long 192 dwarfget128s(DwarfBuf *b) 193 { 194 int nb, c; 195 ulong v; 196 static int nbad; 197 198 v = 0; 199 nb = 0; 200 if(b->p==nil) 201 return 0; 202 while(b->p<b->ep){ 203 c = *b->p++; 204 v |= (c & 0x7F)<<nb; 205 nb += 7; 206 if(!(c&0x80)) 207 break; 208 } 209 if(v&(1<<(nb-1))) 210 v |= ~(((ulong)1<<nb)-1); 211 if(nb > 8*sizeof(ulong)){ 212 if(0) 213 if(++nbad == 1) 214 fprint(2, "dwarf: overflow during parsing of sleb128 integer: got %d bits\n", nb); 215 } 216 return v; 217 }