aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1992-05-01 20:00:26 +0000
committerSteve Chamberlain <sac@cygnus>1992-05-01 20:00:26 +0000
commit859f11ffd8ff43fd7014b5c04d4a1294e7328066 (patch)
tree540f2ad6fb736c90057c55e94d2b46c5dfb8503c
parent7e7e2d40c1404de249d9f071d859d8c376e92bda (diff)
downloadgdb-859f11ffd8ff43fd7014b5c04d4a1294e7328066.zip
gdb-859f11ffd8ff43fd7014b5c04d4a1294e7328066.tar.gz
gdb-859f11ffd8ff43fd7014b5c04d4a1294e7328066.tar.bz2
* coff-a29k.c: various changes to the way relocations work to cope
with the "new order" and latent bugs. * coffcode.h: lint
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/coff-a29k.c272
-rw-r--r--bfd/coffcode.h40
3 files changed, 167 insertions, 151 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b2d6d36..5dd9d69 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 c5b79d9..5ec48aa 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;
-
- unsigned long insn;
- unsigned long sym_value;
- unsigned long unsigned_value;
- unsigned short r_type;
- long signed_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 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);
- }
+ 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);
+ }
- insn = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
- sym_value = get_symbol_value(symbol_in);
- switch (r_type)
+ 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
{
- 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);
+ /* 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);
+ }
+
+ 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);
+ }
- 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 150e511..d969fdd 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);