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