* ecoff.c: First cut at new style of linker backend for
ECOFF--added a bunch of functions. Also: (ecoff_sec_to_styp_flags): Set flags for .pdata and .xdata. (ecoff_slurp_symbolic_header): New function. (ecoff_slurp_symbolic_info): Call ecoff_slurp_symbolic_header. (ecoff_compute_reloc_file_positions): New function. (ecoff_set_section_contents): Get out quickly if count is zero. Check errors better. (ecoff_write_object_contents): Put .xdata section in data segment. Call ecoff_compute_reloc_file_positions. Don't output relocs or external symbols if outsymbols is NULL. (ecoff_bfd_final_link): Completely rewritten. * libecoff.h: Include bfdlink.h. (struct ecoff_backend_data): Add relocate_section field. (ecoff_data_type): Add sym_hashes and symndx_to_section fields. (struct ecoff_link_hash_entry): Define. (struct ecoff_link_hash_table): Define. (ecoff_bfd_link_add_symbols): Declare as function, not macro. (ecoff_bfd_link_hash_table_create): Likewise. * ecofflink.c (bfd_ecoff_debug_one_external): New function. (bfd_ecoff_debug_externals): Call bfd_ecoff_debug_one_external. * bfd-in.h (bfd_ecoff_debug_one_external): Declare. * bfd-in2.h: Rebuilt. * coff-alpha.c (alpha_howto_table): Mark BRADDR as partial_inplace, and set the src_mask to 0x1fffff. (alpha_ecoff_get_relocated_section_contents): Remove unused variable gp_warned. (alpha_convert_external_reloc): New static function. (alpha_relocate_section): New static function. (alpha_ecoff_backend_data): Initialize relocate_section field. * coff-mips.c (mips_relocate_refhi): New static function. (mips_relocate_section): New static function. (mips_ecoff_backend_data): Initialize relocate_section field.
This commit is contained in:
parent
b9395be3af
commit
966e0a16b8
4 changed files with 1393 additions and 360 deletions
|
@ -407,7 +407,8 @@ extern struct bfd_hash_entry *bfd_hash_newfunc
|
|||
const char *));
|
||||
|
||||
/* Grab some space for a hash table entry. */
|
||||
extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, size_t));
|
||||
extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *,
|
||||
unsigned int));
|
||||
|
||||
/* Traverse a hash table in a random order, calling a function on each
|
||||
element. If the function returns false, the traversal stops. The
|
||||
|
@ -558,6 +559,10 @@ extern boolean bfd_ecoff_debug_externals
|
|||
struct ecoff_extr *),
|
||||
void (*set_index) (struct symbol_cache_entry *,
|
||||
bfd_size_type)));
|
||||
extern boolean bfd_ecoff_debug_one_external
|
||||
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
||||
const struct ecoff_debug_swap *swap,
|
||||
const char *name, struct ecoff_extr *esym));
|
||||
extern bfd_size_type bfd_ecoff_debug_size
|
||||
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
||||
const struct ecoff_debug_swap *swap));
|
||||
|
|
|
@ -407,7 +407,8 @@ extern struct bfd_hash_entry *bfd_hash_newfunc
|
|||
const char *));
|
||||
|
||||
/* Grab some space for a hash table entry. */
|
||||
extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *, size_t));
|
||||
extern PTR bfd_hash_allocate PARAMS ((struct bfd_hash_table *,
|
||||
unsigned int));
|
||||
|
||||
/* Traverse a hash table in a random order, calling a function on each
|
||||
element. If the function returns false, the traversal stops. The
|
||||
|
@ -558,6 +559,10 @@ extern boolean bfd_ecoff_debug_externals
|
|||
struct ecoff_extr *),
|
||||
void (*set_index) (struct symbol_cache_entry *,
|
||||
bfd_size_type)));
|
||||
extern boolean bfd_ecoff_debug_one_external
|
||||
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
||||
const struct ecoff_debug_swap *swap,
|
||||
const char *name, struct ecoff_extr *esym));
|
||||
extern bfd_size_type bfd_ecoff_debug_size
|
||||
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
||||
const struct ecoff_debug_swap *swap));
|
||||
|
|
1616
bfd/ecoff.c
1616
bfd/ecoff.c
File diff suppressed because it is too large
Load diff
123
bfd/ecofflink.c
123
bfd/ecofflink.c
|
@ -27,7 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "coff/ecoff.h"
|
||||
|
||||
static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
|
||||
bfd_size_type need));
|
||||
size_t need));
|
||||
static bfd_size_type ecoff_add_string PARAMS ((struct ecoff_debug_info *,
|
||||
FDR *fdr, const char *string));
|
||||
static void ecoff_align_debug PARAMS ((bfd *abfd,
|
||||
|
@ -43,10 +43,10 @@ static boolean
|
|||
ecoff_add_bytes (buf, bufend, need)
|
||||
char **buf;
|
||||
char **bufend;
|
||||
bfd_size_type need;
|
||||
size_t need;
|
||||
{
|
||||
bfd_size_type have;
|
||||
bfd_size_type want;
|
||||
size_t have;
|
||||
size_t want;
|
||||
char *newbuf;
|
||||
|
||||
have = *bufend - *buf;
|
||||
|
@ -78,6 +78,7 @@ ecoff_add_bytes (buf, bufend, need)
|
|||
pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and
|
||||
INPUT_SWAP point to the swapping information needed. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
boolean
|
||||
bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
|
||||
input_bfd, input_debug, input_swap,
|
||||
|
@ -223,13 +224,13 @@ bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
|
|||
/* Copy the information that does not need swapping. */
|
||||
memcpy (output_debug->line + output_symhdr->cbLine,
|
||||
input_debug->line,
|
||||
input_symhdr->cbLine * sizeof (unsigned char));
|
||||
(size_t) (input_symhdr->cbLine * sizeof (unsigned char)));
|
||||
memcpy (output_debug->external_aux + output_symhdr->iauxMax,
|
||||
input_debug->external_aux,
|
||||
input_symhdr->iauxMax * sizeof (union aux_ext));
|
||||
(size_t) (input_symhdr->iauxMax * sizeof (union aux_ext)));
|
||||
memcpy (output_debug->ss + output_symhdr->issMax,
|
||||
input_debug->ss,
|
||||
input_symhdr->issMax * sizeof (char));
|
||||
(size_t) (input_symhdr->issMax * sizeof (char)));
|
||||
|
||||
/* Some of the information may need to be swapped. */
|
||||
if (output_bfd->xvec->header_byteorder_big_p
|
||||
|
@ -245,7 +246,8 @@ bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
|
|||
memcpy (((char *) output_debug->external_dnr
|
||||
+ output_symhdr->idnMax * output_swap->external_dnr_size),
|
||||
input_debug->external_dnr,
|
||||
input_symhdr->idnMax * output_swap->external_dnr_size);
|
||||
((size_t)
|
||||
(input_symhdr->idnMax * output_swap->external_dnr_size)));
|
||||
#endif
|
||||
BFD_ASSERT (output_swap->external_pdr_size
|
||||
== input_swap->external_pdr_size);
|
||||
|
@ -253,14 +255,16 @@ bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
|
|||
memcpy (((char *) output_debug->external_pdr
|
||||
+ output_symhdr->ipdMax * output_swap->external_pdr_size),
|
||||
input_debug->external_pdr,
|
||||
input_symhdr->ipdMax * output_swap->external_pdr_size);
|
||||
((size_t)
|
||||
(input_symhdr->ipdMax * output_swap->external_pdr_size)));
|
||||
BFD_ASSERT (output_swap->external_opt_size
|
||||
== input_swap->external_opt_size);
|
||||
if (input_symhdr->ioptMax > 0)
|
||||
memcpy (((char *) output_debug->external_opt
|
||||
+ output_symhdr->ioptMax * output_swap->external_opt_size),
|
||||
input_debug->external_opt,
|
||||
input_symhdr->ioptMax * output_swap->external_opt_size);
|
||||
((size_t)
|
||||
(input_symhdr->ioptMax * output_swap->external_opt_size)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -462,7 +466,7 @@ ecoff_add_string (output, fdr, string)
|
|||
{
|
||||
if (ecoff_add_bytes (&output->ss, &output->ss_end,
|
||||
symhdr->issMax + len + 1) == false)
|
||||
return -1;
|
||||
return (bfd_size_type) -1;
|
||||
}
|
||||
memcpy (output->ss + symhdr->issMax, string, len + 1);
|
||||
ret = fdr->cbSs;
|
||||
|
@ -504,6 +508,8 @@ bfd_ecoff_debug_link_other (output_bfd, output_debug, output_swap, input_bfd)
|
|||
fdr.cbSs = 0;
|
||||
fdr.rss = ecoff_add_string (output_debug, &fdr,
|
||||
bfd_get_filename (input_bfd));
|
||||
if (fdr.rss == -1)
|
||||
return false;
|
||||
fdr.isymBase = output_symhdr->isymMax;
|
||||
|
||||
/* Get the local symbols from the input BFD. */
|
||||
|
@ -529,6 +535,8 @@ bfd_ecoff_debug_link_other (output_bfd, output_debug, output_swap, input_bfd)
|
|||
internal_sym.iss = ecoff_add_string (output_debug, &fdr,
|
||||
(*sym_ptr)->name);
|
||||
|
||||
if (internal_sym.iss == -1)
|
||||
return false;
|
||||
if (bfd_is_com_section ((*sym_ptr)->section)
|
||||
|| (*sym_ptr)->section == &bfd_und_section)
|
||||
internal_sym.value = (*sym_ptr)->value;
|
||||
|
@ -596,9 +604,6 @@ bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
|
|||
boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
|
||||
void (*set_index) PARAMS ((asymbol *, bfd_size_type));
|
||||
{
|
||||
const bfd_size_type external_ext_size = swap->external_ext_size;
|
||||
void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
|
||||
= swap->swap_ext_out;
|
||||
HDRR * const symhdr = &debug->symbolic_header;
|
||||
asymbol **sym_ptr_ptr;
|
||||
size_t c;
|
||||
|
@ -628,26 +633,6 @@ bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
|
|||
esym.asym.sc = scSBss;
|
||||
}
|
||||
|
||||
if (debug->ssext_end - debug->ssext
|
||||
< symhdr->issExtMax + strlen (sym_ptr->name) + 1)
|
||||
{
|
||||
if (ecoff_add_bytes ((char **) &debug->ssext,
|
||||
(char **) &debug->ssext_end,
|
||||
symhdr->issExtMax + strlen (sym_ptr->name) + 1)
|
||||
== false)
|
||||
return false;
|
||||
}
|
||||
if ((char *) debug->external_ext_end - (char *) debug->external_ext
|
||||
< (symhdr->iextMax + 1) * external_ext_size)
|
||||
{
|
||||
if (ecoff_add_bytes ((char **) &debug->external_ext,
|
||||
(char **) &debug->external_ext_end,
|
||||
(symhdr->iextMax + 1) * external_ext_size)
|
||||
== false)
|
||||
return false;
|
||||
}
|
||||
|
||||
esym.asym.iss = symhdr->issExtMax;
|
||||
|
||||
if (bfd_is_com_section (sym_ptr->section)
|
||||
|| sym_ptr->section == &bfd_und_section)
|
||||
|
@ -657,24 +642,71 @@ bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
|
|||
+ sym_ptr->section->output_offset
|
||||
+ sym_ptr->section->output_section->vma);
|
||||
|
||||
(*swap_ext_out) (abfd, &esym,
|
||||
((char *) debug->external_ext
|
||||
+ symhdr->iextMax * swap->external_ext_size));
|
||||
|
||||
if (set_index)
|
||||
(*set_index) (sym_ptr, symhdr->iextMax);
|
||||
(*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
|
||||
|
||||
++symhdr->iextMax;
|
||||
|
||||
strcpy (debug->ssext + symhdr->issExtMax, sym_ptr->name);
|
||||
symhdr->issExtMax += strlen (sym_ptr->name) + 1;
|
||||
if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
|
||||
sym_ptr->name, &esym))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Add a single external symbol to the debugging information. */
|
||||
|
||||
boolean
|
||||
bfd_ecoff_debug_one_external (abfd, debug, swap, name, esym)
|
||||
bfd *abfd;
|
||||
struct ecoff_debug_info *debug;
|
||||
const struct ecoff_debug_swap *swap;
|
||||
const char *name;
|
||||
EXTR *esym;
|
||||
{
|
||||
const bfd_size_type external_ext_size = swap->external_ext_size;
|
||||
void (* const swap_ext_out) PARAMS ((bfd *, const EXTR *, PTR))
|
||||
= swap->swap_ext_out;
|
||||
HDRR * const symhdr = &debug->symbolic_header;
|
||||
size_t namelen;
|
||||
|
||||
namelen = strlen (name);
|
||||
|
||||
if (debug->ssext_end - debug->ssext
|
||||
< symhdr->issExtMax + namelen + 1)
|
||||
{
|
||||
if (ecoff_add_bytes ((char **) &debug->ssext,
|
||||
(char **) &debug->ssext_end,
|
||||
symhdr->issExtMax + namelen + 1)
|
||||
== false)
|
||||
return false;
|
||||
}
|
||||
if ((char *) debug->external_ext_end - (char *) debug->external_ext
|
||||
< (symhdr->iextMax + 1) * external_ext_size)
|
||||
{
|
||||
if (ecoff_add_bytes ((char **) &debug->external_ext,
|
||||
(char **) &debug->external_ext_end,
|
||||
(symhdr->iextMax + 1) * external_ext_size)
|
||||
== false)
|
||||
return false;
|
||||
}
|
||||
|
||||
esym->asym.iss = symhdr->issExtMax;
|
||||
|
||||
(*swap_ext_out) (abfd, esym,
|
||||
((char *) debug->external_ext
|
||||
+ symhdr->iextMax * swap->external_ext_size));
|
||||
|
||||
++symhdr->iextMax;
|
||||
|
||||
strcpy (debug->ssext + symhdr->issExtMax, name);
|
||||
symhdr->issExtMax += namelen + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Align the ECOFF debugging information. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
ecoff_align_debug (abfd, debug, swap)
|
||||
bfd *abfd;
|
||||
|
@ -682,7 +714,8 @@ ecoff_align_debug (abfd, debug, swap)
|
|||
const struct ecoff_debug_swap *swap;
|
||||
{
|
||||
HDRR * const symhdr = &debug->symbolic_header;
|
||||
bfd_size_type debug_align, aux_align, add;
|
||||
bfd_size_type debug_align, aux_align;
|
||||
size_t add;
|
||||
|
||||
/* Adjust the counts so that structures are aligned. The alignment
|
||||
of ALLOC_SIZE ensures that we do not have to worry about running
|
||||
|
@ -808,7 +841,7 @@ bfd_ecoff_write_debug (abfd, debug, swap, where)
|
|||
|
||||
#define WRITE(ptr, count, size, offset) \
|
||||
BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->offset); \
|
||||
if (bfd_write (debug->ptr, size, symhdr->count, abfd) \
|
||||
if (bfd_write ((PTR) debug->ptr, size, symhdr->count, abfd) \
|
||||
!= size * symhdr->count) \
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Reference in a new issue