1 /*-
2 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3 * Copyright (c) 2010 Kai Wang
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include "_libdwarf.h"
29
30 ELFTC_VCSID("$Id: libdwarf_rw.c 2952 2013-06-26 19:09:40Z kaiwang27 $");
31
32 uint64_t
_dwarf_read_lsb(uint8_t * data,uint64_t * offsetp,int bytes_to_read)33 _dwarf_read_lsb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
34 {
35 uint64_t ret;
36 uint8_t *src;
37
38 src = data + *offsetp;
39
40 ret = 0;
41 switch (bytes_to_read) {
42 case 8:
43 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
44 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
45 case 4:
46 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
47 case 2:
48 ret |= ((uint64_t) src[1]) << 8;
49 case 1:
50 ret |= src[0];
51 break;
52 default:
53 return (0);
54 }
55
56 *offsetp += bytes_to_read;
57
58 return (ret);
59 }
60
61 uint64_t
_dwarf_decode_lsb(uint8_t ** data,int bytes_to_read)62 _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
63 {
64 uint64_t ret;
65 uint8_t *src;
66
67 src = *data;
68
69 ret = 0;
70 switch (bytes_to_read) {
71 case 8:
72 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
73 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
74 case 4:
75 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
76 case 2:
77 ret |= ((uint64_t) src[1]) << 8;
78 case 1:
79 ret |= src[0];
80 break;
81 default:
82 return (0);
83 }
84
85 *data += bytes_to_read;
86
87 return (ret);
88 }
89
90 uint64_t
_dwarf_read_msb(uint8_t * data,uint64_t * offsetp,int bytes_to_read)91 _dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
92 {
93 uint64_t ret;
94 uint8_t *src;
95
96 src = data + *offsetp;
97
98 switch (bytes_to_read) {
99 case 1:
100 ret = src[0];
101 break;
102 case 2:
103 ret = src[1] | ((uint64_t) src[0]) << 8;
104 break;
105 case 4:
106 ret = src[3] | ((uint64_t) src[2]) << 8;
107 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
108 break;
109 case 8:
110 ret = src[7] | ((uint64_t) src[6]) << 8;
111 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
112 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
113 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
114 break;
115 default:
116 return (0);
117 }
118
119 *offsetp += bytes_to_read;
120
121 return (ret);
122 }
123
124 uint64_t
_dwarf_decode_msb(uint8_t ** data,int bytes_to_read)125 _dwarf_decode_msb(uint8_t **data, int bytes_to_read)
126 {
127 uint64_t ret;
128 uint8_t *src;
129
130 src = *data;
131
132 ret = 0;
133 switch (bytes_to_read) {
134 case 1:
135 ret = src[0];
136 break;
137 case 2:
138 ret = src[1] | ((uint64_t) src[0]) << 8;
139 break;
140 case 4:
141 ret = src[3] | ((uint64_t) src[2]) << 8;
142 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
143 break;
144 case 8:
145 ret = src[7] | ((uint64_t) src[6]) << 8;
146 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
147 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
148 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
149 break;
150 default:
151 return (0);
152 break;
153 }
154
155 *data += bytes_to_read;
156
157 return (ret);
158 }
159
160 void
_dwarf_write_lsb(uint8_t * data,uint64_t * offsetp,uint64_t value,int bytes_to_write)161 _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
162 int bytes_to_write)
163 {
164 uint8_t *dst;
165
166 dst = data + *offsetp;
167
168 switch (bytes_to_write) {
169 case 8:
170 dst[7] = (value >> 56) & 0xff;
171 dst[6] = (value >> 48) & 0xff;
172 dst[5] = (value >> 40) & 0xff;
173 dst[4] = (value >> 32) & 0xff;
174 case 4:
175 dst[3] = (value >> 24) & 0xff;
176 dst[2] = (value >> 16) & 0xff;
177 case 2:
178 dst[1] = (value >> 8) & 0xff;
179 case 1:
180 dst[0] = value & 0xff;
181 break;
182 default:
183 return;
184 }
185
186 *offsetp += bytes_to_write;
187 }
188
189 int
_dwarf_write_lsb_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint64_t value,int bytes_to_write,Dwarf_Error * error)190 _dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
191 uint64_t value, int bytes_to_write, Dwarf_Error *error)
192 {
193
194 assert(*size > 0);
195
196 while (*offsetp + bytes_to_write > *size) {
197 *size *= 2;
198 *block = realloc(*block, (size_t) *size);
199 if (*block == NULL) {
200 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
201 return (DW_DLE_MEMORY);
202 }
203 }
204
205 _dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
206
207 return (DW_DLE_NONE);
208 }
209
210 void
_dwarf_write_msb(uint8_t * data,uint64_t * offsetp,uint64_t value,int bytes_to_write)211 _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
212 int bytes_to_write)
213 {
214 uint8_t *dst;
215
216 dst = data + *offsetp;
217
218 switch (bytes_to_write) {
219 case 8:
220 dst[7] = value & 0xff;
221 dst[6] = (value >> 8) & 0xff;
222 dst[5] = (value >> 16) & 0xff;
223 dst[4] = (value >> 24) & 0xff;
224 value >>= 32;
225 case 4:
226 dst[3] = value & 0xff;
227 dst[2] = (value >> 8) & 0xff;
228 value >>= 16;
229 case 2:
230 dst[1] = value & 0xff;
231 value >>= 8;
232 case 1:
233 dst[0] = value & 0xff;
234 break;
235 default:
236 return;
237 }
238
239 *offsetp += bytes_to_write;
240 }
241
242 int
_dwarf_write_msb_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint64_t value,int bytes_to_write,Dwarf_Error * error)243 _dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
244 uint64_t value, int bytes_to_write, Dwarf_Error *error)
245 {
246
247 assert(*size > 0);
248
249 while (*offsetp + bytes_to_write > *size) {
250 *size *= 2;
251 *block = realloc(*block, (size_t) *size);
252 if (*block == NULL) {
253 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
254 return (DW_DLE_MEMORY);
255 }
256 }
257
258 _dwarf_write_msb(*block, offsetp, value, bytes_to_write);
259
260 return (DW_DLE_NONE);
261 }
262
263 int64_t
_dwarf_read_sleb128(uint8_t * data,uint64_t * offsetp)264 _dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
265 {
266 int64_t ret = 0;
267 uint8_t b;
268 int shift = 0;
269 uint8_t *src;
270
271 src = data + *offsetp;
272
273 do {
274 b = *src++;
275 ret |= ((b & 0x7f) << shift);
276 (*offsetp)++;
277 shift += 7;
278 } while ((b & 0x80) != 0);
279
280 if (shift < 64 && (b & 0x40) != 0)
281 ret |= (-1 << shift);
282
283 return (ret);
284 }
285
286 int
_dwarf_write_sleb128(uint8_t * data,uint8_t * end,int64_t val)287 _dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
288 {
289 uint8_t *p;
290
291 p = data;
292
293 for (;;) {
294 if (p >= end)
295 return (-1);
296 *p = val & 0x7f;
297 val >>= 7;
298 if ((val == 0 && (*p & 0x40) == 0) ||
299 (val == -1 && (*p & 0x40) != 0)) {
300 p++;
301 break;
302 }
303 *p++ |= 0x80;
304 }
305
306 return (p - data);
307 }
308
309 int
_dwarf_write_sleb128_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,int64_t val,Dwarf_Error * error)310 _dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
311 int64_t val, Dwarf_Error *error)
312 {
313 int len;
314
315 assert(*size > 0);
316
317 while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
318 val)) < 0) {
319 *size *= 2;
320 *block = realloc(*block, (size_t) *size);
321 if (*block == NULL) {
322 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
323 return (DW_DLE_MEMORY);
324 }
325 }
326
327 *offsetp += len;
328
329 return (DW_DLE_NONE);
330 }
331
332 uint64_t
_dwarf_read_uleb128(uint8_t * data,uint64_t * offsetp)333 _dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
334 {
335 uint64_t ret = 0;
336 uint8_t b;
337 int shift = 0;
338 uint8_t *src;
339
340 src = data + *offsetp;
341
342 do {
343 b = *src++;
344 ret |= ((b & 0x7f) << shift);
345 (*offsetp)++;
346 shift += 7;
347 } while ((b & 0x80) != 0);
348
349 return (ret);
350 }
351
352 int
_dwarf_write_uleb128(uint8_t * data,uint8_t * end,uint64_t val)353 _dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
354 {
355 uint8_t *p;
356
357 p = data;
358
359 do {
360 if (p >= end)
361 return (-1);
362 *p = val & 0x7f;
363 val >>= 7;
364 if (val > 0)
365 *p |= 0x80;
366 p++;
367 } while (val > 0);
368
369 return (p - data);
370 }
371
372 int
_dwarf_write_uleb128_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint64_t val,Dwarf_Error * error)373 _dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
374 uint64_t val, Dwarf_Error *error)
375 {
376 int len;
377
378 assert(*size > 0);
379
380 while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
381 val)) < 0) {
382 *size *= 2;
383 *block = realloc(*block, (size_t) *size);
384 if (*block == NULL) {
385 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
386 return (DW_DLE_MEMORY);
387 }
388 }
389
390 *offsetp += len;
391
392 return (DW_DLE_NONE);
393 }
394
395 int64_t
_dwarf_decode_sleb128(uint8_t ** dp)396 _dwarf_decode_sleb128(uint8_t **dp)
397 {
398 int64_t ret = 0;
399 uint8_t b;
400 int shift = 0;
401
402 uint8_t *src = *dp;
403
404 do {
405 b = *src++;
406 ret |= ((b & 0x7f) << shift);
407 shift += 7;
408 } while ((b & 0x80) != 0);
409
410 if (shift < 64 && (b & 0x40) != 0)
411 ret |= (-1 << shift);
412
413 *dp = src;
414
415 return (ret);
416 }
417
418 uint64_t
_dwarf_decode_uleb128(uint8_t ** dp)419 _dwarf_decode_uleb128(uint8_t **dp)
420 {
421 uint64_t ret = 0;
422 uint8_t b;
423 int shift = 0;
424
425 uint8_t *src = *dp;
426
427 do {
428 b = *src++;
429 ret |= ((b & 0x7f) << shift);
430 shift += 7;
431 } while ((b & 0x80) != 0);
432
433 *dp = src;
434
435 return (ret);
436 }
437
438 char *
_dwarf_read_string(void * data,Dwarf_Unsigned size,uint64_t * offsetp)439 _dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
440 {
441 char *ret, *src;
442
443 ret = src = (char *) data + *offsetp;
444
445 while (*src != '\0' && *offsetp < size) {
446 src++;
447 (*offsetp)++;
448 }
449
450 if (*src == '\0' && *offsetp < size)
451 (*offsetp)++;
452
453 return (ret);
454 }
455
456 void
_dwarf_write_string(void * data,uint64_t * offsetp,char * string)457 _dwarf_write_string(void *data, uint64_t *offsetp, char *string)
458 {
459 char *dst;
460
461 dst = (char *) data + *offsetp;
462 strcpy(dst, string);
463 (*offsetp) += strlen(string) + 1;
464 }
465
466 int
_dwarf_write_string_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,char * string,Dwarf_Error * error)467 _dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
468 char *string, Dwarf_Error *error)
469 {
470 size_t len;
471
472 assert(*size > 0);
473
474 len = strlen(string) + 1;
475 while (*offsetp + len > *size) {
476 *size *= 2;
477 *block = realloc(*block, (size_t) *size);
478 if (*block == NULL) {
479 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
480 return (DW_DLE_MEMORY);
481 }
482 }
483
484 _dwarf_write_string(*block, offsetp, string);
485
486 return (DW_DLE_NONE);
487 }
488
489 uint8_t *
_dwarf_read_block(void * data,uint64_t * offsetp,uint64_t length)490 _dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
491 {
492 uint8_t *ret, *src;
493
494 ret = src = (uint8_t *) data + *offsetp;
495
496 (*offsetp) += length;
497
498 return (ret);
499 }
500
501 void
_dwarf_write_block(void * data,uint64_t * offsetp,uint8_t * blk,uint64_t length)502 _dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
503 uint64_t length)
504 {
505 uint8_t *dst;
506
507 dst = (uint8_t *) data + *offsetp;
508 memcpy(dst, blk, length);
509 (*offsetp) += length;
510 }
511
512 int
_dwarf_write_block_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint8_t * blk,uint64_t length,Dwarf_Error * error)513 _dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
514 uint8_t *blk, uint64_t length, Dwarf_Error *error)
515 {
516
517 assert(*size > 0);
518
519 while (*offsetp + length > *size) {
520 *size *= 2;
521 *block = realloc(*block, (size_t) *size);
522 if (*block == NULL) {
523 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
524 return (DW_DLE_MEMORY);
525 }
526 }
527
528 _dwarf_write_block(*block, offsetp, blk, length);
529
530 return (DW_DLE_NONE);
531 }
532
533 void
_dwarf_write_padding(void * data,uint64_t * offsetp,uint8_t byte,uint64_t length)534 _dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
535 uint64_t length)
536 {
537 uint8_t *dst;
538
539 dst = (uint8_t *) data + *offsetp;
540 memset(dst, byte, length);
541 (*offsetp) += length;
542 }
543
544 int
_dwarf_write_padding_alloc(uint8_t ** block,uint64_t * size,uint64_t * offsetp,uint8_t byte,uint64_t cnt,Dwarf_Error * error)545 _dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
546 uint8_t byte, uint64_t cnt, Dwarf_Error *error)
547 {
548 assert(*size > 0);
549
550 while (*offsetp + cnt > *size) {
551 *size *= 2;
552 *block = realloc(*block, (size_t) *size);
553 if (*block == NULL) {
554 DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
555 return (DW_DLE_MEMORY);
556 }
557 }
558
559 _dwarf_write_padding(*block, offsetp, byte, cnt);
560
561 return (DW_DLE_NONE);
562 }
563