1 /* 2 * Dwarf abbreviation parsing code. 3 * 4 * The convention here is that calling dwarfgetabbrevs relinquishes 5 * access to any abbrevs returned previously. Will have to add 6 * explicit reference counting if this turns out not to be acceptable. 7 */ 8 9 #define NTOSAPI 10 #include <ntddk.h> 11 #include <reactos/rossym.h> 12 #include "rossympriv.h" 13 #include <ntimage.h> 14 15 #define NDEBUG 16 #include <debug.h> 17 18 #include "rossym.h" 19 #include "rossympriv.h" 20 #include "dwarf.h" 21 22 static int parseabbrevs(Dwarf*, ulong, DwarfAbbrev*, DwarfAttr*, int*, int*); 23 DwarfAbbrev *dwarfgetabbrev(Dwarf*, ulong, ulong); 24 25 static int 26 loadabbrevs(Dwarf *d, ulong off, DwarfAbbrev **aa) 27 { 28 int nattr, nabbrev; 29 DwarfAbbrev *abbrev; 30 DwarfAttr *attr; 31 32 if(d->acache.off == off && d->acache.na){ 33 *aa = d->acache.a; 34 return d->acache.na; 35 } 36 37 /* two passes - once to count, then allocate, then a second to copy */ 38 if(parseabbrevs(d, off, nil, nil, &nabbrev, &nattr) < 0) { 39 return -1; 40 } 41 42 abbrev = malloc(nabbrev*sizeof(DwarfAbbrev) + nattr*sizeof(DwarfAttr)); 43 attr = (DwarfAttr*)(abbrev+nabbrev); 44 45 if(parseabbrevs(d, off, abbrev, attr, nil, nil) < 0){ 46 free(abbrev); 47 return -1; 48 } 49 50 free(d->acache.a); 51 d->acache.a = abbrev; 52 d->acache.na = nabbrev; 53 d->acache.off = off; 54 55 *aa = abbrev; 56 return nabbrev; 57 } 58 59 static int 60 parseabbrevs(Dwarf *d, ulong off, DwarfAbbrev *abbrev, DwarfAttr *attr, int *pnabbrev, int *pnattr) 61 { 62 int i, nabbrev, nattr, haskids; 63 ulong num, tag, name, form; 64 DwarfBuf b; 65 66 if(off >= d->abbrev.len){ 67 werrstr("bad abbrev section offset 0x%lux >= 0x%lux\n", off, d->abbrev.len); 68 return -1; 69 } 70 71 memset(&b, 0, sizeof b); 72 b.p = d->abbrev.data + off; 73 b.ep = d->abbrev.data + d->abbrev.len; 74 75 nabbrev = 0; 76 nattr = 0; 77 for(;;){ 78 if(b.p == nil){ 79 werrstr("malformed abbrev data"); 80 return -1; 81 } 82 num = dwarfget128(&b); 83 if(num == 0) 84 break; 85 tag = dwarfget128(&b); 86 haskids = dwarfget1(&b); 87 for(i=0;; i++){ 88 name = dwarfget128(&b); 89 form = dwarfget128(&b); 90 if(name == 0 && form == 0) 91 break; 92 if(attr){ 93 attr[i].name = name; 94 attr[i].form = form; 95 } 96 } 97 if(abbrev){ 98 abbrev->num = num; 99 abbrev->tag = tag; 100 abbrev->haskids = haskids; 101 abbrev->attr = attr; 102 abbrev->nattr = i; 103 abbrev++; 104 attr += i; 105 } 106 nabbrev++; 107 nattr += i; 108 } 109 if(pnabbrev) 110 *pnabbrev = nabbrev; 111 if(pnattr) 112 *pnattr = nattr; 113 return 0; 114 } 115 116 static DwarfAbbrev* 117 findabbrev(DwarfAbbrev *a, int na, ulong num) 118 { 119 int i; 120 121 for(i=0; i<na; i++) 122 if(a[i].num == num) 123 return &a[i]; 124 werrstr("abbrev not found"); 125 return nil; 126 } 127 128 DwarfAbbrev* 129 dwarfgetabbrev(Dwarf *d, ulong off, ulong num) 130 { 131 DwarfAbbrev *a; 132 int na; 133 134 if((na = loadabbrevs(d, off, &a)) < 0){ 135 werrstr("loadabbrevs: %r"); 136 return nil; 137 } 138 return findabbrev(a, na, num); 139 } 140 141 142