plan9port

[fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port # fast
git clone https://src.adamsgaard.dk/plan9port.git # slow
Log | Files | Refs | README | LICENSE Back to index

dwarfget.c (2954B)


      1 /*
      2  * Dwarf data format parsing routines.
      3  */
      4 
      5 #include <u.h>
      6 #include <libc.h>
      7 #include <bio.h>
      8 #include "elf.h"
      9 #include "dwarf.h"
     10 
     11 ulong
     12 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 }
     20 
     21 int
     22 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 }
     33 
     34 uchar*
     35 dwarfgetnref(DwarfBuf *b, ulong n)
     36 {
     37 	uchar *p;
     38 
     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 }
     47 
     48 char*
     49 dwarfgetstring(DwarfBuf *b)
     50 {
     51 	char *s;
     52 
     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 }
     65 
     66 void
     67 dwarfskip(DwarfBuf *b, int n)
     68 {
     69 	if(b->p==nil || b->p+n > b->ep)
     70 		b->p = nil;
     71 	else
     72 		b->p += n;
     73 }
     74 
     75 ulong
     76 dwarfget2(DwarfBuf *b)
     77 {
     78 	ulong v;
     79 
     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 }
     88 
     89 ulong
     90 dwarfget4(DwarfBuf *b)
     91 {
     92 	ulong v;
     93 
     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 }
    102 
    103 uvlong
    104 dwarfget8(DwarfBuf *b)
    105 {
    106 	uvlong v;
    107 
    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 }
    116 
    117 ulong
    118 dwarfgetaddr(DwarfBuf *b)
    119 {
    120 	static int nbad;
    121 
    122 	if(b->addrsize == 0)
    123 		b->addrsize = b->d->addrsize;
    124 
    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 }
    141 
    142 int n1, n2, n3, n4, n5;
    143 
    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 ulong
    147 dwarfget128(DwarfBuf *b)
    148 {
    149 	static int nbad;
    150 	ulong c, d;
    151 
    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 }
    190 
    191 long
    192 dwarfget128s(DwarfBuf *b)
    193 {
    194 	int nb, c;
    195 	ulong v;
    196 	static int nbad;
    197 
    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 }