* som.c (som_prep_for_fixups): New function.
This commit is contained in:
parent
938fa52b82
commit
aff9779048
2 changed files with 101 additions and 0 deletions
|
@ -1,3 +1,7 @@
|
|||
Sat Nov 13 15:27:15 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
|
||||
|
||||
* som.c (som_prep_for_fixups): New function.
|
||||
|
||||
Fri Nov 12 15:29:36 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
|
||||
|
||||
* som.c (som_write_object_contents): Do not abort. Flesh out.
|
||||
|
|
97
bfd/som.c
97
bfd/som.c
|
@ -161,6 +161,7 @@ static boolean som_prep_headers PARAMS ((bfd *));
|
|||
static int som_sizeof_headers PARAMS ((bfd *, boolean));
|
||||
static boolean som_write_headers PARAMS ((bfd *));
|
||||
static boolean som_build_and_write_symbol_table PARAMS ((bfd *));
|
||||
static void som_prep_for_fixups PARAMS ((bfd *, asymbol **, unsigned long));
|
||||
|
||||
|
||||
static reloc_howto_type som_hppa_howto_table[] =
|
||||
|
@ -1443,6 +1444,102 @@ compare_syms (sym1, sym2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Perform various work in preparation for emitting the fixup stream. */
|
||||
|
||||
static void
|
||||
som_prep_for_fixups (abfd, syms, num_syms)
|
||||
bfd *abfd;
|
||||
asymbol **syms;
|
||||
unsigned long num_syms;
|
||||
{
|
||||
int i;
|
||||
asection *section;
|
||||
|
||||
/* Most SOM relocations involving a symbol have a length which is
|
||||
dependent on the index of the symbol. So symbols which are
|
||||
used often in relocations should have a small index. */
|
||||
|
||||
/* First initialize the counters for each symbol. */
|
||||
for (i = 0; i < num_syms; i++)
|
||||
{
|
||||
/* Handle a section symbol; these have no pointers back to the
|
||||
SOM symbol info. So we just use the pointer field (udata)
|
||||
to hold the relocation count.
|
||||
|
||||
FIXME. While we're here set the name of any section symbol
|
||||
to something which will not screw GDB. How do other formats
|
||||
deal with this?!? */
|
||||
if (som_symbol_data (syms[i]) == NULL)
|
||||
{
|
||||
syms[i]->flags |= BSF_SECTION_SYM;
|
||||
syms[i]->name = "L$0\002";
|
||||
syms[i]->udata = (PTR) 0;
|
||||
}
|
||||
else
|
||||
(*som_symbol_data (syms[i]))->reloc_count = 0;
|
||||
}
|
||||
|
||||
/* Now that the counters are initialized, make a weighted count
|
||||
of how often a given symbol is used in a relocation. */
|
||||
for (section = abfd->sections; section != NULL; section = section->next)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Does this section have any relocations? */
|
||||
if (section->reloc_count <= 0)
|
||||
continue;
|
||||
|
||||
/* Walk through each relocation for this section. */
|
||||
for (i = 1; i < section->reloc_count; i++)
|
||||
{
|
||||
arelent *reloc = section->orelocation[i];
|
||||
int scale;
|
||||
|
||||
/* If no symbol, then there is no counter to increase. */
|
||||
if (reloc->sym_ptr_ptr == NULL)
|
||||
continue;
|
||||
|
||||
/* Scaling to encourage symbols involved in R_DP_RELATIVE
|
||||
and R_CODE_ONE_SYMBOL relocations to come first. These
|
||||
two relocations have single byte versions if the symbol
|
||||
index is very small. */
|
||||
if (reloc->howto->type == R_DP_RELATIVE
|
||||
|| reloc->howto->type == R_CODE_ONE_SYMBOL)
|
||||
scale = 2;
|
||||
else
|
||||
scale = 1;
|
||||
|
||||
/* Handle section symbols by ramming the count in the udata
|
||||
field. It will not be used and the count is very important
|
||||
for these symbols. */
|
||||
if ((*reloc->sym_ptr_ptr)->flags & BSF_SECTION_SYM)
|
||||
{
|
||||
(*reloc->sym_ptr_ptr)->udata =
|
||||
(PTR) ((int) (*reloc->sym_ptr_ptr)->udata + scale);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A normal symbol. Increment the count. */
|
||||
(*som_symbol_data ((*reloc->sym_ptr_ptr)))->reloc_count += scale;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now sort the symbols. */
|
||||
qsort (syms, num_syms, sizeof (asymbol *), compare_syms);
|
||||
|
||||
/* Compute the symbol indexes, they will be needed by the relocation
|
||||
code. */
|
||||
for (i = 0; i < num_syms; i++)
|
||||
{
|
||||
/* A section symbol. Again, there is no pointer to backend symbol
|
||||
information, so we reuse (abuse) the udata field again. */
|
||||
if (syms[i]->flags & BSF_SECTION_SYM)
|
||||
syms[i]->udata = (PTR) i;
|
||||
else
|
||||
(*som_symbol_data (syms[i]))->index = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, scribble out the various headers to the disk. */
|
||||
|
||||
static boolean
|
||||
|
|
Loading…
Reference in a new issue