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