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