Blob
1 /*2 * Dwarf data format parsing routines.3 */5 #include <u.h>6 #include <libc.h>7 #include <bio.h>8 #include "elf.h"9 #include "dwarf.h"11 ulong12 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 }21 int22 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 }34 uchar*35 dwarfgetnref(DwarfBuf *b, ulong n)36 {37 uchar *p;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 }48 char*49 dwarfgetstring(DwarfBuf *b)50 {51 char *s;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 }66 void67 dwarfskip(DwarfBuf *b, int n)68 {69 if(b->p==nil || b->p+n > b->ep)70 b->p = nil;71 else72 b->p += n;73 }75 ulong76 dwarfget2(DwarfBuf *b)77 {78 ulong v;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 }89 ulong90 dwarfget4(DwarfBuf *b)91 {92 ulong v;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 }103 uvlong104 dwarfget8(DwarfBuf *b)105 {106 uvlong v;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 }117 ulong118 dwarfgetaddr(DwarfBuf *b)119 {120 static int nbad;122 if(b->addrsize == 0)123 b->addrsize = b->d->addrsize;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 }142 int n1, n2, n3, n4, n5;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 ulong147 dwarfget128(DwarfBuf *b)148 {149 static int nbad;150 ulong c, d;152 if(b->p == nil)153 return 0;154 c = *b->p++;155 if(!(c&0x80))156 {n1++;157 return c;158 }159 d = *b->p++;160 c |= (d&0x7F)<<7;161 if(!(d&0x80))162 {n2++;163 return c;164 }165 d = *b->p++;166 c |= (d&0x7F)<<14;167 if(!(d&0x80))168 {n3++;169 return c;170 }171 d = *b->p++;172 c |= (d&0x7F)<<21;173 if(!(d&0x80))174 {n4++;175 return c;176 }177 d = *b->p++;178 c |= (d&0x7F)<<28;179 if(!(d&0x80))180 {n5++;181 return c;182 }183 while(b->p<b->ep && *b->p&0x80)184 b->p++;185 if(++nbad == 1)186 fprint(2, "dwarf: overflow during parsing of uleb128 integer\n");187 return c;188 }190 long191 dwarfget128s(DwarfBuf *b)192 {193 int nb, c;194 ulong v;195 static int nbad;197 v = 0;198 nb = 0;199 if(b->p==nil)200 return 0;201 while(b->p<b->ep){202 c = *b->p++;203 v |= (c & 0x7F)<<nb;204 nb += 7;205 if(!(c&0x80))206 break;207 }208 if(v&(1<<(nb-1)))209 v |= ~(((ulong)1<<nb)-1);210 if(nb > 8*sizeof(ulong)){211 if(0)212 if(++nbad == 1)213 fprint(2, "dwarf: overflow during parsing of sleb128 integer: got %d bits\n", nb);214 }215 return v;216 }