Tue Jan 9 15:22:53 1996 David Mosberger-Tang <davidm@azstarnet.com>
* coff-alpha.c (alpha_relocate_section): During final link, allow output .lita section to be bigger than 64k by adjusting gp value on a per-input section basis. * libecoff.h (struct ecoff_tdata): Add issued_multiple_gp_warning field. (struct ecoff_section_tdata): Add gp field. Tue Jan 9 12:00:36 1996 Ian Lance Taylor <ian@cygnus.com> Handle Alpha ECOFF changes in OSF/1 3.2. * libecoff.h (struct ecoff_backend_data): Add get_elt_at_filepos field. * coff-alpha.c: Include "aout/ar.h". (alpha_ecoff_get_relocated_section_contents): Don't require an ALPHA_R_IGNORE reloc after an ALPHA_R_GPDISP reloc, since OSF/1 3.2 doesn't generate one. (alpha_relocate_section): Likewise. (alpha_ecoff_slurp_armap): Define. (alpha_ecoff_slurp_extended_name_table): Define. (alpha_ecoff_construct_extended_name_table): Define. (alpha_ecoff_truncate_arname): Define. (alpha_ecoff_write_armap): Define. (alpha_ecoff_generic_stat_arch_elt): Define. (alpha_ecoff_update_armap_timestamp): Define. (ARFZMAG): Define. (alpha_ecoff_read_ar_hdr): New static function. (alpha_ecoff_get_elt_at_filepos): New static function. (alpha_ecoff_openr_next_archived_file): New static function. (alpha_ecoff_get_elt_at_index): New static function. (alpha_ecoff_backend_data): Initialize get_elt_at_filepos field. (ecoffalpha_little_vec): Change BFD_JUMP_TABLE_ARCHIVE from _bfd_ecoff to alpha_ecoff. * ecoff.c (ecoff_link_add_archive_symbols): Use get_elt_at_filepos field from backend structure, rather than always calling _bfd_get_elt_at_filepos. * coff-mips.c (mips_ecoff_backend_data): Initialize get_elt_at_filepos field. * archive.c (_bfd_generic_read_ar_hdr_mag): New function, copied from _bfd_generic_read_ar_hdr with minor changes. (_bfd_generic_read_ar_hdr): Use _bfd_generic_read_ar_hdr_mag. * libbfd-in.h (_bfd_generic_read_ar_hdr_mag): Declare. * libbfd.h: Rebuild. * bfd-in.h (BFD_IN_MEMORY): Define. * libbfd-in.h (struct bfd_in_memory): Define. * libbfd.c (bfd_read): Handle BFD_IN_MEMORY flag. (bfd_get_file_window): Don't try to map a BFD_IN_MEMORY file. (bfd_write, bfd_stat): Abort if BFD_IN_MEMORY is set. (bfd_tell, bfd_flush, bfd_seek): Handle BFD_IN_MEMORY flag. * bfd.c (struct _bfd): Change iostream field from char * to PTR. (bfd_get_size): Handle BFD_IN_MEMORY flag. * cache.c (bfd_cache_close): Ignore BFD_IN_MEMORY files. (bfd_open_file): Cast to PTR, not char *, when setting iostream. (bfd_cache_lookup_worker): Abort if BFD_IN_MEMORY is set. * opncls.c (bfd_fdopenr): Cast to PTR, not char *, when setting iostream. (bfd_openstreamr): Likewise. * aoutx.h (NAME(aout,some_aout_object_p)): Only fstat iostream if BFD_IN_MEMORY is not set. * riscix.c (riscix_some_aout_object_p): Likewise. * bfd-in2.h, libbfd.h: Rebuild. * targets.c (bfd_target): Add _bfd_get_elt_at_index field. (BFD_JUMP_TABLE_ARCHIVE): Add _get_elt_at_index. (bfd_get_elt_at_index): Define. * archive.c (_bfd_generic_get_elt_at_index): Rename from bfd_get_elt_at_index. Change index parameter from int to symindex. * libbfd-in.h (_bfd_generic_get_elt_at_index): Declare. (_bfd_noarchive_get_elt_at_index): Define. (_bfd_archive_bsd_get_elt_at_index): Define. (_bfd_archive_coff_get_elt_at_index): Define. * bfd-in2.h, libbfd.h: Rebuild. * aout-target.h (MY_get_elt_at_index): Define if not defined. * coff-rs6000.c (xcoff_get_elt_at_index): Define. * ieee.c (ieee_get_elt_at_index): Define. * libecoff.h (_bfd_ecoff_get_elt_at_index): Define. * oasys.c (oasys_get_elt_at_index): Define. * som.c (som_get_elt_at_index): Define.
This commit is contained in:
parent
c40d9c773f
commit
64d5f5d061
@ -1,5 +1,85 @@
|
||||
Tue Jan 9 15:22:53 1996 David Mosberger-Tang <davidm@azstarnet.com>
|
||||
|
||||
* coff-alpha.c (alpha_relocate_section): During final link, allow
|
||||
output .lita section to be bigger than 64k by adjusting gp value
|
||||
on a per-input section basis.
|
||||
* libecoff.h (struct ecoff_tdata): Add issued_multiple_gp_warning
|
||||
field.
|
||||
(struct ecoff_section_tdata): Add gp field.
|
||||
|
||||
Tue Jan 9 12:00:36 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
Handle Alpha ECOFF changes in OSF/1 3.2.
|
||||
* libecoff.h (struct ecoff_backend_data): Add get_elt_at_filepos
|
||||
field.
|
||||
* coff-alpha.c: Include "aout/ar.h".
|
||||
(alpha_ecoff_get_relocated_section_contents): Don't require an
|
||||
ALPHA_R_IGNORE reloc after an ALPHA_R_GPDISP reloc, since OSF/1
|
||||
3.2 doesn't generate one.
|
||||
(alpha_relocate_section): Likewise.
|
||||
(alpha_ecoff_slurp_armap): Define.
|
||||
(alpha_ecoff_slurp_extended_name_table): Define.
|
||||
(alpha_ecoff_construct_extended_name_table): Define.
|
||||
(alpha_ecoff_truncate_arname): Define.
|
||||
(alpha_ecoff_write_armap): Define.
|
||||
(alpha_ecoff_generic_stat_arch_elt): Define.
|
||||
(alpha_ecoff_update_armap_timestamp): Define.
|
||||
(ARFZMAG): Define.
|
||||
(alpha_ecoff_read_ar_hdr): New static function.
|
||||
(alpha_ecoff_get_elt_at_filepos): New static function.
|
||||
(alpha_ecoff_openr_next_archived_file): New static function.
|
||||
(alpha_ecoff_get_elt_at_index): New static function.
|
||||
(alpha_ecoff_backend_data): Initialize get_elt_at_filepos field.
|
||||
(ecoffalpha_little_vec): Change BFD_JUMP_TABLE_ARCHIVE from
|
||||
_bfd_ecoff to alpha_ecoff.
|
||||
* ecoff.c (ecoff_link_add_archive_symbols): Use get_elt_at_filepos
|
||||
field from backend structure, rather than always calling
|
||||
_bfd_get_elt_at_filepos.
|
||||
* coff-mips.c (mips_ecoff_backend_data): Initialize
|
||||
get_elt_at_filepos field.
|
||||
* archive.c (_bfd_generic_read_ar_hdr_mag): New function, copied
|
||||
from _bfd_generic_read_ar_hdr with minor changes.
|
||||
(_bfd_generic_read_ar_hdr): Use _bfd_generic_read_ar_hdr_mag.
|
||||
* libbfd-in.h (_bfd_generic_read_ar_hdr_mag): Declare.
|
||||
* libbfd.h: Rebuild.
|
||||
|
||||
* bfd-in.h (BFD_IN_MEMORY): Define.
|
||||
* libbfd-in.h (struct bfd_in_memory): Define.
|
||||
* libbfd.c (bfd_read): Handle BFD_IN_MEMORY flag.
|
||||
(bfd_get_file_window): Don't try to map a BFD_IN_MEMORY file.
|
||||
(bfd_write, bfd_stat): Abort if BFD_IN_MEMORY is set.
|
||||
(bfd_tell, bfd_flush, bfd_seek): Handle BFD_IN_MEMORY flag.
|
||||
* bfd.c (struct _bfd): Change iostream field from char * to PTR.
|
||||
(bfd_get_size): Handle BFD_IN_MEMORY flag.
|
||||
* cache.c (bfd_cache_close): Ignore BFD_IN_MEMORY files.
|
||||
(bfd_open_file): Cast to PTR, not char *, when setting iostream.
|
||||
(bfd_cache_lookup_worker): Abort if BFD_IN_MEMORY is set.
|
||||
* opncls.c (bfd_fdopenr): Cast to PTR, not char *, when setting
|
||||
iostream.
|
||||
(bfd_openstreamr): Likewise.
|
||||
* aoutx.h (NAME(aout,some_aout_object_p)): Only fstat iostream if
|
||||
BFD_IN_MEMORY is not set.
|
||||
* riscix.c (riscix_some_aout_object_p): Likewise.
|
||||
* bfd-in2.h, libbfd.h: Rebuild.
|
||||
|
||||
* targets.c (bfd_target): Add _bfd_get_elt_at_index field.
|
||||
(BFD_JUMP_TABLE_ARCHIVE): Add _get_elt_at_index.
|
||||
(bfd_get_elt_at_index): Define.
|
||||
* archive.c (_bfd_generic_get_elt_at_index): Rename from
|
||||
bfd_get_elt_at_index. Change index parameter from int to
|
||||
symindex.
|
||||
* libbfd-in.h (_bfd_generic_get_elt_at_index): Declare.
|
||||
(_bfd_noarchive_get_elt_at_index): Define.
|
||||
(_bfd_archive_bsd_get_elt_at_index): Define.
|
||||
(_bfd_archive_coff_get_elt_at_index): Define.
|
||||
* bfd-in2.h, libbfd.h: Rebuild.
|
||||
* aout-target.h (MY_get_elt_at_index): Define if not defined.
|
||||
* coff-rs6000.c (xcoff_get_elt_at_index): Define.
|
||||
* ieee.c (ieee_get_elt_at_index): Define.
|
||||
* libecoff.h (_bfd_ecoff_get_elt_at_index): Define.
|
||||
* oasys.c (oasys_get_elt_at_index): Define.
|
||||
* som.c (som_get_elt_at_index): Define.
|
||||
|
||||
* ecoff.c (_bfd_ecoff_find_nearest_line): Don't restrict line
|
||||
numbers to the .text section.
|
||||
|
||||
|
@ -43,6 +43,10 @@ MY(callback) (abfd)
|
||||
obj_datasec (abfd)->vma = N_DATADDR(*execp);
|
||||
obj_bsssec (abfd)->vma = N_BSSADDR(*execp);
|
||||
|
||||
obj_textsec (abfd)->lma = obj_textsec (abfd)->vma;
|
||||
obj_datasec (abfd)->lma = obj_datasec (abfd)->vma;
|
||||
obj_bsssec (abfd)->lma = obj_bsssec (abfd)->vma;
|
||||
|
||||
/* The file offsets of the sections */
|
||||
obj_textsec (abfd)->filepos = N_TXTOFF (*execp);
|
||||
obj_datasec (abfd)->filepos = N_DATOFF (*execp);
|
||||
@ -349,6 +353,9 @@ MY_bfd_final_link (abfd, info)
|
||||
#ifndef MY_openr_next_archived_file
|
||||
#define MY_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#endif
|
||||
#ifndef MY_get_elt_at_index
|
||||
#define MY_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#endif
|
||||
#ifndef MY_generic_stat_arch_elt
|
||||
#define MY_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#endif
|
||||
@ -416,6 +423,9 @@ MY_bfd_final_link (abfd, info)
|
||||
#ifndef MY_get_section_contents
|
||||
#define MY_get_section_contents NAME(aout,get_section_contents)
|
||||
#endif
|
||||
#ifndef MY_get_section_contents_in_window
|
||||
#define MY_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
|
||||
#endif
|
||||
#ifndef MY_new_section_hook
|
||||
#define MY_new_section_hook NAME(aout,new_section_hook)
|
||||
#endif
|
||||
@ -547,11 +557,11 @@ const bfd_target MY(vec) =
|
||||
TARGETNAME, /* name */
|
||||
bfd_target_aout_flavour,
|
||||
#ifdef TARGET_IS_BIG_ENDIAN_P
|
||||
true, /* target byte order (big) */
|
||||
true, /* target headers byte order (big) */
|
||||
BFD_ENDIAN_BIG, /* target byte order (big) */
|
||||
BFD_ENDIAN_BIG, /* target headers byte order (big) */
|
||||
#else
|
||||
false, /* target byte order (little) */
|
||||
false, /* target headers byte order (little) */
|
||||
BFD_ENDIAN_LITTLE, /* target byte order (little) */
|
||||
BFD_ENDIAN_LITTLE, /* target headers byte order (little) */
|
||||
#endif
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
|
36
bfd/aoutx.h
36
bfd/aoutx.h
@ -598,7 +598,8 @@ NAME(aout,some_aout_object_p) (abfd, execp, callback_to_real_object_p)
|
||||
the default text start (obj_textsec(abfd)->vma) and
|
||||
(obj_textsec(abfd)->vma) + text size. This is not just a mach
|
||||
issue. Many kernels are loaded at non standard addresses. */
|
||||
if (abfd->iostream
|
||||
if (abfd->iostream != NULL
|
||||
&& (abfd->flags & BFD_IN_MEMORY) == 0
|
||||
&& (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
|
||||
&& ((stat_buf.st_mode & 0111) != 0))
|
||||
abfd->flags |= EXEC_P;
|
||||
@ -1986,7 +1987,7 @@ NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
|
||||
}
|
||||
|
||||
/* now the fun stuff */
|
||||
if (abfd->xvec->header_byteorder_big_p != false) {
|
||||
if (bfd_header_big_endian (abfd)) {
|
||||
natptr->r_index[0] = r_index >> 16;
|
||||
natptr->r_index[1] = r_index >> 8;
|
||||
natptr->r_index[2] = r_index;
|
||||
@ -2065,7 +2066,7 @@ NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
|
||||
}
|
||||
|
||||
/* now the fun stuff */
|
||||
if (abfd->xvec->header_byteorder_big_p != false) {
|
||||
if (bfd_header_big_endian (abfd)) {
|
||||
natptr->r_index[0] = r_index >> 16;
|
||||
natptr->r_index[1] = r_index >> 8;
|
||||
natptr->r_index[2] = r_index;
|
||||
@ -2142,7 +2143,7 @@ NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
|
||||
cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
|
||||
|
||||
/* now the fun stuff */
|
||||
if (abfd->xvec->header_byteorder_big_p != false) {
|
||||
if (bfd_header_big_endian (abfd)) {
|
||||
r_index = (bytes->r_index[0] << 16)
|
||||
| (bytes->r_index[1] << 8)
|
||||
| bytes->r_index[2];
|
||||
@ -2198,7 +2199,7 @@ NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
|
||||
cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
|
||||
|
||||
/* now the fun stuff */
|
||||
if (abfd->xvec->header_byteorder_big_p != false) {
|
||||
if (bfd_header_big_endian (abfd)) {
|
||||
r_index = (bytes->r_index[0] << 16)
|
||||
| (bytes->r_index[1] << 8)
|
||||
| bytes->r_index[2];
|
||||
@ -2495,6 +2496,7 @@ NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
|
||||
stab_name = buf;
|
||||
}
|
||||
ret->type = '-';
|
||||
ret->stab_type = type_code;
|
||||
ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
|
||||
ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
|
||||
ret->stab_name = stab_name;
|
||||
@ -4598,8 +4600,8 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
|
||||
|
||||
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
|
||||
== output_bfd->xvec->header_byteorder_big_p);
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder
|
||||
== output_bfd->xvec->header_byteorder);
|
||||
|
||||
relocateable = finfo->info->relocateable;
|
||||
syms = obj_aout_external_syms (input_bfd);
|
||||
@ -4633,7 +4635,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||
int r_length;
|
||||
unsigned int howto_idx;
|
||||
|
||||
if (input_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (input_bfd))
|
||||
{
|
||||
r_index = ((rel->r_index[0] << 16)
|
||||
| (rel->r_index[1] << 8)
|
||||
@ -4687,7 +4689,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||
asection *output_section;
|
||||
|
||||
/* Change the r_extern value. */
|
||||
if (output_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (output_bfd))
|
||||
rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
|
||||
else
|
||||
rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
|
||||
@ -4752,7 +4754,7 @@ aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
|
||||
}
|
||||
|
||||
/* Write out the new r_index value. */
|
||||
if (output_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (output_bfd))
|
||||
{
|
||||
rel->r_index[0] = r_index >> 16;
|
||||
rel->r_index[1] = r_index >> 8;
|
||||
@ -4937,8 +4939,8 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||
check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
|
||||
|
||||
BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
|
||||
== output_bfd->xvec->header_byteorder_big_p);
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder
|
||||
== output_bfd->xvec->header_byteorder);
|
||||
|
||||
relocateable = finfo->info->relocateable;
|
||||
syms = obj_aout_external_syms (input_bfd);
|
||||
@ -4962,7 +4964,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||
|
||||
r_addr = GET_SWORD (input_bfd, rel->r_address);
|
||||
|
||||
if (input_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (input_bfd))
|
||||
{
|
||||
r_index = ((rel->r_index[0] << 16)
|
||||
| (rel->r_index[1] << 8)
|
||||
@ -5002,7 +5004,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||
asection *output_section;
|
||||
|
||||
/* Change the r_extern value. */
|
||||
if (output_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (output_bfd))
|
||||
rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
|
||||
else
|
||||
rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
|
||||
@ -5080,7 +5082,7 @@ aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
|
||||
}
|
||||
|
||||
/* Write out the new r_index value. */
|
||||
if (output_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (output_bfd))
|
||||
{
|
||||
rel->r_index[0] = r_index >> 16;
|
||||
rel->r_index[1] = r_index >> 8;
|
||||
@ -5389,7 +5391,7 @@ aout_link_reloc_link_order (finfo, o, p)
|
||||
r_length = howto->size;
|
||||
|
||||
PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
|
||||
if (finfo->output_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (finfo->output_bfd))
|
||||
{
|
||||
srel.r_index[0] = r_index >> 16;
|
||||
srel.r_index[1] = r_index >> 8;
|
||||
@ -5472,7 +5474,7 @@ aout_link_reloc_link_order (finfo, o, p)
|
||||
{
|
||||
PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
|
||||
|
||||
if (finfo->output_bfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (finfo->output_bfd))
|
||||
{
|
||||
erel.r_index[0] = r_index >> 16;
|
||||
erel.r_index[1] = r_index >> 8;
|
||||
|
@ -355,10 +355,17 @@ PTR
|
||||
_bfd_generic_read_ar_hdr (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
return _bfd_generic_read_ar_hdr_mag (abfd, (const char *) NULL);
|
||||
}
|
||||
|
||||
/* Alpha ECOFF uses an optional different ARFMAG value, so we have a
|
||||
variant of _bfd_generic_read_ar_hdr which accepts a magic string. */
|
||||
|
||||
PTR
|
||||
_bfd_generic_read_ar_hdr_mag (abfd, mag)
|
||||
bfd *abfd;
|
||||
const char *mag;
|
||||
{
|
||||
struct ar_hdr hdr;
|
||||
char *hdrp = (char *) &hdr;
|
||||
unsigned int parsed_size;
|
||||
@ -375,7 +382,9 @@ _bfd_generic_read_ar_hdr (abfd)
|
||||
bfd_set_error (bfd_error_no_more_archived_files);
|
||||
return NULL;
|
||||
}
|
||||
if (strncmp (hdr.ar_fmag, ARFMAG, 2))
|
||||
if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
|
||||
&& (mag == NULL
|
||||
|| strncmp (hdr.ar_fmag, mag, 2) != 0))
|
||||
{
|
||||
bfd_set_error (bfd_error_malformed_archive);
|
||||
return NULL;
|
||||
@ -521,23 +530,13 @@ _bfd_get_elt_at_filepos (archive, filepos)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_get_elt_at_index
|
||||
/* Return the BFD which is referenced by the symbol in ABFD indexed by
|
||||
INDEX. INDEX should have been returned by bfd_get_next_mapent. */
|
||||
|
||||
SYNOPSIS
|
||||
bfd *bfd_get_elt_at_index(bfd *archive, int index);
|
||||
|
||||
DESCRIPTION
|
||||
Return the BFD which is referenced by the symbol in @var{archive}
|
||||
indexed by @var{index}. @var{index} should have been returned by
|
||||
<<bfd_get_next_mapent>> (q.v.).
|
||||
|
||||
*/
|
||||
bfd *
|
||||
bfd_get_elt_at_index (abfd, index)
|
||||
_bfd_generic_get_elt_at_index (abfd, index)
|
||||
bfd *abfd;
|
||||
int index;
|
||||
symindex index;
|
||||
{
|
||||
carsym *entry;
|
||||
|
||||
@ -1724,9 +1723,9 @@ _bfd_compute_and_write_armap (arch, elength)
|
||||
elength += sizeof (struct ar_hdr);
|
||||
elength += elength % 2;
|
||||
|
||||
map = (struct orl *) malloc (orl_max * sizeof (struct orl));
|
||||
map = (struct orl *) bfd_malloc (orl_max * sizeof (struct orl));
|
||||
if (map == NULL)
|
||||
goto no_memory_return;
|
||||
goto error_return;
|
||||
|
||||
/* We put the symbol names on the arch obstack, and then discard
|
||||
them when done. */
|
||||
@ -1763,9 +1762,9 @@ _bfd_compute_and_write_armap (arch, elength)
|
||||
if (syms_max > 0)
|
||||
free (syms);
|
||||
syms_max = storage;
|
||||
syms = (asymbol **) malloc ((size_t) syms_max);
|
||||
syms = (asymbol **) bfd_malloc ((size_t) syms_max);
|
||||
if (syms == NULL)
|
||||
goto no_memory_return;
|
||||
goto error_return;
|
||||
}
|
||||
symcount = bfd_canonicalize_symtab (current, syms);
|
||||
if (symcount < 0)
|
||||
@ -1790,11 +1789,11 @@ _bfd_compute_and_write_armap (arch, elength)
|
||||
if (orl_count == orl_max)
|
||||
{
|
||||
orl_max *= 2;
|
||||
new_map = ((struct orl *)
|
||||
realloc ((PTR) map,
|
||||
orl_max * sizeof (struct orl)));
|
||||
new_map =
|
||||
((struct orl *)
|
||||
bfd_realloc (map, orl_max * sizeof (struct orl)));
|
||||
if (new_map == (struct orl *) NULL)
|
||||
goto no_memory_return;
|
||||
goto error_return;
|
||||
|
||||
map = new_map;
|
||||
}
|
||||
@ -1838,9 +1837,6 @@ _bfd_compute_and_write_armap (arch, elength)
|
||||
|
||||
return ret;
|
||||
|
||||
no_memory_return:
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
|
||||
error_return:
|
||||
if (syms_max > 0)
|
||||
free (syms);
|
||||
|
17
bfd/bfd-in.h
17
bfd/bfd-in.h
@ -235,6 +235,10 @@ typedef enum bfd_format {
|
||||
writing out an a.out object the symbols not be hashed to eliminate
|
||||
duplicates. */
|
||||
#define BFD_TRADITIONAL_FORMAT 0x400
|
||||
|
||||
/* This flag indicates that the BFD contents are actually cached in
|
||||
memory. If this is set, iostream points to a bfd_in_memory struct. */
|
||||
#define BFD_IN_MEMORY 0x800
|
||||
|
||||
/* symbols and relocation */
|
||||
|
||||
@ -324,9 +328,10 @@ typedef struct _symbol_info
|
||||
symvalue value;
|
||||
char type;
|
||||
CONST char *name; /* Symbol name. */
|
||||
char stab_other; /* Unused. */
|
||||
short stab_desc; /* Info for N_TYPE. */
|
||||
CONST char *stab_name;
|
||||
unsigned char stab_type; /* Stab type. */
|
||||
char stab_other; /* Stab other. */
|
||||
short stab_desc; /* Stab desc. */
|
||||
CONST char *stab_name; /* String for stab type. */
|
||||
} symbol_info;
|
||||
|
||||
/* Hash table routines. There is no way to free up a hash table. */
|
||||
@ -464,6 +469,12 @@ extern int bfd_stat PARAMS ((bfd *abfd, struct stat *));
|
||||
#define bfd_get_format(abfd) ((abfd)->format)
|
||||
#define bfd_get_target(abfd) ((abfd)->xvec->name)
|
||||
#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
|
||||
#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
|
||||
#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE)
|
||||
#define bfd_header_big_endian(abfd) \
|
||||
((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG)
|
||||
#define bfd_header_little_endian(abfd) \
|
||||
((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
|
||||
#define bfd_get_file_flags(abfd) ((abfd)->flags)
|
||||
#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
|
||||
#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
|
||||
|
@ -235,6 +235,10 @@ typedef enum bfd_format {
|
||||
writing out an a.out object the symbols not be hashed to eliminate
|
||||
duplicates. */
|
||||
#define BFD_TRADITIONAL_FORMAT 0x400
|
||||
|
||||
/* This flag indicates that the BFD contents are actually cached in
|
||||
memory. If this is set, iostream points to a bfd_in_memory struct. */
|
||||
#define BFD_IN_MEMORY 0x800
|
||||
|
||||
/* symbols and relocation */
|
||||
|
||||
@ -324,9 +328,10 @@ typedef struct _symbol_info
|
||||
symvalue value;
|
||||
char type;
|
||||
CONST char *name; /* Symbol name. */
|
||||
char stab_other; /* Unused. */
|
||||
short stab_desc; /* Info for N_TYPE. */
|
||||
CONST char *stab_name;
|
||||
unsigned char stab_type; /* Stab type. */
|
||||
char stab_other; /* Stab other. */
|
||||
short stab_desc; /* Stab desc. */
|
||||
CONST char *stab_name; /* String for stab type. */
|
||||
} symbol_info;
|
||||
|
||||
/* Hash table routines. There is no way to free up a hash table. */
|
||||
@ -464,6 +469,12 @@ extern int bfd_stat PARAMS ((bfd *abfd, struct stat *));
|
||||
#define bfd_get_format(abfd) ((abfd)->format)
|
||||
#define bfd_get_target(abfd) ((abfd)->xvec->name)
|
||||
#define bfd_get_flavour(abfd) ((abfd)->xvec->flavour)
|
||||
#define bfd_big_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_BIG)
|
||||
#define bfd_little_endian(abfd) ((abfd)->xvec->byteorder == BFD_ENDIAN_LITTLE)
|
||||
#define bfd_header_big_endian(abfd) \
|
||||
((abfd)->xvec->header_byteorder == BFD_ENDIAN_BIG)
|
||||
#define bfd_header_little_endian(abfd) \
|
||||
((abfd)->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
|
||||
#define bfd_get_file_flags(abfd) ((abfd)->flags)
|
||||
#define bfd_applicable_file_flags(abfd) ((abfd)->xvec->object_flags)
|
||||
#define bfd_applicable_section_flags(abfd) ((abfd)->xvec->section_flags)
|
||||
@ -1814,8 +1825,10 @@ struct _bfd
|
||||
includes `<<bfd.h>>', IOSTREAM has been declared as a "char
|
||||
*", and MTIME as a "long". Their correct types, to which they
|
||||
are cast when used, are "FILE *" and "time_t". The iostream
|
||||
is the result of an fopen on the filename. */
|
||||
char *iostream;
|
||||
is the result of an fopen on the filename. However, if the
|
||||
BFD_IN_MEMORY flag is set, then iostream is actually a pointer
|
||||
to a bfd_in_memory struct. */
|
||||
PTR iostream;
|
||||
|
||||
/* Is the file descriptor being cached? That is, can it be closed as
|
||||
needed, and re-opened when accessed later? */
|
||||
@ -2118,9 +2131,6 @@ bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));
|
||||
boolean
|
||||
bfd_set_archive_head PARAMS ((bfd *output, bfd *new_head));
|
||||
|
||||
bfd *
|
||||
bfd_get_elt_at_index PARAMS ((bfd *archive, int index));
|
||||
|
||||
bfd *
|
||||
bfd_openr_next_archived_file PARAMS ((bfd *archive, bfd *previous));
|
||||
|
||||
@ -2172,6 +2182,8 @@ enum bfd_flavour {
|
||||
bfd_target_msdos_flavour
|
||||
};
|
||||
|
||||
enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN };
|
||||
|
||||
/* Forward declaration. */
|
||||
typedef struct bfd_link_info _bfd_link_info;
|
||||
|
||||
@ -2179,8 +2191,8 @@ typedef struct bfd_target
|
||||
{
|
||||
char *name;
|
||||
enum bfd_flavour flavour;
|
||||
boolean byteorder_big_p;
|
||||
boolean header_byteorder_big_p;
|
||||
enum bfd_endian byteorder;
|
||||
enum bfd_endian header_byteorder;
|
||||
flagword object_flags;
|
||||
flagword section_flags;
|
||||
char symbol_leading_char;
|
||||
@ -2275,6 +2287,7 @@ CAT(NAME,_truncate_arname),\
|
||||
CAT(NAME,_write_armap),\
|
||||
CAT(NAME,_read_ar_hdr),\
|
||||
CAT(NAME,_openr_next_archived_file),\
|
||||
CAT(NAME,_get_elt_at_index),\
|
||||
CAT(NAME,_generic_stat_arch_elt),\
|
||||
CAT(NAME,_update_armap_timestamp)
|
||||
boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
|
||||
@ -2289,6 +2302,8 @@ CAT(NAME,_update_armap_timestamp)
|
||||
int stridx));
|
||||
PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *));
|
||||
bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
|
||||
#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i))
|
||||
bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex));
|
||||
int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
|
||||
boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *));
|
||||
|
||||
|
10
bfd/bfd.c
10
bfd/bfd.c
@ -44,8 +44,10 @@ CODE_FRAGMENT
|
||||
. includes `<<bfd.h>>', IOSTREAM has been declared as a "char
|
||||
. *", and MTIME as a "long". Their correct types, to which they
|
||||
. are cast when used, are "FILE *" and "time_t". The iostream
|
||||
. is the result of an fopen on the filename. *}
|
||||
. char *iostream;
|
||||
. is the result of an fopen on the filename. However, if the
|
||||
. BFD_IN_MEMORY flag is set, then iostream is actually a pointer
|
||||
. to a bfd_in_memory struct. *}
|
||||
. PTR iostream;
|
||||
.
|
||||
. {* Is the file descriptor being cached? That is, can it be closed as
|
||||
. needed, and re-opened when accessed later? *}
|
||||
@ -158,6 +160,7 @@ CODE_FRAGMENT
|
||||
. struct ieee_data_struct *ieee_data;
|
||||
. struct ieee_ar_data_struct *ieee_ar_data;
|
||||
. struct srec_data_struct *srec_data;
|
||||
. struct ihex_data_struct *ihex_data;
|
||||
. struct tekhex_data_struct *tekhex_data;
|
||||
. struct elf_obj_tdata *elf_obj_data;
|
||||
. struct nlm_obj_tdata *nlm_obj_data;
|
||||
@ -747,6 +750,9 @@ bfd_get_size (abfd)
|
||||
FILE *fp;
|
||||
struct stat buf;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return ((struct bfd_in_memory *) abfd->iostream)->size;
|
||||
|
||||
fp = bfd_cache_lookup (abfd);
|
||||
if (0 != fstat (fileno (fp), &buf))
|
||||
return 0;
|
||||
|
300
bfd/cache.c
300
bfd/cache.c
@ -1,5 +1,5 @@
|
||||
/* BFD library -- caching of file descriptors.
|
||||
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
|
||||
Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
|
||||
|
||||
This file is part of BFD, the Binary File Descriptor library.
|
||||
@ -16,7 +16,7 @@ GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/*
|
||||
SECTION
|
||||
@ -39,6 +39,11 @@ SECTION
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
|
||||
static void insert PARAMS ((bfd *));
|
||||
static void snip PARAMS ((bfd *));
|
||||
static boolean close_one PARAMS ((void));
|
||||
static boolean bfd_cache_delete PARAMS ((bfd *));
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
BFD_CACHE_MAX_OPEN macro
|
||||
@ -51,18 +56,10 @@ DESCRIPTION
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static boolean
|
||||
bfd_cache_delete PARAMS ((bfd *));
|
||||
|
||||
/* Number of bfds on the chain. All such bfds have their file open;
|
||||
if it closed, they get snipd()d from the chain. */
|
||||
/* The number of BFD files we have open. */
|
||||
|
||||
static int open_files;
|
||||
|
||||
static bfd *cache_sentinel = 0; /* Chain of BFDs with active fds we've
|
||||
opened */
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_last_cache
|
||||
@ -96,87 +93,128 @@ bfd *bfd_last_cache;
|
||||
|
||||
*/
|
||||
|
||||
static void
|
||||
DEFUN_VOID(close_one)
|
||||
/* Insert a BFD into the cache. */
|
||||
|
||||
static INLINE void
|
||||
insert (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
bfd *kill = cache_sentinel;
|
||||
if (kill == 0) /* Nothing in the cache */
|
||||
return ;
|
||||
|
||||
/* We can only close files that want to play this game. */
|
||||
while (!kill->cacheable) {
|
||||
kill = kill->lru_prev;
|
||||
if (kill == cache_sentinel) /* Nobody wants to play */
|
||||
return ;
|
||||
if (bfd_last_cache == NULL)
|
||||
{
|
||||
abfd->lru_next = abfd;
|
||||
abfd->lru_prev = abfd;
|
||||
}
|
||||
|
||||
kill->where = ftell((FILE *)(kill->iostream));
|
||||
(void) bfd_cache_delete(kill);
|
||||
else
|
||||
{
|
||||
abfd->lru_next = bfd_last_cache;
|
||||
abfd->lru_prev = bfd_last_cache->lru_prev;
|
||||
abfd->lru_prev->lru_next = abfd;
|
||||
abfd->lru_next->lru_prev = abfd;
|
||||
}
|
||||
bfd_last_cache = abfd;
|
||||
}
|
||||
|
||||
/* Cuts the BFD abfd out of the chain in the cache */
|
||||
static void
|
||||
DEFUN(snip,(abfd),
|
||||
bfd *abfd)
|
||||
/* Remove a BFD from the cache. */
|
||||
|
||||
static INLINE void
|
||||
snip (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
abfd->lru_prev->lru_next = abfd->lru_next;
|
||||
abfd->lru_next->lru_prev = abfd->lru_prev;
|
||||
if (cache_sentinel == abfd) cache_sentinel = (bfd *)NULL;
|
||||
abfd->lru_next->lru_prev = abfd->lru_prev;
|
||||
if (abfd == bfd_last_cache)
|
||||
{
|
||||
bfd_last_cache = abfd->lru_next;
|
||||
if (abfd == bfd_last_cache)
|
||||
bfd_last_cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to open a new file, and the cache is full. Find the least
|
||||
recently used cacheable BFD and close it. */
|
||||
|
||||
static boolean
|
||||
DEFUN(bfd_cache_delete,(abfd),
|
||||
bfd *abfd)
|
||||
close_one ()
|
||||
{
|
||||
register bfd *kill;
|
||||
|
||||
if (bfd_last_cache == NULL)
|
||||
kill = NULL;
|
||||
else
|
||||
{
|
||||
for (kill = bfd_last_cache->lru_prev;
|
||||
! kill->cacheable;
|
||||
kill = kill->lru_prev)
|
||||
{
|
||||
if (kill == bfd_last_cache)
|
||||
{
|
||||
kill = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kill == NULL)
|
||||
{
|
||||
/* There are no open cacheable BFD's. */
|
||||
return true;
|
||||
}
|
||||
|
||||
kill->where = ftell ((FILE *) kill->iostream);
|
||||
|
||||
return bfd_cache_delete (kill);
|
||||
}
|
||||
|
||||
/* Close a BFD and remove it from the cache. */
|
||||
|
||||
static boolean
|
||||
bfd_cache_delete (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
boolean ret;
|
||||
|
||||
if (fclose ((FILE *)(abfd->iostream)) == 0)
|
||||
if (fclose ((FILE *) abfd->iostream) == 0)
|
||||
ret = true;
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
}
|
||||
|
||||
snip (abfd);
|
||||
|
||||
abfd->iostream = NULL;
|
||||
open_files--;
|
||||
bfd_last_cache = 0;
|
||||
--open_files;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bfd *
|
||||
DEFUN(insert,(x,y),
|
||||
bfd *x AND
|
||||
bfd *y)
|
||||
{
|
||||
if (y) {
|
||||
x->lru_next = y;
|
||||
x->lru_prev = y->lru_prev;
|
||||
y->lru_prev->lru_next = x;
|
||||
y->lru_prev = x;
|
||||
|
||||
}
|
||||
else {
|
||||
x->lru_prev = x;
|
||||
x->lru_next = x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize a BFD by putting it on the cache LRU. */
|
||||
|
||||
void
|
||||
DEFUN(bfd_cache_init,(abfd),
|
||||
bfd *abfd)
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_cache_init
|
||||
|
||||
SYNOPSIS
|
||||
boolean bfd_cache_init (bfd *abfd);
|
||||
|
||||
DESCRIPTION
|
||||
Add a newly opened BFD to the cache.
|
||||
*/
|
||||
|
||||
boolean
|
||||
bfd_cache_init (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
BFD_ASSERT (abfd->iostream != NULL);
|
||||
if (open_files >= BFD_CACHE_MAX_OPEN)
|
||||
close_one ();
|
||||
cache_sentinel = insert(abfd, cache_sentinel);
|
||||
{
|
||||
if (! close_one ())
|
||||
return false;
|
||||
}
|
||||
insert (abfd);
|
||||
++open_files;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL_FUNCTION
|
||||
bfd_cache_close
|
||||
@ -192,19 +230,16 @@ RETURNS
|
||||
<<false>> is returned if closing the file fails, <<true>> is
|
||||
returned if all is well.
|
||||
*/
|
||||
|
||||
boolean
|
||||
DEFUN(bfd_cache_close,(abfd),
|
||||
bfd *abfd)
|
||||
bfd_cache_close (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
/* If this file is open then remove from the chain */
|
||||
if (abfd->iostream)
|
||||
{
|
||||
return bfd_cache_delete(abfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (abfd->iostream == NULL
|
||||
|| (abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return true;
|
||||
|
||||
return bfd_cache_delete (abfd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -223,40 +258,47 @@ DESCRIPTION
|
||||
*/
|
||||
|
||||
FILE *
|
||||
DEFUN(bfd_open_file, (abfd),
|
||||
bfd *abfd)
|
||||
bfd_open_file (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
abfd->cacheable = true; /* Allow it to be closed later. */
|
||||
|
||||
if(open_files >= BFD_CACHE_MAX_OPEN) {
|
||||
close_one();
|
||||
}
|
||||
|
||||
switch (abfd->direction) {
|
||||
case read_direction:
|
||||
case no_direction:
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_RB);
|
||||
break;
|
||||
case both_direction:
|
||||
case write_direction:
|
||||
if (abfd->opened_once == true) {
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_RUB);
|
||||
if (!abfd->iostream) {
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_WUB);
|
||||
}
|
||||
} else {
|
||||
/*open for creat */
|
||||
abfd->iostream = (char *) fopen(abfd->filename, FOPEN_WB);
|
||||
abfd->opened_once = true;
|
||||
if (open_files >= BFD_CACHE_MAX_OPEN)
|
||||
{
|
||||
if (! close_one ())
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (abfd->iostream) {
|
||||
bfd_cache_init (abfd);
|
||||
}
|
||||
switch (abfd->direction)
|
||||
{
|
||||
case read_direction:
|
||||
case no_direction:
|
||||
abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RB);
|
||||
break;
|
||||
case both_direction:
|
||||
case write_direction:
|
||||
if (abfd->opened_once == true)
|
||||
{
|
||||
abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_RUB);
|
||||
if (abfd->iostream == NULL)
|
||||
abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*open for creat */
|
||||
abfd->iostream = (PTR) fopen (abfd->filename, FOPEN_WB);
|
||||
abfd->opened_once = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (FILE *)(abfd->iostream);
|
||||
if (abfd->iostream != NULL)
|
||||
{
|
||||
if (! bfd_cache_init (abfd))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (FILE *) abfd->iostream;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -272,40 +314,34 @@ DESCRIPTION
|
||||
necessary, it open it. If there are already more than
|
||||
<<BFD_CACHE_MAX_OPEN>> files open, it tries to close one first, to
|
||||
avoid running out of file descriptors.
|
||||
|
||||
*/
|
||||
|
||||
FILE *
|
||||
DEFUN(bfd_cache_lookup_worker,(abfd),
|
||||
bfd *abfd)
|
||||
bfd_cache_lookup_worker (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
abort ();
|
||||
|
||||
if (abfd->my_archive)
|
||||
{
|
||||
abfd = abfd->my_archive;
|
||||
}
|
||||
/* Is this file already open .. if so then quick exit */
|
||||
if (abfd->iostream)
|
||||
{
|
||||
if (abfd != cache_sentinel) {
|
||||
/* Place onto head of lru chain */
|
||||
abfd = abfd->my_archive;
|
||||
|
||||
if (abfd->iostream != NULL)
|
||||
{
|
||||
/* Move the file to the start of the cache. */
|
||||
if (abfd != bfd_last_cache)
|
||||
{
|
||||
snip (abfd);
|
||||
cache_sentinel = insert(abfd, cache_sentinel);
|
||||
insert (abfd);
|
||||
}
|
||||
}
|
||||
/* This is a BFD without a stream -
|
||||
so it must have been closed or never opened.
|
||||
find an empty cache entry and use it. */
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bfd_open_file (abfd) == NULL)
|
||||
return NULL;
|
||||
if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (open_files >= BFD_CACHE_MAX_OPEN)
|
||||
{
|
||||
close_one();
|
||||
}
|
||||
|
||||
BFD_ASSERT(bfd_open_file (abfd) != (FILE *)NULL) ;
|
||||
fseek((FILE *)(abfd->iostream), abfd->where, false);
|
||||
}
|
||||
bfd_last_cache = abfd;
|
||||
return (FILE *)(abfd->iostream);
|
||||
return (FILE *) abfd->iostream;
|
||||
}
|
||||
|
362
bfd/coff-alpha.c
362
bfd/coff-alpha.c
@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "coff/symconst.h"
|
||||
#include "coff/ecoff.h"
|
||||
#include "coff/alpha.h"
|
||||
#include "aout/ar.h"
|
||||
#include "libcoff.h"
|
||||
#include "libecoff.h"
|
||||
|
||||
@ -57,6 +58,10 @@ static boolean alpha_relocate_section PARAMS ((bfd *, struct bfd_link_info *,
|
||||
bfd_byte *, PTR));
|
||||
static boolean alpha_adjust_headers
|
||||
PARAMS ((bfd *, struct internal_filehdr *, struct internal_aouthdr *));
|
||||
static PTR alpha_ecoff_read_ar_hdr PARAMS ((bfd *));
|
||||
static bfd *alpha_ecoff_get_elt_at_filepos PARAMS ((bfd *, file_ptr));
|
||||
static bfd *alpha_ecoff_openr_next_archived_file PARAMS ((bfd *, bfd *));
|
||||
static bfd *alpha_ecoff_get_elt_at_index PARAMS ((bfd *, symindex));
|
||||
|
||||
/* ECOFF has COFF sections, but the debugging information is stored in
|
||||
a completely different format. ECOFF targets use some of the
|
||||
@ -525,7 +530,7 @@ alpha_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
|
||||
intern->r_vaddr = bfd_h_get_64 (abfd, (bfd_byte *) ext->r_vaddr);
|
||||
intern->r_symndx = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_symndx);
|
||||
|
||||
BFD_ASSERT (abfd->xvec->header_byteorder_big_p == false);
|
||||
BFD_ASSERT (bfd_header_little_endian (abfd));
|
||||
|
||||
intern->r_type = ((ext->r_bits[0] & RELOC_BITS0_TYPE_LITTLE)
|
||||
>> RELOC_BITS0_TYPE_SH_LITTLE);
|
||||
@ -598,7 +603,7 @@ alpha_ecoff_swap_reloc_out (abfd, intern, dst)
|
||||
bfd_h_put_64 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
|
||||
bfd_h_put_32 (abfd, symndx, (bfd_byte *) ext->r_symndx);
|
||||
|
||||
BFD_ASSERT (abfd->xvec->header_byteorder_big_p == false);
|
||||
BFD_ASSERT (bfd_header_little_endian (abfd));
|
||||
|
||||
ext->r_bits[0] = ((intern->r_type << RELOC_BITS0_TYPE_SH_LITTLE)
|
||||
& RELOC_BITS0_TYPE_LITTLE);
|
||||
@ -914,16 +919,12 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
|
||||
/* This marks the ldah of an ldah/lda pair which loads the
|
||||
gp register with the difference of the gp value and the
|
||||
current location. The second of the pair is r_size bytes
|
||||
ahead, and is marked with an ALPHA_R_IGNORE reloc. */
|
||||
ahead; it used to be marked with an ALPHA_R_IGNORE reloc,
|
||||
but that no longer happens in OSF/1 3.2. */
|
||||
{
|
||||
unsigned long insn1, insn2;
|
||||
bfd_vma addend;
|
||||
|
||||
BFD_ASSERT (reloc_vector[1] != NULL
|
||||
&& reloc_vector[1]->howto->type == ALPHA_R_IGNORE
|
||||
&& (rel->address + rel->addend
|
||||
== reloc_vector[1]->address));
|
||||
|
||||
/* Get the two instructions. */
|
||||
insn1 = bfd_get_32 (input_bfd, data + rel->address);
|
||||
insn2 = bfd_get_32 (input_bfd, data + rel->address + rel->addend);
|
||||
@ -945,7 +946,7 @@ alpha_ecoff_get_relocated_section_contents (abfd, link_info, link_order,
|
||||
/* The existing addend includes the different between the
|
||||
gp of the input BFD and the address in the input BFD.
|
||||
Subtract this out. */
|
||||
addend -= (reloc_vector[1]->addend
|
||||
addend -= (ecoff_data (input_bfd)->gp
|
||||
- (input_section->vma + rel->address));
|
||||
|
||||
/* Now add in the final gp value, and subtract out the
|
||||
@ -1364,7 +1365,7 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
bfd_byte *contents;
|
||||
PTR external_relocs;
|
||||
{
|
||||
asection **symndx_to_section;
|
||||
asection **symndx_to_section, *lita_sec;
|
||||
struct ecoff_link_hash_entry **sym_hashes;
|
||||
bfd_vma gp;
|
||||
boolean gp_undefined;
|
||||
@ -1422,14 +1423,79 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
|
||||
sym_hashes = ecoff_data (input_bfd)->sym_hashes;
|
||||
|
||||
gp = ecoff_data (output_bfd)->gp;
|
||||
if (gp == 0)
|
||||
gp_undefined = true;
|
||||
else
|
||||
gp_undefined = false;
|
||||
/* On the Alpha, the .lita section must be addressable by the global
|
||||
pointer. To support large programs, we need to allow multiple
|
||||
global pointers. This works as long as each input .lita section
|
||||
is <64KB big. This implies that when producing relocatable
|
||||
output, the .lita section is limited to 64KB. . */
|
||||
|
||||
BFD_ASSERT (output_bfd->xvec->header_byteorder_big_p == false);
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p == false);
|
||||
lita_sec = symndx_to_section[RELOC_SECTION_LITA];
|
||||
gp = ecoff_data (output_bfd)->gp;
|
||||
if (! info->relocateable && lita_sec != NULL)
|
||||
{
|
||||
struct ecoff_section_tdata *lita_sec_data;
|
||||
|
||||
/* Make sure we have a section data structure to which we can
|
||||
hang on to the gp value we pick for the section. */
|
||||
lita_sec_data = ecoff_section_data (input_bfd, lita_sec);
|
||||
if (lita_sec_data == NULL)
|
||||
{
|
||||
lita_sec_data = ((struct ecoff_section_tdata *)
|
||||
bfd_zalloc (input_bfd,
|
||||
sizeof (struct ecoff_section_tdata)));
|
||||
ecoff_section_data (input_bfd, lita_sec) = lita_sec_data;
|
||||
}
|
||||
|
||||
if (lita_sec_data->gp != 0)
|
||||
{
|
||||
/* If we already assigned a gp to this section, we better
|
||||
stick with that value. */
|
||||
gp = lita_sec_data->gp;
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma lita_vma;
|
||||
bfd_size_type lita_size;
|
||||
|
||||
lita_vma = lita_sec->output_offset + lita_sec->output_section->vma;
|
||||
lita_size = lita_sec->_cooked_size;
|
||||
if (lita_size == 0)
|
||||
lita_size = lita_sec->_raw_size;
|
||||
|
||||
if (gp == 0
|
||||
|| lita_vma < gp - 0x8000
|
||||
|| lita_vma + lita_size >= gp + 0x8000)
|
||||
{
|
||||
/* Either gp hasn't been set at all or the current gp
|
||||
cannot address this .lita section. In both cases we
|
||||
reset the gp to point into the "middle" of the
|
||||
current input .lita section. For now, we issue a
|
||||
warning when redefining the gp value (probably should
|
||||
be made optional). */
|
||||
if (gp && !ecoff_data (output_bfd)->issued_multiple_gp_warning)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
("%s: warning: using multiple gp values",
|
||||
bfd_get_filename (output_bfd));
|
||||
ecoff_data (output_bfd)->issued_multiple_gp_warning = true;
|
||||
}
|
||||
if (lita_vma < gp - 0x8000)
|
||||
gp = lita_vma + lita_size - 0x8000;
|
||||
else
|
||||
gp = lita_vma + 0x8000;
|
||||
|
||||
}
|
||||
|
||||
lita_sec_data->gp = gp;
|
||||
}
|
||||
|
||||
ecoff_data (output_bfd)->gp = gp;
|
||||
}
|
||||
|
||||
gp_undefined = (gp == 0);
|
||||
|
||||
BFD_ASSERT (bfd_header_little_endian (output_bfd));
|
||||
BFD_ASSERT (bfd_header_little_endian (input_bfd));
|
||||
|
||||
ext_rel = (struct external_reloc *) external_relocs;
|
||||
ext_rel_end = ext_rel + input_section->reloc_count;
|
||||
@ -1469,12 +1535,12 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
abort ();
|
||||
|
||||
case ALPHA_R_IGNORE:
|
||||
/* This reloc appears after a GPDISP reloc. It marks the
|
||||
position of the second instruction to be altered by the
|
||||
GPDISP reloc, but is not otherwise used for anything.
|
||||
For some reason, the address of the relocation does not
|
||||
appear to include the section VMA, unlike the other
|
||||
relocation types. */
|
||||
/* This reloc appears after a GPDISP reloc. On earlier
|
||||
versions of OSF/1, It marked the position of the second
|
||||
instruction to be altered by the GPDISP reloc, but it is
|
||||
not otherwise used for anything. For some reason, the
|
||||
address of the relocation does not appear to include the
|
||||
section VMA, unlike the other relocation types. */
|
||||
if (info->relocateable)
|
||||
bfd_h_put_64 (input_bfd,
|
||||
input_section->output_offset + r_vaddr,
|
||||
@ -1544,19 +1610,11 @@ alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
/* This marks the ldah of an ldah/lda pair which loads the
|
||||
gp register with the difference of the gp value and the
|
||||
current location. The second of the pair is r_symndx
|
||||
bytes ahead, and is also marked with an ALPHA_R_IGNORE
|
||||
reloc. */
|
||||
bytes ahead. It used to be marked with an ALPHA_R_IGNORE
|
||||
reloc, but OSF/1 3.2 no longer does that. */
|
||||
{
|
||||
unsigned long insn1, insn2;
|
||||
|
||||
BFD_ASSERT (ext_rel + 1 < ext_rel_end
|
||||
&& (((ext_rel + 1)->r_bits[0]
|
||||
& RELOC_BITS0_TYPE_LITTLE)
|
||||
>> RELOC_BITS0_TYPE_SH_LITTLE) == ALPHA_R_IGNORE
|
||||
&& (bfd_h_get_64 (input_bfd,
|
||||
(bfd_byte *) (ext_rel + 1)->r_vaddr)
|
||||
== r_vaddr - input_section->vma + r_symndx));
|
||||
|
||||
/* Get the two instructions. */
|
||||
insn1 = bfd_get_32 (input_bfd,
|
||||
contents + r_vaddr - input_section->vma);
|
||||
@ -1949,6 +2007,234 @@ alpha_adjust_headers (abfd, fhdr, ahdr)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Archive handling. In OSF/1 (or Digital Unix) v3.2, Digital
|
||||
introduced archive packing, in which the elements in an archive are
|
||||
optionally compressed using a simple dictionary scheme. We know
|
||||
how to read such archives, but we don't write them. */
|
||||
|
||||
#define alpha_ecoff_slurp_armap _bfd_ecoff_slurp_armap
|
||||
#define alpha_ecoff_slurp_extended_name_table \
|
||||
_bfd_ecoff_slurp_extended_name_table
|
||||
#define alpha_ecoff_construct_extended_name_table \
|
||||
_bfd_ecoff_construct_extended_name_table
|
||||
#define alpha_ecoff_truncate_arname _bfd_ecoff_truncate_arname
|
||||
#define alpha_ecoff_write_armap _bfd_ecoff_write_armap
|
||||
#define alpha_ecoff_generic_stat_arch_elt _bfd_ecoff_generic_stat_arch_elt
|
||||
#define alpha_ecoff_update_armap_timestamp _bfd_ecoff_update_armap_timestamp
|
||||
|
||||
/* A compressed file uses this instead of ARFMAG. */
|
||||
|
||||
#define ARFZMAG "Z\012"
|
||||
|
||||
/* Read an archive header. This is like the standard routine, but it
|
||||
also accepts ARFZMAG. */
|
||||
|
||||
static PTR
|
||||
alpha_ecoff_read_ar_hdr (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
struct areltdata *ret;
|
||||
struct ar_hdr *h;
|
||||
|
||||
ret = (struct areltdata *) _bfd_generic_read_ar_hdr_mag (abfd, ARFZMAG);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
h = (struct ar_hdr *) ret->arch_header;
|
||||
if (strncmp (h->ar_fmag, ARFZMAG, 2) == 0)
|
||||
{
|
||||
bfd_byte ab[8];
|
||||
|
||||
/* This is a compressed file. We must set the size correctly.
|
||||
The size is the eight bytes after the dummy file header. */
|
||||
if (bfd_seek (abfd, FILHSZ, SEEK_CUR) != 0
|
||||
|| bfd_read (ab, 1, 8, abfd) != 8
|
||||
|| bfd_seek (abfd, - (FILHSZ + 8), SEEK_CUR) != 0)
|
||||
return NULL;
|
||||
|
||||
ret->parsed_size = bfd_h_get_64 (abfd, ab);
|
||||
}
|
||||
|
||||
return (PTR) ret;
|
||||
}
|
||||
|
||||
/* Get an archive element at a specified file position. This is where
|
||||
we uncompress the archive element if necessary. */
|
||||
|
||||
static bfd *
|
||||
alpha_ecoff_get_elt_at_filepos (archive, filepos)
|
||||
bfd *archive;
|
||||
file_ptr filepos;
|
||||
{
|
||||
bfd *nbfd = NULL;
|
||||
struct areltdata *tdata;
|
||||
struct ar_hdr *hdr;
|
||||
bfd_byte ab[8];
|
||||
bfd_size_type size;
|
||||
bfd_byte *buf, *p;
|
||||
struct bfd_in_memory *bim;
|
||||
|
||||
nbfd = _bfd_get_elt_at_filepos (archive, filepos);
|
||||
if (nbfd == NULL)
|
||||
goto error_return;
|
||||
|
||||
if ((nbfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
/* We have already expanded this BFD. */
|
||||
return nbfd;
|
||||
}
|
||||
|
||||
tdata = (struct areltdata *) nbfd->arelt_data;
|
||||
hdr = (struct ar_hdr *) tdata->arch_header;
|
||||
if (strncmp (hdr->ar_fmag, ARFZMAG, 2) != 0)
|
||||
return nbfd;
|
||||
|
||||
/* We must uncompress this element. We do this by copying it into a
|
||||
memory buffer, and making bfd_read and bfd_seek use that buffer.
|
||||
This can use a lot of memory, but it's simpler than getting a
|
||||
temporary file, making that work with the file descriptor caching
|
||||
code, and making sure that it is deleted at all appropriate
|
||||
times. It can be changed if it ever becomes important. */
|
||||
|
||||
/* The compressed file starts with a dummy ECOFF file header. */
|
||||
if (bfd_seek (nbfd, FILHSZ, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
|
||||
/* The next eight bytes are the real file size. */
|
||||
if (bfd_read (ab, 1, 8, nbfd) != 8)
|
||||
goto error_return;
|
||||
size = bfd_h_get_64 (nbfd, ab);
|
||||
|
||||
if (size == 0)
|
||||
buf = NULL;
|
||||
else
|
||||
{
|
||||
bfd_size_type left;
|
||||
bfd_byte dict[4096];
|
||||
unsigned int h;
|
||||
bfd_byte b;
|
||||
|
||||
buf = (bfd_byte *) bfd_alloc (nbfd, size);
|
||||
if (buf == NULL)
|
||||
goto error_return;
|
||||
p = buf;
|
||||
|
||||
left = size;
|
||||
|
||||
/* I don't know what the next eight bytes are for. */
|
||||
if (bfd_read (ab, 1, 8, nbfd) != 8)
|
||||
goto error_return;
|
||||
|
||||
/* This is the uncompression algorithm. It's a simple
|
||||
dictionary based scheme in which each character is predicted
|
||||
by a hash of the previous three characters. A control byte
|
||||
indicates whether the character is predicted or whether it
|
||||
appears in the input stream; each control byte manages the
|
||||
next eight bytes in the output stream. */
|
||||
memset (dict, 0, sizeof dict);
|
||||
h = 0;
|
||||
while (bfd_read (&b, 1, 1, nbfd) == 1)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 8; i++, b >>= 1)
|
||||
{
|
||||
bfd_byte n;
|
||||
|
||||
if ((b & 1) == 0)
|
||||
n = dict[h];
|
||||
else
|
||||
{
|
||||
if (! bfd_read (&n, 1, 1, nbfd))
|
||||
goto error_return;
|
||||
dict[h] = n;
|
||||
}
|
||||
|
||||
*p++ = n;
|
||||
|
||||
--left;
|
||||
if (left == 0)
|
||||
break;
|
||||
|
||||
h <<= 4;
|
||||
h ^= n;
|
||||
h &= sizeof dict - 1;
|
||||
}
|
||||
|
||||
if (left == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now the uncompressed file contents are in buf. */
|
||||
bim = ((struct bfd_in_memory *)
|
||||
bfd_alloc (nbfd, sizeof (struct bfd_in_memory)));
|
||||
if (bim == NULL)
|
||||
goto error_return;
|
||||
bim->size = size;
|
||||
bim->buffer = buf;
|
||||
|
||||
nbfd->mtime_set = true;
|
||||
nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
|
||||
|
||||
nbfd->flags |= BFD_IN_MEMORY;
|
||||
nbfd->iostream = (PTR) bim;
|
||||
BFD_ASSERT (! nbfd->cacheable);
|
||||
|
||||
return nbfd;
|
||||
|
||||
error_return:
|
||||
if (nbfd != NULL)
|
||||
bfd_close (nbfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Open the next archived file. */
|
||||
|
||||
static bfd *
|
||||
alpha_ecoff_openr_next_archived_file (archive, last_file)
|
||||
bfd *archive;
|
||||
bfd *last_file;
|
||||
{
|
||||
file_ptr filestart;
|
||||
|
||||
if (last_file == NULL)
|
||||
filestart = bfd_ardata (archive)->first_file_filepos;
|
||||
else
|
||||
{
|
||||
struct areltdata *t;
|
||||
struct ar_hdr *h;
|
||||
bfd_size_type size;
|
||||
|
||||
/* We can't use arelt_size here, because that uses parsed_size,
|
||||
which is the uncompressed size. We need the compressed size. */
|
||||
t = (struct areltdata *) last_file->arelt_data;
|
||||
h = (struct ar_hdr *) t->arch_header;
|
||||
size = strtol (h->ar_size, (char **) NULL, 10);
|
||||
|
||||
/* Pad to an even boundary...
|
||||
Note that last_file->origin can be odd in the case of
|
||||
BSD-4.4-style element with a long odd size. */
|
||||
filestart = last_file->origin + size;
|
||||
filestart += filestart % 2;
|
||||
}
|
||||
|
||||
return alpha_ecoff_get_elt_at_filepos (archive, filestart);
|
||||
}
|
||||
|
||||
/* Open the archive file given an index into the armap. */
|
||||
|
||||
static bfd *
|
||||
alpha_ecoff_get_elt_at_index (abfd, index)
|
||||
bfd *abfd;
|
||||
symindex index;
|
||||
{
|
||||
carsym *entry;
|
||||
|
||||
entry = bfd_ardata (abfd)->symdefs + index;
|
||||
return alpha_ecoff_get_elt_at_filepos (abfd, entry->file_offset);
|
||||
}
|
||||
|
||||
/* This is the ECOFF backend structure. The backend field of the
|
||||
target vector points to this. */
|
||||
|
||||
@ -2038,7 +2324,9 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
|
||||
/* Relocate section contents while linking. */
|
||||
alpha_relocate_section,
|
||||
/* Do final adjustments to filehdr and aouthdr. */
|
||||
alpha_adjust_headers
|
||||
alpha_adjust_headers,
|
||||
/* Read an element from an archive at a given file position. */
|
||||
alpha_ecoff_get_elt_at_filepos
|
||||
};
|
||||
|
||||
/* Looking up a reloc type is Alpha specific. */
|
||||
@ -2059,8 +2347,8 @@ const bfd_target ecoffalpha_little_vec =
|
||||
{
|
||||
"ecoff-littlealpha", /* name */
|
||||
bfd_target_ecoff_flavour,
|
||||
false, /* data byte order is little */
|
||||
false, /* header byte order is little */
|
||||
BFD_ENDIAN_LITTLE, /* data byte order is little */
|
||||
BFD_ENDIAN_LITTLE, /* header byte order is little */
|
||||
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
@ -2087,7 +2375,7 @@ const bfd_target ecoffalpha_little_vec =
|
||||
BFD_JUMP_TABLE_GENERIC (_bfd_ecoff),
|
||||
BFD_JUMP_TABLE_COPY (_bfd_ecoff),
|
||||
BFD_JUMP_TABLE_CORE (_bfd_nocore),
|
||||
BFD_JUMP_TABLE_ARCHIVE (_bfd_ecoff),
|
||||
BFD_JUMP_TABLE_ARCHIVE (alpha_ecoff),
|
||||
BFD_JUMP_TABLE_SYMBOLS (_bfd_ecoff),
|
||||
BFD_JUMP_TABLE_RELOCS (_bfd_ecoff),
|
||||
BFD_JUMP_TABLE_WRITE (_bfd_ecoff),
|
||||
|
@ -396,12 +396,12 @@ mips_ecoff_bad_format_hook (abfd, filehdr)
|
||||
case MIPS_MAGIC_BIG:
|
||||
case MIPS_MAGIC_BIG2:
|
||||
case MIPS_MAGIC_BIG3:
|
||||
return abfd->xvec->byteorder_big_p;
|
||||
return bfd_big_endian (abfd);
|
||||
|
||||
case MIPS_MAGIC_LITTLE:
|
||||
case MIPS_MAGIC_LITTLE2:
|
||||
case MIPS_MAGIC_LITTLE3:
|
||||
return abfd->xvec->byteorder_big_p == false;
|
||||
return bfd_little_endian (abfd);
|
||||
|
||||
default:
|
||||
return false;
|
||||
@ -423,7 +423,7 @@ mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
|
||||
const RELOC *ext = (RELOC *) ext_ptr;
|
||||
|
||||
intern->r_vaddr = bfd_h_get_32 (abfd, (bfd_byte *) ext->r_vaddr);
|
||||
if (abfd->xvec->header_byteorder_big_p != false)
|
||||
if (bfd_header_big_endian (abfd))
|
||||
{
|
||||
intern->r_symndx = (((int) ext->r_bits[0]
|
||||
<< RELOC_BITS0_SYMNDX_SH_LEFT_BIG)
|
||||
@ -500,7 +500,7 @@ mips_ecoff_swap_reloc_out (abfd, intern, dst)
|
||||
}
|
||||
|
||||
bfd_h_put_32 (abfd, intern->r_vaddr, (bfd_byte *) ext->r_vaddr);
|
||||
if (abfd->xvec->header_byteorder_big_p != false)
|
||||
if (bfd_header_big_endian (abfd))
|
||||
{
|
||||
ext->r_bits[0] = r_symndx >> RELOC_BITS0_SYMNDX_SH_LEFT_BIG;
|
||||
ext->r_bits[1] = r_symndx >> RELOC_BITS1_SYMNDX_SH_LEFT_BIG;
|
||||
@ -1190,8 +1190,8 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
boolean got_lo;
|
||||
struct internal_reloc lo_int_rel;
|
||||
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
|
||||
== output_bfd->xvec->header_byteorder_big_p);
|
||||
BFD_ASSERT (input_bfd->xvec->header_byteorder
|
||||
== output_bfd->xvec->header_byteorder);
|
||||
|
||||
/* We keep a table mapping the symndx found in an internal reloc to
|
||||
the appropriate section. This is faster than looking up the
|
||||
@ -1927,7 +1927,7 @@ mips_relax_section (abfd, sec, info, again)
|
||||
continue;
|
||||
|
||||
/* Quickly check that this reloc is external PCREL16. */
|
||||
if (abfd->xvec->header_byteorder_big_p)
|
||||
if (bfd_header_big_endian (abfd))
|
||||
{
|
||||
if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
|
||||
|| (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
|
||||
@ -2488,7 +2488,9 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
|
||||
/* Relocate section contents while linking. */
|
||||
mips_relocate_section,
|
||||
/* Do final adjustments to filehdr and aouthdr. */
|
||||
NULL
|
||||
NULL,
|
||||
/* Read an element from an archive at a given file position. */
|
||||
_bfd_get_elt_at_filepos
|
||||
};
|
||||
|
||||
/* Looking up a reloc type is MIPS specific. */
|
||||
@ -2509,8 +2511,8 @@ const bfd_target ecoff_little_vec =
|
||||
{
|
||||
"ecoff-littlemips", /* name */
|
||||
bfd_target_ecoff_flavour,
|
||||
false, /* data byte order is little */
|
||||
false, /* header byte order is little */
|
||||
BFD_ENDIAN_LITTLE, /* data byte order is little */
|
||||
BFD_ENDIAN_LITTLE, /* header byte order is little */
|
||||
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
@ -2551,8 +2553,8 @@ const bfd_target ecoff_big_vec =
|
||||
{
|
||||
"ecoff-bigmips", /* name */
|
||||
bfd_target_ecoff_flavour,
|
||||
true, /* data byte order is big */
|
||||
true, /* header byte order is big */
|
||||
BFD_ENDIAN_BIG, /* data byte order is big */
|
||||
BFD_ENDIAN_BIG, /* header byte order is big */
|
||||
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
|
@ -658,6 +658,10 @@ struct xcoff_ar_hdr
|
||||
bfd_false)
|
||||
#define xcoff_truncate_arname bfd_dont_truncate_arname
|
||||
|
||||
/* We can use the standard get_elt_at_index routine. */
|
||||
|
||||
#define xcoff_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
|
||||
/* XCOFF archives do not have a timestamp. */
|
||||
|
||||
#define xcoff_update_armap_timestamp bfd_true
|
||||
@ -1346,8 +1350,8 @@ const bfd_target
|
||||
"aixcoff-rs6000", /* name */
|
||||
#endif
|
||||
bfd_target_coff_flavour,
|
||||
true, /* data byte order is big */
|
||||
true, /* header byte order is big */
|
||||
BFD_ENDIAN_BIG, /* data byte order is big */
|
||||
BFD_ENDIAN_BIG, /* header byte order is big */
|
||||
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG | DYNAMIC |
|
||||
|
@ -36,6 +36,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
do casts, and casting to the left of assignment isn't portable. */
|
||||
#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v))
|
||||
|
||||
/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points
|
||||
to an instance of this structure. */
|
||||
|
||||
struct bfd_in_memory
|
||||
{
|
||||
/* Size of buffer. */
|
||||
bfd_size_type size;
|
||||
/* Buffer holding contents of BFD. */
|
||||
bfd_byte *buffer;
|
||||
};
|
||||
|
||||
/* tdata for an archive. For an input archive, cache
|
||||
needs to be free()'d. For an output archive, symdefs do. */
|
||||
|
||||
@ -70,16 +81,16 @@ struct areltdata {
|
||||
|
||||
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
|
||||
|
||||
char *bfd_zmalloc PARAMS ((bfd_size_type size));
|
||||
extern PTR bfd_malloc PARAMS ((size_t));
|
||||
extern PTR bfd_realloc PARAMS ((PTR, size_t));
|
||||
extern PTR bfd_zmalloc PARAMS ((size_t));
|
||||
|
||||
extern bfd_error_handler_type _bfd_error_handler;
|
||||
|
||||
/* These routines allocate and free things on the BFD's obstack. Note
|
||||
that realloc can never occur in place. */
|
||||
/* These routines allocate and free things on the BFD's obstack. */
|
||||
|
||||
PTR bfd_alloc PARAMS ((bfd *abfd, size_t size));
|
||||
PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size));
|
||||
PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, size_t size));
|
||||
void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size));
|
||||
PTR bfd_alloc_finish PARAMS ((bfd *abfd));
|
||||
PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted));
|
||||
@ -101,6 +112,7 @@ extern boolean _bfd_construct_extended_name_table
|
||||
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
|
||||
boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength));
|
||||
bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos));
|
||||
extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex));
|
||||
bfd * _bfd_new_bfd PARAMS ((void));
|
||||
|
||||
boolean bfd_false PARAMS ((bfd *ignore));
|
||||
@ -130,13 +142,15 @@ boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength,
|
||||
|
||||
extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *));
|
||||
|
||||
extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *));
|
||||
|
||||
bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
|
||||
bfd *last_file));
|
||||
|
||||
int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
|
||||
|
||||
#define _bfd_read_ar_hdr(abfd) \
|
||||
BFD_SEND (abfd, _bfd_read_ar_hdr, (abfd))
|
||||
BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd))
|
||||
|
||||
/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
|
||||
BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
|
||||
@ -148,6 +162,8 @@ int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
|
||||
extern boolean _bfd_generic_get_section_contents
|
||||
PARAMS ((bfd *, asection *, PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
extern boolean _bfd_generic_get_section_contents_in_window
|
||||
PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type));
|
||||
|
||||
/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use
|
||||
BFD_JUMP_TABLE_COPY (_bfd_generic). */
|
||||
@ -163,7 +179,7 @@ extern boolean _bfd_generic_get_section_contents
|
||||
#define _bfd_generic_bfd_copy_private_symbol_data \
|
||||
((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true)
|
||||
#define _bfd_generic_bfd_print_private_bfd_data \
|
||||
((boolean (*) PARAMS ((bfd *, void *))) bfd_true)
|
||||
((boolean (*) PARAMS ((bfd *, PTR))) bfd_true)
|
||||
|
||||
/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
|
||||
support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */
|
||||
@ -190,6 +206,8 @@ extern boolean _bfd_nocore_core_file_matches_executable_p
|
||||
#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr
|
||||
#define _bfd_noarchive_openr_next_archived_file \
|
||||
((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr)
|
||||
#define _bfd_noarchive_get_elt_at_index \
|
||||
((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr)
|
||||
#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define _bfd_noarchive_update_armap_timestamp bfd_false
|
||||
|
||||
@ -206,6 +224,7 @@ extern boolean _bfd_archive_bsd_construct_extended_name_table
|
||||
#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr
|
||||
#define _bfd_archive_bsd_openr_next_archived_file \
|
||||
bfd_generic_openr_next_archived_file
|
||||
#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define _bfd_archive_bsd_generic_stat_arch_elt \
|
||||
bfd_generic_stat_arch_elt
|
||||
extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *));
|
||||
@ -223,6 +242,7 @@ extern boolean _bfd_archive_coff_construct_extended_name_table
|
||||
#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr
|
||||
#define _bfd_archive_coff_openr_next_archived_file \
|
||||
bfd_generic_openr_next_archived_file
|
||||
#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define _bfd_archive_coff_generic_stat_arch_elt \
|
||||
bfd_generic_stat_arch_elt
|
||||
#define _bfd_archive_coff_update_armap_timestamp bfd_true
|
||||
@ -401,6 +421,9 @@ extern bfd_reloc_status_type _bfd_relocate_contents
|
||||
/* Create a string table. */
|
||||
extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void));
|
||||
|
||||
/* Create an XCOFF .debug section style string table. */
|
||||
extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void));
|
||||
|
||||
/* Free a string table. */
|
||||
extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *));
|
||||
|
||||
|
108
bfd/libbfd.c
108
bfd/libbfd.c
@ -155,27 +155,60 @@ _bfd_dummy_target (ignore_abfd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Allocate memory using malloc. */
|
||||
|
||||
#ifndef bfd_zmalloc
|
||||
/* allocate and clear storage */
|
||||
|
||||
char *
|
||||
bfd_zmalloc (size)
|
||||
bfd_size_type size;
|
||||
PTR
|
||||
bfd_malloc (size)
|
||||
size_t size;
|
||||
{
|
||||
char *ptr = (char *) malloc ((size_t) size);
|
||||
PTR ptr;
|
||||
|
||||
ptr = (PTR) malloc (size);
|
||||
if (ptr == NULL && size != 0)
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Reallocate memory using realloc. */
|
||||
|
||||
PTR
|
||||
bfd_realloc (ptr, size)
|
||||
PTR ptr;
|
||||
size_t size;
|
||||
{
|
||||
PTR ret;
|
||||
|
||||
if (ptr == NULL)
|
||||
ret = malloc (size);
|
||||
else
|
||||
ret = realloc (ptr, size);
|
||||
|
||||
if (ret == NULL)
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate memory using malloc and clear it. */
|
||||
|
||||
PTR
|
||||
bfd_zmalloc (size)
|
||||
size_t size;
|
||||
{
|
||||
PTR ptr;
|
||||
|
||||
ptr = (PTR) malloc (size);
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
else
|
||||
memset (ptr, 0, (size_t) size);
|
||||
memset (ptr, 0, size);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
#endif /* bfd_zmalloc */
|
||||
|
||||
/* Some IO code */
|
||||
|
||||
@ -208,6 +241,24 @@ bfd_read (ptr, size, nitems, abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
int nread;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
struct bfd_in_memory *bim;
|
||||
bfd_size_type get;
|
||||
|
||||
bim = (struct bfd_in_memory *) abfd->iostream;
|
||||
get = size * nitems;
|
||||
if (abfd->where + get > bim->size)
|
||||
{
|
||||
get = bim->size - abfd->where;
|
||||
bfd_set_error (bfd_error_file_truncated);
|
||||
}
|
||||
memcpy (ptr, bim->buffer + abfd->where, get);
|
||||
abfd->where += get;
|
||||
return get;
|
||||
}
|
||||
|
||||
nread = real_read (ptr, 1, (size_t)(size*nitems), bfd_cache_lookup(abfd));
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
if (nread > 0)
|
||||
@ -350,7 +401,9 @@ bfd_get_file_window (abfd, offset, size, windowp, writable)
|
||||
i->data = 0;
|
||||
}
|
||||
#ifdef HAVE_MMAP
|
||||
if (ok_to_map && (i->data == 0 || i->mapped == 1))
|
||||
if (ok_to_map
|
||||
&& (i->data == 0 || i->mapped == 1)
|
||||
&& (abfd->flags & BFD_IN_MEMORY) == 0)
|
||||
{
|
||||
file_ptr file_offset, offset2;
|
||||
size_t real_size;
|
||||
@ -429,10 +482,7 @@ bfd_get_file_window (abfd, offset, size, windowp, writable)
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\n\t%s(%6ld)",
|
||||
i->data ? "realloc" : " malloc", (long) size_to_alloc);
|
||||
if (i->data)
|
||||
i->data = (PTR) realloc (i->data, size_to_alloc);
|
||||
else
|
||||
i->data = (PTR) malloc (size_to_alloc);
|
||||
i->data = (PTR) bfd_realloc (i->data, size_to_alloc);
|
||||
if (debug_windows)
|
||||
fprintf (stderr, "\t-> %p\n", i->data);
|
||||
i->refcount = 1;
|
||||
@ -470,8 +520,13 @@ bfd_write (ptr, size, nitems, abfd)
|
||||
bfd_size_type nitems;
|
||||
bfd *abfd;
|
||||
{
|
||||
long nwrote = fwrite (ptr, 1, (size_t) (size * nitems),
|
||||
bfd_cache_lookup (abfd));
|
||||
long nwrote;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
abort ();
|
||||
|
||||
nwrote = fwrite (ptr, 1, (size_t) (size * nitems),
|
||||
bfd_cache_lookup (abfd));
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
if (nwrote > 0)
|
||||
abfd->where += nwrote;
|
||||
@ -517,6 +572,9 @@ bfd_tell (abfd)
|
||||
{
|
||||
file_ptr ptr;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return abfd->where;
|
||||
|
||||
ptr = ftell (bfd_cache_lookup(abfd));
|
||||
|
||||
if (abfd->my_archive)
|
||||
@ -529,6 +587,8 @@ int
|
||||
bfd_flush (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
return 0;
|
||||
return fflush (bfd_cache_lookup(abfd));
|
||||
}
|
||||
|
||||
@ -541,6 +601,10 @@ bfd_stat (abfd, statbuf)
|
||||
{
|
||||
FILE *f;
|
||||
int result;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
abort ();
|
||||
|
||||
f = bfd_cache_lookup (abfd);
|
||||
if (f == NULL)
|
||||
{
|
||||
@ -573,6 +637,16 @@ bfd_seek (abfd, position, direction)
|
||||
|
||||
if (direction == SEEK_CUR && position == 0)
|
||||
return 0;
|
||||
|
||||
if ((abfd->flags & BFD_IN_MEMORY) != 0)
|
||||
{
|
||||
if (direction == SEEK_SET)
|
||||
abfd->where = position;
|
||||
else
|
||||
abfd->where += position;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef FILE_OFFSET_IS_CHAR_INDEX
|
||||
if (abfd->format != bfd_archive && abfd->my_archive == 0)
|
||||
{
|
||||
@ -1044,7 +1118,7 @@ _bfd_generic_get_section_contents_in_window (abfd, section, w, offset, count)
|
||||
w->i = (bfd_window_internal *) bfd_zmalloc (sizeof (bfd_window_internal));
|
||||
if (w->i == NULL)
|
||||
return false;
|
||||
w->i->data = (PTR) malloc ((size_t) count);
|
||||
w->i->data = (PTR) bfd_malloc ((size_t) count);
|
||||
if (w->i->data == NULL)
|
||||
{
|
||||
free (w->i);
|
||||
|
35
bfd/libbfd.h
35
bfd/libbfd.h
@ -36,6 +36,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
do casts, and casting to the left of assignment isn't portable. */
|
||||
#define set_tdata(bfd, v) ((bfd)->tdata.any = (PTR) (v))
|
||||
|
||||
/* If BFD_IN_MEMORY is set for a BFD, then the iostream fields points
|
||||
to an instance of this structure. */
|
||||
|
||||
struct bfd_in_memory
|
||||
{
|
||||
/* Size of buffer. */
|
||||
bfd_size_type size;
|
||||
/* Buffer holding contents of BFD. */
|
||||
bfd_byte *buffer;
|
||||
};
|
||||
|
||||
/* tdata for an archive. For an input archive, cache
|
||||
needs to be free()'d. For an output archive, symdefs do. */
|
||||
|
||||
@ -70,16 +81,16 @@ struct areltdata {
|
||||
|
||||
#define arelt_size(bfd) (((struct areltdata *)((bfd)->arelt_data))->parsed_size)
|
||||
|
||||
char *bfd_zmalloc PARAMS ((bfd_size_type size));
|
||||
extern PTR bfd_malloc PARAMS ((size_t));
|
||||
extern PTR bfd_realloc PARAMS ((PTR, size_t));
|
||||
extern PTR bfd_zmalloc PARAMS ((size_t));
|
||||
|
||||
extern bfd_error_handler_type _bfd_error_handler;
|
||||
|
||||
/* These routines allocate and free things on the BFD's obstack. Note
|
||||
that realloc can never occur in place. */
|
||||
/* These routines allocate and free things on the BFD's obstack. */
|
||||
|
||||
PTR bfd_alloc PARAMS ((bfd *abfd, size_t size));
|
||||
PTR bfd_zalloc PARAMS ((bfd *abfd, size_t size));
|
||||
PTR bfd_realloc PARAMS ((bfd *abfd, PTR orig, size_t size));
|
||||
void bfd_alloc_grow PARAMS ((bfd *abfd, PTR thing, size_t size));
|
||||
PTR bfd_alloc_finish PARAMS ((bfd *abfd));
|
||||
PTR bfd_alloc_by_size_t PARAMS ((bfd *abfd, size_t wanted));
|
||||
@ -101,6 +112,7 @@ extern boolean _bfd_construct_extended_name_table
|
||||
boolean _bfd_write_archive_contents PARAMS ((bfd *abfd));
|
||||
boolean _bfd_compute_and_write_armap PARAMS ((bfd *, unsigned int elength));
|
||||
bfd *_bfd_get_elt_at_filepos PARAMS ((bfd *archive, file_ptr filepos));
|
||||
extern bfd *_bfd_generic_get_elt_at_index PARAMS ((bfd *, symindex));
|
||||
bfd * _bfd_new_bfd PARAMS ((void));
|
||||
|
||||
boolean bfd_false PARAMS ((bfd *ignore));
|
||||
@ -130,13 +142,15 @@ boolean coff_write_armap PARAMS ((bfd *arch, unsigned int elength,
|
||||
|
||||
extern PTR _bfd_generic_read_ar_hdr PARAMS ((bfd *));
|
||||
|
||||
extern PTR _bfd_generic_read_ar_hdr_mag PARAMS ((bfd *, const char *));
|
||||
|
||||
bfd * bfd_generic_openr_next_archived_file PARAMS ((bfd *archive,
|
||||
bfd *last_file));
|
||||
|
||||
int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
|
||||
|
||||
#define _bfd_read_ar_hdr(abfd) \
|
||||
BFD_SEND (abfd, _bfd_read_ar_hdr, (abfd))
|
||||
BFD_SEND (abfd, _bfd_read_ar_hdr_fn, (abfd))
|
||||
|
||||
/* Generic routines to use for BFD_JUMP_TABLE_GENERIC. Use
|
||||
BFD_JUMP_TABLE_GENERIC (_bfd_generic). */
|
||||
@ -148,6 +162,8 @@ int bfd_generic_stat_arch_elt PARAMS ((bfd *, struct stat *));
|
||||
extern boolean _bfd_generic_get_section_contents
|
||||
PARAMS ((bfd *, asection *, PTR location, file_ptr offset,
|
||||
bfd_size_type count));
|
||||
extern boolean _bfd_generic_get_section_contents_in_window
|
||||
PARAMS ((bfd *, asection *, bfd_window *, file_ptr, bfd_size_type));
|
||||
|
||||
/* Generic routines to use for BFD_JUMP_TABLE_COPY. Use
|
||||
BFD_JUMP_TABLE_COPY (_bfd_generic). */
|
||||
@ -163,7 +179,7 @@ extern boolean _bfd_generic_get_section_contents
|
||||
#define _bfd_generic_bfd_copy_private_symbol_data \
|
||||
((boolean (*) PARAMS ((bfd *, asymbol *, bfd *, asymbol *))) bfd_true)
|
||||
#define _bfd_generic_bfd_print_private_bfd_data \
|
||||
((boolean (*) PARAMS ((bfd *, void *))) bfd_true)
|
||||
((boolean (*) PARAMS ((bfd *, PTR))) bfd_true)
|
||||
|
||||
/* Routines to use for BFD_JUMP_TABLE_CORE when there is no core file
|
||||
support. Use BFD_JUMP_TABLE_CORE (_bfd_nocore). */
|
||||
@ -190,6 +206,8 @@ extern boolean _bfd_nocore_core_file_matches_executable_p
|
||||
#define _bfd_noarchive_read_ar_hdr bfd_nullvoidptr
|
||||
#define _bfd_noarchive_openr_next_archived_file \
|
||||
((bfd *(*) PARAMS ((bfd *, bfd *))) bfd_nullvoidptr)
|
||||
#define _bfd_noarchive_get_elt_at_index \
|
||||
((bfd *(*) PARAMS ((bfd *, symindex))) bfd_nullvoidptr)
|
||||
#define _bfd_noarchive_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define _bfd_noarchive_update_armap_timestamp bfd_false
|
||||
|
||||
@ -206,6 +224,7 @@ extern boolean _bfd_archive_bsd_construct_extended_name_table
|
||||
#define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr
|
||||
#define _bfd_archive_bsd_openr_next_archived_file \
|
||||
bfd_generic_openr_next_archived_file
|
||||
#define _bfd_archive_bsd_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define _bfd_archive_bsd_generic_stat_arch_elt \
|
||||
bfd_generic_stat_arch_elt
|
||||
extern boolean _bfd_archive_bsd_update_armap_timestamp PARAMS ((bfd *));
|
||||
@ -223,6 +242,7 @@ extern boolean _bfd_archive_coff_construct_extended_name_table
|
||||
#define _bfd_archive_coff_read_ar_hdr _bfd_generic_read_ar_hdr
|
||||
#define _bfd_archive_coff_openr_next_archived_file \
|
||||
bfd_generic_openr_next_archived_file
|
||||
#define _bfd_archive_coff_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define _bfd_archive_coff_generic_stat_arch_elt \
|
||||
bfd_generic_stat_arch_elt
|
||||
#define _bfd_archive_coff_update_armap_timestamp bfd_true
|
||||
@ -401,6 +421,9 @@ extern bfd_reloc_status_type _bfd_relocate_contents
|
||||
/* Create a string table. */
|
||||
extern struct bfd_strtab_hash *_bfd_stringtab_init PARAMS ((void));
|
||||
|
||||
/* Create an XCOFF .debug section style string table. */
|
||||
extern struct bfd_strtab_hash *_bfd_xcoff_stringtab_init PARAMS ((void));
|
||||
|
||||
/* Free a string table. */
|
||||
extern void _bfd_stringtab_free PARAMS ((struct bfd_strtab_hash *));
|
||||
|
||||
|
@ -71,6 +71,9 @@ struct ecoff_backend_data
|
||||
/* Do final adjustments to filehdr and aouthdr. */
|
||||
boolean (*adjust_headers) PARAMS ((bfd *, struct internal_filehdr *,
|
||||
struct internal_aouthdr *));
|
||||
/* Read an element from an archive at a given file position. This
|
||||
is needed because OSF/1 3.2 uses a weird archive format. */
|
||||
bfd *(*get_elt_at_filepos) PARAMS ((bfd *, file_ptr));
|
||||
};
|
||||
|
||||
/* This is the target specific information kept for ECOFF files. */
|
||||
@ -127,6 +130,10 @@ typedef struct ecoff_tdata
|
||||
/* True if this BFD was written by the backend linker. */
|
||||
boolean linker;
|
||||
|
||||
/* True if a warning that multiple global pointer values are
|
||||
needed in the output binary was issued already. */
|
||||
boolean issued_multiple_gp_warning;
|
||||
|
||||
/* Used by find_nearest_line entry point. The structure could be
|
||||
included directly in this one, but there's no point to wasting
|
||||
the memory just for the infrequently called find_nearest_line. */
|
||||
@ -197,6 +204,14 @@ struct ecoff_section_tdata
|
||||
section, and the entry for any reloc that is not PC relative is
|
||||
zero. */
|
||||
long *offsets;
|
||||
|
||||
/* When producing an executable (i.e., final, non-relocatable link)
|
||||
on the Alpha, we may need to use multiple global pointer values
|
||||
to span the entire .lita section. In essence, we allow each
|
||||
input .lita section to have its own gp value. To support this,
|
||||
we need to keep track of the gp values that we picked for each
|
||||
input .lita section . */
|
||||
bfd_vma gp;
|
||||
};
|
||||
|
||||
/* An accessor macro for the ecoff_section_tdata structure. */
|
||||
@ -269,8 +284,10 @@ extern boolean _bfd_ecoff_slurp_armap PARAMS ((bfd *abfd));
|
||||
#define _bfd_ecoff_truncate_arname bfd_dont_truncate_arname
|
||||
extern boolean _bfd_ecoff_write_armap
|
||||
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int));
|
||||
#define _bfd_ecoff_read_ar_hdr _bfd_generic_read_ar_hdr
|
||||
#define _bfd_ecoff_openr_next_archived_file \
|
||||
bfd_generic_openr_next_archived_file
|
||||
#define _bfd_ecoff_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define _bfd_ecoff_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define _bfd_ecoff_update_armap_timestamp bfd_true
|
||||
|
||||
|
@ -1455,6 +1455,7 @@ oasys_sizeof_headers (abfd, exec)
|
||||
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \
|
||||
bfd_true)
|
||||
#define oasys_read_ar_hdr bfd_nullvoidptr
|
||||
#define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define oasys_update_armap_timestamp bfd_true
|
||||
|
||||
#define oasys_bfd_is_local_label bfd_generic_is_local_label
|
||||
@ -1483,8 +1484,8 @@ const bfd_target oasys_vec =
|
||||
{
|
||||
"oasys", /* name */
|
||||
bfd_target_oasys_flavour,
|
||||
true, /* target byte order */
|
||||
true, /* target headers byte order */
|
||||
BFD_ENDIAN_BIG, /* target byte order */
|
||||
BFD_ENDIAN_BIG, /* target headers byte order */
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
|
||||
|
68
bfd/opncls.c
68
bfd/opncls.c
@ -40,6 +40,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#define obstack_chunk_alloc malloc
|
||||
#define obstack_chunk_free free
|
||||
|
||||
#ifndef HAVE_GETPAGESIZE
|
||||
#define getpagesize() 2048
|
||||
#endif
|
||||
|
||||
long _bfd_chunksize = -1;
|
||||
|
||||
/* Return a new BFD. All BFD's are allocated through this routine. */
|
||||
|
||||
bfd *
|
||||
@ -49,12 +55,20 @@ _bfd_new_bfd ()
|
||||
|
||||
nbfd = (bfd *)bfd_zmalloc (sizeof (bfd));
|
||||
if (!nbfd)
|
||||
return 0;
|
||||
|
||||
if (_bfd_chunksize <= 0)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return 0;
|
||||
_bfd_chunksize = getpagesize ();
|
||||
if (_bfd_chunksize <= 0)
|
||||
_bfd_chunksize = 2048;
|
||||
/* Leave some slush space, since many malloc implementations
|
||||
prepend a header, and may wind up wasting another page
|
||||
because of it. */
|
||||
_bfd_chunksize -= 32;
|
||||
}
|
||||
|
||||
if (!obstack_begin(&nbfd->memory, 128))
|
||||
if (!obstack_begin(&nbfd->memory, _bfd_chunksize))
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return 0;
|
||||
@ -129,10 +143,8 @@ bfd_openr (filename, target)
|
||||
const bfd_target *target_vec;
|
||||
|
||||
nbfd = _bfd_new_bfd();
|
||||
if (nbfd == NULL) {
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
if (nbfd == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL) {
|
||||
@ -197,7 +209,6 @@ bfd_fdopenr (filename, target, fd)
|
||||
int fdflags;
|
||||
|
||||
bfd_set_error (bfd_error_system_call);
|
||||
|
||||
#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
|
||||
fdflags = O_RDWR; /* Assume full access */
|
||||
#else
|
||||
@ -207,24 +218,22 @@ bfd_fdopenr (filename, target, fd)
|
||||
|
||||
nbfd = _bfd_new_bfd();
|
||||
|
||||
if (nbfd == NULL) {
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
if (nbfd == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL) {
|
||||
bfd_set_error (bfd_error_invalid_target);
|
||||
return NULL;
|
||||
}
|
||||
#if defined(VMS) || defined(__GO32__) || defined (WIN32)
|
||||
nbfd->iostream = (char *)fopen(filename, FOPEN_RB);
|
||||
#if defined(VMS) || defined(__GO32__) || defined (WINGDB)
|
||||
nbfd->iostream = (PTR)fopen(filename, FOPEN_RB);
|
||||
#else
|
||||
/* (O_ACCMODE) parens are to avoid Ultrix header file bug */
|
||||
switch (fdflags & (O_ACCMODE)) {
|
||||
case O_RDONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RB); break;
|
||||
case O_WRONLY: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
|
||||
case O_RDWR: nbfd->iostream = (char *) fdopen (fd, FOPEN_RUB); break;
|
||||
case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB); break;
|
||||
case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
|
||||
case O_RDWR: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB); break;
|
||||
default: abort ();
|
||||
}
|
||||
#endif
|
||||
@ -278,10 +287,7 @@ bfd_openstreamr (filename, target, stream)
|
||||
|
||||
nbfd = _bfd_new_bfd ();
|
||||
if (nbfd == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL)
|
||||
@ -290,7 +296,7 @@ bfd_openstreamr (filename, target, stream)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nbfd->iostream = (char *) stream;
|
||||
nbfd->iostream = (PTR) stream;
|
||||
nbfd->filename = filename;
|
||||
nbfd->direction = read_direction;
|
||||
|
||||
@ -334,10 +340,8 @@ bfd_openw (filename, target)
|
||||
reclaim it correctly. */
|
||||
|
||||
nbfd = _bfd_new_bfd();
|
||||
if (nbfd == NULL) {
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
if (nbfd == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target_vec = bfd_find_target (target, nbfd);
|
||||
if (target_vec == NULL) return NULL;
|
||||
@ -521,10 +525,8 @@ bfd_create (filename, templ)
|
||||
bfd *templ;
|
||||
{
|
||||
bfd *nbfd = _bfd_new_bfd();
|
||||
if (nbfd == (bfd *)NULL) {
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
if (nbfd == (bfd *)NULL)
|
||||
return (bfd *)NULL;
|
||||
}
|
||||
nbfd->filename = filename;
|
||||
if(templ) {
|
||||
nbfd->xvec = templ->xvec;
|
||||
@ -552,7 +554,12 @@ bfd_alloc_by_size_t (abfd, size)
|
||||
bfd *abfd;
|
||||
size_t size;
|
||||
{
|
||||
return obstack_alloc(&(abfd->memory), size);
|
||||
PTR ret;
|
||||
|
||||
ret = obstack_alloc (&(abfd->memory), size);
|
||||
if (ret == NULL)
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
@ -568,7 +575,12 @@ PTR
|
||||
bfd_alloc_finish (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
return obstack_finish(&(abfd->memory));
|
||||
PTR ret;
|
||||
|
||||
ret = obstack_finish (&(abfd->memory));
|
||||
if (ret == NULL)
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return ret;
|
||||
}
|
||||
|
||||
PTR
|
||||
|
@ -349,7 +349,7 @@ riscix_swap_std_reloc_out (abfd, g, natptr)
|
||||
}
|
||||
|
||||
/* now the fun stuff */
|
||||
if (abfd->xvec->header_byteorder_big_p != false)
|
||||
if (bfd_header_big_endian (abfd))
|
||||
{
|
||||
natptr->r_index[0] = r_index >> 16;
|
||||
natptr->r_index[1] = r_index >> 8;
|
||||
@ -580,7 +580,8 @@ riscix_some_aout_object_p (abfd, execp, callback_to_real_object_p)
|
||||
*/
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if (abfd->iostream
|
||||
if (abfd->iostream != NULL
|
||||
&& (abfd->flags & BFD_IN_MEMORY) == 0
|
||||
&& (fstat(fileno((FILE *) (abfd->iostream)), &stat_buf) == 0)
|
||||
&& ((stat_buf.st_mode & 0111) != 0))
|
||||
abfd->flags |= EXEC_P;
|
||||
|
@ -5846,6 +5846,7 @@ som_bfd_link_split_section (abfd, sec)
|
||||
|
||||
#define som_read_ar_hdr _bfd_generic_read_ar_hdr
|
||||
#define som_openr_next_archived_file bfd_generic_openr_next_archived_file
|
||||
#define som_get_elt_at_index _bfd_generic_get_elt_at_index
|
||||
#define som_generic_stat_arch_elt bfd_generic_stat_arch_elt
|
||||
#define som_truncate_arname bfd_bsd_truncate_arname
|
||||
#define som_slurp_extended_name_table _bfd_slurp_extended_name_table
|
||||
@ -5871,8 +5872,8 @@ const bfd_target som_vec =
|
||||
{
|
||||
"som", /* name */
|
||||
bfd_target_som_flavour,
|
||||
true, /* target byte order */
|
||||
true, /* target headers byte order */
|
||||
BFD_ENDIAN_BIG, /* target byte order */
|
||||
BFD_ENDIAN_BIG, /* target headers byte order */
|
||||
(HAS_RELOC | EXEC_P | /* object flags */
|
||||
HAS_LINENO | HAS_DEBUG |
|
||||
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
|
||||
|
@ -311,6 +311,7 @@ The general target vector.
|
||||
.CAT(NAME,_write_armap),\
|
||||
.CAT(NAME,_read_ar_hdr),\
|
||||
.CAT(NAME,_openr_next_archived_file),\
|
||||
.CAT(NAME,_get_elt_at_index),\
|
||||
.CAT(NAME,_generic_stat_arch_elt),\
|
||||
.CAT(NAME,_update_armap_timestamp)
|
||||
. boolean (*_bfd_slurp_armap) PARAMS ((bfd *));
|
||||
@ -325,6 +326,8 @@ The general target vector.
|
||||
. int stridx));
|
||||
. PTR (*_bfd_read_ar_hdr_fn) PARAMS ((bfd *));
|
||||
. bfd * (*openr_next_archived_file) PARAMS ((bfd *arch, bfd *prev));
|
||||
.#define bfd_get_elt_at_index(b,i) BFD_SEND(b, _bfd_get_elt_at_index, (b,i))
|
||||
. bfd * (*_bfd_get_elt_at_index) PARAMS ((bfd *, symindex));
|
||||
. int (*_bfd_stat_arch_elt) PARAMS ((bfd *, struct stat *));
|
||||
. boolean (*_bfd_update_armap_timestamp) PARAMS ((bfd *));
|
||||
.
|
||||
|
Loading…
Reference in New Issue
Block a user