aboutsummaryrefslogtreecommitdiff
path: root/bfd/bout.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/bout.c')
-rw-r--r--bfd/bout.c564
1 files changed, 279 insertions, 285 deletions
diff --git a/bfd/bout.c b/bfd/bout.c
index 008e190..fa9bb7c 100644
--- a/bfd/bout.c
+++ b/bfd/bout.c
@@ -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
};