libbfd.c 26.4 KB
Newer Older
Richard Henderson's avatar
Richard Henderson committed
1
/* Assorted BFD support routines, only used internally.
Nick Clifton's avatar
Nick Clifton committed
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
Richard Henderson's avatar
Richard Henderson committed
4 5 6
   Free Software Foundation, Inc.
   Written by Cygnus Support.

7
   This file is part of BFD, the Binary File Descriptor library.
Richard Henderson's avatar
Richard Henderson committed
8

9 10
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
Richard Henderson's avatar
Richard Henderson committed
13

14 15 16 17
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
Richard Henderson's avatar
Richard Henderson committed
18

19 20
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
21 22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
Richard Henderson's avatar
Richard Henderson committed
23 24

#include "sysdep.h"
Alan Modra's avatar
 
Alan Modra committed
25
#include "bfd.h"
Richard Henderson's avatar
Richard Henderson committed
26 27 28 29 30 31 32 33
#include "libbfd.h"

#ifndef HAVE_GETPAGESIZE
#define getpagesize() 2048
#endif

/*
SECTION
34 35 36
	Implementation details

SUBSECTION
Richard Henderson's avatar
Richard Henderson committed
37 38 39 40 41 42 43 44 45 46 47
	Internal functions

DESCRIPTION
	These routines are used within BFD.
	They are not intended for export, but are documented here for
	completeness.
*/

/* A routine which is used in target vectors for unsupported
   operations.  */

