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 c &= ~0x80;160 d = *b->p++;161 c |= (d&0x7F)<<7;162 if(!(d&0x80))163 {n2++;164 return c;165 }166 d = *b->p++;167 c |= (d&0x7F)<<14;168 if(!(d&0x80))169 {n3++;170 return c;171 }172 d = *b->p++;173 c |= (d&0x7F)<<21;174 if(!(d&0x80))175 {n4++;176 return c;177 }178 d = *b->p++;179 c |= (d&0x7F)<<28;180 if(!(d&0x80))181 {n5++;182 return c;183 }184 while(b->p<b->ep && *b->p&0x80)185 b->p++;186 if(++nbad == 1)187 fprint(2, "dwarf: overflow during parsing of uleb128 integer\n");188 return c;189 }191 long192 dwarfget128s(DwarfBuf *b)193 {194 int nb, c;195 ulong v;196 static int nbad;198 v = 0;199 nb = 0;200 if(b->p==nil)201 return 0;202 while(b->p<b->ep){203 c = *b->p++;204 v |= (c & 0x7F)<<nb;205 nb += 7;206 if(!(c&0x80))207 break;208 }209 if(v&(1<<(nb-1)))210 v |= ~(((ulong)1<<nb)-1);211 if(nb > 8*sizeof(ulong)){212 if(0)213 if(++nbad == 1)214 fprint(2, "dwarf: overflow during parsing of sleb128 integer: got %d bits\n", nb);215 }216 return v;217 }