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