From 859f11ffd8ff43fd7014b5c04d4a1294e7328066 Mon Sep 17 00:00:00 2001 From: Steve Chamberlain Date: Fri, 1 May 1992 20:00:26 +0000 Subject: [PATCH] * coff-a29k.c: various changes to the way relocations work to cope with the "new order" and latent bugs. * coffcode.h: lint --- bfd/ChangeLog | 6 ++ bfd/coff-a29k.c | 274 +++++++++++++++++++++++++----------------------- bfd/coffcode.h | 40 +++---- 3 files changed, 168 insertions(+), 152 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index b2d6d366f2..5dd9d69a7c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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) * aoutx.h (aout_swap_ext_reloc_out, aout_swap_std_reloc_out) diff --git a/bfd/coff-a29k.c b/bfd/coff-a29k.c index c5b79d95dd..5ec48aa910 100644 --- a/bfd/coff-a29k.c +++ b/bfd/coff-a29k.c @@ -44,19 +44,17 @@ asymbol *symbol; { long relocation = 0; - if (symbol != (asymbol *)NULL) { - if (symbol->section == &bfd_com_section) - { - - relocation = 0; - } else { - relocation = symbol->value; - } - if (symbol->section != (asection *)NULL) { - relocation += symbol->section->output_section->vma + - symbol->section->output_offset; - } + if (symbol->section == &bfd_com_section) + { + relocation = 0; } + else + { + relocation = symbol->value + + symbol->section->output_section->vma + + symbol->section->output_offset; + } + return(relocation); } @@ -70,132 +68,145 @@ DEFUN(a29k_reloc,(abfd, reloc_entry, symbol_in, data, input_section), PTR data AND asection *input_section) { - /* the consth relocation comes in two parts, we have to remember - the state between calls, in these variables */ - static boolean part1_consth_active = false; - static unsigned long part1_consth_value; + /* the consth relocation comes in two parts, we have to remember + the state between calls, in these variables */ + static boolean part1_consth_active = false; + static unsigned long part1_consth_value; - unsigned long insn; - unsigned long sym_value; - unsigned long unsigned_value; - unsigned short r_type; - long signed_value; + unsigned long insn; + unsigned long sym_value; + unsigned long unsigned_value; + unsigned short r_type; + 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; - /* FIXME: Do we need to check for partial linking here */ - if (symbol_in && (symbol_in->section == &bfd_und_section)) + /* FIXME: Do we need to check for partial linking here */ + if (symbol_in && (symbol_in->section == &bfd_und_section)) + { + /* Keep the state machine happy in case we're called again */ + if (r_type == R_IHIHALF) { - /* Keep the state machine happy in case we're called again */ - if (r_type == R_IHIHALF) - { - part1_consth_active = true; - part1_consth_value = 0; - } - return(bfd_reloc_undefined); + part1_consth_active = true; + part1_consth_value = 0; + } + return(bfd_reloc_undefined); + } + + if ((part1_consth_active) && (r_type != R_IHCONST)) + { + fprintf(stderr,"Relocation problem : "); + fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename); + part1_consth_active = false; + return(bfd_reloc_dangerous); + } + + + sym_value = get_symbol_value(symbol_in); + + switch (r_type) + { + case R_IREL: + insn = bfd_get_32(abfd, hit_data); + /* Take the value in the field and sign extend it */ + signed_value = EXTRACT_HWORD(insn) << 2; + signed_value = SIGN_EXTEND_HWORD(signed_value); + signed_value += sym_value + reloc_entry->addend; + if ((signed_value&~0x3ffff) == 0) + { /* Absolute jmp/call */ + insn |= (1<<24); /* Make it absolute */ + /* FIXME: Should we change r_type to R_IABS */ + signed_value /= 2; + } + else + { + /* Relative jmp/call, so subtract from the value the + address of the place we're coming from */ + signed_value -= reloc_entry->address + + input_section->output_section->vma + + input_section->output_offset; + if (signed_value>0x1ffff || signed_value<-0x20000) + return(bfd_reloc_outofrange); + + signed_value /= 2; + } + insn = INSERT_HWORD(insn, signed_value); + bfd_put_32(abfd, insn ,hit_data); + break; + case R_ILOHALF: + insn = bfd_get_32(abfd, hit_data); + unsigned_value = EXTRACT_HWORD(insn); + unsigned_value += sym_value + reloc_entry->addend; + insn = INSERT_HWORD(insn, unsigned_value); + bfd_put_32(abfd, insn, hit_data); + break; + case R_IHIHALF: + insn = bfd_get_32(abfd, hit_data); + /* consth, part 1 + Just get the symbol value that is referenced */ + part1_consth_active = true; + part1_consth_value = sym_value + reloc_entry->addend; + /* Don't modify insn until R_IHCONST */ + break; + case R_IHCONST: + insn = bfd_get_32(abfd, hit_data); + /* consth, part 2 + Now relocate the reference */ + if (part1_consth_active == false) { + fprintf(stderr,"Relocation problem : "); + fprintf(stderr,"IHIHALF missing in module %s\n", + abfd->filename); + return(bfd_reloc_dangerous); + } + /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */ + unsigned_value = 0; /*EXTRACT_HWORD(insn) << 16;*/ + unsigned_value += reloc_entry->addend; /* r_symndx */ + unsigned_value += part1_consth_value; + unsigned_value = unsigned_value >> 16; + insn = INSERT_HWORD(insn, unsigned_value); + part1_consth_active = false; + bfd_put_32(abfd, insn, hit_data); + break; + case R_BYTE: + insn = bfd_get_8(abfd, hit_data); + unsigned_value = insn + sym_value + reloc_entry->addend; + if (unsigned_value & 0xffffff00) { + fprintf(stderr,"Relocation problem : "); + fprintf(stderr,"byte value too large in module %s\n", + abfd->filename); + return(bfd_reloc_overflow); + } + bfd_put_8(abfd, insn, hit_data); + break; + case R_HWORD: + insn = bfd_get_16(abfd, hit_data); + unsigned_value = insn + sym_value + reloc_entry->addend; + if (unsigned_value & 0xffff0000) { + fprintf(stderr,"Relocation problem : "); + fprintf(stderr,"hword value too large in module %s\n", + abfd->filename); + return(bfd_reloc_overflow); } - if ((part1_consth_active) && (r_type != R_IHCONST)) - { - fprintf(stderr,"Relocation problem : "); - fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename); - part1_consth_active = false; - return(bfd_reloc_dangerous); - } + bfd_put_16(abfd, insn, hit_data); + break; + case R_WORD: + insn = bfd_get_32(abfd, hit_data); + insn += sym_value + reloc_entry->addend; + bfd_put_32(abfd, insn, hit_data); + break; + default: + fprintf(stderr,"Relocation problem : "); + fprintf(stderr,"Unrecognized reloc type %d, in module %s\n", + r_type,abfd->filename); + return (bfd_reloc_dangerous); + } - insn = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address); - sym_value = get_symbol_value(symbol_in); - switch (r_type) - { - case R_IREL: - /* Take the value in the field and sign extend it */ - signed_value = EXTRACT_HWORD(insn) << 2; - signed_value = SIGN_EXTEND_HWORD(signed_value); - signed_value += sym_value + reloc_entry->addend; - if ((signed_value&~0x3ffff) == 0) - { /* Absolute jmp/call */ - insn |= (1<<24); /* Make it absolute */ - /* FIXME: Should we change r_type to R_IABS */ - signed_value /= 2; - } - else - { - /* Relative jmp/call, so subtract from the value the - address of the place we're coming from */ - signed_value -= reloc_entry->address + - input_section->output_section->vma + - input_section->output_offset; - if (signed_value>0x1ffff || signed_value<-0x20000) - return(bfd_reloc_outofrange); - - signed_value /= 2; - } - insn = INSERT_HWORD(insn, signed_value); - break; - case R_ILOHALF: - unsigned_value = EXTRACT_HWORD(insn); - unsigned_value += sym_value + reloc_entry->addend; - insn = INSERT_HWORD(insn, unsigned_value); - break; - case R_IHIHALF: - /* consth, part 1 - Just get the symbol value that is referenced */ - part1_consth_active = true; - part1_consth_value = sym_value + reloc_entry->addend; - /* Don't modify insn until R_IHCONST */ - return(bfd_reloc_ok); - break; - case R_IHCONST: - /* consth, part 2 - Now relocate the reference */ - if (part1_consth_active == false) { - fprintf(stderr,"Relocation problem : "); - fprintf(stderr,"IHIHALF missing in module %s\n", - abfd->filename); - return(bfd_reloc_dangerous); - } - /* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */ - unsigned_value = 0; /*EXTRACT_HWORD(insn) << 16;*/ - unsigned_value += reloc_entry->addend; /* r_symndx */ - unsigned_value += part1_consth_value; - unsigned_value = unsigned_value >> 16; - insn = INSERT_HWORD(insn, unsigned_value); - part1_consth_active = false; - break; - case R_BYTE: - unsigned_value = (insn >> 24) + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffffff00) { - fprintf(stderr,"Relocation problem : "); - fprintf(stderr,"byte value too large in module %s\n", - abfd->filename); - return(bfd_reloc_overflow); - } - insn = (insn & 0x00ffffff) | (unsigned_value << 24); - break; - case R_HWORD: - unsigned_value = (insn >> 16) + sym_value + reloc_entry->addend; - if (unsigned_value & 0xffff0000) { - fprintf(stderr,"Relocation problem : "); - fprintf(stderr,"hword value too large in module %s\n", - abfd->filename); - return(bfd_reloc_overflow); - } - insn = (insn & 0x0000ffff) | (unsigned_value<<16); - break; - case R_WORD: - insn += sym_value + reloc_entry->addend; - break; - default: - fprintf(stderr,"Relocation problem : "); - fprintf(stderr,"Unrecognized reloc type %d, in module %s\n", - r_type,abfd->filename); - return (bfd_reloc_dangerous); - } - - bfd_put_32(abfd, insn, (bfd_byte *)data + reloc_entry->address); - return(bfd_reloc_ok); + return(bfd_reloc_ok); } /* type rightshift @@ -259,17 +270,16 @@ static void DEFUN(reloc_processing,(relent,reloc, symbols, abfd, section) , if (ptr && ptr->the_bfd == abfd - && ptr->section != (asection *) NULL + && ((ptr->flags & BSF_OLD_COMMON)== 0)) { - relent->addend = -(ptr->section->vma + ptr->value); + relent->addend = 0; } else { relent->addend = 0; } relent->address-= section->vma; -/* relent->section = 0;*/ } } diff --git a/bfd/coffcode.h b/bfd/coffcode.h index 150e511469..d969fddb17 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -556,14 +556,15 @@ DEFUN(coff_swap_sym_out,(abfd, inp, extp), } 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 PTR ext1 AND int type AND int class AND - union internal_auxent *in) + PTR in1) { AUXENT *ext = (AUXENT *)ext1; + union internal_auxent *in = (union internal_auxent *)in1; switch (class) { case C_FILE: @@ -693,7 +694,7 @@ DEFUN(coff_swap_aux_out,(abfd, inp, type, class, extp), default: PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx); #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 if (ISFCN(type)) { @@ -1497,7 +1498,7 @@ unsigned int written) coff_swap_sym_out(abfd, &native->u.syment, &buf); 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; bzero((PTR)&buf, AUXESZ); @@ -2434,12 +2435,12 @@ DEFUN(coff_write_object_contents,(abfd), return false; { 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); } if (abfd->flags & EXEC_P) { 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); } return true; @@ -2704,7 +2705,7 @@ bfd *abfd) raw_src++, internal_ptr++) { 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_end = 0; symbol_ptr = internal_ptr; @@ -2722,13 +2723,18 @@ bfd *abfd) symbol_ptr->u.syment.n_type, symbol_ptr->u.syment.n_sclass, &(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, internal, symbol_ptr->u.syment.n_type, symbol_ptr->u.syment.n_sclass, internal_ptr); } + + } } /* Free all the raw stuff */ @@ -2835,6 +2841,7 @@ DEFUN(section_from_bfd_index,(abfd, index), answer = answer->next; } BFD_ASSERT(0); + return &bfd_und_section; /* For gcc -W and lint. Never executed. */ } #ifndef NO_COFF_LINENOS @@ -2970,6 +2977,9 @@ DEFUN(coff_slurp_symbol_table,(abfd), src->u.syment._n._n_n._n_zeroes = (int) dst; dst->symbol.section = section_from_bfd_index(abfd, src->u.syment.n_scnum); + dst->symbol.flags = 0; + dst->done_lineno = false; + switch (src->u.syment.n_sclass) { #ifdef I960 case C_LEAFEXT: @@ -3227,7 +3237,6 @@ SUBSUBSECTION #ifndef CALC_ADDEND #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \ if (ptr && ptr->the_bfd == abfd \ - && ptr->section != (asection *) NULL \ && ((ptr->flags & BSF_OLD_COMMON)== 0)) \ { \ cache_ptr->addend = -(ptr->section->vma + ptr->value); \ @@ -3305,8 +3314,8 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols), } else { - cache_ptr->sym_ptr_ptr = 0; - ptr = 0; + cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr; + ptr = 0; } @@ -3703,19 +3712,10 @@ DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet), bfd_seclet_type *seclet) { - asymbol **symbols = 0; - extern bfd *output_bfd; - /* Get enough memory to hold the stuff */ bfd *input_bfd = seclet->u.indirect.section->owner; asection *input_section = seclet->u.indirect.section; - 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, input_section); arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);