1 /* $MirOS: src/gnu/usr.bin/binutils/bfd/libbfd.c,v 1.5 2005/07/07 16:22:42 tg Exp $ */
2
3 /* Assorted BFD support routines, only used internally.
4 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
5 2000, 2001, 2002, 2003, 2004, 2005
6 Free Software Foundation, Inc.
7 Written by Cygnus Support.
8
9 This file is part of BFD, the Binary File Descriptor library.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24
25 #include "bfd.h"
26 #include "sysdep.h"
27 #include "libbfd.h"
28
29 #ifndef HAVE_GETPAGESIZE
30 #define getpagesize() 2048
31 #endif
32
33 /*
34 SECTION
35 Internal functions
36
37 DESCRIPTION
38 These routines are used within BFD.
39 They are not intended for export, but are documented here for
40 completeness.
41 */
42
43 /* A routine which is used in target vectors for unsupported
44 operations. */
45
46 bfd_boolean
bfd_false(bfd * ignore ATTRIBUTE_UNUSED)47 bfd_false (bfd *ignore ATTRIBUTE_UNUSED)
48 {
49 bfd_set_error (bfd_error_invalid_operation);
50 return FALSE;
51 }
52
53 /* A routine which is used in target vectors for supported operations
54 which do not actually do anything. */
55
56 bfd_boolean
bfd_true(bfd * ignore ATTRIBUTE_UNUSED)57 bfd_true (bfd *ignore ATTRIBUTE_UNUSED)
58 {
59 return TRUE;
60 }
61
62 /* A routine which is used in target vectors for unsupported
63 operations which return a pointer value. */
64
65 void *
bfd_nullvoidptr(bfd * ignore ATTRIBUTE_UNUSED)66 bfd_nullvoidptr (bfd *ignore ATTRIBUTE_UNUSED)
67 {
68 bfd_set_error (bfd_error_invalid_operation);
69 return NULL;
70 }
71
72 int
bfd_0(bfd * ignore ATTRIBUTE_UNUSED)73 bfd_0 (bfd *ignore ATTRIBUTE_UNUSED)
74 {
75 return 0;
76 }
77
78 unsigned int
bfd_0u(bfd * ignore ATTRIBUTE_UNUSED)79 bfd_0u (bfd *ignore ATTRIBUTE_UNUSED)
80 {
81 return 0;
82 }
83
84 long
bfd_0l(bfd * ignore ATTRIBUTE_UNUSED)85 bfd_0l (bfd *ignore ATTRIBUTE_UNUSED)
86 {
87 return 0;
88 }
89
90 /* A routine which is used in target vectors for unsupported
91 operations which return -1 on error. */
92
93 long
_bfd_n1(bfd * ignore_abfd ATTRIBUTE_UNUSED)94 _bfd_n1 (bfd *ignore_abfd ATTRIBUTE_UNUSED)
95 {
96 bfd_set_error (bfd_error_invalid_operation);
97 return -1;
98 }
99
100 void
bfd_void(bfd * ignore ATTRIBUTE_UNUSED)101 bfd_void (bfd *ignore ATTRIBUTE_UNUSED)
102 {
103 }
104
105 bfd_boolean
_bfd_nocore_core_file_matches_executable_p(bfd * ignore_core_bfd ATTRIBUTE_UNUSED,bfd * ignore_exec_bfd ATTRIBUTE_UNUSED)106 _bfd_nocore_core_file_matches_executable_p
107 (bfd *ignore_core_bfd ATTRIBUTE_UNUSED,
108 bfd *ignore_exec_bfd ATTRIBUTE_UNUSED)
109 {
110 bfd_set_error (bfd_error_invalid_operation);
111 return FALSE;
112 }
113
114 /* Routine to handle core_file_failing_command entry point for targets
115 without core file support. */
116
117 char *
_bfd_nocore_core_file_failing_command(bfd * ignore_abfd ATTRIBUTE_UNUSED)118 _bfd_nocore_core_file_failing_command (bfd *ignore_abfd ATTRIBUTE_UNUSED)
119 {
120 bfd_set_error (bfd_error_invalid_operation);
121 return NULL;
122 }
123
124 /* Routine to handle core_file_failing_signal entry point for targets
125 without core file support. */
126
127 int
_bfd_nocore_core_file_failing_signal(bfd * ignore_abfd ATTRIBUTE_UNUSED)128 _bfd_nocore_core_file_failing_signal (bfd *ignore_abfd ATTRIBUTE_UNUSED)
129 {
130 bfd_set_error (bfd_error_invalid_operation);
131 return 0;
132 }
133
134 const bfd_target *
_bfd_dummy_target(bfd * ignore_abfd ATTRIBUTE_UNUSED)135 _bfd_dummy_target (bfd *ignore_abfd ATTRIBUTE_UNUSED)
136 {
137 bfd_set_error (bfd_error_wrong_format);
138 return 0;
139 }
140
141 /* Allocate memory using malloc. */
142
143 void *
bfd_malloc(bfd_size_type size)144 bfd_malloc (bfd_size_type size)
145 {
146 void *ptr;
147
148 if (size != (size_t) size)
149 {
150 bfd_set_error (bfd_error_no_memory);
151 return NULL;
152 }
153
154 ptr = malloc ((size_t) size);
155 if (ptr == NULL && (size_t) size != 0)
156 bfd_set_error (bfd_error_no_memory);
157
158 return ptr;
159 }
160
161 /* Allocate memory using malloc, nmemb * size with overflow checking. */
162
163 void *
bfd_malloc2(bfd_size_type nmemb,bfd_size_type size)164 bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
165 {
166 void *ptr;
167
168 if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
169 && size != 0
170 && nmemb > ~(bfd_size_type) 0 / size)
171 {
172 bfd_set_error (bfd_error_no_memory);
173 return NULL;
174 }
175
176 size *= nmemb;
177
178 if (size != (size_t) size)
179 {
180 bfd_set_error (bfd_error_no_memory);
181 return NULL;
182 }
183
184 ptr = malloc ((size_t) size);
185 if (ptr == NULL && (size_t) size != 0)
186 bfd_set_error (bfd_error_no_memory);
187
188 return ptr;
189 }
190
191 /* Reallocate memory using realloc. */
192
193 void *
bfd_realloc(void * ptr,bfd_size_type size)194 bfd_realloc (void *ptr, bfd_size_type size)
195 {
196 void *ret;
197
198 if (size != (size_t) size)
199 {
200 bfd_set_error (bfd_error_no_memory);
201 return NULL;
202 }
203
204 if (ptr == NULL)
205 ret = malloc ((size_t) size);
206 else
207 ret = realloc (ptr, (size_t) size);
208
209 if (ret == NULL && (size_t) size != 0)
210 bfd_set_error (bfd_error_no_memory);
211
212 return ret;
213 }
214
215 /* Reallocate memory using realloc, nmemb * size with overflow checking. */
216
217 void *
bfd_realloc2(void * ptr,bfd_size_type nmemb,bfd_size_type size)218 bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size)
219 {
220 void *ret;
221
222 if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
223 && size != 0
224 && nmemb > ~(bfd_size_type) 0 / size)
225 {
226 bfd_set_error (bfd_error_no_memory);
227 return NULL;
228 }
229
230 size *= nmemb;
231
232 if (size != (size_t) size)
233 {
234 bfd_set_error (bfd_error_no_memory);
235 return NULL;
236 }
237
238 if (ptr == NULL)
239 ret = malloc ((size_t) size);
240 else
241 ret = realloc (ptr, (size_t) size);
242
243 if (ret == NULL && (size_t) size != 0)
244 bfd_set_error (bfd_error_no_memory);
245
246 return ret;
247 }
248
249 /* Allocate memory using malloc and clear it. */
250
251 void *
bfd_zmalloc(bfd_size_type size)252 bfd_zmalloc (bfd_size_type size)
253 {
254 void *ptr;
255
256 if (size != (size_t) size)
257 {
258 bfd_set_error (bfd_error_no_memory);
259 return NULL;
260 }
261
262 ptr = malloc ((size_t) size);
263
264 if ((size_t) size != 0)
265 {
266 if (ptr == NULL)
267 bfd_set_error (bfd_error_no_memory);
268 else
269 memset (ptr, 0, (size_t) size);
270 }
271
272 return ptr;
273 }
274
275 /* Allocate memory using malloc (nmemb * size) with overflow checking
276 and clear it. */
277
278 void *
bfd_zmalloc2(bfd_size_type nmemb,bfd_size_type size)279 bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
280 {
281 void *ptr;
282
283 if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
284 && size != 0
285 && nmemb > ~(bfd_size_type) 0 / size)
286 {
287 bfd_set_error (bfd_error_no_memory);
288 return NULL;
289 }
290
291 size *= nmemb;
292
293 if (size != (size_t) size)
294 {
295 bfd_set_error (bfd_error_no_memory);
296 return NULL;
297 }
298
299 ptr = malloc ((size_t) size);
300
301 if ((size_t) size != 0)
302 {
303 if (ptr == NULL)
304 bfd_set_error (bfd_error_no_memory);
305 else
306 memset (ptr, 0, (size_t) size);
307 }
308
309 return ptr;
310 }
311
312 /*
313 INTERNAL_FUNCTION
314 bfd_write_bigendian_4byte_int
315
316 SYNOPSIS
317 bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
318
319 DESCRIPTION
320 Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
321 endian order regardless of what else is going on. This is useful in
322 archives.
323
324 */
325 bfd_boolean
bfd_write_bigendian_4byte_int(bfd * abfd,unsigned int i)326 bfd_write_bigendian_4byte_int (bfd *abfd, unsigned int i)
327 {
328 bfd_byte buffer[4];
329 bfd_putb32 ((bfd_vma) i, buffer);
330 return bfd_bwrite (buffer, (bfd_size_type) 4, abfd) == 4;
331 }
332
333
334 /** The do-it-yourself (byte) sex-change kit */
335
336 /* The middle letter e.g. get<b>short indicates Big or Little endian
337 target machine. It doesn't matter what the byte order of the host
338 machine is; these routines work for either. */
339
340 /* FIXME: Should these take a count argument?
341 Answer (gnu@cygnus.com): No, but perhaps they should be inline
342 functions in swap.h #ifdef __GNUC__.
343 Gprof them later and find out. */
344
345 /*
346 FUNCTION
347 bfd_put_size
348 FUNCTION
349 bfd_get_size
350
351 DESCRIPTION
352 These macros as used for reading and writing raw data in
353 sections; each access (except for bytes) is vectored through
354 the target format of the BFD and mangled accordingly. The
355 mangling performs any necessary endian translations and
356 removes alignment restrictions. Note that types accepted and
357 returned by these macros are identical so they can be swapped
358 around in macros---for example, @file{libaout.h} defines <<GET_WORD>>
359 to either <<bfd_get_32>> or <<bfd_get_64>>.
360
361 In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a
362 system without prototypes, the caller is responsible for making
363 sure that is true, with a cast if necessary. We don't cast
364 them in the macro definitions because that would prevent <<lint>>
365 or <<gcc -Wall>> from detecting sins such as passing a pointer.
366 To detect calling these with less than a <<bfd_vma>>, use
367 <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s.
368
369 .
370 .{* Byte swapping macros for user section data. *}
371 .
372 .#define bfd_put_8(abfd, val, ptr) \
373 . ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
374 .#define bfd_put_signed_8 \
375 . bfd_put_8
376 .#define bfd_get_8(abfd, ptr) \
377 . (*(unsigned char *) (ptr) & 0xff)
378 .#define bfd_get_signed_8(abfd, ptr) \
379 . (((*(unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80)
380 .
381 .#define bfd_put_16(abfd, val, ptr) \
382 . BFD_SEND (abfd, bfd_putx16, ((val),(ptr)))
383 .#define bfd_put_signed_16 \
384 . bfd_put_16
385 .#define bfd_get_16(abfd, ptr) \
386 . BFD_SEND (abfd, bfd_getx16, (ptr))
387 .#define bfd_get_signed_16(abfd, ptr) \
388 . BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
389 .
390 .#define bfd_put_32(abfd, val, ptr) \
391 . BFD_SEND (abfd, bfd_putx32, ((val),(ptr)))
392 .#define bfd_put_signed_32 \
393 . bfd_put_32
394 .#define bfd_get_32(abfd, ptr) \
395 . BFD_SEND (abfd, bfd_getx32, (ptr))
396 .#define bfd_get_signed_32(abfd, ptr) \
397 . BFD_SEND (abfd, bfd_getx_signed_32, (ptr))
398 .
399 .#define bfd_put_64(abfd, val, ptr) \
400 . BFD_SEND (abfd, bfd_putx64, ((val), (ptr)))
401 .#define bfd_put_signed_64 \
402 . bfd_put_64
403 .#define bfd_get_64(abfd, ptr) \
404 . BFD_SEND (abfd, bfd_getx64, (ptr))
405 .#define bfd_get_signed_64(abfd, ptr) \
406 . BFD_SEND (abfd, bfd_getx_signed_64, (ptr))
407 .
408 .#define bfd_get(bits, abfd, ptr) \
409 . ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \
410 . : (bits) == 16 ? bfd_get_16 (abfd, ptr) \
411 . : (bits) == 32 ? bfd_get_32 (abfd, ptr) \
412 . : (bits) == 64 ? bfd_get_64 (abfd, ptr) \
413 . : (abort (), (bfd_vma) - 1))
414 .
415 .#define bfd_put(bits, abfd, val, ptr) \
416 . ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \
417 . : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \
418 . : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \
419 . : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \
420 . : (abort (), (void) 0))
421 .
422 */
423
424 /*
425 FUNCTION
426 bfd_h_put_size
427 bfd_h_get_size
428
429 DESCRIPTION
430 These macros have the same function as their <<bfd_get_x>>
431 brethren, except that they are used for removing information
432 for the header records of object files. Believe it or not,
433 some object files keep their header records in big endian
434 order and their data in little endian order.
435 .
436 .{* Byte swapping macros for file header data. *}
437 .
438 .#define bfd_h_put_8(abfd, val, ptr) \
439 . bfd_put_8 (abfd, val, ptr)
440 .#define bfd_h_put_signed_8(abfd, val, ptr) \
441 . bfd_put_8 (abfd, val, ptr)
442 .#define bfd_h_get_8(abfd, ptr) \
443 . bfd_get_8 (abfd, ptr)
444 .#define bfd_h_get_signed_8(abfd, ptr) \
445 . bfd_get_signed_8 (abfd, ptr)
446 .
447 .#define bfd_h_put_16(abfd, val, ptr) \
448 . BFD_SEND (abfd, bfd_h_putx16, (val, ptr))
449 .#define bfd_h_put_signed_16 \
450 . bfd_h_put_16
451 .#define bfd_h_get_16(abfd, ptr) \
452 . BFD_SEND (abfd, bfd_h_getx16, (ptr))
453 .#define bfd_h_get_signed_16(abfd, ptr) \
454 . BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr))
455 .
456 .#define bfd_h_put_32(abfd, val, ptr) \
457 . BFD_SEND (abfd, bfd_h_putx32, (val, ptr))
458 .#define bfd_h_put_signed_32 \
459 . bfd_h_put_32
460 .#define bfd_h_get_32(abfd, ptr) \
461 . BFD_SEND (abfd, bfd_h_getx32, (ptr))
462 .#define bfd_h_get_signed_32(abfd, ptr) \
463 . BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr))
464 .
465 .#define bfd_h_put_64(abfd, val, ptr) \
466 . BFD_SEND (abfd, bfd_h_putx64, (val, ptr))
467 .#define bfd_h_put_signed_64 \
468 . bfd_h_put_64
469 .#define bfd_h_get_64(abfd, ptr) \
470 . BFD_SEND (abfd, bfd_h_getx64, (ptr))
471 .#define bfd_h_get_signed_64(abfd, ptr) \
472 . BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr))
473 .
474 .{* Aliases for the above, which should eventually go away. *}
475 .
476 .#define H_PUT_64 bfd_h_put_64
477 .#define H_PUT_32 bfd_h_put_32
478 .#define H_PUT_16 bfd_h_put_16
479 .#define H_PUT_8 bfd_h_put_8
480 .#define H_PUT_S64 bfd_h_put_signed_64
481 .#define H_PUT_S32 bfd_h_put_signed_32
482 .#define H_PUT_S16 bfd_h_put_signed_16
483 .#define H_PUT_S8 bfd_h_put_signed_8
484 .#define H_GET_64 bfd_h_get_64
485 .#define H_GET_32 bfd_h_get_32
486 .#define H_GET_16 bfd_h_get_16
487 .#define H_GET_8 bfd_h_get_8
488 .#define H_GET_S64 bfd_h_get_signed_64
489 .#define H_GET_S32 bfd_h_get_signed_32
490 .#define H_GET_S16 bfd_h_get_signed_16
491 .#define H_GET_S8 bfd_h_get_signed_8
492 .
493 .*/
494
495 /* Sign extension to bfd_signed_vma. */
496 #define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
497 #define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
498 #define EIGHT_GAZILLION ((bfd_int64_t) 1 << 63)
499 #define COERCE64(x) \
500 (((bfd_int64_t) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
501
502 bfd_vma
bfd_getb16(const void * p)503 bfd_getb16 (const void *p)
504 {
505 const bfd_byte *addr = p;
506 return (addr[0] << 8) | addr[1];
507 }
508
509 bfd_vma
bfd_getl16(const void * p)510 bfd_getl16 (const void *p)
511 {
512 const bfd_byte *addr = p;
513 return (addr[1] << 8) | addr[0];
514 }
515
516 bfd_signed_vma
bfd_getb_signed_16(const void * p)517 bfd_getb_signed_16 (const void *p)
518 {
519 const bfd_byte *addr = p;
520 return COERCE16 ((addr[0] << 8) | addr[1]);
521 }
522
523 bfd_signed_vma
bfd_getl_signed_16(const void * p)524 bfd_getl_signed_16 (const void *p)
525 {
526 const bfd_byte *addr = p;
527 return COERCE16 ((addr[1] << 8) | addr[0]);
528 }
529
530 void
bfd_putb16(bfd_vma data,void * p)531 bfd_putb16 (bfd_vma data, void *p)
532 {
533 bfd_byte *addr = p;
534 addr[0] = (data >> 8) & 0xff;
535 addr[1] = data & 0xff;
536 }
537
538 void
bfd_putl16(bfd_vma data,void * p)539 bfd_putl16 (bfd_vma data, void *p)
540 {
541 bfd_byte *addr = p;
542 addr[0] = data & 0xff;
543 addr[1] = (data >> 8) & 0xff;
544 }
545
546 bfd_vma
bfd_getb32(const void * p)547 bfd_getb32 (const void *p)
548 {
549 const bfd_byte *addr = p;
550 unsigned long v;
551
552 v = (unsigned long) addr[0] << 24;
553 v |= (unsigned long) addr[1] << 16;
554 v |= (unsigned long) addr[2] << 8;
555 v |= (unsigned long) addr[3];
556 return v;
557 }
558
559 bfd_vma
bfd_getl32(const void * p)560 bfd_getl32 (const void *p)
561 {
562 const bfd_byte *addr = p;
563 unsigned long v;
564
565 v = (unsigned long) addr[0];
566 v |= (unsigned long) addr[1] << 8;
567 v |= (unsigned long) addr[2] << 16;
568 v |= (unsigned long) addr[3] << 24;
569 return v;
570 }
571
572 bfd_signed_vma
bfd_getb_signed_32(const void * p)573 bfd_getb_signed_32 (const void *p)
574 {
575 const bfd_byte *addr = p;
576 unsigned long v;
577
578 v = (unsigned long) addr[0] << 24;
579 v |= (unsigned long) addr[1] << 16;
580 v |= (unsigned long) addr[2] << 8;
581 v |= (unsigned long) addr[3];
582 return COERCE32 (v);
583 }
584
585 bfd_signed_vma
bfd_getl_signed_32(const void * p)586 bfd_getl_signed_32 (const void *p)
587 {
588 const bfd_byte *addr = p;
589 unsigned long v;
590
591 v = (unsigned long) addr[0];
592 v |= (unsigned long) addr[1] << 8;
593 v |= (unsigned long) addr[2] << 16;
594 v |= (unsigned long) addr[3] << 24;
595 return COERCE32 (v);
596 }
597
598 bfd_uint64_t
bfd_getb64(const void * p ATTRIBUTE_UNUSED)599 bfd_getb64 (const void *p ATTRIBUTE_UNUSED)
600 {
601 #ifdef BFD_HOST_64_BIT
602 const bfd_byte *addr = p;
603 bfd_uint64_t v;
604
605 v = addr[0]; v <<= 8;
606 v |= addr[1]; v <<= 8;
607 v |= addr[2]; v <<= 8;
608 v |= addr[3]; v <<= 8;
609 v |= addr[4]; v <<= 8;
610 v |= addr[5]; v <<= 8;
611 v |= addr[6]; v <<= 8;
612 v |= addr[7];
613
614 return v;
615 #else
616 BFD_FAIL();
617 return 0;
618 #endif
619 }
620
621 bfd_uint64_t
bfd_getl64(const void * p ATTRIBUTE_UNUSED)622 bfd_getl64 (const void *p ATTRIBUTE_UNUSED)
623 {
624 #ifdef BFD_HOST_64_BIT
625 const bfd_byte *addr = p;
626 bfd_uint64_t v;
627
628 v = addr[7]; v <<= 8;
629 v |= addr[6]; v <<= 8;
630 v |= addr[5]; v <<= 8;
631 v |= addr[4]; v <<= 8;
632 v |= addr[3]; v <<= 8;
633 v |= addr[2]; v <<= 8;
634 v |= addr[1]; v <<= 8;
635 v |= addr[0];
636
637 return v;
638 #else
639 BFD_FAIL();
640 return 0;
641 #endif
642
643 }
644
645 bfd_int64_t
bfd_getb_signed_64(const void * p ATTRIBUTE_UNUSED)646 bfd_getb_signed_64 (const void *p ATTRIBUTE_UNUSED)
647 {
648 #ifdef BFD_HOST_64_BIT
649 const bfd_byte *addr = p;
650 bfd_uint64_t v;
651
652 v = addr[0]; v <<= 8;
653 v |= addr[1]; v <<= 8;
654 v |= addr[2]; v <<= 8;
655 v |= addr[3]; v <<= 8;
656 v |= addr[4]; v <<= 8;
657 v |= addr[5]; v <<= 8;
658 v |= addr[6]; v <<= 8;
659 v |= addr[7];
660
661 return COERCE64 (v);
662 #else
663 BFD_FAIL();
664 return 0;
665 #endif
666 }
667
668 bfd_int64_t
bfd_getl_signed_64(const void * p ATTRIBUTE_UNUSED)669 bfd_getl_signed_64 (const void *p ATTRIBUTE_UNUSED)
670 {
671 #ifdef BFD_HOST_64_BIT
672 const bfd_byte *addr = p;
673 bfd_uint64_t v;
674
675 v = addr[7]; v <<= 8;
676 v |= addr[6]; v <<= 8;
677 v |= addr[5]; v <<= 8;
678 v |= addr[4]; v <<= 8;
679 v |= addr[3]; v <<= 8;
680 v |= addr[2]; v <<= 8;
681 v |= addr[1]; v <<= 8;
682 v |= addr[0];
683
684 return COERCE64 (v);
685 #else
686 BFD_FAIL();
687 return 0;
688 #endif
689 }
690
691 void
bfd_putb32(bfd_vma data,void * p)692 bfd_putb32 (bfd_vma data, void *p)
693 {
694 bfd_byte *addr = p;
695 addr[0] = (data >> 24) & 0xff;
696 addr[1] = (data >> 16) & 0xff;
697 addr[2] = (data >> 8) & 0xff;
698 addr[3] = data & 0xff;
699 }
700
701 void
bfd_putl32(bfd_vma data,void * p)702 bfd_putl32 (bfd_vma data, void *p)
703 {
704 bfd_byte *addr = p;
705 addr[0] = data & 0xff;
706 addr[1] = (data >> 8) & 0xff;
707 addr[2] = (data >> 16) & 0xff;
708 addr[3] = (data >> 24) & 0xff;
709 }
710
711 void
bfd_putb64(bfd_uint64_t data ATTRIBUTE_UNUSED,void * p ATTRIBUTE_UNUSED)712 bfd_putb64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED)
713 {
714 #ifdef BFD_HOST_64_BIT
715 bfd_byte *addr = p;
716 addr[0] = (data >> (7*8)) & 0xff;
717 addr[1] = (data >> (6*8)) & 0xff;
718 addr[2] = (data >> (5*8)) & 0xff;
719 addr[3] = (data >> (4*8)) & 0xff;
720 addr[4] = (data >> (3*8)) & 0xff;
721 addr[5] = (data >> (2*8)) & 0xff;
722 addr[6] = (data >> (1*8)) & 0xff;
723 addr[7] = (data >> (0*8)) & 0xff;
724 #else
725 BFD_FAIL();
726 #endif
727 }
728
729 void
bfd_putl64(bfd_uint64_t data ATTRIBUTE_UNUSED,void * p ATTRIBUTE_UNUSED)730 bfd_putl64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED)
731 {
732 #ifdef BFD_HOST_64_BIT
733 bfd_byte *addr = p;
734 addr[7] = (data >> (7*8)) & 0xff;
735 addr[6] = (data >> (6*8)) & 0xff;
736 addr[5] = (data >> (5*8)) & 0xff;
737 addr[4] = (data >> (4*8)) & 0xff;
738 addr[3] = (data >> (3*8)) & 0xff;
739 addr[2] = (data >> (2*8)) & 0xff;
740 addr[1] = (data >> (1*8)) & 0xff;
741 addr[0] = (data >> (0*8)) & 0xff;
742 #else
743 BFD_FAIL();
744 #endif
745 }
746
747 void
bfd_put_bits(bfd_uint64_t data,void * p,int bits,bfd_boolean big_p)748 bfd_put_bits (bfd_uint64_t data, void *p, int bits, bfd_boolean big_p)
749 {
750 bfd_byte *addr = p;
751 int i;
752 int bytes;
753
754 if (bits % 8 != 0)
755 abort ();
756
757 bytes = bits / 8;
758 for (i = 0; i < bytes; i++)
759 {
760 int index = big_p ? bytes - i - 1 : i;
761
762 addr[index] = data & 0xff;
763 data >>= 8;
764 }
765 }
766
767 bfd_uint64_t
bfd_get_bits(const void * p,int bits,bfd_boolean big_p)768 bfd_get_bits (const void *p, int bits, bfd_boolean big_p)
769 {
770 const bfd_byte *addr = p;
771 bfd_uint64_t data;
772 int i;
773 int bytes;
774
775 if (bits % 8 != 0)
776 abort ();
777
778 data = 0;
779 bytes = bits / 8;
780 for (i = 0; i < bytes; i++)
781 {
782 int index = big_p ? i : bytes - i - 1;
783
784 data = (data << 8) | addr[index];
785 }
786
787 return data;
788 }
789
790 /* Default implementation */
791
792 bfd_boolean
_bfd_generic_get_section_contents(bfd * abfd,sec_ptr section,void * location,file_ptr offset,bfd_size_type count)793 _bfd_generic_get_section_contents (bfd *abfd,
794 sec_ptr section,
795 void *location,
796 file_ptr offset,
797 bfd_size_type count)
798 {
799 bfd_size_type sz;
800 if (count == 0)
801 return TRUE;
802
803 sz = section->rawsize ? section->rawsize : section->size;
804 if (offset + count > sz)
805 {
806 bfd_set_error (bfd_error_invalid_operation);
807 return FALSE;
808 }
809
810 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
811 || bfd_bread (location, count, abfd) != count)
812 return FALSE;
813
814 return TRUE;
815 }
816
817 bfd_boolean
_bfd_generic_get_section_contents_in_window(bfd * abfd ATTRIBUTE_UNUSED,sec_ptr section ATTRIBUTE_UNUSED,bfd_window * w ATTRIBUTE_UNUSED,file_ptr offset ATTRIBUTE_UNUSED,bfd_size_type count ATTRIBUTE_UNUSED)818 _bfd_generic_get_section_contents_in_window
819 (bfd *abfd ATTRIBUTE_UNUSED,
820 sec_ptr section ATTRIBUTE_UNUSED,
821 bfd_window *w ATTRIBUTE_UNUSED,
822 file_ptr offset ATTRIBUTE_UNUSED,
823 bfd_size_type count ATTRIBUTE_UNUSED)
824 {
825 #ifdef USE_MMAP
826 bfd_size_type sz;
827
828 if (count == 0)
829 return TRUE;
830 if (abfd->xvec->_bfd_get_section_contents
831 != _bfd_generic_get_section_contents)
832 {
833 /* We don't know what changes the bfd's get_section_contents
834 method may have to make. So punt trying to map the file
835 window, and let get_section_contents do its thing. */
836 /* @@ FIXME : If the internal window has a refcount of 1 and was
837 allocated with malloc instead of mmap, just reuse it. */
838 bfd_free_window (w);
839 w->i = bfd_zmalloc (sizeof (bfd_window_internal));
840 if (w->i == NULL)
841 return FALSE;
842 w->i->data = bfd_malloc (count);
843 if (w->i->data == NULL)
844 {
845 free (w->i);
846 w->i = NULL;
847 return FALSE;
848 }
849 w->i->mapped = 0;
850 w->i->refcount = 1;
851 w->size = w->i->size = count;
852 w->data = w->i->data;
853 return bfd_get_section_contents (abfd, section, w->data, offset, count);
854 }
855 sz = section->rawsize ? section->rawsize : section->size;
856 if (offset + count > sz
857 || ! bfd_get_file_window (abfd, section->filepos + offset, count, w,
858 TRUE))
859 return FALSE;
860 return TRUE;
861 #else
862 abort ();
863 #endif
864 }
865
866 /* This generic function can only be used in implementations where creating
867 NEW sections is disallowed. It is useful in patching existing sections
868 in read-write files, though. See other set_section_contents functions
869 to see why it doesn't work for new sections. */
870 bfd_boolean
_bfd_generic_set_section_contents(bfd * abfd,sec_ptr section,const void * location,file_ptr offset,bfd_size_type count)871 _bfd_generic_set_section_contents (bfd *abfd,
872 sec_ptr section,
873 const void *location,
874 file_ptr offset,
875 bfd_size_type count)
876 {
877 if (count == 0)
878 return TRUE;
879
880 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
881 || bfd_bwrite (location, count, abfd) != count)
882 return FALSE;
883
884 return TRUE;
885 }
886
887 /*
888 INTERNAL_FUNCTION
889 bfd_log2
890
891 SYNOPSIS
892 unsigned int bfd_log2 (bfd_vma x);
893
894 DESCRIPTION
895 Return the log base 2 of the value supplied, rounded up. E.g., an
896 @var{x} of 1025 returns 11. A @var{x} of 0 returns 0.
897 */
898
899 unsigned int
bfd_log2(bfd_vma x)900 bfd_log2 (bfd_vma x)
901 {
902 unsigned int result = 0;
903
904 while ((x = (x >> 1)) != 0)
905 ++result;
906 return result;
907 }
908
909 bfd_boolean
bfd_generic_is_local_label_name(bfd * abfd,const char * name)910 bfd_generic_is_local_label_name (bfd *abfd, const char *name)
911 {
912 char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
913
914 return name[0] == locals_prefix;
915 }
916
917 /* Can be used from / for bfd_merge_private_bfd_data to check that
918 endianness matches between input and output file. Returns
919 TRUE for a match, otherwise returns FALSE and emits an error. */
920 bfd_boolean
_bfd_generic_verify_endian_match(bfd * ibfd,bfd * obfd)921 _bfd_generic_verify_endian_match (bfd *ibfd, bfd *obfd)
922 {
923 if (ibfd->xvec->byteorder != obfd->xvec->byteorder
924 && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
925 && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
926 {
927 const char *msg;
928
929 if (bfd_big_endian (ibfd))
930 msg = _("%B: compiled for a big endian system and target is little endian");
931 else
932 msg = _("%B: compiled for a little endian system and target is big endian");
933
934 (*_bfd_error_handler) (msg, ibfd);
935
936 bfd_set_error (bfd_error_wrong_format);
937 return FALSE;
938 }
939
940 return TRUE;
941 }
942
943 /* Give a warning at runtime if someone compiles code which calls
944 old routines. */
945
946 void
warn_deprecated(const char * what,const char * file,int line,const char * func)947 warn_deprecated (const char *what,
948 const char *file,
949 int line,
950 const char *func)
951 {
952 /* Poor man's tracking of functions we've already warned about. */
953 static size_t mask = 0;
954
955 if (~(size_t) func & ~mask)
956 {
957 /* Note: separate sentences in order to allow
958 for translation into other languages. */
959 if (func)
960 fprintf (stderr, _("Deprecated %s called at %s line %d in %s\n"),
961 what, file, line, func);
962 else
963 fprintf (stderr, _("Deprecated %s called\n"), what);
964 mask |= ~(size_t) func;
965 }
966 }
967
968 /* Helper function for reading uleb128 encoded data. */
969
970 bfd_vma
read_unsigned_leb128(bfd * abfd ATTRIBUTE_UNUSED,bfd_byte * buf,unsigned int * bytes_read_ptr)971 read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
972 bfd_byte *buf,
973 unsigned int *bytes_read_ptr)
974 {
975 bfd_vma result;
976 unsigned int num_read;
977 unsigned int shift;
978 unsigned char byte;
979
980 result = 0;
981 shift = 0;
982 num_read = 0;
983 do
984 {
985 byte = bfd_get_8 (abfd, buf);
986 buf++;
987 num_read++;
988 result |= (((bfd_vma) byte & 0x7f) << shift);
989 shift += 7;
990 }
991 while (byte & 0x80);
992 *bytes_read_ptr = num_read;
993 return result;
994 }
995
996 /* Helper function for reading sleb128 encoded data. */
997
998 bfd_signed_vma
read_signed_leb128(bfd * abfd ATTRIBUTE_UNUSED,bfd_byte * buf,unsigned int * bytes_read_ptr)999 read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
1000 bfd_byte *buf,
1001 unsigned int *bytes_read_ptr)
1002 {
1003 bfd_vma result;
1004 unsigned int shift;
1005 unsigned int num_read;
1006 unsigned char byte;
1007
1008 result = 0;
1009 shift = 0;
1010 num_read = 0;
1011 do
1012 {
1013 byte = bfd_get_8 (abfd, buf);
1014 buf ++;
1015 num_read ++;
1016 result |= (((bfd_vma) byte & 0x7f) << shift);
1017 shift += 7;
1018 }
1019 while (byte & 0x80);
1020 if (shift < 8 * sizeof (result) && (byte & 0x40))
1021 result |= (((bfd_vma) -1) << shift);
1022 *bytes_read_ptr = num_read;
1023 return result;
1024 }
1025
1026 bfd_boolean
_bfd_generic_find_line(bfd * abfd ATTRIBUTE_UNUSED,asymbol ** symbols ATTRIBUTE_UNUSED,asymbol * symbol ATTRIBUTE_UNUSED,const char ** filename_ptr ATTRIBUTE_UNUSED,unsigned int * linenumber_ptr ATTRIBUTE_UNUSED)1027 _bfd_generic_find_line (bfd *abfd ATTRIBUTE_UNUSED,
1028 asymbol **symbols ATTRIBUTE_UNUSED,
1029 asymbol *symbol ATTRIBUTE_UNUSED,
1030 const char **filename_ptr ATTRIBUTE_UNUSED,
1031 unsigned int *linenumber_ptr ATTRIBUTE_UNUSED)
1032 {
1033 return FALSE;
1034 }
1035