48
bfd_boolean
49
bfd_false (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
50 51
{
  bfd_set_error (bfd_error_invalid_operation);
52
  return FALSE;
Richard Henderson's avatar
Richard Henderson committed
53 54 55 56 57
}

/* A routine which is used in target vectors for supported operations
   which do not actually do anything.  */

58
bfd_boolean
59
bfd_true (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
60
{
61
  return TRUE;
Richard Henderson's avatar
Richard Henderson committed
62 63 64 65 66
}

/* A routine which is used in target vectors for unsupported
   operations which return a pointer value.  */

67 68
void *
bfd_nullvoidptr (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
69 70 71 72 73
{
  bfd_set_error (bfd_error_invalid_operation);
  return NULL;
}

74
int
75
bfd_0 (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
76 77 78 79
{
  return 0;
}

80
unsigned int
81
bfd_0u (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
82 83 84 85 86
{
   return 0;
}

long
87
bfd_0l (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
88 89 90 91 92 93 94 95
{
  return 0;
}

/* A routine which is used in target vectors for unsupported
   operations which return -1 on error.  */

long
96
_bfd_n1 (bfd *ignore_abfd ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
97 98 99 100 101
{
  bfd_set_error (bfd_error_invalid_operation);
  return -1;
}

102
void
103
bfd_void (bfd *ignore ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
104 105 106
{
}

107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
long
_bfd_norelocs_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
				     asection *sec ATTRIBUTE_UNUSED)
{
  return sizeof (arelent *);
}

long
_bfd_norelocs_canonicalize_reloc (bfd *abfd ATTRIBUTE_UNUSED,
				  asection *sec ATTRIBUTE_UNUSED,
				  arelent **relptr,
				  asymbol **symbols ATTRIBUTE_UNUSED)
{
  *relptr = NULL;
  return 0;
}

124
bfd_boolean
125 126 127
_bfd_nocore_core_file_matches_executable_p
  (bfd *ignore_core_bfd ATTRIBUTE_UNUSED,
   bfd *ignore_exec_bfd ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
128 129
{
  bfd_set_error (bfd_error_invalid_operation);
130
  return FALSE;
Richard Henderson's avatar
Richard Henderson committed
131 132 133 134 135 136
}

/* Routine to handle core_file_failing_command entry point for targets
   without core file support.  */

char *
137
_bfd_nocore_core_file_failing_command (bfd *ignore_abfd ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
138 139
{
  bfd_set_error (bfd_error_invalid_operation);
140
  return NULL;
Richard Henderson's avatar
Richard Henderson committed
141 142 143 144 145 146
}

/* Routine to handle core_file_failing_signal entry point for targets
   without core file support.  */

int
147
_bfd_nocore_core_file_failing_signal (bfd *ignore_abfd ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
148 149 150 151 152
{
  bfd_set_error (bfd_error_invalid_operation);
  return 0;
}

153 154 155 156 157 158 159 160 161 162
/* Routine to handle the core_file_pid entry point for targets without
   core file support.  */

int
_bfd_nocore_core_file_pid (bfd *ignore_abfd ATTRIBUTE_UNUSED)
{
  bfd_set_error (bfd_error_invalid_operation);
  return 0;
}

Richard Henderson's avatar
Richard Henderson committed
163
const bfd_target *
164
_bfd_dummy_target (bfd *ignore_abfd ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
165 166 167 168 169 170 171
{
  bfd_set_error (bfd_error_wrong_format);
  return 0;
}

/* Allocate memory using malloc.  */

172 173
void *
bfd_malloc (bfd_size_type size)
Richard Henderson's avatar
Richard Henderson committed
174
{
175
  void *ptr;
Richard Henderson's avatar
Richard Henderson committed
176

177 178 179 180 181 182
  if (size != (size_t) size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

183
  ptr = malloc ((size_t) size);
184
  if (ptr == NULL && (size_t) size != 0)
Richard Henderson's avatar
Richard Henderson committed
185
    bfd_set_error (bfd_error_no_memory);
186

Richard Henderson's avatar
Richard Henderson committed
187 188 189
  return ptr;
}

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
/* Allocate memory using malloc, nmemb * size with overflow checking.  */

void *
bfd_malloc2 (bfd_size_type nmemb, bfd_size_type size)
{
  void *ptr;

  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
      && size != 0
      && nmemb > ~(bfd_size_type) 0 / size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  size *= nmemb;

  if (size != (size_t) size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  ptr = malloc ((size_t) size);
  if (ptr == NULL && (size_t) size != 0)
    bfd_set_error (bfd_error_no_memory);

  return ptr;
}

Richard Henderson's avatar
Richard Henderson committed
220 221
/* Reallocate memory using realloc.  */

222 223
void *
bfd_realloc (void *ptr, bfd_size_type size)
Richard Henderson's avatar
Richard Henderson committed
224
{
225
  void *ret;
Richard Henderson's avatar
Richard Henderson committed
226

227 228 229 230 231 232
  if (size != (size_t) size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

Richard Henderson's avatar
Richard Henderson committed
233
  if (ptr == NULL)
234
    ret = malloc ((size_t) size);
Richard Henderson's avatar
Richard Henderson committed
235
  else
236
    ret = realloc (ptr, (size_t) size);
Richard Henderson's avatar
Richard Henderson committed
237

238
  if (ret == NULL && (size_t) size != 0)
Richard Henderson's avatar
Richard Henderson committed
239 240 241 242 243
    bfd_set_error (bfd_error_no_memory);

  return ret;
}

244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
/* Reallocate memory using realloc, nmemb * size with overflow checking.  */

void *
bfd_realloc2 (void *ptr, bfd_size_type nmemb, bfd_size_type size)
{
  void *ret;

  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
      && size != 0
      && nmemb > ~(bfd_size_type) 0 / size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  size *= nmemb;

  if (size != (size_t) size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  if (ptr == NULL)
    ret = malloc ((size_t) size);
  else
    ret = realloc (ptr, (size_t) size);

  if (ret == NULL && (size_t) size != 0)
    bfd_set_error (bfd_error_no_memory);

  return ret;
}

Nick Clifton's avatar
Nick Clifton committed
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
/* Reallocate memory using realloc.
   If this fails the pointer is freed before returning.  */

void *
bfd_realloc_or_free (void *ptr, bfd_size_type size)
{
  size_t amount = (size_t) size;
  void *ret;

  if (size != amount)
    ret = NULL;
  else if (ptr == NULL)
    ret = malloc (amount);
  else
    ret = realloc (ptr, amount);

  if (ret == NULL)
    {
      if (amount > 0)
	bfd_set_error (bfd_error_no_memory);

      if (ptr != NULL)
	free (ptr);
    }

  return ret;
}

Richard Henderson's avatar
Richard Henderson committed
306 307
/* Allocate memory using malloc and clear it.  */

308 309
void *
bfd_zmalloc (bfd_size_type size)
Richard Henderson's avatar
Richard Henderson committed
310
{
311
  void *ptr;
Richard Henderson's avatar
Richard Henderson committed
312

313 314 315 316 317
  if (size != (size_t) size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }
Richard Henderson's avatar
Richard Henderson committed
318

319
  ptr = malloc ((size_t) size);
320 321

  if ((size_t) size != 0)
Richard Henderson's avatar
Richard Henderson committed
322 323 324 325
    {
      if (ptr == NULL)
	bfd_set_error (bfd_error_no_memory);
      else
326
	memset (ptr, 0, (size_t) size);
Richard Henderson's avatar
Richard Henderson committed
327 328 329 330
    }

  return ptr;
}
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

/* Allocate memory using malloc (nmemb * size) with overflow checking
   and clear it.  */

void *
bfd_zmalloc2 (bfd_size_type nmemb, bfd_size_type size)
{
  void *ptr;

  if ((nmemb | size) >= HALF_BFD_SIZE_TYPE
      && size != 0
      && nmemb > ~(bfd_size_type) 0 / size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  size *= nmemb;

  if (size != (size_t) size)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  ptr = malloc ((size_t) size);

  if ((size_t) size != 0)
    {
      if (ptr == NULL)
	bfd_set_error (bfd_error_no_memory);
      else
	memset (ptr, 0, (size_t) size);
    }

  return ptr;
}

Richard Henderson's avatar
Richard Henderson committed
369 370 371 372 373
/*
INTERNAL_FUNCTION
	bfd_write_bigendian_4byte_int

SYNOPSIS
374
	bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
Richard Henderson's avatar
Richard Henderson committed
375 376 377 378 379 380 381

DESCRIPTION
	Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
	endian order regardless of what else is going on.  This is useful in
	archives.

*/
382
bfd_boolean
383
bfd_write_bigendian_4byte_int (bfd *abfd, unsigned int i)
Richard Henderson's avatar
Richard Henderson committed
384 385
{
  bfd_byte buffer[4];
386
  bfd_putb32 ((bfd_vma) i, buffer);
387
  return bfd_bwrite (buffer, (bfd_size_type) 4, abfd) == 4;
Richard Henderson's avatar
Richard Henderson committed
388 389 390 391 392 393 394 395 396 397 398
}


/** The do-it-yourself (byte) sex-change kit */

/* The middle letter e.g. get<b>short indicates Big or Little endian
   target machine.  It doesn't matter what the byte order of the host
   machine is; these routines work for either.  */

/* FIXME: Should these take a count argument?
   Answer (gnu@cygnus.com):  No, but perhaps they should be inline
399
                             functions in swap.h #ifdef __GNUC__.
Richard Henderson's avatar
Richard Henderson committed
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429
                             Gprof them later and find out.  */

/*
FUNCTION
	bfd_put_size
FUNCTION
	bfd_get_size

DESCRIPTION
	These macros as used for reading and writing raw data in
	sections; each access (except for bytes) is vectored through
	the target format of the BFD and mangled accordingly. The
	mangling performs any necessary endian translations and
	removes alignment restrictions.  Note that types accepted and
	returned by these macros are identical so they can be swapped
	around in macros---for example, @file{libaout.h} defines <<GET_WORD>>
	to either <<bfd_get_32>> or <<bfd_get_64>>.

	In the put routines, @var{val} must be a <<bfd_vma>>.  If we are on a
	system without prototypes, the caller is responsible for making
	sure that is true, with a cast if necessary.  We don't cast
	them in the macro definitions because that would prevent <<lint>>
	or <<gcc -Wall>> from detecting sins such as passing a pointer.
	To detect calling these with less than a <<bfd_vma>>, use
	<<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s.

.
.{* Byte swapping macros for user section data.  *}
.
.#define bfd_put_8(abfd, val, ptr) \
430
.  ((void) (*((unsigned char *) (ptr)) = (val) & 0xff))
Richard Henderson's avatar
Richard Henderson committed
431
.#define bfd_put_signed_8 \
432
.  bfd_put_8
Richard Henderson's avatar
Richard Henderson committed
433
.#define bfd_get_8(abfd, ptr) \
Alan Modra's avatar
Alan Modra committed
434
.  (*(const unsigned char *) (ptr) & 0xff)
Richard Henderson's avatar
Richard Henderson committed
435
.#define bfd_get_signed_8(abfd, ptr) \
Alan Modra's avatar
Alan Modra committed
436
.  (((*(const unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80)
Richard Henderson's avatar
Richard Henderson committed
437 438
.
.#define bfd_put_16(abfd, val, ptr) \
439
.  BFD_SEND (abfd, bfd_putx16, ((val),(ptr)))
Richard Henderson's avatar
Richard Henderson committed
440
.#define bfd_put_signed_16 \
441
.  bfd_put_16
Richard Henderson's avatar
Richard Henderson committed
442
.#define bfd_get_16(abfd, ptr) \
443
.  BFD_SEND (abfd, bfd_getx16, (ptr))
Richard Henderson's avatar
Richard Henderson committed
444
.#define bfd_get_signed_16(abfd, ptr) \
445
.  BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
Richard Henderson's avatar
Richard Henderson committed
446 447
.
.#define bfd_put_32(abfd, val, ptr) \
448
.  BFD_SEND (abfd, bfd_putx32, ((val),(ptr)))
Richard Henderson's avatar
Richard Henderson committed
449
.#define bfd_put_signed_32 \
450
.  bfd_put_32
Richard Henderson's avatar
Richard Henderson committed
451
.#define bfd_get_32(abfd, ptr) \
452
.  BFD_SEND (abfd, bfd_getx32, (ptr))
Richard Henderson's avatar
Richard Henderson committed
453
.#define bfd_get_signed_32(abfd, ptr) \
454
.  BFD_SEND (abfd, bfd_getx_signed_32, (ptr))
Richard Henderson's avatar
Richard Henderson committed
455 456
.
.#define bfd_put_64(abfd, val, ptr) \
457
.  BFD_SEND (abfd, bfd_putx64, ((val), (ptr)))
Richard Henderson's avatar
Richard Henderson committed
458
.#define bfd_put_signed_64 \
459
.  bfd_put_64
Richard Henderson's avatar
Richard Henderson committed
460
.#define bfd_get_64(abfd, ptr) \
461
.  BFD_SEND (abfd, bfd_getx64, (ptr))
Richard Henderson's avatar
Richard Henderson committed
462
.#define bfd_get_signed_64(abfd, ptr) \
463
.  BFD_SEND (abfd, bfd_getx_signed_64, (ptr))
Richard Henderson's avatar
Richard Henderson committed
464
.
465 466 467 468 469 470
.#define bfd_get(bits, abfd, ptr)			\
.  ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr)	\
.   : (bits) == 16 ? bfd_get_16 (abfd, ptr)		\
.   : (bits) == 32 ? bfd_get_32 (abfd, ptr)		\
.   : (bits) == 64 ? bfd_get_64 (abfd, ptr)		\
.   : (abort (), (bfd_vma) - 1))
471
.
472 473 474 475 476 477
.#define bfd_put(bits, abfd, val, ptr)			\
.  ((bits) == 8 ? bfd_put_8  (abfd, val, ptr)		\
.   : (bits) == 16 ? bfd_put_16 (abfd, val, ptr)		\
.   : (bits) == 32 ? bfd_put_32 (abfd, val, ptr)		\
.   : (bits) == 64 ? bfd_put_64 (abfd, val, ptr)		\
.   : (abort (), (void) 0))
478
.
479
*/
Richard Henderson's avatar
Richard Henderson committed
480 481 482 483 484 485 486 487

/*
FUNCTION
	bfd_h_put_size
	bfd_h_get_size

DESCRIPTION
	These macros have the same function as their <<bfd_get_x>>
488
	brethren, except that they are used for removing information
Richard Henderson's avatar
Richard Henderson committed
489 490 491 492 493 494 495
	for the header records of object files. Believe it or not,
	some object files keep their header records in big endian
	order and their data in little endian order.
.
.{* Byte swapping macros for file header data.  *}
.
.#define bfd_h_put_8(abfd, val, ptr) \
496
.  bfd_put_8 (abfd, val, ptr)
Richard Henderson's avatar
Richard Henderson committed
497
.#define bfd_h_put_signed_8(abfd, val, ptr) \
498
.  bfd_put_8 (abfd, val, ptr)
Richard Henderson's avatar
Richard Henderson committed
499
.#define bfd_h_get_8(abfd, ptr) \
500
.  bfd_get_8 (abfd, ptr)
Richard Henderson's avatar
Richard Henderson committed
501
.#define bfd_h_get_signed_8(abfd, ptr) \
502
.  bfd_get_signed_8 (abfd, ptr)
Richard Henderson's avatar
Richard Henderson committed
503 504
.
.#define bfd_h_put_16(abfd, val, ptr) \
505
.  BFD_SEND (abfd, bfd_h_putx16, (val, ptr))
Richard Henderson's avatar
Richard Henderson committed
506
.#define bfd_h_put_signed_16 \
507
.  bfd_h_put_16
Richard Henderson's avatar
Richard Henderson committed
508
.#define bfd_h_get_16(abfd, ptr) \
509
.  BFD_SEND (abfd, bfd_h_getx16, (ptr))
Richard Henderson's avatar
Richard Henderson committed
510
.#define bfd_h_get_signed_16(abfd, ptr) \
511
.  BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr))
Richard Henderson's avatar
Richard Henderson committed
512 513
.
.#define bfd_h_put_32(abfd, val, ptr) \
514
.  BFD_SEND (abfd, bfd_h_putx32, (val, ptr))
Richard Henderson's avatar
Richard Henderson committed
515
.#define bfd_h_put_signed_32 \
516
.  bfd_h_put_32
Richard Henderson's avatar
Richard Henderson committed
517
.#define bfd_h_get_32(abfd, ptr) \
518
.  BFD_SEND (abfd, bfd_h_getx32, (ptr))
Richard Henderson's avatar
Richard Henderson committed
519
.#define bfd_h_get_signed_32(abfd, ptr) \
520
.  BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr))
Richard Henderson's avatar
Richard Henderson committed
521 522
.
.#define bfd_h_put_64(abfd, val, ptr) \
523
.  BFD_SEND (abfd, bfd_h_putx64, (val, ptr))
Richard Henderson's avatar
Richard Henderson committed
524
.#define bfd_h_put_signed_64 \
525
.  bfd_h_put_64
Richard Henderson's avatar
Richard Henderson committed
526
.#define bfd_h_get_64(abfd, ptr) \
527
.  BFD_SEND (abfd, bfd_h_getx64, (ptr))
Richard Henderson's avatar
Richard Henderson committed
528
.#define bfd_h_get_signed_64(abfd, ptr) \
529
.  BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr))
Richard Henderson's avatar
Richard Henderson committed
530
.
531
.{* Aliases for the above, which should eventually go away.  *}
532
.
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
.#define H_PUT_64  bfd_h_put_64
.#define H_PUT_32  bfd_h_put_32
.#define H_PUT_16  bfd_h_put_16
.#define H_PUT_8   bfd_h_put_8
.#define H_PUT_S64 bfd_h_put_signed_64
.#define H_PUT_S32 bfd_h_put_signed_32
.#define H_PUT_S16 bfd_h_put_signed_16
.#define H_PUT_S8  bfd_h_put_signed_8
.#define H_GET_64  bfd_h_get_64
.#define H_GET_32  bfd_h_get_32
.#define H_GET_16  bfd_h_get_16
.#define H_GET_8   bfd_h_get_8
.#define H_GET_S64 bfd_h_get_signed_64
.#define H_GET_S32 bfd_h_get_signed_32
.#define H_GET_S16 bfd_h_get_signed_16
.#define H_GET_S8  bfd_h_get_signed_8
549 550
.
.*/
Richard Henderson's avatar
Richard Henderson committed
551 552 553

/* Sign extension to bfd_signed_vma.  */
#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
554
#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
555
#define EIGHT_GAZILLION ((bfd_int64_t) 1 << 63)
Richard Henderson's avatar
Richard Henderson committed
556
#define COERCE64(x) \
557
  (((bfd_int64_t) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
Richard Henderson's avatar
Richard Henderson committed
558 559

bfd_vma
560
bfd_getb16 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
561
{
562
  const bfd_byte *addr = (const bfd_byte *) p;
Richard Henderson's avatar
Richard Henderson committed
563 564 565 566
  return (addr[0] << 8) | addr[1];
}

bfd_vma
567
bfd_getl16 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
568
{
569
  const bfd_byte *addr = (const bfd_byte *) p;
Richard Henderson's avatar
Richard Henderson committed
570 571 572 573
  return (addr[1] << 8) | addr[0];
}

bfd_signed_vma
574
bfd_getb_signed_16 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
575
{
576
  const bfd_byte *addr = (const bfd_byte *) p;
577
  return COERCE16 ((addr[0] << 8) | addr[1]);
Richard Henderson's avatar
Richard Henderson committed
578 579 580
}

bfd_signed_vma
581
bfd_getl_signed_16 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
582
{
583
  const bfd_byte *addr = (const bfd_byte *) p;
584
  return COERCE16 ((addr[1] << 8) | addr[0]);
Richard Henderson's avatar
Richard Henderson committed
585 586 587
}

void
588
bfd_putb16 (bfd_vma data, void *p)
Richard Henderson's avatar
Richard Henderson committed
589
{
590
  bfd_byte *addr = (bfd_byte *) p;
591 592
  addr[0] = (data >> 8) & 0xff;
  addr[1] = data & 0xff;
Richard Henderson's avatar
Richard Henderson committed
593 594 595
}

void
596
bfd_putl16 (bfd_vma data, void *p)
Richard Henderson's avatar
Richard Henderson committed
597
{
598
  bfd_byte *addr = (bfd_byte *) p;
599 600
  addr[0] = data & 0xff;
  addr[1] = (data >> 8) & 0xff;
Richard Henderson's avatar
Richard Henderson committed
601 602 603
}

bfd_vma
604
bfd_getb32 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
605
{
606
  const bfd_byte *addr = (const bfd_byte *) p;
Richard Henderson's avatar
Richard Henderson committed
607 608 609 610 611 612
  unsigned long v;

  v = (unsigned long) addr[0] << 24;
  v |= (unsigned long) addr[1] << 16;
  v |= (unsigned long) addr[2] << 8;
  v |= (unsigned long) addr[3];
613
  return v;
Richard Henderson's avatar
Richard Henderson committed
614 615 616
}

bfd_vma
617
bfd_getl32 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
618
{
619
  const bfd_byte *addr = (const bfd_byte *) p;
Richard Henderson's avatar
Richard Henderson committed
620 621 622 623 624 625
  unsigned long v;

  v = (unsigned long) addr[0];
  v |= (unsigned long) addr[1] << 8;
  v |= (unsigned long) addr[2] << 16;
  v |= (unsigned long) addr[3] << 24;
626
  return v;
Richard Henderson's avatar
Richard Henderson committed
627 628 629
}

bfd_signed_vma
630
bfd_getb_signed_32 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
631
{
632
  const bfd_byte *addr = (const bfd_byte *) p;
Richard Henderson's avatar
Richard Henderson committed
633 634 635 636 637 638 639 640 641 642
  unsigned long v;

  v = (unsigned long) addr[0] << 24;
  v |= (unsigned long) addr[1] << 16;
  v |= (unsigned long) addr[2] << 8;
  v |= (unsigned long) addr[3];
  return COERCE32 (v);
}

bfd_signed_vma
643
bfd_getl_signed_32 (const void *p)
Richard Henderson's avatar
Richard Henderson committed
644
{
645
  const bfd_byte *addr = (const bfd_byte *) p;
Richard Henderson's avatar
Richard Henderson committed
646 647 648 649 650 651 652 653 654
  unsigned long v;

  v = (unsigned long) addr[0];
  v |= (unsigned long) addr[1] << 8;
  v |= (unsigned long) addr[2] << 16;
  v |= (unsigned long) addr[3] << 24;
  return COERCE32 (v);
}

655
bfd_uint64_t
656
bfd_getb64 (const void *p ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
657
{
658
#ifdef BFD_HOST_64_BIT
659
  const bfd_byte *addr = (const bfd_byte *) p;
660
  bfd_uint64_t v;
661 662 663 664 665 666 667 668 669 670 671

  v  = addr[0]; v <<= 8;
  v |= addr[1]; v <<= 8;
  v |= addr[2]; v <<= 8;
  v |= addr[3]; v <<= 8;
  v |= addr[4]; v <<= 8;
  v |= addr[5]; v <<= 8;
  v |= addr[6]; v <<= 8;
  v |= addr[7];

  return v;
Richard Henderson's avatar
Richard Henderson committed
672 673 674 675 676 677
#else
  BFD_FAIL();
  return 0;
#endif
}

678
bfd_uint64_t
679
bfd_getl64 (const void *p ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
680
{
681
#ifdef BFD_HOST_64_BIT
682
  const bfd_byte *addr = (const bfd_byte *) p;
683
  bfd_uint64_t v;
684 685 686 687 688 689 690 691 692 693 694

  v  = addr[7]; v <<= 8;
  v |= addr[6]; v <<= 8;
  v |= addr[5]; v <<= 8;
  v |= addr[4]; v <<= 8;
  v |= addr[3]; v <<= 8;
  v |= addr[2]; v <<= 8;
  v |= addr[1]; v <<= 8;
  v |= addr[0];

  return v;
Richard Henderson's avatar
Richard Henderson committed
695 696 697 698 699 700 701
#else
  BFD_FAIL();
  return 0;
#endif

}

702
bfd_int64_t
703
bfd_getb_signed_64 (const void *p ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
704
{
705
#ifdef BFD_HOST_64_BIT
706
  const bfd_byte *addr = (const bfd_byte *) p;
707
  bfd_uint64_t v;
708 709 710 711 712 713 714 715 716 717 718

  v  = addr[0]; v <<= 8;
  v |= addr[1]; v <<= 8;
  v |= addr[2]; v <<= 8;
  v |= addr[3]; v <<= 8;
  v |= addr[4]; v <<= 8;
  v |= addr[5]; v <<= 8;
  v |= addr[6]; v <<= 8;
  v |= addr[7];

  return COERCE64 (v);
Richard Henderson's avatar
Richard Henderson committed
719 720 721 722 723 724
#else
  BFD_FAIL();
  return 0;
#endif
}

725
bfd_int64_t
726
bfd_getl_signed_64 (const void *p ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
727
{
728
#ifdef BFD_HOST_64_BIT
729
  const bfd_byte *addr = (const bfd_byte *) p;
730
  bfd_uint64_t v;
731 732 733 734 735 736 737 738 739 740 741

  v  = addr[7]; v <<= 8;
  v |= addr[6]; v <<= 8;
  v |= addr[5]; v <<= 8;
  v |= addr[4]; v <<= 8;
  v |= addr[3]; v <<= 8;
  v |= addr[2]; v <<= 8;
  v |= addr[1]; v <<= 8;
  v |= addr[0];

  return COERCE64 (v);
Richard Henderson's avatar
Richard Henderson committed
742 743 744 745 746 747 748
#else
  BFD_FAIL();
  return 0;
#endif
}

void
749
bfd_putb32 (bfd_vma data, void *p)
Richard Henderson's avatar
Richard Henderson committed
750
{
751
  bfd_byte *addr = (bfd_byte *) p;
752 753 754 755
  addr[0] = (data >> 24) & 0xff;
  addr[1] = (data >> 16) & 0xff;
  addr[2] = (data >>  8) & 0xff;
  addr[3] = data & 0xff;
Richard Henderson's avatar
Richard Henderson committed
756 757 758
}

void
759
bfd_putl32 (bfd_vma data, void *p)
Richard Henderson's avatar
Richard Henderson committed
760
{
761
  bfd_byte *addr = (bfd_byte *) p;
762 763 764 765
  addr[0] = data & 0xff;
  addr[1] = (data >>  8) & 0xff;
  addr[2] = (data >> 16) & 0xff;
  addr[3] = (data >> 24) & 0xff;
Richard Henderson's avatar
Richard Henderson committed
766 767 768
}

void
769
bfd_putb64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
770
{
771
#ifdef BFD_HOST_64_BIT
772
  bfd_byte *addr = (bfd_byte *) p;
773 774 775 776 777 778 779 780
  addr[0] = (data >> (7*8)) & 0xff;
  addr[1] = (data >> (6*8)) & 0xff;
  addr[2] = (data >> (5*8)) & 0xff;
  addr[3] = (data >> (4*8)) & 0xff;
  addr[4] = (data >> (3*8)) & 0xff;
  addr[5] = (data >> (2*8)) & 0xff;
  addr[6] = (data >> (1*8)) & 0xff;
  addr[7] = (data >> (0*8)) & 0xff;
Richard Henderson's avatar
Richard Henderson committed
781 782 783 784 785 786
#else
  BFD_FAIL();
#endif
}

void
787
bfd_putl64 (bfd_uint64_t data ATTRIBUTE_UNUSED, void *p ATTRIBUTE_UNUSED)
Richard Henderson's avatar
Richard Henderson committed
788
{
789
#ifdef BFD_HOST_64_BIT
790
  bfd_byte *addr = (bfd_byte *) p;
791 792 793 794 795 796 797 798
  addr[7] = (data >> (7*8)) & 0xff;
  addr[6] = (data >> (6*8)) & 0xff;
  addr[5] = (data >> (5*8)) & 0xff;
  addr[4] = (data >> (4*8)) & 0xff;
  addr[3] = (data >> (3*8)) & 0xff;
  addr[2] = (data >> (2*8)) & 0xff;
  addr[1] = (data >> (1*8)) & 0xff;
  addr[0] = (data >> (0*8)) & 0xff;
Richard Henderson's avatar
Richard Henderson committed
799 800 801 802
#else
  BFD_FAIL();
#endif
}
803 804

void
805
bfd_put_bits (bfd_uint64_t data, void *p, int bits, bfd_boolean big_p)
806
{
807
  bfd_byte *addr = (bfd_byte *) p;
808 809 810 811 812 813 814 815 816
  int i;
  int bytes;

  if (bits % 8 != 0)
    abort ();

  bytes = bits / 8;
  for (i = 0; i < bytes; i++)
    {
817
      int addr_index = big_p ? bytes - i - 1 : i;
818

819
      addr[addr_index] = data & 0xff;
820 821 822 823
      data >>= 8;
    }
}

824
bfd_uint64_t
825
bfd_get_bits (const void *p, int bits, bfd_boolean big_p)
826
{
827
  const bfd_byte *addr = (const bfd_byte *) p;
828
  bfd_uint64_t data;
829 830 831 832 833 834 835 836 837 838
  int i;
  int bytes;

  if (bits % 8 != 0)
    abort ();

  data = 0;
  bytes = bits / 8;
  for (i = 0; i < bytes; i++)
    {
839
      int addr_index = big_p ? i : bytes - i - 1;
840

841
      data = (data << 8) | addr[addr_index];
842 843 844 845
    }

  return data;
}
Richard Henderson's avatar
Richard Henderson committed
846 847 848

/* Default implementation */

849
bfd_boolean
850 851 852 853 854
_bfd_generic_get_section_contents (bfd *abfd,
				   sec_ptr section,
				   void *location,
				   file_ptr offset,
				   bfd_size_type count)
Richard Henderson's avatar
Richard Henderson committed
855
{
Alan Modra's avatar
bfd/  
Alan Modra committed
856
  bfd_size_type sz;
857
  if (count == 0)
858
    return TRUE;
859

860 861 862 863 864 865 866 867 868
  if (section->compress_status != COMPRESS_SECTION_NONE)
    {
      (*_bfd_error_handler)
	(_("%B: unable to get decompressed section %A"),
	 abfd, section);
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

869 870 871 872 873 874 875 876 877
  /* We do allow reading of a section after bfd_final_link has
     written the contents out to disk.  In that situation, rawsize is
     just a stale version of size, so ignore it.  Otherwise we must be
     reading an input section, where rawsize, if different to size,
     is the on-disk size.  */
  if (abfd->direction != write_direction && section->rawsize != 0)
    sz = section->rawsize;
  else
    sz = section->size;
878 879
  if (offset + count < count
      || offset + count > sz)
880 881
    {
      bfd_set_error (bfd_error_invalid_operation);
882
      return FALSE;
883 884 885
    }

  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
886
      || bfd_bread (location, count, abfd) != count)
887
    return FALSE;
888

889
  return TRUE;
Richard Henderson's avatar
Richard Henderson committed
890 891
}

892
bfd_boolean
893 894 895 896 897 898
_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)
Richard Henderson's avatar
Richard Henderson committed
899 900
{
#ifdef USE_MMAP
Alan Modra's avatar
bfd/  
Alan Modra committed
901 902
  bfd_size_type sz;

Richard Henderson's avatar
Richard Henderson committed
903
  if (count == 0)
904
    return TRUE;
905 906
  if (abfd->xvec->_bfd_get_section_contents
      != _bfd_generic_get_section_contents)
Richard Henderson's avatar
Richard Henderson committed
907 908 909 910 911 912 913
    {
      /* We don't know what changes the bfd's get_section_contents
	 method may have to make.  So punt trying to map the file
	 window, and let get_section_contents do its thing.  */
      /* @@ FIXME : If the internal window has a refcount of 1 and was
	 allocated with malloc instead of mmap, just reuse it.  */
      bfd_free_window (w);
914
      w->i = bfd_zmalloc (sizeof (bfd_window_internal));
Richard Henderson's avatar
Richard Henderson committed
915
      if (w->i == NULL)
916
	return FALSE;
917
      w->i->data = bfd_malloc (count);
Richard Henderson's avatar
Richard Henderson committed
918 919 920 921
      if (w->i->data == NULL)
	{
	  free (w->i);
	  w->i = NULL;
922
	  return FALSE;
Richard Henderson's avatar
Richard Henderson committed
923 924 925 926 927 928 929
	}
      w->i->mapped = 0;
      w->i->refcount = 1;
      w->size = w->i->size = count;
      w->data = w->i->data;
      return bfd_get_section_contents (abfd, section, w->data, offset, count);
    }
930 931 932 933
  if (abfd->direction != write_direction && section->rawsize != 0)
    sz = section->rawsize;
  else
    sz = section->size;
Alan Modra's avatar
bfd/  
Alan Modra committed
934
  if (offset + count > sz
935
      || ! bfd_get_file_window (abfd, section->filepos + offset, count, w,
936 937 938
				TRUE))
    return FALSE;
  return TRUE;
Richard Henderson's avatar
Richard Henderson committed
939 940 941 942 943 944 945 946 947
#else
  abort ();
#endif
}

/* This generic function can only be used in implementations where creating
   NEW sections is disallowed.  It is useful in patching existing sections
   in read-write files, though.  See other set_section_contents functions
   to see why it doesn't work for new sections.  */
948
bfd_boolean
949 950
_bfd_generic_set_section_contents (bfd *abfd,
				   sec_ptr section,
951
				   const void *location,
952 953
				   file_ptr offset,
				   bfd_size_type count)
Richard Henderson's avatar
Richard Henderson committed
954 955
{
  if (count == 0)
956
    return TRUE;
Richard Henderson's avatar
Richard Henderson committed
957

958 959
  if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
      || bfd_bwrite (location, count, abfd) != count)
960
    return FALSE;
Richard Henderson's avatar
Richard Henderson committed
961

962
  return TRUE;
Richard Henderson's avatar
Richard Henderson committed
963 964 965 966 967 968 969
}

/*
INTERNAL_FUNCTION
	bfd_log2

SYNOPSIS
970
	unsigned int bfd_log2 (bfd_vma x);
Richard Henderson's avatar
Richard Henderson committed
971 972 973

DESCRIPTION
	Return the log base 2 of the value supplied, rounded up.  E.g., an
974
	@var{x} of 1025 returns 11.  A @var{x} of 0 returns 0.
Richard Henderson's avatar
Richard Henderson committed
975 976 977
*/

unsigned int
978
bfd_log2 (bfd_vma x)
Richard Henderson's avatar
Richard Henderson committed
979 980 981
{
  unsigned int result = 0;

982 983 984 985
  if (x <= 1)
    return result;
  --x;
  do
Richard Henderson's avatar
Richard Henderson committed
986
    ++result;
987
  while ((x >>= 1) != 0);
Richard Henderson's avatar
Richard Henderson committed
988 989 990
  return result;
}

991
bfd_boolean
992
bfd_generic_is_local_label_name (bfd *abfd, const char *name)
Richard Henderson's avatar
Richard Henderson committed
993 994 995
{
  char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';

996
  return name[0] == locals_prefix;
Richard Henderson's avatar
Richard Henderson committed
997 998
}

999 1000
/*  Can be used from / for bfd_merge_private_bfd_data to check that
    endianness matches between input and output file.  Returns
1001 1002
    TRUE for a match, otherwise returns FALSE and emits an error.  */
bfd_boolean
1003
_bfd_generic_verify_endian_match (bfd *ibfd, bfd *obfd)
1004 1005
{
  if (ibfd->xvec->byteorder != obfd->xvec->byteorder
1006
      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
1007 1008
      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
    {
1009 1010 1011
      const char *msg;

      if (bfd_big_endian (ibfd))
Alan Modra's avatar
bfd/  
Alan Modra committed
1012
	msg = _("%B: compiled for a big endian system and target is little endian");
1013
      else
Alan Modra's avatar
bfd/  
Alan Modra committed
1014
	msg = _("%B: compiled for a little endian system and target is big endian");
1015

Alan Modra's avatar
bfd/  
Alan Modra committed
1016
      (*_bfd_error_handler) (msg, ibfd);
1017 1018

      bfd_set_error (bfd_error_wrong_format);
1019
      return FALSE;
1020 1021
    }

1022
  return TRUE;
1023
}
1024 1025 1026

/* Give a warning at runtime if someone compiles code which calls
   old routines.  */
1027

1028
void
1029 1030 1031 1032
warn_deprecated (const char *what,
		 const char *file,
		 int line,
		 const char *func)
1033 1034 1035 1036 1037 1038
{
  /* Poor man's tracking of functions we've already warned about.  */
  static size_t mask = 0;

  if (~(size_t) func & ~mask)
    {
1039
      fflush (stdout);
1040
      /* Note: separate sentences in order to allow
1041
	 for translation into other languages.  */
1042
      if (func)
1043 1044
	fprintf (stderr, _("Deprecated %s called at %s line %d in %s\n"),
		 what, file, line, func);
1045
      else
1046
	fprintf (stderr, _("Deprecated %s called\n"), what);
1047
      fflush (stderr);
1048 1049 1050
      mask |= ~(size_t) func;
    }
}
1051 1052 1053 1054 1055

/* Helper function for reading uleb128 encoded data.  */

bfd_vma
read_unsigned_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
Alan Modra's avatar
Alan Modra committed
1056
		      bfd_byte *buf,
1057 1058 1059 1060
		      unsigned int *bytes_read_ptr)
{
  bfd_vma result;
  unsigned int num_read;
Alan Modra's avatar
Alan Modra committed
1061
  unsigned int shift;
1062 1063 1064 1065 1066 1067 1068
  unsigned char byte;

  result = 0;
  shift = 0;
  num_read = 0;
  do
    {
Alan Modra's avatar
Alan Modra committed
1069
      byte = bfd_get_8 (abfd, buf);
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
      buf++;
      num_read++;
      result |= (((bfd_vma) byte & 0x7f) << shift);
      shift += 7;
    }
  while (byte & 0x80);
  *bytes_read_ptr = num_read;
  return result;
}

/* Helper function for reading sleb128 encoded data.  */

bfd_signed_vma
read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
Alan Modra's avatar
Alan Modra committed
1084 1085
		    bfd_byte *buf,
		    unsigned int *bytes_read_ptr)
1086 1087
{
  bfd_vma result;
Alan Modra's avatar
Alan Modra committed
1088 1089
  unsigned int shift;
  unsigned int num_read;
1090 1091 1092 1093 1094 1095 1096
  unsigned char byte;

  result = 0;
  shift = 0;
  num_read = 0;
  do
    {
Alan Modra's avatar
Alan Modra committed
1097
      byte = bfd_get_8 (abfd, buf);
1098 1099 1100 1101 1102 1103
      buf ++;
      num_read ++;
      result |= (((bfd_vma) byte & 0x7f) << shift);
      shift += 7;
    }
  while (byte & 0x80);
Alan Modra's avatar
Alan Modra committed
1104
  if (shift < 8 * sizeof (result) && (byte & 0x40))
1105
    result |= -((bfd_vma) 1 << shift);
1106 1107 1108
  *bytes_read_ptr = num_read;
  return result;
}
H.J. Lu's avatar
bfd/  
H.J. Lu committed
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118

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)
{
  return FALSE;
}
H.J. Lu's avatar
bfd/  
H.J. Lu committed
1119

1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
bfd_boolean
_bfd_generic_find_nearest_line_discriminator (bfd *abfd ATTRIBUTE_UNUSED,
                                              asection *section ATTRIBUTE_UNUSED,
                                              asymbol **symbols ATTRIBUTE_UNUSED,
                                              bfd_vma offset ATTRIBUTE_UNUSED,
                                              const char **filename_ptr ATTRIBUTE_UNUSED,
                                              const char **functionname_ptr ATTRIBUTE_UNUSED,
                                              unsigned int *line_ptr ATTRIBUTE_UNUSED,
                                              unsigned int *discriminator_ptr ATTRIBUTE_UNUSED)
{
  return FALSE;
}

H.J. Lu's avatar
bfd/  
H.J. Lu committed
1133 1134 1135 1136 1137 1138 1139 1140 1141
bfd_boolean
_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
					asection *isec ATTRIBUTE_UNUSED,
					bfd *obfd ATTRIBUTE_UNUSED,
					asection *osec ATTRIBUTE_UNUSED,
					struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
{
  return TRUE;
}