* coff-a29k.c: various changes to the way relocations work to cope

with the "new order" and latent bugs.
	* coffcode.h: lint
This commit is contained in:
Steve Chamberlain 1992-05-01 20:00:26 +00:00
parent 7e7e2d40c1
commit 859f11ffd8
3 changed files with 168 additions and 152 deletions

View file

@ -1,3 +1,9 @@
Fri May 1 12:58:34 1992 Steve Chamberlain (sac@thepub.cygnus.com)
* coff-a29k.c: various changes to the way relocations work to cope
with the "new order" and latent bugs.
* coffcode.h: lint
Wed Apr 29 12:37:07 1992 Steve Chamberlain (sac@thepub.cygnus.com) Wed Apr 29 12:37:07 1992 Steve Chamberlain (sac@thepub.cygnus.com)
* aoutx.h (aout_swap_ext_reloc_out, aout_swap_std_reloc_out) * aoutx.h (aout_swap_ext_reloc_out, aout_swap_std_reloc_out)

View file

@ -44,19 +44,17 @@ asymbol *symbol;
{ {
long relocation = 0; long relocation = 0;
if (symbol != (asymbol *)NULL) {
if (symbol->section == &bfd_com_section) if (symbol->section == &bfd_com_section)
{ {
relocation = 0; relocation = 0;
} else {
relocation = symbol->value;
} }
if (symbol->section != (asection *)NULL) { else
relocation += symbol->section->output_section->vma + {
relocation = symbol->value +
symbol->section->output_section->vma +
symbol->section->output_offset; symbol->section->output_offset;
} }
}
return(relocation); return(relocation);
} }
@ -81,6 +79,8 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section),
unsigned short r_type; unsigned short r_type;
long signed_value; long signed_value;
unsigned long addr = reloc_entry->address + input_section->vma;
bfd_byte *hit_data =addr + (bfd_byte *)(data);
r_type = reloc_entry->howto->type; r_type = reloc_entry->howto->type;
@ -104,12 +104,13 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section),
return(bfd_reloc_dangerous); return(bfd_reloc_dangerous);
} }
insn = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
sym_value = get_symbol_value(symbol_in); sym_value = get_symbol_value(symbol_in);
switch (r_type) switch (r_type)
{ {
case R_IREL: case R_IREL:
insn = bfd_get_32(abfd, hit_data);
/* Take the value in the field and sign extend it */ /* Take the value in the field and sign extend it */
signed_value = EXTRACT_HWORD(insn) << 2; signed_value = EXTRACT_HWORD(insn) << 2;
signed_value = SIGN_EXTEND_HWORD(signed_value); signed_value = SIGN_EXTEND_HWORD(signed_value);
@ -133,21 +134,25 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section),
signed_value /= 2; signed_value /= 2;
} }
insn = INSERT_HWORD(insn, signed_value); insn = INSERT_HWORD(insn, signed_value);
bfd_put_32(abfd, insn ,hit_data);
break; break;
case R_ILOHALF: case R_ILOHALF:
insn = bfd_get_32(abfd, hit_data);
unsigned_value = EXTRACT_HWORD(insn); unsigned_value = EXTRACT_HWORD(insn);
unsigned_value += sym_value + reloc_entry->addend; unsigned_value += sym_value + reloc_entry->addend;
insn = INSERT_HWORD(insn, unsigned_value); insn = INSERT_HWORD(insn, unsigned_value);
bfd_put_32(abfd, insn, hit_data);
break; break;
case R_IHIHALF: case R_IHIHALF:
insn = bfd_get_32(abfd, hit_data);
/* consth, part 1 /* consth, part 1
Just get the symbol value that is referenced */ Just get the symbol value that is referenced */
part1_consth_active = true; part1_consth_active = true;
part1_consth_value = sym_value + reloc_entry->addend; part1_consth_value = sym_value + reloc_entry->addend;
/* Don't modify insn until R_IHCONST */ /* Don't modify insn until R_IHCONST */
return(bfd_reloc_ok);
break; break;
case R_IHCONST: case R_IHCONST:
insn = bfd_get_32(abfd, hit_data);
/* consth, part 2 /* consth, part 2
Now relocate the reference */ Now relocate the reference */
if (part1_consth_active == false) { if (part1_consth_active == false) {
@ -163,29 +168,35 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section),
unsigned_value = unsigned_value >> 16; unsigned_value = unsigned_value >> 16;
insn = INSERT_HWORD(insn, unsigned_value); insn = INSERT_HWORD(insn, unsigned_value);
part1_consth_active = false; part1_consth_active = false;
bfd_put_32(abfd, insn, hit_data);
break; break;
case R_BYTE: case R_BYTE:
unsigned_value = (insn >> 24) + sym_value + reloc_entry->addend; insn = bfd_get_8(abfd, hit_data);
unsigned_value = insn + sym_value + reloc_entry->addend;
if (unsigned_value & 0xffffff00) { if (unsigned_value & 0xffffff00) {
fprintf(stderr,"Relocation problem : "); fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"byte value too large in module %s\n", fprintf(stderr,"byte value too large in module %s\n",
abfd->filename); abfd->filename);
return(bfd_reloc_overflow); return(bfd_reloc_overflow);
} }
insn = (insn & 0x00ffffff) | (unsigned_value << 24); bfd_put_8(abfd, insn, hit_data);
break; break;
case R_HWORD: case R_HWORD:
unsigned_value = (insn >> 16) + sym_value + reloc_entry->addend; insn = bfd_get_16(abfd, hit_data);
unsigned_value = insn + sym_value + reloc_entry->addend;
if (unsigned_value & 0xffff0000) { if (unsigned_value & 0xffff0000) {
fprintf(stderr,"Relocation problem : "); fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"hword value too large in module %s\n", fprintf(stderr,"hword value too large in module %s\n",
abfd->filename); abfd->filename);
return(bfd_reloc_overflow); return(bfd_reloc_overflow);
} }
insn = (insn & 0x0000ffff) | (unsigned_value<<16);
bfd_put_16(abfd, insn, hit_data);
break; break;
case R_WORD: case R_WORD:
insn = bfd_get_32(abfd, hit_data);
insn += sym_value + reloc_entry->addend; insn += sym_value + reloc_entry->addend;
bfd_put_32(abfd, insn, hit_data);
break; break;
default: default:
fprintf(stderr,"Relocation problem : "); fprintf(stderr,"Relocation problem : ");
@ -194,7 +205,7 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section),
return (bfd_reloc_dangerous); return (bfd_reloc_dangerous);
} }
bfd_put_32(abfd, insn, (bfd_byte *)data + reloc_entry->address);
return(bfd_reloc_ok); return(bfd_reloc_ok);
} }
@ -259,17 +270,16 @@ static void DEFUN(reloc_processing,(relent,reloc, symbols, abfd, section) ,
if (ptr if (ptr
&& ptr->the_bfd == abfd && ptr->the_bfd == abfd
&& ptr->section != (asection *) NULL
&& ((ptr->flags & BSF_OLD_COMMON)== 0)) && ((ptr->flags & BSF_OLD_COMMON)== 0))
{ {
relent->addend = -(ptr->section->vma + ptr->value); relent->addend = 0;
} }
else else
{ {
relent->addend = 0; relent->addend = 0;
} }
relent->address-= section->vma; relent->address-= section->vma;
/* relent->section = 0;*/
} }
} }

