aboutsummaryrefslogtreecommitdiff
path: root/bfd/bfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/bfd.c')
-rw-r--r--bfd/bfd.c947
1 files changed, 221 insertions, 726 deletions
diff --git a/bfd/bfd.c b/bfd/bfd.c
index b05ec9c..eb435c8 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,11 +1,3 @@
- /* -*- C -*- */
-
-/*** bfd -- binary file diddling routines by Gumby Wallace of Cygnus Support.
- Every definition in this file should be exported and declared
- in bfd.h. If you don't want it to be user-visible, put it in
- libbfd.c!
-*/
-
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Diddler.
@@ -24,55 +16,198 @@ You should have received a copy of the GNU General Public License
along with BFD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
/* $Id$ */
+
+/*proto*
+@section typedef bfd
+
+Pointers to bfd structs are the cornerstone of any application using
+libbfd. References though the bfd and to data in the bfd give the
+entire bfd functionality.
+
+Finally! The BFD struct itself. This contains the major data about
+the file, and contains pointers to the rest of the data.
+
+*+++
+
+$struct _bfd
+${
+ The filename the application opened the bfd with.
+
+$ CONST char *filename;
+
+A pointer to the target jump table.
+
+$ struct bfd_target *xvec;
+
+
+To avoid dragging too many header files into every file that
+includes bfd.h, IOSTREAM has been declared as a "char *", and MTIME
+as a "long". Their correct types, to which they are cast when used,
+are "FILE *" and "time_t".
+
+The iostream is the result of an fopen on the filename.
+
+$ char *iostream;
+
+Is the file being cached @xref{File Caching}.
+
+$ boolean cacheable;
+
+Marks whether there was a default target specified when the bfd was
+opened. This is used to select what matching algorithm to use to chose
+the back end.
+
+$ boolean target_defaulted;
+
+The caching routines use these to maintain an LRU list of bfds.
+
+$ struct _bfd *lru_prev, *lru_next;
+
+When a file is closed by the caching routines, it retains the state
+here:
+
+$ file_ptr where;
+
+and here:
+
+$ boolean opened_once;
+
+$ boolean mtime_set;
+File modified time
+
+$ long mtime;
+
+For output files, channel we locked (is this used?).
+
+$int ifd;
+
+The format which belongs to the bfd.
+
+$ bfd_format format;
+
+The direction the bfd was opened with
+
+$ enum bfd_direction {no_direction = 0,
+$ read_direction = 1,
+$ write_direction = 2,
+$ both_direction = 3} direction;
+
+Format_specific flags
+
+$ flagword flags;
+
+Currently my_archive is tested before adding origin to anything. I
+believe that this can become always an add of origin, with origin set
+to 0 for non archive files.
+
+$ file_ptr origin;
+
+Remember when output has begun, to stop strange things happening.
+
+$ boolean output_has_begun;
+
+Pointer to linked list of sections
+
+$ struct sec *sections;
+
+The number of sections
+
+$ unsigned int section_count;
+
+Stuff only usefull for object files:
+The start address.
+
+$ bfd_vma start_address;
+Used for input and output
+
+$ unsigned int symcount;
+Symtab for output bfd
+
+$ struct symbol_cache_entry **outsymbols;
+
+Architecture of object machine, eg m68k
+
+$ enum bfd_architecture obj_arch;
+
+Particular machine within arch, e.g. 68010
+
+$ unsigned long obj_machine;
+
+Stuff only usefull for archives:
+
+$ PTR arelt_data;
+$ struct _bfd *my_archive;
+$ struct _bfd *next;
+$ struct _bfd *archive_head;
+$ boolean has_armap;
+
+Used by the back end to hold private data.
+
+$ PTR tdata;
+
+Used by the application to hold private data
+
+$ PTR usrdata;
+
+Where all the allocated stuff under this BFD goes
+
+$ struct obstack memory;
+$};
+
+*---
+
+*/
#include <sysdep.h>
#include "bfd.h"
#include "libbfd.h"
+
short _bfd_host_big_endian = 0x0100;
- /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
- return 1 if the host is big-endian, 0 otherwise.
- (assuming that a short is two bytes long!!! FIXME)
- (See HOST_IS_BIG_ENDIAN_P in bfd.h.) */
+ /* Accessing the above as (*(char*)&_bfd_host_big_endian), will
+ return 1 if the host is big-endian, 0 otherwise.
+ (assuming that a short is two bytes long!!! FIXME)
+ (See HOST_IS_BIG_ENDIAN_P in bfd.h.) */
/** Error handling
o - Most functions return nonzero on success (check doc for
- precise semantics); 0 or NULL on error.
+ precise semantics); 0 or NULL on error.
o - Internal errors are documented by the value of bfd_error.
- If that is system_call_error then check errno.
+ If that is system_call_error then check errno.
o - The easiest way to report this to the user is to use bfd_perror.
*/
bfd_ec bfd_error = no_error;
-char *bfd_errmsgs[] = { "No error",
- "System call error",
- "Invalid target",
- "File in wrong format",
- "Invalid operation",
- "Memory exhausted",
- "No symbols",
- "No relocation info",
- "No more archived files",
- "Malformed archive",
- "Symbol not found",
- "File format not recognized",
- "File format is ambiguous",
- "Section has no contents",
- "Nonrepresentable section on output",
- "#<Invalid error code>"
- };
+char *bfd_errmsgs[] = { "No error",
+ "System call error",
+ "Invalid target",
+ "File in wrong format",
+ "Invalid operation",
+ "Memory exhausted",
+ "No symbols",
+ "No relocation info",
+ "No more archived files",
+ "Malformed archive",
+ "Symbol not found",
+ "File format not recognized",
+ "File format is ambiguous",
+ "Section has no contents",
+ "Nonrepresentable section on output",
+ "#<Invalid error code>"
+ };
static
void
DEFUN(bfd_nonrepresentable_section,(abfd, name),
- CONST bfd * CONST abfd AND
- CONST char * CONST name)
+ CONST bfd * CONST abfd AND
+ CONST char * CONST name)
{
printf("bfd error writing file %s, format %s can't represent section %s\n",
- abfd->filename,
- abfd->xvec->name,
- name);
+ abfd->filename,
+ abfd->xvec->name,
+ name);
exit(1);
}
@@ -90,7 +225,7 @@ strerror (code)
extern char *sys_errlist[];
return (((code < 0) || (code >= sys_nerr)) ? "(unknown error)" :
- sys_errlist [code]);
+ sys_errlist [code]);
}
#endif /* not ANSI_LIBRARIES */
@@ -127,7 +262,7 @@ DEFUN(bfd_perror,(message),
CONST char *message)
{
if (bfd_error == system_call_error)
- perror((char *)message); /* must be system error then... */
+ perror((char *)message); /* must be system error then... */
else {
if (message == NULL || *message == '\0')
fprintf (stderr, "%s\n", bfd_errmsg (bfd_error));
@@ -136,415 +271,11 @@ DEFUN(bfd_perror,(message),
}
}
-/* for error messages */
-char *
-bfd_format_string (format)
- bfd_format format;
-{
- if (((int)format <(int) bfd_unknown) || ((int)format >=(int) bfd_type_end)) return "invalid";
-
- switch (format) {
- case bfd_object: return "object"; /* linker/assember/compiler output */
- case bfd_archive: return "archive"; /* object archive file */
- case bfd_core: return "core"; /* core dump */
- default: return "unknown";
- }
-}
-
-/** Target configurations */
-
-extern bfd_target *target_vector[];
-extern bfd_target *default_vector[];
-
-/* Returns a pointer to the transfer vector for the object target
- named target_name. If target_name is NULL, chooses the one in the
- environment variable GNUTARGET; if that is null or not defined then
- the first entry in the target list is chosen. Passing in the
- string "default" or setting the environment variable to "default"
- will cause the first entry in the target list to be returned,
- and "target_defaulted" will be set in the bfd. This causes
- bfd_check_format to loop over all the targets to find the one
- that matches the file being read. */
-
-bfd_target *
-DEFUN(bfd_find_target,(target_name, abfd),
- CONST char *target_name AND
- bfd *abfd)
-{
- bfd_target **target;
- extern char *getenv ();
- CONST char *targname = (target_name ? target_name : getenv ("GNUTARGET"));
-
- /* This is safe; the vector cannot be null */
- if (targname == NULL || !strcmp (targname, "default")) {
- abfd->target_defaulted = true;
- return abfd->xvec = target_vector[0];
- }
-
- abfd->target_defaulted = false;
-
- for (target = &target_vector[0]; *target != NULL; target++) {
- if (!strcmp (targname, (*target)->name))
- return abfd->xvec = *target;
- }
-
- bfd_error = invalid_target;
- return NULL;
-}
-
-
-/* Returns a freshly-consed, NULL-terminated vector of the names of all the
- valid bfd targets. Do not modify the names */
-
-char **
-bfd_target_list ()
-{
- int vec_length= 0;
- bfd_target **target;
- char **name_list, **name_ptr;
-
- for (target = &target_vector[0]; *target != NULL; target++)
- vec_length++;
-
- name_ptr = name_list = (char **) zalloc ((vec_length + 1) * sizeof (char **));
-
- if (name_list == NULL) {
- bfd_error = no_memory;
- return NULL;
- }
-
- for (target = &target_vector[0]; *target != NULL; target++)
- *(name_ptr++) = (*target)->name;
-
- return name_list;
-}
-
-/* Init a bfd for read of the proper format. If the target was unspecified,
- search all the possible targets. */
-
-boolean
-DEFUN(bfd_check_format,(abfd, format),
- bfd *abfd AND
- bfd_format format)
-{
- bfd_target **target, *save_targ, *right_targ;
- int match_count;
-
- if (!bfd_read_p (abfd) ||
- ((int)(abfd->format) < (int)bfd_unknown) ||
- ((int)(abfd->format) >= (int)bfd_type_end)) {
- bfd_error = invalid_operation;
- return false;
- }
-
- if (abfd->format != bfd_unknown)
- return (abfd->format == format)? true: false;
-
- /* presume the answer is yes */
- abfd->format = format;
-
- /* If the target type was explicitly specified, just check that target. */
-
- if (!abfd->target_defaulted) {
- bfd_seek (abfd, (file_ptr)0, SEEK_SET); /* rewind! */
-
- right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
- if (right_targ) {
- abfd->xvec = right_targ; /* Set the target as returned */
- return true; /* File position has moved, BTW */
- }
- return false; /* Specified target is not right */
- }
-
- /* Since the target type was defaulted, check them
- all in the hope that one will be uniquely recognized. */
-
- save_targ = abfd->xvec;
- match_count = 0;
- right_targ = 0;
-
- for (target = target_vector; *target != NULL; target++) {
- bfd_target *temp;
-
- abfd->xvec = *target; /* Change BFD's target temporarily */
- bfd_seek (abfd, (file_ptr)0, SEEK_SET);
- temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
- if (temp) { /* This format checks out as ok! */
- right_targ = temp;
- match_count++;
- /* If this is the default target, accept it, even if other targets
- might match. People who want those other targets have to set
- the GNUTARGET variable. */
- if (temp == default_vector[0])
- break;
-#ifdef GNU960
- /* Big- and little-endian b.out archives look the same, but it doesn't
- * matter: there is no difference in their headers, and member file byte
- * orders will (I hope) be handled appropriately by bfd. Ditto for big
- * and little coff archives. And the 4 coff/b.out object formats are
- * unambiguous. So accept the first match we find.
- */
- break;
-#endif
- }
- }
-
- if (match_count == 1) {
- abfd->xvec = right_targ; /* Change BFD's target permanently */
- return true; /* File position has moved, BTW */
- }
-
- abfd->xvec = save_targ; /* Restore original target type */
- abfd->format = bfd_unknown; /* Restore original format */
- bfd_error = ((match_count == 0) ? file_not_recognized :
- file_ambiguously_recognized);
- return false;
-}
-
-boolean
-DEFUN(bfd_set_format,(abfd, format),
- bfd *abfd AND
- bfd_format format)
-{
-
- if (bfd_read_p (abfd) ||
- ((int)abfd->format < (int)bfd_unknown) ||
- ((int)abfd->format >= (int)bfd_type_end)) {
- bfd_error = invalid_operation;
- return false;
- }
-
- if (abfd->format != bfd_unknown) return (abfd->format == format) ? true:false;
-
- /* presume the answer is yes */
- abfd->format = format;
-
- if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
- abfd->format = bfd_unknown;
- return false;
- }
-
- return true;
-}
-
-/* Hack object and core file sections */
-
-sec_ptr
-DEFUN(bfd_get_section_by_name,(abfd, name),
- bfd *abfd AND
- CONST char *name)
-{
- asection *sect;
-
- for (sect = abfd->sections; sect != NULL; sect = sect->next)
- if (!strcmp (sect->name, name)) return sect;
- return NULL;
-}
-
-/* If you try to create a section with a name which is already in use,
- returns the old section by that name instead. */
-sec_ptr
-DEFUN(bfd_make_section,(abfd, name),
- bfd *abfd AND
- CONST char *CONST name)
-{
- asection *newsect;
- asection ** prev = &abfd->sections;
- asection * sect = abfd->sections;
-
- if (abfd->output_has_begun) {
- bfd_error = invalid_operation;
- return NULL;
- }
-
- while (sect) {
- if (!strcmp(sect->name, name)) return sect;
- prev = &sect->next;
- sect = sect->next;
- }
-
- newsect = (asection *) bfd_zalloc(abfd, sizeof (asection));
- if (newsect == NULL) {
- bfd_error = no_memory;
- return NULL;
- }
-
- newsect->name = name;
- newsect->index = abfd->section_count++;
- newsect->flags = SEC_NO_FLAGS;
-
- newsect->userdata = 0;
- newsect->next = (asection *)NULL;
- newsect->relocation = (arelent *)NULL;
- newsect->reloc_count = 0;
- newsect->line_filepos =0;
-
- if (BFD_SEND (abfd, _new_section_hook, (abfd, newsect)) != true) {
- free (newsect);
- return NULL;
- }
-
- *prev = newsect;
- return newsect;
-}
-
-/* Call operation on each section. Operation gets three args: the bfd,
- the section, and a void * pointer (whatever the user supplied). */
-
-/* This is attractive except that without lexical closures its use is hard
- to make reentrant. */
-/*VARARGS2*/
-void
-bfd_map_over_sections (abfd, operation, user_storage)
- bfd *abfd;
- void (*operation)();
- PTR user_storage;
-{
- asection *sect;
- int i = 0;
-
- for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
- (*operation) (abfd, sect, user_storage);
-
- if (i != abfd->section_count) /* Debugging */
- abort();
-}
-
-boolean
-bfd_set_section_flags (abfd, section, flags)
- bfd *abfd;
- sec_ptr section;
- flagword flags;
-{
- if ((flags & bfd_applicable_section_flags (abfd)) != flags) {
- bfd_error = invalid_operation;
- return false;
- }
-
- section->flags = flags;
-return true;
-}
-
-
-boolean
-bfd_set_section_size (abfd, ptr, val)
- bfd *abfd;
- sec_ptr ptr;
- unsigned long val;
-{
- /* Once you've started writing to any section you cannot create or change
- the size of any others. */
-
- if (abfd->output_has_begun) {
- bfd_error = invalid_operation;
- return false;
- }
-
- ptr->size = val;
-
- return true;
-}
-
-boolean
-DEFUN(bfd_set_section_contents,(abfd, section, location, offset, count),
- bfd *abfd AND
- sec_ptr section AND
- PTR location AND
- file_ptr offset AND
- bfd_size_type count)
-{
- if (!(bfd_get_section_flags(abfd, section) &
- SEC_HAS_CONTENTS)) {
- bfd_error = no_contents;
- return(false);
- } /* if section has no contents */
-
- if (BFD_SEND (abfd, _bfd_set_section_contents,
- (abfd, section, location, offset, count))) {
- abfd->output_has_begun = true;
- return true;
- }
-
- return false;
-}
-
-boolean
-DEFUN(bfd_get_section_contents,(abfd, section, location, offset, count),
- bfd *abfd AND
- sec_ptr section AND
- PTR location AND
- file_ptr offset AND
- bfd_size_type count)
-{
- if (section->flags & SEC_CONSTRUCTOR) {
- memset(location, 0, (unsigned)count);
- return true;
- }
- else {
- return (BFD_SEND (abfd, _bfd_get_section_contents,
- (abfd, section, location, offset, count)));
- }
-}
-
-
-/** Some core file info commands */
-
-/* Returns a read-only string explaining what program was running when
- it failed. */
-
-char *
-bfd_core_file_failing_command (abfd)
- bfd *abfd;
-{
- if (abfd->format != bfd_core) {
- bfd_error = invalid_operation;
- return NULL;
- }
- return BFD_SEND (abfd, _core_file_failing_command, (abfd));
-}
-
-int
-bfd_core_file_failing_signal (abfd)
- bfd *abfd;
-{
- if (abfd->format != bfd_core) {
- bfd_error = invalid_operation;
- return 0;
- }
- return BFD_SEND (abfd, _core_file_failing_signal, (abfd));
-}
-
-boolean
-core_file_matches_executable_p (core_bfd, exec_bfd)
- bfd *core_bfd, *exec_bfd;
-{
- if ((core_bfd->format != bfd_core) || (exec_bfd->format != bfd_object)) {
- bfd_error = wrong_format;
- return false;
- }
-
- return BFD_SEND (core_bfd, _core_file_matches_executable_p, (core_bfd, exec_bfd));
-}
-
+
/** Symbols */
-boolean
-bfd_set_symtab (abfd, location, symcount)
- bfd *abfd;
- asymbol **location;
- unsigned int symcount;
-{
- if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
- bfd_error = invalid_operation;
- return false;
- }
-
- bfd_get_outsymbols (abfd) = location;
- bfd_get_symcount (abfd) = symcount;
- return true;
-}
-
/* returns the number of octets of storage required */
+
unsigned int
get_reloc_upper_bound (abfd, asect)
bfd *abfd;
@@ -573,32 +304,6 @@ bfd_canonicalize_reloc (abfd, asect, location, symbols)
return BFD_SEND (abfd, _bfd_canonicalize_reloc, (abfd, asect, location, symbols));
}
-void
-bfd_print_symbol_vandf(file, symbol)
-PTR file;
-asymbol *symbol;
-{
- flagword type = symbol->flags;
- if (symbol->section != (asection *)NULL)
- {
-
- fprintf_vma(file, symbol->value+symbol->section->vma);
- }
- else
- {
- fprintf_vma(file, symbol->value);
- }
- fprintf(file," %c%c%c%c%c%c%c",
- (type & BSF_LOCAL) ? 'l':' ',
- (type & BSF_GLOBAL) ? 'g' : ' ',
- (type & BSF_IMPORT) ? 'i' : ' ',
- (type & BSF_EXPORT) ? 'e' : ' ',
- (type & BSF_UNDEFINED) ? 'u' : ' ',
- (type & BSF_FORT_COMM) ? 'c' : ' ',
- (type & BSF_DEBUGGING) ? 'd' :' ');
-
-}
-
boolean
bfd_set_file_flags (abfd, flags)
@@ -635,250 +340,6 @@ bfd_set_reloc (ignore_abfd, asect, location, count)
asect->orelocation = location;
asect->reloc_count = count;
}
-/*
-If an output_bfd is supplied to this function the generated image
-will be relocatable, the relocations are copied to the output file
-after they have been changed to reflect the new state of the world.
-There are two ways of reflecting the results of partial linkage in an
-output file; by modifying the output data in place, and by modifying
-the relocation record. Some native formats (eg basic a.out and basic
-coff) have no way of specifying an addend in the relocation type, so
-the addend has to go in the output data. This is no big deal since in
-these formats the output data slot will always be big enough for the
-addend. Complex reloc types with addends were invented to solve just
-this problem.
-*/
-
-bfd_reloc_status_enum_type
-DEFUN(bfd_perform_relocation,(abfd,
- reloc_entry,
- data,
- input_section,
- output_bfd),
- bfd *abfd AND
- arelent *reloc_entry AND
- PTR data AND
- asection *input_section AND
- bfd *output_bfd)
-{
- bfd_vma relocation;
- bfd_reloc_status_enum_type flag = bfd_reloc_ok;
- bfd_vma addr = reloc_entry->address ;
- bfd_vma output_base = 0;
- reloc_howto_type *howto = reloc_entry->howto;
- asection *reloc_target_output_section;
- asection *reloc_target_input_section;
- asymbol *symbol;
-
- if (reloc_entry->sym_ptr_ptr) {
- symbol = *( reloc_entry->sym_ptr_ptr);
- if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) {
- flag = bfd_reloc_undefined;
- }
- }
- else {
- symbol = (asymbol*)NULL;
- }
-
- if (howto->special_function){
- bfd_reloc_status_enum_type cont;
- cont = howto->special_function(abfd,
- reloc_entry,
- symbol,
- data,
- input_section);
- if (cont != bfd_reloc_continue) return cont;
- }
-
- /*
- Work out which section the relocation is targetted at and the
- initial relocation command value.
- */
-
-
- if (symbol != (asymbol *)NULL){
- if (symbol->flags & BSF_FORT_COMM) {
- relocation = 0;
- }
- else {
- relocation = symbol->value;
- }
- if (symbol->section != (asection *)NULL)
- {
- reloc_target_input_section = symbol->section;
- }
- else {
- reloc_target_input_section = (asection *)NULL;
- }
- }
- else if (reloc_entry->section != (asection *)NULL)
- {
- relocation = 0;
- reloc_target_input_section = reloc_entry->section;
- }
- else {
- relocation = 0;
- reloc_target_input_section = (asection *)NULL;
- }
-
-
- if (reloc_target_input_section != (asection *)NULL) {
-
- reloc_target_output_section =
- reloc_target_input_section->output_section;
-
- if (output_bfd && howto->partial_inplace==false) {
- output_base = 0;
- }
- else {
- output_base = reloc_target_output_section->vma;
-
- }
-
- relocation += output_base + reloc_target_input_section->output_offset;
- }
-
- relocation += reloc_entry->addend ;
-
-
- if(reloc_entry->address > (bfd_vma)(input_section->size))
- {
- return bfd_reloc_outofrange;
- }
-
-
- if (howto->pc_relative == true)
- {
- /*
- Anything which started out as pc relative should end up that
- way too.
-
- There are two ways we can see a pcrel instruction. Sometimes
- the pcrel displacement has been partially calculated, it
- includes the distance from the start of the section to the
- instruction in it (eg sun3), and sometimes the field is
- totally blank - eg m88kbcs.
- */
-
-
- relocation -=
- output_base + input_section->output_offset;
-
- if (howto->pcrel_offset == true) {
- relocation -= reloc_entry->address;
- }
-
- }
-
- if (output_bfd!= (bfd *)NULL) {
- if ( howto->partial_inplace == false) {
- /*
- This is a partial relocation, and we want to apply the relocation
- to the reloc entry rather than the raw data. Modify the reloc
- inplace to reflect what we now know.
- */
- reloc_entry->addend = relocation ;
- reloc_entry->section = reloc_target_input_section;
- if (reloc_target_input_section != (asection *)NULL) {
- /* If we know the output section we can forget the symbol */
- reloc_entry->sym_ptr_ptr = (asymbol**)NULL;
- }
- reloc_entry->address +=
- input_section->output_offset;
- return flag;
- }
- else
- {
- /* This is a partial relocation, but inplace, so modify the
- reloc record a bit
- */
-
- }
- }
-
- reloc_entry->addend = 0;
-
-
- /*
- Either we are relocating all the way, or we don't want to apply
- the relocation to the reloc entry (probably because there isn't
- any room in the output format to describe addends to relocs)
- */
- relocation >>= howto->rightshift;
-
- /* Shift everything up to where it's going to be used */
-
- relocation <<= howto->bitpos;
-
- /* Wait for the day when all have the mask in them */
-
- /* What we do:
- i instruction to be left alone
- o offset within instruction
- r relocation offset to apply
- S src mask
- D dst mask
- N ~dst mask
- A part 1
- B part 2
- R result
-
- Do this:
- i i i i i o o o o o from bfd_get<size>
- and S S S S S to get the size offset we want
- + r r r r r r r r r r to get the final value to place
- and D D D D D to chop to right size
- -----------------------
- A A A A A
- And this:
- ... i i i i i o o o o o from bfd_get<size>
- and N N N N N get instruction
- -----------------------
- ... B B B B B
-
- And then:
- B B B B B
- or A A A A A
- -----------------------
- R R R R R R R R R R put into bfd_put<size>
- */
-
-#define DOIT(x) \
- x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask))
-
- switch (howto->size)
- {
- case 0:
- {
- char x = bfd_get_8(abfd, (char *)data + addr);
- DOIT(x);
- bfd_put_8(abfd,x, (unsigned char *) data + addr);
- }
- break;
-
- case 1:
- {
- short x = bfd_get_16(abfd, (bfd_byte *)data + addr);
- DOIT(x);
- bfd_put_16(abfd, x, (unsigned char *)data + addr);
- }
- break;
- case 2:
- {
- long x = bfd_get_32(abfd, (bfd_byte *) data + addr);
- DOIT(x);
- bfd_put_32(abfd,x, (bfd_byte *)data + addr);
- }
- break;
- case 3:
- /* Do nothing */
- break;
- default:
- return bfd_reloc_other;
- }
-
- return flag;
-}
void
bfd_assert(file, line)
@@ -889,6 +350,14 @@ int line;
}
+/*proto* bfd_set_start_address
+
+Marks the entry point of an output bfd. Returns @code{true} on
+success, @code{false} otherwise.
+
+*; PROTO(boolean, bfd_set_start_address,(bfd *, bfd_vma));
+*/
+
boolean
bfd_set_start_address(abfd, vma)
bfd *abfd;
@@ -899,19 +368,15 @@ bfd_vma vma;
}
-bfd_vma bfd_log2(x)
-bfd_vma x;
-{
- bfd_vma result = 0;
- while ( (bfd_vma)(1<< result) < x)
- result++;
- return result;
-}
+/*proto* bfd_get_mtime
+
+Return cached file modification time (e.g. as read from archive header
+for archive members, or from file system if we have been called
+before); else determine modify time, cache it, and return it.
-/* bfd_get_mtime: Return cached file modification time (e.g. as read
- from archive header for archive members, or from file system if we have
- been called before); else determine modify time, cache it, and
- return it. */
+*;PROTO(long, bfd_get_mtime, (bfd *));
+
+*/
long
bfd_get_mtime (abfd)
@@ -931,3 +396,33 @@ bfd_get_mtime (abfd)
abfd->mtime = buf.st_mtime;
return abfd->mtime;
}
+
+/*proto*
+*i stuff
+*+
+#define bfd_sizeof_headers(abfd, reloc) \
+ BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))
+
+#define bfd_find_nearest_line(abfd, section, symbols, offset, filename_ptr, func, line_ptr) \
+ BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, section, symbols, offset, filename_ptr, func, line_ptr))
+
+#define bfd_debug_info_start(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
+
+#define bfd_debug_info_end(abfd) \
+ BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
+
+#define bfd_debug_info_accumulate(abfd, section) \
+ BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
+
+#define bfd_stat_arch_elt(abfd, stat) \
+ BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))
+*-
+
+*/
+
+
+
+
+
+