Saber C cleanup. Fix horrid bug in opncls.c in which an obstack is
[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 (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 addr = reloc_entry->address ;
652 bfd_vma output_base = 0;
653 reloc_howto_type *howto = reloc_entry->howto;
654 asection *reloc_target_output_section;
655 asection *reloc_target_input_section;
656 asymbol *symbol;
657
658 if (reloc_entry->sym_ptr_ptr) {
659 symbol = *( reloc_entry->sym_ptr_ptr);
660 if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
661 flag = bfd_reloc_undefined;
662 }
663 }
664 else {
665 symbol = (asymbol*)NULL;
666 }
667
668 if (howto->special_function){
669 bfd_reloc_status_enum_type cont;
670 cont = howto->special_function(abfd,
671 reloc_entry,
672 symbol,
673 data,
674 input_section);
675 if (cont != bfd_reloc_continue) return cont;
676 }
677
678 /*
679 Work out which section the relocation is targetted at and the
680 initial relocation command value.
681 */
682
683
684 if (symbol != (asymbol *)NULL){
685 if (symbol->flags & BSF_FORT_COMM) {
686 relocation = 0;
687 }
688 else {
689 relocation = symbol->value;
690 }
691 if (symbol->section != (asection *)NULL)
692 {
693 reloc_target_input_section = symbol->section;
694 }
695 else {
696 reloc_target_input_section = (asection *)NULL;
697 }
698 }
699 else if (reloc_entry->section != (asection *)NULL)
700 {
701 relocation = 0;
702 reloc_target_input_section = reloc_entry->section;
703 }
704 else {
705 relocation = 0;
706 reloc_target_input_section = (asection *)NULL;
707 }
708
709
710 if (reloc_target_input_section != (asection *)NULL) {
711
712 reloc_target_output_section =
713 reloc_target_input_section->output_section;
714
715 if (output_bfd && howto->partial_inplace==false) {
716 output_base = 0;
717 }
718 else {
719 output_base = reloc_target_output_section->vma;
720
721 }
722
723 relocation += output_base + reloc_target_input_section->output_offset;
724 }
725
726 relocation += reloc_entry->addend ;
727
728
729 if(reloc_entry->address > (bfd_vma)(input_section->size))
730 {
731 return bfd_reloc_outofrange;
732 }
733
734
735 if (howto->pc_relative == true)
736 {
737 /*
738 Anything which started out as pc relative should end up that
739 way too.
740
741 There are two ways we can see a pcrel instruction. Sometimes
742 the pcrel displacement has been partially calculated, it
743 includes the distance from the start of the section to the
744 instruction in it (eg sun3), and sometimes the field is
745 totally blank - eg m88kbcs.
746 */
747
748
749 relocation -=
750 output_base + input_section->output_offset;
751
752 if (howto->pcrel_offset == true) {
753 relocation -= reloc_entry->address;
754 }
755
756 }
757
758 if (output_bfd!= (bfd *)NULL) {
759 if ( howto->partial_inplace == false) {
760 /*
761 This is a partial relocation, and we want to apply the relocation
762 to the reloc entry rather than the raw data. Modify the reloc
763 inplace to reflect what we now know.
764 */
765 reloc_entry->addend = relocation ;
766 reloc_entry->section = reloc_target_input_section;
767 if (reloc_target_input_section != (asection *)NULL) {
768 /* If we know the output section we can forget the symbol */
769 reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
770 }
771 reloc_entry->address +=
772 input_section->output_offset;
773 return flag;
774 }
775 else
776 {
777 /* This is a partial relocation, but inplace, so modify the
778 reloc record a bit
779 */
780
781 }
782 }
783
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 /* Wait for the day when all have the mask in them */
799
800 /* What we do:
801 i instruction to be left alone
802 o offset within instruction
803 r relocation offset to apply
804 S src mask
805 D dst mask
806 N ~dst mask
807 A part 1
808 B part 2
809 R result
810
811 Do this:
812 i i i i i o o o o o from bfd_get<size>
813 and S S S S S to get the size offset we want
814 + r r r r r r r r r r to get the final value to place
815 and D D D D D to chop to right size
816 -----------------------
817 A A A A A
818 And this:
819 ... i i i i i o o o o o from bfd_get<size>
820 and N N N N N get instruction
821 -----------------------
822 ... B B B B B
823
824 And then:
825 B B B B B
826 or A A A A A
827 -----------------------
828 R R R R R R R R R R put into bfd_put<size>
829 */
830
831 #define DOIT(x) \
832 x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
833
834 switch (howto->size)
835 {
836 case 0:
837 {
838 char x = bfd_getchar(abfd, (char *)data + addr);
839 DOIT(x);
840 bfd_putchar(abfd,x, (unsigned char *) data + addr);
841 }
842 break;
843
844 case 1:
845 {
846 short x = bfd_getshort(abfd, (bfd_byte *)data + addr);
847 DOIT(x);
848 bfd_putshort(abfd, x, (unsigned char *)data + addr);
849 }
850 break;
851 case 2:
852 {
853 long x = bfd_getlong(abfd, (bfd_byte *) data + addr);
854 DOIT(x);
855 bfd_putlong(abfd,x, (bfd_byte *)data + addr);
856 }
857 break;
858 case 3:
859 /* Do nothing */
860 break;
861 default:
862 return bfd_reloc_other;
863 }
864
865 return flag;
866 }
867
868 void
869 bfd_assert(file, line)
870 char *file;
871 int line;
872 {
873 printf("bfd assertion fail %s:%d\n",file,line);
874 }
875
876
877 boolean
878 bfd_set_start_address(abfd, vma)
879 bfd *abfd;
880 bfd_vma vma;
881 {
882 abfd->start_address = vma;
883 return true;
884 }
885
886
887 bfd_vma bfd_log2(x)
888 bfd_vma x;
889 {
890 bfd_vma result = 0;
891 while ( (bfd_vma)(1<< result) < x)
892 result++;
893 return result;
894 }
895
896 /* bfd_get_mtime: Return cached file modification time (e.g. as read
897 from archive header for archive members, or from file system if we have
898 been called before); else determine modify time, cache it, and
899 return it. */
900
901 long
902 bfd_get_mtime (abfd)
903 bfd *abfd;
904 {
905 FILE *fp;
906 struct stat buf;
907
908 if (abfd->mtime_set)
909 return abfd->mtime;
910
911 fp = bfd_cache_lookup (abfd);
912 if (0 != fstat (fileno (fp), &buf))
913 return 0;
914
915 abfd->mtime_set = true;
916 abfd->mtime = buf.st_mtime;
917 return abfd->mtime;
918 }
This page took 0.063078 seconds and 5 git commands to generate.