From 3be56062313b092e65b8e99d79469f165d5d9b1a Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Thu, 27 Aug 1992 00:35:09 +0000 Subject: [PATCH] * 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 --- bfd/ChangeLog | 5 +++ bfd/bout.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++------- bfd/seclet.c | 21 +++++----- 3 files changed, 133 insertions(+), 24 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4860dc8..eae5842 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,10 @@ 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 polution. diff --git a/bfd/bout.c b/bfd/bout.c index 25ab2a7..dcabc77 100644 --- a/bfd/bout.c +++ b/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_WAS_RELAXABLE 2 +#define ALIGN 10 +#define ALIGNDONE 11 static reloc_howto_type howto_reloc_callj = HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false); 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 = 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 * b_out_reloc_type_lookup (abfd, code) bfd *abfd; @@ -417,7 +434,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) register struct relocation_info *rptr; unsigned int counter ; arelent *cache_ptr ; - int extern_mask, pcrel_mask, callj_mask; + int extern_mask, pcrel_mask, callj_mask, length_shift; int incode_mask; int size_mask; bfd_vma prev_addr = 0; @@ -474,6 +491,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) incode_mask = 0x08; callj_mask = 0x02; size_mask = 0x20; + length_shift = 5; } else { /* little-endian bit field allocation order */ pcrel_mask = 0x01; @@ -481,6 +499,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) incode_mask = 0x10; callj_mask = 0x40; size_mask = 0x02; + length_shift = 1; } 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 * file of the data, so subtract the base to make the reloc * 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; - switch (symnum) + switch (s) { case N_TEXT: 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->addend = 0; 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: BFD_ASSERT(0); break; @@ -548,7 +587,9 @@ b_out_slurp_reloc_table (abfd, asect, symbols) /* the i960 only has a few relocation types: 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; } @@ -579,7 +620,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols) unsigned int where = counter; bfd_vma stop = cache_ptr->address; tmp = *cache_ptr; - while (cursor->address > stop) + while (cursor->address > stop && cursor >= reloc_cache) { cursor[1] = cursor[0]; 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 reached with a 24bit offset instead of a 32 bit one. If it can, then it changes the amode */ @@ -901,8 +942,6 @@ DEFUN(abs32code,(input_section, symbols, r, shrink), 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; @@ -932,6 +971,60 @@ DEFUN(abs32code,(input_section, symbols, r, 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 DEFUN(b_out_relax_section,(abfd, i, symbols), @@ -961,6 +1054,11 @@ DEFUN(b_out_relax_section,(abfd, i, symbols), { arelent *r = *parent; switch (r->howto->type) { + case ALIGN: + /* 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); @@ -977,6 +1075,7 @@ DEFUN(b_out_relax_section,(abfd, i, symbols), return new; } +#endif static bfd_byte * DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), bfd *in_abfd AND @@ -1059,6 +1158,10 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), 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 */ @@ -1080,11 +1183,11 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data), & BAL_MASK); bfd_put_32(in_abfd,word, data+dst_address); - dst_address+=4; - src_address+=4; + dst_address+=4; + src_address+=4; } -break; + break; case PCREL13: { @@ -1099,13 +1202,13 @@ break; & PCREL13_MASK); bfd_put_32(in_abfd,word, data+dst_address); - dst_address+=4; - src_address+=4; + dst_address+=4; + src_address+=4; } -break; + break; - default: + default: abort(); } diff --git a/bfd/seclet.c b/bfd/seclet.c index e7fb65c..685653f 100644 --- a/bfd/seclet.c +++ b/bfd/seclet.c @@ -52,17 +52,17 @@ extern bfd_error_vector_type bfd_error_vector; void -DEFUN(rel,(abfd, seclet, output_section), +DEFUN(rel,(abfd, seclet, output_section, data), bfd *abfd AND bfd_seclet_type *seclet AND - asection *output_section) + asection *output_section AND + PTR data) { if (output_section->flags & SEC_HAS_CONTENTS && !(output_section->flags & SEC_NEVER_LOAD) && seclet->size) { - bfd_byte *data = (bfd_byte *)alloca(seclet->size); data = bfd_get_relocated_section_contents(abfd, seclet, data); if(bfd_set_section_contents(abfd, output_section, @@ -72,22 +72,22 @@ DEFUN(rel,(abfd, seclet, output_section), { abort(); } - } } void -DEFUN(seclet_dump_seclet,(abfd, seclet, section), +DEFUN(seclet_dump_seclet,(abfd, seclet, section, data), bfd *abfd AND bfd_seclet_type *seclet AND - asection *section) + asection *section AND + PTR data) { switch (seclet->type) { case bfd_indirect_seclet: /* The contents of this section come from another one somewhere else */ - rel(abfd, seclet, section); + rel(abfd, seclet, section, data); break; case bfd_fill_seclet: /* Fill in the section with us */ @@ -110,8 +110,9 @@ DEFUN(seclet_dump_seclet,(abfd, seclet, section), } void -DEFUN(seclet_dump,(abfd), - bfd *abfd) +DEFUN(seclet_dump,(abfd, data), + bfd *abfd AND + PTR data) { /* Write all the seclets on the bfd out, relocate etc according to the rules */ @@ -122,7 +123,7 @@ DEFUN(seclet_dump,(abfd), bfd_seclet_type *p = o->seclets_head; while (p != (bfd_seclet_type *)NULL) { - seclet_dump_seclet(abfd, p, o); + seclet_dump_seclet(abfd, p, o, data); p = p ->next; } o = o->next; -- 2.7.4