/src/binutils-gdb/bfd/libbfd.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Assorted BFD support routines, only used internally. |
2 | | Copyright (C) 1990-2023 Free Software Foundation, Inc. |
3 | | Written by Cygnus Support. |
4 | | |
5 | | This file is part of BFD, the Binary File Descriptor library. |
6 | | |
7 | | This program is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3 of the License, or |
10 | | (at your option) any later version. |
11 | | |
12 | | This program is distributed in the hope that it will be useful, |
13 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | GNU General Public License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; if not, write to the Free Software |
19 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 | | MA 02110-1301, USA. */ |
21 | | |
22 | | #include "sysdep.h" |
23 | | #include "bfd.h" |
24 | | #include "libbfd.h" |
25 | | #include "objalloc.h" |
26 | | |
27 | | #ifndef HAVE_GETPAGESIZE |
28 | | #define getpagesize() 2048 |
29 | | #endif |
30 | | |
31 | | /* |
32 | | SECTION |
33 | | Implementation details |
34 | | |
35 | | SUBSECTION |
36 | | Internal functions |
37 | | |
38 | | DESCRIPTION |
39 | | These routines are used within BFD. |
40 | | They are not intended for export, but are documented here for |
41 | | completeness. |
42 | | */ |
43 | | |
44 | | bool |
45 | | _bfd_bool_bfd_false (bfd *abfd ATTRIBUTE_UNUSED) |
46 | 0 | { |
47 | 0 | return false; |
48 | 0 | } |
49 | | |
50 | | bool |
51 | | _bfd_bool_bfd_asymbol_false (bfd *abfd ATTRIBUTE_UNUSED, |
52 | | asymbol *sym ATTRIBUTE_UNUSED) |
53 | 1.36M | { |
54 | 1.36M | return false; |
55 | 1.36M | } |
56 | | |
57 | | /* A routine which is used in target vectors for unsupported |
58 | | operations. */ |
59 | | |
60 | | bool |
61 | | _bfd_bool_bfd_false_error (bfd *ignore ATTRIBUTE_UNUSED) |
62 | 11.4k | { |
63 | 11.4k | bfd_set_error (bfd_error_invalid_operation); |
64 | 11.4k | return false; |
65 | 11.4k | } |
66 | | |
67 | | bool |
68 | | _bfd_bool_bfd_link_false_error (bfd *abfd, |
69 | | struct bfd_link_info *info ATTRIBUTE_UNUSED) |
70 | 0 | { |
71 | 0 | return _bfd_bool_bfd_false_error (abfd); |
72 | 0 | } |
73 | | |
74 | | /* A routine which is used in target vectors for supported operations |
75 | | which do not actually do anything. */ |
76 | | |
77 | | bool |
78 | | _bfd_bool_bfd_true (bfd *ignore ATTRIBUTE_UNUSED) |
79 | 21.6k | { |
80 | 21.6k | return true; |
81 | 21.6k | } |
82 | | |
83 | | bool |
84 | | _bfd_bool_bfd_link_true (bfd *abfd ATTRIBUTE_UNUSED, |
85 | | struct bfd_link_info *info ATTRIBUTE_UNUSED) |
86 | 0 | { |
87 | 0 | return true; |
88 | 0 | } |
89 | | |
90 | | bool |
91 | | _bfd_bool_bfd_bfd_true (bfd *ibfd ATTRIBUTE_UNUSED, |
92 | | bfd *obfd ATTRIBUTE_UNUSED) |
93 | 70 | { |
94 | 70 | return true; |
95 | 70 | } |
96 | | |
97 | | bool |
98 | | _bfd_bool_bfd_uint_true (bfd *abfd ATTRIBUTE_UNUSED, |
99 | | unsigned int flags ATTRIBUTE_UNUSED) |
100 | 0 | { |
101 | 0 | return true; |
102 | 0 | } |
103 | | |
104 | | bool |
105 | | _bfd_bool_bfd_asection_bfd_asection_true (bfd *ibfd ATTRIBUTE_UNUSED, |
106 | | asection *isec ATTRIBUTE_UNUSED, |
107 | | bfd *obfd ATTRIBUTE_UNUSED, |
108 | | asection *osec ATTRIBUTE_UNUSED) |
109 | 7.25k | { |
110 | 7.25k | return true; |
111 | 7.25k | } |
112 | | |
113 | | bool |
114 | | _bfd_bool_bfd_asymbol_bfd_asymbol_true (bfd *ibfd ATTRIBUTE_UNUSED, |
115 | | asymbol *isym ATTRIBUTE_UNUSED, |
116 | | bfd *obfd ATTRIBUTE_UNUSED, |
117 | | asymbol *osym ATTRIBUTE_UNUSED) |
118 | 0 | { |
119 | 0 | return true; |
120 | 0 | } |
121 | | |
122 | | bool |
123 | | _bfd_bool_bfd_ptr_true (bfd *abfd ATTRIBUTE_UNUSED, |
124 | | void *ptr ATTRIBUTE_UNUSED) |
125 | 11.8k | { |
126 | 11.8k | return true; |
127 | 11.8k | } |
128 | | |
129 | | /* A routine which is used in target vectors for unsupported |
130 | | operations which return a pointer value. */ |
131 | | |
132 | | void * |
133 | | _bfd_ptr_bfd_null_error (bfd *ignore ATTRIBUTE_UNUSED) |
134 | 160k | { |
135 | 160k | bfd_set_error (bfd_error_invalid_operation); |
136 | 160k | return NULL; |
137 | 160k | } |
138 | | |
139 | | int |
140 | | _bfd_int_bfd_0 (bfd *ignore ATTRIBUTE_UNUSED) |
141 | 0 | { |
142 | 0 | return 0; |
143 | 0 | } |
144 | | |
145 | | unsigned int |
146 | | _bfd_uint_bfd_0 (bfd *ignore ATTRIBUTE_UNUSED) |
147 | 0 | { |
148 | 0 | return 0; |
149 | 0 | } |
150 | | |
151 | | long |
152 | | _bfd_long_bfd_0 (bfd *ignore ATTRIBUTE_UNUSED) |
153 | 0 | { |
154 | 0 | return 0; |
155 | 0 | } |
156 | | |
157 | | /* A routine which is used in target vectors for unsupported |
158 | | operations which return -1 on error. */ |
159 | | |
160 | | long |
161 | | _bfd_long_bfd_n1_error (bfd *ignore_abfd ATTRIBUTE_UNUSED) |
162 | 30.0k | { |
163 | 30.0k | bfd_set_error (bfd_error_invalid_operation); |
164 | 30.0k | return -1; |
165 | 30.0k | } |
166 | | |
167 | | void |
168 | | _bfd_void_bfd (bfd *ignore ATTRIBUTE_UNUSED) |
169 | 3.48M | { |
170 | 3.48M | } |
171 | | |
172 | | void |
173 | | _bfd_void_bfd_link (bfd *abfd ATTRIBUTE_UNUSED, |
174 | | struct bfd_link_info *info ATTRIBUTE_UNUSED) |
175 | 0 | { |
176 | 0 | } |
177 | | |
178 | | void |
179 | | _bfd_void_bfd_asection (bfd *abfd ATTRIBUTE_UNUSED, |
180 | | asection *sec ATTRIBUTE_UNUSED) |
181 | 0 | { |
182 | 0 | } |
183 | | |
184 | | long |
185 | | _bfd_norelocs_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED, |
186 | | asection *sec ATTRIBUTE_UNUSED) |
187 | 11 | { |
188 | 11 | return sizeof (arelent *); |
189 | 11 | } |
190 | | |
191 | | long |
192 | | _bfd_norelocs_canonicalize_reloc (bfd *abfd ATTRIBUTE_UNUSED, |
193 | | asection *sec ATTRIBUTE_UNUSED, |
194 | | arelent **relptr, |
195 | | asymbol **symbols ATTRIBUTE_UNUSED) |
196 | 11 | { |
197 | 11 | *relptr = NULL; |
198 | 11 | return 0; |
199 | 11 | } |
200 | | |
201 | | void |
202 | | _bfd_norelocs_set_reloc (bfd *abfd ATTRIBUTE_UNUSED, |
203 | | asection *sec ATTRIBUTE_UNUSED, |
204 | | arelent **relptr ATTRIBUTE_UNUSED, |
205 | | unsigned int count ATTRIBUTE_UNUSED) |
206 | 7 | { |
207 | | /* Do nothing. */ |
208 | 7 | } |
209 | | |
210 | | bool |
211 | | _bfd_nocore_core_file_matches_executable_p |
212 | | (bfd *ignore_core_bfd ATTRIBUTE_UNUSED, |
213 | | bfd *ignore_exec_bfd ATTRIBUTE_UNUSED) |
214 | 0 | { |
215 | 0 | bfd_set_error (bfd_error_invalid_operation); |
216 | 0 | return false; |
217 | 0 | } |
218 | | |
219 | | /* Routine to handle core_file_failing_command entry point for targets |
220 | | without core file support. */ |
221 | | |
222 | | char * |
223 | | _bfd_nocore_core_file_failing_command (bfd *ignore_abfd ATTRIBUTE_UNUSED) |
224 | 0 | { |
225 | 0 | bfd_set_error (bfd_error_invalid_operation); |
226 | 0 | return NULL; |
227 | 0 | } |
228 | | |
229 | | /* Routine to handle core_file_failing_signal entry point for targets |
230 | | without core file support. */ |
231 | | |
232 | | int |
233 | | _bfd_nocore_core_file_failing_signal (bfd *ignore_abfd ATTRIBUTE_UNUSED) |
234 | 0 | { |
235 | 0 | bfd_set_error (bfd_error_invalid_operation); |
236 | 0 | return 0; |
237 | 0 | } |
238 | | |
239 | | /* Routine to handle the core_file_pid entry point for targets without |
240 | | core file support. */ |
241 | | |
242 | | int |
243 | | _bfd_nocore_core_file_pid (bfd *ignore_abfd ATTRIBUTE_UNUSED) |
244 | 0 | { |
245 | 0 | bfd_set_error (bfd_error_invalid_operation); |
246 | 0 | return 0; |
247 | 0 | } |
248 | | |
249 | | bfd_cleanup |
250 | | _bfd_dummy_target (bfd *ignore_abfd ATTRIBUTE_UNUSED) |
251 | 8.94M | { |
252 | 8.94M | bfd_set_error (bfd_error_wrong_format); |
253 | 8.94M | return 0; |
254 | 8.94M | } |
255 | | |
256 | | /* Allocate memory using malloc. */ |
257 | | |
258 | | #ifndef SSIZE_MAX |
259 | 18.2M | #define SSIZE_MAX ((size_t) -1 >> 1) |
260 | | #endif |
261 | | |
262 | | /* |
263 | | INTERNAL_FUNCTION |
264 | | bfd_malloc |
265 | | |
266 | | SYNOPSIS |
267 | | void *bfd_malloc (bfd_size_type {*size*}); |
268 | | |
269 | | DESCRIPTION |
270 | | Returns a pointer to an allocated block of memory that is at least |
271 | | SIZE bytes long. If SIZE is 0 then it will be treated as if it were |
272 | | 1. If SIZE is too big then NULL will be returned. |
273 | | |
274 | | Returns NULL upon error and sets bfd_error. |
275 | | */ |
276 | | void * |
277 | | bfd_malloc (bfd_size_type size) |
278 | 18.1M | { |
279 | 18.1M | void *ptr; |
280 | 18.1M | size_t sz = (size_t) size; |
281 | | |
282 | 18.1M | if (size != sz |
283 | | /* This is to pacify memory checkers like valgrind. */ |
284 | 18.1M | || sz > SSIZE_MAX) |
285 | 0 | { |
286 | 0 | bfd_set_error (bfd_error_no_memory); |
287 | 0 | return NULL; |
288 | 0 | } |
289 | | |
290 | 18.1M | ptr = malloc (sz ? sz : 1); |
291 | 18.1M | if (ptr == NULL) |
292 | 0 | bfd_set_error (bfd_error_no_memory); |
293 | | |
294 | 18.1M | return ptr; |
295 | 18.1M | } |
296 | | |
297 | | /* |
298 | | INTERNAL_FUNCTION |
299 | | bfd_realloc |
300 | | |
301 | | SYNOPSIS |
302 | | void *bfd_realloc (void *{*mem*}, bfd_size_type {*size*}); |
303 | | |
304 | | DESCRIPTION |
305 | | Returns a pointer to an allocated block of memory that is at least |
306 | | SIZE bytes long. If SIZE is 0 then it will be treated as if it were |
307 | | 1. If SIZE is too big then NULL will be returned. |
308 | | |
309 | | If MEM is not NULL then it must point to an allocated block of memory. |
310 | | If this block is large enough then MEM may be used as the return |
311 | | value for this function, but this is not guaranteed. |
312 | | |
313 | | If MEM is not returned then the first N bytes in the returned block |
314 | | will be identical to the first N bytes in region pointed to by MEM, |
315 | | where N is the lessor of SIZE and the length of the region of memory |
316 | | currently addressed by MEM. |
317 | | |
318 | | Returns NULL upon error and sets bfd_error. |
319 | | */ |
320 | | void * |
321 | | bfd_realloc (void *ptr, bfd_size_type size) |
322 | 211k | { |
323 | 211k | void *ret; |
324 | 211k | size_t sz = (size_t) size; |
325 | | |
326 | 211k | if (ptr == NULL) |
327 | 87.3k | return bfd_malloc (size); |
328 | | |
329 | 124k | if (size != sz |
330 | | /* This is to pacify memory checkers like valgrind. */ |
331 | 124k | || sz > SSIZE_MAX) |
332 | 0 | { |
333 | 0 | bfd_set_error (bfd_error_no_memory); |
334 | 0 | return NULL; |
335 | 0 | } |
336 | | |
337 | | /* The behaviour of realloc(0) is implementation defined, |
338 | | but for this function we always allocate memory. */ |
339 | 124k | ret = realloc (ptr, sz ? sz : 1); |
340 | | |
341 | 124k | if (ret == NULL) |
342 | 0 | bfd_set_error (bfd_error_no_memory); |
343 | | |
344 | 124k | return ret; |
345 | 124k | } |
346 | | |
347 | | /* |
348 | | INTERNAL_FUNCTION |
349 | | bfd_realloc_or_free |
350 | | |
351 | | SYNOPSIS |
352 | | void *bfd_realloc_or_free (void *{*mem*}, bfd_size_type {*size*}); |
353 | | |
354 | | DESCRIPTION |
355 | | Returns a pointer to an allocated block of memory that is at least |
356 | | SIZE bytes long. If SIZE is 0 then no memory will be allocated, |
357 | | MEM will be freed, and NULL will be returned. This will not cause |
358 | | bfd_error to be set. |
359 | | |
360 | | If SIZE is too big then NULL will be returned and bfd_error will be |
361 | | set. |
362 | | |
363 | | If MEM is not NULL then it must point to an allocated block of memory. |
364 | | If this block is large enough then MEM may be used as the return |
365 | | value for this function, but this is not guaranteed. |
366 | | |
367 | | If MEM is not returned then the first N bytes in the returned block |
368 | | will be identical to the first N bytes in region pointed to by MEM, |
369 | | where N is the lessor of SIZE and the length of the region of memory |
370 | | currently addressed by MEM. |
371 | | */ |
372 | | void * |
373 | | bfd_realloc_or_free (void *ptr, bfd_size_type size) |
374 | 74.6k | { |
375 | 74.6k | void *ret; |
376 | | |
377 | | /* The behaviour of realloc(0) is implementation defined, but |
378 | | for this function we treat it is always freeing the memory. */ |
379 | 74.6k | if (size == 0) |
380 | 0 | { |
381 | 0 | free (ptr); |
382 | 0 | return NULL; |
383 | 0 | } |
384 | | |
385 | 74.6k | ret = bfd_realloc (ptr, size); |
386 | 74.6k | if (ret == NULL) |
387 | 0 | free (ptr); |
388 | | |
389 | 74.6k | return ret; |
390 | 74.6k | } |
391 | | |
392 | | /* |
393 | | INTERNAL_FUNCTION |
394 | | bfd_zmalloc |
395 | | |
396 | | SYNOPSIS |
397 | | void *bfd_zmalloc (bfd_size_type {*size*}); |
398 | | |
399 | | DESCRIPTION |
400 | | Returns a pointer to an allocated block of memory that is at least |
401 | | SIZE bytes long. If SIZE is 0 then it will be treated as if it were |
402 | | 1. If SIZE is too big then NULL will be returned. |
403 | | |
404 | | Returns NULL upon error and sets bfd_error. |
405 | | |
406 | | If NULL is not returned then the allocated block of memory will |
407 | | have been cleared. |
408 | | */ |
409 | | void * |
410 | | bfd_zmalloc (bfd_size_type size) |
411 | 3.18M | { |
412 | 3.18M | void *ptr = bfd_malloc (size); |
413 | | |
414 | 3.18M | if (ptr != NULL) |
415 | 3.18M | memset (ptr, 0, size ? (size_t) size : 1); |
416 | | |
417 | 3.18M | return ptr; |
418 | 3.18M | } |
419 | | |
420 | | /* |
421 | | FUNCTION |
422 | | bfd_alloc |
423 | | |
424 | | SYNOPSIS |
425 | | void *bfd_alloc (bfd *abfd, bfd_size_type wanted); |
426 | | |
427 | | DESCRIPTION |
428 | | Allocate a block of @var{wanted} bytes of memory attached to |
429 | | <<abfd>> and return a pointer to it. |
430 | | */ |
431 | | |
432 | | void * |
433 | | bfd_alloc (bfd *abfd, bfd_size_type size) |
434 | 909M | { |
435 | 909M | void *ret; |
436 | 909M | unsigned long ul_size = (unsigned long) size; |
437 | | |
438 | 909M | if (size != ul_size |
439 | | /* Note - although objalloc_alloc takes an unsigned long as its |
440 | | argument, internally the size is treated as a signed long. This can |
441 | | lead to problems where, for example, a request to allocate -1 bytes |
442 | | can result in just 1 byte being allocated, rather than |
443 | | ((unsigned long) -1) bytes. Also memory checkers will often |
444 | | complain about attempts to allocate a negative amount of memory. |
445 | | So to stop these problems we fail if the size is negative. */ |
446 | 909M | || ((signed long) ul_size) < 0) |
447 | 0 | { |
448 | 0 | bfd_set_error (bfd_error_no_memory); |
449 | 0 | return NULL; |
450 | 0 | } |
451 | | |
452 | 909M | ret = objalloc_alloc ((struct objalloc *) abfd->memory, ul_size); |
453 | 909M | if (ret == NULL) |
454 | 0 | bfd_set_error (bfd_error_no_memory); |
455 | 909M | else |
456 | 909M | abfd->alloc_size += size; |
457 | 909M | return ret; |
458 | 909M | } |
459 | | |
460 | | /* |
461 | | FUNCTION |
462 | | bfd_zalloc |
463 | | |
464 | | SYNOPSIS |
465 | | void *bfd_zalloc (bfd *abfd, bfd_size_type wanted); |
466 | | |
467 | | DESCRIPTION |
468 | | Allocate a block of @var{wanted} bytes of zeroed memory |
469 | | attached to <<abfd>> and return a pointer to it. |
470 | | */ |
471 | | |
472 | | void * |
473 | | bfd_zalloc (bfd *abfd, bfd_size_type size) |
474 | 255M | { |
475 | 255M | void *res; |
476 | | |
477 | 255M | res = bfd_alloc (abfd, size); |
478 | 255M | if (res) |
479 | 255M | memset (res, 0, (size_t) size); |
480 | 255M | return res; |
481 | 255M | } |
482 | | |
483 | | /* |
484 | | FUNCTION |
485 | | bfd_release |
486 | | |
487 | | SYNOPSIS |
488 | | void bfd_release (bfd *, void *); |
489 | | |
490 | | DESCRIPTION |
491 | | Free a block allocated for a BFD. |
492 | | Note: Also frees all more recently allocated blocks! |
493 | | */ |
494 | | |
495 | | void |
496 | | bfd_release (bfd *abfd, void *block) |
497 | 530M | { |
498 | 530M | objalloc_free_block ((struct objalloc *) abfd->memory, block); |
499 | 530M | } |
500 | | |
501 | | /* |
502 | | INTERNAL_FUNCTION |
503 | | bfd_write_bigendian_4byte_int |
504 | | |
505 | | SYNOPSIS |
506 | | bool bfd_write_bigendian_4byte_int (bfd *, unsigned int); |
507 | | |
508 | | DESCRIPTION |
509 | | Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big |
510 | | endian order regardless of what else is going on. This is useful in |
511 | | archives. |
512 | | |
513 | | */ |
514 | | bool |
515 | | bfd_write_bigendian_4byte_int (bfd *abfd, unsigned int i) |
516 | 37 | { |
517 | 37 | bfd_byte buffer[4]; |
518 | 37 | bfd_putb32 (i, buffer); |
519 | 37 | return bfd_write (buffer, 4, abfd) == 4; |
520 | 37 | } |
521 | | |
522 | | |
523 | | /** The do-it-yourself (byte) sex-change kit */ |
524 | | |
525 | | /* The middle letter e.g. get<b>short indicates Big or Little endian |
526 | | target machine. It doesn't matter what the byte order of the host |
527 | | machine is; these routines work for either. */ |
528 | | |
529 | | /* FIXME: Should these take a count argument? |
530 | | Answer (gnu@cygnus.com): No, but perhaps they should be inline |
531 | | functions in swap.h #ifdef __GNUC__. |
532 | | Gprof them later and find out. */ |
533 | | |
534 | | /* |
535 | | FUNCTION |
536 | | bfd_put_size |
537 | | FUNCTION |
538 | | bfd_get_size |
539 | | |
540 | | DESCRIPTION |
541 | | These macros as used for reading and writing raw data in |
542 | | sections; each access (except for bytes) is vectored through |
543 | | the target format of the BFD and mangled accordingly. The |
544 | | mangling performs any necessary endian translations and |
545 | | removes alignment restrictions. Note that types accepted and |
546 | | returned by these macros are identical so they can be swapped |
547 | | around in macros---for example, @file{libaout.h} defines <<GET_WORD>> |
548 | | to either <<bfd_get_32>> or <<bfd_get_64>>. |
549 | | |
550 | | In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a |
551 | | system without prototypes, the caller is responsible for making |
552 | | sure that is true, with a cast if necessary. We don't cast |
553 | | them in the macro definitions because that would prevent <<lint>> |
554 | | or <<gcc -Wall>> from detecting sins such as passing a pointer. |
555 | | To detect calling these with less than a <<bfd_vma>>, use |
556 | | <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s. |
557 | | |
558 | | . |
559 | | .{* Byte swapping macros for user section data. *} |
560 | | . |
561 | | .#define bfd_put_8(abfd, val, ptr) \ |
562 | | . ((void) (*((bfd_byte *) (ptr)) = (val) & 0xff)) |
563 | | .#define bfd_put_signed_8 \ |
564 | | . bfd_put_8 |
565 | | .#define bfd_get_8(abfd, ptr) \ |
566 | | . ((bfd_vma) *(const bfd_byte *) (ptr) & 0xff) |
567 | | .#define bfd_get_signed_8(abfd, ptr) \ |
568 | | . ((((bfd_signed_vma) *(const bfd_byte *) (ptr) & 0xff) ^ 0x80) - 0x80) |
569 | | . |
570 | | .#define bfd_put_16(abfd, val, ptr) \ |
571 | | . BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) |
572 | | .#define bfd_put_signed_16 \ |
573 | | . bfd_put_16 |
574 | | .#define bfd_get_16(abfd, ptr) \ |
575 | | . BFD_SEND (abfd, bfd_getx16, (ptr)) |
576 | | .#define bfd_get_signed_16(abfd, ptr) \ |
577 | | . BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) |
578 | | . |
579 | | .#define bfd_put_24(abfd, val, ptr) \ |
580 | | . do \ |
581 | | . if (bfd_big_endian (abfd)) \ |
582 | | . bfd_putb24 ((val), (ptr)); \ |
583 | | . else \ |
584 | | . bfd_putl24 ((val), (ptr)); \ |
585 | | . while (0) |
586 | | . |
587 | | .bfd_vma bfd_getb24 (const void *p); |
588 | | .bfd_vma bfd_getl24 (const void *p); |
589 | | . |
590 | | .#define bfd_get_24(abfd, ptr) \ |
591 | | . (bfd_big_endian (abfd) ? bfd_getb24 (ptr) : bfd_getl24 (ptr)) |
592 | | . |
593 | | .#define bfd_put_32(abfd, val, ptr) \ |
594 | | . BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) |
595 | | .#define bfd_put_signed_32 \ |
596 | | . bfd_put_32 |
597 | | .#define bfd_get_32(abfd, ptr) \ |
598 | | . BFD_SEND (abfd, bfd_getx32, (ptr)) |
599 | | .#define bfd_get_signed_32(abfd, ptr) \ |
600 | | . BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) |
601 | | . |
602 | | .#define bfd_put_64(abfd, val, ptr) \ |
603 | | . BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) |
604 | | .#define bfd_put_signed_64 \ |
605 | | . bfd_put_64 |
606 | | .#define bfd_get_64(abfd, ptr) \ |
607 | | . BFD_SEND (abfd, bfd_getx64, (ptr)) |
608 | | .#define bfd_get_signed_64(abfd, ptr) \ |
609 | | . BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) |
610 | | . |
611 | | .#define bfd_get(bits, abfd, ptr) \ |
612 | | . ((bits) == 8 ? bfd_get_8 (abfd, ptr) \ |
613 | | . : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ |
614 | | . : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ |
615 | | . : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ |
616 | | . : (abort (), (bfd_vma) - 1)) |
617 | | . |
618 | | .#define bfd_put(bits, abfd, val, ptr) \ |
619 | | . ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ |
620 | | . : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ |
621 | | . : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ |
622 | | . : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ |
623 | | . : (abort (), (void) 0)) |
624 | | . |
625 | | */ |
626 | | |
627 | | /* |
628 | | FUNCTION |
629 | | bfd_h_put_size |
630 | | bfd_h_get_size |
631 | | |
632 | | DESCRIPTION |
633 | | These macros have the same function as their <<bfd_get_x>> |
634 | | brethren, except that they are used for removing information |
635 | | for the header records of object files. Believe it or not, |
636 | | some object files keep their header records in big endian |
637 | | order and their data in little endian order. |
638 | | . |
639 | | .{* Byte swapping macros for file header data. *} |
640 | | . |
641 | | .#define bfd_h_put_8(abfd, val, ptr) \ |
642 | | . bfd_put_8 (abfd, val, ptr) |
643 | | .#define bfd_h_put_signed_8(abfd, val, ptr) \ |
644 | | . bfd_put_8 (abfd, val, ptr) |
645 | | .#define bfd_h_get_8(abfd, ptr) \ |
646 | | . bfd_get_8 (abfd, ptr) |
647 | | .#define bfd_h_get_signed_8(abfd, ptr) \ |
648 | | . bfd_get_signed_8 (abfd, ptr) |
649 | | . |
650 | | .#define bfd_h_put_16(abfd, val, ptr) \ |
651 | | . BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) |
652 | | .#define bfd_h_put_signed_16 \ |
653 | | . bfd_h_put_16 |
654 | | .#define bfd_h_get_16(abfd, ptr) \ |
655 | | . BFD_SEND (abfd, bfd_h_getx16, (ptr)) |
656 | | .#define bfd_h_get_signed_16(abfd, ptr) \ |
657 | | . BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) |
658 | | . |
659 | | .#define bfd_h_put_32(abfd, val, ptr) \ |
660 | | . BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) |
661 | | .#define bfd_h_put_signed_32 \ |
662 | | . bfd_h_put_32 |
663 | | .#define bfd_h_get_32(abfd, ptr) \ |
664 | | . BFD_SEND (abfd, bfd_h_getx32, (ptr)) |
665 | | .#define bfd_h_get_signed_32(abfd, ptr) \ |
666 | | . BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) |
667 | | . |
668 | | .#define bfd_h_put_64(abfd, val, ptr) \ |
669 | | . BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) |
670 | | .#define bfd_h_put_signed_64 \ |
671 | | . bfd_h_put_64 |
672 | | .#define bfd_h_get_64(abfd, ptr) \ |
673 | | . BFD_SEND (abfd, bfd_h_getx64, (ptr)) |
674 | | .#define bfd_h_get_signed_64(abfd, ptr) \ |
675 | | . BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) |
676 | | . |
677 | | .{* Aliases for the above, which should eventually go away. *} |
678 | | . |
679 | | .#define H_PUT_64 bfd_h_put_64 |
680 | | .#define H_PUT_32 bfd_h_put_32 |
681 | | .#define H_PUT_16 bfd_h_put_16 |
682 | | .#define H_PUT_8 bfd_h_put_8 |
683 | | .#define H_PUT_S64 bfd_h_put_signed_64 |
684 | | .#define H_PUT_S32 bfd_h_put_signed_32 |
685 | | .#define H_PUT_S16 bfd_h_put_signed_16 |
686 | | .#define H_PUT_S8 bfd_h_put_signed_8 |
687 | | .#define H_GET_64 bfd_h_get_64 |
688 | | .#define H_GET_32 bfd_h_get_32 |
689 | | .#define H_GET_16 bfd_h_get_16 |
690 | | .#define H_GET_8 bfd_h_get_8 |
691 | | .#define H_GET_S64 bfd_h_get_signed_64 |
692 | | .#define H_GET_S32 bfd_h_get_signed_32 |
693 | | .#define H_GET_S16 bfd_h_get_signed_16 |
694 | | .#define H_GET_S8 bfd_h_get_signed_8 |
695 | | . |
696 | | .*/ |
697 | | |
698 | | /* Sign extension to bfd_signed_vma. */ |
699 | 112k | #define COERCE16(x) (((bfd_vma) (x) ^ 0x8000) - 0x8000) |
700 | 44.0M | #define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000) |
701 | | #define COERCE64(x) \ |
702 | 62.7M | (((uint64_t) (x) ^ ((uint64_t) 1 << 63)) - ((uint64_t) 1 << 63)) |
703 | | |
704 | | /* |
705 | | FUNCTION |
706 | | Byte swapping routines. |
707 | | |
708 | | SYNOPSIS |
709 | | uint64_t bfd_getb64 (const void *); |
710 | | uint64_t bfd_getl64 (const void *); |
711 | | int64_t bfd_getb_signed_64 (const void *); |
712 | | int64_t bfd_getl_signed_64 (const void *); |
713 | | bfd_vma bfd_getb32 (const void *); |
714 | | bfd_vma bfd_getl32 (const void *); |
715 | | bfd_signed_vma bfd_getb_signed_32 (const void *); |
716 | | bfd_signed_vma bfd_getl_signed_32 (const void *); |
717 | | bfd_vma bfd_getb16 (const void *); |
718 | | bfd_vma bfd_getl16 (const void *); |
719 | | bfd_signed_vma bfd_getb_signed_16 (const void *); |
720 | | bfd_signed_vma bfd_getl_signed_16 (const void *); |
721 | | void bfd_putb64 (uint64_t, void *); |
722 | | void bfd_putl64 (uint64_t, void *); |
723 | | void bfd_putb32 (bfd_vma, void *); |
724 | | void bfd_putl32 (bfd_vma, void *); |
725 | | void bfd_putb24 (bfd_vma, void *); |
726 | | void bfd_putl24 (bfd_vma, void *); |
727 | | void bfd_putb16 (bfd_vma, void *); |
728 | | void bfd_putl16 (bfd_vma, void *); |
729 | | uint64_t bfd_get_bits (const void *, int, bool); |
730 | | void bfd_put_bits (uint64_t, void *, int, bool); |
731 | | */ |
732 | | |
733 | | bfd_vma |
734 | | bfd_getb16 (const void *p) |
735 | 230M | { |
736 | 230M | const bfd_byte *addr = (const bfd_byte *) p; |
737 | 230M | return (addr[0] << 8) | addr[1]; |
738 | 230M | } |
739 | | |
740 | | bfd_vma |
741 | | bfd_getl16 (const void *p) |
742 | 581M | { |
743 | 581M | const bfd_byte *addr = (const bfd_byte *) p; |
744 | 581M | return (addr[1] << 8) | addr[0]; |
745 | 581M | } |
746 | | |
747 | | bfd_signed_vma |
748 | | bfd_getb_signed_16 (const void *p) |
749 | 20 | { |
750 | 20 | const bfd_byte *addr = (const bfd_byte *) p; |
751 | 20 | return COERCE16 ((addr[0] << 8) | addr[1]); |
752 | 20 | } |
753 | | |
754 | | bfd_signed_vma |
755 | | bfd_getl_signed_16 (const void *p) |
756 | 112k | { |
757 | 112k | const bfd_byte *addr = (const bfd_byte *) p; |
758 | 112k | return COERCE16 ((addr[1] << 8) | addr[0]); |
759 | 112k | } |
760 | | |
761 | | void |
762 | | bfd_putb16 (bfd_vma data, void *p) |
763 | 23.1k | { |
764 | 23.1k | bfd_byte *addr = (bfd_byte *) p; |
765 | 23.1k | addr[0] = (data >> 8) & 0xff; |
766 | 23.1k | addr[1] = data & 0xff; |
767 | 23.1k | } |
768 | | |
769 | | void |
770 | | bfd_putl16 (bfd_vma data, void *p) |
771 | 152k | { |
772 | 152k | bfd_byte *addr = (bfd_byte *) p; |
773 | 152k | addr[0] = data & 0xff; |
774 | 152k | addr[1] = (data >> 8) & 0xff; |
775 | 152k | } |
776 | | |
777 | | void |
778 | | bfd_putb24 (bfd_vma data, void *p) |
779 | 0 | { |
780 | 0 | bfd_byte *addr = (bfd_byte *) p; |
781 | 0 | addr[0] = (data >> 16) & 0xff; |
782 | 0 | addr[1] = (data >> 8) & 0xff; |
783 | 0 | addr[2] = data & 0xff; |
784 | 0 | } |
785 | | |
786 | | void |
787 | | bfd_putl24 (bfd_vma data, void *p) |
788 | 4 | { |
789 | 4 | bfd_byte *addr = (bfd_byte *) p; |
790 | 4 | addr[0] = data & 0xff; |
791 | 4 | addr[1] = (data >> 8) & 0xff; |
792 | 4 | addr[2] = (data >> 16) & 0xff; |
793 | 4 | } |
794 | | |
795 | | bfd_vma |
796 | | bfd_getb24 (const void *p) |
797 | 0 | { |
798 | 0 | const bfd_byte *addr = (const bfd_byte *) p; |
799 | 0 | uint32_t v; |
800 | |
|
801 | 0 | v = (uint32_t) addr[0] << 16; |
802 | 0 | v |= (uint32_t) addr[1] << 8; |
803 | 0 | v |= (uint32_t) addr[2]; |
804 | 0 | return v; |
805 | 0 | } |
806 | | |
807 | | bfd_vma |
808 | | bfd_getl24 (const void *p) |
809 | 0 | { |
810 | 0 | const bfd_byte *addr = (const bfd_byte *) p; |
811 | 0 | uint32_t v; |
812 | |
|
813 | 0 | v = (uint32_t) addr[0]; |
814 | 0 | v |= (uint32_t) addr[1] << 8; |
815 | 0 | v |= (uint32_t) addr[2] << 16; |
816 | 0 | return v; |
817 | 0 | } |
818 | | |
819 | | bfd_vma |
820 | | bfd_getb32 (const void *p) |
821 | 537M | { |
822 | 537M | const bfd_byte *addr = (const bfd_byte *) p; |
823 | 537M | uint32_t v; |
824 | | |
825 | 537M | v = (uint32_t) addr[0] << 24; |
826 | 537M | v |= (uint32_t) addr[1] << 16; |
827 | 537M | v |= (uint32_t) addr[2] << 8; |
828 | 537M | v |= (uint32_t) addr[3]; |
829 | 537M | return v; |
830 | 537M | } |
831 | | |
832 | | bfd_vma |
833 | | bfd_getl32 (const void *p) |
834 | 1.08G | { |
835 | 1.08G | const bfd_byte *addr = (const bfd_byte *) p; |
836 | 1.08G | uint32_t v; |
837 | | |
838 | 1.08G | v = (uint32_t) addr[0]; |
839 | 1.08G | v |= (uint32_t) addr[1] << 8; |
840 | 1.08G | v |= (uint32_t) addr[2] << 16; |
841 | 1.08G | v |= (uint32_t) addr[3] << 24; |
842 | 1.08G | return v; |
843 | 1.08G | } |
844 | | |
845 | | bfd_signed_vma |
846 | | bfd_getb_signed_32 (const void *p) |
847 | 554k | { |
848 | 554k | const bfd_byte *addr = (const bfd_byte *) p; |
849 | 554k | uint32_t v; |
850 | | |
851 | 554k | v = (uint32_t) addr[0] << 24; |
852 | 554k | v |= (uint32_t) addr[1] << 16; |
853 | 554k | v |= (uint32_t) addr[2] << 8; |
854 | 554k | v |= (uint32_t) addr[3]; |
855 | 554k | return COERCE32 (v); |
856 | 554k | } |
857 | | |
858 | | bfd_signed_vma |
859 | | bfd_getl_signed_32 (const void *p) |
860 | 43.4M | { |
861 | 43.4M | const bfd_byte *addr = (const bfd_byte *) p; |
862 | 43.4M | uint32_t v; |
863 | | |
864 | 43.4M | v = (uint32_t) addr[0]; |
865 | 43.4M | v |= (uint32_t) addr[1] << 8; |
866 | 43.4M | v |= (uint32_t) addr[2] << 16; |
867 | 43.4M | v |= (uint32_t) addr[3] << 24; |
868 | 43.4M | return COERCE32 (v); |
869 | 43.4M | } |
870 | | |
871 | | uint64_t |
872 | | bfd_getb64 (const void *p) |
873 | 33.7M | { |
874 | 33.7M | const bfd_byte *addr = (const bfd_byte *) p; |
875 | 33.7M | uint64_t v; |
876 | | |
877 | 33.7M | v = addr[0]; v <<= 8; |
878 | 33.7M | v |= addr[1]; v <<= 8; |
879 | 33.7M | v |= addr[2]; v <<= 8; |
880 | 33.7M | v |= addr[3]; v <<= 8; |
881 | 33.7M | v |= addr[4]; v <<= 8; |
882 | 33.7M | v |= addr[5]; v <<= 8; |
883 | 33.7M | v |= addr[6]; v <<= 8; |
884 | 33.7M | v |= addr[7]; |
885 | | |
886 | 33.7M | return v; |
887 | 33.7M | } |
888 | | |
889 | | uint64_t |
890 | | bfd_getl64 (const void *p) |
891 | 231M | { |
892 | 231M | const bfd_byte *addr = (const bfd_byte *) p; |
893 | 231M | uint64_t v; |
894 | | |
895 | 231M | v = addr[7]; v <<= 8; |
896 | 231M | v |= addr[6]; v <<= 8; |
897 | 231M | v |= addr[5]; v <<= 8; |
898 | 231M | v |= addr[4]; v <<= 8; |
899 | 231M | v |= addr[3]; v <<= 8; |
900 | 231M | v |= addr[2]; v <<= 8; |
901 | 231M | v |= addr[1]; v <<= 8; |
902 | 231M | v |= addr[0]; |
903 | | |
904 | 231M | return v; |
905 | 231M | } |
906 | | |
907 | | int64_t |
908 | | bfd_getb_signed_64 (const void *p) |
909 | 127k | { |
910 | 127k | const bfd_byte *addr = (const bfd_byte *) p; |
911 | 127k | uint64_t v; |
912 | | |
913 | 127k | v = addr[0]; v <<= 8; |
914 | 127k | v |= addr[1]; v <<= 8; |
915 | 127k | v |= addr[2]; v <<= 8; |
916 | 127k | v |= addr[3]; v <<= 8; |
917 | 127k | v |= addr[4]; v <<= 8; |
918 | 127k | v |= addr[5]; v <<= 8; |
919 | 127k | v |= addr[6]; v <<= 8; |
920 | 127k | v |= addr[7]; |
921 | | |
922 | 127k | return COERCE64 (v); |
923 | 127k | } |
924 | | |
925 | | int64_t |
926 | | bfd_getl_signed_64 (const void *p) |
927 | 62.6M | { |
928 | 62.6M | const bfd_byte *addr = (const bfd_byte *) p; |
929 | 62.6M | uint64_t v; |
930 | | |
931 | 62.6M | v = addr[7]; v <<= 8; |
932 | 62.6M | v |= addr[6]; v <<= 8; |
933 | 62.6M | v |= addr[5]; v <<= 8; |
934 | 62.6M | v |= addr[4]; v <<= 8; |
935 | 62.6M | v |= addr[3]; v <<= 8; |
936 | 62.6M | v |= addr[2]; v <<= 8; |
937 | 62.6M | v |= addr[1]; v <<= 8; |
938 | 62.6M | v |= addr[0]; |
939 | | |
940 | 62.6M | return COERCE64 (v); |
941 | 62.6M | } |
942 | | |
943 | | void |
944 | | bfd_putb32 (bfd_vma data, void *p) |
945 | 3.39M | { |
946 | 3.39M | bfd_byte *addr = (bfd_byte *) p; |
947 | 3.39M | addr[0] = (data >> 24) & 0xff; |
948 | 3.39M | addr[1] = (data >> 16) & 0xff; |
949 | 3.39M | addr[2] = (data >> 8) & 0xff; |
950 | 3.39M | addr[3] = data & 0xff; |
951 | 3.39M | } |
952 | | |
953 | | void |
954 | | bfd_putl32 (bfd_vma data, void *p) |
955 | 252k | { |
956 | 252k | bfd_byte *addr = (bfd_byte *) p; |
957 | 252k | addr[0] = data & 0xff; |
958 | 252k | addr[1] = (data >> 8) & 0xff; |
959 | 252k | addr[2] = (data >> 16) & 0xff; |
960 | 252k | addr[3] = (data >> 24) & 0xff; |
961 | 252k | } |
962 | | |
963 | | void |
964 | | bfd_putb64 (uint64_t data, void *p) |
965 | 2.32k | { |
966 | 2.32k | bfd_byte *addr = (bfd_byte *) p; |
967 | 2.32k | addr[0] = (data >> (7*8)) & 0xff; |
968 | 2.32k | addr[1] = (data >> (6*8)) & 0xff; |
969 | 2.32k | addr[2] = (data >> (5*8)) & 0xff; |
970 | 2.32k | addr[3] = (data >> (4*8)) & 0xff; |
971 | 2.32k | addr[4] = (data >> (3*8)) & 0xff; |
972 | 2.32k | addr[5] = (data >> (2*8)) & 0xff; |
973 | 2.32k | addr[6] = (data >> (1*8)) & 0xff; |
974 | 2.32k | addr[7] = (data >> (0*8)) & 0xff; |
975 | 2.32k | } |
976 | | |
977 | | void |
978 | | bfd_putl64 (uint64_t data, void *p) |
979 | 415k | { |
980 | 415k | bfd_byte *addr = (bfd_byte *) p; |
981 | 415k | addr[7] = (data >> (7*8)) & 0xff; |
982 | 415k | addr[6] = (data >> (6*8)) & 0xff; |
983 | 415k | addr[5] = (data >> (5*8)) & 0xff; |
984 | 415k | addr[4] = (data >> (4*8)) & 0xff; |
985 | 415k | addr[3] = (data >> (3*8)) & 0xff; |
986 | 415k | addr[2] = (data >> (2*8)) & 0xff; |
987 | 415k | addr[1] = (data >> (1*8)) & 0xff; |
988 | 415k | addr[0] = (data >> (0*8)) & 0xff; |
989 | 415k | } |
990 | | |
991 | | void |
992 | | bfd_put_bits (uint64_t data, void *p, int bits, bool big_p) |
993 | 48.6k | { |
994 | 48.6k | bfd_byte *addr = (bfd_byte *) p; |
995 | 48.6k | int i; |
996 | 48.6k | int bytes; |
997 | | |
998 | 48.6k | if (bits % 8 != 0) |
999 | 0 | abort (); |
1000 | | |
1001 | 48.6k | bytes = bits / 8; |
1002 | 225k | for (i = 0; i < bytes; i++) |
1003 | 176k | { |
1004 | 176k | int addr_index = big_p ? bytes - i - 1 : i; |
1005 | | |
1006 | 176k | addr[addr_index] = data & 0xff; |
1007 | 176k | data >>= 8; |
1008 | 176k | } |
1009 | 48.6k | } |
1010 | | |
1011 | | uint64_t |
1012 | | bfd_get_bits (const void *p, int bits, bool big_p) |
1013 | 286M | { |
1014 | 286M | const bfd_byte *addr = (const bfd_byte *) p; |
1015 | 286M | uint64_t data; |
1016 | 286M | int i; |
1017 | 286M | int bytes; |
1018 | | |
1019 | 286M | if (bits % 8 != 0) |
1020 | 0 | abort (); |
1021 | | |
1022 | 286M | data = 0; |
1023 | 286M | bytes = bits / 8; |
1024 | 1.07G | for (i = 0; i < bytes; i++) |
1025 | 786M | { |
1026 | 786M | int addr_index = big_p ? i : bytes - i - 1; |
1027 | | |
1028 | 786M | data = (data << 8) | addr[addr_index]; |
1029 | 786M | } |
1030 | | |
1031 | 286M | return data; |
1032 | 286M | } |
1033 | | |
1034 | | /* Default implementation */ |
1035 | | |
1036 | | bool |
1037 | | _bfd_generic_get_section_contents (bfd *abfd, |
1038 | | sec_ptr section, |
1039 | | void *location, |
1040 | | file_ptr offset, |
1041 | | bfd_size_type count) |
1042 | 382k | { |
1043 | 382k | bfd_size_type sz; |
1044 | 382k | if (count == 0) |
1045 | 0 | return true; |
1046 | | |
1047 | 382k | if (section->compress_status != COMPRESS_SECTION_NONE) |
1048 | 0 | { |
1049 | 0 | _bfd_error_handler |
1050 | | /* xgettext:c-format */ |
1051 | 0 | (_("%pB: unable to get decompressed section %pA"), |
1052 | 0 | abfd, section); |
1053 | 0 | bfd_set_error (bfd_error_invalid_operation); |
1054 | 0 | return false; |
1055 | 0 | } |
1056 | | |
1057 | 382k | sz = bfd_get_section_limit_octets (abfd, section); |
1058 | 382k | if (offset + count < count |
1059 | 382k | || offset + count > sz |
1060 | 382k | || (abfd->my_archive != NULL |
1061 | 382k | && !bfd_is_thin_archive (abfd->my_archive) |
1062 | 382k | && ((ufile_ptr) section->filepos + offset + count |
1063 | 155k | > arelt_size (abfd)))) |
1064 | 18.0k | { |
1065 | 18.0k | bfd_set_error (bfd_error_invalid_operation); |
1066 | 18.0k | return false; |
1067 | 18.0k | } |
1068 | | |
1069 | 364k | if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 |
1070 | 364k | || bfd_read (location, count, abfd) != count) |
1071 | 10.0k | return false; |
1072 | | |
1073 | 354k | return true; |
1074 | 364k | } |
1075 | | |
1076 | | bool |
1077 | | _bfd_generic_get_section_contents_in_window |
1078 | | (bfd *abfd ATTRIBUTE_UNUSED, |
1079 | | sec_ptr section ATTRIBUTE_UNUSED, |
1080 | | bfd_window *w ATTRIBUTE_UNUSED, |
1081 | | file_ptr offset ATTRIBUTE_UNUSED, |
1082 | | bfd_size_type count ATTRIBUTE_UNUSED) |
1083 | 0 | { |
1084 | | #ifdef USE_MMAP |
1085 | | bfd_size_type sz; |
1086 | | |
1087 | | if (count == 0) |
1088 | | return true; |
1089 | | if (abfd->xvec->_bfd_get_section_contents |
1090 | | != _bfd_generic_get_section_contents) |
1091 | | { |
1092 | | /* We don't know what changes the bfd's get_section_contents |
1093 | | method may have to make. So punt trying to map the file |
1094 | | window, and let get_section_contents do its thing. */ |
1095 | | /* @@ FIXME : If the internal window has a refcount of 1 and was |
1096 | | allocated with malloc instead of mmap, just reuse it. */ |
1097 | | bfd_free_window (w); |
1098 | | w->i = bfd_zmalloc (sizeof (bfd_window_internal)); |
1099 | | if (w->i == NULL) |
1100 | | return false; |
1101 | | w->i->data = bfd_malloc (count); |
1102 | | if (w->i->data == NULL) |
1103 | | { |
1104 | | free (w->i); |
1105 | | w->i = NULL; |
1106 | | return false; |
1107 | | } |
1108 | | w->i->mapped = 0; |
1109 | | w->i->refcount = 1; |
1110 | | w->size = w->i->size = count; |
1111 | | w->data = w->i->data; |
1112 | | return bfd_get_section_contents (abfd, section, w->data, offset, count); |
1113 | | } |
1114 | | if (abfd->direction != write_direction && section->rawsize != 0) |
1115 | | sz = section->rawsize; |
1116 | | else |
1117 | | sz = section->size; |
1118 | | if (offset + count < count |
1119 | | || offset + count > sz |
1120 | | || (abfd->my_archive != NULL |
1121 | | && !bfd_is_thin_archive (abfd->my_archive) |
1122 | | && ((ufile_ptr) section->filepos + offset + count |
1123 | | > arelt_size (abfd))) |
1124 | | || ! bfd_get_file_window (abfd, section->filepos + offset, count, w, |
1125 | | true)) |
1126 | | return false; |
1127 | | return true; |
1128 | | #else |
1129 | 0 | abort (); |
1130 | 0 | #endif |
1131 | 0 | } |
1132 | | |
1133 | | /* This generic function can only be used in implementations where creating |
1134 | | NEW sections is disallowed. It is useful in patching existing sections |
1135 | | in read-write files, though. See other set_section_contents functions |
1136 | | to see why it doesn't work for new sections. */ |
1137 | | bool |
1138 | | _bfd_generic_set_section_contents (bfd *abfd, |
1139 | | sec_ptr section, |
1140 | | const void *location, |
1141 | | file_ptr offset, |
1142 | | bfd_size_type count) |
1143 | 1.87k | { |
1144 | 1.87k | if (count == 0) |
1145 | 0 | return true; |
1146 | | |
1147 | 1.87k | if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0 |
1148 | 1.87k | || bfd_write (location, count, abfd) != count) |
1149 | 0 | return false; |
1150 | | |
1151 | 1.87k | return true; |
1152 | 1.87k | } |
1153 | | |
1154 | | /* |
1155 | | INTERNAL_FUNCTION |
1156 | | bfd_log2 |
1157 | | |
1158 | | SYNOPSIS |
1159 | | unsigned int bfd_log2 (bfd_vma x); |
1160 | | |
1161 | | DESCRIPTION |
1162 | | Return the log base 2 of the value supplied, rounded up. E.g., an |
1163 | | @var{x} of 1025 returns 11. A @var{x} of 0 returns 0. |
1164 | | */ |
1165 | | |
1166 | | unsigned int |
1167 | | bfd_log2 (bfd_vma x) |
1168 | 3.52M | { |
1169 | 3.52M | unsigned int result = 0; |
1170 | | |
1171 | 3.52M | if (x <= 1) |
1172 | 1.24M | return result; |
1173 | 2.27M | --x; |
1174 | 2.27M | do |
1175 | 42.6M | ++result; |
1176 | 42.6M | while ((x >>= 1) != 0); |
1177 | 2.27M | return result; |
1178 | 3.52M | } |
1179 | | |
1180 | | bool |
1181 | | bfd_generic_is_local_label_name (bfd *abfd, const char *name) |
1182 | 0 | { |
1183 | 0 | char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.'; |
1184 | |
|
1185 | 0 | return name[0] == locals_prefix; |
1186 | 0 | } |
1187 | | |
1188 | | /* Helper function for reading uleb128 encoded data. */ |
1189 | | |
1190 | | bfd_vma |
1191 | | _bfd_read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED, |
1192 | | bfd_byte *buf, |
1193 | | unsigned int *bytes_read_ptr) |
1194 | 0 | { |
1195 | 0 | bfd_vma result; |
1196 | 0 | unsigned int num_read; |
1197 | 0 | unsigned int shift; |
1198 | 0 | bfd_byte byte; |
1199 | |
|
1200 | 0 | result = 0; |
1201 | 0 | shift = 0; |
1202 | 0 | num_read = 0; |
1203 | 0 | do |
1204 | 0 | { |
1205 | 0 | byte = bfd_get_8 (abfd, buf); |
1206 | 0 | buf++; |
1207 | 0 | num_read++; |
1208 | 0 | if (shift < 8 * sizeof (result)) |
1209 | 0 | { |
1210 | 0 | result |= (((bfd_vma) byte & 0x7f) << shift); |
1211 | 0 | shift += 7; |
1212 | 0 | } |
1213 | 0 | } |
1214 | 0 | while (byte & 0x80); |
1215 | 0 | *bytes_read_ptr = num_read; |
1216 | 0 | return result; |
1217 | 0 | } |
1218 | | |
1219 | | /* Read in a LEB128 encoded value from ABFD starting at *PTR. |
1220 | | If SIGN is true, return a signed LEB128 value. |
1221 | | *PTR is incremented by the number of bytes read. |
1222 | | No bytes will be read at address END or beyond. */ |
1223 | | |
1224 | | bfd_vma |
1225 | | _bfd_safe_read_leb128 (bfd *abfd ATTRIBUTE_UNUSED, |
1226 | | bfd_byte **ptr, |
1227 | | bool sign, |
1228 | | const bfd_byte * const end) |
1229 | 3.49M | { |
1230 | 3.49M | bfd_vma result = 0; |
1231 | 3.49M | unsigned int shift = 0; |
1232 | 3.49M | bfd_byte byte = 0; |
1233 | 3.49M | bfd_byte *data = *ptr; |
1234 | | |
1235 | 4.20M | while (data < end) |
1236 | 4.20M | { |
1237 | 4.20M | byte = bfd_get_8 (abfd, data); |
1238 | 4.20M | data++; |
1239 | 4.20M | if (shift < 8 * sizeof (result)) |
1240 | 4.14M | { |
1241 | 4.14M | result |= ((bfd_vma) (byte & 0x7f)) << shift; |
1242 | 4.14M | shift += 7; |
1243 | 4.14M | } |
1244 | 4.20M | if ((byte & 0x80) == 0) |
1245 | 3.48M | break; |
1246 | 4.20M | } |
1247 | | |
1248 | 3.49M | *ptr = data; |
1249 | | |
1250 | 3.49M | if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) |
1251 | 172k | result |= -((bfd_vma) 1 << shift); |
1252 | | |
1253 | 3.49M | return result; |
1254 | 3.49M | } |
1255 | | |
1256 | | /* Helper function for reading sleb128 encoded data. */ |
1257 | | |
1258 | | bfd_signed_vma |
1259 | | _bfd_read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED, |
1260 | | bfd_byte *buf, |
1261 | | unsigned int *bytes_read_ptr) |
1262 | 0 | { |
1263 | 0 | bfd_vma result; |
1264 | 0 | unsigned int shift; |
1265 | 0 | unsigned int num_read; |
1266 | 0 | bfd_byte byte; |
1267 | |
|
1268 | 0 | result = 0; |
1269 | 0 | shift = 0; |
1270 | 0 | num_read = 0; |
1271 | 0 | do |
1272 | 0 | { |
1273 | 0 | byte = bfd_get_8 (abfd, buf); |
1274 | 0 | buf ++; |
1275 | 0 | num_read ++; |
1276 | 0 | if (shift < 8 * sizeof (result)) |
1277 | 0 | { |
1278 | 0 | result |= (((bfd_vma) byte & 0x7f) << shift); |
1279 | 0 | shift += 7; |
1280 | 0 | } |
1281 | 0 | } |
1282 | 0 | while (byte & 0x80); |
1283 | 0 | if (shift < 8 * sizeof (result) && (byte & 0x40)) |
1284 | 0 | result |= (((bfd_vma) -1) << shift); |
1285 | 0 | *bytes_read_ptr = num_read; |
1286 | 0 | return result; |
1287 | 0 | } |
1288 | | |
1289 | | /* Write VAL in uleb128 format to P. |
1290 | | END indicates the last byte of allocated space for the uleb128 value to fit |
1291 | | in. |
1292 | | Return a pointer to the byte following the last byte that was written, or |
1293 | | NULL if the uleb128 value does not fit in the allocated space between P and |
1294 | | END. */ |
1295 | | bfd_byte * |
1296 | | _bfd_write_unsigned_leb128 (bfd_byte *p, bfd_byte *end, bfd_vma val) |
1297 | 0 | { |
1298 | 0 | bfd_byte c; |
1299 | 0 | do |
1300 | 0 | { |
1301 | 0 | if (p > end) |
1302 | 0 | return NULL; |
1303 | 0 | c = val & 0x7f; |
1304 | 0 | val >>= 7; |
1305 | 0 | if (val) |
1306 | 0 | c |= 0x80; |
1307 | 0 | *(p++) = c; |
1308 | 0 | } |
1309 | 0 | while (val); |
1310 | 0 | return p; |
1311 | 0 | } |
1312 | | |
1313 | | bool |
1314 | | _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, |
1315 | | asection *isec ATTRIBUTE_UNUSED, |
1316 | | bfd *obfd ATTRIBUTE_UNUSED, |
1317 | | asection *osec ATTRIBUTE_UNUSED, |
1318 | | struct bfd_link_info *link_info ATTRIBUTE_UNUSED) |
1319 | 0 | { |
1320 | 0 | return true; |
1321 | 0 | } |