]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/libdwarf/libdwarf_rw.c
Merge apr-1.4.8 -> apr-1.5.1 and update.
[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 2952 2013-06-26 19:09:40Z kaiwang27 $");
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         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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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 *
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
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
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
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
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 }