* bout.c: added support for relaxable alignment relocs.
* seclet.c (rel, seclet_dump_seclet, seclet_dump): get the app to pass down pointer to play area rather than use alloca
This commit is contained in:
parent
cd1d8c6d89
commit
3be5606231
@ -1,5 +1,10 @@
|
|||||||
Wed Aug 26 14:20:16 1992 Steve Chamberlain (sac@thepub.cygnus.com)
|
Wed Aug 26 14:20:16 1992 Steve Chamberlain (sac@thepub.cygnus.com)
|
||||||
|
|
||||||
|
* bout.c: added support for relaxable alignment relocs.
|
||||||
|
|
||||||
|
* seclet.c (rel, seclet_dump_seclet, seclet_dump): get the app to
|
||||||
|
pass down pointer to play area rather than use alloca
|
||||||
|
|
||||||
* cpu-z8k.c (compatible): made static to reduce name space
|
* cpu-z8k.c (compatible): made static to reduce name space
|
||||||
polution.
|
polution.
|
||||||
|
|
||||||
|
117
bfd/bout.c
117
bfd/bout.c
@ -371,6 +371,8 @@ DEFUN (callj_callback, (abfd, reloc_entry, data, srcidx,dstidx, input_section),
|
|||||||
#define ABS32_MAYBE_RELAXABLE 1
|
#define ABS32_MAYBE_RELAXABLE 1
|
||||||
#define ABS32_WAS_RELAXABLE 2
|
#define ABS32_WAS_RELAXABLE 2
|
||||||
|
|
||||||
|
#define ALIGN 10
|
||||||
|
#define ALIGNDONE 11
|
||||||
static reloc_howto_type howto_reloc_callj =
|
static reloc_howto_type howto_reloc_callj =
|
||||||
HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"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 =
|
static reloc_howto_type howto_reloc_abs32 =
|
||||||
@ -388,6 +390,21 @@ HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0
|
|||||||
static reloc_howto_type howto_reloc_abs32code =
|
static reloc_howto_type howto_reloc_abs32code =
|
||||||
HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
|
HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
|
||||||
|
|
||||||
|
static reloc_howto_type howto_align_table[] = {
|
||||||
|
HOWTO (ALIGN, 0, 0x1, 0, 0, 0, 0, 0, 0, "align16", 0, 0, 0, 0),
|
||||||
|
HOWTO (ALIGN, 0, 0x3, 0, 0, 0, 0, 0, 0, "align32", 0, 0, 0, 0),
|
||||||
|
HOWTO (ALIGN, 0, 0x7, 0, 0, 0, 0, 0, 0, "align64", 0, 0, 0, 0),
|
||||||
|
HOWTO (ALIGN, 0, 0xf, 0, 0, 0, 0, 0, 0, "align128", 0, 0, 0, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
static reloc_howto_type howto_done_align_table[] = {
|
||||||
|
HOWTO (ALIGNDONE, 0x1, 0x1, 0, 0, 0, 0, 0, 0, "donealign16", 0, 0, 0,0),
|
||||||
|
HOWTO (ALIGNDONE, 0x3, 0x3, 0, 0, 0, 0, 0, 0, "donealign32", 0, 0, 0,0),
|
||||||
|
HOWTO (ALIGNDONE, 0x7, 0x7, 0, 0, 0, 0, 0, 0, "donealign64", 0, 0, 0,0),
|
||||||
|
HOWTO (ALIGNDONE, 0xf, 0xf, 0, 0, 0, 0, 0, 0, "donealign128", 0, 0, 0,0),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
static reloc_howto_type *
|
static reloc_howto_type *
|
||||||
b_out_reloc_type_lookup (abfd, code)
|
b_out_reloc_type_lookup (abfd, code)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
@ -417,7 +434,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
register struct relocation_info *rptr;
|
register struct relocation_info *rptr;
|
||||||
unsigned int counter ;
|
unsigned int counter ;
|
||||||
arelent *cache_ptr ;
|
arelent *cache_ptr ;
|
||||||
int extern_mask, pcrel_mask, callj_mask;
|
int extern_mask, pcrel_mask, callj_mask, length_shift;
|
||||||
int incode_mask;
|
int incode_mask;
|
||||||
int size_mask;
|
int size_mask;
|
||||||
bfd_vma prev_addr = 0;
|
bfd_vma prev_addr = 0;
|
||||||
@ -474,6 +491,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
incode_mask = 0x08;
|
incode_mask = 0x08;
|
||||||
callj_mask = 0x02;
|
callj_mask = 0x02;
|
||||||
size_mask = 0x20;
|
size_mask = 0x20;
|
||||||
|
length_shift = 5;
|
||||||
} else {
|
} else {
|
||||||
/* little-endian bit field allocation order */
|
/* little-endian bit field allocation order */
|
||||||
pcrel_mask = 0x01;
|
pcrel_mask = 0x01;
|
||||||
@ -481,6 +499,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
incode_mask = 0x10;
|
incode_mask = 0x10;
|
||||||
callj_mask = 0x40;
|
callj_mask = 0x40;
|
||||||
size_mask = 0x02;
|
size_mask = 0x02;
|
||||||
|
length_shift = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
|
for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
|
||||||
@ -516,8 +535,15 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
* the reloc entry addend has added to it the offset into the
|
* the reloc entry addend has added to it the offset into the
|
||||||
* file of the data, so subtract the base to make the reloc
|
* file of the data, so subtract the base to make the reloc
|
||||||
* section relative */
|
* section relative */
|
||||||
|
int s;
|
||||||
|
{
|
||||||
|
/* sign-extend symnum from 24 bits to whatever host uses */
|
||||||
|
s = symnum;
|
||||||
|
if (s & (1 << 23))
|
||||||
|
s |= (~0) << 24;
|
||||||
|
}
|
||||||
cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
|
cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
|
||||||
switch (symnum)
|
switch (s)
|
||||||
{
|
{
|
||||||
case N_TEXT:
|
case N_TEXT:
|
||||||
case N_TEXT | N_EXT:
|
case N_TEXT | N_EXT:
|
||||||
@ -539,6 +565,19 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
|
cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
|
||||||
cache_ptr->addend = 0;
|
cache_ptr->addend = 0;
|
||||||
break;
|
break;
|
||||||
|
case -2: /* .align */
|
||||||
|
if (raw[7] & pcrel_mask)
|
||||||
|
{
|
||||||
|
cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
|
||||||
|
cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* .org? */
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
cache_ptr->addend = 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BFD_ASSERT(0);
|
BFD_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
@ -548,7 +587,9 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
|
|
||||||
/* the i960 only has a few relocation types:
|
/* the i960 only has a few relocation types:
|
||||||
abs 32-bit and pcrel 24bit. except for callj's! */
|
abs 32-bit and pcrel 24bit. except for callj's! */
|
||||||
if (raw[7] & callj_mask)
|
if (cache_ptr->howto != 0)
|
||||||
|
;
|
||||||
|
else if (raw[7] & callj_mask)
|
||||||
{
|
{
|
||||||
cache_ptr->howto = &howto_reloc_callj;
|
cache_ptr->howto = &howto_reloc_callj;
|
||||||
}
|
}
|
||||||
@ -579,7 +620,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
|
|||||||
unsigned int where = counter;
|
unsigned int where = counter;
|
||||||
bfd_vma stop = cache_ptr->address;
|
bfd_vma stop = cache_ptr->address;
|
||||||
tmp = *cache_ptr;
|
tmp = *cache_ptr;
|
||||||
while (cursor->address > stop)
|
while (cursor->address > stop && cursor >= reloc_cache)
|
||||||
{
|
{
|
||||||
cursor[1] = cursor[0];
|
cursor[1] = cursor[0];
|
||||||
cursor--;
|
cursor--;
|
||||||
@ -888,7 +929,7 @@ DEFUN(perform_slip,(s, slip, input_section, value),
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
/* This routine works out if the thing we want to get to can be
|
/* 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.
|
reached with a 24bit offset instead of a 32 bit one.
|
||||||
If it can, then it changes the amode */
|
If it can, then it changes the amode */
|
||||||
@ -901,8 +942,6 @@ DEFUN(abs32code,(input_section, symbols, r, shrink),
|
|||||||
unsigned int shrink)
|
unsigned int shrink)
|
||||||
{
|
{
|
||||||
bfd_vma value = get_value(r,0);
|
bfd_vma value = get_value(r,0);
|
||||||
|
|
||||||
|
|
||||||
bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address;
|
bfd_vma dot = input_section->output_section->vma + input_section->output_offset + r->address;
|
||||||
bfd_vma gap;
|
bfd_vma gap;
|
||||||
|
|
||||||
@ -932,6 +971,60 @@ DEFUN(abs32code,(input_section, symbols, r, shrink),
|
|||||||
return shrink;
|
return shrink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
DEFUN(aligncode,(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;
|
||||||
|
bfd_vma this_dot;
|
||||||
|
bfd_vma old_end;
|
||||||
|
bfd_vma new_end;
|
||||||
|
int shrink_delta;
|
||||||
|
int size = r->howto->size;
|
||||||
|
/* Reduce the size of the alignment so that it's still aligned but
|
||||||
|
smaller - the current size is already the same size as or bigger
|
||||||
|
than the alignment required. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* calculate the first byte following the padding before we optimize */
|
||||||
|
old_end = ((dot + size ) & ~size) + size+1;
|
||||||
|
/* work out where the new end will be - remember that we're smaller
|
||||||
|
than we used to be */
|
||||||
|
new_end = ((dot - shrink + size) & ~size);
|
||||||
|
|
||||||
|
/* This is the new end */
|
||||||
|
gap = old_end - ((dot + size) & ~size);
|
||||||
|
|
||||||
|
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 ;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static boolean
|
static boolean
|
||||||
DEFUN(b_out_relax_section,(abfd, i, symbols),
|
DEFUN(b_out_relax_section,(abfd, i, symbols),
|
||||||
@ -961,6 +1054,11 @@ DEFUN(b_out_relax_section,(abfd, i, symbols),
|
|||||||
{
|
{
|
||||||
arelent *r = *parent;
|
arelent *r = *parent;
|
||||||
switch (r->howto->type) {
|
switch (r->howto->type) {
|
||||||
|
case ALIGN:
|
||||||
|
/* An alignment reloc */
|
||||||
|
shrink = aligncode(input_section, symbols, r,shrink);
|
||||||
|
new=true;
|
||||||
|
break;
|
||||||
case ABS32CODE:
|
case ABS32CODE:
|
||||||
/* A 32bit reloc in an addressing mode */
|
/* A 32bit reloc in an addressing mode */
|
||||||
shrink = abs32code(input_section, symbols, r,shrink);
|
shrink = abs32code(input_section, symbols, r,shrink);
|
||||||
@ -977,6 +1075,7 @@ DEFUN(b_out_relax_section,(abfd, i, symbols),
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
static bfd_byte *
|
static bfd_byte *
|
||||||
DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
|
DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
|
||||||
bfd *in_abfd AND
|
bfd *in_abfd AND
|
||||||
@ -1059,6 +1158,10 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
|
|||||||
src_address+=4;
|
src_address+=4;
|
||||||
dst_address+=4;
|
dst_address+=4;
|
||||||
break;
|
break;
|
||||||
|
case ALIGNDONE:
|
||||||
|
src_address = reloc->addend;
|
||||||
|
dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
|
||||||
|
break;
|
||||||
case ABS32CODE_SHRUNK:
|
case ABS32CODE_SHRUNK:
|
||||||
/* This used to be a callx, but we've found out that a
|
/* This used to be a callx, but we've found out that a
|
||||||
callj will reach, so do the right thing */
|
callj will reach, so do the right thing */
|
||||||
|
21
bfd/seclet.c
21
bfd/seclet.c
@ -52,17 +52,17 @@ extern bfd_error_vector_type bfd_error_vector;
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DEFUN(rel,(abfd, seclet, output_section),
|
DEFUN(rel,(abfd, seclet, output_section, data),
|
||||||
bfd *abfd AND
|
bfd *abfd AND
|
||||||
bfd_seclet_type *seclet AND
|
bfd_seclet_type *seclet AND
|
||||||
asection *output_section)
|
asection *output_section AND
|
||||||
|
PTR data)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (output_section->flags & SEC_HAS_CONTENTS
|
if (output_section->flags & SEC_HAS_CONTENTS
|
||||||
&& !(output_section->flags & SEC_NEVER_LOAD)
|
&& !(output_section->flags & SEC_NEVER_LOAD)
|
||||||
&& seclet->size)
|
&& seclet->size)
|
||||||
{
|
{
|
||||||
bfd_byte *data = (bfd_byte *)alloca(seclet->size);
|
|
||||||
data = bfd_get_relocated_section_contents(abfd, seclet, data);
|
data = bfd_get_relocated_section_contents(abfd, seclet, data);
|
||||||
if(bfd_set_section_contents(abfd,
|
if(bfd_set_section_contents(abfd,
|
||||||
output_section,
|
output_section,
|
||||||
@ -72,22 +72,22 @@ DEFUN(rel,(abfd, seclet, output_section),
|
|||||||
{
|
{
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DEFUN(seclet_dump_seclet,(abfd, seclet, section),
|
DEFUN(seclet_dump_seclet,(abfd, seclet, section, data),
|
||||||
bfd *abfd AND
|
bfd *abfd AND
|
||||||
bfd_seclet_type *seclet AND
|
bfd_seclet_type *seclet AND
|
||||||
asection *section)
|
asection *section AND
|
||||||
|
PTR data)
|
||||||
{
|
{
|
||||||
switch (seclet->type)
|
switch (seclet->type)
|
||||||
{
|
{
|
||||||
case bfd_indirect_seclet:
|
case bfd_indirect_seclet:
|
||||||
/* The contents of this section come from another one somewhere
|
/* The contents of this section come from another one somewhere
|
||||||
else */
|
else */
|
||||||
rel(abfd, seclet, section);
|
rel(abfd, seclet, section, data);
|
||||||
break;
|
break;
|
||||||
case bfd_fill_seclet:
|
case bfd_fill_seclet:
|
||||||
/* Fill in the section with us */
|
/* Fill in the section with us */
|
||||||
@ -110,8 +110,9 @@ DEFUN(seclet_dump_seclet,(abfd, seclet, section),
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DEFUN(seclet_dump,(abfd),
|
DEFUN(seclet_dump,(abfd, data),
|
||||||
bfd *abfd)
|
bfd *abfd AND
|
||||||
|
PTR data)
|
||||||
{
|
{
|
||||||
/* Write all the seclets on the bfd out, relocate etc according to the
|
/* Write all the seclets on the bfd out, relocate etc according to the
|
||||||
rules */
|
rules */
|
||||||
@ -122,7 +123,7 @@ DEFUN(seclet_dump,(abfd),
|
|||||||
bfd_seclet_type *p = o->seclets_head;
|
bfd_seclet_type *p = o->seclets_head;
|
||||||
while (p != (bfd_seclet_type *)NULL)
|
while (p != (bfd_seclet_type *)NULL)
|
||||||
{
|
{
|
||||||
seclet_dump_seclet(abfd, p, o);
|
seclet_dump_seclet(abfd, p, o, data);
|
||||||
p = p ->next;
|
p = p ->next;
|
||||||
}
|
}
|
||||||
o = o->next;
|
o = o->next;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user