diff options
author | Fred Fish <fnf@specifix.com> | 1992-08-09 06:16:44 +0000 |
---|---|---|
committer | Fred Fish <fnf@specifix.com> | 1992-08-09 06:16:44 +0000 |
commit | 671450818af171e95039e07089ba13b3d05d81c7 (patch) | |
tree | 3b3e37bb5ce893acbc6d70f1c897802750e9bbea /bfd | |
parent | 50055e94a1d558f9f8edce1c07e90560d7161b76 (diff) | |
download | gdb-671450818af171e95039e07089ba13b3d05d81c7.zip gdb-671450818af171e95039e07089ba13b3d05d81c7.tar.gz gdb-671450818af171e95039e07089ba13b3d05d81c7.tar.bz2 |
* bout.c (bfd_reloc_status_type, callj_callback): Cast void*
pointers to bfd_byte* before performing arithmetic on them. Such
use with bare void* pointers is a gcc extension.
* cache.c (bfd_cache_delete): Forward decl with prototype form.
* archive (normalize): Add to CONST to match actual usages with
CONST.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/bout.c | 660 |
2 files changed, 559 insertions, 110 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 94b8054..b4d39f9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +Sat Aug 8 23:15:35 1992 Fred Fish (fnf@cygnus.com) + + * bout.c (bfd_reloc_status_type, callj_callback): Cast void* + pointers to bfd_byte* before performing arithmetic on them. Such + use with bare void* pointers is a gcc extension. + * cache.c (bfd_cache_delete): Forward decl with prototype form. + * archive (normalize): Add to CONST to match actual usages with + CONST. + Mon Aug 3 00:35:29 1992 Fred Fish (fnf@cygnus.com) * configure.in: Recognize i486 host cpu, and use i386-elf @@ -18,17 +18,18 @@ 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. */ -/* $Id$ */ #include "bfd.h" #include "sysdep.h" #include "libbfd.h" - +#include "seclet.h" #include "bout.h" #include "aout/stab_gnu.h" #include "libaout.h" /* BFD a.out internal data structures */ + +extern bfd_error_vector_type bfd_error_vector; PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section)); PROTO (static bfd_target *, b_out_callback, (bfd *)); @@ -65,6 +66,7 @@ DEFUN(bout_swap_exec_header_in,(abfd, raw_bytes, execp), execp->a_talign = bytes->e_talign[0]; execp->a_dalign = bytes->e_dalign[0]; execp->a_balign = bytes->e_balign[0]; + execp->a_relaxable = bytes->e_relaxable[0]; } /* Swaps the information in an internal exec header structure into the @@ -96,7 +98,7 @@ DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes), bytes->e_talign[0] = execp->a_talign; bytes->e_dalign[0] = execp->a_dalign; bytes->e_balign[0] = execp->a_balign; - bytes->e_unused[0] = 0; /* Clean structs are godly structs */ + bytes->e_relaxable[0] = execp->a_relaxable; } @@ -168,10 +170,12 @@ b_out_callback (abfd) obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); - adata(abfd).page_size = 1; /* Not applicable. */ + adata(abfd).page_size = 1; /* Not applicable. */ adata(abfd).segment_size = 1; /* Not applicable. */ adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE; + if (execp->a_relaxable) + abfd->flags |= BFD_IS_RELAXABLE; return abfd->xvec; } @@ -258,59 +262,149 @@ b_out_write_object_contents (abfd) /** Some reloc hackery */ #define CALLS 0x66003800 /* Template for 'calls' instruction */ -#define BAL 0x0b000000 /* Template for 'bal' instruction */ +#define BAL 0x0b000000 /* Template for 'bal' instruction */ +#define BALX 0x85000000 /* Template for 'balx' instruction */ #define BAL_MASK 0x00ffffff +#define CALL 0x09000000 +#define PCREL13_MASK 0x1fff +/* Magic to turn callx into calljx */ +static bfd_reloc_status_type +DEFUN (calljx_callback, (abfd, reloc_entry, src, dst, input_section), + bfd *abfd AND + arelent *reloc_entry AND + PTR src AND + PTR dst AND + + asection *input_section) +{ + int word = bfd_get_32(abfd, src); + asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); + aout_symbol_type *symbol = aout_symbol(symbol_in); + if (IS_CALLNAME(symbol->other)) + { + + aout_symbol_type *balsym = symbol+1; + int inst = bfd_get_32(abfd, (bfd_byte *) src-4); + /* The next symbol should be an N_BALNAME */ + BFD_ASSERT(IS_BALNAME(balsym->other)); + inst &= BAL_MASK; + inst |= BALX; + bfd_put_32(abfd, inst, (bfd_byte *) dst-4); + symbol = balsym; + } + + word += symbol->symbol.section->output_offset + + symbol->symbol.section->output_section->vma + + symbol->symbol.value + reloc_entry->addend; + + bfd_put_32(abfd, word, dst); + return bfd_reloc_ok; +} + + +/* Magic to turn call into callj */ static bfd_reloc_status_type -callj_callback(abfd, reloc_entry, symbol_in, data, input_section) -bfd *abfd; -arelent *reloc_entry; -asymbol *symbol_in; -PTR data; -asection *input_section; +DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx, input_section), + bfd *abfd AND + arelent *reloc_entry AND + PTR data AND + unsigned int srcidx AND + unsigned int dstidx AND + asection *input_section ) { - int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address); + int word = bfd_get_32(abfd, (bfd_byte *) data + srcidx); + asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr); + aout_symbol_type *symbol = aout_symbol(symbol_in); - if (IS_OTHER(symbol->other)) { + if (IS_OTHER(symbol->other)) + { /* Call to a system procedure - replace code with system procedure number */ word = CALLS | (symbol->other - 1); - bfd_put_32(abfd, word, (bfd_byte *)data + reloc_entry->address); /* rplc */ - return bfd_reloc_ok; + } - if (IS_CALLNAME(symbol->other)) { + else if (IS_CALLNAME(symbol->other)) + { aout_symbol_type *balsym = symbol+1; /* The next symbol should be an N_BALNAME */ BFD_ASSERT(IS_BALNAME(balsym->other)); /* We are calling a leaf - so replace the call instruction with a bal */ - + word = BAL | - (((word & BAL_MASK) + - balsym->symbol.section->output_offset + - balsym->symbol.section->output_section->vma+ - balsym->symbol.value + reloc_entry->addend - - ( input_section->output_section->vma + input_section->output_offset)) - & BAL_MASK); - - bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address); /* rplc */ - return bfd_reloc_ok; + (((word & BAL_MASK) + + balsym->symbol.section->output_offset + + balsym->symbol.section->output_section->vma+ + balsym->symbol.value + reloc_entry->addend - dstidx - + ( input_section->output_section->vma + input_section->output_offset)) + & BAL_MASK); + + } - return bfd_reloc_continue; + else + { + word = CALL | + (((word & BAL_MASK) + + symbol->symbol.section->output_offset + + symbol->symbol.section->output_section->vma+ + symbol->symbol.value + reloc_entry->addend - dstidx - + ( input_section->output_section->vma + input_section->output_offset)) + & BAL_MASK); + } + bfd_put_32(abfd, word, (bfd_byte *) data + dstidx); + return bfd_reloc_ok; } + /* type rshift size bitsize pcrel bitpos absolute overflow check*/ +#define ABS32CODE 0 +#define ABS32CODE_SHRUNK 1 +#define PCREL24 2 +#define CALLJ 3 +#define ABS32 4 +#define PCREL13 5 +#define ABS32_MAYBE_RELAXABLE 1 +#define ABS32_WAS_RELAXABLE 2 static reloc_howto_type howto_reloc_callj = -HOWTO( 3, 0, 2, 24, true, 0, true, true, callj_callback,"callj", true, 0x00ffffff, 0x00ffffff,false); +HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false); static reloc_howto_type howto_reloc_abs32 = -HOWTO(1, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false); +HOWTO(ABS32, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false); static reloc_howto_type howto_reloc_pcrel24 = -HOWTO(2, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false); +HOWTO(PCREL24, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false); + +static reloc_howto_type howto_reloc_pcrel13 = +HOWTO(PCREL13, 0, 2, 13, true, 0, true, true,0,"pcrel13", true, 0x00001fff,0x00001fff,false); + + +static reloc_howto_type howto_reloc_abs32codeshrunk = +HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false); + +static reloc_howto_type howto_reloc_abs32code = +HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false); + +static reloc_howto_type * +b_out_reloc_type_lookup (abfd, code) + bfd *abfd; + bfd_reloc_code_real_type code; +{ + switch (code) + { + default: + return 0; + case BFD_RELOC_I960_CALLJ: + return &howto_reloc_callj; + case BFD_RELOC_32: + return &howto_reloc_abs32; + case BFD_RELOC_24_PCREL: + return &howto_reloc_pcrel24; + } +} /* Allocate enough room for all the reloc entries, plus pointers to them all */ @@ -324,7 +418,9 @@ b_out_slurp_reloc_table (abfd, asect, symbols) unsigned int counter ; arelent *cache_ptr ; int extern_mask, pcrel_mask, callj_mask; - + int incode_mask; + int size_mask; + bfd_vma prev_addr = 0; unsigned int count; size_t reloc_size; struct relocation_info *relocs; @@ -334,14 +430,14 @@ b_out_slurp_reloc_table (abfd, asect, symbols) if (!aout_32_slurp_symbol_table (abfd)) return false; if (asect == obj_datasec (abfd)) { - reloc_size = exec_hdr(abfd)->a_drsize; - goto doit; - } + reloc_size = exec_hdr(abfd)->a_drsize; + goto doit; + } if (asect == obj_textsec (abfd)) { - reloc_size = exec_hdr(abfd)->a_trsize; - goto doit; - } + reloc_size = exec_hdr(abfd)->a_trsize; + goto doit; + } bfd_error = invalid_operation; return false; @@ -352,36 +448,40 @@ b_out_slurp_reloc_table (abfd, asect, symbols) relocs = (struct relocation_info *) bfd_xmalloc (reloc_size); if (!relocs) { - bfd_error = no_memory; - return false; - } + bfd_error = no_memory; + return false; + } reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent)); if (!reloc_cache) { - free ((char*)relocs); - bfd_error = no_memory; - return false; - } + free ((char*)relocs); + bfd_error = no_memory; + return false; + } if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) { - bfd_error = system_call_error; - free (reloc_cache); - free (relocs); - return false; - } + bfd_error = system_call_error; + free (reloc_cache); + free (relocs); + return false; + } if (abfd->xvec->header_byteorder_big_p) { - /* big-endian bit field allocation order */ - pcrel_mask = 0x80; - extern_mask = 0x10; - callj_mask = 0x02; - } else { - /* little-endian bit field allocation order */ - pcrel_mask = 0x01; - extern_mask = 0x08; - callj_mask = 0x40; - } + /* big-endian bit field allocation order */ + pcrel_mask = 0x80; + extern_mask = 0x10; + incode_mask = 0x08; + callj_mask = 0x02; + size_mask = 0x20; + } else { + /* little-endian bit field allocation order */ + pcrel_mask = 0x01; + extern_mask = 0x08; + incode_mask = 0x10; + callj_mask = 0x40; + size_mask = 0x02; + } for (rptr = relocs, cache_ptr = reloc_cache, counter = 0; counter < count; @@ -401,58 +501,95 @@ b_out_slurp_reloc_table (abfd, asect, symbols) if (raw[7] & extern_mask) { - /* if this is set then the r_index is a index into the symbol table; - * if the bit is not set then r_index contains a section map. - * we either fill in the sym entry with a pointer to the symbol, - * or point to the correct section - */ - cache_ptr->sym_ptr_ptr = symbols + symnum; - cache_ptr->addend = 0; - } else + /* if this is set then the r_index is a index into the symbol table; + * if the bit is not set then r_index contains a section map. + * we either fill in the sym entry with a pointer to the symbol, + * or point to the correct section + */ + cache_ptr->sym_ptr_ptr = symbols + symnum; + cache_ptr->addend = 0; + } else + { + /* in a.out symbols are relative to the beginning of the + * file rather than sections ? + * (look in translate_from_native_sym_flags) + * the reloc entry addend has added to it the offset into the + * file of the data, so subtract the base to make the reloc + * section relative */ + cache_ptr->sym_ptr_ptr = (asymbol **)NULL; + switch (symnum) { - /* in a.out symbols are relative to the beginning of the - * file rather than sections ? - * (look in translate_from_native_sym_flags) - * the reloc entry addend has added to it the offset into the - * file of the data, so subtract the base to make the reloc - * section relative */ - cache_ptr->sym_ptr_ptr = (asymbol **)NULL; - switch (symnum) - { - case N_TEXT: - case N_TEXT | N_EXT: - cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_textsec(abfd)->vma; - break; - case N_DATA: - case N_DATA | N_EXT: - cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_datasec(abfd)->vma; - break; - case N_BSS: - case N_BSS | N_EXT: - cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; - cache_ptr->addend = - obj_bsssec(abfd)->vma; - break; - case N_ABS: - case N_ABS | N_EXT: - BFD_ASSERT(0); - break; - default: - BFD_ASSERT(0); - break; - } + case N_TEXT: + case N_TEXT | N_EXT: + cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr; + cache_ptr->addend = - obj_textsec(abfd)->vma; + break; + case N_DATA: + case N_DATA | N_EXT: + cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr; + cache_ptr->addend = - obj_datasec(abfd)->vma; + break; + case N_BSS: + case N_BSS | N_EXT: + cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; + cache_ptr->addend = - obj_bsssec(abfd)->vma; + break; + case N_ABS: + case N_ABS | N_EXT: + cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr; + cache_ptr->addend = 0; + break; + default: + BFD_ASSERT(0); + break; + } - } + } /* the i960 only has a few relocation types: abs 32-bit and pcrel 24bit. except for callj's! */ if (raw[7] & callj_mask) - cache_ptr->howto = &howto_reloc_callj; + { + cache_ptr->howto = &howto_reloc_callj; + } else if ( raw[7] & pcrel_mask) - cache_ptr->howto = &howto_reloc_pcrel24; - else - cache_ptr->howto = &howto_reloc_abs32; + { + if (raw[7] & size_mask) + cache_ptr->howto = &howto_reloc_pcrel13; + else + cache_ptr->howto = &howto_reloc_pcrel24; + } + else + { + if (raw[7] & incode_mask) + { + cache_ptr->howto = &howto_reloc_abs32code; + } + else + { + cache_ptr->howto = &howto_reloc_abs32; + } + } + if (cache_ptr->address < prev_addr) + { + /* Ouch! this reloc is out of order, insert into the right place + */ + arelent tmp; + arelent *cursor = cache_ptr-1; + unsigned int where = counter; + bfd_vma stop = cache_ptr->address; + tmp = *cache_ptr; + while (cursor->address > stop) + { + cursor[1] = cursor[0]; + cursor--; + } + cursor[1] = tmp; + } + else + { + prev_addr = cache_ptr->address; + } } @@ -475,11 +612,13 @@ b_out_squirt_out_relocs (abfd, section) int r_extern; int r_idx; int r_addend; - + int incode_mask; + int len_1; unsigned int count = section->reloc_count; struct relocation_info *native, *natptr; size_t natsize = count * sizeof (struct relocation_info); int extern_mask, pcrel_mask, len_2, callj_mask; + int len1; if (count == 0) return true; generic = section->orelocation; native = ((struct relocation_info *) bfd_xmalloc (natsize)); @@ -494,7 +633,9 @@ b_out_squirt_out_relocs (abfd, section) pcrel_mask = 0x80; extern_mask = 0x10; len_2 = 0x40; + len_1 = 0x20; callj_mask = 0x02; + incode_mask = 0x08; } else { @@ -502,7 +643,9 @@ else pcrel_mask = 0x01; extern_mask = 0x08; len_2 = 0x04; + len_1 = 0x02; callj_mask = 0x40; + incode_mask = 0x10; } for (natptr = native; count > 0; --count, ++natptr, ++generic) @@ -524,7 +667,15 @@ else } else if (g->howto == &howto_reloc_pcrel24) { - raw[7] = pcrel_mask +len_2; + raw[7] = pcrel_mask + len_2; + } + else if (g->howto == &howto_reloc_pcrel13) + { + raw[7] = pcrel_mask + len_1; + } + else if (g->howto == &howto_reloc_abs32code) + { + raw[7] = len_2 + incode_mask; } else { raw[7] = len_2; @@ -680,6 +831,290 @@ DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore), +/************************************************************************/ +static bfd_vma +DEFUN(get_value,(reloc, seclet), + arelent *reloc AND + bfd_seclet_type *seclet) +{ + bfd_vma value; + asymbol *symbol = *(reloc->sym_ptr_ptr); + /* A symbol holds a pointer to a section, and an offset from the + base of the section. To relocate, we find where the section will + live in the output and add that in */ + + if (symbol->section == &bfd_und_section) + { + /* Ouch, this is an undefined symbol.. */ + bfd_error_vector.undefined_symbol(reloc, seclet); + value = symbol->value; + } + else + { + value = symbol->value + + symbol->section->output_offset + + symbol->section->output_section->vma; + } + + + /* Add the value contained in the relocation */ + value += (short)((reloc->addend) & 0xffff); + + return value; +} + +static void +DEFUN(perform_slip,(s, slip, input_section, value), + asymbol **s AND + unsigned int slip AND + asection *input_section AND + bfd_vma value) +{ + + /* Find all symbols past this point, and make them know + what's happened */ + while (*s) + { + asymbol *p = *s; + if (p->section == input_section) + { + /* This was pointing into this section, so mangle it */ + if (p->value > value) + { + p->value -=slip; + } + } + s++; + + } +} + +/* This routine works out if the thing we want to get to can be + reached with a 24bit offset instead of a 32 bit one. + If it can, then it changes the amode */ + +static int +DEFUN(abs32code,(input_section, symbols, r, shrink), + asection *input_section AND + asymbol **symbols AND + arelent *r AND + unsigned int shrink) +{ + bfd_vma value = get_value(r,0); + + + bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address; + bfd_vma gap; + + /* See if the address we're looking at within 2^23 bytes of where + we are, if so then we can use a small branch rather than the + jump we were going to */ + + gap = value - (dot - shrink); + + + if (-1<<23 < (long)gap && (long)gap < 1<<23 ) + { + + /* Change the reloc type from 32bitcode possible 24, to 24bit + possible 32 */ + + r->howto = &howto_reloc_abs32codeshrunk; + /* The place to relc moves back by four bytes */ + r->address -=4; + + /* This will be four bytes smaller in the long run */ + shrink += 4 ; + perform_slip(symbols, 4, input_section, r->address-shrink +4); + + + } + return shrink; +} + + +static boolean +DEFUN(b_out_relax_section,(abfd, i, symbols), + bfd *abfd AND + asection *i AND + asymbol **symbols) +{ + + /* Get enough memory to hold the stuff */ + bfd *input_bfd = i->owner; + asection *input_section = i; + int shrink = 0 ; + boolean new = false; + + bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, + input_section); + arelent **reloc_vector = (arelent **)alloca(reloc_size); + + /* Get the relocs and think about them */ + if (bfd_canonicalize_reloc(input_bfd, + input_section, + reloc_vector, + symbols)) + { + arelent **parent; + for (parent = reloc_vector; *parent; parent++) + { + arelent *r = *parent; + switch (r->howto->type) { + case ABS32CODE: + /* A 32bit reloc in an addressing mode */ + shrink = abs32code(input_section, symbols, r,shrink); + new=true; + break; + case ABS32CODE_SHRUNK: + shrink+=4; + break; + } + } + } + input_section->_cooked_size = input_section->_raw_size - shrink; + + return new; +} + +static bfd_byte * +DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), + bfd *in_abfd AND + bfd_seclet_type *seclet AND + bfd_byte *data) + +{ + /* Get enough memory to hold the stuff */ + bfd *input_bfd = seclet->u.indirect.section->owner; + asection *input_section = seclet->u.indirect.section; + bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, + input_section); + arelent **reloc_vector = (arelent **)alloca(reloc_size); + + /* read in the section */ + bfd_get_section_contents(input_bfd, + input_section, + data, + 0, + input_section->_raw_size); + + + if (bfd_canonicalize_reloc(input_bfd, + input_section, + reloc_vector, + seclet->u.indirect.symbols) ) + { + arelent **parent = reloc_vector; + arelent *reloc ; + + + + unsigned int dst_address = 0; + unsigned int src_address = 0; + unsigned int run; + unsigned int idx; + + /* Find how long a run we can do */ + while (dst_address < seclet->size) + { + + reloc = *parent; + if (reloc) + { + /* Note that the relaxing didn't tie up the addresses in the + relocation, so we use the original address to work out the + run of non-relocated data */ + run = reloc->address - src_address; + parent++; + + } + else + { + run = seclet->size - dst_address; + } + /* Copy the bytes */ + for (idx = 0; idx < run; idx++) + { + data[dst_address++] = data[src_address++]; + } + + /* Now do the relocation */ + + if (reloc) + { + switch (reloc->howto->type) + { + case ABS32CODE: + calljx_callback(in_abfd, reloc, src_address + data, dst_address+data, input_section); + src_address+=4; + dst_address+=4; + break; + case ABS32: + bfd_put_32(in_abfd, get_value(reloc, seclet), data+dst_address); + src_address+=4; + dst_address+=4; + break; + case CALLJ: + callj_callback(in_abfd, reloc ,data,src_address,dst_address,input_section); + src_address+=4; + dst_address+=4; + break; + case ABS32CODE_SHRUNK: + /* This used to be a callx, but we've found out that a + callj will reach, so do the right thing */ + callj_callback(in_abfd, reloc,data,src_address+4, dst_address,input_section); + + dst_address+=4; + src_address+=8; + break; + case PCREL24: + { + long int word = bfd_get_32(in_abfd, data+src_address); + asymbol *symbol = *(reloc->sym_ptr_ptr); + word = (word & ~BAL_MASK) | + (((word & BAL_MASK) + + symbol->section->output_offset + + symbol->section->output_section->vma+ + symbol->value + reloc->addend - dst_address - + ( input_section->output_section->vma + input_section->output_offset)) + & BAL_MASK); + + bfd_put_32(in_abfd,word, data+dst_address); + dst_address+=4; + src_address+=4; + + } +break; + + case PCREL13: + { + long int word = bfd_get_32(in_abfd, data+src_address); + asymbol *symbol = *(reloc->sym_ptr_ptr); + word = (word & ~PCREL13_MASK) | + (((word & PCREL13_MASK) + + symbol->section->output_offset + + symbol->section->output_section->vma+ + symbol->value + reloc->addend - dst_address - + ( input_section->output_section->vma + input_section->output_offset)) + & PCREL13_MASK); + + bfd_put_32(in_abfd,word, data+dst_address); + dst_address+=4; + src_address+=4; + + } +break; + + default: + + abort(); + } + } + } + } + return data; +} +/***********************************************************************/ /* Build the transfer vectors for Big and Little-Endian B.OUT files. */ @@ -708,8 +1143,9 @@ DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore), #define aout_32_bfd_debug_info_end bfd_void #define aout_32_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void -#define aout_32_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents -#define aout_32_bfd_relax_section bfd_generic_relax_section +#define aout_32_bfd_get_relocated_section_contents b_out_get_relocated_section_contents +#define aout_32_bfd_relax_section b_out_relax_section + bfd_target b_out_vec_big_host = { "b.out.big", /* name */ @@ -733,7 +1169,9 @@ _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, - JUMP_TABLE(aout_32) + JUMP_TABLE(aout_32), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */ + b_out_reloc_type_lookup, }; @@ -759,5 +1197,7 @@ _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs _bfd_generic_mkarchive, bfd_false}, {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ _bfd_write_archive_contents, bfd_false}, - JUMP_TABLE(aout_32) + JUMP_TABLE(aout_32), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */ + b_out_reloc_type_lookup, }; |