| 1 |
/* BFD back-end for IBM RS/6000 "XCOFF" files. |
/* BFD back-end for IBM RS/6000 "XCOFF" files. |
| 2 |
Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, |
Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, |
| 3 |
2008 Free Software Foundation, Inc. |
2008, 2009 Free Software Foundation, Inc. |
| 4 |
Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore. |
Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore. |
| 5 |
Archive support from Damon A. Permezel. |
Archive support from Damon A. Permezel. |
| 6 |
Contributed by IBM Corporation and Cygnus Support. |
Contributed by IBM Corporation and Cygnus Support. |
| 180 |
PARAMS ((bfd *, unsigned int)); |
PARAMS ((bfd *, unsigned int)); |
| 181 |
static bfd_boolean do_copy |
static bfd_boolean do_copy |
| 182 |
PARAMS ((bfd *, bfd *)); |
PARAMS ((bfd *, bfd *)); |
|
static bfd_boolean do_shared_object_padding |
|
|
PARAMS ((bfd *, bfd *, file_ptr *, int)); |
|
| 183 |
|
|
| 184 |
/* Relocation functions */ |
/* Relocation functions */ |
| 185 |
static bfd_boolean xcoff_reloc_type_br |
static bfd_boolean xcoff_reloc_type_br |
| 236 |
xcoff_complain_overflow_unsigned_func, |
xcoff_complain_overflow_unsigned_func, |
| 237 |
}; |
}; |
| 238 |
|
|
| 239 |
|
/* Information about one member of an archive. */ |
| 240 |
|
struct member_layout { |
| 241 |
|
/* The archive member that this structure describes. */ |
| 242 |
|
bfd *member; |
| 243 |
|
|
| 244 |
|
/* The number of bytes of padding that must be inserted before the |
| 245 |
|
start of the member in order to ensure that the section contents |
| 246 |
|
are correctly aligned. */ |
| 247 |
|
unsigned int leading_padding; |
| 248 |
|
|
| 249 |
|
/* The offset of MEMBER from the start of the archive (i.e. the end |
| 250 |
|
of the leading padding). */ |
| 251 |
|
file_ptr offset; |
| 252 |
|
|
| 253 |
|
/* The normalized name of MEMBER. */ |
| 254 |
|
const char *name; |
| 255 |
|
|
| 256 |
|
/* The length of NAME, without padding. */ |
| 257 |
|
bfd_size_type namlen; |
| 258 |
|
|
| 259 |
|
/* The length of NAME, with padding. */ |
| 260 |
|
bfd_size_type padded_namlen; |
| 261 |
|
|
| 262 |
|
/* The size of MEMBER's header, including the name and magic sequence. */ |
| 263 |
|
bfd_size_type header_size; |
| 264 |
|
|
| 265 |
|
/* The size of the MEMBER's contents. */ |
| 266 |
|
bfd_size_type contents_size; |
| 267 |
|
|
| 268 |
|
/* The number of bytes of padding that must be inserted after MEMBER |
| 269 |
|
in order to preserve even alignment. */ |
| 270 |
|
bfd_size_type trailing_padding; |
| 271 |
|
}; |
| 272 |
|
|
| 273 |
|
/* A structure used for iterating over the members of an archive. */ |
| 274 |
|
struct archive_iterator { |
| 275 |
|
/* The archive itself. */ |
| 276 |
|
bfd *archive; |
| 277 |
|
|
| 278 |
|
/* Information about the current archive member. */ |
| 279 |
|
struct member_layout current; |
| 280 |
|
|
| 281 |
|
/* Information about the next archive member. MEMBER is null if there |
| 282 |
|
are no more archive members, in which case OFFSET is the offset of |
| 283 |
|
the first unused byte. */ |
| 284 |
|
struct member_layout next; |
| 285 |
|
}; |
| 286 |
|
|
| 287 |
|
/* Initialize INFO so that it describes member MEMBER of archive ARCHIVE. |
| 288 |
|
OFFSET is the even-padded offset of MEMBER, not including any leading |
| 289 |
|
padding needed for section alignment. */ |
| 290 |
|
|
| 291 |
|
static void |
| 292 |
|
member_layout_init (struct member_layout *info, bfd *archive, |
| 293 |
|
bfd *member, file_ptr offset) |
| 294 |
|
{ |
| 295 |
|
info->member = member; |
| 296 |
|
info->leading_padding = 0; |
| 297 |
|
if (member) |
| 298 |
|
{ |
| 299 |
|
info->name = normalize_filename (member); |
| 300 |
|
info->namlen = strlen (info->name); |
| 301 |
|
info->padded_namlen = info->namlen + (info->namlen & 1); |
| 302 |
|
if (xcoff_big_format_p (archive)) |
| 303 |
|
info->header_size = SIZEOF_AR_HDR_BIG; |
| 304 |
|
else |
| 305 |
|
info->header_size = SIZEOF_AR_HDR; |
| 306 |
|
info->header_size += info->padded_namlen + SXCOFFARFMAG; |
| 307 |
|
info->contents_size = arelt_size (member); |
| 308 |
|
info->trailing_padding = info->contents_size & 1; |
| 309 |
|
|
| 310 |
|
if (bfd_check_format (member, bfd_object) |
| 311 |
|
&& bfd_get_flavour (member) == bfd_target_xcoff_flavour |
| 312 |
|
&& (member->flags & DYNAMIC) != 0) |
| 313 |
|
info->leading_padding |
| 314 |
|
= (-(offset + info->header_size) |
| 315 |
|
& ((1 << bfd_xcoff_text_align_power (member)) - 1)); |
| 316 |
|
} |
| 317 |
|
info->offset = offset + info->leading_padding; |
| 318 |
|
} |
| 319 |
|
|
| 320 |
|
/* Set up ITERATOR to iterate through archive ARCHIVE. */ |
| 321 |
|
|
| 322 |
|
static void |
| 323 |
|
archive_iterator_begin (struct archive_iterator *iterator, |
| 324 |
|
bfd *archive) |
| 325 |
|
{ |
| 326 |
|
iterator->archive = archive; |
| 327 |
|
member_layout_init (&iterator->next, archive, archive->archive_head, |
| 328 |
|
xcoff_big_format_p (archive) |
| 329 |
|
? SIZEOF_AR_FILE_HDR_BIG |
| 330 |
|
: SIZEOF_AR_FILE_HDR); |
| 331 |
|
} |
| 332 |
|
|
| 333 |
|
/* Make ITERATOR visit the first unvisited archive member. Return true |
| 334 |
|
on success; return false if all members have been visited. */ |
| 335 |
|
|
| 336 |
|
static bfd_boolean |
| 337 |
|
archive_iterator_next (struct archive_iterator *iterator) |
| 338 |
|
{ |
| 339 |
|
if (!iterator->next.member) |
| 340 |
|
return FALSE; |
| 341 |
|
|
| 342 |
|
iterator->current = iterator->next; |
| 343 |
|
member_layout_init (&iterator->next, iterator->archive, |
| 344 |
|
iterator->current.member->archive_next, |
| 345 |
|
iterator->current.offset |
| 346 |
|
+ iterator->current.header_size |
| 347 |
|
+ iterator->current.contents_size |
| 348 |
|
+ iterator->current.trailing_padding); |
| 349 |
|
return TRUE; |
| 350 |
|
} |
| 351 |
|
|
| 352 |
/* 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, |
| 353 |
so the COFF routines are compatible. */ |
so the COFF routines are compatible. */ |
| 354 |
|
|
| 533 |
|
|
| 534 |
/* RS/6000 "csect" auxents */ |
/* RS/6000 "csect" auxents */ |
| 535 |
case C_EXT: |
case C_EXT: |
| 536 |
|
case C_AIX_WEAKEXT: |
| 537 |
case C_HIDEXT: |
case C_HIDEXT: |
| 538 |
if (indx + 1 == numaux) |
if (indx + 1 == numaux) |
| 539 |
{ |
{ |
| 643 |
|
|
| 644 |
/* RS/6000 "csect" auxents */ |
/* RS/6000 "csect" auxents */ |
| 645 |
case C_EXT: |
case C_EXT: |
| 646 |
|
case C_AIX_WEAKEXT: |
| 647 |
case C_HIDEXT: |
case C_HIDEXT: |
| 648 |
if (indx + 1 == numaux) |
if (indx + 1 == numaux) |
| 649 |
{ |
{ |
| 1714 |
unsigned int orl_count; |
unsigned int orl_count; |
| 1715 |
int stridx; |
int stridx; |
| 1716 |
{ |
{ |
| 1717 |
|
struct archive_iterator iterator; |
| 1718 |
struct xcoff_ar_hdr hdr; |
struct xcoff_ar_hdr hdr; |
| 1719 |
char *p; |
char *p; |
| 1720 |
unsigned char buf[4]; |
unsigned char buf[4]; |
|
bfd *sub; |
|
|
file_ptr fileoff; |
|
| 1721 |
unsigned int i; |
unsigned int i; |
| 1722 |
|
|
| 1723 |
memset (&hdr, 0, sizeof hdr); |
memset (&hdr, 0, sizeof hdr); |
| 1745 |
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4) |
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4) |
| 1746 |
return FALSE; |
return FALSE; |
| 1747 |
|
|
|
sub = abfd->archive_head; |
|
|
fileoff = SIZEOF_AR_FILE_HDR; |
|
| 1748 |
i = 0; |
i = 0; |
| 1749 |
while (sub != NULL && i < orl_count) |
archive_iterator_begin (&iterator, abfd); |
| 1750 |
{ |
while (i < orl_count && archive_iterator_next (&iterator)) |
| 1751 |
size_t namlen; |
while (map[i].u.abfd == iterator.current.member) |
| 1752 |
|
{ |
| 1753 |
while (map[i].u.abfd == sub) |
H_PUT_32 (abfd, iterator.current.offset, buf); |
| 1754 |
{ |
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4) |
| 1755 |
H_PUT_32 (abfd, fileoff, buf); |
return FALSE; |
| 1756 |
if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4) |
++i; |
| 1757 |
return FALSE; |
} |
|
++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; |
|
|
} |
|
| 1758 |
|
|
| 1759 |
for (i = 0; i < orl_count; i++) |
for (i = 0; i < orl_count; i++) |
| 1760 |
{ |
{ |
| 1856 |
} |
} |
| 1857 |
|
|
| 1858 |
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 |
|
| 1859 |
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx) |
xcoff_write_armap_big (abfd, elength, map, orl_count, stridx) |
| 1860 |
bfd *abfd; |
bfd *abfd; |
| 1861 |
unsigned int elength ATTRIBUTE_UNUSED; |
unsigned int elength ATTRIBUTE_UNUSED; |
| 1863 |
unsigned int orl_count; |
unsigned int orl_count; |
| 1864 |
int stridx; |
int stridx; |
| 1865 |
{ |
{ |
| 1866 |
|
struct archive_iterator iterator; |
| 1867 |
struct xcoff_ar_file_hdr_big *fhdr; |
struct xcoff_ar_file_hdr_big *fhdr; |
| 1868 |
bfd_vma i, sym_32, sym_64, str_32, str_64; |
bfd_vma i, sym_32, sym_64, str_32, str_64; |
| 1869 |
const bfd_arch_info_type *arch_info = NULL; |
const bfd_arch_info_type *arch_info; |
| 1870 |
bfd *current_bfd; |
bfd *current_bfd; |
| 1871 |
size_t string_length; |
size_t string_length; |
| 1872 |
file_ptr nextoff, prevoff; |
file_ptr nextoff, prevoff; |
| 1875 |
from 32-bit objects and which from 64-bit ones. */ |
from 32-bit objects and which from 64-bit ones. */ |
| 1876 |
sym_32 = sym_64 = str_32 = str_64 = 0; |
sym_32 = sym_64 = str_32 = str_64 = 0; |
| 1877 |
|
|
| 1878 |
current_bfd = abfd->archive_head; |
i = 0; |
| 1879 |
if (current_bfd != NULL) |
for (current_bfd = abfd->archive_head; |
| 1880 |
arch_info = bfd_get_arch_info (current_bfd); |
current_bfd != NULL && i < orl_count; |
| 1881 |
i = 0; |
current_bfd = current_bfd->archive_next) |
|
while (current_bfd != NULL && i < orl_count) |
|
| 1882 |
{ |
{ |
| 1883 |
|
arch_info = bfd_get_arch_info (current_bfd); |
| 1884 |
while (map[i].u.abfd == current_bfd) |
while (map[i].u.abfd == current_bfd) |
| 1885 |
{ |
{ |
| 1886 |
string_length = strlen (*map[i].name) + 1; |
string_length = strlen (*map[i].name) + 1; |
|
|
|
| 1887 |
if (arch_info->bits_per_address == 64) |
if (arch_info->bits_per_address == 64) |
| 1888 |
{ |
{ |
| 1889 |
sym_64++; |
sym_64++; |
| 1896 |
} |
} |
| 1897 |
i++; |
i++; |
| 1898 |
} |
} |
|
current_bfd = current_bfd->archive_next; |
|
|
if (current_bfd != NULL) |
|
|
arch_info = bfd_get_arch_info (current_bfd); |
|
| 1899 |
} |
} |
| 1900 |
|
|
| 1901 |
/* A quick sanity check... */ |
/* A quick sanity check... */ |
| 1937 |
struct xcoff_ar_hdr_big *hdr; |
struct xcoff_ar_hdr_big *hdr; |
| 1938 |
char *symbol_table; |
char *symbol_table; |
| 1939 |
char *st; |
char *st; |
|
file_ptr fileoff; |
|
| 1940 |
|
|
| 1941 |
bfd_vma symbol_table_size = |
bfd_vma symbol_table_size = |
| 1942 |
SIZEOF_AR_HDR_BIG |
SIZEOF_AR_HDR_BIG |
| 1973 |
st += 8; |
st += 8; |
| 1974 |
|
|
| 1975 |
/* 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; |
|
| 1976 |
i = 0; |
i = 0; |
| 1977 |
while (current_bfd != NULL && i < orl_count) |
archive_iterator_begin (&iterator, abfd); |
| 1978 |
|
while (i < orl_count && archive_iterator_next (&iterator)) |
| 1979 |
{ |
{ |
| 1980 |
while (map[i].u.abfd == current_bfd) |
arch_info = bfd_get_arch_info (iterator.current.member); |
| 1981 |
|
while (map[i].u.abfd == iterator.current.member) |
| 1982 |
{ |
{ |
| 1983 |
if (arch_info->bits_per_address == 32) |
if (arch_info->bits_per_address == 32) |
| 1984 |
{ |
{ |
| 1985 |
bfd_h_put_64 (abfd, fileoff, st); |
bfd_h_put_64 (abfd, iterator.current.offset, st); |
| 1986 |
st += 8; |
st += 8; |
| 1987 |
} |
} |
| 1988 |
i++; |
i++; |
| 1989 |
} |
} |
|
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); |
|
| 1990 |
} |
} |
| 1991 |
|
|
| 1992 |
/* 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); |
|
| 1993 |
i = 0; |
i = 0; |
| 1994 |
while (current_bfd != NULL && i < orl_count) |
for (current_bfd = abfd->archive_head; |
| 1995 |
|
current_bfd != NULL && i < orl_count; |
| 1996 |
|
current_bfd = current_bfd->archive_next) |
| 1997 |
{ |
{ |
| 1998 |
|
arch_info = bfd_get_arch_info (current_bfd); |
| 1999 |
while (map[i].u.abfd == current_bfd) |
while (map[i].u.abfd == current_bfd) |
| 2000 |
{ |
{ |
| 2001 |
if (arch_info->bits_per_address == 32) |
if (arch_info->bits_per_address == 32) |
| 2005 |
} |
} |
| 2006 |
i++; |
i++; |
| 2007 |
} |
} |
|
current_bfd = current_bfd->archive_next; |
|
|
if (current_bfd != NULL) |
|
|
arch_info = bfd_get_arch_info (current_bfd); |
|
| 2008 |
} |
} |
| 2009 |
|
|
| 2010 |
bfd_bwrite (symbol_table, symbol_table_size, abfd); |
bfd_bwrite (symbol_table, symbol_table_size, abfd); |
| 2022 |
struct xcoff_ar_hdr_big *hdr; |
struct xcoff_ar_hdr_big *hdr; |
| 2023 |
char *symbol_table; |
char *symbol_table; |
| 2024 |
char *st; |
char *st; |
|
file_ptr fileoff; |
|
| 2025 |
|
|
| 2026 |
bfd_vma symbol_table_size = |
bfd_vma symbol_table_size = |
| 2027 |
SIZEOF_AR_HDR_BIG |
SIZEOF_AR_HDR_BIG |
| 2053 |
st += 8; |
st += 8; |
| 2054 |
|
|
| 2055 |
/* 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; |
|
| 2056 |
i = 0; |
i = 0; |
| 2057 |
while (current_bfd != NULL && i < orl_count) |
archive_iterator_begin (&iterator, abfd); |
| 2058 |
|
while (i < orl_count && archive_iterator_next (&iterator)) |
| 2059 |
{ |
{ |
| 2060 |
while (map[i].u.abfd == current_bfd) |
arch_info = bfd_get_arch_info (iterator.current.member); |
| 2061 |
|
while (map[i].u.abfd == iterator.current.member) |
| 2062 |
{ |
{ |
| 2063 |
if (arch_info->bits_per_address == 64) |
if (arch_info->bits_per_address == 64) |
| 2064 |
{ |
{ |
| 2065 |
bfd_h_put_64 (abfd, fileoff, st); |
bfd_h_put_64 (abfd, iterator.current.offset, st); |
| 2066 |
st += 8; |
st += 8; |
| 2067 |
} |
} |
| 2068 |
i++; |
i++; |
| 2069 |
} |
} |
|
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); |
|
| 2070 |
} |
} |
| 2071 |
|
|
| 2072 |
/* 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); |
|
| 2073 |
i = 0; |
i = 0; |
| 2074 |
while (current_bfd != NULL && i < orl_count) |
for (current_bfd = abfd->archive_head; |
| 2075 |
|
current_bfd != NULL && i < orl_count; |
| 2076 |
|
current_bfd = current_bfd->archive_next) |
| 2077 |
{ |
{ |
| 2078 |
|
arch_info = bfd_get_arch_info (current_bfd); |
| 2079 |
while (map[i].u.abfd == current_bfd) |
while (map[i].u.abfd == current_bfd) |
| 2080 |
{ |
{ |
| 2081 |
if (arch_info->bits_per_address == 64) |
if (arch_info->bits_per_address == 64) |
| 2085 |
} |
} |
| 2086 |
i++; |
i++; |
| 2087 |
} |
} |
|
current_bfd = current_bfd->archive_next; |
|
|
if (current_bfd != NULL) |
|
|
arch_info = bfd_get_arch_info (current_bfd); |
|
| 2088 |
} |
} |
| 2089 |
|
|
| 2090 |
bfd_bwrite (symbol_table, symbol_table_size, abfd); |
bfd_bwrite (symbol_table, symbol_table_size, abfd); |
| 2120 |
xcoff_write_archive_contents_old (abfd) |
xcoff_write_archive_contents_old (abfd) |
| 2121 |
bfd *abfd; |
bfd *abfd; |
| 2122 |
{ |
{ |
| 2123 |
|
struct archive_iterator iterator; |
| 2124 |
struct xcoff_ar_file_hdr fhdr; |
struct xcoff_ar_file_hdr fhdr; |
| 2125 |
bfd_size_type count; |
bfd_size_type count; |
| 2126 |
bfd_size_type total_namlen; |
bfd_size_type total_namlen; |
| 2146 |
{ |
{ |
| 2147 |
++count; |
++count; |
| 2148 |
total_namlen += strlen (normalize_filename (sub)) + 1; |
total_namlen += strlen (normalize_filename (sub)) + 1; |
| 2149 |
} |
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) |
|
| 2150 |
{ |
{ |
| 2151 |
if (bfd_check_format (sub, bfd_object)) |
sub->arelt_data = bfd_zalloc (sub, sizeof (struct areltdata)); |
| 2152 |
hasobjects = TRUE; |
if (sub->arelt_data == NULL) |
| 2153 |
|
return FALSE; |
| 2154 |
} |
} |
| 2155 |
|
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) |
|
| 2156 |
{ |
{ |
| 2157 |
|
struct xcoff_ar_hdr *ahdrp; |
| 2158 |
struct stat s; |
struct stat s; |
| 2159 |
|
|
|
memset (&ahdr, 0, sizeof ahdr); |
|
|
ahdrp = &ahdr; |
|
| 2160 |
if (stat (bfd_get_filename (sub), &s) != 0) |
if (stat (bfd_get_filename (sub), &s) != 0) |
| 2161 |
{ |
{ |
| 2162 |
bfd_set_error (bfd_error_system_call); |
bfd_set_error (bfd_error_system_call); |
| 2163 |
return FALSE; |
return FALSE; |
| 2164 |
} |
} |
| 2165 |
|
|
| 2166 |
|
ahdrp = bfd_zalloc (sub, sizeof (*ahdrp)); |
| 2167 |
|
if (ahdrp == NULL) |
| 2168 |
|
return FALSE; |
| 2169 |
|
|
| 2170 |
sprintf (ahdrp->size, "%ld", (long) s.st_size); |
sprintf (ahdrp->size, "%ld", (long) s.st_size); |
| 2171 |
sprintf (ahdrp->date, "%ld", (long) s.st_mtime); |
sprintf (ahdrp->date, "%ld", (long) s.st_mtime); |
| 2172 |
sprintf (ahdrp->uid, "%ld", (long) s.st_uid); |
sprintf (ahdrp->uid, "%ld", (long) s.st_uid); |
| 2173 |
sprintf (ahdrp->gid, "%ld", (long) s.st_gid); |
sprintf (ahdrp->gid, "%ld", (long) s.st_gid); |
| 2174 |
sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode); |
sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode); |
| 2175 |
|
|
| 2176 |
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; |
|
|
} |
|
|
|
|
| 2177 |
arch_eltdata (sub)->parsed_size = s.st_size; |
arch_eltdata (sub)->parsed_size = s.st_size; |
| 2178 |
} |
} |
| 2179 |
|
} |
| 2180 |
|
offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr)); |
| 2181 |
|
if (offsets == NULL) |
| 2182 |
|
return FALSE; |
| 2183 |
|
|
| 2184 |
sprintf (ahdrp->prevoff, "%ld", (long) prevoff); |
if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0) |
| 2185 |
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)); |
|
| 2186 |
|
|
| 2187 |
offsets[i] = nextoff; |
makemap = bfd_has_map (abfd); |
| 2188 |
|
hasobjects = FALSE; |
| 2189 |
|
prevoff = 0; |
| 2190 |
|
for (archive_iterator_begin (&iterator, abfd), i = 0; |
| 2191 |
|
archive_iterator_next (&iterator); |
| 2192 |
|
i++) |
| 2193 |
|
{ |
| 2194 |
|
bfd_size_type namlen; |
| 2195 |
|
struct xcoff_ar_hdr *ahdrp; |
| 2196 |
|
|
| 2197 |
prevoff = nextoff; |
if (makemap && ! hasobjects) |
| 2198 |
nextoff += size + (size & 1); |
{ |
| 2199 |
|
if (bfd_check_format (iterator.current.member, bfd_object)) |
| 2200 |
|
hasobjects = TRUE; |
| 2201 |
|
} |
| 2202 |
|
|
| 2203 |
sprintf (ahdrp->nextoff, "%ld", (long) nextoff); |
ahdrp = arch_xhdr (iterator.current.member); |
| 2204 |
|
sprintf (ahdrp->prevoff, "%ld", (long) prevoff); |
| 2205 |
|
sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen); |
| 2206 |
|
sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset); |
| 2207 |
|
|
| 2208 |
/* We need spaces, not null bytes, in the header. */ |
/* We need spaces, not null bytes, in the header. */ |
| 2209 |
for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++) |
for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++) |
| 2210 |
if (*p == '\0') |
if (*p == '\0') |
| 2211 |
*p = ' '; |
*p = ' '; |
| 2212 |
|
|
| 2213 |
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) |
|
| 2214 |
return FALSE; |
return FALSE; |
| 2215 |
|
|
| 2216 |
if (! do_copy (abfd, sub)) |
BFD_ASSERT (iterator.current.offset == bfd_tell (abfd)); |
| 2217 |
|
namlen = iterator.current.padded_namlen; |
| 2218 |
|
if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR |
| 2219 |
|
|| bfd_bwrite (iterator.current.name, namlen, abfd) != namlen |
| 2220 |
|
|| bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG |
| 2221 |
|
|| bfd_seek (iterator.current.member, 0, SEEK_SET) != 0 |
| 2222 |
|
|| !do_copy (abfd, iterator.current.member) |
| 2223 |
|
|| !do_pad (abfd, iterator.current.trailing_padding)) |
| 2224 |
return FALSE; |
return FALSE; |
| 2225 |
|
|
| 2226 |
if (! do_pad (abfd, size & 1)) |
offsets[i] = iterator.current.offset; |
| 2227 |
return FALSE; |
prevoff = iterator.current.offset; |
| 2228 |
} |
} |
| 2229 |
|
|
| 2230 |
sprintf (fhdr.lastmemoff, "%ld", (long) prevoff); |
sprintf (fhdr.lastmemoff, "%ld", (long) prevoff); |
| 2231 |
|
|
| 2232 |
/* Write out the member table. */ |
/* Write out the member table. */ |
| 2233 |
|
|
| 2234 |
|
nextoff = iterator.next.offset; |
| 2235 |
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
| 2236 |
sprintf (fhdr.memoff, "%ld", (long) nextoff); |
sprintf (fhdr.memoff, "%ld", (long) nextoff); |
| 2237 |
|
|
| 2336 |
file_ptr prevoff, nextoff; |
file_ptr prevoff, nextoff; |
| 2337 |
bfd *current_bfd; |
bfd *current_bfd; |
| 2338 |
size_t i; |
size_t i; |
| 2339 |
struct xcoff_ar_hdr_big *hdr, ahdr; |
struct xcoff_ar_hdr_big *hdr; |
| 2340 |
bfd_size_type size; |
bfd_size_type size; |
| 2341 |
char *member_table, *mt; |
char *member_table, *mt; |
| 2342 |
bfd_vma member_table_size; |
bfd_vma member_table_size; |
| 2343 |
|
struct archive_iterator iterator; |
| 2344 |
|
|
| 2345 |
memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG); |
memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG); |
| 2346 |
memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG); |
memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG); |
| 2361 |
&& ! hasobjects |
&& ! hasobjects |
| 2362 |
&& bfd_check_format (current_bfd, bfd_object)) |
&& bfd_check_format (current_bfd, bfd_object)) |
| 2363 |
hasobjects = TRUE; |
hasobjects = TRUE; |
|
} |
|
| 2364 |
|
|
| 2365 |
offsets = NULL; |
if (current_bfd->arelt_data == NULL) |
| 2366 |
if (count) |
{ |
| 2367 |
{ |
size = sizeof (struct areltdata); |
| 2368 |
offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr)); |
current_bfd->arelt_data = bfd_zalloc (current_bfd, size); |
| 2369 |
if (offsets == NULL) |
if (current_bfd->arelt_data == NULL) |
| 2370 |
return FALSE; |
return FALSE; |
| 2371 |
} |
} |
|
|
|
|
prevoff = 0; |
|
|
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; |
|
|
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; |
|
| 2372 |
|
|
| 2373 |
if (ahdrp == NULL) |
if (arch_xhdr_big (current_bfd) == NULL) |
| 2374 |
{ |
{ |
| 2375 |
|
struct xcoff_ar_hdr_big *ahdrp; |
| 2376 |
struct stat s; |
struct stat s; |
| 2377 |
|
|
|
ahdrp = &ahdr; |
|
| 2378 |
/* XXX This should actually be a call to stat64 (at least on |
/* XXX This should actually be a call to stat64 (at least on |
| 2379 |
32-bit machines). |
32-bit machines). |
| 2380 |
XXX This call will fail if the original object is not found. */ |
XXX This call will fail if the original object is not found. */ |
| 2384 |
return FALSE; |
return FALSE; |
| 2385 |
} |
} |
| 2386 |
|
|
| 2387 |
|
ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp)); |
| 2388 |
|
if (ahdrp == NULL) |
| 2389 |
|
return FALSE; |
| 2390 |
|
|
| 2391 |
PRINT20 (ahdrp->size, s.st_size); |
PRINT20 (ahdrp->size, s.st_size); |
| 2392 |
PRINT12 (ahdrp->date, s.st_mtime); |
PRINT12 (ahdrp->date, s.st_mtime); |
| 2393 |
PRINT12 (ahdrp->uid, s.st_uid); |
PRINT12 (ahdrp->uid, s.st_uid); |
| 2394 |
PRINT12 (ahdrp->gid, s.st_gid); |
PRINT12 (ahdrp->gid, s.st_gid); |
| 2395 |
PRINT12_OCTAL (ahdrp->mode, s.st_mode); |
PRINT12_OCTAL (ahdrp->mode, s.st_mode); |
| 2396 |
|
|
| 2397 |
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; |
|
|
} |
|
|
|
|
| 2398 |
arch_eltdata (current_bfd)->parsed_size = s.st_size; |
arch_eltdata (current_bfd)->parsed_size = s.st_size; |
| 2399 |
} |
} |
| 2400 |
|
} |
| 2401 |
|
|
| 2402 |
PRINT20 (ahdrp->prevoff, prevoff); |
offsets = NULL; |
| 2403 |
PRINT4 (ahdrp->namlen, namlen); |
if (count) |
| 2404 |
|
{ |
| 2405 |
/* If the length of the name is odd, we write out the null byte |
offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr)); |
| 2406 |
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)) |
|
| 2407 |
return FALSE; |
return FALSE; |
| 2408 |
|
} |
| 2409 |
|
|
| 2410 |
offsets[i] = nextoff; |
prevoff = 0; |
| 2411 |
|
for (archive_iterator_begin (&iterator, abfd), i = 0; |
| 2412 |
prevoff = nextoff; |
archive_iterator_next (&iterator); |
| 2413 |
nextoff += size + (size & 1); |
i++) |
| 2414 |
|
{ |
| 2415 |
PRINT20 (ahdrp->nextoff, nextoff); |
bfd_size_type namlen; |
| 2416 |
|
struct xcoff_ar_hdr_big *ahdrp; |
| 2417 |
|
|
| 2418 |
if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd) |
ahdrp = arch_xhdr_big (iterator.current.member); |
| 2419 |
!= SIZEOF_AR_HDR_BIG) |
PRINT20 (ahdrp->prevoff, prevoff); |
| 2420 |
|| bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen |
PRINT4 (ahdrp->namlen, iterator.current.namlen); |
| 2421 |
|| (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG, |
PRINT20 (ahdrp->nextoff, iterator.next.offset); |
|
abfd) != SXCOFFARFMAG)) |
|
|
return FALSE; |
|
| 2422 |
|
|
| 2423 |
if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0) |
if (!do_pad (abfd, iterator.current.leading_padding)) |
| 2424 |
return FALSE; |
return FALSE; |
| 2425 |
|
|
| 2426 |
if (! do_copy (abfd, current_bfd)) |
BFD_ASSERT (iterator.current.offset == bfd_tell (abfd)); |
| 2427 |
|
namlen = iterator.current.padded_namlen; |
| 2428 |
|
if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG |
| 2429 |
|
|| bfd_bwrite (iterator.current.name, namlen, abfd) != namlen |
| 2430 |
|
|| bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG |
| 2431 |
|
|| bfd_seek (iterator.current.member, 0, SEEK_SET) != 0 |
| 2432 |
|
|| !do_copy (abfd, iterator.current.member) |
| 2433 |
|
|| !do_pad (abfd, iterator.current.trailing_padding)) |
| 2434 |
return FALSE; |
return FALSE; |
| 2435 |
|
|
| 2436 |
if (! do_pad (abfd, size & 1)) |
offsets[i] = iterator.current.offset; |
| 2437 |
return FALSE; |
prevoff = iterator.current.offset; |
| 2438 |
} |
} |
| 2439 |
|
|
| 2440 |
if (count) |
if (count) |
| 2464 |
?? pad to even bytes. |
?? pad to even bytes. |
| 2465 |
*/ |
*/ |
| 2466 |
|
|
| 2467 |
|
nextoff = iterator.next.offset; |
| 2468 |
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
BFD_ASSERT (nextoff == bfd_tell (abfd)); |
| 2469 |
|
|
| 2470 |
member_table_size = (SIZEOF_AR_HDR_BIG |
member_table_size = (SIZEOF_AR_HDR_BIG |
| 2929 |
bfd_byte *contents; |
bfd_byte *contents; |
| 2930 |
{ |
{ |
| 2931 |
struct xcoff_link_hash_entry *h; |
struct xcoff_link_hash_entry *h; |
| 2932 |
|
bfd_vma section_offset; |
| 2933 |
|
|
| 2934 |
if (0 > rel->r_symndx) |
if (0 > rel->r_symndx) |
| 2935 |
return FALSE; |
return FALSE; |
| 2936 |
|
|
| 2937 |
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx]; |
h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx]; |
| 2938 |
|
section_offset = rel->r_vaddr - input_section->vma; |
| 2939 |
|
|
| 2940 |
/* 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 |
| 2941 |
linkage code, and it is followed by an appropriate cror nop |
linkage code, and it is followed by an appropriate cror nop |
| 2945 |
going to global linkage code, we can replace the load with a |
going to global linkage code, we can replace the load with a |
| 2946 |
cror. */ |
cror. */ |
| 2947 |
if (NULL != h |
if (NULL != h |
| 2948 |
&& bfd_link_hash_defined == h->root.type |
&& (bfd_link_hash_defined == h->root.type |
| 2949 |
&& rel->r_vaddr - input_section->vma + 8 <= input_section->size) |
|| bfd_link_hash_defweak == h->root.type) |
| 2950 |
|
&& section_offset + 8 <= input_section->size) |
| 2951 |
{ |
{ |
| 2952 |
bfd_byte *pnext; |
bfd_byte *pnext; |
| 2953 |
unsigned long next; |
unsigned long next; |
| 2954 |
|
|
| 2955 |
pnext = contents + (rel->r_vaddr - input_section->vma) + 4; |
pnext = contents + section_offset + 4; |
| 2956 |
next = bfd_get_32 (input_bfd, pnext); |
next = bfd_get_32 (input_bfd, pnext); |
| 2957 |
|
|
| 2958 |
/* The _ptrgl function is magic. It is used by the AIX |
/* The _ptrgl function is magic. It is used by the AIX |
| 2962 |
if (next == 0x4def7b82 /* cror 15,15,15 */ |
if (next == 0x4def7b82 /* cror 15,15,15 */ |
| 2963 |
|| next == 0x4ffffb82 /* cror 31,31,31 */ |
|| next == 0x4ffffb82 /* cror 31,31,31 */ |
| 2964 |
|| next == 0x60000000) /* ori r0,r0,0 */ |
|| next == 0x60000000) /* ori r0,r0,0 */ |
| 2965 |
bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r1,20(r1) */ |
bfd_put_32 (input_bfd, 0x80410014, pnext); /* lwz r2,20(r1) */ |
| 2966 |
|
|
| 2967 |
} |
} |
| 2968 |
else |
else |
| 2969 |
{ |
{ |
| 2970 |
if (next == 0x80410014) /* lwz r1,20(r1) */ |
if (next == 0x80410014) /* lwz r2,20(r1) */ |
| 2971 |
bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */ |
bfd_put_32 (input_bfd, 0x60000000, pnext); /* ori r0,r0,0 */ |
| 2972 |
} |
} |
| 2973 |
} |
} |
| 2983 |
howto->complain_on_overflow = complain_overflow_dont; |
howto->complain_on_overflow = complain_overflow_dont; |
| 2984 |
} |
} |
| 2985 |
|
|
| 2986 |
howto->pc_relative = TRUE; |
/* The original PC-relative relocation is biased by -r_vaddr, so adding |
| 2987 |
|
the value below will give the absolute target address. */ |
| 2988 |
|
*relocation = val + addend + rel->r_vaddr; |
| 2989 |
|
|
| 2990 |
howto->src_mask &= ~3; |
howto->src_mask &= ~3; |
| 2991 |
howto->dst_mask = howto->src_mask; |
howto->dst_mask = howto->src_mask; |
| 2992 |
|
|
| 2993 |
/* A PC relative reloc includes the section address. */ |
if (h != NULL |
| 2994 |
addend += input_section->vma; |
&& (h->root.type == bfd_link_hash_defined |
| 2995 |
|
|| h->root.type == bfd_link_hash_defweak) |
| 2996 |
*relocation = val + addend; |
&& bfd_is_abs_section (h->root.u.def.section) |
| 2997 |
*relocation -= (input_section->output_section->vma |
&& section_offset + 4 <= input_section->size) |
| 2998 |
+ input_section->output_offset); |
{ |
| 2999 |
|
bfd_byte *ptr; |
| 3000 |
|
bfd_vma insn; |
| 3001 |
|
|
| 3002 |
|
/* Turn the relative branch into an absolute one by setting the |
| 3003 |
|
AA bit. */ |
| 3004 |
|
ptr = contents + section_offset; |
| 3005 |
|
insn = bfd_get_32 (input_bfd, ptr); |
| 3006 |
|
insn |= 2; |
| 3007 |
|
bfd_put_32 (input_bfd, insn, ptr); |
| 3008 |
|
|
| 3009 |
|
/* Make the howto absolute too. */ |
| 3010 |
|
howto->pc_relative = FALSE; |
| 3011 |
|
howto->complain_on_overflow = complain_overflow_bitfield; |
| 3012 |
|
} |
| 3013 |
|
else |
| 3014 |
|
{ |
| 3015 |
|
/* Use a PC-relative howto and subtract the instruction's address |
| 3016 |
|
from the target address we calculated above. */ |
| 3017 |
|
howto->pc_relative = TRUE; |
| 3018 |
|
*relocation -= (input_section->output_section->vma |
| 3019 |
|
+ input_section->output_offset |
| 3020 |
|
+ section_offset); |
| 3021 |
|
} |
| 3022 |
return TRUE; |
return TRUE; |
| 3023 |
} |
} |
| 3024 |
|
|
| 3334 |
|
|
| 3335 |
R_RBR: |
R_RBR: |
| 3336 |
A relative branch which may be modified to become an |
A relative branch which may be modified to become an |
| 3337 |
absolute branch. FIXME: We don't implement this, |
absolute branch. |
|
although we should for symbols of storage mapping class |
|
|
XMC_XO. |
|
| 3338 |
|
|
| 3339 |
R_RL: |
R_RL: |
| 3340 |
The PowerPC AIX ABI describes this as a load which may be |
The PowerPC AIX ABI describes this as a load which may be |
| 3431 |
} |
} |
| 3432 |
else |
else |
| 3433 |
{ |
{ |
| 3434 |
|
if (info->unresolved_syms_in_objects != RM_IGNORE |
| 3435 |
|
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0) |
| 3436 |
|
{ |
| 3437 |
|
if (! ((*info->callbacks->undefined_symbol) |
| 3438 |
|
(info, h->root.root.string, |
| 3439 |
|
input_bfd, input_section, |
| 3440 |
|
rel->r_vaddr - input_section->vma, |
| 3441 |
|
(info->unresolved_syms_in_objects |
| 3442 |
|
== RM_GENERATE_ERROR)))) |
| 3443 |
|
return FALSE; |
| 3444 |
|
} |
| 3445 |
if (h->root.type == bfd_link_hash_defined |
if (h->root.type == bfd_link_hash_defined |
| 3446 |
|| h->root.type == bfd_link_hash_defweak) |
|| h->root.type == bfd_link_hash_defweak) |
| 3447 |
{ |
{ |
| 3457 |
+ sec->output_offset); |
+ sec->output_offset); |
| 3458 |
|
|
| 3459 |
} |
} |
| 3460 |
else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT))) |
else |
|
&& ! info->relocatable) |
|
| 3461 |
{ |
{ |
| 3462 |
if (! ((*info->callbacks->undefined_symbol) |
BFD_ASSERT (info->relocatable |
| 3463 |
(info, h->root.root.string, input_bfd, input_section, |
|| (info->static_link |
| 3464 |
rel->r_vaddr - input_section->vma, TRUE))) |
&& (h->flags & XCOFF_WAS_UNDEFINED) != 0) |
| 3465 |
return FALSE; |
|| (h->flags & XCOFF_DEF_DYNAMIC) != 0 |
| 3466 |
|
|| (h->flags & XCOFF_IMPORT) != 0); |
|
/* Don't try to process the reloc. It can't help, and |
|
|
it may generate another error. */ |
|
|
continue; |
|
| 3467 |
} |
} |
| 3468 |
} |
} |
| 3469 |
} |
} |
| 4027 |
LINESZ, |
LINESZ, |
| 4028 |
FILNMLEN, |
FILNMLEN, |
| 4029 |
TRUE, /* _bfd_coff_long_filenames */ |
TRUE, /* _bfd_coff_long_filenames */ |
| 4030 |
FALSE, /* _bfd_coff_long_section_names */ |
XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */ |
| 4031 |
3, /* _bfd_coff_default_section_alignment_power */ |
3, /* _bfd_coff_default_section_alignment_power */ |
| 4032 |
FALSE, /* _bfd_coff_force_symnames_in_strings */ |
FALSE, /* _bfd_coff_force_symnames_in_strings */ |
| 4033 |
2, /* _bfd_coff_debug_string_prefix_length */ |
2, /* _bfd_coff_debug_string_prefix_length */ |
| 4235 |
bfd_generic_is_group_section, |
bfd_generic_is_group_section, |
| 4236 |
bfd_generic_discard_group, |
bfd_generic_discard_group, |
| 4237 |
_bfd_generic_section_already_linked, |
_bfd_generic_section_already_linked, |
| 4238 |
|
_bfd_xcoff_define_common_symbol, |
| 4239 |
|
|
| 4240 |
/* Dynamic */ |
/* Dynamic */ |
| 4241 |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |
| 4280 |
LINESZ, |
LINESZ, |
| 4281 |
FILNMLEN, |
FILNMLEN, |
| 4282 |
TRUE, /* _bfd_coff_long_filenames */ |
TRUE, /* _bfd_coff_long_filenames */ |
| 4283 |
FALSE, /* _bfd_coff_long_section_names */ |
XCOFF_NO_LONG_SECTION_NAMES, /* _bfd_coff_long_section_names */ |
| 4284 |
3, /* _bfd_coff_default_section_alignment_power */ |
3, /* _bfd_coff_default_section_alignment_power */ |
| 4285 |
FALSE, /* _bfd_coff_force_symnames_in_strings */ |
FALSE, /* _bfd_coff_force_symnames_in_strings */ |
| 4286 |
2, /* _bfd_coff_debug_string_prefix_length */ |
2, /* _bfd_coff_debug_string_prefix_length */ |
| 4488 |
bfd_generic_is_group_section, |
bfd_generic_is_group_section, |
| 4489 |
bfd_generic_discard_group, |
bfd_generic_discard_group, |
| 4490 |
_bfd_generic_section_already_linked, |
_bfd_generic_section_already_linked, |
| 4491 |
|
_bfd_xcoff_define_common_symbol, |
| 4492 |
|
|
| 4493 |
/* Dynamic */ |
/* Dynamic */ |
| 4494 |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |
_bfd_xcoff_get_dynamic_symtab_upper_bound, |