Merged in some changes from Intel,
[deliverable/binutils-gdb.git] / bfd / bfd.c
1 /* -*- C -*- */
2
3 /*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support.
4 Every definition in this file should be exported and declared
5 in bfd.c. If you don't want it to be user-visible, put it in
6 libbfd.c!
7 */
8
9 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
10
11 This file is part of BFD, the Binary File Diddler.
12
13 BFD is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 1, or (at your option)
16 any later version.
17
18 BFD is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with BFD; see the file COPYING. If not, write to
25 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26
27 /* $Id$ */
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "libbfd.h"
31
32 short _bfd_host_big_endian = 0x0100;
33 /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
34 * return 1 if the host is big-endian, 0 otherwise.
35 * (See HOST_IS_BIG_ENDIAN_P in bfd.h.)
36 */
37
38
39
40 \f
41
42 /** Error handling
43 o - Most functions return nonzero on success (check doc for
44 precise semantics); 0 or NULL on error.
45 o - Internal errors are documented by the value of bfd_error.
46 If that is system_call_error then check errno.
47 o - The easiest way to report this to the user is to use bfd_perror.
48 */
49
50 bfd_ec bfd_error = no_error;
51
52 char *bfd_errmsgs[] = {"No error",
53 "System call error",
54 "Invalid target",
55 "File in wrong format",
56 "Invalid operation",
57 "Memory exhausted",
58 "No symbols",
59 "No relocation info",
60 "No more archived files",
61 "Malformed archive",
62 "Symbol not found",
63 "File format not recognized",
64 "File format is ambiguous",
65 "Section has no contents",
66 "Nonrepresentable section on output",
67 "#<Invalid error code>"
68 };
69
70
71 static
72 void
73 DEFUN(bfd_nonrepresentable_section,(abfd, name),
74 CONST bfd * CONST abfd AND
75 CONST char * CONST name)
76 {
77 printf("bfd error writing file %s, can't represent section name %s\n", abfd->filename, name);
78 exit(1);
79 }
80 bfd_error_vector_type bfd_error_vector =
81 {
82 bfd_nonrepresentable_section
83 };
84
85 #if !defined(ANSI_LIBRARIES)
86 char *
87 strerror (code)
88 int code;
89 {
90 extern int sys_nerr;
91 extern char *sys_errlist[];
92
93 return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" :
94 sys_errlist [code]);
95 }
96 #endif /* not ANSI_LIBRARIES */
97
98
99
100 char *
101 bfd_errmsg (error_tag)
102 bfd_ec error_tag;
103 {
104 extern int errno;
105
106 if (error_tag == system_call_error)
107 return strerror (errno);
108
109 if ((((int)error_tag <(int) no_error) ||
110 ((int)error_tag > (int)invalid_error_code)))
111 error_tag = invalid_error_code;/* sanity check */
112
113 return bfd_errmsgs [(int)error_tag];
114 }
115
116
117 void bfd_default_error_trap(error_tag)
118 bfd_ec error_tag;
119 {
120 printf("bfd assert fail (%s)\n", bfd_errmsg(error_tag));
121 }
122
123 void (*bfd_error_trap)() = bfd_default_error_trap;
124 void (*bfd_error_nonrepresentabltrap)() = bfd_default_error_trap;
125 void
126 bfd_perror (message)
127 char *message;
128 {
129 if (bfd_error == system_call_error)
130 perror(message); /* must be system error then... */
131 else {
132 if (message == NULL || *message == '\0')
133 fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
134 else
135 fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_error));
136 }
137 }
138
139 /* for error messages */
140 char *
141 bfd_format_string (format)
142 bfd_format format;
143 {
144 if (((int)format <(int) bfd_unknown) || ((int)format >=(int) bfd_type_end)) return "invalid";
145
146 switch (format) {
147 case bfd_object: return "object"; /* linker/assember/compiler output */
148 case bfd_archive: return "archive"; /* object archive file */
149 case bfd_core: return "core"; /* core dump */
150 default: return "unknown";
151 }
152 }
153 \f
154 /** Target configurations */
155
156 extern bfd_target *target_vector[];
157
158 /* Returns a pointer to the transfer vector for the object target
159 named target_name. If target_name is NULL, chooses the one in the
160 environment variable GNUTARGET; if that is null or not defined then
161 the first entry in the target list is chosen. Passing in the
162 string "default" or setting the environment variable to "default"
163 will cause the first entry in the target list to be returned. */
164
165 bfd_target *
166 DEFUN(bfd_find_target,(target_name),
167 CONST char *target_name)
168 {
169 bfd_target **target;
170 extern char *getenv ();
171 CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
172
173 /* This is safe; the vector cannot be null */
174 if (targname == NULL || !strcmp (targname, "default"))
175 return target_vector[0];
176
177 for (target = &target_vector[0]; *target != NULL; target++) {
178 if (!strcmp (targname, (*target)->name))
179 return *target;
180 }
181
182 bfd_error = invalid_target;
183 return NULL;
184 }
185
186 /* Returns a freshly-consed, NULL-terminated vector of the names of all the
187 valid bfd targets. Do not modify the names */
188
189 char **
190 bfd_target_list ()
191 {
192 int vec_length= 0;
193 bfd_target **target;
194 char **name_list, **name_ptr;
195
196 for (target = &target_vector[0]; *target != NULL; target++)
197 vec_length++;
198
199 name_ptr = name_list = (char **) zalloc ((vec_length + 1) * sizeof (char **));
200
201 if (name_list == NULL) {
202 bfd_error = no_memory;
203 return NULL;
204 }
205
206 for (target = &target_vector[0]; *target != NULL; target++)
207 *(name_ptr++) = (*target)->name;
208
209 return name_list;
210 }
211 \f
212 /** Init a bfd for read of the proper format.
213 */
214
215 /* We should be able to find out if the target was defaulted or user-specified.
216 If the user specified the target explicitly then we should do no search.
217 I guess the best way to do this is to pass an extra argument which specifies
218 the DWIM. */
219
220 /* I have chanegd this always to set the filepos to the origin before
221 guessing. -- Gumby, 14 Februar 1991*/
222
223 boolean
224 bfd_check_format (abfd, format)
225 bfd *abfd;
226 bfd_format format;
227 {
228 #if obsolete
229 file_ptr filepos;
230 #endif
231 bfd_target **target, *save_targ, *right_targ;
232 int match_count;
233
234 if (!bfd_read_p (abfd) ||
235 ((int)(abfd->format) < (int)bfd_unknown) ||
236 ((int)(abfd->format) >= (int)bfd_type_end)) {
237 bfd_error = invalid_operation;
238 return false;
239 }
240
241 if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false;
242
243 /* presume the answer is yes */
244 abfd->format = format;
245
246 #if obsolete
247 filepos = bfd_tell (abfd);
248 #endif
249 bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* instead, rewind! */
250
251
252 right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
253 if (right_targ) {
254 abfd->xvec = right_targ; /* Set the target as returned */
255 return true; /* File position has moved, BTW */
256 }
257
258 /* This isn't a <format> file in the specified or defaulted target type.
259 See if we recognize it for any other target type. (We check them
260 all to make sure it's uniquely recognized.) */
261
262 save_targ = abfd->xvec;
263 match_count = 0;
264 right_targ = 0;
265
266 for (target = target_vector; *target != NULL; target++) {
267 bfd_target *temp;
268
269 abfd->xvec = *target; /* Change BFD's target temporarily */
270 #if obsolete
271 bfd_seek (abfd, filepos, SEEK_SET); /* Restore original file position */
272 #endif
273 bfd_seek (abfd, (file_ptr)0, SEEK_SET);
274 temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
275 if (temp) { /* This format checks out as ok! */
276 right_targ = temp;
277 match_count++;
278 #ifdef GNU960
279 /* Big- and little-endian b.out archives look the same, but it doesn't
280 * matter: there is no difference in their headers, and member file byte
281 * orders will (I hope) be handled appropriately by bfd. Ditto for big
282 * and little coff archives. And the 4 coff/b.out object formats are
283 * unambiguous. So accept the first match we find.
284 */
285 break;
286 #endif
287 }
288 }
289
290 if (match_count == 1) {
291 abfd->xvec = right_targ; /* Change BFD's target permanently */
292 return true; /* File position has moved, BTW */
293 }
294
295 abfd->xvec = save_targ; /* Restore original target type */
296 abfd->format = bfd_unknown; /* Restore original format */
297 bfd_error = ((match_count == 0) ? file_not_recognized :
298 file_ambiguously_recognized);
299 #if obsolete
300 bfd_seek (abfd, filepos, SEEK_SET); /* Restore original file position */
301 #endif
302 return false;
303 }
304
305 boolean
306 bfd_set_format (abfd, format)
307 bfd *abfd;
308 bfd_format format;
309 {
310 file_ptr filepos;
311
312 if (bfd_read_p (abfd) ||
313 ((int)abfd->format < (int)bfd_unknown) ||
314 ((int)abfd->format >= (int)bfd_type_end)) {
315 bfd_error = invalid_operation;
316 return false;
317 }
318
319 if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false;
320
321 /* presume the answer is yes */
322 abfd->format = format;
323
324 filepos = bfd_tell (abfd);
325
326 if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
327 abfd->format = bfd_unknown;
328 bfd_seek (abfd, filepos, SEEK_SET);
329 return false;
330 }
331
332 return true;
333 }
334 \f
335 /* Hack object and core file sections */
336
337 sec_ptr
338 DEFUN(bfd_get_section_by_name,(abfd, name),
339 bfd *abfd AND
340 CONST char *name)
341 {
342 asection *sect;
343
344 for (sect = abfd->sections; sect != NULL; sect = sect->next)
345 if (!strcmp (sect->name, name)) return sect;
346 return NULL;
347 }
348
349 /* If you try to create a section with a name which is already in use,
350 returns the old section by that name instead. */
351 sec_ptr
352 DEFUN(bfd_make_section,(abfd, name),
353 bfd *abfd AND
354 CONST char *name)
355 {
356 asection *newsect;
357 asection ** prev = &abfd->sections;
358 asection * sect = abfd->sections;
359
360 if (abfd->output_has_begun) {
361 bfd_error = invalid_operation;
362 return NULL;
363 }
364
365 while (sect) {
366 if (!strcmp(sect->name, name)) return sect;
367 prev = &sect->next;
368 sect = sect->next;
369 }
370
371 newsect = (asection *) zalloc (sizeof (asection));
372 if (newsect == NULL) {
373 bfd_error = no_memory;
374 return NULL;
375 }
376
377 newsect->name = name;
378 newsect->index = abfd->section_count++;
379 newsect->flags = SEC_NO_FLAGS;
380
381 #if ignore /* the compiler doesn't know that zalloc clears the storage */
382 newsect->userdata = 0;
383 newsect->next = (asection *)NULL;
384 newsect->relocation = (arelent *)NULL;
385 newsect->reloc_count = 0;
386 newsect->line_filepos =0;
387 #endif
388 if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
389 free (newsect);
390 return NULL;
391 }
392
393 *prev = newsect;
394 return newsect;
395 }
396
397 /* Call operation on each section. Operation gets three args: the bfd,
398 the section, and a void * pointer (whatever the user supplied). */
399
400 /* This is attractive except that without lexical closures its use is hard
401 to make reentrant. */
402 /*VARARGS2*/
403 void
404 bfd_map_over_sections (abfd, operation, user_storage)
405 bfd *abfd;
406 void (*operation)();
407 PTR user_storage;
408 {
409 asection *sect;
410 int i = 0;
411
412 for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
413 (*operation) (abfd, sect, user_storage);
414
415 if (i != abfd->section_count) /* Debugging */
416 abort();
417 }
418
419 boolean
420 bfd_set_section_flags (abfd, section, flags)
421 bfd *abfd;
422 sec_ptr section;
423 flagword flags;
424 {
425 if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
426 bfd_error = invalid_operation;
427 return false;
428 }
429
430 section->flags = flags;
431 return true;
432 }
433
434
435 boolean
436 bfd_set_section_size (abfd, ptr, val)
437 bfd *abfd;
438 sec_ptr ptr;
439 unsigned long val;
440 {
441 /* Once you've started writing to any section you cannot create or change
442 the size of any others. */
443
444 if (abfd->output_has_begun) {
445 bfd_error = invalid_operation;
446 return false;
447 }
448
449 ptr->size = val;
450
451 return true;
452 }
453
454 boolean
455 bfd_set_section_contents (abfd, section, location, offset, count)
456 bfd *abfd;
457 sec_ptr section;
458 PTR location;
459 file_ptr offset;
460 int count;
461 {
462 if (!(bfd_get_section_flags(abfd, section) &
463 SEC_HAS_CONTENTS)) {
464 bfd_error = no_contents;
465 return(false);
466 } /* if section has no contents */
467
468 if (BFD_SEND (abfd, _bfd_set_section_contents,
469 (abfd, section, location, offset, count))) {
470 abfd->output_has_begun = true;
471 return true;
472 }
473
474 return false;
475 }
476
477 boolean
478 bfd_get_section_contents (abfd, section, location, offset, count)
479 bfd *abfd;
480 sec_ptr section;
481 PTR location;
482 file_ptr offset;
483 int count;
484 {
485 if (section->flags & SEC_CONSTRUCTOR) {
486 memset(location, 0, count);
487 return true;
488 }
489 else {
490 return (BFD_SEND (abfd, _bfd_get_section_contents,
491 (abfd, section, location, offset, count)));
492 }
493 }
494
495 \f
496 /** Some core file info commands */
497
498 /* Returns a read-only string explaining what program was running when
499 it failed. */
500
501 char *
502 bfd_core_file_failing_command (abfd)
503 bfd *abfd;
504 {
505 if (abfd->format != bfd_core) {
506 bfd_error = invalid_operation;
507 return NULL;
508 }
509 return BFD_SEND (abfd, _core_file_failing_command, (abfd));
510 }
511
512 int
513 bfd_core_file_failing_signal (abfd)
514 bfd *abfd;
515 {
516 if (abfd->format != bfd_core) {
517 bfd_error = invalid_operation;
518 return NULL;
519 }
520 return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
521 }
522
523 boolean
524 core_file_matches_executable_p (core_bfd, exec_bfd)
525 bfd *core_bfd, *exec_bfd;
526 {
527 if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
528 bfd_error = wrong_format;
529 return false;
530 }
531
532 return BFD_SEND (core_bfd, _core_file_matches_executable_p, (core_bfd, exec_bfd));
533 }
534 \f
535 /** Symbols */
536
537 boolean
538 bfd_set_symtab (abfd, location, symcount)
539 bfd *abfd;
540 asymbol **location;
541 unsigned int symcount;
542 {
543 if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
544 bfd_error = invalid_operation;
545 return false;
546 }
547
548 bfd_get_outsymbols (abfd) = location;
549 bfd_get_symcount (abfd) = symcount;
550 return true;
551 }
552
553 /* returns the number of octets of storage required */
554 unsigned int
555 get_reloc_upper_bound (abfd, asect)
556 bfd *abfd;
557 sec_ptr asect;
558 {
559 if (abfd->format != bfd_object) {
560 bfd_error = invalid_operation;
561 return 0;
562 }
563
564 return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
565 }
566
567 unsigned int
568 bfd_canonicalize_reloc (abfd, asect, location, symbols)
569 bfd *abfd;
570 sec_ptr asect;
571 arelent **location;
572 asymbol **symbols;
573 {
574 if (abfd->format != bfd_object) {
575 bfd_error = invalid_operation;
576 return 0;
577 }
578
579 return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
580 }
581
582 void
583 bfd_print_symbol_vandf(file, symbol)
584 PTR file;
585 asymbol *symbol;
586 {
587 flagword type = symbol->flags;
588 if (symbol->section != (asection *)NULL)
589 {
590 fprintf(file,"%08lx ", symbol->value+symbol->section->vma);
591 }
592 else
593 {
594 fprintf(file,"%08lx ", symbol->value);
595 }
596 fprintf(file,"%c%c%c%c%c%c%c",
597 (type & BSF_LOCAL) ? 'l':' ',
598 (type & BSF_GLOBAL) ? 'g' : ' ',
599 (type & BSF_IMPORT) ? 'i' : ' ',
600 (type & BSF_EXPORT) ? 'e' : ' ',
601 (type & BSF_UNDEFINED) ? 'u' : ' ',
602 (type & BSF_FORT_COMM) ? 'c' : ' ',
603 (type & BSF_DEBUGGING) ? 'd' :' ');
604
605 }
606
607
608 boolean
609 bfd_set_file_flags (abfd, flags)
610 bfd *abfd;
611 flagword flags;
612 {
613 if (abfd->format != bfd_object) {
614 bfd_error = wrong_format;
615 return false;
616 }
617
618 if (bfd_read_p (abfd)) {
619 bfd_error = invalid_operation;
620 return false;
621 }
622
623 if ((flags & bfd_applicable_file_flags (abfd)) != flags) {
624 bfd_error = invalid_operation;
625 return false;
626 }
627
628 bfd_get_file_flags (abfd) = flags;
629 return true;
630 }
631
632
633 void
634 bfd_set_reloc (ignore_abfd, asect, location, count)
635 bfd *ignore_abfd;
636 sec_ptr asect;
637 arelent **location;
638 unsigned int count;
639 {
640 asect->orelocation = location;
641 asect->reloc_count = count;
642 }
643 /*
644 If an output_bfd is supplied to this function the generated image
645 will be relocatable, the relocations are copied to the output file
646 after they have been changed to reflect the new state of the world.
647 There are two ways of reflecting the results of partial linkage in an
648 output file; by modifying the output data in place, and by modifying
649 the relocation record. Some native formats (eg basic a.out and basic
650 coff) have no way of specifying an addend in the relocation type, so
651 the addend has to go in the output data. This is no big deal since in
652 these formats the output data slot will always be big enough for the
653 addend. Complex reloc types with addends were invented to solve just
654 this problem.
655 */
656
657 bfd_reloc_status_enum_type
658 bfd_perform_relocation(abfd,
659 reloc_entry,
660 data,
661 input_section,
662 output_bfd)
663 bfd *abfd;
664 arelent *reloc_entry;
665 PTR data;
666 asection *input_section;
667 bfd *output_bfd;
668 {
669 bfd_vma relocation;
670 bfd_reloc_status_enum_type flag = bfd_reloc_ok;
671 bfd_vma relocation_before;
672 bfd_vma addr = reloc_entry->address ;
673 bfd_vma output_base = 0;
674 CONST struct rint_struct *howto = reloc_entry->howto;
675 asection *reloc_target_output_section;
676 asection *reloc_target_input_section;
677 asymbol *symbol;
678
679 if (reloc_entry->sym_ptr_ptr) {
680 symbol = *( reloc_entry->sym_ptr_ptr);
681 if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
682 flag = bfd_reloc_undefined;
683 }
684 }
685 else {
686 symbol = (asymbol*)NULL;
687 }
688
689 if (howto->special_function){
690 bfd_reloc_status_enum_type cont;
691 cont = howto->special_function(abfd,
692 reloc_entry,
693 symbol,
694 data,
695 input_section);
696 if (cont != bfd_reloc_continue) return cont;
697 }
698
699 /*
700 Work out which section the relocation is targetted at and the
701 initial relocation command value.
702 */
703
704
705 if (symbol != (asymbol *)NULL){
706 if (symbol->flags & BSF_FORT_COMM) {
707 relocation = 0;
708 }
709 else {
710 relocation = symbol->value;
711 }
712 if (symbol->section != (asection *)NULL)
713 {
714 reloc_target_input_section = symbol->section;
715 }
716 else {
717 reloc_target_input_section = (asection *)NULL;
718 }
719 }
720 else if (reloc_entry->section != (asection *)NULL)
721 {
722 relocation = 0;
723 reloc_target_input_section = reloc_entry->section;
724 }
725 else {
726 relocation = 0;
727 reloc_target_input_section = (asection *)NULL;
728 }
729
730
731 if (reloc_target_input_section != (asection *)NULL) {
732
733 reloc_target_output_section =
734 reloc_target_input_section->output_section;
735
736 if (output_bfd && howto->partial_inplace==false) {
737 output_base = 0;
738 }
739 else {
740 output_base = reloc_target_output_section->vma;
741
742 }
743
744 relocation += output_base + reloc_target_input_section->output_offset;
745 }
746
747 relocation += reloc_entry->addend ;
748
749
750 if(reloc_entry->address > (bfd_vma)(input_section->size))
751 {
752 return bfd_reloc_outofrange;
753 }
754
755
756 if (howto->pc_relative == true)
757 {
758 /*
759 Anything which started out as pc relative should end up that
760 way too
761 */
762
763 relocation -=
764 output_base + input_section->output_offset;
765
766 }
767
768 if (output_bfd!= (bfd *)NULL && howto->partial_inplace == false) {
769 /*
770 This is a partial relocation, and we want to apply the relocation
771 to the reloc entry rather than the raw data. Modify the reloc
772 inplace to reflect what we now know.
773 */
774 reloc_entry->addend = relocation ;
775 reloc_entry->section = reloc_target_input_section;
776 if (reloc_target_input_section != (asection *)NULL) {
777 /* If we know the output section we can forget the symbol */
778 reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
779 }
780 reloc_entry->address +=
781 input_section->output_offset;
782 }
783 else {
784 reloc_entry->addend = 0;
785
786
787 /*
788 Either we are relocating all the way, or we don't want to apply
789 the relocation to the reloc entry (probably because there isn't
790 any room in the output format to describe addends to relocs)
791 */
792 relocation >>= howto->rightshift;
793
794 /* Shift everything up to where it's going to be used */
795
796 relocation <<= howto->bitpos;
797
798
799 /* Wait for the day when all have the mask in them */
800
801
802
803 relocation_before = relocation;
804
805
806 /* What we do:
807 i instruction to be left alone
808 o offset within instruction
809 r relocation offset to apply
810 S src mask
811 D dst mask
812 N ~dst mask
813 A part 1
814 B part 2
815 R result
816
817 Do this:
818 i i i i i o o o o o from bfd_get<size>
819 and S S S S S to get the size offset we want
820 + r r r r r r r r r r to get the final value to place
821 and D D D D D to chop to right size
822 -----------------------
823 A A A A A
824 And this:
825 i i i i i o o o o o from bfd_get<size>
826 and N N N N N get instruction
827 -----------------------
828 B B B B B
829
830 And then:
831 B B B B B
832 or A A A A A
833 -----------------------
834 R R R R R R R R R R put into bfd_put<size>
835 */
836
837 #define DOIT(x) \
838 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
839
840 switch (howto->size)
841 {
842 case 0:
843 {
844 char x = bfd_getchar(abfd, (char *)data + addr);
845 DOIT(x);
846 bfd_putchar(abfd,x, (unsigned char *) data + addr);
847 }
848 break;
849
850 case 1:
851 {
852 short x = bfd_getshort(abfd, (bfd_byte *)data + addr);
853 DOIT(x);
854 bfd_putshort(abfd, x, (unsigned char *)data + addr);
855 }
856 break;
857 case 2:
858 {
859 long x = bfd_getlong(abfd, (bfd_byte *) data + addr);
860 DOIT(x);
861 bfd_putlong(abfd,x, (bfd_byte *)data + addr);
862 }
863 break;
864 case 3:
865 /* Do nothing */
866 break;
867 default:
868 return bfd_reloc_other;
869 }
870 }
871 return flag;
872 }
873
874 void
875 bfd_assert(file, line)
876 char *file;
877 int line;
878 {
879 printf("bfd assertion fail %s:%d\n",file,line);
880 }
881
882
883 boolean
884 bfd_set_start_address(abfd, vma)
885 bfd *abfd;
886 bfd_vma vma;
887 {
888 abfd->start_address = vma;
889 return true;
890 }
891
892
893 bfd_vma bfd_log2(x)
894 bfd_vma x;
895 {
896 bfd_vma result = 0;
897 while ( (bfd_vma)(1<< result) < x)
898 result++;
899 return result;
900 }
901
902 /* bfd_get_mtime: Return cached file modification time (e.g. as read
903 from archive header for archive members, or from file system if we have
904 been called before); else determine modify time, cache it, and
905 return it. */
906
907 long
908 bfd_get_mtime (abfd)
909 bfd *abfd;
910 {
911 FILE *fp;
912 struct stat buf;
913
914 if (abfd->mtime_set)
915 return abfd->mtime;
916
917 fp = bfd_cache_lookup (abfd);
918 if (0 != fstat (fileno (fp), &buf))
919 return 0;
920
921 abfd->mtime_set = true;
922 abfd->mtime = buf.st_mtime;
923 return abfd->mtime;
924 }
This page took 0.051958 seconds and 4 git commands to generate.