Fixed all the places where there were problems with the size and
[deliverable/binutils-gdb.git] / bfd / bfd.c
CommitLineData
4a81b561
DHW
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
11This file is part of BFD, the Binary File Diddler.
12
13BFD is free software; you can redistribute it and/or modify
14it under the terms of the GNU General Public License as published by
15the Free Software Foundation; either version 1, or (at your option)
16any later version.
17
18BFD is distributed in the hope that it will be useful,
19but WITHOUT ANY WARRANTY; without even the implied warranty of
20MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21GNU General Public License for more details.
22
23You should have received a copy of the GNU General Public License
24along with BFD; see the file COPYING. If not, write to
25the 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
32short _bfd_host_big_endian = 0x0100;
33 /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
fc723380
JG
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.) */
4a81b561
DHW
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
46bfd_ec bfd_error = no_error;
47
fc723380
JG
48char *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>"
4a81b561
DHW
64 };
65
9846338e
SC
66static
67void
68DEFUN(bfd_nonrepresentable_section,(abfd, name),
69 CONST bfd * CONST abfd AND
70 CONST char * CONST name)
71{
1f4d3c79
SC
72 printf("bfd error writing file %s, format %s can't represent section %s\n",
73 abfd->filename,
74 abfd->xvec->name,
75 name);
9846338e
SC
76 exit(1);
77}
fc723380 78
9846338e
SC
79bfd_error_vector_type bfd_error_vector =
80 {
81 bfd_nonrepresentable_section
82 };
83
4a81b561
DHW
84#if !defined(ANSI_LIBRARIES)
85char *
86strerror (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
9846338e 97
4a81b561
DHW
98char *
99bfd_errmsg (error_tag)
100 bfd_ec error_tag;
101{
4a81b561
DHW
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
9846338e
SC
113
114void bfd_default_error_trap(error_tag)
115bfd_ec error_tag;
116{
117 printf("bfd assert fail (%s)\n", bfd_errmsg(error_tag));
118}
119
120void (*bfd_error_trap)() = bfd_default_error_trap;
121void (*bfd_error_nonrepresentabltrap)() = bfd_default_error_trap;
fc723380 122
4a81b561 123void
1f4d3c79
SC
124DEFUN(bfd_perror,(message),
125 CONST char *message)
4a81b561
DHW
126{
127 if (bfd_error == system_call_error)
fc723380 128 perror((char *)message); /* must be system error then... */
4a81b561
DHW
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 */
138char *
139bfd_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
154extern 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
163bfd_target *
9846338e
SC
164DEFUN(bfd_find_target,(target_name),
165 CONST char *target_name)
4a81b561
DHW
166{
167 bfd_target **target;
168 extern char *getenv ();
9846338e 169 CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
4a81b561
DHW
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
187char **
188bfd_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
221boolean
222bfd_check_format (abfd, format)
223 bfd *abfd;
224 bfd_format format;
225{
4a81b561
DHW
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
fc723380 241 bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* rewind! */
4a81b561
DHW
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 */
4a81b561
DHW
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++;
9846338e
SC
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
4a81b561
DHW
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);
4a81b561
DHW
287 return false;
288}
289
290boolean
291bfd_set_format (abfd, format)
292 bfd *abfd;
293 bfd_format format;
294{
9872a49c 295
4a81b561
DHW
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
4a81b561
DHW
308 if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
309 abfd->format = bfd_unknown;
4a81b561
DHW
310 return false;
311 }
312
313 return true;
314}
315\f
316/* Hack object and core file sections */
317
318sec_ptr
9846338e
SC
319DEFUN(bfd_get_section_by_name,(abfd, name),
320 bfd *abfd AND
321 CONST char *name)
4a81b561
DHW
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. */
332sec_ptr
9846338e
SC
333DEFUN(bfd_make_section,(abfd, name),
334 bfd *abfd AND
335 CONST char *name)
4a81b561
DHW
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
9872a49c 352 newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
4a81b561
DHW
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
4a81b561
DHW
362 newsect->userdata = 0;
363 newsect->next = (asection *)NULL;
364 newsect->relocation = (arelent *)NULL;
365 newsect->reloc_count = 0;
366 newsect->line_filepos =0;
9872a49c 367
4a81b561
DHW
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*/
383void
384bfd_map_over_sections (abfd, operation, user_storage)
385 bfd *abfd;
386 void (*operation)();
9846338e 387 PTR user_storage;
4a81b561
DHW
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
399boolean
400bfd_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;
411return true;
412}
413
414
415boolean
416bfd_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
434boolean
435bfd_set_section_contents (abfd, section, location, offset, count)
436 bfd *abfd;
437 sec_ptr section;
9846338e 438 PTR location;
4a81b561
DHW
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
457boolean
458bfd_get_section_contents (abfd, section, location, offset, count)
459 bfd *abfd;
460 sec_ptr section;
9846338e 461 PTR location;
4a81b561
DHW
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
481char *
482bfd_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
492int
493bfd_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
503boolean
504core_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
517boolean
518bfd_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 */
534unsigned int
535get_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
547unsigned int
548bfd_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
562void
563bfd_print_symbol_vandf(file, symbol)
9846338e 564PTR file;
4a81b561
DHW
565asymbol *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
588boolean
589bfd_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;
609return true;
610}
611
612
613void
614bfd_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/*
624If an output_bfd is supplied to this function the generated image
625will be relocatable, the relocations are copied to the output file
626after they have been changed to reflect the new state of the world.
627There are two ways of reflecting the results of partial linkage in an
628output file; by modifying the output data in place, and by modifying
629the relocation record. Some native formats (eg basic a.out and basic
630coff) have no way of specifying an addend in the relocation type, so
631the addend has to go in the output data. This is no big deal since in
632these formats the output data slot will always be big enough for the
633addend. Complex reloc types with addends were invented to solve just
634this problem.
635*/
636
637bfd_reloc_status_enum_type
638bfd_perform_relocation(abfd,
639 reloc_entry,
640 data,
641 input_section,
642 output_bfd)
643bfd *abfd;
644arelent *reloc_entry;
9846338e 645PTR data;
4a81b561
DHW
646asection *input_section;
647bfd *output_bfd;
648{
649 bfd_vma relocation;
650 bfd_reloc_status_enum_type flag = bfd_reloc_ok;
4a81b561
DHW
651 bfd_vma addr = reloc_entry->address ;
652 bfd_vma output_base = 0;
fc723380 653 reloc_howto_type *howto = reloc_entry->howto;
4a81b561
DHW
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
9846338e 668 if (howto->special_function){
4a81b561
DHW
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 /*
9846338e
SC
679 Work out which section the relocation is targetted at and the
680 initial relocation command value.
681 */
4a81b561
DHW
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)
9846338e
SC
692 {
693 reloc_target_input_section = symbol->section;
694 }
4a81b561
DHW
695 else {
696 reloc_target_input_section = (asection *)NULL;
697 }
698 }
699 else if (reloc_entry->section != (asection *)NULL)
9846338e
SC
700 {
701 relocation = 0;
702 reloc_target_input_section = reloc_entry->section;
703 }
4a81b561
DHW
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))
9846338e
SC
730 {
731 return bfd_reloc_outofrange;
732 }
4a81b561
DHW
733
734
735 if (howto->pc_relative == true)
9846338e
SC
736 {
737 /*
738 Anything which started out as pc relative should end up that
4cddd1c9
SC
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.
9846338e 746 */
4a81b561 747
4cddd1c9 748
9846338e
SC
749 relocation -=
750 output_base + input_section->output_offset;
4a81b561 751
4cddd1c9
SC
752 if (howto->pcrel_offset == true) {
753 relocation -= reloc_entry->address;
754 }
755
9846338e 756 }
4a81b561 757
1f4d3c79
SC
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;
4a81b561 774 }
1f4d3c79
SC
775 else
776 {
777 /* This is a partial relocation, but inplace, so modify the
778 reloc record a bit
779 */
780
781 }
4a81b561 782 }
1f4d3c79
SC
783
784 reloc_entry->addend = 0;
4a81b561
DHW
785
786
1f4d3c79
SC
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;
4a81b561 793
1f4d3c79 794 /* Shift everything up to where it's going to be used */
4a81b561 795
1f4d3c79
SC
796 relocation <<= howto->bitpos;
797
1f4d3c79
SC
798 /* Wait for the day when all have the mask in them */
799
1f4d3c79
SC
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 */
4a81b561 830
9846338e 831#define DOIT(x) \
1f4d3c79
SC
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
4a81b561
DHW
865 return flag;
866}
867
868void
869bfd_assert(file, line)
870char *file;
871int line;
872{
873 printf("bfd assertion fail %s:%d\n",file,line);
874}
875
876
877boolean
878bfd_set_start_address(abfd, vma)
879bfd *abfd;
880bfd_vma vma;
881{
882 abfd->start_address = vma;
883 return true;
884}
885
886
887bfd_vma bfd_log2(x)
888bfd_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
901long
902bfd_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.058397 seconds and 4 git commands to generate.