aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog80
-rw-r--r--bfd/aout-target.h18
-rw-r--r--bfd/aoutx.h36
-rw-r--r--bfd/archive.c54
-rw-r--r--bfd/bfd-in.h17
-rw-r--r--bfd/bfd-in2.h35
-rw-r--r--bfd/bfd.c10
-rw-r--r--bfd/cache.c296
-rw-r--r--bfd/coff-alpha.c360
-rw-r--r--bfd/coff-mips.c26
-rw-r--r--bfd/coff-rs6000.c8
-rw-r--r--bfd/libbfd-in.h35
-rw-r--r--bfd/libbfd.c104
-rw-r--r--bfd/libbfd.h35
-rw-r--r--bfd/libecoff.h17
-rw-r--r--bfd/oasys.c5
-rw-r--r--bfd/opncls.c68
-rw-r--r--bfd/riscix.c5
-rw-r--r--bfd/som.c5
-rw-r--r--bfd/targets.c3
20 files changed, 911 insertions, 306 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0f3acac..cf31ee0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/aout-target.h b/bfd/aout-target.h
index 3813826..c66e433 100644
--- a/bfd/aout-target.h
+++ b/bfd/aout-target.h
@@ -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 |
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 8e30f54..b8389fe 100644
--- a/bfd/aoutx.h
+++ b/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;
diff --git a/bfd/archive.c b/bfd/archive.c
index fba52a6..50f5be7 100644
--- a/bfd/archive.c
+++ b/bfd/archive.c
@@ -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
-
-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.).
+/* Return the BFD which is referenced by the symbol in ABFD indexed by
+ INDEX. INDEX should have been returned by bfd_get_next_mapent. */
-*/
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);
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 7713760..858daa8 100644
--- a/bfd/bfd-in.h
+++ b/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)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4ff9c9d..d5821fc 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.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)
@@ -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? */
@@ -2119,9 +2132,6 @@ 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));
CONST char *
@@ -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 *));
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 3fa0e08..c565bf8 100644
--- a/bfd/bfd.c
+++ b/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;
diff --git a/bfd/cache.c b/bfd/cache.c
index c6b968a..f965bdc 100644
--- a/bfd/cache.c
+++ b/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. */
+/*
+INTERNAL_FUNCTION
+ bfd_cache_init
+
+SYNOPSIS
+ boolean bfd_cache_init (bfd *abfd);
+
+DESCRIPTION
+ Add a newly opened BFD to the cache.
+*/
-void
-DEFUN(bfd_cache_init,(abfd),
- bfd *abfd)
+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;
+ }
+
+ 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;
}
- break;
- }
- if (abfd->iostream) {
- bfd_cache_init (abfd);
- }
+ if (abfd->iostream != NULL)
+ {
+ if (! bfd_cache_init (abfd))
+ return NULL;
+ }
- return (FILE *)(abfd->iostream);
+ 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
- {
-
- if (open_files >= BFD_CACHE_MAX_OPEN)
- {
- close_one();
- }
+ }
+ else
+ {
+ if (bfd_open_file (abfd) == NULL)
+ return NULL;
+ if (fseek ((FILE *) abfd->iostream, abfd->where, SEEK_SET) != 0)
+ return NULL;
+ }
- 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;
}
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
index 4ad7077..1bbec4c 100644
--- a/bfd/coff-alpha.c
+++ b/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;
+ /* 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. . */
+
+ lita_sec = symndx_to_section[RELOC_SECTION_LITA];
gp = ecoff_data (output_bfd)->gp;
- if (gp == 0)
- gp_undefined = true;
- else
- gp_undefined = false;
+ 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 (output_bfd->xvec->header_byteorder_big_p == false);
- BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p == false);
+ 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),
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
index 51a5ecd..bab8beb 100644
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -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 |
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index ba27ebe..c07981b 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -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 |
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index dd68b8a..2a35b5b 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.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 *));
diff --git a/bfd/libbfd.c b/bfd/libbfd.c
index 4bd8f58..cd8f896 100644
--- a/bfd/libbfd.c
+++ b/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 */
+PTR
+bfd_malloc (size)
+ size_t size;
+{
+ PTR ptr;
-char *
+ 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)
- bfd_size_type size;
+ size_t size;
{
- char *ptr = (char *) malloc ((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);
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index e86f355..dc22c64 100644
--- a/bfd/libbfd.h
+++ b/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 *));
diff --git a/bfd/libecoff.h b/bfd/libecoff.h
index e8af957..939e813 100644
--- a/bfd/libecoff.h
+++ b/bfd/libecoff.h
@@ -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
diff --git a/bfd/oasys.c b/bfd/oasys.c
index 71dee97..b72b5ef 100644
--- a/bfd/oasys.c
+++ b/bfd/oasys.c
@@ -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),
diff --git a/bfd/opncls.c b/bfd/opncls.c
index bfb3415..6117d87 100644
--- a/bfd/opncls.c
+++ b/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
diff --git a/bfd/riscix.c b/bfd/riscix.c
index 8489859..192ebff 100644
--- a/bfd/riscix.c
+++ b/bfd/riscix.c
@@ -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;
diff --git a/bfd/som.c b/bfd/som.c
index 3cc3979..59d07fc 100644
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -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),
diff --git a/bfd/targets.c b/bfd/targets.c
index 32f27f3..24a0963 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -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 *));
.