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