Fixes for ChrisB

This commit is contained in:
Steve Chamberlain
1991-03-26 20:31:47 +00:00
parent 16423a4a99
commit d6aa3fb01a

View File

@ -19,28 +19,7 @@ You should have received a copy of the GNU General Public License along with
/* $Id$ */ /* $Id$ */
/* /*
FIXME-SOON. There is a major, potentially invalid assumption in this Most of this hacked by Steve Chamberlain, steve@cygnus.com
code. Namely, that incoming symbol tables will be broken up and glued back
together but only on C_FILE boundaries. That is, if you break the symbol
table on some other boundary, or if you remove a single symbol in the
middle, it is possible to end up with garbage where you expect your
debugging info to be. This only affects debugging info. Specifically, it
affects all of the foondx's in the aux entries. C_FILE entries ARE glued
back together properly. Line numbers and relocations are tracked with
pointers so their ndx's aren't affected.
On the other hand, if the symbol that a line number or reloc points to goes
away, or isn't included in an output bfd, then you'll end up with mush
anyway.
I'm not sure at this point, (Sun Mar 3 00:56:11 PST 1991), but I suspect the
bfd library will need to provide at least the option of a higher and/or
lower abstraction for (at least debugging) symbols. The current
abstraction is sufficient for linking, nm, and very nearly for stripping,
but is nowhere near what would be needed for gas to create coff symbols or
for gdb to read them.
xoxorich.
*/ */
#include "archures.h" /* Machine architectures and types */ #include "archures.h" /* Machine architectures and types */
@ -235,7 +214,53 @@ set_index(symbol, idx)
symbol->value = idx; symbol->value = idx;
} }
#if 0
/* move the section with the specified name to the front of the bfd */
static void
coff_section_to_front(bfd_ptr, move_section_with_this_name)
bfd *bfd_ptr;
char *move_section_with_this_name;
{
asection **section_ptr_ptr = &(bfd_ptr->sections);
while (*section_ptr_ptr != (asection *)NULL)
{
asection *section_ptr = *section_ptr_ptr;
if (strcmp(section_ptr->name, move_section_with_this_name) == 0)
{
*section_ptr_ptr = section_ptr->next;
section_ptr->next = bfd_ptr->sections;
bfd_ptr->sections = section_ptr;
/* Now run through them all and patch the indexes */
{
unsigned int index = 0;
section_ptr = bfd_ptr->sections;
while (section_ptr != (asection *)NULL) {
section_ptr->index = index;
index++;
section_ptr = section_ptr->next;
}
}
return;
}
section_ptr_ptr = &(section_ptr->next);
}
}
/* Reorder the sections to .text, .data, .bss */
static
void
coff_section_reorder(abfd)
bfd *abfd;
{
coff_section_to_front(abfd,".bss");
coff_section_to_front(abfd,".data");
coff_section_to_front(abfd,".text");
}
#endif
/* /*
initialize a section structure with information peculiar to this initialize a section structure with information peculiar to this
particular implementation of coff particular implementation of coff
@ -246,6 +271,7 @@ coff_new_section_hook(abfd_ignore, section_ignore)
bfd *abfd_ignore; bfd *abfd_ignore;
asection *section_ignore; asection *section_ignore;
{ {
return true; return true;
} }
/* actually it makes itself and its children from the file headers */ /* actually it makes itself and its children from the file headers */
@ -361,7 +387,7 @@ coff_real_object_p(abfd, nscns, opthdr)
tdata->raw_linenos = 0; tdata->raw_linenos = 0;
tdata->raw_syments = 0; tdata->raw_syments = 0;
tdata->sym_filepos =0; tdata->sym_filepos =0;
tdata->flags = filehdr->f_flags;
if (nscns != 0) { if (nscns != 0) {
unsigned int i; unsigned int i;
for (i = 0; i < nscns; i++) { for (i = 0; i < nscns; i++) {
@ -440,17 +466,24 @@ coff_real_object_p(abfd, nscns, opthdr)
return abfd->xvec; return abfd->xvec;
} }
/*
Takes a bfd and a symbol, returns a pointer to the coff specific area
of the symbol if there is one.
*/
static coff_symbol_type * static coff_symbol_type *
coff_symbol_from(abfd, symbol) coff_symbol_from(abfd, symbol)
bfd *abfd; bfd *abfd;
asymbol *symbol; asymbol *symbol;
{ {
return symbol->the_bfd->xvec->flavour == bfd_target_coff_flavour_enum if (symbol->the_bfd->xvec->flavour != bfd_target_coff_flavour_enum)
? return (coff_symbol_type *)NULL;
(coff_symbol_type *) symbol
:
(coff_symbol_type *) NULL;
if (symbol->the_bfd->tdata == (void *)NULL)
return (coff_symbol_type *)NULL;
return (coff_symbol_type *) symbol;
} }
@ -655,186 +688,212 @@ bfd *abfd;
/* /*
run through the internal symbol table and make all the pointers and things This procedure runs through the native entries in a coff symbol table
within the table point to the right places and links up all the elements which should point to one another, in
*/ particular these are:
strtag, entag and untags have an auxent endindex which points to the
first syment after the .eos. This is simple to do, we just keep a
pointer to the symbol with the most recent pending strtag and patch it
when we see the eos. This works since coff structs are never nested.
ISFCN type entries have an endindex which points to the next static or
extern in the table, thereby skipping the function contents.
The coff book says that an ISFCN's tagindex
points to the first .bf for the function, so far I havn't seen it
used. We do this using the same mechanism as strtags.
Each file entry has a value which points to the next file entry,
the last file entry points to the first extern symbol in the table
which is not an ISFCN.
Each .bb entry points to the matching .eb entry, but these are nested
so we keep a stack of them.
The tagndx of .eos items points to the strtag attached to them, this
is simply the last_tagndx again.
The tagndx of items with type strtag point to the defining struct.
This bit is complicated; We know that a struct ref and def must be
within the same file, so all the natives will be in the same vector.
This means that we can subtracts two pointers and get the index
differences between to items, used to work out the true index of the
target.
We store in the name field of each syment the actual native index
applied so we can dig it out through a pointer.
*/
static void static void
coff_mangle_symbols(abfd) coff_mangle_symbols(bfd_ptr)
bfd *abfd; bfd *bfd_ptr;
{ {
asymbol **p; unsigned int symbol_count = bfd_get_symcount(bfd_ptr);
asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
SYMENT *last_tagndx = (SYMENT *)NULL;
SYMENT *last_file = (SYMENT *)NULL;
SYMENT *last_fcn = (SYMENT *)NULL;
SYMENT *block_stack[50];
SYMENT **last_block = &block_stack[0];
boolean first_time = true;
unsigned int symbol_index;
unsigned int native_index = 0; unsigned int native_index = 0;
unsigned int last_file_index = 0; for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) {
unsigned int limit = bfd_get_symcount(abfd); coff_symbol_type *coff_symbol_ptr =
SYMENT *last_file_symbol = (SYMENT *) NULL; coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
if (coff_symbol_ptr == (coff_symbol_type *)NULL) {
/* Remember the bfd from the last symbol */ /*
bfd *last_bfd = (bfd *) NULL; This symbol has no coff information in it, it will take up
/* Remember the native from the last symbol */ only one slot in the output symbol table
SYMENT *last_native = (SYMENT *) NULL; */
preload_n_offset(abfd);
p = abfd->outsymbols;
limit = bfd_get_symcount(abfd);
native_index = 0;
while (limit--)
{
coff_symbol_type *q = coff_symbol_from(abfd, *p);
if ((*p)->the_bfd != last_bfd) {
last_bfd = (*p)->the_bfd;
last_native = 0;
last_file_index = native_index;
}
if (!q) {
native_index++; native_index++;
} }
else { else {
SYMENT *native = q->native; SYMENT *syment = coff_symbol_ptr->native;
if (native == (SYMENT *) NULL) { if (syment == (SYMENT *)NULL) {
native_index++; native_index++;
} }
else { else {
/* Normalize the symbol flags */
if (coff_symbol_ptr->symbol.flags & BSF_FORT_COMM) {
/* Alter the native representation */ /* a common symbol is undefined with a value */
if (q->symbol.flags & BSF_FORT_COMM) { syment->n_scnum = N_UNDEF;
native->n_scnum = 0; syment->n_value = coff_symbol_ptr->symbol.value;
native->n_value = q->symbol.value;
} }
else if (q->symbol.flags & BSF_DEBUGGING) { else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) {
/* native->n_scnum = -2; */ syment->n_value = coff_symbol_ptr->symbol.value;
native->n_value = q->symbol.value;
} }
else if (q->symbol.flags & BSF_UNDEFINED) { else if (coff_symbol_ptr->symbol.flags & BSF_UNDEFINED) {
native->n_scnum = 0; syment->n_scnum = N_UNDEF;
native->n_value = 0; syment->n_value = 0;
} }
else if (q->symbol.flags & BSF_ABSOLUTE) { else if (coff_symbol_ptr->symbol.flags & BSF_ABSOLUTE) {
native->n_scnum = -1; syment->n_scnum = N_ABS;
native->n_value = q->symbol.value; syment->n_value = coff_symbol_ptr->symbol.value;
} }
else { else {
native->n_scnum = q->symbol.section->output_section->index + 1; syment->n_scnum =
native->n_value = coff_symbol_ptr->symbol.section->output_section->index+1;
q->symbol.value + syment->n_value =
q->symbol.section->output_offset + coff_symbol_ptr->symbol.value +
q->symbol.section->output_section->vma; coff_symbol_ptr->symbol.section->output_offset +
coff_symbol_ptr->symbol.section->output_section->vma;
} }
if (native->n_numaux != 0)
{
union auxent *a = (union auxent *) (native + 1);
/* If this symbol forward references another, put
into it the real index of it by looking around /* If this symbol ties up something then do it */
*/
if (uses_x_sym_x_fcnary_x_fcn_x_endndx_p(native)) if (syment->n_sclass == C_FILE && last_file != (SYMENT *)NULL)
{ {
/* If this is a FCN entry without a last_file->n_value = native_index;
following .bf then we cheat and }
insert the correct value directy. else if ((syment->n_sclass == C_EXT
|| syment->n_sclass == C_STAT
|| syment->n_sclass == C_LEAFEXT
|| syment->n_sclass == C_LEAFSTAT)
&& last_fcn != (SYMENT *)NULL)
{
AUXENT *auxent = (AUXENT *)(last_fcn+1);
auxent->x_sym.x_fcnary.x_fcn.x_endndx = native_index;
last_fcn = (SYMENT *)NULL;
}
else if (syment->n_sclass == C_EOS && last_tagndx != (SYMENT*)NULL)
{
AUXENT *auxent = (AUXENT *)(last_tagndx+1);
/* Remember that we keep the native index in the offset
so patch the beginning of the struct to point to this
*/ */
if (ISFCN(native->n_type) && auxent->x_sym.x_tagndx = last_tagndx->n_offset;
(native+2)->n_sclass != C_BLOCK) { auxent->x_sym.x_fcnary.x_fcn.x_endndx =
a->x_sym.x_fcnary.x_fcn.x_endndx = native_index + syment->n_numaux + 1 ;
native_index+ native->n_numaux + 1; /* Now point the eos to the structure */
auxent = (AUXENT *)(syment+1);
auxent->x_sym.x_tagndx = last_tagndx->n_offset;
}
else if (syment->n_sclass == C_BLOCK
&& coff_symbol_ptr->symbol.name[1] == 'e')
{
AUXENT *auxent = (AUXENT *)((*(--last_block))+1);
auxent->x_sym.x_fcnary.x_fcn.x_endndx =
native_index + syment->n_numaux + 1;
}
if (syment->n_sclass == C_EXT
&& !ISFCN(syment->n_type)
&& first_time == true
&& last_file != (SYMENT *)NULL) {
/* This is the first external symbol seen which isn't a
function place it in the last .file entry */
last_file->n_value = native_index;
first_time = false;
}
if (syment->n_sclass == C_LEAFPROC && syment->n_numaux == 2) {
AUXENT *auxent = (AUXENT *)(syment+2);
/* This is the definition of a leaf proc, we'll relocate the
address */
auxent->x_bal.x_balntry +=
coff_symbol_ptr->symbol.section->output_offset +
coff_symbol_ptr->symbol.section->output_section->vma ;
}
/* If this symbol needs to be tied up then remember some facts */
if (syment->n_sclass == C_FILE)
{
last_file = syment;
}
if (syment->n_numaux != 0) {
/*
If this symbol would like to point to something in the
future then remember where it is
*/
if (uses_x_sym_x_tagndx_p(syment)) {
/*
If this is a ref to a structure then we'll tie it up
now - there are never any forward refs for one
*/
if (syment->n_sclass == C_STRTAG ||
syment->n_sclass == C_ENTAG ||
syment->n_sclass == C_UNTAG) {
last_tagndx = syment;
} }
else { else {
a->x_sym.x_fcnary.x_fcn.x_endndx =
new_idx(q,a->x_sym.x_fcnary.x_fcn.x_endndx);
}
}
if (uses_x_sym_x_tagndx_p(native)) {
a->x_sym.x_tagndx =
new_idx(q,a->x_sym.x_tagndx);
}
#ifdef I960
else if (native->n_sclass == C_FCN
|| !strcmp((char *) q->symbol.name, ".bf")) {
a->x_sym.x_fcnary.x_fcn.x_endndx = 0;
}
#endif /* I960 */
}
switch (native->n_sclass) {
case C_MOS:
case C_EOS:
case C_REGPARM:
case C_REG:
#ifdef C_AUTOARG
case C_AUTOARG: /* 960-specific storage class */
#endif
/* /*
Fix so that they have an absolute section This is a ref to a structure - the structure must
have been defined within the same file, and previous
to this point, so we can deduce the new tagndx
directly.
*/ */
native->n_scnum = -1; AUXENT *auxent = (AUXENT *)(syment+1);
break; bfd *bfd_ptr = coff_symbol_ptr->symbol.the_bfd;
SYMENT *base = obj_raw_syments(bfd_ptr);
case C_FILE: auxent->x_sym.x_tagndx = base[auxent->x_sym.x_tagndx].n_offset;
if (last_file_symbol) {
if (last_file_symbol->n_value != 0) {
abort();
} /* sanity assertion */
last_file_symbol->n_value = native_index;
} /* Chain all the .file symbols together */
last_file_symbol = native;
break;
case C_EXT:
if (!ISFCN(native->n_type)
&& last_file_symbol != NULL) {
if (last_file_symbol->n_value != 0) {
abort();
} /* sanity assertion */
last_file_symbol->n_value = native_index;
last_file_symbol = NULL;
} /* This should be the first global variable. */
break;
case C_FCN:
case C_NULL:
case C_AUTO:
case C_EXTDEF:
case C_LABEL:
case C_ULABEL:
case C_USTATIC:
case C_STRTAG:
case C_BLOCK:
case C_STAT:
#ifdef I960
case C_LEAFEXT:
case C_LEAFSTAT:
#endif
break;
default:
/*
Bogus: This should be returning an error code, not
printing something out!
*/
/*
warning("Unrecognised sclass %d", native->n_sclass);
*/
break;
}
native_index += 1 + native->n_numaux;
/* Remember the last native here */
last_native = native + native->n_numaux;
}
} }
}
p++; if (ISFCN(syment->n_type)) {
last_fcn = syment;
}
if (syment->n_sclass == C_BLOCK
&& coff_symbol_ptr->symbol.name[1] == 'b')
{
*last_block++ = syment;
}
}
syment->n_offset = native_index;
native_index = native_index + 1 + syment->n_numaux;
}
}
}
} }
}
static void static void
@ -868,8 +927,12 @@ coff_write_symbols(abfd)
coff format. It has no native element to inherit, make our coff format. It has no native element to inherit, make our
own own
*/ */
native = &dummy; native = &dummy;
native->n_type = T_NULL; native->n_type = T_NULL;
#ifdef I960
native->n_flags = 0;
#endif
if (symbol->flags & BSF_ABSOLUTE) { if (symbol->flags & BSF_ABSOLUTE) {
native->n_scnum = N_ABS; native->n_scnum = N_ABS;
native->n_value = symbol->value; native->n_value = symbol->value;
@ -897,20 +960,24 @@ coff_write_symbols(abfd)
native->n_value = symbol->value + native->n_value = symbol->value +
symbol->section->output_section->vma + symbol->section->output_section->vma +
symbol->section->output_offset; symbol->section->output_offset;
#ifdef I960
/* Copy the any flags from the the file hdr into the symbol */
{
coff_symbol_type *c = coff_symbol_from(abfd, symbol);
if (c != (coff_symbol_type *)NULL) {
native->n_flags = c->symbol.the_bfd->flags;
}
}
#endif
} }
#ifdef I960
/*
FIXME-SOON: THIS IS ALREADY WRONG FOR I960. Should echo the
flags in the filehdr. (?)
*/
native->n_flags = 0;
#else /* else not I960 */
#ifdef HASPAD1 #ifdef HASPAD1
native->pad1[0] = 0; native->pad1[0] = 0;
native->pad1[0] = 0; native->pad1[0] = 0;
#endif #endif
#endif /* I960 */
native->pad2[0] = 0; native->pad2[0] = 0;
native->pad2[1] = 0; native->pad2[1] = 0;
@ -1253,6 +1320,9 @@ coff_compute_section_file_positions(abfd)
obj_relocbase(abfd) = sofar; obj_relocbase(abfd) = sofar;
} }
/* SUPPRESS 558 */ /* SUPPRESS 558 */
/* SUPPRESS 529 */ /* SUPPRESS 529 */
static boolean static boolean
@ -1289,6 +1359,9 @@ coff_write_object_contents(abfd)
reloc_base = obj_relocbase(abfd); reloc_base = obj_relocbase(abfd);
/* /*
Make a pass through the symbol table to count line number entries and Make a pass through the symbol table to count line number entries and
put them into the correct asections put them into the correct asections
@ -2463,12 +2536,24 @@ coff_find_nearest_line(abfd,
unsigned int i = 0; unsigned int i = 0;
struct icofdata *cof = obj_icof(abfd); struct icofdata *cof = obj_icof(abfd);
/* Run through the raw syments if available */ /* Run through the raw syments if available */
SYMENT *p = cof->raw_syments; SYMENT *p;
alent *l; alent *l;
unsigned int line_base = 0; unsigned int line_base = 0;
*filename_ptr = 0; *filename_ptr = 0;
*functionname_ptr = 0; *functionname_ptr = 0;
*line_ptr = 0; *line_ptr = 0;
/* Don't try and find line numbers in a non coff file */
if (abfd->xvec->flavour != bfd_target_coff_flavour_enum)
return false;
if (cof == (struct icofdata *)NULL)
return false;
p = cof->raw_syments;
/* /*
I don't know for sure what's right, but this isn't it. First off, an I don't know for sure what's right, but this isn't it. First off, an
object file may not have any C_FILE's in it. After object file may not have any C_FILE's in it. After