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