+/* BFD support for handling relocation entries.
+ Copyright (C) 1990-1991 Free Software Foundation, Inc.
+ Written by Cygnus Support.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
/*doc*
@section Relocations
-Bfd maintains relocations in much the same was as it maintains
+BFD maintains relocations in much the same was as it maintains
symbols; they are left alone until required, then read in en-mass and
traslated into an internal form. There is a common routine
@code{bfd_perform_relocation} which acts upon the canonical form to to
the actual fixup.
Note that relocations are maintained on a per section basis, whilst
-symbols are maintained on a per bfd basis.
+symbols are maintained on a per BFD basis.
-All a back end has to do to fit the bfd interface is to create as many
+All a back end has to do to fit the BFD interface is to create as many
@code{struct reloc_cache_entry} as there are relocations in a
particuar section, and fill in the right bits:
#include "bfd.h"
#include "libbfd.h"
/*doc
-*node typedef arelent, Relocations, reloc handling functions, Relocations
+@node typedef arelent, Relocations, reloc handling functions, Relocations
@section typedef arelent
$ bfd_reloc_undefined,
-The relocaction was performed, but may not be ok - presently generated
+The relocation was performed, but may not be ok - presently generated
only when linking i960 coff files with i960 b.out symbols.
$ bfd_reloc_dangerous
Pointer to how to perform the required relocation
-$ struct reloc_howto_struct *howto;
+$ CONST struct reloc_howto_struct *howto;
$} arelent;
*---
/*doc*
@table @code
@item sym_ptr_ptr
-The symbol table pointer points to a pointer to the symbol ascociated with the
-relocation request. This would naturaly be the pointer into the table
+The symbol table pointer points to a pointer to the symbol associated with the
+relocation request. This would naturally be the pointer into the table
returned by the back end's get_symtab action. @xref{Symbols}. The
symbol is referenced through a pointer to a pointer so that tools like
-the linker can fixup all the symbols of the same name by modifying
+the linker can fix up all the symbols of the same name by modifying
only one pointer. The relocation routine looks in the symbol and uses
-the base of the section the symbol is attatched to and the value of
+the base of the section the symbol is attached to and the value of
the symbol as the initial relocation offset. If the symbol pointer is
zero, then the section provided is looked up.
@item address
to in a big endian world.
@item addend
The addend is a value provided by the back end to be added (!) to the
-relocation offset. It's interpretation is dependent upon the howto.
+relocation offset. Its interpretation is dependent upon the howto.
For example, on the 68k the code:
*+
I'm not sure what it means when both a symbol pointer an a section
pointer are present. Some formats use this sort of mechanism to
-describe PIC relocations, but bfd can't to that sort of thing yet.
+describe PIC relocations, but BFD can't to that sort of thing yet.
@item howto
The howto field can be imagined as a relocation instruction. It is a
pointer to a struct which contains information on what to do with all
/*proto* reloc_howto_type
The @code{reloc_howto_type} is a structure which contains all the
-information that bfd needs to know to tie up a back end's data.
+information that BFD needs to know to tie up a back end's data.
*+++
{(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
*-
+And will be replaced with the totally magic way. But for the moment,
+we are compatible, so do it this way..
+
+*+
+#define NEWHOWTO( FUNCTION, NAME,SIZE,REL) HOWTO(0,0,SIZE,0,REL,0,false,false,FUNCTION, NAME,false,0,0,false)
+*-
+
+Helper routine to turn a symbol into a relocation value.
+
+*+
+
+
+#define HOWTO_PREPARE(relocation, symbol) \
+ { \
+ if (symbol != (asymbol *)NULL) { \
+ if (symbol->flags & BSF_FORT_COMM) { \
+ relocation = 0; \
+ } \
+ else { \
+ relocation = symbol->value; \
+ } \
+ } \
+ if (symbol->section != (asection *)NULL) { \
+ relocation += symbol->section->output_section->vma + \
+ symbol->section->output_offset; \
+ } \
+}
+*-
*/
/*proto* reloc_chain
{
/*
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.
- */
+ 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;
+ input_section->output_section->vma + input_section->output_offset;
if (howto->pcrel_offset == true) {
relocation -= reloc_entry->address;
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.
- */
+ 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) {
else
{
/* This is a partial relocation, but inplace, so modify the
- reloc record a bit
- */
+ reloc record a bit.
+
+ If we've relocated with a symbol with a section, change
+ into a ref to the section belonging to the symbol
+ */
+
+ if (symbol != (asymbol *)NULL && reloc_target_input_section != (asection *)NULL)
+ {
+ reloc_entry->section = reloc_target_input_section;
+ reloc_entry->sym_ptr_ptr = (asymbol **)NULL;
+ }
}
}
}
break;
case 3:
+
/* Do nothing */
break;
default:
return flag;
}
+
+