View file

@ -556,14 +556,15 @@ DEFUN(coff_swap_sym_out,(abfd, inp, extp),
} }
static void static void
DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in), DEFUN(coff_swap_aux_in,(abfd, ext1, type, class, in1),
bfd *abfd AND bfd *abfd AND
PTR ext1 AND PTR ext1 AND
int type AND int type AND
int class AND int class AND
union internal_auxent *in) PTR in1)
{ {
AUXENT *ext = (AUXENT *)ext1; AUXENT *ext = (AUXENT *)ext1;
union internal_auxent *in = (union internal_auxent *)in1;
switch (class) { switch (class) {
case C_FILE: case C_FILE:
@ -693,7 +694,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp),
default: default:
PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
#ifndef NO_TVNDX #ifndef NO_TVNDX
PUTWORD(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx); bfd_h_put_16(abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
#endif #endif
if (ISFCN(type)) { if (ISFCN(type)) {
@ -1497,7 +1498,7 @@ unsigned int written)
coff_swap_sym_out(abfd, &native->u.syment, &buf); coff_swap_sym_out(abfd, &native->u.syment, &buf);
bfd_write((PTR)& buf, 1, SYMESZ, abfd); bfd_write((PTR)& buf, 1, SYMESZ, abfd);
for (j = 0; j <= native->u.syment.n_numaux; j++) for (j = 0; j < native->u.syment.n_numaux; j++)
{ {
AUXENT buf1; AUXENT buf1;
bzero((PTR)&buf, AUXESZ); bzero((PTR)&buf, AUXESZ);
@ -2434,12 +2435,12 @@ DEFUN(coff_write_object_contents,(abfd),
return false; return false;
{ {
FILHDR buff; FILHDR buff;
coff_swap_filehdr_out(abfd, &internal_f, &buff); coff_swap_filehdr_out(abfd, (PTR)&internal_f, (PTR)&buff);
bfd_write((PTR) &buff, 1, FILHSZ, abfd); bfd_write((PTR) &buff, 1, FILHSZ, abfd);
} }
if (abfd->flags & EXEC_P) { if (abfd->flags & EXEC_P) {
AOUTHDR buff; AOUTHDR buff;
coff_swap_aouthdr_out(abfd, &internal_a, &buff); coff_swap_aouthdr_out(abfd, (PTR)&internal_a, (PTR)&buff);
bfd_write((PTR) &buff, 1, AOUTSZ, abfd); bfd_write((PTR) &buff, 1, AOUTSZ, abfd);
} }
return true; return true;
@ -2704,7 +2705,7 @@ bfd *abfd)
raw_src++, internal_ptr++) { raw_src++, internal_ptr++) {
unsigned int i; unsigned int i;
coff_swap_sym_in(abfd, (char *)raw_src, (char *)&internal_ptr->u.syment); coff_swap_sym_in(abfd, (PTR)raw_src, (PTR)&internal_ptr->u.syment);
internal_ptr->fix_tag = 0; internal_ptr->fix_tag = 0;
internal_ptr->fix_end = 0; internal_ptr->fix_end = 0;
symbol_ptr = internal_ptr; symbol_ptr = internal_ptr;
@ -2722,6 +2723,9 @@ bfd *abfd)
symbol_ptr->u.syment.n_type, symbol_ptr->u.syment.n_type,
symbol_ptr->u.syment.n_sclass, symbol_ptr->u.syment.n_sclass,
&(internal_ptr->u.auxent)); &(internal_ptr->u.auxent));
/* Remember that bal entries arn't pointerized */
if (i != 1 || symbol_ptr->u.syment.n_sclass != C_LEAFPROC)
{
coff_pointerize_aux(abfd, coff_pointerize_aux(abfd,
internal, internal,
@ -2729,6 +2733,8 @@ bfd *abfd)
symbol_ptr->u.syment.n_sclass, symbol_ptr->u.syment.n_sclass,
internal_ptr); internal_ptr);
} }
}
} }
/* Free all the raw stuff */ /* Free all the raw stuff */
@ -2835,6 +2841,7 @@ DEFUN(section_from_bfd_index,(abfd, index),
answer = answer->next; answer = answer->next;
} }
BFD_ASSERT(0); BFD_ASSERT(0);
return &bfd_und_section; /* For gcc -W and lint. Never executed. */
} }
#ifndef NO_COFF_LINENOS #ifndef NO_COFF_LINENOS
@ -2970,6 +2977,9 @@ DEFUN(coff_slurp_symbol_table,(abfd),
src->u.syment._n._n_n._n_zeroes = (int) dst; src->u.syment._n._n_n._n_zeroes = (int) dst;
dst->symbol.section = section_from_bfd_index(abfd, dst->symbol.section = section_from_bfd_index(abfd,
src->u.syment.n_scnum); src->u.syment.n_scnum);
dst->symbol.flags = 0;
dst->done_lineno = false;
switch (src->u.syment.n_sclass) { switch (src->u.syment.n_sclass) {
#ifdef I960 #ifdef I960
case C_LEAFEXT: case C_LEAFEXT:
@ -3227,7 +3237,6 @@ SUBSUBSECTION
#ifndef CALC_ADDEND #ifndef CALC_ADDEND
#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
if (ptr && ptr->the_bfd == abfd \ if (ptr && ptr->the_bfd == abfd \
&& ptr->section != (asection *) NULL \
&& ((ptr->flags & BSF_OLD_COMMON)== 0)) \ && ((ptr->flags & BSF_OLD_COMMON)== 0)) \
{ \ { \
cache_ptr->addend = -(ptr->section->vma + ptr->value); \ cache_ptr->addend = -(ptr->section->vma + ptr->value); \
@ -3305,7 +3314,7 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
} }
else else
{ {
cache_ptr->sym_ptr_ptr = 0; cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr;
ptr = 0; ptr = 0;
} }
@ -3703,19 +3712,10 @@ DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet),
bfd_seclet_type *seclet) bfd_seclet_type *seclet)
{ {
asymbol **symbols = 0;
extern bfd *output_bfd;
/* Get enough memory to hold the stuff */ /* Get enough memory to hold the stuff */
bfd *input_bfd = seclet->u.indirect.section->owner; bfd *input_bfd = seclet->u.indirect.section->owner;
asection *input_section = seclet->u.indirect.section; asection *input_section = seclet->u.indirect.section;
bfd_byte *data = (bfd_byte *)malloc(input_section->_raw_size); bfd_byte *data = (bfd_byte *)malloc(input_section->_raw_size);
bfd_byte *dst = data;
bfd_byte *prev_dst = data;
unsigned int gap = 0;
bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
input_section); input_section);
arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size); arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);