mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-30 13:33:53 +08:00
(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.
This commit is contained in:
parent
66d9f06f6d
commit
ca16370388
546
bfd/bout.c
546
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);
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
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;
|
||||
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++];
|
||||
}
|
||||
|
||||
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));
|
||||
/* Now do the relocation */
|
||||
|
||||
bfd_put_32(in_abfd,word, data+dst_address);
|
||||
dst_address+=4;
|
||||
src_address+=4;
|
||||
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;
|
||||
|
||||
}
|
||||
break;
|
||||
value = get_value (reloc, link_info, input_section);
|
||||
word = ((word & ~BAL_MASK)
|
||||
| (((word & BAL_MASK)
|
||||
+ value
|
||||
- output_addr (input_section)
|
||||
+ reloc->addend)
|
||||
& BAL_MASK));
|
||||
|
||||
case PCREL13:
|
||||
{
|
||||
long int word = bfd_get_32(in_abfd, data+src_address);
|
||||
bfd_vma value;
|
||||
bfd_put_32(in_abfd,word, data+dst_address);
|
||||
dst_address+=4;
|
||||
src_address+=4;
|
||||
|
||||
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));
|
||||
}
|
||||
break;
|
||||
|
||||
bfd_put_32(in_abfd,word, data+dst_address);
|
||||
dst_address+=4;
|
||||
src_address+=4;
|
||||
case PCREL13:
|
||||
{
|
||||
long int word = bfd_get_32(in_abfd, data+src_address);
|
||||
bfd_vma value;
|
||||
|
||||
}
|
||||
break;
|
||||
value = get_value (reloc, link_info, input_section);
|
||||
word = ((word & ~PCREL13_MASK)
|
||||
| (((word & PCREL13_MASK)
|
||||
+ value
|
||||
+ reloc->addend
|
||||
- output_addr (input_section))
|
||||
& PCREL13_MASK));
|
||||
|
||||
default:
|
||||
bfd_put_32(in_abfd,word, data+dst_address);
|
||||
dst_address+=4;
|
||||
src_address+=4;
|
||||
|
||||
abort();
|
||||
}
|
||||
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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user