Merge in changes from gdb-3.95 release into mainstream of BFD development.
[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 extern bfd_target *default_vector[];
158
159 /* Returns a pointer to the transfer vector for the object target
160 named target_name. If target_name is NULL, chooses the one in the
161 environment variable GNUTARGET; if that is null or not defined then
162 the first entry in the target list is chosen. Passing in the
163 string "default" or setting the environment variable to "default"
164 will cause the first entry in the target list to be returned,
165 and "target_defaulted" will be set in the bfd. This causes
166 bfd_check_format to loop over all the targets to find the one
167 that matches the file being read. */
168
169 bfd_target *
170 DEFUN(bfd_find_target,(target_name, abfd),
171 CONST char *target_name AND
172 bfd *abfd)
173 {
174 bfd_target **target;
175 extern char *getenv ();
176 CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
177
178 /* This is safe; the vector cannot be null */
179 if (targname == NULL || !strcmp (targname, "default")) {
180 abfd->target_defaulted = true;
181 return abfd->xvec = target_vector[0];
182 }
183
184 abfd->target_defaulted = false;
185
186 for (target = &target_vector[0]; *target != NULL; target++) {
187 if (!strcmp (targname, (*target)->name))
188 return abfd->xvec = *target;
189 }
190
191 bfd_error = invalid_target;
192 return NULL;
193 }
194
195
196 /* Returns a freshly-consed, NULL-terminated vector of the names of all the
197 valid bfd targets. Do not modify the names */
198
199 char **
200 bfd_target_list ()
201 {
202 int vec_length= 0;
203 bfd_target **target;
204 char **name_list, **name_ptr;
205
206 for (target = &target_vector[0]; *target != NULL; target++)
207 vec_length++;
208
209 name_ptr = name_list = (char **) zalloc ((vec_length + 1) * sizeof (char **));
210
211 if (name_list == NULL) {
212 bfd_error = no_memory;
213 return NULL;
214 }
215
216 for (target = &target_vector[0]; *target != NULL; target++)
217 *(name_ptr++) = (*target)->name;
218
219 return name_list;
220 }
221
222 /* Init a bfd for read of the proper format. If the target was unspecified,
223 search all the possible targets. */
224
225 boolean
226 DEFUN(bfd_check_format,(abfd, format),
227 bfd *abfd AND
228 bfd_format format)
229 {
230 bfd_target **target, *save_targ, *right_targ;
231 int match_count;
232
233 if (!bfd_read_p (abfd) ||
234 ((int)(abfd->format) < (int)bfd_unknown) ||
235 ((int)(abfd->format) >= (int)bfd_type_end)) {
236 bfd_error = invalid_operation;
237 return false;
238 }
239
240 if (abfd->format != bfd_unknown)
241 return (abfd->format == format)? true: false;
242
243 /* presume the answer is yes */
244 abfd->format = format;
245
246 /* If the target type was explicitly specified, just check that target. */
247
248 if (!abfd->target_defaulted) {
249 bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* rewind! */
250
251 right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
252 if (right_targ) {
253 abfd->xvec = right_targ; /* Set the target as returned */
254 return true; /* File position has moved, BTW */
255 }
256 return false; /* Specified target is not right */
257 }
258
259 /* Since the target type was defaulted, check them
260 all in the hope that one will be 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 bfd_seek (abfd, (file_ptr)0, SEEK_SET);
271 temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
272 if (temp) { /* This format checks out as ok! */
273 right_targ = temp;
274 match_count++;
275 /* If this is the default target, accept it, even if other targets
276 might match. People who want those other targets have to set
277 the GNUTARGET variable. */
278 if (temp == default_vector[0])
279 break;
280 #ifdef GNU960
281 /* Big- and little-endian b.out archives look the same, but it doesn't
282 * matter: there is no difference in their headers, and member file byte
283 * orders will (I hope) be handled appropriately by bfd. Ditto for big
284 * and little coff archives. And the 4 coff/b.out object formats are
285 * unambiguous. So accept the first match we find.
286 */
287 break;
288 #endif
289 }
290 }
291
292 if (match_count == 1) {
293 abfd->xvec = right_targ; /* Change BFD's target permanently */
294 return true; /* File position has moved, BTW */
295 }
296
297 abfd->xvec = save_targ; /* Restore original target type */
298 abfd->format = bfd_unknown; /* Restore original format */
299 bfd_error = ((match_count == 0) ? file_not_recognized :
300 file_ambiguously_recognized);
301 return false;
302 }
303
304 boolean
305 DEFUN(bfd_set_format,(abfd, format),
306 bfd *abfd AND
307 bfd_format format)
308 {
309
310 if (bfd_read_p (abfd) ||
311 ((int)abfd->format < (int)bfd_unknown) ||
312 ((int)abfd->format >= (int)bfd_type_end)) {
313 bfd_error = invalid_operation;
314 return false;
315 }
316
317 if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false;
318
319 /* presume the answer is yes */
320 abfd->format = format;
321
322 if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
323 abfd->format = bfd_unknown;
324 return false;
325 }
326
327 return true;
328 }
329 \f
330 /* Hack object and core file sections */
331
332 sec_ptr
333 DEFUN(bfd_get_section_by_name,(abfd, name),
334 bfd *abfd AND
335 CONST char *name)
336 {
337 asection *sect;
338
339 for (sect = abfd->sections; sect != NULL; sect = sect->next)
340 if (!strcmp (sect->name, name)) return sect;
341 return NULL;
342 }
343
344 /* If you try to create a section with a name which is already in use,
345 returns the old section by that name instead. */
346 sec_ptr
347 DEFUN(bfd_make_section,(abfd, name),
348 bfd *abfd AND
349 CONST char *CONST name)
350 {
351 asection *newsect;
352 asection ** prev = &abfd->sections;
353 asection * sect = abfd->sections;
354
355 if (abfd->output_has_begun) {
356 bfd_error = invalid_operation;
357 return NULL;
358 }
359
360 while (sect) {
361 if (!strcmp(sect->name, name)) return sect;
362 prev = &sect->next;
363 sect = sect->next;
364 }
365
366 newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
367 if (newsect == NULL) {
368 bfd_error = no_memory;
369 return NULL;
370 }
371
372 newsect->name = name;
373 newsect->index = abfd->section_count++;
374 newsect->flags = SEC_NO_FLAGS;
375
376 newsect->userdata = 0;
377 newsect->next = (asection *)NULL;
378 newsect->relocation = (arelent *)NULL;
379 newsect->reloc_count = 0;
380 newsect->line_filepos =0;
381
382 if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
383 free (newsect);
384 return NULL;
385 }
386
387 *prev = newsect;
388 return newsect;
389 }
390
391 /* Call operation on each section. Operation gets three args: the bfd,
392 the section, and a void * pointer (whatever the user supplied). */
393
394 /* This is attractive except that without lexical closures its use is hard
395 to make reentrant. */
396 /*VARARGS2*/
397 void
398 bfd_map_over_sections (abfd, operation, user_storage)
399 bfd *abfd;
400 void (*operation)();
401 PTR user_storage;
402 {
403 asection *sect;
404 int i = 0;
405
406 for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
407 (*operation) (abfd, sect, user_storage);
408
409 if (i != abfd->section_count) /* Debugging */
410 abort();
411 }
412
413 boolean
414 bfd_set_section_flags (abfd, section, flags)
415 bfd *abfd;
416 sec_ptr section;
417 flagword flags;
418 {
419 if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
420 bfd_error = invalid_operation;
421 return false;
422 }
423
424 section->flags = flags;
425 return true;
426 }
427
428
429 boolean
430 bfd_set_section_size (abfd, ptr, val)
431 bfd *abfd;
432 sec_ptr ptr;
433 unsigned long val;
434 {
435 /* Once you've started writing to any section you cannot create or change
436 the size of any others. */
437
438 if (abfd->output_has_begun) {
439 bfd_error = invalid_operation;
440 return false;
441 }
442
443 ptr->size = val;
444
445 return true;
446 }
447
448 boolean
449 DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count),
450 bfd *abfd AND
451 sec_ptr section AND
452 PTR location AND
453 file_ptr offset AND
454 bfd_size_type count)
455 {
456 if (!(bfd_get_section_flags(abfd, section) &
457 SEC_HAS_CONTENTS)) {
458 bfd_error = no_contents;
459 return(false);
460 } /* if section has no contents */
461
462 if (BFD_SEND (abfd, _bfd_set_section_contents,
463 (abfd, section, location, offset, count))) {
464 abfd->output_has_begun = true;
465 return true;
466 }
467
468 return false;
469 }
470
471 boolean
472 DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count),
473 bfd *abfd AND
474 sec_ptr section AND
475 PTR location AND
476 file_ptr offset AND
477 bfd_size_type count)
478 {
479 if (section->flags & SEC_CONSTRUCTOR) {
480 memset(location, 0, (unsigned)count);
481 return true;
482 }
483 else {
484 return (BFD_SEND (abfd, _bfd_get_section_contents,
485 (abfd, section, location, offset, count)));
486 }
487 }
488
489 \f
490 /** Some core file info commands */
491
492 /* Returns a read-only string explaining what program was running when
493 it failed. */
494
495 char *
496 bfd_core_file_failing_command (abfd)
497 bfd *abfd;
498 {
499 if (abfd->format != bfd_core) {
500 bfd_error = invalid_operation;
501 return NULL;
502 }
503 return BFD_SEND (abfd, _core_file_failing_command, (abfd));
504 }
505
506 int
507 bfd_core_file_failing_signal (abfd)
508 bfd *abfd;
509 {
510 if (abfd->format != bfd_core) {
511 bfd_error = invalid_operation;
512 return 0;
513 }
514 return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
515 }
516
517 boolean
518 core_file_matches_executable_p (core_bfd, exec_bfd)
519 bfd *core_bfd, *exec_bfd;
520 {
521 if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
522 bfd_error = wrong_format;
523 return false;
524 }
525
526 return BFD_SEND (core_bfd, _core_file_matches_executable_p, (core_bfd, exec_bfd));
527 }
528 \f
529 /** Symbols */
530
531 boolean
532 bfd_set_symtab (abfd, location, symcount)
533 bfd *abfd;
534 asymbol **location;
535 unsigned int symcount;
536 {
537 if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
538 bfd_error = invalid_operation;
539 return false;
540 }
541
542 bfd_get_outsymbols (abfd) = location;
543 bfd_get_symcount (abfd) = symcount;
544 return true;
545 }
546
547 /* returns the number of octets of storage required */
548 unsigned int
549 get_reloc_upper_bound (abfd, asect)
550 bfd *abfd;
551 sec_ptr asect;
552 {
553 if (abfd->format != bfd_object) {
554 bfd_error = invalid_operation;
555 return 0;
556 }
557
558 return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
559 }
560
561 unsigned int
562 bfd_canonicalize_reloc (abfd, asect, location, symbols)
563 bfd *abfd;
564 sec_ptr asect;
565 arelent **location;
566 asymbol **symbols;
567 {
568 if (abfd->format != bfd_object) {
569 bfd_error = invalid_operation;
570 return 0;
571 }
572
573 return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
574 }
575
576 void
577 bfd_print_symbol_vandf(file, symbol)
578 PTR file;
579 asymbol *symbol;
580 {
581 flagword type = symbol->flags;
582 if (symbol->section != (asection *)NULL)
583 {
584
585 fprintf_vma(file, symbol->value+symbol->section->vma);
586 }
587 else
588 {
589 fprintf_vma(file, symbol->value);
590 }
591 fprintf(file," %c%c%c%c%c%c%c",
592 (type & BSF_LOCAL) ? 'l':' ',
593 (type & BSF_GLOBAL) ? 'g' : ' ',
594 (type & BSF_IMPORT) ? 'i' : ' ',
595 (type & BSF_EXPORT) ? 'e' : ' ',
596 (type & BSF_UNDEFINED) ? 'u' : ' ',
597 (type & BSF_FORT_COMM) ? 'c' : ' ',
598 (type & BSF_DEBUGGING) ? 'd' :' ');
599
600 }
601
602
603 boolean
604 bfd_set_file_flags (abfd, flags)
605 bfd *abfd;
606 flagword flags;
607 {
608 if (abfd->format != bfd_object) {
609 bfd_error = wrong_format;
610 return false;
611 }
612
613 if (bfd_read_p (abfd)) {
614 bfd_error = invalid_operation;
615 return false;
616 }
617
618 if ((flags & bfd_applicable_file_flags (abfd)) != flags) {
619 bfd_error = invalid_operation;
620 return false;
621 }
622
623 bfd_get_file_flags (abfd) = flags;
624 return true;
625 }
626
627
628 void
629 bfd_set_reloc (ignore_abfd, asect, location, count)
630 bfd *ignore_abfd;
631 sec_ptr asect;
632 arelent **location;
633 unsigned int count;
634 {
635 asect->orelocation = location;
636 asect->reloc_count = count;
637 }
638 /*
639 If an output_bfd is supplied to this function the generated image
640 will be relocatable, the relocations are copied to the output file
641 after they have been changed to reflect the new state of the world.
642 There are two ways of reflecting the results of partial linkage in an
643 output file; by modifying the output data in place, and by modifying
644 the relocation record. Some native formats (eg basic a.out and basic
645 coff) have no way of specifying an addend in the relocation type, so
646 the addend has to go in the output data. This is no big deal since in
647 these formats the output data slot will always be big enough for the
648 addend. Complex reloc types with addends were invented to solve just
649 this problem.
650 */
651
652 bfd_reloc_status_enum_type
653 DEFUN(bfd_perform_relocation,(abfd,
654 reloc_entry,
655 data,
656 input_section,
657 output_bfd),
658 bfd *abfd AND
659 arelent *reloc_entry AND
660 PTR data AND
661 asection *input_section AND
662 bfd *output_bfd)
663 {
664 bfd_vma relocation;
665 bfd_reloc_status_enum_type flag = bfd_reloc_ok;
666 bfd_vma addr = reloc_entry->address ;
667 bfd_vma output_base = 0;
668 reloc_howto_type *howto = reloc_entry->howto;
669 asection *reloc_target_output_section;
670 asection *reloc_target_input_section;
671 asymbol *symbol;
672
673 if (reloc_entry->sym_ptr_ptr) {
674 symbol = *( reloc_entry->sym_ptr_ptr);
675 if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
676 flag = bfd_reloc_undefined;
677 }
678 }
679 else {
680 symbol = (asymbol*)NULL;
681 }
682
683 if (howto->special_function){
684 bfd_reloc_status_enum_type cont;
685 cont = howto->special_function(abfd,
686 reloc_entry,
687 symbol,
688 data,
689 input_section);
690 if (cont != bfd_reloc_continue) return cont;
691 }
692
693 /*
694 Work out which section the relocation is targetted at and the
695 initial relocation command value.
696 */
697
698
699 if (symbol != (asymbol *)NULL){
700 if (symbol->flags & BSF_FORT_COMM) {
701 relocation = 0;
702 }
703 else {
704 relocation = symbol->value;
705 }
706 if (symbol->section != (asection *)NULL)
707 {
708 reloc_target_input_section = symbol->section;
709 }
710 else {
711 reloc_target_input_section = (asection *)NULL;
712 }
713 }
714 else if (reloc_entry->section != (asection *)NULL)
715 {
716 relocation = 0;
717 reloc_target_input_section = reloc_entry->section;
718 }
719 else {
720 relocation = 0;
721 reloc_target_input_section = (asection *)NULL;
722 }
723
724
725 if (reloc_target_input_section != (asection *)NULL) {
726
727 reloc_target_output_section =
728 reloc_target_input_section->output_section;
729
730 if (output_bfd && howto->partial_inplace==false) {
731 output_base = 0;
732 }
733 else {
734 output_base = reloc_target_output_section->vma;
735
736 }
737
738 relocation += output_base + reloc_target_input_section->output_offset;
739 }
740
741 relocation += reloc_entry->addend ;
742
743
744 if(reloc_entry->address > (bfd_vma)(input_section->size))
745 {
746 return bfd_reloc_outofrange;
747 }
748
749
750 if (howto->pc_relative == true)
751 {
752 /*
753 Anything which started out as pc relative should end up that
754 way too.
755
756 There are two ways we can see a pcrel instruction. Sometimes
757 the pcrel displacement has been partially calculated, it
758 includes the distance from the start of the section to the
759 instruction in it (eg sun3), and sometimes the field is
760 totally blank - eg m88kbcs.
761 */
762
763
764 relocation -=
765 output_base + input_section->output_offset;
766
767 if (howto->pcrel_offset == true) {
768 relocation -= reloc_entry->address;
769 }
770
771 }
772
773 if (output_bfd!= (bfd *)NULL) {
774 if ( howto->partial_inplace == false) {
775 /*
776 This is a partial relocation, and we want to apply the relocation
777 to the reloc entry rather than the raw data. Modify the reloc
778 inplace to reflect what we now know.
779 */
780 reloc_entry->addend = relocation ;
781 reloc_entry->section = reloc_target_input_section;
782 if (reloc_target_input_section != (asection *)NULL) {
783 /* If we know the output section we can forget the symbol */
784 reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
785 }
786 reloc_entry->address +=
787 input_section->output_offset;
788 return flag;
789 }
790 else
791 {
792 /* This is a partial relocation, but inplace, so modify the
793 reloc record a bit
794 */
795
796 }
797 }
798
799 reloc_entry->addend = 0;
800
801
802 /*
803 Either we are relocating all the way, or we don't want to apply
804 the relocation to the reloc entry (probably because there isn't
805 any room in the output format to describe addends to relocs)
806 */
807 relocation >>= howto->rightshift;
808
809 /* Shift everything up to where it's going to be used */
810
811 relocation <<= howto->bitpos;
812
813 /* Wait for the day when all have the mask in them */
814
815 /* What we do:
816 i instruction to be left alone
817 o offset within instruction
818 r relocation offset to apply
819 S src mask
820 D dst mask
821 N ~dst mask
822 A part 1
823 B part 2
824 R result
825
826 Do this:
827 i i i i i o o o o o from bfd_get<size>
828 and S S S S S to get the size offset we want
829 + r r r r r r r r r r to get the final value to place
830 and D D D D D to chop to right size
831 -----------------------
832 A A A A A
833 And this:
834 ... i i i i i o o o o o from bfd_get<size>
835 and N N N N N get instruction
836 -----------------------
837 ... B B B B B
838
839 And then:
840 B B B B B
841 or A A A A A
842 -----------------------
843 R R R R R R R R R R put into bfd_put<size>
844 */
845
846 #define DOIT(x) \
847 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
848
849 switch (howto->size)
850 {
851 case 0:
852 {
853 char x = bfd_get_8(abfd, (char *)data + addr);
854 DOIT(x);
855 bfd_put_8(abfd,x, (unsigned char *) data + addr);
856 }
857 break;
858
859 case 1:
860 {
861 short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
862 DOIT(x);
863 bfd_put_16(abfd, x, (unsigned char *)data + addr);
864 }
865 break;
866 case 2:
867 {
868 long x = bfd_get_32(abfd, (bfd_byte *) data + addr);
869 DOIT(x);
870 bfd_put_32(abfd,x, (bfd_byte *)data + addr);
871 }
872 break;
873 case 3:
874 /* Do nothing */
875 break;
876 default:
877 return bfd_reloc_other;
878 }
879
880 return flag;
881 }
882
883 void
884 bfd_assert(file, line)
885 char *file;
886 int line;
887 {
888 printf("bfd assertion fail %s:%d\n",file,line);
889 }
890
891
892 boolean
893 bfd_set_start_address(abfd, vma)
894 bfd *abfd;
895 bfd_vma vma;
896 {
897 abfd->start_address = vma;
898 return true;
899 }
900
901
902 bfd_vma bfd_log2(x)
903 bfd_vma x;
904 {
905 bfd_vma result = 0;
906 while ( (bfd_vma)(1<< result) < x)
907 result++;
908 return result;
909 }
910
911 /* bfd_get_mtime: Return cached file modification time (e.g. as read
912 from archive header for archive members, or from file system if we have
913 been called before); else determine modify time, cache it, and
914 return it. */
915
916 long
917 bfd_get_mtime (abfd)
918 bfd *abfd;
919 {
920 FILE *fp;
921 struct stat buf;
922
923 if (abfd->mtime_set)
924 return abfd->mtime;
925
926 fp = bfd_cache_lookup (abfd);
927 if (0 != fstat (fileno (fp), &buf))
928 return 0;
929
930 abfd->mtime_set = true;
931 abfd->mtime = buf.st_mtime;
932 return abfd->mtime;
933 }