Wed Mar 30 16:25:41 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
[deliverable/binutils-gdb.git] / bfd / libbfd.c
1 /* Assorted BFD support routines, only used internally.
2 Copyright 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
3 Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24
25 /*
26 SECTION
27 Internal functions
28
29 DESCRIPTION
30 These routines are used within BFD.
31 They are not intended for export, but are documented here for
32 completeness.
33 */
34
35 /*ARGSUSED*/
36 boolean
37 _bfd_dummy_new_section_hook (ignore, ignore_newsect)
38 bfd *ignore;
39 asection *ignore_newsect;
40 {
41 return true;
42 }
43
44 /*ARGSUSED*/
45 boolean
46 bfd_false (ignore)
47 bfd *ignore;
48 {
49 return false;
50 }
51
52 /*ARGSUSED*/
53 boolean
54 bfd_true (ignore)
55 bfd *ignore;
56 {
57 return true;
58 }
59
60 /*ARGSUSED*/
61 PTR
62 bfd_nullvoidptr (ignore)
63 bfd *ignore;
64 {
65 return (PTR)NULL;
66 }
67
68 /*ARGSUSED*/
69 int
70 bfd_0 (ignore)
71 bfd *ignore;
72 {
73 return 0;
74 }
75
76 /*ARGSUSED*/
77 unsigned int
78 bfd_0u (ignore)
79 bfd *ignore;
80 {
81 return 0;
82 }
83
84 /*ARGUSED*/
85 long
86 bfd_0l (ignore)
87 bfd *ignore;
88 {
89 return 0;
90 }
91
92 /*ARGSUSED*/
93 void
94 bfd_void (ignore)
95 bfd *ignore;
96 {
97 }
98
99 /*ARGSUSED*/
100 boolean
101 _bfd_dummy_core_file_matches_executable_p (ignore_core_bfd, ignore_exec_bfd)
102 bfd *ignore_core_bfd;
103 bfd *ignore_exec_bfd;
104 {
105 bfd_set_error (bfd_error_invalid_operation);
106 return false;
107 }
108
109 /* of course you can't initialize a function to be the same as another, grr */
110
111 /*ARGSUSED*/
112 char *
113 _bfd_dummy_core_file_failing_command (ignore_abfd)
114 bfd *ignore_abfd;
115 {
116 return (char *)NULL;
117 }
118
119 /*ARGSUSED*/
120 int
121 _bfd_dummy_core_file_failing_signal (ignore_abfd)
122 bfd *ignore_abfd;
123 {
124 return 0;
125 }
126
127 /*ARGSUSED*/
128 bfd_target *
129 _bfd_dummy_target (ignore_abfd)
130 bfd *ignore_abfd;
131 {
132 return 0;
133 }
134 \f
135
136 #ifndef bfd_zmalloc
137 /* allocate and clear storage */
138
139 char *
140 bfd_zmalloc (size)
141 bfd_size_type size;
142 {
143 char *ptr = (char *) malloc ((size_t) size);
144
145 if (ptr && size)
146 memset(ptr, 0, (size_t) size);
147
148 return ptr;
149 }
150 #endif /* bfd_zmalloc */
151 \f
152 /* Some IO code */
153
154
155 /* Note that archive entries don't have streams; they share their parent's.
156 This allows someone to play with the iostream behind BFD's back.
157
158 Also, note that the origin pointer points to the beginning of a file's
159 contents (0 for non-archive elements). For archive entries this is the
160 first octet in the file, NOT the beginning of the archive header. */
161
162 static
163 int
164 real_read (where, a,b, file)
165 PTR where;
166 int a;
167 int b;
168 FILE *file;
169 {
170 return fread(where, a,b,file);
171 }
172
173 /* Return value is amount read (FIXME: how are errors and end of file dealt
174 with? We never call bfd_set_error, which is probably a mistake). */
175
176 bfd_size_type
177 bfd_read (ptr, size, nitems, abfd)
178 PTR ptr;
179 bfd_size_type size;
180 bfd_size_type nitems;
181 bfd *abfd;
182 {
183 int nread;
184 nread = real_read (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
185 #ifdef FILE_OFFSET_IS_CHAR_INDEX
186 if (nread > 0)
187 abfd->where += nread;
188 #endif
189
190 /* Set bfd_error if we did not read as much data as we expected.
191
192 If the read failed due to an error set the bfd_error_system_call,
193 else set bfd_error_file_truncated.
194
195 A BFD backend may wish to override bfd_error_file_truncated to
196 provide something more useful (eg. no_symbols or wrong_format). */
197 if (nread < (int)(size * nitems))
198 {
199 if (ferror (bfd_cache_lookup (abfd)))
200 bfd_set_error (bfd_error_system_call);
201 else
202 bfd_set_error (bfd_error_file_truncated);
203 }
204
205 return nread;
206 }
207
208 bfd_size_type
209 bfd_write (ptr, size, nitems, abfd)
210 CONST PTR ptr;
211 bfd_size_type size;
212 bfd_size_type nitems;
213 bfd *abfd;
214 {
215 int nwrote = fwrite (ptr, 1, (int) (size * nitems), bfd_cache_lookup (abfd));
216 #ifdef FILE_OFFSET_IS_CHAR_INDEX
217 if (nwrote > 0)
218 abfd->where += nwrote;
219 #endif
220 if (nwrote != size * nitems)
221 {
222 #ifdef ENOSPC
223 if (nwrote >= 0)
224 errno = ENOSPC;
225 #endif
226 bfd_set_error (bfd_error_system_call);
227 }
228 return nwrote;
229 }
230
231 /*
232 INTERNAL_FUNCTION
233 bfd_write_bigendian_4byte_int
234
235 SYNOPSIS
236 void bfd_write_bigendian_4byte_int(bfd *abfd, int i);
237
238 DESCRIPTION
239 Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big
240 endian order regardless of what else is going on. This is useful in
241 archives.
242
243 */
244 void
245 bfd_write_bigendian_4byte_int (abfd, i)
246 bfd *abfd;
247 int i;
248 {
249 bfd_byte buffer[4];
250 bfd_putb32(i, buffer);
251 bfd_write((PTR)buffer, 4, 1, abfd);
252 }
253
254 long
255 bfd_tell (abfd)
256 bfd *abfd;
257 {
258 file_ptr ptr;
259
260 ptr = ftell (bfd_cache_lookup(abfd));
261
262 if (abfd->my_archive)
263 ptr -= abfd->origin;
264 abfd->where = ptr;
265 return ptr;
266 }
267
268 int
269 bfd_flush (abfd)
270 bfd *abfd;
271 {
272 return fflush (bfd_cache_lookup(abfd));
273 }
274
275 int
276 bfd_stat (abfd, statbuf)
277 bfd *abfd;
278 struct stat *statbuf;
279 {
280 return fstat (fileno(bfd_cache_lookup(abfd)), statbuf);
281 }
282
283 /* Returns 0 for success, nonzero for failure (in which case bfd_get_error
284 can retrieve the error code). */
285
286 int
287 bfd_seek (abfd, position, direction)
288 bfd * CONST abfd;
289 CONST file_ptr position;
290 CONST int direction;
291 {
292 int result;
293 FILE *f;
294 file_ptr file_position;
295 /* For the time being, a BFD may not seek to it's end. The problem
296 is that we don't easily have a way to recognize the end of an
297 element in an archive. */
298
299 BFD_ASSERT (direction == SEEK_SET || direction == SEEK_CUR);
300
301 if (direction == SEEK_CUR && position == 0)
302 return 0;
303 #ifdef FILE_OFFSET_IS_CHAR_INDEX
304 if (abfd->format != bfd_archive && abfd->my_archive == 0)
305 {
306 #if 0
307 /* Explanation for this code: I'm only about 95+% sure that the above
308 conditions are sufficient and that all i/o calls are properly
309 adjusting the `where' field. So this is sort of an `assert'
310 that the `where' field is correct. If we can go a while without
311 tripping the abort, we can probably safely disable this code,
312 so that the real optimizations happen. */
313 file_ptr where_am_i_now;
314 where_am_i_now = ftell (bfd_cache_lookup (abfd));
315 if (abfd->my_archive)
316 where_am_i_now -= abfd->origin;
317 if (where_am_i_now != abfd->where)
318 abort ();
319 #endif
320 if (direction == SEEK_SET && position == abfd->where)
321 return 0;
322 }
323 else
324 {
325 /* We need something smarter to optimize access to archives.
326 Currently, anything inside an archive is read via the file
327 handle for the archive. Which means that a bfd_seek on one
328 component affects the `current position' in the archive, as
329 well as in any other component.
330
331 It might be sufficient to put a spike through the cache
332 abstraction, and look to the archive for the file position,
333 but I think we should try for something cleaner.
334
335 In the meantime, no optimization for archives. */
336 }
337 #endif
338
339 f = bfd_cache_lookup (abfd);
340 file_position = position;
341 if (direction == SEEK_SET && abfd->my_archive != NULL)
342 file_position += abfd->origin;
343
344 result = fseek (f, file_position, direction);
345
346 if (result != 0)
347 {
348 /* Force redetermination of `where' field. */
349 bfd_tell (abfd);
350 bfd_set_error (bfd_error_system_call);
351 }
352 else
353 {
354 #ifdef FILE_OFFSET_IS_CHAR_INDEX
355 /* Adjust `where' field. */
356 if (direction == SEEK_SET)
357 abfd->where = position;
358 else
359 abfd->where += position;
360 #endif
361 }
362 return result;
363 }
364 \f
365 /** Make a string table */
366
367 /*>bfd.h<
368 Add string to table pointed to by table, at location starting with free_ptr.
369 resizes the table if necessary (if it's NULL, creates it, ignoring
370 table_length). Updates free_ptr, table, table_length */
371
372 boolean
373 bfd_add_to_string_table (table, new_string, table_length, free_ptr)
374 char **table;
375 char *new_string;
376 unsigned int *table_length;
377 char **free_ptr;
378 {
379 size_t string_length = strlen (new_string) + 1; /* include null here */
380 char *base = *table;
381 size_t space_length = *table_length;
382 unsigned int offset = (base ? *free_ptr - base : 0);
383
384 if (base == NULL) {
385 /* Avoid a useless regrow if we can (but of course we still
386 take it next time). */
387 space_length = (string_length < DEFAULT_STRING_SPACE_SIZE ?
388 DEFAULT_STRING_SPACE_SIZE : string_length+1);
389 base = bfd_zmalloc ((bfd_size_type) space_length);
390
391 if (base == NULL) {
392 bfd_set_error (bfd_error_no_memory);
393 return false;
394 }
395 }
396
397 if ((size_t)(offset + string_length) >= space_length) {
398 /* Make sure we will have enough space */
399 while ((size_t)(offset + string_length) >= space_length)
400 space_length += space_length/2; /* grow by 50% */
401
402 base = (char *) realloc (base, space_length);
403 if (base == NULL) {
404 bfd_set_error (bfd_error_no_memory);
405 return false;
406 }
407
408 }
409
410 memcpy (base + offset, new_string, string_length);
411 *table = base;
412 *table_length = space_length;
413 *free_ptr = base + offset + string_length;
414
415 return true;
416 }
417 \f
418 /** The do-it-yourself (byte) sex-change kit */
419
420 /* The middle letter e.g. get<b>short indicates Big or Little endian
421 target machine. It doesn't matter what the byte order of the host
422 machine is; these routines work for either. */
423
424 /* FIXME: Should these take a count argument?
425 Answer (gnu@cygnus.com): No, but perhaps they should be inline
426 functions in swap.h #ifdef __GNUC__.
427 Gprof them later and find out. */
428
429 /*
430 FUNCTION
431 bfd_put_size
432 FUNCTION
433 bfd_get_size
434
435 DESCRIPTION
436 These macros as used for reading and writing raw data in
437 sections; each access (except for bytes) is vectored through
438 the target format of the BFD and mangled accordingly. The
439 mangling performs any necessary endian translations and
440 removes alignment restrictions. Note that types accepted and
441 returned by these macros are identical so they can be swapped
442 around in macros---for example, @file{libaout.h} defines <<GET_WORD>>
443 to either <<bfd_get_32>> or <<bfd_get_64>>.
444
445 In the put routines, @var{val} must be a <<bfd_vma>>. If we are on a
446 system without prototypes, the caller is responsible for making
447 sure that is true, with a cast if necessary. We don't cast
448 them in the macro definitions because that would prevent <<lint>>
449 or <<gcc -Wall>> from detecting sins such as passing a pointer.
450 To detect calling these with less than a <<bfd_vma>>, use
451 <<gcc -Wconversion>> on a host with 64 bit <<bfd_vma>>'s.
452
453 .
454 .{* Byte swapping macros for user section data. *}
455 .
456 .#define bfd_put_8(abfd, val, ptr) \
457 . (*((unsigned char *)(ptr)) = (unsigned char)(val))
458 .#define bfd_put_signed_8 \
459 . bfd_put_8
460 .#define bfd_get_8(abfd, ptr) \
461 . (*(unsigned char *)(ptr))
462 .#define bfd_get_signed_8(abfd, ptr) \
463 . ((*(unsigned char *)(ptr) ^ 0x80) - 0x80)
464 .
465 .#define bfd_put_16(abfd, val, ptr) \
466 . BFD_SEND(abfd, bfd_putx16, ((val),(ptr)))
467 .#define bfd_put_signed_16 \
468 . bfd_put_16
469 .#define bfd_get_16(abfd, ptr) \
470 . BFD_SEND(abfd, bfd_getx16, (ptr))
471 .#define bfd_get_signed_16(abfd, ptr) \
472 . BFD_SEND (abfd, bfd_getx_signed_16, (ptr))
473 .
474 .#define bfd_put_32(abfd, val, ptr) \
475 . BFD_SEND(abfd, bfd_putx32, ((val),(ptr)))
476 .#define bfd_put_signed_32 \
477 . bfd_put_32
478 .#define bfd_get_32(abfd, ptr) \
479 . BFD_SEND(abfd, bfd_getx32, (ptr))
480 .#define bfd_get_signed_32(abfd, ptr) \
481 . BFD_SEND(abfd, bfd_getx_signed_32, (ptr))
482 .
483 .#define bfd_put_64(abfd, val, ptr) \
484 . BFD_SEND(abfd, bfd_putx64, ((val), (ptr)))
485 .#define bfd_put_signed_64 \
486 . bfd_put_64
487 .#define bfd_get_64(abfd, ptr) \
488 . BFD_SEND(abfd, bfd_getx64, (ptr))
489 .#define bfd_get_signed_64(abfd, ptr) \
490 . BFD_SEND(abfd, bfd_getx_signed_64, (ptr))
491 .
492 */
493
494 /*
495 FUNCTION
496 bfd_h_put_size
497 bfd_h_get_size
498
499 DESCRIPTION
500 These macros have the same function as their <<bfd_get_x>>
501 bretheren, except that they are used for removing information
502 for the header records of object files. Believe it or not,
503 some object files keep their header records in big endian
504 order and their data in little endian order.
505 .
506 .{* Byte swapping macros for file header data. *}
507 .
508 .#define bfd_h_put_8(abfd, val, ptr) \
509 . bfd_put_8 (abfd, val, ptr)
510 .#define bfd_h_put_signed_8(abfd, val, ptr) \
511 . bfd_put_8 (abfd, val, ptr)
512 .#define bfd_h_get_8(abfd, ptr) \
513 . bfd_get_8 (abfd, ptr)
514 .#define bfd_h_get_signed_8(abfd, ptr) \
515 . bfd_get_signed_8 (abfd, ptr)
516 .
517 .#define bfd_h_put_16(abfd, val, ptr) \
518 . BFD_SEND(abfd, bfd_h_putx16,(val,ptr))
519 .#define bfd_h_put_signed_16 \
520 . bfd_h_put_16
521 .#define bfd_h_get_16(abfd, ptr) \
522 . BFD_SEND(abfd, bfd_h_getx16,(ptr))
523 .#define bfd_h_get_signed_16(abfd, ptr) \
524 . BFD_SEND(abfd, bfd_h_getx_signed_16, (ptr))
525 .
526 .#define bfd_h_put_32(abfd, val, ptr) \
527 . BFD_SEND(abfd, bfd_h_putx32,(val,ptr))
528 .#define bfd_h_put_signed_32 \
529 . bfd_h_put_32
530 .#define bfd_h_get_32(abfd, ptr) \
531 . BFD_SEND(abfd, bfd_h_getx32,(ptr))
532 .#define bfd_h_get_signed_32(abfd, ptr) \
533 . BFD_SEND(abfd, bfd_h_getx_signed_32, (ptr))
534 .
535 .#define bfd_h_put_64(abfd, val, ptr) \
536 . BFD_SEND(abfd, bfd_h_putx64,(val, ptr))
537 .#define bfd_h_put_signed_64 \
538 . bfd_h_put_64
539 .#define bfd_h_get_64(abfd, ptr) \
540 . BFD_SEND(abfd, bfd_h_getx64,(ptr))
541 .#define bfd_h_get_signed_64(abfd, ptr) \
542 . BFD_SEND(abfd, bfd_h_getx_signed_64, (ptr))
543 .
544 */
545
546 /* Sign extension to bfd_signed_vma. */
547 #define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000)
548 #define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000)
549 #define EIGHT_GAZILLION (((BFD_HOST_64_BIT)0x80000000) << 32)
550 #define COERCE64(x) \
551 (((bfd_signed_vma) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION)
552
553 bfd_vma
554 bfd_getb16 (addr)
555 register const bfd_byte *addr;
556 {
557 return (addr[0] << 8) | addr[1];
558 }
559
560 bfd_vma
561 bfd_getl16 (addr)
562 register const bfd_byte *addr;
563 {
564 return (addr[1] << 8) | addr[0];
565 }
566
567 bfd_signed_vma
568 bfd_getb_signed_16 (addr)
569 register const bfd_byte *addr;
570 {
571 return COERCE16((addr[0] << 8) | addr[1]);
572 }
573
574 bfd_signed_vma
575 bfd_getl_signed_16 (addr)
576 register const bfd_byte *addr;
577 {
578 return COERCE16((addr[1] << 8) | addr[0]);
579 }
580
581 void
582 bfd_putb16 (data, addr)
583 bfd_vma data;
584 register bfd_byte *addr;
585 {
586 addr[0] = (bfd_byte)(data >> 8);
587 addr[1] = (bfd_byte )data;
588 }
589
590 void
591 bfd_putl16 (data, addr)
592 bfd_vma data;
593 register bfd_byte *addr;
594 {
595 addr[0] = (bfd_byte )data;
596 addr[1] = (bfd_byte)(data >> 8);
597 }
598
599 bfd_vma
600 bfd_getb32 (addr)
601 register const bfd_byte *addr;
602 {
603 return (((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
604 | addr[2]) << 8 | addr[3];
605 }
606
607 bfd_vma
608 bfd_getl32 (addr)
609 register const bfd_byte *addr;
610 {
611 return (((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
612 | addr[1]) << 8 | addr[0];
613 }
614
615 bfd_signed_vma
616 bfd_getb_signed_32 (addr)
617 register const bfd_byte *addr;
618 {
619 return COERCE32((((((bfd_vma)addr[0] << 8) | addr[1]) << 8)
620 | addr[2]) << 8 | addr[3]);
621 }
622
623 bfd_signed_vma
624 bfd_getl_signed_32 (addr)
625 register const bfd_byte *addr;
626 {
627 return COERCE32((((((bfd_vma)addr[3] << 8) | addr[2]) << 8)
628 | addr[1]) << 8 | addr[0]);
629 }
630
631 bfd_vma
632 bfd_getb64 (addr)
633 register const bfd_byte *addr;
634 {
635 #ifdef BFD64
636 bfd_vma low, high;
637
638 high= ((((((((addr[0]) << 8) |
639 addr[1]) << 8) |
640 addr[2]) << 8) |
641 addr[3]) );
642
643 low = (((((((((bfd_vma)addr[4]) << 8) |
644 addr[5]) << 8) |
645 addr[6]) << 8) |
646 addr[7]));
647
648 return high << 32 | low;
649 #else
650 BFD_FAIL();
651 return 0;
652 #endif
653 }
654
655 bfd_vma
656 bfd_getl64 (addr)
657 register const bfd_byte *addr;
658 {
659 #ifdef BFD64
660 bfd_vma low, high;
661 high= (((((((addr[7] << 8) |
662 addr[6]) << 8) |
663 addr[5]) << 8) |
664 addr[4]));
665
666 low = ((((((((bfd_vma)addr[3] << 8) |
667 addr[2]) << 8) |
668 addr[1]) << 8) |
669 addr[0]) );
670
671 return high << 32 | low;
672 #else
673 BFD_FAIL();
674 return 0;
675 #endif
676
677 }
678
679 bfd_signed_vma
680 bfd_getb_signed_64 (addr)
681 register const bfd_byte *addr;
682 {
683 #ifdef BFD64
684 bfd_vma low, high;
685
686 high= ((((((((addr[0]) << 8) |
687 addr[1]) << 8) |
688 addr[2]) << 8) |
689 addr[3]) );
690
691 low = (((((((((bfd_vma)addr[4]) << 8) |
692 addr[5]) << 8) |
693 addr[6]) << 8) |
694 addr[7]));
695
696 return COERCE64(high << 32 | low);
697 #else
698 BFD_FAIL();
699 return 0;
700 #endif
701 }
702
703 bfd_signed_vma
704 bfd_getl_signed_64 (addr)
705 register const bfd_byte *addr;
706 {
707 #ifdef BFD64
708 bfd_vma low, high;
709 high= (((((((addr[7] << 8) |
710 addr[6]) << 8) |
711 addr[5]) << 8) |
712 addr[4]));
713
714 low = ((((((((bfd_vma)addr[3] << 8) |
715 addr[2]) << 8) |
716 addr[1]) << 8) |
717 addr[0]) );
718
719 return COERCE64(high << 32 | low);
720 #else
721 BFD_FAIL();
722 return 0;
723 #endif
724 }
725
726 void
727 bfd_putb32 (data, addr)
728 bfd_vma data;
729 register bfd_byte *addr;
730 {
731 addr[0] = (bfd_byte)(data >> 24);
732 addr[1] = (bfd_byte)(data >> 16);
733 addr[2] = (bfd_byte)(data >> 8);
734 addr[3] = (bfd_byte)data;
735 }
736
737 void
738 bfd_putl32 (data, addr)
739 bfd_vma data;
740 register bfd_byte *addr;
741 {
742 addr[0] = (bfd_byte)data;
743 addr[1] = (bfd_byte)(data >> 8);
744 addr[2] = (bfd_byte)(data >> 16);
745 addr[3] = (bfd_byte)(data >> 24);
746 }
747
748 void
749 bfd_putb64 (data, addr)
750 bfd_vma data;
751 register bfd_byte *addr;
752 {
753 #ifdef BFD64
754 addr[0] = (bfd_byte)(data >> (7*8));
755 addr[1] = (bfd_byte)(data >> (6*8));
756 addr[2] = (bfd_byte)(data >> (5*8));
757 addr[3] = (bfd_byte)(data >> (4*8));
758 addr[4] = (bfd_byte)(data >> (3*8));
759 addr[5] = (bfd_byte)(data >> (2*8));
760 addr[6] = (bfd_byte)(data >> (1*8));
761 addr[7] = (bfd_byte)(data >> (0*8));
762 #else
763 BFD_FAIL();
764 #endif
765 }
766
767 void
768 bfd_putl64 (data, addr)
769 bfd_vma data;
770 register bfd_byte *addr;
771 {
772 #ifdef BFD64
773 addr[7] = (bfd_byte)(data >> (7*8));
774 addr[6] = (bfd_byte)(data >> (6*8));
775 addr[5] = (bfd_byte)(data >> (5*8));
776 addr[4] = (bfd_byte)(data >> (4*8));
777 addr[3] = (bfd_byte)(data >> (3*8));
778 addr[2] = (bfd_byte)(data >> (2*8));
779 addr[1] = (bfd_byte)(data >> (1*8));
780 addr[0] = (bfd_byte)(data >> (0*8));
781 #else
782 BFD_FAIL();
783 #endif
784 }
785 \f
786 /* Default implementation */
787
788 boolean
789 bfd_generic_get_section_contents (abfd, section, location, offset, count)
790 bfd *abfd;
791 sec_ptr section;
792 PTR location;
793 file_ptr offset;
794 bfd_size_type count;
795 {
796 if (count == 0)
797 return true;
798 if ((bfd_size_type)(offset+count) > section->_raw_size
799 || bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
800 || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
801 return (false); /* on error */
802 return (true);
803 }
804
805 /* This generic function can only be used in implementations where creating
806 NEW sections is disallowed. It is useful in patching existing sections
807 in read-write files, though. See other set_section_contents functions
808 to see why it doesn't work for new sections. */
809 boolean
810 bfd_generic_set_section_contents (abfd, section, location, offset, count)
811 bfd *abfd;
812 sec_ptr section;
813 PTR location;
814 file_ptr offset;
815 bfd_size_type count;
816 {
817 if (count == 0)
818 return true;
819
820 if (bfd_seek (abfd, (file_ptr) (section->filepos + offset), SEEK_SET) == -1
821 || bfd_write (location, (bfd_size_type) 1, count, abfd) != count)
822 return false;
823
824 return true;
825 }
826
827 /*
828 INTERNAL_FUNCTION
829 bfd_log2
830
831 SYNOPSIS
832 unsigned int bfd_log2(bfd_vma x);
833
834 DESCRIPTION
835 Return the log base 2 of the value supplied, rounded up. E.g., an
836 @var{x} of 1025 returns 11.
837 */
838
839 unsigned
840 bfd_log2(x)
841 bfd_vma x;
842 {
843 unsigned result = 0;
844 while ( (bfd_vma)(1<< result) < x)
845 result++;
846 return result;
847 }
848
849 boolean
850 bfd_generic_is_local_label (abfd, sym)
851 bfd *abfd;
852 asymbol *sym;
853 {
854 char locals_prefix = (bfd_get_symbol_leading_char (abfd) == '_') ? 'L' : '.';
855
856 return (sym->name[0] == locals_prefix);
857 }
858
This page took 0.046547 seconds and 4 git commands to generate.