Line 1... |
Line 1... |
/* BFD back-end for IBM RS/6000 "XCOFF" files.
|
/* BFD back-end for IBM RS/6000 "XCOFF" files.
|
Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
Free Software Foundation, Inc.
|
2008, 2009 Free Software Foundation, Inc.
|
Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.
|
Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.
|
Archive support from Damon A. Permezel.
|
Archive support from Damon A. Permezel.
|
Contributed by IBM Corporation and Cygnus Support.
|
Contributed by IBM Corporation and Cygnus Support.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
Line 126... |
Line 126... |
#define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
|
#define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
|
#define coff_swap_reloc_in xcoff_swap_reloc_in
|
#define coff_swap_reloc_in xcoff_swap_reloc_in
|
#define coff_swap_reloc_out xcoff_swap_reloc_out
|
#define coff_swap_reloc_out xcoff_swap_reloc_out
|
#define NO_COFF_RELOCS
|
#define NO_COFF_RELOCS
|
|
|
|
#ifndef bfd_pe_print_pdata
|
|
#define bfd_pe_print_pdata NULL
|
|
#endif
|
|
|
#include "coffcode.h"
|
#include "coffcode.h"
|
|
|
/* The main body of code is in coffcode.h. */
|
/* The main body of code is in coffcode.h. */
|
|
|
static const char *normalize_filename
|
static const char *normalize_filename
|
Line 174... |
Line 178... |
PARAMS ((bfd *, const char *, const char *, bfd_boolean));
|
PARAMS ((bfd *, const char *, const char *, bfd_boolean));
|
static bfd_boolean do_pad
|
static bfd_boolean do_pad
|
PARAMS ((bfd *, unsigned int));
|
PARAMS ((bfd *, unsigned int));
|
static bfd_boolean do_copy
|
static bfd_boolean do_copy
|
PARAMS ((bfd *, bfd *));
|
PARAMS ((bfd *, bfd *));
|
static bfd_boolean do_shared_object_padding
|
|
PARAMS ((bfd *, bfd *, file_ptr *, int));
|
|
|
|
/* Relocation functions */
|
/* Relocation functions */
|
static bfd_boolean xcoff_reloc_type_br
|
static bfd_boolean xcoff_reloc_type_br
|
PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
|
PARAMS ((XCOFF_RELOC_FUNCTION_ARGS));
|
|
|
Line 232... |
Line 234... |
xcoff_complain_overflow_bitfield_func,
|
xcoff_complain_overflow_bitfield_func,
|
xcoff_complain_overflow_signed_func,
|
xcoff_complain_overflow_signed_func,
|
xcoff_complain_overflow_unsigned_func,
|
xcoff_complain_overflow_unsigned_func,
|
};
|
};
|
|
|
|
/* Information about one member of an archive. */
|
|
struct member_layout {
|
|
/* The archive member that this structure describes. */
|
|
bfd *member;
|
|
|
|
/* The number of bytes of padding that must be inserted before the
|
|
start of the member in order to ensure that the section contents
|
|
are correctly aligned. */
|
|
unsigned int leading_padding;
|
|
|
|
/* The offset of MEMBER from the start of the archive (i.e. the end
|
|
of the leading padding). */
|
|
file_ptr offset;
|
|
|
|
/* The normalized name of MEMBER. */
|
|
const char *name;
|
|
|
|
/* The length of NAME, without padding. */
|
|
bfd_size_type namlen;
|
|
|
|
/* The length of NAME, with padding. */
|
|
bfd_size_type padded_namlen;
|
|
|
|
/* The size of MEMBER's header, including the name and magic sequence. */
|
|
bfd_size_type header_size;
|
|
|
|
/* The size of the MEMBER's contents. */
|
|
bfd_size_type contents_size;
|
|
|
|
/* The number of bytes of padding that must be inserted after MEMBER
|
|
in order to preserve even alignment. */
|
|
bfd_size_type trailing_padding;
|
|
};
|
|
|
|
/* A structure used for iterating over the members of an archive. */
|
|
struct archive_iterator {
|
|
/* The archive itself. */
|
|
bfd *archive;
|
|
|
|
/* Information about the current archive member. */
|
|
struct member_layout current;
|
|
|
|
/* Information about the next archive member. MEMBER is null if there
|
|
are no more archive members, in which case OFFSET is the offset of
|
|
the first unused byte. */
|
|
struct member_layout next;
|
|
};
|
|
|
|
/* Initialize INFO so that it describes member MEMBER of archive ARCHIVE.
|
|
OFFSET is the even-padded offset of MEMBER, not including any leading
|
|
padding needed for section alignment. */
|
|
|
|
static void
|
|
member_layout_init (struct member_layout *info, bfd *archive,
|
|
bfd *member, file_ptr offset)
|
|
{
|
|
info->member = member;
|
|
info->leading_padding = 0;
|
|
if (member)
|
|
{
|
|
info->name = normalize_filename (member);
|
|
info->namlen = strlen (info->name);
|
|
info->padded_namlen = info->namlen + (info->namlen & 1);
|
|
if (xcoff_big_format_p (archive))
|
|
info->header_size = SIZEOF_AR_HDR_BIG;
|
|
else
|
|
info->header_size = SIZEOF_AR_HDR;
|
|
info->header_size += info->padded_namlen + SXCOFFARFMAG;
|
|
info->contents_size = arelt_size (member);
|
|
info->trailing_padding = info->contents_size & 1;
|
|
|
|
if (bfd_check_format (member, bfd_object)
|
|
&& bfd_get_flavour (member) == bfd_target_xcoff_flavour
|
|
&& (member->flags & DYNAMIC) != 0)
|
|
info->leading_padding
|
|
= (-(offset + info->header_size)
|
|
& ((1 << bfd_xcoff_text_align_power (member)) - 1));
|
|
}
|
|
info->offset = offset + info->leading_padding;
|
|
}
|
|
|
|
/* Set up ITERATOR to iterate through archive ARCHIVE. */
|
|
|
|
static void
|
|
archive_iterator_begin (struct archive_iterator *iterator,
|
|
bfd *archive)
|
|
{
|
|
iterator->archive = archive;
|
|
member_layout_init (&iterator->next, archive, archive->archive_head,
|
|
xcoff_big_format_p (archive)
|
|
? SIZEOF_AR_FILE_HDR_BIG
|
|
: SIZEOF_AR_FILE_HDR);
|
|
}
|
|
|
|
/* Make ITERATOR visit the first unvisited archive member. Return true
|
|
on success; return false if all members have been visited. */
|
|
|
|
static bfd_boolean
|
|
archive_iterator_next (struct archive_iterator *iterator)
|
|
{
|
|
if (!iterator->next.member)
|
|
return FALSE;
|
|
|
|
iterator->current = iterator->next;
|
|
member_layout_init (&iterator->next, iterator->archive,
|
|
iterator->current.member->archive_next,
|
|
iterator->current.offset
|
|
+ iterator->current.header_size
|
|
+ iterator->current.contents_size
|
|
+ iterator->current.trailing_padding);
|
|
return TRUE;
|
|
}
|
|
|
/* We use our own tdata type. Its first field is the COFF tdata type,
|
/* We use our own tdata type. Its first field is the COFF tdata type,
|
so the COFF routines are compatible. */
|
so the COFF routines are compatible. */
|
|
|
bfd_boolean
|
bfd_boolean
|
_bfd_xcoff_mkobject (abfd)
|
_bfd_xcoff_mkobject (abfd)
|
Line 378... |
Line 493... |
H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
|
H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
|
return bfd_coff_symesz (abfd);
|
return bfd_coff_symesz (abfd);
|
}
|
}
|
|
|
void
|
void
|
_bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
|
_bfd_xcoff_swap_aux_in (abfd, ext1, type, in_class, indx, numaux, in1)
|
bfd *abfd;
|
bfd *abfd;
|
PTR ext1;
|
PTR ext1;
|
int type;
|
int type;
|
int class;
|
int in_class;
|
int indx;
|
int indx;
|
int numaux;
|
int numaux;
|
PTR in1;
|
PTR in1;
|
{
|
{
|
AUXENT * ext = (AUXENT *)ext1;
|
AUXENT * ext = (AUXENT *)ext1;
|
union internal_auxent *in = (union internal_auxent *)in1;
|
union internal_auxent *in = (union internal_auxent *)in1;
|
|
|
switch (class)
|
switch (in_class)
|
{
|
{
|
case C_FILE:
|
case C_FILE:
|
if (ext->x_file.x_fname[0] == 0)
|
if (ext->x_file.x_fname[0] == 0)
|
{
|
{
|
in->x_file.x_n.x_zeroes = 0;
|
in->x_file.x_n.x_zeroes = 0;
|
Line 416... |
Line 531... |
}
|
}
|
goto end;
|
goto end;
|
|
|
/* RS/6000 "csect" auxents */
|
/* RS/6000 "csect" auxents */
|
case C_EXT:
|
case C_EXT:
|
|
case C_AIX_WEAKEXT:
|
case C_HIDEXT:
|
case C_HIDEXT:
|
if (indx + 1 == numaux)
|
if (indx + 1 == numaux)
|
{
|
{
|
in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
|
in->x_csect.x_scnlen.l = H_GET_32 (abfd, ext->x_csect.x_scnlen);
|
in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
|
in->x_csect.x_parmhash = H_GET_32 (abfd, ext->x_csect.x_parmhash);
|
Line 455... |
Line 571... |
}
|
}
|
|
|
in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
|
in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx);
|
in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
|
in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
|
in->x_sym.x_fcnary.x_fcn.x_lnnoptr =
|
H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
|
H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
|
in->x_sym.x_fcnary.x_fcn.x_endndx.l =
|
in->x_sym.x_fcnary.x_fcn.x_endndx.l =
|
H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
|
H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx);
|
Line 496... |
Line 613... |
|
|
unsigned int _bfd_xcoff_swap_aux_out
|
unsigned int _bfd_xcoff_swap_aux_out
|
PARAMS ((bfd *, PTR, int, int, int, int, PTR));
|
PARAMS ((bfd *, PTR, int, int, int, int, PTR));
|
|
|
unsigned int
|
unsigned int
|
_bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
|
_bfd_xcoff_swap_aux_out (abfd, inp, type, in_class, indx, numaux, extp)
|
bfd * abfd;
|
bfd * abfd;
|
PTR inp;
|
PTR inp;
|
int type;
|
int type;
|
int class;
|
int in_class;
|
int indx ATTRIBUTE_UNUSED;
|
int indx ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
int numaux ATTRIBUTE_UNUSED;
|
PTR extp;
|
PTR extp;
|
{
|
{
|
union internal_auxent *in = (union internal_auxent *)inp;
|
union internal_auxent *in = (union internal_auxent *)inp;
|
AUXENT *ext = (AUXENT *)extp;
|
AUXENT *ext = (AUXENT *)extp;
|
|
|
memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
|
memset ((PTR)ext, 0, bfd_coff_auxesz (abfd));
|
switch (class)
|
switch (in_class)
|
{
|
{
|
case C_FILE:
|
case C_FILE:
|
if (in->x_file.x_fname[0] == 0)
|
if (in->x_file.x_fname[0] == 0)
|
{
|
{
|
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
|
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
|
Line 525... |
Line 642... |
}
|
}
|
goto end;
|
goto end;
|
|
|
/* RS/6000 "csect" auxents */
|
/* RS/6000 "csect" auxents */
|
case C_EXT:
|
case C_EXT:
|
|
case C_AIX_WEAKEXT:
|
case C_HIDEXT:
|
case C_HIDEXT:
|
if (indx + 1 == numaux)
|
if (indx + 1 == numaux)
|
{
|
{
|
H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
|
H_PUT_32 (abfd, in->x_csect.x_scnlen.l, ext->x_csect.x_scnlen);
|
H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
|
H_PUT_32 (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
|
Line 558... |
Line 676... |
}
|
}
|
|
|
H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
|
H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx);
|
H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
|
H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
|
|
|
if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
|
if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
|
|
|| ISTAG (in_class))
|
{
|
{
|
H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
|
H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
|
ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
|
ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
|
H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
|
H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
|
ext->x_sym.x_fcnary.x_fcn.x_endndx);
|
ext->x_sym.x_fcnary.x_fcn.x_endndx);
|
Line 775... |
Line 894... |
0xffff, /* dst_mask */
|
0xffff, /* dst_mask */
|
FALSE), /* pcrel_offset */
|
FALSE), /* pcrel_offset */
|
|
|
EMPTY_HOWTO (0xe),
|
EMPTY_HOWTO (0xe),
|
|
|
/* Non-relocating reference. */
|
/* Non-relocating reference. Bitsize is 1 so that r_rsize is 0. */
|
HOWTO (R_REF, /* type */
|
HOWTO (R_REF, /* type */
|
0, /* rightshift */
|
0, /* rightshift */
|
2, /* size (0 = byte, 1 = short, 2 = long) */
|
0, /* size (0 = byte, 1 = short, 2 = long) */
|
32, /* bitsize */
|
1, /* bitsize */
|
FALSE, /* pc_relative */
|
FALSE, /* pc_relative */
|
0, /* bitpos */
|
0, /* bitpos */
|
complain_overflow_dont, /* complain_on_overflow */
|
complain_overflow_dont, /* complain_on_overflow */
|
0, /* special_function */
|
0, /* special_function */
|
"R_REF", /* name */
|
"R_REF", /* name */
|
Line 1041... |
Line 1160... |
case BFD_RELOC_PPC_TOC16:
|
case BFD_RELOC_PPC_TOC16:
|
return &xcoff_howto_table[3];
|
return &xcoff_howto_table[3];
|
case BFD_RELOC_32:
|
case BFD_RELOC_32:
|
case BFD_RELOC_CTOR:
|
case BFD_RELOC_CTOR:
|
return &xcoff_howto_table[0];
|
return &xcoff_howto_table[0];
|
|
case BFD_RELOC_NONE:
|
|
return &xcoff_howto_table[0xf];
|
default:
|
default:
|
return NULL;
|
return NULL;
|
}
|
}
|
}
|
}
|
|
|
Line 1595... |
Line 1716... |
unsigned int elength ATTRIBUTE_UNUSED;
|
unsigned int elength ATTRIBUTE_UNUSED;
|
struct orl *map;
|
struct orl *map;
|
unsigned int orl_count;
|
unsigned int orl_count;
|
int stridx;
|
int stridx;
|
{
|
{
|
|
struct archive_iterator iterator;
|
struct xcoff_ar_hdr hdr;
|
struct xcoff_ar_hdr hdr;
|
char *p;
|
char *p;
|
unsigned char buf[4];
|
unsigned char buf[4];
|
bfd *sub;
|
|
file_ptr fileoff;
|
|
unsigned int i;
|
unsigned int i;
|
|
|
memset (&hdr, 0, sizeof hdr);
|
memset (&hdr, 0, sizeof hdr);
|
sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
|
sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
|
sprintf (hdr.nextoff, "%d", 0);
|
sprintf (hdr.nextoff, "%d", 0);
|
Line 1627... |
Line 1747... |
|
|
H_PUT_32 (abfd, orl_count, buf);
|
H_PUT_32 (abfd, orl_count, buf);
|
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
|
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
|
return FALSE;
|
return FALSE;
|
|
|
sub = abfd->archive_head;
|
|
fileoff = SIZEOF_AR_FILE_HDR;
|
|
i = 0;
|
i = 0;
|
while (sub != NULL && i < orl_count)
|
archive_iterator_begin (&iterator, abfd);
|
{
|
while (i < orl_count && archive_iterator_next (&iterator))
|
size_t namlen;
|
while (map[i].u.abfd == iterator.current.member)
|
|
|
while (map[i].u.abfd == sub)
|
|
{
|
{
|
H_PUT_32 (abfd, fileoff, buf);
|
H_PUT_32 (abfd, iterator.current.offset, buf);
|
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
|
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
|
return FALSE;
|
return FALSE;
|
++i;
|
++i;
|
}
|
}
|
namlen = strlen (normalize_filename (sub));
|
|
namlen = (namlen + 1) &~ (size_t) 1;
|
|
fileoff += (SIZEOF_AR_HDR
|
|
+ namlen
|
|
+ SXCOFFARFMAG
|
|
+ arelt_size (sub));
|
|
fileoff = (fileoff + 1) &~ 1;
|
|
sub = sub->archive_next;
|
|
}
|
|
|
|
for (i = 0; i < orl_count; i++)
|
for (i = 0; i < orl_count; i++)
|
{
|
{
|
const char *name;
|
const char *name;
|
size_t namlen;
|
size_t namlen;
|
Line 1751... |
Line 1858... |
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
static bfd_boolean
|
static bfd_boolean
|
do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)
|
|
bfd *out_bfd;
|
|
bfd *in_bfd;
|
|
file_ptr *offset;
|
|
int ar_header_size;
|
|
{
|
|
if (bfd_check_format (in_bfd, bfd_object)
|
|
&& bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour
|
|
&& (in_bfd->flags & DYNAMIC) != 0)
|
|
{
|
|
bfd_size_type pad = 0;
|
|
int text_align_power;
|
|
|
|
text_align_power = bfd_xcoff_text_align_power (in_bfd);
|
|
|
|
pad = 1 << text_align_power;
|
|
pad -= (*offset + ar_header_size) & (pad - 1);
|
|
|
|
if (! do_pad (out_bfd, pad))
|
|
return FALSE;
|
|
|
|
*offset += pad;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static bfd_boolean
|
|
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
|
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
|
bfd *abfd;
|
bfd *abfd;
|
unsigned int elength ATTRIBUTE_UNUSED;
|
unsigned int elength ATTRIBUTE_UNUSED;
|
struct orl *map;
|
struct orl *map;
|
unsigned int orl_count;
|
unsigned int orl_count;
|
int stridx;
|
int stridx;
|
{
|
{
|
|
struct archive_iterator iterator;
|
struct xcoff_ar_file_hdr_big *fhdr;
|
struct xcoff_ar_file_hdr_big *fhdr;
|
bfd_vma i, sym_32, sym_64, str_32, str_64;
|
bfd_vma i, sym_32, sym_64, str_32, str_64;
|
const bfd_arch_info_type *arch_info = NULL;
|
const bfd_arch_info_type *arch_info;
|
bfd *current_bfd;
|
bfd *current_bfd;
|
size_t string_length;
|
size_t string_length;
|
file_ptr nextoff, prevoff;
|
file_ptr nextoff, prevoff;
|
|
|
/* First, we look through the symbols and work out which are
|
/* First, we look through the symbols and work out which are
|
from 32-bit objects and which from 64-bit ones. */
|
from 32-bit objects and which from 64-bit ones. */
|
sym_32 = sym_64 = str_32 = str_64 = 0;
|
sym_32 = sym_64 = str_32 = str_64 = 0;
|
|
|
current_bfd = abfd->archive_head;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
i = 0;
|
i = 0;
|
while (current_bfd != NULL && i < orl_count)
|
for (current_bfd = abfd->archive_head;
|
|
current_bfd != NULL && i < orl_count;
|
|
current_bfd = current_bfd->archive_next)
|
{
|
{
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
while (map[i].u.abfd == current_bfd)
|
while (map[i].u.abfd == current_bfd)
|
{
|
{
|
string_length = strlen (*map[i].name) + 1;
|
string_length = strlen (*map[i].name) + 1;
|
|
|
if (arch_info->bits_per_address == 64)
|
if (arch_info->bits_per_address == 64)
|
{
|
{
|
sym_64++;
|
sym_64++;
|
str_64 += string_length;
|
str_64 += string_length;
|
}
|
}
|
Line 1819... |
Line 1898... |
sym_32++;
|
sym_32++;
|
str_32 += string_length;
|
str_32 += string_length;
|
}
|
}
|
i++;
|
i++;
|
}
|
}
|
current_bfd = current_bfd->archive_next;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
}
|
}
|
|
|
/* A quick sanity check... */
|
/* A quick sanity check... */
|
BFD_ASSERT (sym_64 + sym_32 == orl_count);
|
BFD_ASSERT (sym_64 + sym_32 == orl_count);
|
/* Explicit cast to int for compiler. */
|
/* Explicit cast to int for compiler. */
|
Line 1863... |
Line 1939... |
if (sym_32)
|
if (sym_32)
|
{
|
{
|
struct xcoff_ar_hdr_big *hdr;
|
struct xcoff_ar_hdr_big *hdr;
|
char *symbol_table;
|
char *symbol_table;
|
char *st;
|
char *st;
|
file_ptr fileoff;
|
|
|
|
bfd_vma symbol_table_size =
|
bfd_vma symbol_table_size =
|
SIZEOF_AR_HDR_BIG
|
SIZEOF_AR_HDR_BIG
|
+ SXCOFFARFMAG
|
+ SXCOFFARFMAG
|
+ 8
|
+ 8
|
Line 1900... |
Line 1975... |
|
|
bfd_h_put_64 (abfd, sym_32, st);
|
bfd_h_put_64 (abfd, sym_32, st);
|
st += 8;
|
st += 8;
|
|
|
/* loop over the 32 bit offsets */
|
/* loop over the 32 bit offsets */
|
current_bfd = abfd->archive_head;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
fileoff = SIZEOF_AR_FILE_HDR_BIG;
|
|
i = 0;
|
i = 0;
|
while (current_bfd != NULL && i < orl_count)
|
archive_iterator_begin (&iterator, abfd);
|
|
while (i < orl_count && archive_iterator_next (&iterator))
|
{
|
{
|
while (map[i].u.abfd == current_bfd)
|
arch_info = bfd_get_arch_info (iterator.current.member);
|
|
while (map[i].u.abfd == iterator.current.member)
|
{
|
{
|
if (arch_info->bits_per_address == 32)
|
if (arch_info->bits_per_address == 32)
|
{
|
{
|
bfd_h_put_64 (abfd, fileoff, st);
|
bfd_h_put_64 (abfd, iterator.current.offset, st);
|
st += 8;
|
st += 8;
|
}
|
}
|
i++;
|
i++;
|
}
|
}
|
string_length = strlen (normalize_filename (current_bfd));
|
|
string_length += string_length & 1;
|
|
fileoff += (SIZEOF_AR_HDR_BIG
|
|
+ string_length
|
|
+ SXCOFFARFMAG
|
|
+ arelt_size (current_bfd));
|
|
fileoff += fileoff & 1;
|
|
current_bfd = current_bfd->archive_next;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
}
|
}
|
|
|
/* loop over the 32 bit symbol names */
|
/* loop over the 32 bit symbol names */
|
current_bfd = abfd->archive_head;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
i = 0;
|
i = 0;
|
while (current_bfd != NULL && i < orl_count)
|
for (current_bfd = abfd->archive_head;
|
|
current_bfd != NULL && i < orl_count;
|
|
current_bfd = current_bfd->archive_next)
|
{
|
{
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
while (map[i].u.abfd == current_bfd)
|
while (map[i].u.abfd == current_bfd)
|
{
|
{
|
if (arch_info->bits_per_address == 32)
|
if (arch_info->bits_per_address == 32)
|
{
|
{
|
string_length = sprintf (st, "%s", *map[i].name);
|
string_length = sprintf (st, "%s", *map[i].name);
|
st += string_length + 1;
|
st += string_length + 1;
|
}
|
}
|
i++;
|
i++;
|
}
|
}
|
current_bfd = current_bfd->archive_next;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
}
|
}
|
|
|
bfd_bwrite (symbol_table, symbol_table_size, abfd);
|
bfd_bwrite (symbol_table, symbol_table_size, abfd);
|
|
|
free (symbol_table);
|
free (symbol_table);
|
Line 1964... |
Line 2024... |
if (sym_64)
|
if (sym_64)
|
{
|
{
|
struct xcoff_ar_hdr_big *hdr;
|
struct xcoff_ar_hdr_big *hdr;
|
char *symbol_table;
|
char *symbol_table;
|
char *st;
|
char *st;
|
file_ptr fileoff;
|
|
|
|
bfd_vma symbol_table_size =
|
bfd_vma symbol_table_size =
|
SIZEOF_AR_HDR_BIG
|
SIZEOF_AR_HDR_BIG
|
+ SXCOFFARFMAG
|
+ SXCOFFARFMAG
|
+ 8
|
+ 8
|
Line 1996... |
Line 2055... |
|
|
bfd_h_put_64 (abfd, sym_64, st);
|
bfd_h_put_64 (abfd, sym_64, st);
|
st += 8;
|
st += 8;
|
|
|
/* loop over the 64 bit offsets */
|
/* loop over the 64 bit offsets */
|
current_bfd = abfd->archive_head;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
fileoff = SIZEOF_AR_FILE_HDR_BIG;
|
|
i = 0;
|
i = 0;
|
while (current_bfd != NULL && i < orl_count)
|
archive_iterator_begin (&iterator, abfd);
|
|
while (i < orl_count && archive_iterator_next (&iterator))
|
{
|
{
|
while (map[i].u.abfd == current_bfd)
|
arch_info = bfd_get_arch_info (iterator.current.member);
|
|
while (map[i].u.abfd == iterator.current.member)
|
{
|
{
|
if (arch_info->bits_per_address == 64)
|
if (arch_info->bits_per_address == 64)
|
{
|
{
|
bfd_h_put_64 (abfd, fileoff, st);
|
bfd_h_put_64 (abfd, iterator.current.offset, st);
|
st += 8;
|
st += 8;
|
}
|
}
|
i++;
|
i++;
|
}
|
}
|
string_length = strlen (normalize_filename (current_bfd));
|
|
string_length += string_length & 1;
|
|
fileoff += (SIZEOF_AR_HDR_BIG
|
|
+ string_length
|
|
+ SXCOFFARFMAG
|
|
+ arelt_size (current_bfd));
|
|
fileoff += fileoff & 1;
|
|
current_bfd = current_bfd->archive_next;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
}
|
}
|
|
|
/* loop over the 64 bit symbol names */
|
/* loop over the 64 bit symbol names */
|
current_bfd = abfd->archive_head;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
i = 0;
|
i = 0;
|
while (current_bfd != NULL && i < orl_count)
|
for (current_bfd = abfd->archive_head;
|
|
current_bfd != NULL && i < orl_count;
|
|
current_bfd = current_bfd->archive_next)
|
{
|
{
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
while (map[i].u.abfd == current_bfd)
|
while (map[i].u.abfd == current_bfd)
|
{
|
{
|
if (arch_info->bits_per_address == 64)
|
if (arch_info->bits_per_address == 64)
|
{
|
{
|
string_length = sprintf (st, "%s", *map[i].name);
|
string_length = sprintf (st, "%s", *map[i].name);
|
st += string_length + 1;
|
st += string_length + 1;
|
}
|
}
|
i++;
|
i++;
|
}
|
}
|
current_bfd = current_bfd->archive_next;
|
|
if (current_bfd != NULL)
|
|
arch_info = bfd_get_arch_info (current_bfd);
|
|
}
|
}
|
|
|
bfd_bwrite (symbol_table, symbol_table_size, abfd);
|
bfd_bwrite (symbol_table, symbol_table_size, abfd);
|
|
|
free (symbol_table);
|
free (symbol_table);
|
Line 2078... |
Line 2122... |
|
|
static bfd_boolean
|
static bfd_boolean
|
xcoff_write_archive_contents_old (abfd)
|
xcoff_write_archive_contents_old (abfd)
|
bfd *abfd;
|
bfd *abfd;
|
{
|
{
|
|
struct archive_iterator iterator;
|
struct xcoff_ar_file_hdr fhdr;
|
struct xcoff_ar_file_hdr fhdr;
|
bfd_size_type count;
|
bfd_size_type count;
|
bfd_size_type total_namlen;
|
bfd_size_type total_namlen;
|
file_ptr *offsets;
|
file_ptr *offsets;
|
bfd_boolean makemap;
|
bfd_boolean makemap;
|
Line 2103... |
Line 2148... |
total_namlen = 0;
|
total_namlen = 0;
|
for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
|
for (sub = abfd->archive_head; sub != NULL; sub = sub->archive_next)
|
{
|
{
|
++count;
|
++count;
|
total_namlen += strlen (normalize_filename (sub)) + 1;
|
total_namlen += strlen (normalize_filename (sub)) + 1;
|
}
|
if (sub->arelt_data == NULL)
|
offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
|
|
if (offsets == NULL)
|
|
return FALSE;
|
|
|
|
if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
|
|
return FALSE;
|
|
|
|
makemap = bfd_has_map (abfd);
|
|
hasobjects = FALSE;
|
|
prevoff = 0;
|
|
nextoff = SIZEOF_AR_FILE_HDR;
|
|
for (sub = abfd->archive_head, i = 0;
|
|
sub != NULL;
|
|
sub = sub->archive_next, i++)
|
|
{
|
|
const char *name;
|
|
bfd_size_type namlen;
|
|
struct xcoff_ar_hdr *ahdrp;
|
|
bfd_size_type remaining;
|
|
|
|
if (makemap && ! hasobjects)
|
|
{
|
{
|
if (bfd_check_format (sub, bfd_object))
|
sub->arelt_data = bfd_zalloc (sub, sizeof (struct areltdata));
|
hasobjects = TRUE;
|
if (sub->arelt_data == NULL)
|
|
return FALSE;
|
}
|
}
|
|
if (arch_xhdr (sub) == NULL)
|
name = normalize_filename (sub);
|
|
namlen = strlen (name);
|
|
|
|
if (sub->arelt_data != NULL)
|
|
ahdrp = arch_xhdr (sub);
|
|
else
|
|
ahdrp = NULL;
|
|
|
|
if (ahdrp == NULL)
|
|
{
|
{
|
|
struct xcoff_ar_hdr *ahdrp;
|
struct stat s;
|
struct stat s;
|
|
|
memset (&ahdr, 0, sizeof ahdr);
|
|
ahdrp = &ahdr;
|
|
if (stat (bfd_get_filename (sub), &s) != 0)
|
if (stat (bfd_get_filename (sub), &s) != 0)
|
{
|
{
|
bfd_set_error (bfd_error_system_call);
|
bfd_set_error (bfd_error_system_call);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
|
ahdrp = bfd_zalloc (sub, sizeof (*ahdrp));
|
|
if (ahdrp == NULL)
|
|
return FALSE;
|
|
|
sprintf (ahdrp->size, "%ld", (long) s.st_size);
|
sprintf (ahdrp->size, "%ld", (long) s.st_size);
|
sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
|
sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
|
sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
|
sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
|
sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
|
sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
|
sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
|
sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
|
|
|
if (sub->arelt_data == NULL)
|
arch_eltdata (sub)->arch_header = (char *) ahdrp;
|
{
|
|
size = sizeof (struct areltdata);
|
|
sub->arelt_data = bfd_alloc (sub, size);
|
|
if (sub->arelt_data == NULL)
|
|
return FALSE;
|
|
}
|
|
|
|
arch_eltdata (sub)->parsed_size = s.st_size;
|
arch_eltdata (sub)->parsed_size = s.st_size;
|
}
|
}
|
|
}
|
|
offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
|
|
if (offsets == NULL)
|
|
return FALSE;
|
|
|
sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
|
if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
|
sprintf (ahdrp->namlen, "%ld", (long) namlen);
|
return FALSE;
|
|
|
/* If the length of the name is odd, we write out the null byte
|
|
after the name as well. */
|
|
namlen = (namlen + 1) &~ (bfd_size_type) 1;
|
|
|
|
remaining = arelt_size (sub);
|
|
size = (SIZEOF_AR_HDR
|
|
+ namlen
|
|
+ SXCOFFARFMAG
|
|
+ remaining);
|
|
|
|
BFD_ASSERT (nextoff == bfd_tell (abfd));
|
|
|
|
offsets[i] = nextoff;
|
makemap = bfd_has_map (abfd);
|
|
hasobjects = FALSE;
|
|
prevoff = 0;
|
|
for (archive_iterator_begin (&iterator, abfd), i = 0;
|
|
archive_iterator_next (&iterator);
|
|
i++)
|
|
{
|
|
bfd_size_type namlen;
|
|
struct xcoff_ar_hdr *ahdrp;
|
|
|
prevoff = nextoff;
|
if (makemap && ! hasobjects)
|
nextoff += size + (size & 1);
|
{
|
|
if (bfd_check_format (iterator.current.member, bfd_object))
|
|
hasobjects = TRUE;
|
|
}
|
|
|
sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
|
ahdrp = arch_xhdr (iterator.current.member);
|
|
sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
|
|
sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen);
|
|
sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset);
|
|
|
/* We need spaces, not null bytes, in the header. */
|
/* We need spaces, not null bytes, in the header. */
|
for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
|
for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
|
if (*p == '\0')
|
if (*p == '\0')
|
*p = ' ';
|
*p = ' ';
|
|
|
if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)
|
if (!do_pad (abfd, iterator.current.leading_padding))
|
!= SIZEOF_AR_HDR)
|
|
|| bfd_bwrite ((PTR) name, namlen, abfd) != namlen
|
|
|| bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
|
|
abfd) != SXCOFFARFMAG)
|
|
return FALSE;
|
|
|
|
if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
|
|
return FALSE;
|
return FALSE;
|
|
|
if (! do_copy (abfd, sub))
|
BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
|
|
namlen = iterator.current.padded_namlen;
|
|
if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
|
|
|| bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
|
|
|| bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
|
|
|| bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
|
|
|| !do_copy (abfd, iterator.current.member)
|
|
|| !do_pad (abfd, iterator.current.trailing_padding))
|
return FALSE;
|
return FALSE;
|
|
|
if (! do_pad (abfd, size & 1))
|
offsets[i] = iterator.current.offset;
|
return FALSE;
|
prevoff = iterator.current.offset;
|
}
|
}
|
|
|
sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
|
sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
|
|
|
/* Write out the member table. */
|
/* Write out the member table. */
|
|
|
|
nextoff = iterator.next.offset;
|
BFD_ASSERT (nextoff == bfd_tell (abfd));
|
BFD_ASSERT (nextoff == bfd_tell (abfd));
|
sprintf (fhdr.memoff, "%ld", (long) nextoff);
|
sprintf (fhdr.memoff, "%ld", (long) nextoff);
|
|
|
memset (&ahdr, 0, sizeof ahdr);
|
memset (&ahdr, 0, sizeof ahdr);
|
sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
|
sprintf (ahdr.size, "%ld", (long) (XCOFFARMAG_ELEMENT_SIZE
|
Line 2319... |
Line 2338... |
bfd_boolean makemap;
|
bfd_boolean makemap;
|
bfd_boolean hasobjects;
|
bfd_boolean hasobjects;
|
file_ptr prevoff, nextoff;
|
file_ptr prevoff, nextoff;
|
bfd *current_bfd;
|
bfd *current_bfd;
|
size_t i;
|
size_t i;
|
struct xcoff_ar_hdr_big *hdr, ahdr;
|
struct xcoff_ar_hdr_big *hdr;
|
bfd_size_type size;
|
bfd_size_type size;
|
char *member_table, *mt;
|
char *member_table, *mt;
|
bfd_vma member_table_size;
|
bfd_vma member_table_size;
|
|
struct archive_iterator iterator;
|
|
|
memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
|
memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
|
memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
|
memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
|
|
|
if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
|
if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
|
Line 2343... |
Line 2363... |
|
|
if (makemap
|
if (makemap
|
&& ! hasobjects
|
&& ! hasobjects
|
&& bfd_check_format (current_bfd, bfd_object))
|
&& bfd_check_format (current_bfd, bfd_object))
|
hasobjects = TRUE;
|
hasobjects = TRUE;
|
}
|
|
|
|
offsets = NULL;
|
if (current_bfd->arelt_data == NULL)
|
if (count)
|
|
{
|
{
|
offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
|
size = sizeof (struct areltdata);
|
if (offsets == NULL)
|
current_bfd->arelt_data = bfd_zalloc (current_bfd, size);
|
|
if (current_bfd->arelt_data == NULL)
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
prevoff = 0;
|
if (arch_xhdr_big (current_bfd) == NULL)
|
nextoff = SIZEOF_AR_FILE_HDR_BIG;
|
|
for (current_bfd = abfd->archive_head, i = 0;
|
|
current_bfd != NULL;
|
|
current_bfd = current_bfd->archive_next, i++)
|
|
{
|
{
|
const char *name;
|
|
bfd_size_type namlen;
|
|
struct xcoff_ar_hdr_big *ahdrp;
|
struct xcoff_ar_hdr_big *ahdrp;
|
bfd_size_type remaining;
|
|
|
|
name = normalize_filename (current_bfd);
|
|
namlen = strlen (name);
|
|
|
|
if (current_bfd->arelt_data != NULL)
|
|
ahdrp = arch_xhdr_big (current_bfd);
|
|
else
|
|
ahdrp = NULL;
|
|
|
|
if (ahdrp == NULL)
|
|
{
|
|
struct stat s;
|
struct stat s;
|
|
|
ahdrp = &ahdr;
|
|
/* XXX This should actually be a call to stat64 (at least on
|
/* XXX This should actually be a call to stat64 (at least on
|
32-bit machines).
|
32-bit machines).
|
XXX This call will fail if the original object is not found. */
|
XXX This call will fail if the original object is not found. */
|
if (stat (bfd_get_filename (current_bfd), &s) != 0)
|
if (stat (bfd_get_filename (current_bfd), &s) != 0)
|
{
|
{
|
bfd_set_error (bfd_error_system_call);
|
bfd_set_error (bfd_error_system_call);
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
|
ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp));
|
|
if (ahdrp == NULL)
|
|
return FALSE;
|
|
|
PRINT20 (ahdrp->size, s.st_size);
|
PRINT20 (ahdrp->size, s.st_size);
|
PRINT12 (ahdrp->date, s.st_mtime);
|
PRINT12 (ahdrp->date, s.st_mtime);
|
PRINT12 (ahdrp->uid, s.st_uid);
|
PRINT12 (ahdrp->uid, s.st_uid);
|
PRINT12 (ahdrp->gid, s.st_gid);
|
PRINT12 (ahdrp->gid, s.st_gid);
|
PRINT12_OCTAL (ahdrp->mode, s.st_mode);
|
PRINT12_OCTAL (ahdrp->mode, s.st_mode);
|
|
|
if (current_bfd->arelt_data == NULL)
|
arch_eltdata (current_bfd)->arch_header = (char *) ahdrp;
|
{
|
|
size = sizeof (struct areltdata);
|
|
current_bfd->arelt_data = bfd_alloc (current_bfd, size);
|
|
if (current_bfd->arelt_data == NULL)
|
|
return FALSE;
|
|
}
|
|
|
|
arch_eltdata (current_bfd)->parsed_size = s.st_size;
|
arch_eltdata (current_bfd)->parsed_size = s.st_size;
|
}
|
}
|
|
}
|
|
|
PRINT20 (ahdrp->prevoff, prevoff);
|
offsets = NULL;
|
PRINT4 (ahdrp->namlen, namlen);
|
if (count)
|
|
{
|
/* If the length of the name is odd, we write out the null byte
|
offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
|
after the name as well. */
|
if (offsets == NULL)
|
namlen = (namlen + 1) &~ (bfd_size_type) 1;
|
|
|
|
remaining = arelt_size (current_bfd);
|
|
size = (SIZEOF_AR_HDR_BIG
|
|
+ namlen
|
|
+ SXCOFFARFMAG
|
|
+ remaining);
|
|
|
|
BFD_ASSERT (nextoff == bfd_tell (abfd));
|
|
|
|
/* Check for xcoff shared objects.
|
|
Their text section needs to be aligned wrt the archive file position.
|
|
This requires extra padding before the archive header. */
|
|
if (! do_shared_object_padding (abfd, current_bfd, & nextoff,
|
|
SIZEOF_AR_HDR_BIG + namlen
|
|
+ SXCOFFARFMAG))
|
|
return FALSE;
|
return FALSE;
|
|
}
|
|
|
offsets[i] = nextoff;
|
prevoff = 0;
|
|
for (archive_iterator_begin (&iterator, abfd), i = 0;
|
prevoff = nextoff;
|
archive_iterator_next (&iterator);
|
nextoff += size + (size & 1);
|
i++)
|
|
{
|
PRINT20 (ahdrp->nextoff, nextoff);
|
bfd_size_type namlen;
|
|
struct xcoff_ar_hdr_big *ahdrp;
|
|
|
if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)
|
ahdrp = arch_xhdr_big (iterator.current.member);
|
!= SIZEOF_AR_HDR_BIG)
|
PRINT20 (ahdrp->prevoff, prevoff);
|
|| bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen
|
PRINT4 (ahdrp->namlen, iterator.current.namlen);
|
|| (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,
|
PRINT20 (ahdrp->nextoff, iterator.next.offset);
|
abfd) != SXCOFFARFMAG))
|
|
return FALSE;
|
|
|
|
if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)
|
if (!do_pad (abfd, iterator.current.leading_padding))
|
return FALSE;
|
return FALSE;
|
|
|
if (! do_copy (abfd, current_bfd))
|
BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
|
|
namlen = iterator.current.padded_namlen;
|
|
if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
|
|
|| bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
|
|
|| bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
|
|
|| bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
|
|
|| !do_copy (abfd, iterator.current.member)
|
|
|| !do_pad (abfd, iterator.current.trailing_padding))
|
return FALSE;
|
return FALSE;
|
|
|
if (! do_pad (abfd, size & 1))
|
offsets[i] = iterator.current.offset;
|
return FALSE;
|
prevoff = iterator.current.offset;
|
}
|
}
|
|
|
if (count)
|
if (count)
|
{
|
{
|
PRINT20 (fhdr.firstmemoff, offsets[0]);
|
PRINT20 (fhdr.firstmemoff, offsets[0]);
|
Line 2477... |
Line 2466... |
0x0086 offsets [0x14 * counts]
|
0x0086 offsets [0x14 * counts]
|
0x0086 + 0x14 * counts names [??]
|
0x0086 + 0x14 * counts names [??]
|
?? pad to even bytes.
|
?? pad to even bytes.
|
*/
|
*/
|
|
|
|
nextoff = iterator.next.offset;
|
BFD_ASSERT (nextoff == bfd_tell (abfd));
|
BFD_ASSERT (nextoff == bfd_tell (abfd));
|
|
|
member_table_size = (SIZEOF_AR_HDR_BIG
|
member_table_size = (SIZEOF_AR_HDR_BIG
|
+ SXCOFFARFMAG
|
+ SXCOFFARFMAG
|
+ XCOFFARMAGBIG_ELEMENT_SIZE
|
+ XCOFFARMAGBIG_ELEMENT_SIZE
|
Line 2941... |
Line 2931... |
bfd_vma addend;
|
bfd_vma addend;
|
bfd_vma *relocation;
|
bfd_vma *relocation;
|
bfd_byte *contents;
|
bfd_byte *contents;
|
{
|
{
|
struct xcoff_link_hash_entry *h;
|
struct xcoff_link_hash_entry *h;
|
|
bfd_vma section_offset;
|
|
|
if (0 > rel->r_symndx)
|
if (0 > rel->r_symndx)
|
return FALSE;
|
return FALSE;
|
|
|
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
|
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
|
|
section_offset = rel->r_vaddr - input_section->vma;
|
|
|
/* If we see an R_BR or R_RBR reloc which is jumping to global
|
/* If we see an R_BR or R_RBR reloc which is jumping to global
|
linkage code, and it is followed by an appropriate cror nop
|
linkage code, and it is followed by an appropriate cror nop
|
instruction, we replace the cror with lwz r2,20(r1). This
|
instruction, we replace the cror with lwz r2,20(r1). This
|
restores the TOC after the glink code. Contrariwise, if the
|
restores the TOC after the glink code. Contrariwise, if the
|
call is followed by a lwz r2,20(r1), but the call is not
|
call is followed by a lwz r2,20(r1), but the call is not
|
going to global linkage code, we can replace the load with a
|
going to global linkage code, we can replace the load with a
|
cror. */
|
cror. */
|
if (NULL != h
|
if (NULL != h
|
&& bfd_link_hash_defined == h->root.type
|
&& (bfd_link_hash_defined == h->root.type
|
&& rel->r_vaddr - input_section->vma + 8 <= input_section->size)
|
|| bfd_link_hash_defweak == h->root.type)
|
|
&& section_offset + 8 <= input_section->size)
|
{
|
{
|
bfd_byte *pnext;
|
bfd_byte *pnext;
|
unsigned long next;
|
unsigned long next;
|
|
|
pnext = contents + (rel->r_vaddr - input_section->vma) + 4;
|
pnext = contents + section_offset + 4;
|
next = bfd_get_32 (input_bfd, pnext);
|
next = bfd_get_32 (input_bfd, pnext);
|
|
|
/* The _ptrgl function is magic. It is used by the AIX
|
/* The _ptrgl function is magic. It is used by the AIX
|
compiler to call a function through a pointer. */
|
compiler to call a function through a pointer. */
|
if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
|
if (h->smclas == XMC_GL || strcmp (h->root.root.string, "._ptrgl") == 0)
|
{
|
{
|
if (next == 0x4def7b82 /* cror 15,15,15 */
|
if (next == 0x4def7b82 /* cror 15,15,15 */
|
|| next == 0x4ffffb82 /* cror 31,31,31 */
|
|| next == 0x4ffffb82 /* cror 31,31,31 */
|
|| next == 0x60000000) /* ori r0,r0,0 */
|
|| next == 0x60000000) /* ori r0,r0,0 */
|
bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */
|
bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r2,20(r1) */
|
|
|
}
|
}
|
else
|
else
|
{
|
{
|
if (next == 0x80410014) /* lwz r1,20(r1) */
|
if (next == 0x80410014) /* lwz r2,20(r1) */
|
bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
|
bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */
|
}
|
}
|
}
|
}
|
else if (NULL != h && bfd_link_hash_undefined == h->root.type)
|
else if (NULL != h && bfd_link_hash_undefined == h->root.type)
|
{
|
{
|
Line 2992... |
Line 2985... |
overflow checking. */
|
overflow checking. */
|
|
|
howto->complain_on_overflow = complain_overflow_dont;
|
howto->complain_on_overflow = complain_overflow_dont;
|
}
|
}
|
|
|
howto->pc_relative = TRUE;
|
/* The original PC-relative relocation is biased by -r_vaddr, so adding
|
|
the value below will give the absolute target address. */
|
|
*relocation = val + addend + rel->r_vaddr;
|
|
|
howto->src_mask &= ~3;
|
howto->src_mask &= ~3;
|
howto->dst_mask = howto->src_mask;
|
howto->dst_mask = howto->src_mask;
|
|
|
/* A PC relative reloc includes the section address. */
|
if (h != NULL
|
addend += input_section->vma;
|
&& (h->root.type == bfd_link_hash_defined
|
|
|| h->root.type == bfd_link_hash_defweak)
|
|
&& bfd_is_abs_section (h->root.u.def.section)
|
|
&& section_offset + 4 <= input_section->size)
|
|
{
|
|
bfd_byte *ptr;
|
|
bfd_vma insn;
|
|
|
*relocation = val + addend;
|
/* Turn the relative branch into an absolute one by setting the
|
|
AA bit. */
|
|
ptr = contents + section_offset;
|
|
insn = bfd_get_32 (input_bfd, ptr);
|
|
insn |= 2;
|
|
bfd_put_32 (input_bfd, insn, ptr);
|
|
|
|
/* Make the howto absolute too. */
|
|
howto->pc_relative = FALSE;
|
|
howto->complain_on_overflow = complain_overflow_bitfield;
|
|
}
|
|
else
|
|
{
|
|
/* Use a PC-relative howto and subtract the instruction's address
|
|
from the target address we calculated above. */
|
|
howto->pc_relative = TRUE;
|
*relocation -= (input_section->output_section->vma
|
*relocation -= (input_section->output_section->vma
|
+ input_section->output_offset);
|
+ input_section->output_offset
|
|
+ section_offset);
|
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
bfd_boolean
|
bfd_boolean
|
xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
|
xcoff_reloc_type_crel (input_bfd, input_section, output_bfd, rel, sym, howto,
|
Line 3317... |
Line 3336... |
be modified to become an absolute call. The PowerOpen
|
be modified to become an absolute call. The PowerOpen
|
ABI does not define this relocation type.
|
ABI does not define this relocation type.
|
|
|
R_RBR:
|
R_RBR:
|
A relative branch which may be modified to become an
|
A relative branch which may be modified to become an
|
absolute branch. FIXME: We don't implement this,
|
absolute branch.
|
although we should for symbols of storage mapping class
|
|
XMC_XO.
|
|
|
|
R_RL:
|
R_RL:
|
The PowerPC AIX ABI describes this as a load which may be
|
The PowerPC AIX ABI describes this as a load which may be
|
changed to a load address. The PowerOpen ABI says this
|
changed to a load address. The PowerOpen ABI says this
|
is the same as case R_POS.
|
is the same as case R_POS.
|
Line 3416... |
Line 3433... |
+ sym->n_value
|
+ sym->n_value
|
- sec->vma);
|
- sec->vma);
|
}
|
}
|
else
|
else
|
{
|
{
|
|
if (info->unresolved_syms_in_objects != RM_IGNORE
|
|
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
|
{
|
|
if (! ((*info->callbacks->undefined_symbol)
|
|
(info, h->root.root.string,
|
|
input_bfd, input_section,
|
|
rel->r_vaddr - input_section->vma,
|
|
(info->unresolved_syms_in_objects
|
|
== RM_GENERATE_ERROR))))
|
|
return FALSE;
|
|
}
|
if (h->root.type == bfd_link_hash_defined
|
if (h->root.type == bfd_link_hash_defined
|
|| h->root.type == bfd_link_hash_defweak)
|
|| h->root.type == bfd_link_hash_defweak)
|
{
|
{
|
sec = h->root.u.def.section;
|
sec = h->root.u.def.section;
|
val = (h->root.u.def.value
|
val = (h->root.u.def.value
|
Line 3431... |
Line 3459... |
sec = h->root.u.c.p->section;
|
sec = h->root.u.c.p->section;
|
val = (sec->output_section->vma
|
val = (sec->output_section->vma
|
+ sec->output_offset);
|
+ sec->output_offset);
|
|
|
}
|
}
|
else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))
|
else
|
&& ! info->relocatable)
|
|
{
|
{
|
if (! ((*info->callbacks->undefined_symbol)
|
BFD_ASSERT (info->relocatable
|
(info, h->root.root.string, input_bfd, input_section,
|
|| (info->static_link
|
rel->r_vaddr - input_section->vma, TRUE)))
|
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0)
|
return FALSE;
|
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0
|
|
|| (h->flags & XCOFF_IMPORT) != 0);
|
/* Don't try to process the reloc. It can't help, and
|
|
it may generate another error. */
|
|
continue;
|
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
|
if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION
|
Line 4005... |
Line 4029... |
AUXESZ,
|
AUXESZ,
|
RELSZ,
|
RELSZ,
|
LINESZ,
|
LINESZ,
|
FILNMLEN,
|
FILNMLEN,
|
TRUE, /* _bfd_coff_long_filenames */
|
TRUE, /* _bfd_coff_long_filenames */
|
FALSE, /* _bfd_coff_long_section_names */
|
XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
|
3, /* _bfd_coff_default_section_alignment_power */
|
3, /* _bfd_coff_default_section_alignment_power */
|
FALSE, /* _bfd_coff_force_symnames_in_strings */
|
FALSE, /* _bfd_coff_force_symnames_in_strings */
|
2, /* _bfd_coff_debug_string_prefix_length */
|
2, /* _bfd_coff_debug_string_prefix_length */
|
coff_swap_filehdr_in,
|
coff_swap_filehdr_in,
|
coff_swap_aouthdr_in,
|
coff_swap_aouthdr_in,
|
Line 4032... |
Line 4056... |
xcoff_ppc_relocate_section,
|
xcoff_ppc_relocate_section,
|
coff_rtype_to_howto,
|
coff_rtype_to_howto,
|
NULL, /* _bfd_coff_adjust_symndx */
|
NULL, /* _bfd_coff_adjust_symndx */
|
_bfd_generic_link_add_one_symbol,
|
_bfd_generic_link_add_one_symbol,
|
coff_link_output_has_begun,
|
coff_link_output_has_begun,
|
coff_final_link_postscript
|
coff_final_link_postscript,
|
|
NULL /* print_pdata. */
|
},
|
},
|
|
|
0x01DF, /* magic number */
|
0x01DF, /* magic number */
|
bfd_arch_rs6000,
|
bfd_arch_rs6000,
|
bfd_mach_rs6k,
|
bfd_mach_rs6k,
|
Line 4212... |
Line 4237... |
bfd_generic_gc_sections,
|
bfd_generic_gc_sections,
|
bfd_generic_merge_sections,
|
bfd_generic_merge_sections,
|
bfd_generic_is_group_section,
|
bfd_generic_is_group_section,
|
bfd_generic_discard_group,
|
bfd_generic_discard_group,
|
_bfd_generic_section_already_linked,
|
_bfd_generic_section_already_linked,
|
|
_bfd_xcoff_define_common_symbol,
|
|
|
/* Dynamic */
|
/* Dynamic */
|
_bfd_xcoff_get_dynamic_symtab_upper_bound,
|
_bfd_xcoff_get_dynamic_symtab_upper_bound,
|
_bfd_xcoff_canonicalize_dynamic_symtab,
|
_bfd_xcoff_canonicalize_dynamic_symtab,
|
_bfd_nodynamic_get_synthetic_symtab,
|
_bfd_nodynamic_get_synthetic_symtab,
|
Line 4256... |
Line 4282... |
AUXESZ,
|
AUXESZ,
|
RELSZ,
|
RELSZ,
|
LINESZ,
|
LINESZ,
|
FILNMLEN,
|
FILNMLEN,
|
TRUE, /* _bfd_coff_long_filenames */
|
TRUE, /* _bfd_coff_long_filenames */
|
FALSE, /* _bfd_coff_long_section_names */
|
XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */
|
3, /* _bfd_coff_default_section_alignment_power */
|
3, /* _bfd_coff_default_section_alignment_power */
|
FALSE, /* _bfd_coff_force_symnames_in_strings */
|
FALSE, /* _bfd_coff_force_symnames_in_strings */
|
2, /* _bfd_coff_debug_string_prefix_length */
|
2, /* _bfd_coff_debug_string_prefix_length */
|
coff_swap_filehdr_in,
|
coff_swap_filehdr_in,
|
coff_swap_aouthdr_in,
|
coff_swap_aouthdr_in,
|
Line 4283... |
Line 4309... |
xcoff_ppc_relocate_section,
|
xcoff_ppc_relocate_section,
|
coff_rtype_to_howto,
|
coff_rtype_to_howto,
|
NULL, /* _bfd_coff_adjust_symndx */
|
NULL, /* _bfd_coff_adjust_symndx */
|
_bfd_generic_link_add_one_symbol,
|
_bfd_generic_link_add_one_symbol,
|
coff_link_output_has_begun,
|
coff_link_output_has_begun,
|
coff_final_link_postscript
|
coff_final_link_postscript,
|
|
NULL /* print_pdata. */
|
},
|
},
|
|
|
0x01DF, /* magic number */
|
0x01DF, /* magic number */
|
bfd_arch_powerpc,
|
bfd_arch_powerpc,
|
bfd_mach_ppc,
|
bfd_mach_ppc,
|
Line 4463... |
Line 4490... |
bfd_generic_gc_sections,
|
bfd_generic_gc_sections,
|
bfd_generic_merge_sections,
|
bfd_generic_merge_sections,
|
bfd_generic_is_group_section,
|
bfd_generic_is_group_section,
|
bfd_generic_discard_group,
|
bfd_generic_discard_group,
|
_bfd_generic_section_already_linked,
|
_bfd_generic_section_already_linked,
|
|
_bfd_xcoff_define_common_symbol,
|
|
|
/* Dynamic */
|
/* Dynamic */
|
_bfd_xcoff_get_dynamic_symtab_upper_bound,
|
_bfd_xcoff_get_dynamic_symtab_upper_bound,
|
_bfd_xcoff_canonicalize_dynamic_symtab,
|
_bfd_xcoff_canonicalize_dynamic_symtab,
|
_bfd_nodynamic_get_synthetic_symtab,
|
_bfd_nodynamic_get_synthetic_symtab,
|