* som.c (setup_sections): Don't lose for a space which has
[deliverable/binutils-gdb.git] / bfd / libbfd.c
CommitLineData
0d552306 1/* Assorted BFD support routines, only used internally.
f4bd7a8f 2 Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
f58809fd 3 Written by Cygnus Support.
4a81b561 4
f58809fd 5This file is part of BFD, the Binary File Descriptor library.
4a81b561 6
f58809fd 7This program is free software; you can redistribute it and/or modify
4a81b561 8it under the terms of the GNU General Public License as published by
f58809fd
SC
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
4a81b561 11
f58809fd 12This program is distributed in the hope that it will be useful,
4a81b561
DHW
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
f58809fd 18along with this program; if not, write to the Free Software
4fe6d901 19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
4a81b561 20
4a81b561 21#include "bfd.h"
f58809fd 22#include "sysdep.h"
4a81b561
DHW
23#include "libbfd.h"
24
4fe6d901
KR
25static int real_read PARAMS ((PTR, size_t, size_t, FILE *));
26
f8e01940
JG
27/*
28SECTION
17ecba1a 29 Internal functions
f8e01940
JG
30
31DESCRIPTION
c188b0be 32 These routines are used within BFD.
f8e01940
JG
33 They are not intended for export, but are documented here for
34 completeness.
35*/
4a81b561 36
6812b607
ILT
37/* A routine which is used in target vectors for unsupported
38 operations. */
4a81b561 39
728472f1 40/*ARGSUSED*/
4a81b561 41boolean
f4bd7a8f
DM
42bfd_false (ignore)
43 bfd *ignore;
4a81b561 44{
6812b607 45 bfd_set_error (bfd_error_invalid_operation);
4a81b561
DHW
46 return false;
47}
48
6812b607
ILT
49/* A routine which is used in target vectors for supported operations
50 which do not actually do anything. */
51
728472f1 52/*ARGSUSED*/
4a81b561 53boolean
f4bd7a8f
DM
54bfd_true (ignore)
55 bfd *ignore;
4a81b561
DHW
56{
57 return true;
58}
59
6812b607
ILT
60/* A routine which is used in target vectors for unsupported
61 operations which return a pointer value. */
62
728472f1 63/*ARGSUSED*/
d0ec7a8e 64PTR
f4bd7a8f
DM
65bfd_nullvoidptr (ignore)
66 bfd *ignore;
4a81b561 67{
6812b607
ILT
68 bfd_set_error (bfd_error_invalid_operation);
69 return NULL;
4a81b561 70}
fc723380 71
728472f1 72/*ARGSUSED*/
4a81b561 73int
f4bd7a8f
DM
74bfd_0 (ignore)
75 bfd *ignore;
4a81b561
DHW
76{
77 return 0;
78}
fc723380 79
728472f1 80/*ARGSUSED*/
4a81b561 81unsigned int
f4bd7a8f
DM
82bfd_0u (ignore)
83 bfd *ignore;
4a81b561
DHW
84{
85 return 0;
86}
87
326e32d7
ILT
88/*ARGUSED*/
89long
90bfd_0l (ignore)
91 bfd *ignore;
92{
93 return 0;
94}
95
6812b607
ILT
96/* A routine which is used in target vectors for unsupported
97 operations which return -1 on error. */
98
99/*ARGSUSED*/
100long
101_bfd_n1 (ignore_abfd)
102 bfd *ignore_abfd;
103{
104 bfd_set_error (bfd_error_invalid_operation);
105 return -1;
106}
107
728472f1 108/*ARGSUSED*/
4a81b561 109void
f4bd7a8f
DM
110bfd_void (ignore)
111 bfd *ignore;
4a81b561
DHW
112{
113}
114
728472f1 115/*ARGSUSED*/
4a81b561 116boolean
6812b607 117_bfd_nocore_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd)
f4bd7a8f
DM
118 bfd *ignore_core_bfd;
119 bfd *ignore_exec_bfd;
4a81b561 120{
120f5bd9 121 bfd_set_error (bfd_error_invalid_operation);
4a81b561
DHW
122 return false;
123}
124
6812b607
ILT
125/* Routine to handle core_file_failing_command entry point for targets
126 without core file support. */
4a81b561 127
728472f1 128/*ARGSUSED*/
4a81b561 129char *
6812b607 130_bfd_nocore_core_file_failing_command (ignore_abfd)
f4bd7a8f 131 bfd *ignore_abfd;
4a81b561 132{
6812b607 133 bfd_set_error (bfd_error_invalid_operation);
4a81b561
DHW
134 return (char *)NULL;
135}
136
6812b607
ILT
137/* Routine to handle core_file_failing_signal entry point for targets
138 without core file support. */
139
728472f1 140/*ARGSUSED*/
4a81b561 141int
6812b607 142_bfd_nocore_core_file_failing_signal (ignore_abfd)
f4bd7a8f 143 bfd *ignore_abfd;
4a81b561 144{
6812b607 145 bfd_set_error (bfd_error_invalid_operation);
4a81b561
DHW
146 return 0;
147}
148
728472f1 149/*ARGSUSED*/
4fe6d901 150const bfd_target *
f4bd7a8f
DM
151_bfd_dummy_target (ignore_abfd)
152 bfd *ignore_abfd;
4a81b561 153{
4fe6d901 154 bfd_set_error (bfd_error_wrong_format);
4a81b561
DHW
155 return 0;
156}
157\f
64d5f5d0 158/* Allocate memory using malloc. */
4a81b561 159
64d5f5d0
ILT
160PTR
161bfd_malloc (size)
162 size_t size;
163{
164 PTR ptr;
4a81b561 165
64d5f5d0
ILT
166 ptr = (PTR) malloc (size);
167 if (ptr == NULL && size != 0)
168 bfd_set_error (bfd_error_no_memory);
169 return ptr;
170}
171
172/* Reallocate memory using realloc. */
173
174PTR
175bfd_realloc (ptr, size)
176 PTR ptr;
177 size_t size;
178{
179 PTR ret;
180
181 if (ptr == NULL)
182 ret = malloc (size);
183 else
184 ret = realloc (ptr, size);
185
186 if (ret == NULL)
187 bfd_set_error (bfd_error_no_memory);
188
189 return ret;
190}
191
192/* Allocate memory using malloc and clear it. */
193
194PTR
f4bd7a8f 195bfd_zmalloc (size)
64d5f5d0 196 size_t size;
4a81b561 197{
64d5f5d0
ILT
198 PTR ptr;
199
200 ptr = (PTR) malloc (size);
4a81b561 201
a9713b91
ILT
202 if (size != 0)
203 {
204 if (ptr == NULL)
205 bfd_set_error (bfd_error_no_memory);
206 else
64d5f5d0 207 memset (ptr, 0, size);
a9713b91 208 }
4a81b561
DHW
209
210 return ptr;
211}
4a81b561
DHW
212\f
213/* Some IO code */
214
215
216/* Note that archive entries don't have streams; they share their parent's.
f58809fd 217 This allows someone to play with the iostream behind BFD's back.
4a81b561
DHW
218
219 Also, note that the origin pointer points to the beginning of a file's
220 contents (0 for non-archive elements). For archive entries this is the
221 first octet in the file, NOT the beginning of the archive header. */
222
4fe6d901 223static int
f4bd7a8f
DM
224real_read (where, a,b, file)
225 PTR where;
4fe6d901
KR
226 size_t a;
227 size_t b;
f4bd7a8f 228 FILE *file;
7ed4093a 229{
4fe6d901 230 return fread (where, a, b, file);
7ed4093a 231}
f4bd7a8f 232
120f5bd9
JL
233/* Return value is amount read (FIXME: how are errors and end of file dealt
234 with? We never call bfd_set_error, which is probably a mistake). */
235
23b0b558 236bfd_size_type
f4bd7a8f
DM
237bfd_read (ptr, size, nitems, abfd)
238 PTR ptr;
239 bfd_size_type size;
240 bfd_size_type nitems;
241 bfd *abfd;
4a81b561 242{
0d552306 243 int nread;
64d5f5d0
ILT
244
245 if ((abfd->flags & BFD_IN_MEMORY) != 0)
246 {
247 struct bfd_in_memory *bim;
248 bfd_size_type get;
249
250 bim = (struct bfd_in_memory *) abfd->iostream;
251 get = size * nitems;
252 if (abfd->where + get > bim->size)
253 {
254 get = bim->size - abfd->where;
255 bfd_set_error (bfd_error_file_truncated);
256 }
257 memcpy (ptr, bim->buffer + abfd->where, get);
258 abfd->where += get;
259 return get;
260 }
261
4fe6d901 262 nread = real_read (ptr, 1, (size_t)(size*nitems), bfd_cache_lookup(abfd));
0d552306
KR
263#ifdef FILE_OFFSET_IS_CHAR_INDEX
264 if (nread > 0)
265 abfd->where += nread;
266#endif
120f5bd9
JL
267
268 /* Set bfd_error if we did not read as much data as we expected.
269
270 If the read failed due to an error set the bfd_error_system_call,
271 else set bfd_error_file_truncated.
272
273 A BFD backend may wish to override bfd_error_file_truncated to
274 provide something more useful (eg. no_symbols or wrong_format). */
275 if (nread < (int)(size * nitems))
276 {
277 if (ferror (bfd_cache_lookup (abfd)))
278 bfd_set_error (bfd_error_system_call);
279 else
280 bfd_set_error (bfd_error_file_truncated);
281 }
282
0d552306 283 return nread;
4a81b561
DHW
284}
285
4fe6d901
KR
286/* The window support stuff should probably be broken out into
287 another file.... */
288/* The idea behind the next and refcount fields is that one mapped
289 region can suffice for multiple read-only windows or multiple
290 non-overlapping read-write windows. It's not implemented yet
291 though. */
292struct _bfd_window_internal {
293 struct _bfd_window_internal *next;
294 PTR data;
295 bfd_size_type size;
296 int refcount : 31; /* should be enough... */
297 unsigned mapped : 1; /* 1 = mmap, 0 = malloc */
298};
299
300void
301bfd_init_window (windowp)
302 bfd_window *windowp;
303{
304 windowp->data = 0;
305 windowp->i = 0;
306 windowp->size = 0;
307}
308
309#undef HAVE_MPROTECT /* code's not tested yet */
310
a9713b91 311#if HAVE_MMAP || HAVE_MPROTECT || HAVE_MADVISE
4fe6d901
KR
312#include <sys/types.h>
313#include <sys/mman.h>
314#endif
315
316#ifndef MAP_FILE
317#define MAP_FILE 0
318#endif
319
320static int debug_windows;
321
a9713b91
ILT
322/* Currently, if USE_MMAP is undefined, none if the window stuff is
323 used. Okay, so it's mis-named. At least the command-line option
324 "--without-mmap" is more obvious than "--without-windows" or some
325 such. */
326#ifdef USE_MMAP
327
4fe6d901
KR
328void
329bfd_free_window (windowp)
330 bfd_window *windowp;
331{
332 bfd_window_internal *i = windowp->i;
333 windowp->i = 0;
334 windowp->data = 0;
335 if (i == 0)
336 return;
337 i->refcount--;
338 if (debug_windows)
339 fprintf (stderr, "freeing window @%p<%p,%lx,%p>\n",
340 windowp, windowp->data, windowp->size, windowp->i);
341 if (i->refcount != 0)
342 return;
343
344 if (i->mapped)
345 {
346#ifdef HAVE_MMAP
347 munmap (i->data, i->size);
348 goto no_free;
349#else
350 abort ();
351#endif
352 }
353#ifdef HAVE_MPROTECT
354 mprotect (i->data, i->size, PROT_READ | PROT_WRITE);
355#endif
356 free (i->data);
357#ifdef HAVE_MMAP
358 no_free:
359#endif
360 i->data = 0;
361 /* There should be no more references to i at this point. */
362 free (i);
363}
a9713b91 364#endif
4fe6d901
KR
365
366static int ok_to_map = 1;
367
092abcdf 368boolean
4fe6d901
KR
369bfd_get_file_window (abfd, offset, size, windowp, writable)
370 bfd *abfd;
371 file_ptr offset;
372 bfd_size_type size;
373 bfd_window *windowp;
0bb8ff19 374 boolean writable;
4fe6d901
KR
375{
376 static size_t pagesize;
377 bfd_window_internal *i = windowp->i;
378 size_t size_to_alloc = size;
379
a9713b91
ILT
380#ifndef USE_MMAP
381 abort ();
382#endif
383
4fe6d901
KR
384 if (debug_windows)
385 fprintf (stderr, "bfd_get_file_window (%p, %6ld, %6ld, %p<%p,%lx,%p>, %d)",
386 abfd, (long) offset, (long) size,
387 windowp, windowp->data, windowp->size, windowp->i,
388 writable);
389
390 /* Make sure we know the page size, so we can be friendly to mmap. */
391 if (pagesize == 0)
392 pagesize = getpagesize ();
393 if (pagesize == 0)
394 abort ();
395
396 if (i == 0)
397 {
398 windowp->i = i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
399 if (i == 0)
400 return false;
401 i->data = 0;
402 }
403#ifdef HAVE_MMAP
64d5f5d0
ILT
404 if (ok_to_map
405 && (i->data == 0 || i->mapped == 1)
406 && (abfd->flags & BFD_IN_MEMORY) == 0)
4fe6d901
KR
407 {
408 file_ptr file_offset, offset2;
409 size_t real_size;
410 int fd;
411 FILE *f;
412
413 /* Find the real file and the real offset into it. */
414 while (abfd->my_archive != NULL)
415 {
416 offset += abfd->origin;
417 abfd = abfd->my_archive;
418 }
419 f = bfd_cache_lookup (abfd);
420 fd = fileno (f);
421
422 /* Compute offsets and size for mmap and for the user's data. */
423 offset2 = offset % pagesize;
424 if (offset2 < 0)
425 abort ();
426 file_offset = offset - offset2;
427 real_size = offset + size - file_offset;
428 real_size = real_size + pagesize - 1;
429 real_size -= real_size % pagesize;
430
431 /* If we're re-using a memory region, make sure it's big enough. */
432 if (i->data && i->size < size)
433 {
434 munmap (i->data, i->size);
435 i->data = 0;
436 }
437 i->data = mmap (i->data, real_size,
438 writable ? PROT_WRITE | PROT_READ : PROT_READ,
0bb8ff19
ILT
439 (writable
440 ? MAP_FILE | MAP_PRIVATE
441 : MAP_FILE | MAP_SHARED),
4fe6d901
KR
442 fd, file_offset);
443 if (i->data == (PTR) -1)
444 {
445 /* An error happened. Report it, or try using malloc, or
446 something. */
447 bfd_set_error (bfd_error_system_call);
448 i->data = 0;
449 windowp->data = 0;
450 if (debug_windows)
451 fprintf (stderr, "\t\tmmap failed!\n");
452 return false;
453 }
454 if (debug_windows)
455 fprintf (stderr, "\n\tmapped %ld at %p, offset is %ld\n",
456 (long) real_size, i->data, (long) offset2);
457 i->size = real_size;
a9713b91 458 windowp->data = (PTR) ((bfd_byte *) i->data + offset2);
4fe6d901
KR
459 windowp->size = size;
460 i->mapped = 1;
461 return true;
462 }
463 else if (debug_windows)
464 {
465 if (ok_to_map)
3b168da4
ILT
466 fprintf (stderr, "not mapping: data=%lx mapped=%d\n",
467 (unsigned long) i->data, (int) i->mapped);
4fe6d901
KR
468 else
469 fprintf (stderr, "not mapping: env var not set\n");
470 }
471#else
472 ok_to_map = 0;
473#endif
474
475#ifdef HAVE_MPROTECT
476 if (!writable)
477 {
478 size_to_alloc += pagesize - 1;
479 size_to_alloc -= size_to_alloc % pagesize;
480 }
481#endif
482 if (debug_windows)
483 fprintf (stderr, "\n\t%s(%6ld)",
484 i->data ? "realloc" : " malloc", (long) size_to_alloc);
64d5f5d0 485 i->data = (PTR) bfd_realloc (i->data, size_to_alloc);
4fe6d901
KR
486 if (debug_windows)
487 fprintf (stderr, "\t-> %p\n", i->data);
488 i->refcount = 1;
092abcdf
ILT
489 if (i->data == NULL)
490 {
491 if (size_to_alloc == 0)
492 return true;
493 bfd_set_error (bfd_error_no_memory);
494 return false;
495 }
4fe6d901
KR
496 if (bfd_seek (abfd, offset, SEEK_SET) != 0)
497 return false;
498 i->size = bfd_read (i->data, size, 1, abfd);
499 if (i->size != size)
500 return false;
501 i->mapped = 0;
502#ifdef HAVE_MPROTECT
503 if (!writable)
504 {
505 if (debug_windows)
506 fprintf (stderr, "\tmprotect (%p, %ld, PROT_READ)\n", i->data,
507 (long) i->size);
508 mprotect (i->data, i->size, PROT_READ);
509 }
510#endif
511 windowp->data = i->data;
512 windowp->size = i->size;
513 return true;
514}
515
23b0b558 516bfd_size_type
df34342b
ILT
517bfd_write (ptr, size, nitems, abfd)
518 CONST PTR ptr;
519 bfd_size_type size;
520 bfd_size_type nitems;
521 bfd *abfd;
4a81b561 522{
64d5f5d0
ILT
523 long nwrote;
524
525 if ((abfd->flags & BFD_IN_MEMORY) != 0)
526 abort ();
527
528 nwrote = fwrite (ptr, 1, (size_t) (size * nitems),
529 bfd_cache_lookup (abfd));
0d552306
KR
530#ifdef FILE_OFFSET_IS_CHAR_INDEX
531 if (nwrote > 0)
532 abfd->where += nwrote;
533#endif
4fe6d901 534 if ((bfd_size_type) nwrote != size * nitems)
df34342b
ILT
535 {
536#ifdef ENOSPC
537 if (nwrote >= 0)
538 errno = ENOSPC;
539#endif
120f5bd9 540 bfd_set_error (bfd_error_system_call);
df34342b 541 }
0d552306 542 return nwrote;
4a81b561
DHW
543}
544
f8e01940
JG
545/*
546INTERNAL_FUNCTION
547 bfd_write_bigendian_4byte_int
548
549SYNOPSIS
550 void bfd_write_bigendian_4byte_int(bfd *abfd, int i);
551
552DESCRIPTION
c188b0be
DM
553 Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
554 endian order regardless of what else is going on. This is useful in
f8e01940 555 archives.
1e310759 556
1e310759 557*/
f58809fd 558void
f4bd7a8f
DM
559bfd_write_bigendian_4byte_int (abfd, i)
560 bfd *abfd;
561 int i;
f58809fd 562{
1e310759 563 bfd_byte buffer[4];
b5b4294e 564 bfd_putb32(i, buffer);
4002f18a
ILT
565 if (bfd_write((PTR)buffer, 4, 1, abfd) != 4)
566 abort ();
f58809fd
SC
567}
568
0d552306 569long
f4bd7a8f
DM
570bfd_tell (abfd)
571 bfd *abfd;
0d552306
KR
572{
573 file_ptr ptr;
574
64d5f5d0
ILT
575 if ((abfd->flags & BFD_IN_MEMORY) != 0)
576 return abfd->where;
577
0d552306
KR
578 ptr = ftell (bfd_cache_lookup(abfd));
579
580 if (abfd->my_archive)
581 ptr -= abfd->origin;
582 abfd->where = ptr;
583 return ptr;
584}
585
b5b4294e 586int
f4bd7a8f
DM
587bfd_flush (abfd)
588 bfd *abfd;
b5b4294e 589{
64d5f5d0
ILT
590 if ((abfd->flags & BFD_IN_MEMORY) != 0)
591 return 0;
b5b4294e
JG
592 return fflush (bfd_cache_lookup(abfd));
593}
594
4fe6d901
KR
595/* Returns 0 for success, negative value for failure (in which case
596 bfd_get_error can retrieve the error code). */
b5b4294e 597int
f4bd7a8f
DM
598bfd_stat (abfd, statbuf)
599 bfd *abfd;
600 struct stat *statbuf;
b5b4294e 601{
4fe6d901
KR
602 FILE *f;
603 int result;
64d5f5d0
ILT
604
605 if ((abfd->flags & BFD_IN_MEMORY) != 0)
606 abort ();
607
4fe6d901
KR
608 f = bfd_cache_lookup (abfd);
609 if (f == NULL)
610 {
611 bfd_set_error (bfd_error_system_call);
612 return -1;
613 }
614 result = fstat (fileno (f), statbuf);
615 if (result < 0)
616 bfd_set_error (bfd_error_system_call);
617 return result;
b5b4294e
JG
618}
619
120f5bd9
JL
620/* Returns 0 for success, nonzero for failure (in which case bfd_get_error
621 can retrieve the error code). */
622
4a81b561 623int
f4bd7a8f 624bfd_seek (abfd, position, direction)
4fe6d901
KR
625 bfd *abfd;
626 file_ptr position;
627 int direction;
4a81b561 628{
0d552306
KR
629 int result;
630 FILE *f;
e5b02860 631 file_ptr file_position;
0d552306
KR
632 /* For the time being, a BFD may not seek to it's end. The problem
633 is that we don't easily have a way to recognize the end of an
634 element in an archive. */
635
636 BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
637
b31d06ca 638 if (direction == SEEK_CUR && position == 0)
0d552306 639 return 0;
64d5f5d0
ILT
640
641 if ((abfd->flags & BFD_IN_MEMORY) != 0)
642 {
643 if (direction == SEEK_SET)
644 abfd->where = position;
645 else
646 abfd->where += position;
647 return 0;
648 }
649
0d552306 650#ifdef FILE_OFFSET_IS_CHAR_INDEX
b6090f4d
JG
651 if (abfd->format != bfd_archive && abfd->my_archive == 0)
652 {
4c3721d5 653#if 0
b6090f4d
JG
654 /* Explanation for this code: I'm only about 95+% sure that the above
655 conditions are sufficient and that all i/o calls are properly
656 adjusting the `where' field. So this is sort of an `assert'
657 that the `where' field is correct. If we can go a while without
658 tripping the abort, we can probably safely disable this code,
659 so that the real optimizations happen. */
660 file_ptr where_am_i_now;
661 where_am_i_now = ftell (bfd_cache_lookup (abfd));
662 if (abfd->my_archive)
663 where_am_i_now -= abfd->origin;
664 if (where_am_i_now != abfd->where)
665 abort ();
666#endif
667 if (direction == SEEK_SET && position == abfd->where)
668 return 0;
669 }
670 else
671 {
672 /* We need something smarter to optimize access to archives.
673 Currently, anything inside an archive is read via the file
674 handle for the archive. Which means that a bfd_seek on one
675 component affects the `current position' in the archive, as
676 well as in any other component.
677
678 It might be sufficient to put a spike through the cache
679 abstraction, and look to the archive for the file position,
680 but I think we should try for something cleaner.
681
682 In the meantime, no optimization for archives. */
683 }
0d552306 684#endif
4a81b561 685
0d552306 686 f = bfd_cache_lookup (abfd);
e5b02860 687 file_position = position;
0d552306 688 if (direction == SEEK_SET && abfd->my_archive != NULL)
e5b02860
KR
689 file_position += abfd->origin;
690
691 result = fseek (f, file_position, direction);
692
693 if (result != 0)
df34342b
ILT
694 {
695 /* Force redetermination of `where' field. */
696 bfd_tell (abfd);
120f5bd9 697 bfd_set_error (bfd_error_system_call);
df34342b 698 }
0d552306
KR
699 else
700 {
e5b02860
KR
701#ifdef FILE_OFFSET_IS_CHAR_INDEX
702 /* Adjust `where' field. */
703 if (direction == SEEK_SET)
704 abfd->where = position;
705 else
706 abfd->where += position;
707#endif
0d552306 708 }
e5b02860 709 return result;
4a81b561
DHW
710}
711\f
4a81b561
DHW
712/** The do-it-yourself (byte) sex-change kit */
713
714/* The middle letter e.g. get<b>short indicates Big or Little endian
715 target machine. It doesn't matter what the byte order of the host
716 machine is; these routines work for either. */
717
718/* FIXME: Should these take a count argument?
719 Answer (gnu@cygnus.com): No, but perhaps they should be inline
6f715d66
SC
720 functions in swap.h #ifdef __GNUC__.
721 Gprof them later and find out. */
722
f8e01940
JG
723/*
724FUNCTION
725 bfd_put_size
726FUNCTION
727 bfd_get_size
728
729DESCRIPTION
730 These macros as used for reading and writing raw data in
731 sections; each access (except for bytes) is vectored through
732 the target format of the BFD and mangled accordingly. The
733 mangling performs any necessary endian translations and
14e3c2e4
JK
734 removes alignment restrictions. Note that types accepted and
735 returned by these macros are identical so they can be swapped
17ecba1a
DM
736 around in macros---for example, @file{libaout.h} defines <<GET_WORD>>
737 to either <<bfd_get_32>> or <<bfd_get_64>>.
f8e01940 738
17ecba1a 739 In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a
7e4db254
JK
740 system without prototypes, the caller is responsible for making
741 sure that is true, with a cast if necessary. We don't cast
17ecba1a
DM
742 them in the macro definitions because that would prevent <<lint>>
743 or <<gcc -Wall>> from detecting sins such as passing a pointer.
744 To detect calling these with less than a <<bfd_vma>>, use
745 <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s.
7e4db254 746
da3cd00a
KR
747.
748.{* Byte swapping macros for user section data. *}
749.
f8e01940 750.#define bfd_put_8(abfd, val, ptr) \
4c3721d5 751. (*((unsigned char *)(ptr)) = (unsigned char)(val))
da3cd00a
KR
752.#define bfd_put_signed_8 \
753. bfd_put_8
f8e01940 754.#define bfd_get_8(abfd, ptr) \
da3cd00a
KR
755. (*(unsigned char *)(ptr))
756.#define bfd_get_signed_8(abfd, ptr) \
757. ((*(unsigned char *)(ptr) ^ 0x80) - 0x80)
758.
f8e01940 759.#define bfd_put_16(abfd, val, ptr) \
7e4db254 760. BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
da3cd00a
KR
761.#define bfd_put_signed_16 \
762. bfd_put_16
f8e01940
JG
763.#define bfd_get_16(abfd, ptr) \
764. BFD_SEND(abfd, bfd_getx16, (ptr))
14e3c2e4
JK
765.#define bfd_get_signed_16(abfd, ptr) \
766. BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
da3cd00a 767.
f8e01940 768.#define bfd_put_32(abfd, val, ptr) \
7e4db254 769. BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
da3cd00a
KR
770.#define bfd_put_signed_32 \
771. bfd_put_32
f8e01940
JG
772.#define bfd_get_32(abfd, ptr) \
773. BFD_SEND(abfd, bfd_getx32, (ptr))
14e3c2e4
JK
774.#define bfd_get_signed_32(abfd, ptr) \
775. BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
da3cd00a 776.
f8e01940 777.#define bfd_put_64(abfd, val, ptr) \
7e4db254 778. BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
da3cd00a
KR
779.#define bfd_put_signed_64 \
780. bfd_put_64
f8e01940
JG
781.#define bfd_get_64(abfd, ptr) \
782. BFD_SEND(abfd, bfd_getx64, (ptr))
14e3c2e4
JK
783.#define bfd_get_signed_64(abfd, ptr) \
784. BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
da3cd00a 785.
f8e01940
JG
786*/
787
788/*
789FUNCTION
790 bfd_h_put_size
f8e01940
JG
791 bfd_h_get_size
792
793DESCRIPTION
794 These macros have the same function as their <<bfd_get_x>>
c188b0be 795 bretheren, except that they are used for removing information
f8e01940
JG
796 for the header records of object files. Believe it or not,
797 some object files keep their header records in big endian
c188b0be 798 order and their data in little endian order.
da3cd00a
KR
799.
800.{* Byte swapping macros for file header data. *}
801.
f8e01940 802.#define bfd_h_put_8(abfd, val, ptr) \
da3cd00a
KR
803. bfd_put_8 (abfd, val, ptr)
804.#define bfd_h_put_signed_8(abfd, val, ptr) \
805. bfd_put_8 (abfd, val, ptr)
f8e01940 806.#define bfd_h_get_8(abfd, ptr) \
da3cd00a
KR
807. bfd_get_8 (abfd, ptr)
808.#define bfd_h_get_signed_8(abfd, ptr) \
809. bfd_get_signed_8 (abfd, ptr)
810.
f8e01940
JG
811.#define bfd_h_put_16(abfd, val, ptr) \
812. BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
da3cd00a
KR
813.#define bfd_h_put_signed_16 \
814. bfd_h_put_16
f8e01940
JG
815.#define bfd_h_get_16(abfd, ptr) \
816. BFD_SEND(abfd, bfd_h_getx16,(ptr))
14e3c2e4
JK
817.#define bfd_h_get_signed_16(abfd, ptr) \
818. BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
da3cd00a 819.
f8e01940
JG
820.#define bfd_h_put_32(abfd, val, ptr) \
821. BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
da3cd00a
KR
822.#define bfd_h_put_signed_32 \
823. bfd_h_put_32
f8e01940
JG
824.#define bfd_h_get_32(abfd, ptr) \
825. BFD_SEND(abfd, bfd_h_getx32,(ptr))
14e3c2e4
JK
826.#define bfd_h_get_signed_32(abfd, ptr) \
827. BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
da3cd00a 828.
f8e01940
JG
829.#define bfd_h_put_64(abfd, val, ptr) \
830. BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
da3cd00a
KR
831.#define bfd_h_put_signed_64 \
832. bfd_h_put_64
f8e01940
JG
833.#define bfd_h_get_64(abfd, ptr) \
834. BFD_SEND(abfd, bfd_h_getx64,(ptr))
14e3c2e4
JK
835.#define bfd_h_get_signed_64(abfd, ptr) \
836. BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
da3cd00a 837.
f8e01940 838*/
4a81b561 839
14e3c2e4 840/* Sign extension to bfd_signed_vma. */
df34342b
ILT
841#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
842#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
96ad107b 843#define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32)
df34342b
ILT
844#define COERCE64(x) \
845 (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
14e3c2e4 846
f58809fd 847bfd_vma
f4bd7a8f
DM
848bfd_getb16 (addr)
849 register const bfd_byte *addr;
4a81b561 850{
f4bd7a8f 851 return (addr[0] << 8) | addr[1];
4a81b561
DHW
852}
853
f58809fd 854bfd_vma
f4bd7a8f
DM
855bfd_getl16 (addr)
856 register const bfd_byte *addr;
4a81b561 857{
f4bd7a8f 858 return (addr[1] << 8) | addr[0];
4a81b561
DHW
859}
860
14e3c2e4 861bfd_signed_vma
f4bd7a8f
DM
862bfd_getb_signed_16 (addr)
863 register const bfd_byte *addr;
14e3c2e4 864{
f4bd7a8f 865 return COERCE16((addr[0] << 8) | addr[1]);
14e3c2e4
JK
866}
867
868bfd_signed_vma
f4bd7a8f
DM
869bfd_getl_signed_16 (addr)
870 register const bfd_byte *addr;
14e3c2e4 871{
f4bd7a8f 872 return COERCE16((addr[1] << 8) | addr[0]);
14e3c2e4
JK
873}
874
4a81b561 875void
f4bd7a8f
DM
876bfd_putb16 (data, addr)
877 bfd_vma data;
878 register bfd_byte *addr;
4a81b561 879{
f4bd7a8f
DM
880 addr[0] = (bfd_byte)(data >> 8);
881 addr[1] = (bfd_byte )data;
4a81b561
DHW
882}
883
884void
f4bd7a8f
DM
885bfd_putl16 (data, addr)
886 bfd_vma data;
887 register bfd_byte *addr;
4a81b561 888{
f4bd7a8f
DM
889 addr[0] = (bfd_byte )data;
890 addr[1] = (bfd_byte)(data >> 8);
4a81b561
DHW
891}
892
f58809fd 893bfd_vma
b5b4294e 894bfd_getb32 (addr)
f4bd7a8f 895 register const bfd_byte *addr;
4a81b561 896{
f4bd7a8f
DM
897 return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
898 | addr[2]) << 8 | addr[3];
4a81b561
DHW
899}
900
f58809fd 901bfd_vma
b5b4294e 902bfd_getl32 (addr)
f4bd7a8f 903 register const bfd_byte *addr;
4a81b561 904{
f4bd7a8f
DM
905 return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
906 | addr[1]) << 8 | addr[0];
4a81b561
DHW
907}
908
14e3c2e4 909bfd_signed_vma
b5b4294e 910bfd_getb_signed_32 (addr)
f4bd7a8f 911 register const bfd_byte *addr;
14e3c2e4 912{
f4bd7a8f
DM
913 return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
914 | addr[2]) << 8 | addr[3]);
14e3c2e4
JK
915}
916
917bfd_signed_vma
b5b4294e 918bfd_getl_signed_32 (addr)
f4bd7a8f 919 register const bfd_byte *addr;
14e3c2e4 920{
f4bd7a8f
DM
921 return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
922 | addr[1]) << 8 | addr[0]);
14e3c2e4
JK
923}
924
f58809fd 925bfd_vma
f4bd7a8f
DM
926bfd_getb64 (addr)
927 register const bfd_byte *addr;
7ed4093a 928{
b5b4294e 929#ifdef BFD64
b6090f4d 930 bfd_vma low, high;
536b27a5 931
7ed4093a 932 high= ((((((((addr[0]) << 8) |
6f715d66
SC
933 addr[1]) << 8) |
934 addr[2]) << 8) |
935 addr[3]) );
7ed4093a 936
df34342b 937 low = (((((((((bfd_vma)addr[4]) << 8) |
6f715d66
SC
938 addr[5]) << 8) |
939 addr[6]) << 8) |
940 addr[7]));
7ed4093a
SC
941
942 return high << 32 | low;
943#else
944 BFD_FAIL();
f58809fd 945 return 0;
7ed4093a 946#endif
7ed4093a
SC
947}
948
f58809fd 949bfd_vma
f4bd7a8f
DM
950bfd_getl64 (addr)
951 register const bfd_byte *addr;
7ed4093a 952{
b5b4294e 953#ifdef BFD64
b6090f4d 954 bfd_vma low, high;
7ed4093a 955 high= (((((((addr[7] << 8) |
6f715d66
SC
956 addr[6]) << 8) |
957 addr[5]) << 8) |
958 addr[4]));
7ed4093a 959
df34342b 960 low = ((((((((bfd_vma)addr[3] << 8) |
6f715d66
SC
961 addr[2]) << 8) |
962 addr[1]) << 8) |
963 addr[0]) );
7ed4093a
SC
964
965 return high << 32 | low;
966#else
967 BFD_FAIL();
f58809fd 968 return 0;
7ed4093a 969#endif
6f715d66 970
7ed4093a
SC
971}
972
14e3c2e4 973bfd_signed_vma
f4bd7a8f
DM
974bfd_getb_signed_64 (addr)
975 register const bfd_byte *addr;
14e3c2e4 976{
b5b4294e 977#ifdef BFD64
14e3c2e4
JK
978 bfd_vma low, high;
979
980 high= ((((((((addr[0]) << 8) |
981 addr[1]) << 8) |
982 addr[2]) << 8) |
983 addr[3]) );
984
df34342b 985 low = (((((((((bfd_vma)addr[4]) << 8) |
14e3c2e4
JK
986 addr[5]) << 8) |
987 addr[6]) << 8) |
988 addr[7]));
989
990 return COERCE64(high << 32 | low);
991#else
992 BFD_FAIL();
993 return 0;
994#endif
14e3c2e4
JK
995}
996
997bfd_signed_vma
f4bd7a8f
DM
998bfd_getl_signed_64 (addr)
999 register const bfd_byte *addr;
14e3c2e4 1000{
b5b4294e 1001#ifdef BFD64
14e3c2e4
JK
1002 bfd_vma low, high;
1003 high= (((((((addr[7] << 8) |
1004 addr[6]) << 8) |
1005 addr[5]) << 8) |
1006 addr[4]));
1007
df34342b 1008 low = ((((((((bfd_vma)addr[3] << 8) |
14e3c2e4
JK
1009 addr[2]) << 8) |
1010 addr[1]) << 8) |
1011 addr[0]) );
1012
1013 return COERCE64(high << 32 | low);
1014#else
1015 BFD_FAIL();
1016 return 0;
1017#endif
14e3c2e4
JK
1018}
1019
4a81b561 1020void
f4bd7a8f
DM
1021bfd_putb32 (data, addr)
1022 bfd_vma data;
1023 register bfd_byte *addr;
4a81b561 1024{
6f715d66
SC
1025 addr[0] = (bfd_byte)(data >> 24);
1026 addr[1] = (bfd_byte)(data >> 16);
1027 addr[2] = (bfd_byte)(data >> 8);
1028 addr[3] = (bfd_byte)data;
4a81b561
DHW
1029}
1030
1031void
f4bd7a8f
DM
1032bfd_putl32 (data, addr)
1033 bfd_vma data;
1034 register bfd_byte *addr;
4a81b561 1035{
6f715d66
SC
1036 addr[0] = (bfd_byte)data;
1037 addr[1] = (bfd_byte)(data >> 8);
1038 addr[2] = (bfd_byte)(data >> 16);
1039 addr[3] = (bfd_byte)(data >> 24);
4a81b561 1040}
f4bd7a8f 1041
7ed4093a 1042void
f4bd7a8f
DM
1043bfd_putb64 (data, addr)
1044 bfd_vma data;
1045 register bfd_byte *addr;
7ed4093a 1046{
b5b4294e 1047#ifdef BFD64
536b27a5
SC
1048 addr[0] = (bfd_byte)(data >> (7*8));
1049 addr[1] = (bfd_byte)(data >> (6*8));
1050 addr[2] = (bfd_byte)(data >> (5*8));
1051 addr[3] = (bfd_byte)(data >> (4*8));
1052 addr[4] = (bfd_byte)(data >> (3*8));
1053 addr[5] = (bfd_byte)(data >> (2*8));
1054 addr[6] = (bfd_byte)(data >> (1*8));
1055 addr[7] = (bfd_byte)(data >> (0*8));
7ed4093a 1056#else
536b27a5 1057 BFD_FAIL();
7ed4093a 1058#endif
7ed4093a
SC
1059}
1060
1061void
f4bd7a8f
DM
1062bfd_putl64 (data, addr)
1063 bfd_vma data;
1064 register bfd_byte *addr;
7ed4093a 1065{
b5b4294e 1066#ifdef BFD64
536b27a5
SC
1067 addr[7] = (bfd_byte)(data >> (7*8));
1068 addr[6] = (bfd_byte)(data >> (6*8));
1069 addr[5] = (bfd_byte)(data >> (5*8));
1070 addr[4] = (bfd_byte)(data >> (4*8));
1071 addr[3] = (bfd_byte)(data >> (3*8));
1072 addr[2] = (bfd_byte)(data >> (2*8));
1073 addr[1] = (bfd_byte)(data >> (1*8));
1074 addr[0] = (bfd_byte)(data >> (0*8));
7ed4093a 1075#else
536b27a5 1076 BFD_FAIL();
7ed4093a 1077#endif
7ed4093a 1078}
2203f786
JG
1079\f
1080/* Default implementation */
4a81b561 1081
2203f786 1082boolean
6812b607 1083_bfd_generic_get_section_contents (abfd, section, location, offset, count)
f4bd7a8f
DM
1084 bfd *abfd;
1085 sec_ptr section;
1086 PTR location;
1087 file_ptr offset;
1088 bfd_size_type count;
2203f786
JG
1089{
1090 if (count == 0)
6f715d66 1091 return true;
f8e01940
JG
1092 if ((bfd_size_type)(offset+count) > section->_raw_size
1093 || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
6f715d66
SC
1094 || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
1095 return (false); /* on error */
2203f786
JG
1096 return (true);
1097}
6f715d66 1098
4fe6d901
KR
1099boolean
1100_bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count)
1101 bfd *abfd;
1102 sec_ptr section;
1103 bfd_window *w;
1104 file_ptr offset;
1105 bfd_size_type count;
1106{
a9713b91 1107#ifdef USE_MMAP
4fe6d901
KR
1108 if (count == 0)
1109 return true;
1110 if (abfd->xvec->_bfd_get_section_contents != _bfd_generic_get_section_contents)
1111 {
1112 /* We don't know what changes the bfd's get_section_contents
1113 method may have to make. So punt trying to map the file
1114 window, and let get_section_contents do its thing. */
1115 /* @@ FIXME : If the internal window has a refcount of 1 and was
1116 allocated with malloc instead of mmap, just reuse it. */
1117 bfd_free_window (w);
1118 w->i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
1119 if (w->i == NULL)
1120 return false;
64d5f5d0 1121 w->i->data = (PTR) bfd_malloc ((size_t) count);
4fe6d901
KR
1122 if (w->i->data == NULL)
1123 {
1124 free (w->i);
1125 w->i = NULL;
1126 return false;
1127 }
1128 w->i->mapped = 0;
1129 w->i->refcount = 1;
1130 w->size = w->i->size = count;
1131 w->data = w->i->data;
1132 return bfd_get_section_contents (abfd, section, w->data, offset, count);
1133 }
1134 if ((bfd_size_type) (offset+count) > section->_raw_size
0bb8ff19 1135 || (bfd_get_file_window (abfd, section->filepos + offset, count, w, true)
4fe6d901
KR
1136 == false))
1137 return false;
1138 return true;
a9713b91
ILT
1139#else
1140 abort ();
1141#endif
4fe6d901
KR
1142}
1143
f58809fd
SC
1144/* This generic function can only be used in implementations where creating
1145 NEW sections is disallowed. It is useful in patching existing sections
1146 in read-write files, though. See other set_section_contents functions
1147 to see why it doesn't work for new sections. */
1148boolean
6812b607 1149_bfd_generic_set_section_contents (abfd, section, location, offset, count)
df34342b
ILT
1150 bfd *abfd;
1151 sec_ptr section;
1152 PTR location;
1153 file_ptr offset;
1154 bfd_size_type count;
f58809fd 1155{
df34342b
ILT
1156 if (count == 0)
1157 return true;
1158
df34342b
ILT
1159 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) == -1
1160 || bfd_write (location, (bfd_size_type) 1, count, abfd) != count)
1161 return false;
1162
1163 return true;
f58809fd
SC
1164}
1165
f8e01940
JG
1166/*
1167INTERNAL_FUNCTION
1168 bfd_log2
1169
17ecba1a
DM
1170SYNOPSIS
1171 unsigned int bfd_log2(bfd_vma x);
1172
f8e01940 1173DESCRIPTION
c188b0be
DM
1174 Return the log base 2 of the value supplied, rounded up. E.g., an
1175 @var{x} of 1025 returns 11.
f8e01940 1176*/
6f715d66 1177
b5b4294e
JG
1178unsigned
1179bfd_log2(x)
1180 bfd_vma x;
6f715d66 1181{
b5b4294e 1182 unsigned result = 0;
6f715d66
SC
1183 while ( (bfd_vma)(1<< result) < x)
1184 result++;
1185 return result;
1186}
120f5bd9
JL
1187
1188boolean
1189bfd_generic_is_local_label (abfd, sym)
1190 bfd *abfd;
1191 asymbol *sym;
1192{
1193 char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
1194
1195 return (sym->name[0] == locals_prefix);
1196}
1197
This page took 0.3814 seconds and 4 git commands to generate.