]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/libdwarf/libdwarf_rw.c
MFS r353106:
[FreeBSD/FreeBSD.git] / contrib / elftoolchain / libdwarf / libdwarf_rw.c
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 3286 2015-12-31 16:45:46Z emaste $");
31
32 uint64_t
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                 /* FALLTHROUGH */
46         case 4:
47                 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
48                 /* FALLTHROUGH */
49         case 2:
50                 ret |= ((uint64_t) src[1]) << 8;
51                 /* FALLTHROUGH */
52         case 1:
53                 ret |= src[0];
54                 break;
55         default:
56                 return (0);
57         }
58
59         *offsetp += bytes_to_read;
60
61         return (ret);
62 }
63
64 uint64_t
65 _dwarf_decode_lsb(uint8_t **data, int bytes_to_read)
66 {
67         uint64_t ret;
68         uint8_t *src;
69
70         src = *data;
71
72         ret = 0;
73         switch (bytes_to_read) {
74         case 8:
75                 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
76                 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
77                 /* FALLTHROUGH */
78         case 4:
79                 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
80                 /* FALLTHROUGH */
81         case 2:
82                 ret |= ((uint64_t) src[1]) << 8;
83                 /* FALLTHROUGH */
84         case 1:
85                 ret |= src[0];
86                 break;
87         default:
88                 return (0);
89         }
90
91         *data += bytes_to_read;
92
93         return (ret);
94 }
95
96 uint64_t
97 _dwarf_read_msb(uint8_t *data, uint64_t *offsetp, int bytes_to_read)
98 {
99         uint64_t ret;
100         uint8_t *src;
101
102         src = data + *offsetp;
103
104         switch (bytes_to_read) {
105         case 1:
106                 ret = src[0];
107                 break;
108         case 2:
109                 ret = src[1] | ((uint64_t) src[0]) << 8;
110                 break;
111         case 4:
112                 ret = src[3] | ((uint64_t) src[2]) << 8;
113                 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
114                 break;
115         case 8:
116                 ret = src[7] | ((uint64_t) src[6]) << 8;
117                 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
118                 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
119                 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
120                 break;
121         default:
122                 return (0);
123         }
124
125         *offsetp += bytes_to_read;
126
127         return (ret);
128 }
129
130 uint64_t
131 _dwarf_decode_msb(uint8_t **data, int bytes_to_read)
132 {
133         uint64_t ret;
134         uint8_t *src;
135
136         src = *data;
137
138         ret = 0;
139         switch (bytes_to_read) {
140         case 1:
141                 ret = src[0];
142                 break;
143         case 2:
144                 ret = src[1] | ((uint64_t) src[0]) << 8;
145                 break;
146         case 4:
147                 ret = src[3] | ((uint64_t) src[2]) << 8;
148                 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
149                 break;
150         case 8:
151                 ret = src[7] | ((uint64_t) src[6]) << 8;
152                 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
153                 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
154                 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
155                 break;
156         default:
157                 return (0);
158                 break;
159         }
160
161         *data += bytes_to_read;
162
163         return (ret);
164 }
165
166 void
167 _dwarf_write_lsb(uint8_t *data, uint64_t *offsetp, uint64_t value,
168     int bytes_to_write)
169 {
170         uint8_t *dst;
171
172         dst = data + *offsetp;
173
174         switch (bytes_to_write) {
175         case 8:
176                 dst[7] = (value >> 56) & 0xff;
177                 dst[6] = (value >> 48) & 0xff;
178                 dst[5] = (value >> 40) & 0xff;
179                 dst[4] = (value >> 32) & 0xff;
180                 /* FALLTHROUGH */
181         case 4:
182                 dst[3] = (value >> 24) & 0xff;
183                 dst[2] = (value >> 16) & 0xff;
184                 /* FALLTHROUGH */
185         case 2:
186                 dst[1] = (value >> 8) & 0xff;
187                 /* FALLTHROUGH */
188         case 1:
189                 dst[0] = value & 0xff;
190                 break;
191         default:
192                 return;
193         }
194
195         *offsetp += bytes_to_write;
196 }
197
198 int
199 _dwarf_write_lsb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
200     uint64_t value, int bytes_to_write, Dwarf_Error *error)
201 {
202
203         assert(*size > 0);
204
205         while (*offsetp + bytes_to_write > *size) {
206                 *size *= 2;
207                 *block = realloc(*block, (size_t) *size);
208                 if (*block == NULL) {
209                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
210                         return (DW_DLE_MEMORY);
211                 }
212         }
213
214         _dwarf_write_lsb(*block, offsetp, value, bytes_to_write);
215
216         return (DW_DLE_NONE);
217 }
218
219 void
220 _dwarf_write_msb(uint8_t *data, uint64_t *offsetp, uint64_t value,
221     int bytes_to_write)
222 {
223         uint8_t *dst;
224
225         dst = data + *offsetp;
226
227         switch (bytes_to_write) {
228         case 8:
229                 dst[7] = value & 0xff;
230                 dst[6] = (value >> 8) & 0xff;
231                 dst[5] = (value >> 16) & 0xff;
232                 dst[4] = (value >> 24) & 0xff;
233                 value >>= 32;
234                 /* FALLTHROUGH */
235         case 4:
236                 dst[3] = value & 0xff;
237                 dst[2] = (value >> 8) & 0xff;
238                 value >>= 16;
239                 /* FALLTHROUGH */
240         case 2:
241                 dst[1] = value & 0xff;
242                 value >>= 8;
243                 /* FALLTHROUGH */
244         case 1:
245                 dst[0] = value & 0xff;
246                 break;
247         default:
248                 return;
249         }
250
251         *offsetp += bytes_to_write;
252 }
253
254 int
255 _dwarf_write_msb_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
256     uint64_t value, int bytes_to_write, Dwarf_Error *error)
257 {
258
259         assert(*size > 0);
260
261         while (*offsetp + bytes_to_write > *size) {
262                 *size *= 2;
263                 *block = realloc(*block, (size_t) *size);
264                 if (*block == NULL) {
265                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
266                         return (DW_DLE_MEMORY);
267                 }
268         }
269
270         _dwarf_write_msb(*block, offsetp, value, bytes_to_write);
271
272         return (DW_DLE_NONE);
273 }
274
275 int64_t
276 _dwarf_read_sleb128(uint8_t *data, uint64_t *offsetp)
277 {
278         int64_t ret = 0;
279         uint8_t b;
280         int shift = 0;
281         uint8_t *src;
282
283         src = data + *offsetp;
284
285         do {
286                 b = *src++;
287                 ret |= ((b & 0x7f) << shift);
288                 (*offsetp)++;
289                 shift += 7;
290         } while ((b & 0x80) != 0);
291
292         if (shift < 64 && (b & 0x40) != 0)
293                 ret |= (-1 << shift);
294
295         return (ret);
296 }
297
298 int
299 _dwarf_write_sleb128(uint8_t *data, uint8_t *end, int64_t val)
300 {
301         uint8_t *p;
302
303         p = data;
304
305         for (;;) {
306                 if (p >= end)
307                         return (-1);
308                 *p = val & 0x7f;
309                 val >>= 7;
310                 if ((val == 0 && (*p & 0x40) == 0) ||
311                     (val == -1 && (*p & 0x40) != 0)) {
312                         p++;
313                         break;
314                 }
315                 *p++ |= 0x80;
316         }
317
318         return (p - data);
319 }
320
321 int
322 _dwarf_write_sleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
323     int64_t val, Dwarf_Error *error)
324 {
325         int len;
326
327         assert(*size > 0);
328
329         while ((len = _dwarf_write_sleb128(*block + *offsetp, *block + *size,
330             val)) < 0) {
331                 *size *= 2;
332                 *block = realloc(*block, (size_t) *size);
333                 if (*block == NULL) {
334                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
335                         return (DW_DLE_MEMORY);
336                 }
337         }
338
339         *offsetp += len;
340
341         return (DW_DLE_NONE);
342 }
343
344 uint64_t
345 _dwarf_read_uleb128(uint8_t *data, uint64_t *offsetp)
346 {
347         uint64_t ret = 0;
348         uint8_t b;
349         int shift = 0;
350         uint8_t *src;
351
352         src = data + *offsetp;
353
354         do {
355                 b = *src++;
356                 ret |= ((b & 0x7f) << shift);
357                 (*offsetp)++;
358                 shift += 7;
359         } while ((b & 0x80) != 0);
360
361         return (ret);
362 }
363
364 int
365 _dwarf_write_uleb128(uint8_t *data, uint8_t *end, uint64_t val)
366 {
367         uint8_t *p;
368
369         p = data;
370
371         do {
372                 if (p >= end)
373                         return (-1);
374                 *p = val & 0x7f;
375                 val >>= 7;
376                 if (val > 0)
377                         *p |= 0x80;
378                 p++;
379         } while (val > 0);
380
381         return (p - data);
382 }
383
384 int
385 _dwarf_write_uleb128_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
386     uint64_t val, Dwarf_Error *error)
387 {
388         int len;
389
390         assert(*size > 0);
391
392         while ((len = _dwarf_write_uleb128(*block + *offsetp, *block + *size,
393             val)) < 0) {
394                 *size *= 2;
395                 *block = realloc(*block, (size_t) *size);
396                 if (*block == NULL) {
397                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
398                         return (DW_DLE_MEMORY);
399                 }
400         }
401
402         *offsetp += len;
403
404         return (DW_DLE_NONE);
405 }
406
407 int64_t
408 _dwarf_decode_sleb128(uint8_t **dp)
409 {
410         int64_t ret = 0;
411         uint8_t b;
412         int shift = 0;
413
414         uint8_t *src = *dp;
415
416         do {
417                 b = *src++;
418                 ret |= ((b & 0x7f) << shift);
419                 shift += 7;
420         } while ((b & 0x80) != 0);
421
422         if (shift < 64 && (b & 0x40) != 0)
423                 ret |= (-1 << shift);
424
425         *dp = src;
426
427         return (ret);
428 }
429
430 uint64_t
431 _dwarf_decode_uleb128(uint8_t **dp)
432 {
433         uint64_t ret = 0;
434         uint8_t b;
435         int shift = 0;
436
437         uint8_t *src = *dp;
438
439         do {
440                 b = *src++;
441                 ret |= ((b & 0x7f) << shift);
442                 shift += 7;
443         } while ((b & 0x80) != 0);
444
445         *dp = src;
446
447         return (ret);
448 }
449
450 char *
451 _dwarf_read_string(void *data, Dwarf_Unsigned size, uint64_t *offsetp)
452 {
453         char *ret, *src;
454
455         ret = src = (char *) data + *offsetp;
456
457         while (*src != '\0' && *offsetp < size) {
458                 src++;
459                 (*offsetp)++;
460         }
461
462         if (*src == '\0' && *offsetp < size)
463                 (*offsetp)++;
464
465         return (ret);
466 }
467
468 void
469 _dwarf_write_string(void *data, uint64_t *offsetp, char *string)
470 {
471         char *dst;
472
473         dst = (char *) data + *offsetp;
474         strcpy(dst, string);
475         (*offsetp) += strlen(string) + 1;
476 }
477
478 int
479 _dwarf_write_string_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
480     char *string, Dwarf_Error *error)
481 {
482         size_t len;
483
484         assert(*size > 0);
485
486         len = strlen(string) + 1;
487         while (*offsetp + len > *size) {
488                 *size *= 2;
489                 *block = realloc(*block, (size_t) *size);
490                 if (*block == NULL) {
491                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
492                         return (DW_DLE_MEMORY);
493                 }
494         }
495
496         _dwarf_write_string(*block, offsetp, string);
497
498         return (DW_DLE_NONE);
499 }
500
501 uint8_t *
502 _dwarf_read_block(void *data, uint64_t *offsetp, uint64_t length)
503 {
504         uint8_t *ret, *src;
505
506         ret = src = (uint8_t *) data + *offsetp;
507
508         (*offsetp) += length;
509
510         return (ret);
511 }
512
513 void
514 _dwarf_write_block(void *data, uint64_t *offsetp, uint8_t *blk,
515     uint64_t length)
516 {
517         uint8_t *dst;
518
519         dst = (uint8_t *) data + *offsetp;
520         memcpy(dst, blk, length);
521         (*offsetp) += length;
522 }
523
524 int
525 _dwarf_write_block_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
526     uint8_t *blk, uint64_t length, Dwarf_Error *error)
527 {
528
529         assert(*size > 0);
530
531         while (*offsetp + length > *size) {
532                 *size *= 2;
533                 *block = realloc(*block, (size_t) *size);
534                 if (*block == NULL) {
535                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
536                         return (DW_DLE_MEMORY);
537                 }
538         }
539
540         _dwarf_write_block(*block, offsetp, blk, length);
541
542         return (DW_DLE_NONE);
543 }
544
545 void
546 _dwarf_write_padding(void *data, uint64_t *offsetp, uint8_t byte,
547     uint64_t length)
548 {
549         uint8_t *dst;
550
551         dst = (uint8_t *) data + *offsetp;
552         memset(dst, byte, length);
553         (*offsetp) += length;
554 }
555
556 int
557 _dwarf_write_padding_alloc(uint8_t **block, uint64_t *size, uint64_t *offsetp,
558     uint8_t byte, uint64_t cnt, Dwarf_Error *error)
559 {
560         assert(*size > 0);
561
562         while (*offsetp + cnt > *size) {
563                 *size *= 2;
564                 *block = realloc(*block, (size_t) *size);
565                 if (*block == NULL) {
566                         DWARF_SET_ERROR(NULL, error, DW_DLE_MEMORY);
567                         return (DW_DLE_MEMORY);
568                 }
569         }
570
571         _dwarf_write_padding(*block, offsetp, byte, cnt);
572
573         return (DW_DLE_NONE);
574 }