diff options
author | Ken Raeburn <raeburn@cygnus> | 1994-02-16 00:59:19 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@cygnus> | 1994-02-16 00:59:19 +0000 |
commit | ca163703883dd2f0a79120ad12eeedc77fad6518 (patch) | |
tree | 8e979e665441898080687fab9c2b2698d46df586 | |
parent | 66d9f06f6d4d2ba293055522ce5adc267a37158d (diff) | |
download | gdb-ca163703883dd2f0a79120ad12eeedc77fad6518.zip gdb-ca163703883dd2f0a79120ad12eeedc77fad6518.tar.gz gdb-ca163703883dd2f0a79120ad12eeedc77fad6518.tar.bz2 |
(b_out_get_reloc_upper_bound): For BSS section, just return 0.
(aligncode): When shrinking, the addend should be set to the current offset in
the section plus the number of bytes of padding that will actually be retained.
(b_out_relax_section): If a section contains no relocations, don't bother
processing them.
(b_out_get_relocated_section_contents): Set reloc_done. Assert that
bfd_get_section_contents returns true. Check that relocs are properly ordered.
(b_out_get_relocated_section_contents, case ALIGNDONE): Assert that reloc's
addend falls between the current source offset and the raw size of the input
section.
Changed some indentation, deleted trailing whitespace, fixed some comments,
removed some "#if 1" lines.
(output_addr): New macro.
(calljx_callback, callj_callback, get_value, abs32code, aligncode,
b_out_get_relocated_section_contents): Use it for readability.
-rw-r--r-- | bfd/bout.c | 564 |
1 files changed, 279 insertions, 285 deletions
@@ -86,7 +86,7 @@ PROTO(void, bout_swap_exec_header_out, void DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes), bfd *abfd AND - struct internal_exec *execp AND + struct internal_exec *execp AND struct external_exec *raw_bytes) { struct external_exec *bytes = (struct external_exec *)raw_bytes; @@ -145,7 +145,7 @@ b_out_callback (abfd) unsigned long bss_start; /* Architecture and machine type */ - bfd_set_arch_mach(abfd, + bfd_set_arch_mach(abfd, bfd_arch_i960, /* B.out only used on i960 */ bfd_mach_i960_core /* Default */ ); @@ -249,7 +249,7 @@ b_out_write_object_contents (abfd) bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd); /* Now write out reloc info, followed by syms and strings */ - if (bfd_get_symcount (abfd) != 0) + if (bfd_get_symcount (abfd) != 0) { bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET); @@ -274,8 +274,12 @@ b_out_write_object_contents (abfd) #define BAL_MASK 0x00ffffff #define CALL 0x09000000 #define PCREL13_MASK 0x1fff + + +#define output_addr(sec) ((sec)->output_offset+(sec)->output_section->vma) + /* Magic to turn callx into calljx */ -static bfd_reloc_status_type +static bfd_reloc_status_type calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section) bfd *abfd; struct bfd_link_info *link_info; @@ -291,7 +295,7 @@ calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section) value = get_value (reloc_entry, link_info, input_section); - if (IS_CALLNAME (symbol->other)) + if (IS_CALLNAME (symbol->other)) { aout_symbol_type *balsym = symbol+1; int inst = bfd_get_32 (abfd, (bfd_byte *) src-4); @@ -302,8 +306,7 @@ calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section) bfd_put_32 (abfd, inst, (bfd_byte *) dst-4); symbol = balsym; value = (symbol->symbol.value - + symbol->symbol.section->output_section->vma - + symbol->symbol.section->output_offset); + + output_addr (symbol->symbol.section)); } word += value + reloc_entry->addend; @@ -314,7 +317,7 @@ calljx_callback (abfd, link_info, reloc_entry, src, dst, input_section) /* Magic to turn call into callj */ -static bfd_reloc_status_type +static bfd_reloc_status_type callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx, input_section) bfd *abfd; @@ -325,52 +328,44 @@ callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx, unsigned int dstidx; asection *input_section; { - int word = bfd_get_32 (abfd, (bfd_byte *) data + srcidx); + 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); bfd_vma value; value = get_value (reloc_entry, link_info, input_section); - if (IS_OTHER(symbol->other)) - { - /* Call to a system procedure - replace code with system - procedure number */ - word = CALLS | (symbol->other - 1); - - } - - 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 - dstidx - - ( input_section->output_section->vma + input_section->output_offset)) - & BAL_MASK); - - - } - else - { + if (IS_OTHER(symbol->other)) + { + /* Call to a system procedure - replace code with system + procedure number. */ + word = CALLS | (symbol->other - 1); + } + else if (IS_CALLNAME(symbol->other)) + { + aout_symbol_type *balsym = symbol+1; - word = (CALL - | (((word & BAL_MASK) - + value - + reloc_entry->addend - - dstidx - - (input_section->output_section->vma - + input_section->output_offset)) - & BAL_MASK)); - } + /* 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 + + output_addr (balsym->symbol.section) + + balsym->symbol.value + reloc_entry->addend + - dstidx + - output_addr (input_section)) + & BAL_MASK); + } + else + { + word = CALL | (((word & BAL_MASK) + + value + + reloc_entry->addend + - dstidx + - output_addr (input_section)) + & BAL_MASK); + } bfd_put_32(abfd, word, (bfd_byte *) data + dstidx); return bfd_reloc_ok; } @@ -378,7 +373,7 @@ callj_callback (abfd, link_info, reloc_entry, data, srcidx, dstidx, /* type rshift size bitsize pcrel bitpos absolute overflow check*/ #define ABS32CODE 0 -#define ABS32CODE_SHRUNK 1 +#define ABS32CODE_SHRUNK 1 #define PCREL24 2 #define CALLJ 3 #define ABS32 4 @@ -399,7 +394,7 @@ static reloc_howto_type howto_reloc_pcrel13 = HOWTO(PCREL13, 0, 2, 13, true, 0, complain_overflow_signed,0,"pcrel13", true, 0x00001fff,0x00001fff,false); -static reloc_howto_type howto_reloc_abs32codeshrunk = +static reloc_howto_type howto_reloc_abs32codeshrunk = HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, complain_overflow_signed, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false); static reloc_howto_type howto_reloc_abs32code = @@ -477,12 +472,12 @@ b_out_slurp_reloc_table (abfd, asect, symbols) bfd_seek (abfd, (file_ptr)(asect->rel_filepos), SEEK_SET); count = reloc_size / sizeof (struct relocation_info); - relocs = (struct relocation_info *) bfd_xmalloc (reloc_size); + relocs = (struct relocation_info *) malloc (reloc_size); if (!relocs) { bfd_error = no_memory; return false; } - reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent)); + reloc_cache = (arelent *) malloc ((count+1) * sizeof (arelent)); if (!reloc_cache) { free ((char*)relocs); bfd_error = no_memory; @@ -497,7 +492,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) } - + if (abfd->xvec->header_byteorder_big_p) { /* big-endian bit field allocation order */ pcrel_mask = 0x80; @@ -518,22 +513,22 @@ b_out_slurp_reloc_table (abfd, asect, symbols) for (rptr = relocs, cache_ptr = reloc_cache, counter = 0; counter < count; - counter++, rptr++, cache_ptr++) + counter++, rptr++, cache_ptr++) { unsigned char *raw = (unsigned char *)rptr; unsigned int symnum; cache_ptr->address = bfd_h_get_32 (abfd, raw + 0); cache_ptr->howto = 0; - if (abfd->xvec->header_byteorder_big_p) + if (abfd->xvec->header_byteorder_big_p) { symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6]; - } + } else { symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4]; } - if (raw[7] & extern_mask) + 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. @@ -542,7 +537,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) */ cache_ptr->sym_ptr_ptr = symbols + symnum; cache_ptr->addend = 0; - } else + } else { /* in a.out symbols are relative to the beginning of the * file rather than sections ? @@ -597,7 +592,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) BFD_ASSERT(0); break; } - + } /* the i960 only has a few relocation types: @@ -615,18 +610,18 @@ b_out_slurp_reloc_table (abfd, asect, symbols) else cache_ptr->howto = &howto_reloc_pcrel24; } - else + else { - if (raw[7] & incode_mask) + if (raw[7] & incode_mask) { cache_ptr->howto = &howto_reloc_abs32code; } - else + else { cache_ptr->howto = &howto_reloc_abs32; } } - if (cache_ptr->address < prev_addr) + if (cache_ptr->address < prev_addr) { /* Ouch! this reloc is out of order, insert into the right place */ @@ -638,10 +633,10 @@ b_out_slurp_reloc_table (abfd, asect, symbols) { cursor[1] = cursor[0]; cursor--; - } + } cursor[1] = tmp; } - else + else { prev_addr = cache_ptr->address; } @@ -662,11 +657,10 @@ b_out_squirt_out_relocs (abfd, section) bfd *abfd; asection *section; { - arelent **generic; int r_extern = 0; int r_idx; - int incode_mask; + int incode_mask; int len_1; unsigned int count = section->reloc_count; struct relocation_info *native, *natptr; @@ -674,13 +668,13 @@ b_out_squirt_out_relocs (abfd, section) int extern_mask, pcrel_mask, len_2, callj_mask; if (count == 0) return true; generic = section->orelocation; - native = ((struct relocation_info *) bfd_xmalloc (natsize)); + native = ((struct relocation_info *) malloc (natsize)); if (!native) { bfd_error = no_memory; return false; } - if (abfd->xvec->header_byteorder_big_p) + if (abfd->xvec->header_byteorder_big_p) { /* Big-endian bit field allocation order */ pcrel_mask = 0x80; @@ -689,8 +683,8 @@ b_out_squirt_out_relocs (abfd, section) len_1 = 0x20; callj_mask = 0x02; incode_mask = 0x08; - } - else + } + else { /* Little-endian bit field allocation order */ pcrel_mask = 0x01; @@ -701,7 +695,7 @@ b_out_squirt_out_relocs (abfd, section) incode_mask = 0x10; } - for (natptr = native; count > 0; --count, ++natptr, ++generic) + for (natptr = native; count > 0; --count, ++natptr, ++generic) { arelent *g = *generic; unsigned char *raw = (unsigned char *)natptr; @@ -709,26 +703,26 @@ b_out_squirt_out_relocs (abfd, section) asection *output_section = sym->section->output_section; - bfd_h_put_32(abfd, g->address, raw); - /* Find a type in the output format which matches the input howto - + bfd_h_put_32(abfd, g->address, raw); + /* Find a type in the output format which matches the input howto - * at the moment we assume input format == output format FIXME!! */ r_idx = 0; /* FIXME: Need callj stuff here, and to check the howto entries to be sure they are real for this architecture. */ - if (g->howto== &howto_reloc_callj) + if (g->howto== &howto_reloc_callj) { raw[7] = callj_mask + pcrel_mask + len_2; } - else if (g->howto == &howto_reloc_pcrel24) + else if (g->howto == &howto_reloc_pcrel24) { raw[7] = pcrel_mask + len_2; } - else if (g->howto == &howto_reloc_pcrel13) + else if (g->howto == &howto_reloc_pcrel13) { raw[7] = pcrel_mask + len_1; } - else if (g->howto == &howto_reloc_abs32code) + else if (g->howto == &howto_reloc_abs32code) { raw[7] = len_2 + incode_mask; } @@ -751,7 +745,7 @@ b_out_squirt_out_relocs (abfd, section) /* already mucked with r_extern, r_idx */; else if (bfd_is_com_section (output_section) || output_section == &bfd_abs_section - || output_section == &bfd_und_section) + || output_section == &bfd_und_section) { if (bfd_abs_section.symbol == sym) @@ -761,7 +755,7 @@ b_out_squirt_out_relocs (abfd, section) r_idx = 0; r_extern = 0; } - else + else { /* Fill in symbol */ @@ -769,11 +763,11 @@ b_out_squirt_out_relocs (abfd, section) r_idx = stoi((*(g->sym_ptr_ptr))->flags); } } - else + else { /* Just an ordinary section */ r_extern = 0; - r_idx = output_section->target_index; + r_idx = output_section->target_index; } if (abfd->xvec->header_byteorder_big_p) { @@ -784,9 +778,9 @@ b_out_squirt_out_relocs (abfd, section) raw[6] = (unsigned char) (r_idx >> 16); raw[5] = (unsigned char) (r_idx>> 8); raw[4] = (unsigned char) (r_idx ); - } + } if (r_extern) - raw[7] |= extern_mask; + raw[7] |= extern_mask; } if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) { @@ -841,6 +835,9 @@ b_out_get_reloc_upper_bound (abfd, asect) ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info)) +1)); + if (asect == obj_bsssec (abfd)) + return 0; + bfd_error = invalid_operation; return 0; } @@ -862,7 +859,7 @@ b_out_set_section_contents (abfd, section, location, offset, count) } obj_textsec (abfd)->filepos = sizeof(struct internal_exec); - obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos + obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos + obj_textsec (abfd)->_raw_size; } @@ -902,7 +899,7 @@ b_out_set_arch_mach (abfd, arch, machine) return false; } -static int +static int DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore), bfd *ignore_abfd AND boolean ignore) @@ -913,7 +910,7 @@ DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore), /************************************************************************/ -static bfd_vma +static bfd_vma get_value (reloc, link_info, input_section) arelent *reloc; struct bfd_link_info *link_info; @@ -939,9 +936,7 @@ get_value (reloc, link_info, input_section) false, false, true); if (h != (struct bfd_link_hash_entry *) NULL && h->type == bfd_link_hash_defined) - value = (h->u.def.value - + h->u.def.section->output_section->vma - + h->u.def.section->output_offset); + value = h->u.def.value + output_addr (h->u.def.section); else if (h != (struct bfd_link_hash_entry *) NULL && h->type == bfd_link_hash_common) value = h->u.c.size; @@ -954,16 +949,14 @@ get_value (reloc, link_info, input_section) value = 0; } } - else + else { - value = (symbol->value - + symbol->section->output_offset - + symbol->section->output_section->vma); + value = symbol->value + output_addr (symbol->section); } /* Add the value contained in the relocation */ value += reloc->addend; - + return value; } @@ -974,13 +967,13 @@ DEFUN(perform_slip,(s, slip, input_section, value), asection *input_section AND bfd_vma value) { - + /* Find all symbols past this point, and make them know what's happened */ - while (*s) + while (*s) { asymbol *p = *s; - if (p->section == input_section) + if (p->section == input_section) { /* This was pointing into this section, so mangle it */ if (p->value > value) @@ -989,15 +982,15 @@ DEFUN(perform_slip,(s, slip, input_section, value), } } s++; - - } + + } } -#if 1 + /* 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 +static int abs32code (input_section, symbols, r, shrink, link_info) asection *input_section; asymbol **symbols; @@ -1006,40 +999,40 @@ abs32code (input_section, symbols, r, shrink, link_info) struct bfd_link_info *link_info; { bfd_vma value = get_value (r, link_info, input_section); - bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address; + bfd_vma dot = output_addr (input_section) + 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; + } + return shrink; } -static int +static int DEFUN(aligncode,(input_section, symbols, r, shrink), asection *input_section AND asymbol **symbols AND arelent *r AND - unsigned int shrink) + unsigned int shrink) { - bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address; + bfd_vma dot = output_addr (input_section) + r->address; bfd_vma gap; bfd_vma old_end; bfd_vma new_end; @@ -1062,72 +1055,74 @@ DEFUN(aligncode,(input_section, symbols, r, shrink), shrink_delta = (old_end - new_end) - shrink; if (shrink_delta) - { + { /* Change the reloc so that it knows how far to align to */ r->howto = howto_done_align_table + (r->howto - howto_align_table); /* Encode the stuff into the addend - for future use we need to know how big the reloc used to be */ - r->addend = old_end ; + r->addend = old_end - dot + r->address; /* This will be N bytes smaller in the long run, adjust all the symbols */ perform_slip(symbols, shrink_delta, input_section, r->address - shrink ); shrink += shrink_delta; - } - return shrink; + } + return shrink; } -static boolean +static boolean b_out_relax_section (abfd, i, link_info, symbols) bfd *abfd; asection *i; struct bfd_link_info *link_info; 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++) + if (reloc_size) { - arelent *r = *parent; - switch (r->howto->type) { - case ALIGNER: - /* An alignment reloc */ - shrink = aligncode(input_section, symbols, r,shrink); - new=true; - break; - case ABS32CODE: - /* A 32bit reloc in an addressing mode */ - shrink = abs32code (input_section, symbols, r, shrink, link_info); - new=true; - break; - case ABS32CODE_SHRUNK: - shrink+=4; - break; - } + 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 ALIGNER: + /* An alignment reloc */ + shrink = aligncode(input_section, symbols, r,shrink); + new=true; + break; + case ABS32CODE: + /* A 32bit reloc in an addressing mode */ + shrink = abs32code (input_section, symbols, r, shrink, link_info); + new=true; + break; + case ABS32CODE_SHRUNK: + shrink+=4; + break; + } + } + } } - } - input_section->_cooked_size = input_section->_raw_size - shrink; + input_section->_cooked_size = input_section->_raw_size - shrink; return new; } -#endif static bfd_byte * b_out_get_relocated_section_contents (in_abfd, link_info, link_order, data, relocateable, symbols) @@ -1144,7 +1139,7 @@ b_out_get_relocated_section_contents (in_abfd, link_info, link_order, data, bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, input_section); arelent **reloc_vector = (arelent **)alloca(reloc_size); - + /* If producing relocateable output, don't bother to relax. */ if (relocateable) return bfd_generic_get_relocated_section_contents (in_abfd, link_info, @@ -1152,140 +1147,139 @@ b_out_get_relocated_section_contents (in_abfd, link_info, link_order, data, data, relocateable, symbols); + input_section->reloc_done = 1; + /* read in the section */ - bfd_get_section_contents(input_bfd, - input_section, - data, - 0, - input_section->_raw_size); - - - if (bfd_canonicalize_reloc(input_bfd, + BFD_ASSERT (true == bfd_get_section_contents(input_bfd, + input_section, + data, + 0, + input_section->_raw_size)); + + if (bfd_canonicalize_reloc(input_bfd, input_section, reloc_vector, 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 < link_order->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 = link_order->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) + 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 < link_order->size) { - case ABS32CODE: - calljx_callback (in_abfd, link_info, reloc, src_address + data, - dst_address + data, input_section); - src_address+=4; - dst_address+=4; - break; - case ABS32: - bfd_put_32(in_abfd, - (bfd_get_32 (in_abfd, data+src_address) - + get_value (reloc, link_info, input_section)), - data+dst_address); - src_address+=4; - dst_address+=4; - break; - case CALLJ: - callj_callback (in_abfd, link_info, reloc, data, src_address, - dst_address, input_section); - src_address+=4; - dst_address+=4; - break; - case ALIGNDONE: - src_address = reloc->addend; - dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size; - 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, link_info, 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); - bfd_vma value; - - value = get_value (reloc, link_info, input_section); - word = ((word & ~BAL_MASK) - | (((word & BAL_MASK) - + value - - (input_section->output_section->vma - + input_section->output_offset) - + reloc->addend) - & 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); - bfd_vma value; - - value = get_value (reloc, link_info, input_section); - word = ((word & ~PCREL13_MASK) - | (((word & PCREL13_MASK) - + value - + reloc->addend - - (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(); + 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 */ + BFD_ASSERT (reloc->address >= src_address); + run = reloc->address - src_address; + parent++; + } + else + { + run = link_order->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, link_info, reloc, + src_address + data, dst_address + data, + input_section); + src_address+=4; + dst_address+=4; + break; + case ABS32: + bfd_put_32(in_abfd, + (bfd_get_32 (in_abfd, data+src_address) + + get_value (reloc, link_info, input_section)), + data+dst_address); + src_address+=4; + dst_address+=4; + break; + case CALLJ: + callj_callback (in_abfd, link_info, reloc, data, src_address, + dst_address, input_section); + src_address+=4; + dst_address+=4; + break; + case ALIGNDONE: + BFD_ASSERT (reloc->addend >= src_address); + BFD_ASSERT (reloc->addend <= input_section->_raw_size); + src_address = reloc->addend; + dst_address = ((dst_address + reloc->howto->size) + & ~reloc->howto->size); + 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, link_info, 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); + bfd_vma value; + + value = get_value (reloc, link_info, input_section); + word = ((word & ~BAL_MASK) + | (((word & BAL_MASK) + + value + - output_addr (input_section) + + reloc->addend) + & 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); + bfd_vma value; + + value = get_value (reloc, link_info, input_section); + word = ((word & ~PCREL13_MASK) + | (((word & PCREL13_MASK) + + value + + reloc->addend + - output_addr (input_section)) + & PCREL13_MASK)); + + bfd_put_32(in_abfd,word, data+dst_address); + dst_address+=4; + src_address+=4; + + } + break; + + default: + abort(); + } + } } - } } - } return data; } /***********************************************************************/ @@ -1369,23 +1363,23 @@ bfd_target b_out_vec_little_host = HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ), (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */ - '_', /* symbol leading char */ + '_', /* symbol leading char */ ' ', /* ar_pad_char */ 16, /* ar_max_namelen */ - 2, /* minum align */ -bfd_getl64, bfd_getl_signed_64, bfd_putl64, - bfd_getl32, bfd_getl_signed_32, bfd_putl32, + 2, /* minum align */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ -bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl64, bfd_getl_signed_64, bfd_putl64, bfd_getl32, bfd_getl_signed_32, bfd_putl32, bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ - - {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */ - bfd_generic_archive_p, _bfd_dummy_target}, - {bfd_false, b_out_mkobject, /* bfd_set_format */ - _bfd_generic_mkarchive, bfd_false}, - {bfd_false, b_out_write_object_contents, /* bfd_write_contents */ - _bfd_write_archive_contents, bfd_false}, + + {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */ + bfd_generic_archive_p, _bfd_dummy_target}, + {bfd_false, b_out_mkobject, /* bfd_set_format */ + _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), (PTR) 0 }; |