* 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 *));
|
const char *));
|
||||||
|
|
||||||
/* Grab some space for a hash table entry. */
|
/* 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
|
/* Traverse a hash table in a random order, calling a function on each
|
||||||
element. If the function returns false, the traversal stops. The
|
element. If the function returns false, the traversal stops. The
|
||||||
|
@ -558,6 +559,10 @@ extern boolean bfd_ecoff_debug_externals
|
||||||
struct ecoff_extr *),
|
struct ecoff_extr *),
|
||||||
void (*set_index) (struct symbol_cache_entry *,
|
void (*set_index) (struct symbol_cache_entry *,
|
||||||
bfd_size_type)));
|
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
|
extern bfd_size_type bfd_ecoff_debug_size
|
||||||
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
||||||
const struct ecoff_debug_swap *swap));
|
const struct ecoff_debug_swap *swap));
|
||||||
|
|
|
@ -407,7 +407,8 @@ extern struct bfd_hash_entry *bfd_hash_newfunc
|
||||||
const char *));
|
const char *));
|
||||||
|
|
||||||
/* Grab some space for a hash table entry. */
|
/* 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
|
/* Traverse a hash table in a random order, calling a function on each
|
||||||
element. If the function returns false, the traversal stops. The
|
element. If the function returns false, the traversal stops. The
|
||||||
|
@ -558,6 +559,10 @@ extern boolean bfd_ecoff_debug_externals
|
||||||
struct ecoff_extr *),
|
struct ecoff_extr *),
|
||||||
void (*set_index) (struct symbol_cache_entry *,
|
void (*set_index) (struct symbol_cache_entry *,
|
||||||
bfd_size_type)));
|
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
|
extern bfd_size_type bfd_ecoff_debug_size
|
||||||
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
PARAMS ((bfd *abfd, struct ecoff_debug_info *debug,
|
||||||
const struct ecoff_debug_swap *swap));
|
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"
|
#include "coff/ecoff.h"
|
||||||
|
|
||||||
static boolean ecoff_add_bytes PARAMS ((char **buf, char **bufend,
|
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 *,
|
static bfd_size_type ecoff_add_string PARAMS ((struct ecoff_debug_info *,
|
||||||
FDR *fdr, const char *string));
|
FDR *fdr, const char *string));
|
||||||
static void ecoff_align_debug PARAMS ((bfd *abfd,
|
static void ecoff_align_debug PARAMS ((bfd *abfd,
|
||||||
|
@ -43,10 +43,10 @@ static boolean
|
||||||
ecoff_add_bytes (buf, bufend, need)
|
ecoff_add_bytes (buf, bufend, need)
|
||||||
char **buf;
|
char **buf;
|
||||||
char **bufend;
|
char **bufend;
|
||||||
bfd_size_type need;
|
size_t need;
|
||||||
{
|
{
|
||||||
bfd_size_type have;
|
size_t have;
|
||||||
bfd_size_type want;
|
size_t want;
|
||||||
char *newbuf;
|
char *newbuf;
|
||||||
|
|
||||||
have = *bufend - *buf;
|
have = *bufend - *buf;
|
||||||
|
@ -78,6 +78,7 @@ ecoff_add_bytes (buf, bufend, need)
|
||||||
pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and
|
pointed to by the OUTPUT_DEBUG argument. OUTPUT_SWAP and
|
||||||
INPUT_SWAP point to the swapping information needed. */
|
INPUT_SWAP point to the swapping information needed. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
boolean
|
boolean
|
||||||
bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
|
bfd_ecoff_debug_accumulate (output_bfd, output_debug, output_swap,
|
||||||
input_bfd, input_debug, input_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. */
|
/* Copy the information that does not need swapping. */
|
||||||
memcpy (output_debug->line + output_symhdr->cbLine,
|
memcpy (output_debug->line + output_symhdr->cbLine,
|
||||||
input_debug->line,
|
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,
|
memcpy (output_debug->external_aux + output_symhdr->iauxMax,
|
||||||
input_debug->external_aux,
|
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,
|
memcpy (output_debug->ss + output_symhdr->issMax,
|
||||||
input_debug->ss,
|
input_debug->ss,
|
||||||
input_symhdr->issMax * sizeof (char));
|
(size_t) (input_symhdr->issMax * sizeof (char)));
|
||||||
|
|
||||||
/* Some of the information may need to be swapped. */
|
/* Some of the information may need to be swapped. */
|
||||||
if (output_bfd->xvec->header_byteorder_big_p
|
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
|
memcpy (((char *) output_debug->external_dnr
|
||||||
+ output_symhdr->idnMax * output_swap->external_dnr_size),
|
+ output_symhdr->idnMax * output_swap->external_dnr_size),
|
||||||
input_debug->external_dnr,
|
input_debug->external_dnr,
|
||||||
input_symhdr->idnMax * output_swap->external_dnr_size);
|
((size_t)
|
||||||
|
(input_symhdr->idnMax * output_swap->external_dnr_size)));
|
||||||
#endif
|
#endif
|
||||||
BFD_ASSERT (output_swap->external_pdr_size
|
BFD_ASSERT (output_swap->external_pdr_size
|
||||||
== input_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
|
memcpy (((char *) output_debug->external_pdr
|
||||||
+ output_symhdr->ipdMax * output_swap->external_pdr_size),
|
+ output_symhdr->ipdMax * output_swap->external_pdr_size),
|
||||||
input_debug->external_pdr,
|
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
|
BFD_ASSERT (output_swap->external_opt_size
|
||||||
== input_swap->external_opt_size);
|
== input_swap->external_opt_size);
|
||||||
if (input_symhdr->ioptMax > 0)
|
if (input_symhdr->ioptMax > 0)
|
||||||
memcpy (((char *) output_debug->external_opt
|
memcpy (((char *) output_debug->external_opt
|
||||||
+ output_symhdr->ioptMax * output_swap->external_opt_size),
|
+ output_symhdr->ioptMax * output_swap->external_opt_size),
|
||||||
input_debug->external_opt,
|
input_debug->external_opt,
|
||||||
input_symhdr->ioptMax * output_swap->external_opt_size);
|
((size_t)
|
||||||
|
(input_symhdr->ioptMax * output_swap->external_opt_size)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -462,7 +466,7 @@ ecoff_add_string (output, fdr, string)
|
||||||
{
|
{
|
||||||
if (ecoff_add_bytes (&output->ss, &output->ss_end,
|
if (ecoff_add_bytes (&output->ss, &output->ss_end,
|
||||||
symhdr->issMax + len + 1) == false)
|
symhdr->issMax + len + 1) == false)
|
||||||
return -1;
|
return (bfd_size_type) -1;
|
||||||
}
|
}
|
||||||
memcpy (output->ss + symhdr->issMax, string, len + 1);
|
memcpy (output->ss + symhdr->issMax, string, len + 1);
|
||||||
ret = fdr->cbSs;
|
ret = fdr->cbSs;
|
||||||
|
@ -504,6 +508,8 @@ bfd_ecoff_debug_link_other (output_bfd, output_debug, output_swap, input_bfd)
|
||||||
fdr.cbSs = 0;
|
fdr.cbSs = 0;
|
||||||
fdr.rss = ecoff_add_string (output_debug, &fdr,
|
fdr.rss = ecoff_add_string (output_debug, &fdr,
|
||||||
bfd_get_filename (input_bfd));
|
bfd_get_filename (input_bfd));
|
||||||
|
if (fdr.rss == -1)
|
||||||
|
return false;
|
||||||
fdr.isymBase = output_symhdr->isymMax;
|
fdr.isymBase = output_symhdr->isymMax;
|
||||||
|
|
||||||
/* Get the local symbols from the input BFD. */
|
/* 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,
|
internal_sym.iss = ecoff_add_string (output_debug, &fdr,
|
||||||
(*sym_ptr)->name);
|
(*sym_ptr)->name);
|
||||||
|
|
||||||
|
if (internal_sym.iss == -1)
|
||||||
|
return false;
|
||||||
if (bfd_is_com_section ((*sym_ptr)->section)
|
if (bfd_is_com_section ((*sym_ptr)->section)
|
||||||
|| (*sym_ptr)->section == &bfd_und_section)
|
|| (*sym_ptr)->section == &bfd_und_section)
|
||||||
internal_sym.value = (*sym_ptr)->value;
|
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 *));
|
boolean (*get_extr) PARAMS ((asymbol *, EXTR *));
|
||||||
void (*set_index) PARAMS ((asymbol *, bfd_size_type));
|
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;
|
HDRR * const symhdr = &debug->symbolic_header;
|
||||||
asymbol **sym_ptr_ptr;
|
asymbol **sym_ptr_ptr;
|
||||||
size_t c;
|
size_t c;
|
||||||
|
@ -628,26 +633,6 @@ bfd_ecoff_debug_externals (abfd, debug, swap, relocateable, get_extr,
|
||||||
esym.asym.sc = scSBss;
|
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)
|
if (bfd_is_com_section (sym_ptr->section)
|
||||||
|| sym_ptr->section == &bfd_und_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_offset
|
||||||
+ sym_ptr->section->output_section->vma);
|
+ sym_ptr->section->output_section->vma);
|
||||||
|
|
||||||
(*swap_ext_out) (abfd, &esym,
|
|
||||||
((char *) debug->external_ext
|
|
||||||
+ symhdr->iextMax * swap->external_ext_size));
|
|
||||||
|
|
||||||
if (set_index)
|
if (set_index)
|
||||||
(*set_index) (sym_ptr, symhdr->iextMax);
|
(*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);
|
||||||
|
|
||||||
++symhdr->iextMax;
|
if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
|
||||||
|
sym_ptr->name, &esym))
|
||||||
strcpy (debug->ssext + symhdr->issExtMax, sym_ptr->name);
|
return false;
|
||||||
symhdr->issExtMax += strlen (sym_ptr->name) + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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. */
|
/* Align the ECOFF debugging information. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
static void
|
static void
|
||||||
ecoff_align_debug (abfd, debug, swap)
|
ecoff_align_debug (abfd, debug, swap)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
|
@ -682,7 +714,8 @@ ecoff_align_debug (abfd, debug, swap)
|
||||||
const struct ecoff_debug_swap *swap;
|
const struct ecoff_debug_swap *swap;
|
||||||
{
|
{
|
||||||
HDRR * const symhdr = &debug->symbolic_header;
|
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
|
/* Adjust the counts so that structures are aligned. The alignment
|
||||||
of ALLOC_SIZE ensures that we do not have to worry about running
|
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) \
|
#define WRITE(ptr, count, size, offset) \
|
||||||
BFD_ASSERT (symhdr->offset == 0 || bfd_tell (abfd) == symhdr->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) \
|
!= size * symhdr->count) \
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue