|
|
|
@ -496,6 +496,55 @@ static reloc_howto_type xcoff_howto_table[] = |
|
|
|
false) /* pcrel_offset */ |
|
|
|
}; |
|
|
|
|
|
|
|
/* These are the first two like the above but for 16-bit relocs. */ |
|
|
|
static reloc_howto_type xcoff_howto_table_16[] = |
|
|
|
{ |
|
|
|
/* Standard 16 bit relocation. */ |
|
|
|
HOWTO (0, /* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
16, /* bitsize */ |
|
|
|
false, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
complain_overflow_bitfield, /* complain_on_overflow */ |
|
|
|
0, /* special_function */ |
|
|
|
"R_POS_16", /* name */ |
|
|
|
true, /* partial_inplace */ |
|
|
|
0xffffffff, /* src_mask */ |
|
|
|
0xffffffff, /* dst_mask */ |
|
|
|
false), /* pcrel_offset */ |
|
|
|
|
|
|
|
/* 16 bit relocation, but store negative value. */ |
|
|
|
HOWTO (1, /* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
-2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
16, /* bitsize */ |
|
|
|
false, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
complain_overflow_bitfield, /* complain_on_overflow */ |
|
|
|
0, /* special_function */ |
|
|
|
"R_NEG_16", /* name */ |
|
|
|
true, /* partial_inplace */ |
|
|
|
0xffffffff, /* src_mask */ |
|
|
|
0xffffffff, /* dst_mask */ |
|
|
|
false), /* pcrel_offset */ |
|
|
|
|
|
|
|
/* 16 bit PC relative relocation. */ |
|
|
|
HOWTO (2, /* type */ |
|
|
|
0, /* rightshift */ |
|
|
|
2, /* size (0 = byte, 1 = short, 2 = long) */ |
|
|
|
32, /* bitsize */ |
|
|
|
true, /* pc_relative */ |
|
|
|
0, /* bitpos */ |
|
|
|
complain_overflow_signed, /* complain_on_overflow */ |
|
|
|
0, /* special_function */ |
|
|
|
"R_REL_16", /* name */ |
|
|
|
true, /* partial_inplace */ |
|
|
|
0xffffffff, /* src_mask */ |
|
|
|
0xffffffff, /* dst_mask */ |
|
|
|
false), /* pcrel_offset */ |
|
|
|
}; |
|
|
|
|
|
|
|
static void |
|
|
|
xcoff_rtype2howto (relent, internal) |
|
|
|
arelent *relent; |
|
|
|
@ -503,6 +552,11 @@ xcoff_rtype2howto (relent, internal) |
|
|
|
{ |
|
|
|
relent->howto = xcoff_howto_table + internal->r_type; |
|
|
|
|
|
|
|
if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1 |
|
|
|
&& (internal->r_type |
|
|
|
< sizeof(xcoff_howto_table_16)/sizeof(xcoff_howto_table_16[0]))) |
|
|
|
relent->howto = xcoff_howto_table_16 + internal->r_type; |
|
|
|
|
|
|
|
/* The r_size field of an XCOFF reloc encodes the bitsize of the
|
|
|
|
relocation, as well as indicating whether it is signed or not. |
|
|
|
Doublecheck that the relocation information gathered from the |
|
|
|
@ -591,11 +645,24 @@ xcoff_reloc_type_lookup (abfd, code) |
|
|
|
binary number which is the number of entries. This is followed by |
|
|
|
a that many four byte binary numbers; each is the file offset of an |
|
|
|
entry in the archive. These numbers are followed by a series of |
|
|
|
null terminated strings, which are symbol names. */ |
|
|
|
null terminated strings, which are symbol names. |
|
|
|
|
|
|
|
AIX 4.3 introduced a new archive format which can handle larger |
|
|
|
files and also 32- and 64-bit objects in the same archive. The |
|
|
|
things said above remain true except that there is now more than |
|
|
|
one global symbol table. The one is used to index 32-bit objects, |
|
|
|
the other for 64-bit objects. |
|
|
|
|
|
|
|
The new archives (recognizable by the new ARMAG string) has larger |
|
|
|
field lengths so that we cannot really share any code. Also we have |
|
|
|
to take care that we are not generating the new form of archives |
|
|
|
on AIX 4.2 or earlier systems. */ |
|
|
|
|
|
|
|
/* XCOFF archives use this as a magic string. */ |
|
|
|
/* XCOFF archives use this as a magic string. Note that both strings
|
|
|
|
have the same length. */ |
|
|
|
|
|
|
|
#define XCOFFARMAG "<aiaff>\012" |
|
|
|
#define XCOFFARMAGBIG "<bigaf>\012" |
|
|
|
#define SXCOFFARMAG 8 |
|
|
|
|
|
|
|
/* This terminates an XCOFF archive member name. */ |
|
|
|
@ -629,6 +696,38 @@ struct xcoff_ar_file_hdr |
|
|
|
|
|
|
|
#define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG) |
|
|
|
|
|
|
|
/* This is the equivalent data structure for the big archive format. */ |
|
|
|
|
|
|
|
struct xcoff_ar_file_hdr_big |
|
|
|
{ |
|
|
|
/* Magic string. */ |
|
|
|
char magic[SXCOFFARMAG]; |
|
|
|
|
|
|
|
/* Offset of the member table (decimal ASCII string). */ |
|
|
|
char memoff[20]; |
|
|
|
|
|
|
|
/* Offset of the global symbol table for 32-bit objects (decimal ASCII
|
|
|
|
string). */ |
|
|
|
char symoff[20]; |
|
|
|
|
|
|
|
/* Offset of the global symbol table for 64-bit objects (decimal ASCII
|
|
|
|
string). */ |
|
|
|
char symoff64[20]; |
|
|
|
|
|
|
|
/* Offset of the first member in the archive (decimal ASCII string). */ |
|
|
|
char firstmemoff[20]; |
|
|
|
|
|
|
|
/* Offset of the last member in the archive (decimal ASCII string). */ |
|
|
|
char lastmemoff[20]; |
|
|
|
|
|
|
|
/* Offset of the first member on the free list (decimal ASCII
|
|
|
|
string). */ |
|
|
|
char freeoff[20]; |
|
|
|
}; |
|
|
|
|
|
|
|
#define SIZEOF_AR_FILE_HDR_BIG (6 * 20 + SXCOFFARMAG) |
|
|
|
|
|
|
|
|
|
|
|
/* Each XCOFF archive member starts with this (printable) structure. */ |
|
|
|
|
|
|
|
struct xcoff_ar_hdr |
|
|
|
@ -667,16 +766,65 @@ struct xcoff_ar_hdr |
|
|
|
|
|
|
|
#define SIZEOF_AR_HDR (7 * 12 + 4) |
|
|
|
|
|
|
|
/* The equivalent for the big archive format. */ |
|
|
|
|
|
|
|
struct xcoff_ar_hdr_big |
|
|
|
{ |
|
|
|
/* File size not including the header (decimal ASCII string). */ |
|
|
|
char size[20]; |
|
|
|
|
|
|
|
/* File offset of next archive member (decimal ASCII string). */ |
|
|
|
char nextoff[20]; |
|
|
|
|
|
|
|
/* File offset of previous archive member (decimal ASCII string). */ |
|
|
|
char prevoff[20]; |
|
|
|
|
|
|
|
/* File mtime (decimal ASCII string). */ |
|
|
|
char date[12]; |
|
|
|
|
|
|
|
/* File UID (decimal ASCII string). */ |
|
|
|
char uid[12]; |
|
|
|
|
|
|
|
/* File GID (decimal ASCII string). */ |
|
|
|
char gid[12]; |
|
|
|
|
|
|
|
/* File mode (octal ASCII string). */ |
|
|
|
char mode[12]; |
|
|
|
|
|
|
|
/* Length of file name (decimal ASCII string). */ |
|
|
|
char namlen[4]; |
|
|
|
|
|
|
|
/* This structure is followed by the file name. The length of the
|
|
|
|
name is given in the namlen field. If the length of the name is |
|
|
|
odd, the name is followed by a null byte. The name and optional |
|
|
|
null byte are followed by XCOFFARFMAG, which is not included in |
|
|
|
namlen. The contents of the archive member follow; the number of |
|
|
|
bytes is given in the size field. */ |
|
|
|
}; |
|
|
|
|
|
|
|
#define SIZEOF_AR_HDR_BIG (3 * 20 + 4 * 12 + 4) |
|
|
|
|
|
|
|
|
|
|
|
/* We often have to distinguish between the old and big file format.
|
|
|
|
Make it a bit cleaner. We can use `xcoff_ardata' here because the |
|
|
|
`hdr' member has the same size and position in both formats. */ |
|
|
|
#define xcoff_big_format_p(abfd) \ |
|
|
|
(xcoff_ardata (abfd)->magic[1] == 'b') |
|
|
|
|
|
|
|
/* We store a copy of the xcoff_ar_file_hdr in the tdata field of the
|
|
|
|
artdata structure. */ |
|
|
|
artdata structure. Similar for the big archive. */ |
|
|
|
#define xcoff_ardata(abfd) \ |
|
|
|
((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata) |
|
|
|
#define xcoff_ardata_big(abfd) \ |
|
|
|
((struct xcoff_ar_file_hdr_big *) bfd_ardata (abfd)->tdata) |
|
|
|
|
|
|
|
/* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
|
|
|
|
archive element. */ |
|
|
|
archive element. Similar for the big archive. */ |
|
|
|
#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data)) |
|
|
|
#define arch_xhdr(bfd) \ |
|
|
|
((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header) |
|
|
|
#define arch_xhdr_big(bfd) \ |
|
|
|
((struct xcoff_ar_hdr_big *) arch_eltdata (bfd)->arch_header) |
|
|
|
|
|
|
|
/* XCOFF archives do not have anything which corresponds to an
|
|
|
|
extended name table. */ |
|
|
|
@ -702,7 +850,6 @@ xcoff_slurp_armap (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
file_ptr off; |
|
|
|
struct xcoff_ar_hdr hdr; |
|
|
|
size_t namlen; |
|
|
|
bfd_size_type sz; |
|
|
|
bfd_byte *contents, *cend; |
|
|
|
@ -716,6 +863,11 @@ xcoff_slurp_armap (abfd) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (! xcoff_big_format_p (abfd)) |
|
|
|
{ |
|
|
|
/* This is for the old format. */ |
|
|
|
struct xcoff_ar_hdr hdr; |
|
|
|
|
|
|
|
off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10); |
|
|
|
if (off == 0) |
|
|
|
{ |
|
|
|
@ -735,8 +887,40 @@ xcoff_slurp_armap (abfd) |
|
|
|
if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0) |
|
|
|
return false; |
|
|
|
|
|
|
|
/* Read in the entire symbol table. */ |
|
|
|
sz = strtol (hdr.size, (char **) NULL, 10); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
/* This is for the new format. */ |
|
|
|
struct xcoff_ar_hdr_big hdr; |
|
|
|
|
|
|
|
off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10); |
|
|
|
if (off == 0) |
|
|
|
{ |
|
|
|
bfd_has_map (abfd) = false; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
if (bfd_seek (abfd, off, SEEK_SET) != 0) |
|
|
|
return false; |
|
|
|
|
|
|
|
/* The symbol table starts with a normal archive header. */ |
|
|
|
if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) |
|
|
|
!= SIZEOF_AR_HDR_BIG) |
|
|
|
return false; |
|
|
|
|
|
|
|
/* Skip the name (normally empty). */ |
|
|
|
namlen = strtol (hdr.namlen, (char **) NULL, 10); |
|
|
|
if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0) |
|
|
|
return false; |
|
|
|
|
|
|
|
/* XXX This actually has to be a call to strtoll (at least on 32-bit
|
|
|
|
machines) since the field width is 20 and there numbers with more |
|
|
|
than 32 bits can be represented. */ |
|
|
|
sz = strtol (hdr.size, (char **) NULL, 10); |
|
|
|
} |
|
|
|
|
|
|
|
/* Read in the entire symbol table. */ |
|
|
|
contents = (bfd_byte *) bfd_alloc (abfd, sz); |
|
|
|
if (contents == NULL) |
|
|
|
return false; |
|
|
|
@ -789,17 +973,17 @@ static const bfd_target * |
|
|
|
xcoff_archive_p (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
struct xcoff_ar_file_hdr hdr; |
|
|
|
char magic[SXCOFFARMAG]; |
|
|
|
|
|
|
|
if (bfd_read ((PTR) &hdr, SIZEOF_AR_FILE_HDR, 1, abfd) |
|
|
|
!= SIZEOF_AR_FILE_HDR) |
|
|
|
if (bfd_read ((PTR) magic, SXCOFFARMAG, 1, abfd) != SXCOFFARMAG) |
|
|
|
{ |
|
|
|
if (bfd_get_error () != bfd_error_system_call) |
|
|
|
bfd_set_error (bfd_error_wrong_format); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (strncmp (hdr.magic, XCOFFARMAG, SXCOFFARMAG) != 0) |
|
|
|
if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0 |
|
|
|
&& strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0) |
|
|
|
{ |
|
|
|
bfd_set_error (bfd_error_wrong_format); |
|
|
|
return NULL; |
|
|
|
@ -814,18 +998,67 @@ xcoff_archive_p (abfd) |
|
|
|
if (bfd_ardata (abfd) == (struct artdata *) NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, |
|
|
|
(char **) NULL, 10); |
|
|
|
bfd_ardata (abfd)->cache = NULL; |
|
|
|
bfd_ardata (abfd)->archive_head = NULL; |
|
|
|
bfd_ardata (abfd)->symdefs = NULL; |
|
|
|
bfd_ardata (abfd)->extended_names = NULL; |
|
|
|
|
|
|
|
/* Now handle the two formats. */ |
|
|
|
if (magic[1] != 'b') |
|
|
|
{ |
|
|
|
/* This is the old format. */ |
|
|
|
struct xcoff_ar_file_hdr hdr; |
|
|
|
|
|
|
|
/* Copy over the magic string. */ |
|
|
|
memcpy (hdr.magic, magic, SXCOFFARMAG); |
|
|
|
|
|
|
|
/* Now read the rest of the file header. */ |
|
|
|
if (bfd_read ((PTR) &hdr.memoff, SIZEOF_AR_FILE_HDR - SXCOFFARMAG, 1, |
|
|
|
abfd) != SIZEOF_AR_FILE_HDR - SXCOFFARMAG) |
|
|
|
{ |
|
|
|
if (bfd_get_error () != bfd_error_system_call) |
|
|
|
bfd_set_error (bfd_error_wrong_format); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, |
|
|
|
(char **) NULL, 10); |
|
|
|
|
|
|
|
bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR); |
|
|
|
if (bfd_ardata (abfd)->tdata == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
/* This is the new format. */ |
|
|
|
struct xcoff_ar_file_hdr_big hdr; |
|
|
|
|
|
|
|
/* Copy over the magic string. */ |
|
|
|
memcpy (hdr.magic, magic, SXCOFFARMAG); |
|
|
|
|
|
|
|
/* Now read the rest of the file header. */ |
|
|
|
if (bfd_read ((PTR) &hdr.memoff, SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG, 1, |
|
|
|
abfd) != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG) |
|
|
|
{ |
|
|
|
if (bfd_get_error () != bfd_error_system_call) |
|
|
|
bfd_set_error (bfd_error_wrong_format); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
/* XXX This actually has to be a call to strtoll (at least on 32-bit
|
|
|
|
machines) since the field width is 20 and there numbers with more |
|
|
|
than 32 bits can be represented. */ |
|
|
|
bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, |
|
|
|
(char **) NULL, 10); |
|
|
|
|
|
|
|
bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR_BIG); |
|
|
|
if (bfd_ardata (abfd)->tdata == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG); |
|
|
|
} |
|
|
|
|
|
|
|
if (! xcoff_slurp_armap (abfd)) |
|
|
|
{ |
|
|
|
@ -843,29 +1076,80 @@ static PTR |
|
|
|
xcoff_read_ar_hdr (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
struct xcoff_ar_hdr hdr; |
|
|
|
size_t namlen; |
|
|
|
struct xcoff_ar_hdr *hdrp; |
|
|
|
struct areltdata *ret; |
|
|
|
|
|
|
|
ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata)); |
|
|
|
if (ret == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
if (! xcoff_big_format_p (abfd)) |
|
|
|
{ |
|
|
|
struct xcoff_ar_hdr hdr; |
|
|
|
struct xcoff_ar_hdr *hdrp; |
|
|
|
|
|
|
|
if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR) |
|
|
|
{ |
|
|
|
free (ret); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
namlen = strtol (hdr.namlen, (char **) NULL, 10); |
|
|
|
hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1); |
|
|
|
hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, |
|
|
|
SIZEOF_AR_HDR + namlen + 1); |
|
|
|
if (hdrp == NULL) |
|
|
|
{ |
|
|
|
free (ret); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
memcpy (hdrp, &hdr, SIZEOF_AR_HDR); |
|
|
|
if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen) |
|
|
|
{ |
|
|
|
free (ret); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0'; |
|
|
|
|
|
|
|
ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata)); |
|
|
|
if (ret == NULL) |
|
|
|
return NULL; |
|
|
|
ret->arch_header = (char *) hdrp; |
|
|
|
ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); |
|
|
|
ret->filename = (char *) hdrp + SIZEOF_AR_HDR; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
struct xcoff_ar_hdr_big hdr; |
|
|
|
struct xcoff_ar_hdr_big *hdrp; |
|
|
|
|
|
|
|
if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) |
|
|
|
!= SIZEOF_AR_HDR_BIG) |
|
|
|
{ |
|
|
|
free (ret); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
namlen = strtol (hdr.namlen, (char **) NULL, 10); |
|
|
|
hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, |
|
|
|
SIZEOF_AR_HDR_BIG |
|
|
|
+ namlen + 1); |
|
|
|
if (hdrp == NULL) |
|
|
|
{ |
|
|
|
free (ret); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG); |
|
|
|
if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR_BIG, 1, namlen, abfd) != namlen) |
|
|
|
{ |
|
|
|
free (ret); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0'; |
|
|
|
|
|
|
|
ret->arch_header = (char *) hdrp; |
|
|
|
/* XXX This actually has to be a call to strtoll (at least on 32-bit
|
|
|
|
machines) since the field width is 20 and there numbers with more |
|
|
|
than 32 bits can be represented. */ |
|
|
|
ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); |
|
|
|
ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG; |
|
|
|
} |
|
|
|
|
|
|
|
/* Skip over the XCOFFARFMAG at the end of the file name. */ |
|
|
|
if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0) |
|
|
|
@ -889,10 +1173,13 @@ xcoff_openr_next_archived_file (archive, last_file) |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (! xcoff_big_format_p (archive)) |
|
|
|
{ |
|
|
|
if (last_file == NULL) |
|
|
|
filestart = bfd_ardata (archive)->first_file_filepos; |
|
|
|
else |
|
|
|
filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10); |
|
|
|
filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, |
|
|
|
10); |
|
|
|
|
|
|
|
if (filestart == 0 |
|
|
|
|| filestart == strtol (xcoff_ardata (archive)->memoff, |
|
|
|
@ -903,6 +1190,31 @@ xcoff_openr_next_archived_file (archive, last_file) |
|
|
|
bfd_set_error (bfd_error_no_more_archived_files); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (last_file == NULL) |
|
|
|
filestart = bfd_ardata (archive)->first_file_filepos; |
|
|
|
else |
|
|
|
/* XXX These actually have to be a calls to strtoll (at least
|
|
|
|
on 32-bit machines) since the fields's width is 20 and |
|
|
|
there numbers with more than 32 bits can be represented. */ |
|
|
|
filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL, |
|
|
|
10); |
|
|
|
|
|
|
|
/* XXX These actually have to be calls to strtoll (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with more |
|
|
|
than 32 bits can be represented. */ |
|
|
|
if (filestart == 0 |
|
|
|
|| filestart == strtol (xcoff_ardata_big (archive)->memoff, |
|
|
|
(char **) NULL, 10) |
|
|
|
|| filestart == strtol (xcoff_ardata_big (archive)->symoff, |
|
|
|
(char **) NULL, 10)) |
|
|
|
{ |
|
|
|
bfd_set_error (bfd_error_no_more_archived_files); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return _bfd_get_elt_at_filepos (archive, filestart); |
|
|
|
} |
|
|
|
@ -914,21 +1226,32 @@ xcoff_generic_stat_arch_elt (abfd, s) |
|
|
|
bfd *abfd; |
|
|
|
struct stat *s; |
|
|
|
{ |
|
|
|
struct xcoff_ar_hdr *hdrp; |
|
|
|
|
|
|
|
if (abfd->arelt_data == NULL) |
|
|
|
{ |
|
|
|
bfd_set_error (bfd_error_invalid_operation); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
hdrp = arch_xhdr (abfd); |
|
|
|
if (! xcoff_big_format_p (abfd)) |
|
|
|
{ |
|
|
|
struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd); |
|
|
|
|
|
|
|
s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); |
|
|
|
s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); |
|
|
|
s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); |
|
|
|
s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); |
|
|
|
s->st_size = arch_eltdata (abfd)->parsed_size; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd); |
|
|
|
|
|
|
|
s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); |
|
|
|
s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); |
|
|
|
s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); |
|
|
|
s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); |
|
|
|
s->st_size = arch_eltdata (abfd)->parsed_size; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
@ -955,7 +1278,7 @@ normalize_filename (abfd) |
|
|
|
|
|
|
|
/*ARGSUSED*/ |
|
|
|
static boolean |
|
|
|
xcoff_write_armap (abfd, elength, map, orl_count, stridx) |
|
|
|
xcoff_write_armap_old (abfd, elength, map, orl_count, stridx) |
|
|
|
bfd *abfd; |
|
|
|
unsigned int elength ATTRIBUTE_UNUSED; |
|
|
|
struct orl *map; |
|
|
|
@ -1039,28 +1362,132 @@ xcoff_write_armap (abfd, elength, map, orl_count, stridx) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/* Write out an XCOFF archive. We always write an entire archive,
|
|
|
|
rather than fussing with the freelist and so forth. */ |
|
|
|
|
|
|
|
/*ARGSUSED*/ |
|
|
|
static boolean |
|
|
|
xcoff_write_archive_contents (abfd) |
|
|
|
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx) |
|
|
|
bfd *abfd; |
|
|
|
unsigned int elength ATTRIBUTE_UNUSED; |
|
|
|
struct orl *map; |
|
|
|
unsigned int orl_count; |
|
|
|
int stridx; |
|
|
|
{ |
|
|
|
struct xcoff_ar_file_hdr fhdr; |
|
|
|
size_t count; |
|
|
|
size_t total_namlen; |
|
|
|
file_ptr *offsets; |
|
|
|
boolean makemap; |
|
|
|
boolean hasobjects; |
|
|
|
file_ptr prevoff, nextoff; |
|
|
|
struct xcoff_ar_hdr_big hdr; |
|
|
|
char *p; |
|
|
|
unsigned char buf[4]; |
|
|
|
bfd *sub; |
|
|
|
file_ptr fileoff; |
|
|
|
unsigned int i; |
|
|
|
struct xcoff_ar_hdr ahdr; |
|
|
|
bfd_size_type size; |
|
|
|
char *p; |
|
|
|
char decbuf[13]; |
|
|
|
|
|
|
|
memset (&fhdr, 0, sizeof fhdr); |
|
|
|
memset (&hdr, 0, sizeof hdr); |
|
|
|
/* XXX This call actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx)); |
|
|
|
sprintf (hdr.nextoff, "%d", 0); |
|
|
|
memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12); |
|
|
|
sprintf (hdr.date, "%d", 0); |
|
|
|
sprintf (hdr.uid, "%d", 0); |
|
|
|
sprintf (hdr.gid, "%d", 0); |
|
|
|
sprintf (hdr.mode, "%d", 0); |
|
|
|
sprintf (hdr.namlen, "%d", 0); |
|
|
|
|
|
|
|
/* We need spaces, not null bytes, in the header. */ |
|
|
|
for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR_BIG; p++) |
|
|
|
if (*p == '\0') |
|
|
|
*p = ' '; |
|
|
|
|
|
|
|
if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) != SIZEOF_AR_HDR_BIG |
|
|
|
|| bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG) |
|
|
|
return false; |
|
|
|
|
|
|
|
bfd_h_put_32 (abfd, orl_count, buf); |
|
|
|
if (bfd_write (buf, 1, 4, abfd) != 4) |
|
|
|
return false; |
|
|
|
|
|
|
|
sub = abfd->archive_head; |
|
|
|
fileoff = SIZEOF_AR_FILE_HDR_BIG; |
|
|
|
i = 0; |
|
|
|
while (sub != NULL && i < orl_count) |
|
|
|
{ |
|
|
|
size_t namlen; |
|
|
|
|
|
|
|
while (((bfd *) (map[i]).pos) == sub) |
|
|
|
{ |
|
|
|
bfd_h_put_32 (abfd, fileoff, buf); |
|
|
|
if (bfd_write (buf, 1, 4, abfd) != 4) |
|
|
|
return false; |
|
|
|
++i; |
|
|
|
} |
|
|
|
namlen = strlen (normalize_filename (sub)); |
|
|
|
namlen = (namlen + 1) &~ 1; |
|
|
|
fileoff += (SIZEOF_AR_HDR_BIG |
|
|
|
+ namlen |
|
|
|
+ SXCOFFARFMAG |
|
|
|
+ arelt_size (sub)); |
|
|
|
fileoff = (fileoff + 1) &~ 1; |
|
|
|
sub = sub->next; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i < orl_count; i++) |
|
|
|
{ |
|
|
|
const char *name; |
|
|
|
size_t namlen; |
|
|
|
|
|
|
|
name = *map[i].name; |
|
|
|
namlen = strlen (name); |
|
|
|
if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if ((stridx & 1) != 0) |
|
|
|
{ |
|
|
|
char b; |
|
|
|
|
|
|
|
b = '\0'; |
|
|
|
if (bfd_write (&b, 1, 1, abfd) != 1) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/*ARGSUSED*/ |
|
|
|
static boolean |
|
|
|
xcoff_write_armap (abfd, elength, map, orl_count, stridx) |
|
|
|
bfd *abfd; |
|
|
|
unsigned int elength ATTRIBUTE_UNUSED; |
|
|
|
struct orl *map; |
|
|
|
unsigned int orl_count; |
|
|
|
int stridx; |
|
|
|
{ |
|
|
|
if (! xcoff_big_format_p (abfd)) |
|
|
|
return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx); |
|
|
|
else |
|
|
|
return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx); |
|
|
|
} |
|
|
|
|
|
|
|
/* Write out an XCOFF archive. We always write an entire archive,
|
|
|
|
rather than fussing with the freelist and so forth. */ |
|
|
|
|
|
|
|
static boolean |
|
|
|
xcoff_write_archive_contents_old (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
struct xcoff_ar_file_hdr fhdr; |
|
|
|
size_t count; |
|
|
|
size_t total_namlen; |
|
|
|
file_ptr *offsets; |
|
|
|
boolean makemap; |
|
|
|
boolean hasobjects; |
|
|
|
file_ptr prevoff, nextoff; |
|
|
|
bfd *sub; |
|
|
|
unsigned int i; |
|
|
|
struct xcoff_ar_hdr ahdr; |
|
|
|
bfd_size_type size; |
|
|
|
char *p; |
|
|
|
char decbuf[13]; |
|
|
|
|
|
|
|
memset (&fhdr, 0, sizeof fhdr); |
|
|
|
strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG); |
|
|
|
sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR); |
|
|
|
sprintf (fhdr.freeoff, "%d", 0); |
|
|
|
@ -1286,6 +1713,285 @@ xcoff_write_archive_contents (abfd) |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static boolean |
|
|
|
xcoff_write_archive_contents_big (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
struct xcoff_ar_file_hdr_big fhdr; |
|
|
|
size_t count; |
|
|
|
size_t total_namlen; |
|
|
|
file_ptr *offsets; |
|
|
|
boolean makemap; |
|
|
|
boolean hasobjects; |
|
|
|
file_ptr prevoff, nextoff; |
|
|
|
bfd *sub; |
|
|
|
unsigned int i; |
|
|
|
struct xcoff_ar_hdr_big ahdr; |
|
|
|
bfd_size_type size; |
|
|
|
char *p; |
|
|
|
char decbuf[13]; |
|
|
|
|
|
|
|
memset (&fhdr, 0, sizeof fhdr); |
|
|
|
strncpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG); |
|
|
|
sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR_BIG); |
|
|
|
sprintf (fhdr.freeoff, "%d", 0); |
|
|
|
|
|
|
|
count = 0; |
|
|
|
total_namlen = 0; |
|
|
|
for (sub = abfd->archive_head; sub != NULL; sub = sub->next) |
|
|
|
{ |
|
|
|
++count; |
|
|
|
total_namlen += strlen (normalize_filename (sub)) + 1; |
|
|
|
} |
|
|
|
offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr)); |
|
|
|
if (offsets == NULL) |
|
|
|
return false; |
|
|
|
|
|
|
|
if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0) |
|
|
|
return false; |
|
|
|
|
|
|
|
makemap = bfd_has_map (abfd); |
|
|
|
hasobjects = false; |
|
|
|
prevoff = 0; |
|
|
|
nextoff = SIZEOF_AR_FILE_HDR_BIG; |
|
|
|
for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++) |
|
|
|
{ |
|
|
|
const char *name; |
|
|
|
size_t namlen; |
|
|
|
struct xcoff_ar_hdr_big *ahdrp; |
|
|
|
bfd_size_type remaining; |
|
|
|
|
|
|
|
if (makemap && ! hasobjects) |
|
|
|
{ |
|
|
|
if (bfd_check_format (sub, bfd_object)) |
|
|
|
hasobjects = true; |
|
|
|
} |
|
|
|
|
|
|
|
name = normalize_filename (sub); |
|
|
|
namlen = strlen (name); |
|
|
|
|
|
|
|
if (sub->arelt_data != NULL) |
|
|
|
ahdrp = arch_xhdr_big (sub); |
|
|
|
else |
|
|
|
ahdrp = NULL; |
|
|
|
|
|
|
|
if (ahdrp == NULL) |
|
|
|
{ |
|
|
|
struct stat s; |
|
|
|
|
|
|
|
memset (&ahdr, 0, sizeof ahdr); |
|
|
|
ahdrp = &ahdr; |
|
|
|
/* XXX This should actually be a call to stat64 (at least on
|
|
|
|
32-bit machines). */ |
|
|
|
if (stat (bfd_get_filename (sub), &s) != 0) |
|
|
|
{ |
|
|
|
bfd_set_error (bfd_error_system_call); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/* XXX This call actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (ahdrp->size, "%ld", (long) s.st_size); |
|
|
|
sprintf (ahdrp->date, "%ld", (long) s.st_mtime); |
|
|
|
sprintf (ahdrp->uid, "%ld", (long) s.st_uid); |
|
|
|
sprintf (ahdrp->gid, "%ld", (long) s.st_gid); |
|
|
|
sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode); |
|
|
|
|
|
|
|
if (sub->arelt_data == NULL) |
|
|
|
{ |
|
|
|
sub->arelt_data = bfd_alloc (sub, sizeof (struct areltdata)); |
|
|
|
if (sub->arelt_data == NULL) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
arch_eltdata (sub)->parsed_size = s.st_size; |
|
|
|
} |
|
|
|
|
|
|
|
/* XXX These calls actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (ahdrp->prevoff, "%ld", (long) prevoff); |
|
|
|
sprintf (ahdrp->namlen, "%ld", (long) namlen); |
|
|
|
|
|
|
|
/* If the length of the name is odd, we write out the null byte
|
|
|
|
after the name as well. */ |
|
|
|
namlen = (namlen + 1) &~ 1; |
|
|
|
|
|
|
|
remaining = arelt_size (sub); |
|
|
|
size = (SIZEOF_AR_HDR_BIG |
|
|
|
+ namlen |
|
|
|
+ SXCOFFARFMAG |
|
|
|
+ remaining); |
|
|
|
|
|
|
|
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
|
|
|
|
|
|
|
offsets[i] = nextoff; |
|
|
|
|
|
|
|
prevoff = nextoff; |
|
|
|
nextoff += size + (size & 1); |
|
|
|
|
|
|
|
sprintf (ahdrp->nextoff, "%ld", (long) nextoff); |
|
|
|
|
|
|
|
/* We need spaces, not null bytes, in the header. */ |
|
|
|
for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR_BIG; p++) |
|
|
|
if (*p == '\0') |
|
|
|
*p = ' '; |
|
|
|
|
|
|
|
if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR_BIG, abfd) |
|
|
|
!= SIZEOF_AR_HDR_BIG |
|
|
|
|| bfd_write ((PTR) name, 1, namlen, abfd) != namlen |
|
|
|
|| (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) |
|
|
|
!= SXCOFFARFMAG)) |
|
|
|
return false; |
|
|
|
|
|
|
|
if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0) |
|
|
|
return false; |
|
|
|
while (remaining != 0) |
|
|
|
{ |
|
|
|
bfd_size_type amt; |
|
|
|
bfd_byte buffer[DEFAULT_BUFFERSIZE]; |
|
|
|
|
|
|
|
amt = sizeof buffer; |
|
|
|
if (amt > remaining) |
|
|
|
amt = remaining; |
|
|
|
if (bfd_read (buffer, 1, amt, sub) != amt |
|
|
|
|| bfd_write (buffer, 1, amt, abfd) != amt) |
|
|
|
return false; |
|
|
|
remaining -= amt; |
|
|
|
} |
|
|
|
|
|
|
|
if ((size & 1) != 0) |
|
|
|
{ |
|
|
|
bfd_byte b; |
|
|
|
|
|
|
|
b = '\0'; |
|
|
|
if (bfd_write (&b, 1, 1, abfd) != 1) |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* XXX This call actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (fhdr.lastmemoff, "%ld", (long) prevoff); |
|
|
|
|
|
|
|
/* Write out the member table. */ |
|
|
|
|
|
|
|
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
|
|
|
/* XXX This call actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (fhdr.memoff, "%ld", (long) nextoff); |
|
|
|
|
|
|
|
memset (&ahdr, 0, sizeof ahdr); |
|
|
|
/* XXX The next two calls actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen)); |
|
|
|
sprintf (ahdr.prevoff, "%ld", (long) prevoff); |
|
|
|
sprintf (ahdr.date, "%d", 0); |
|
|
|
sprintf (ahdr.uid, "%d", 0); |
|
|
|
sprintf (ahdr.gid, "%d", 0); |
|
|
|
sprintf (ahdr.mode, "%d", 0); |
|
|
|
sprintf (ahdr.namlen, "%d", 0); |
|
|
|
|
|
|
|
size = (SIZEOF_AR_HDR_BIG |
|
|
|
+ 12 |
|
|
|
+ count * 12 |
|
|
|
+ total_namlen |
|
|
|
+ SXCOFFARFMAG); |
|
|
|
|
|
|
|
prevoff = nextoff; |
|
|
|
nextoff += size + (size & 1); |
|
|
|
|
|
|
|
if (makemap && hasobjects) |
|
|
|
/* XXX This call actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (ahdr.nextoff, "%ld", (long) nextoff); |
|
|
|
else |
|
|
|
sprintf (ahdr.nextoff, "%d", 0); |
|
|
|
|
|
|
|
/* We need spaces, not null bytes, in the header. */ |
|
|
|
for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR_BIG; p++) |
|
|
|
if (*p == '\0') |
|
|
|
*p = ' '; |
|
|
|
|
|
|
|
if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG |
|
|
|
|| (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) |
|
|
|
!= SXCOFFARFMAG)) |
|
|
|
return false; |
|
|
|
|
|
|
|
sprintf (decbuf, "%-12ld", (long) count); |
|
|
|
if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12) |
|
|
|
return false; |
|
|
|
for (i = 0; i < count; i++) |
|
|
|
{ |
|
|
|
sprintf (decbuf, "%-12ld", (long) offsets[i]); |
|
|
|
if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12) |
|
|
|
return false; |
|
|
|
} |
|
|
|
for (sub = abfd->archive_head; sub != NULL; sub = sub->next) |
|
|
|
{ |
|
|
|
const char *name; |
|
|
|
size_t namlen; |
|
|
|
|
|
|
|
name = normalize_filename (sub); |
|
|
|
namlen = strlen (name); |
|
|
|
if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1) |
|
|
|
return false; |
|
|
|
} |
|
|
|
if ((size & 1) != 0) |
|
|
|
{ |
|
|
|
bfd_byte b; |
|
|
|
|
|
|
|
b = '\0'; |
|
|
|
if (bfd_write ((PTR) &b, 1, 1, abfd) != 1) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/* Write out the armap, if appropriate. */ |
|
|
|
|
|
|
|
if (! makemap || ! hasobjects) |
|
|
|
sprintf (fhdr.symoff, "%d", 0); |
|
|
|
else |
|
|
|
{ |
|
|
|
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
|
|
|
/* XXX This call actually should use %lld (at least on 32-bit
|
|
|
|
machines) since the fields's width is 20 and there numbers with |
|
|
|
more than 32 bits can be represented. */ |
|
|
|
sprintf (fhdr.symoff, "%ld", (long) nextoff); |
|
|
|
bfd_ardata (abfd)->tdata = (PTR) &fhdr; |
|
|
|
if (! _bfd_compute_and_write_armap (abfd, 0)) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/* Write out the archive file header. */ |
|
|
|
|
|
|
|
/* We need spaces, not null bytes, in the header. */ |
|
|
|
for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR_BIG; p++) |
|
|
|
if (*p == '\0') |
|
|
|
*p = ' '; |
|
|
|
|
|
|
|
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 |
|
|
|
|| (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR_BIG, 1, abfd) != |
|
|
|
SIZEOF_AR_FILE_HDR_BIG)) |
|
|
|
return false; |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static boolean |
|
|
|
xcoff_write_archive_contents (abfd) |
|
|
|
bfd *abfd; |
|
|
|
{ |
|
|
|
if (! xcoff_big_format_p (abfd)) |
|
|
|
return xcoff_write_archive_contents_old (abfd); |
|
|
|
else |
|
|
|
return xcoff_write_archive_contents_big (abfd); |
|
|
|
} |
|
|
|
|
|
|
|
/* We can't use the usual coff_sizeof_headers routine, because AIX
|
|
|
|
always uses an a.out header. */ |
|
|
|
|