2000-11-23 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / bfd / coff-rs6000.c
CommitLineData
252b5132 1/* BFD back-end for IBM RS/6000 "XCOFF" files.
5f771d47
ILT
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
252b5132
RH
4 FIXME: Can someone provide a transliteration of this name into ASCII?
5 Using the following chars caused a compiler warning on HIUX (so I replaced
6 them with octal escapes), and isn't useful without an understanding of what
7 character set it is.
c5930ee6 8 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
252b5132
RH
9 and John Gilmore.
10 Archive support from Damon A. Permezel.
11 Contributed by IBM Corporation and Cygnus Support.
12
13This file is part of BFD, the Binary File Descriptor library.
14
15This program is free software; you can redistribute it and/or modify
16it under the terms of the GNU General Public License as published by
17the Free Software Foundation; either version 2 of the License, or
18(at your option) any later version.
19
20This program is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23GNU General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, write to the Free Software
27Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28
252b5132
RH
29#include "bfd.h"
30#include "sysdep.h"
31#include "libbfd.h"
32#include "coff/internal.h"
33#include "coff/rs6000.h"
34#include "libcoff.h"
14958a43
CP
35#define TARGET_NAME "aixcoff-rs6000"
36#define TARGET_SYM rs6000coff_vec
2c38bc20 37#include "xcoff-target.h"
14958a43 38
252b5132
RH
39/* The main body of code is in coffcode.h. */
40
252b5132 41static const char *normalize_filename PARAMS ((bfd *));
14958a43 42
252b5132
RH
43/* We use our own tdata type. Its first field is the COFF tdata type,
44 so the COFF routines are compatible. */
45
7f6d05e8
CP
46boolean
47_bfd_xcoff_mkobject (abfd)
252b5132
RH
48 bfd *abfd;
49{
50 coff_data_type *coff;
51
52 abfd->tdata.xcoff_obj_data =
53 ((struct xcoff_tdata *)
54 bfd_zalloc (abfd, sizeof (struct xcoff_tdata)));
55 if (abfd->tdata.xcoff_obj_data == NULL)
56 return false;
57 coff = coff_data (abfd);
58 coff->symbols = (coff_symbol_type *) NULL;
59 coff->conversion_table = (unsigned int *) NULL;
60 coff->raw_syments = (struct coff_ptr_struct *) NULL;
61 coff->relocbase = 0;
62
63 xcoff_data (abfd)->modtype = ('1' << 8) | 'L';
64
65 /* We set cputype to -1 to indicate that it has not been
66 initialized. */
67 xcoff_data (abfd)->cputype = -1;
68
69 xcoff_data (abfd)->csects = NULL;
70 xcoff_data (abfd)->debug_indices = NULL;
71
72 return true;
73}
74
75/* Copy XCOFF data from one BFD to another. */
76
7f6d05e8
CP
77boolean
78_bfd_xcoff_copy_private_bfd_data (ibfd, obfd)
252b5132
RH
79 bfd *ibfd;
80 bfd *obfd;
81{
82 struct xcoff_tdata *ix, *ox;
83 asection *sec;
84
85 if (ibfd->xvec != obfd->xvec)
86 return true;
87 ix = xcoff_data (ibfd);
88 ox = xcoff_data (obfd);
89 ox->full_aouthdr = ix->full_aouthdr;
90 ox->toc = ix->toc;
91 if (ix->sntoc == 0)
92 ox->sntoc = 0;
93 else
94 {
95 sec = coff_section_from_bfd_index (ibfd, ix->sntoc);
96 if (sec == NULL)
97 ox->sntoc = 0;
98 else
99 ox->sntoc = sec->output_section->target_index;
100 }
101 if (ix->snentry == 0)
102 ox->snentry = 0;
103 else
104 {
105 sec = coff_section_from_bfd_index (ibfd, ix->snentry);
106 if (sec == NULL)
107 ox->snentry = 0;
108 else
109 ox->snentry = sec->output_section->target_index;
110 }
111 ox->text_align_power = ix->text_align_power;
112 ox->data_align_power = ix->data_align_power;
113 ox->modtype = ix->modtype;
114 ox->cputype = ix->cputype;
115 ox->maxdata = ix->maxdata;
116 ox->maxstack = ix->maxstack;
117 return true;
118}
119
120/* I don't think XCOFF really has a notion of local labels based on
121 name. This will mean that ld -X doesn't actually strip anything.
122 The AIX native linker does not have a -X option, and it ignores the
123 -x option. */
124
7f6d05e8
CP
125boolean
126_bfd_xcoff_is_local_label_name (abfd, name)
5f771d47
ILT
127 bfd *abfd ATTRIBUTE_UNUSED;
128 const char *name ATTRIBUTE_UNUSED;
252b5132
RH
129{
130 return false;
131}
7f6d05e8
CP
132\f
133
14958a43
CP
134void
135_bfd_xcoff_swap_sym_in (abfd, ext1, in1)
7f6d05e8
CP
136 bfd *abfd;
137 PTR ext1;
138 PTR in1;
139{
140 SYMENT *ext = (SYMENT *)ext1;
141 struct internal_syment *in = (struct internal_syment *)in1;
142
6e301b2b 143 if (ext->e.e_name[0] != 0)
7f6d05e8
CP
144 {
145 memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
146 }
c5930ee6 147 else
7f6d05e8
CP
148 {
149 in->_n._n_n._n_zeroes = 0;
c5930ee6 150 in->_n._n_n._n_offset =
7f6d05e8
CP
151 bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
152 }
153
c5930ee6 154 in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value);
7f6d05e8
CP
155 in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
156 in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
157 in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
158 in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
159}
160
14958a43
CP
161unsigned int
162_bfd_xcoff_swap_sym_out (abfd, inp, extp)
7f6d05e8
CP
163 bfd *abfd;
164 PTR inp;
165 PTR extp;
166{
167 struct internal_syment *in = (struct internal_syment *)inp;
168 SYMENT *ext =(SYMENT *)extp;
169
6e301b2b 170 if (in->_n._n_name[0] != 0)
7f6d05e8
CP
171 {
172 memcpy(ext->e.e_name, in->_n._n_name, SYMNMLEN);
173 }
174 else
175 {
176 bfd_h_put_32(abfd, 0, (bfd_byte *) ext->e.e.e_zeroes);
c5930ee6 177 bfd_h_put_32(abfd, in->_n._n_n._n_offset,
7f6d05e8
CP
178 (bfd_byte *) ext->e.e.e_offset);
179 }
180
181 bfd_h_put_32(abfd, in->n_value , (bfd_byte *) ext->e_value);
182 bfd_h_put_16(abfd, in->n_scnum , (bfd_byte *) ext->e_scnum);
183 bfd_h_put_16(abfd, in->n_type , (bfd_byte *) ext->e_type);
184 bfd_h_put_8(abfd, in->n_sclass , ext->e_sclass);
185 bfd_h_put_8(abfd, in->n_numaux , ext->e_numaux);
186 return bfd_coff_symesz (abfd);
187}
188
189#define PUTWORD bfd_h_put_32
190#define PUTHALF bfd_h_put_16
191#define PUTBYTE bfd_h_put_8
192#define GETWORD bfd_h_get_32
193#define GETHALF bfd_h_get_16
194#define GETBYTE bfd_h_get_8
195
14958a43
CP
196void
197_bfd_xcoff_swap_aux_in (abfd, ext1, type, class, indx, numaux, in1)
7f6d05e8
CP
198 bfd *abfd;
199 PTR ext1;
200 int type;
201 int class;
202 int indx;
203 int numaux;
204 PTR in1;
205{
206 AUXENT *ext = (AUXENT *)ext1;
207 union internal_auxent *in = (union internal_auxent *)in1;
208
209 switch (class) {
210 case C_FILE:
211 if (ext->x_file.x_fname[0] == 0) {
212 in->x_file.x_n.x_zeroes = 0;
c5930ee6 213 in->x_file.x_n.x_offset =
7f6d05e8
CP
214 bfd_h_get_32(abfd, (bfd_byte *) ext->x_file.x_n.x_offset);
215 } else {
216 if (numaux > 1)
217 {
218 if (indx == 0)
219 memcpy (in->x_file.x_fname, ext->x_file.x_fname,
220 numaux * sizeof (AUXENT));
221 }
222 else
223 {
224 memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
225 }
226 }
227 goto end;
228
229 /* RS/6000 "csect" auxents */
230 case C_EXT:
231 case C_HIDEXT:
232 if (indx + 1 == numaux)
233 {
c5930ee6 234 in->x_csect.x_scnlen.l =
7f6d05e8
CP
235 bfd_h_get_32 (abfd, ext->x_csect.x_scnlen);
236 in->x_csect.x_parmhash = bfd_h_get_32 (abfd,
237 ext->x_csect.x_parmhash);
238 in->x_csect.x_snhash = bfd_h_get_16 (abfd, ext->x_csect.x_snhash);
239 /* We don't have to hack bitfields in x_smtyp because it's
240 defined by shifts-and-ands, which are equivalent on all
241 byte orders. */
242 in->x_csect.x_smtyp = bfd_h_get_8 (abfd, ext->x_csect.x_smtyp);
243 in->x_csect.x_smclas = bfd_h_get_8 (abfd, ext->x_csect.x_smclas);
244 in->x_csect.x_stab = bfd_h_get_32 (abfd, ext->x_csect.x_stab);
245 in->x_csect.x_snstab = bfd_h_get_16 (abfd, ext->x_csect.x_snstab);
246 goto end;
247 }
248 break;
249
250 case C_STAT:
251 case C_LEAFSTAT:
252 case C_HIDDEN:
253 if (type == T_NULL) {
c5930ee6 254 in->x_scn.x_scnlen = bfd_h_get_32(abfd,
7f6d05e8 255 (bfd_byte *) ext->x_scn.x_scnlen);
c5930ee6 256 in->x_scn.x_nreloc = bfd_h_get_16(abfd,
7f6d05e8 257 (bfd_byte *) ext->x_scn.x_nreloc);
c5930ee6 258 in->x_scn.x_nlinno = bfd_h_get_16(abfd,
7f6d05e8
CP
259 (bfd_byte *) ext->x_scn.x_nlinno);
260 /* PE defines some extra fields; we zero them out for
261 safety. */
262 in->x_scn.x_checksum = 0;
263 in->x_scn.x_associated = 0;
264 in->x_scn.x_comdat = 0;
265
266 goto end;
267 }
268 break;
269 }
270
271 in->x_sym.x_tagndx.l = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_tagndx);
272 in->x_sym.x_tvndx = bfd_h_get_16(abfd, (bfd_byte *) ext->x_sym.x_tvndx);
273
274 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
275 {
276 in->x_sym.x_fcnary.x_fcn.x_lnnoptr = bfd_h_get_32(abfd, (bfd_byte *)
277 ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
278 in->x_sym.x_fcnary.x_fcn.x_endndx.l = bfd_h_get_32(abfd, (bfd_byte *)
279 ext->x_sym.x_fcnary.x_fcn.x_endndx);
280 }
281 else
282 {
283 in->x_sym.x_fcnary.x_ary.x_dimen[0] =
284 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
285 in->x_sym.x_fcnary.x_ary.x_dimen[1] =
286 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
287 in->x_sym.x_fcnary.x_ary.x_dimen[2] =
288 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
289 in->x_sym.x_fcnary.x_ary.x_dimen[3] =
290 bfd_h_get_16 (abfd, (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
291 }
292 if (ISFCN(type)) {
293 in->x_sym.x_misc.x_fsize = bfd_h_get_32(abfd, (bfd_byte *) ext->x_sym.x_misc.x_fsize);
294 }
295 else {
296 in->x_sym.x_misc.x_lnsz.x_lnno = bfd_h_get_16(abfd, (bfd_byte *)
297 ext->x_sym.x_misc.x_lnsz.x_lnno);
298 in->x_sym.x_misc.x_lnsz.x_size = bfd_h_get_16(abfd, (bfd_byte *)
299 ext->x_sym.x_misc.x_lnsz.x_size);
300 }
301
302end: ;
303 /* the semicolon is because MSVC doesn't like labels at
c5930ee6 304 end of block. */
7f6d05e8
CP
305
306}
307
14958a43
CP
308unsigned int
309_bfd_xcoff_swap_aux_out (abfd, inp, type, class, indx, numaux, extp)
7f6d05e8
CP
310 bfd *abfd;
311 PTR inp;
312 int type;
313 int class;
314 int indx ATTRIBUTE_UNUSED;
315 int numaux ATTRIBUTE_UNUSED;
316 PTR extp;
317{
318 union internal_auxent *in = (union internal_auxent *)inp;
319 AUXENT *ext = (AUXENT *)extp;
320
321 memset((PTR)ext, 0, bfd_coff_auxesz (abfd));
322 switch (class)
323 {
324 case C_FILE:
325 if (in->x_file.x_fname[0] == 0)
326 {
327 PUTWORD(abfd, 0, (bfd_byte *) ext->x_file.x_n.x_zeroes);
328 PUTWORD(abfd,
329 in->x_file.x_n.x_offset,
330 (bfd_byte *) ext->x_file.x_n.x_offset);
331 }
332 else
333 {
334 memcpy (ext->x_file.x_fname, in->x_file.x_fname, FILNMLEN);
335 }
336 goto end;
337
338 /* RS/6000 "csect" auxents */
339 case C_EXT:
340 case C_HIDEXT:
341 if (indx + 1 == numaux)
342 {
343 PUTWORD (abfd, in->x_csect.x_scnlen.l,ext->x_csect.x_scnlen);
344 PUTWORD (abfd, in->x_csect.x_parmhash, ext->x_csect.x_parmhash);
345 PUTHALF (abfd, in->x_csect.x_snhash, ext->x_csect.x_snhash);
346 /* We don't have to hack bitfields in x_smtyp because it's
347 defined by shifts-and-ands, which are equivalent on all
348 byte orders. */
349 PUTBYTE (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp);
350 PUTBYTE (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas);
351 PUTWORD (abfd, in->x_csect.x_stab, ext->x_csect.x_stab);
352 PUTHALF (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab);
353 goto end;
354 }
355 break;
356
357 case C_STAT:
358 case C_LEAFSTAT:
359 case C_HIDDEN:
360 if (type == T_NULL) {
361 bfd_h_put_32(abfd, in->x_scn.x_scnlen, (bfd_byte *) ext->x_scn.x_scnlen);
362 bfd_h_put_16(abfd, in->x_scn.x_nreloc, (bfd_byte *) ext->x_scn.x_nreloc);
363 bfd_h_put_16(abfd, in->x_scn.x_nlinno, (bfd_byte *) ext->x_scn.x_nlinno);
364 goto end;
365 }
366 break;
367 }
368
369 PUTWORD(abfd, in->x_sym.x_tagndx.l, (bfd_byte *) ext->x_sym.x_tagndx);
492055e6 370 bfd_h_put_16 (abfd, in->x_sym.x_tvndx , (bfd_byte *) ext->x_sym.x_tvndx);
7f6d05e8
CP
371
372 if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
373 {
c5930ee6 374 bfd_h_put_32(abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,
7f6d05e8 375 (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_lnnoptr);
c5930ee6 376 PUTWORD(abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l,
7f6d05e8
CP
377 (bfd_byte *) ext->x_sym.x_fcnary.x_fcn.x_endndx);
378 }
379 else
380 {
381 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
382 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
383 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
384 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
385 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
386 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
387 bfd_h_put_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
388 (bfd_byte *) ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
389 }
390
391 if (ISFCN (type))
392 PUTWORD (abfd, in->x_sym.x_misc.x_fsize,
393 (bfd_byte *) ext->x_sym.x_misc.x_fsize);
394 else
395 {
c5930ee6 396 bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_lnno,
7f6d05e8 397 (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_lnno);
c5930ee6 398 bfd_h_put_16(abfd, in->x_sym.x_misc.x_lnsz.x_size,
7f6d05e8
CP
399 (bfd_byte *)ext->x_sym.x_misc.x_lnsz.x_size);
400 }
401
402end:
403 return bfd_coff_auxesz (abfd);
404}
405
252b5132
RH
406\f
407/* The XCOFF reloc table. Actually, XCOFF relocations specify the
408 bitsize and whether they are signed or not, along with a
409 conventional type. This table is for the types, which are used for
410 different algorithms for putting in the reloc. Many of these
411 relocs need special_function entries, which I have not written. */
412
7f6d05e8
CP
413/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
414 from smaller values. Start with zero, widen, *then* decrement. */
415#define MINUS_ONE (((bfd_vma)0) - 1)
416
417reloc_howto_type xcoff_howto_table[] =
252b5132
RH
418{
419 /* Standard 32 bit relocation. */
c5930ee6
KH
420 HOWTO (0, /* type */
421 0, /* rightshift */
422 2, /* size (0 = byte, 1 = short, 2 = long) */
423 32, /* bitsize */
424 false, /* pc_relative */
425 0, /* bitpos */
252b5132 426 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
427 0, /* special_function */
428 "R_POS", /* name */
429 true, /* partial_inplace */
430 0xffffffff, /* src_mask */
431 0xffffffff, /* dst_mask */
252b5132
RH
432 false), /* pcrel_offset */
433
434 /* 32 bit relocation, but store negative value. */
c5930ee6
KH
435 HOWTO (1, /* type */
436 0, /* rightshift */
437 -2, /* size (0 = byte, 1 = short, 2 = long) */
438 32, /* bitsize */
439 false, /* pc_relative */
440 0, /* bitpos */
252b5132 441 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
442 0, /* special_function */
443 "R_NEG", /* name */
444 true, /* partial_inplace */
445 0xffffffff, /* src_mask */
446 0xffffffff, /* dst_mask */
252b5132
RH
447 false), /* pcrel_offset */
448
449 /* 32 bit PC relative relocation. */
c5930ee6
KH
450 HOWTO (2, /* type */
451 0, /* rightshift */
452 2, /* size (0 = byte, 1 = short, 2 = long) */
453 32, /* bitsize */
454 true, /* pc_relative */
455 0, /* bitpos */
252b5132 456 complain_overflow_signed, /* complain_on_overflow */
c5930ee6
KH
457 0, /* special_function */
458 "R_REL", /* name */
459 true, /* partial_inplace */
460 0xffffffff, /* src_mask */
461 0xffffffff, /* dst_mask */
252b5132 462 false), /* pcrel_offset */
c5930ee6 463
252b5132 464 /* 16 bit TOC relative relocation. */
c5930ee6
KH
465 HOWTO (3, /* type */
466 0, /* rightshift */
467 1, /* size (0 = byte, 1 = short, 2 = long) */
468 16, /* bitsize */
469 false, /* pc_relative */
470 0, /* bitpos */
252b5132 471 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
472 0, /* special_function */
473 "R_TOC", /* name */
474 true, /* partial_inplace */
475 0xffff, /* src_mask */
476 0xffff, /* dst_mask */
252b5132 477 false), /* pcrel_offset */
c5930ee6 478
252b5132 479 /* I don't really know what this is. */
c5930ee6
KH
480 HOWTO (4, /* type */
481 1, /* rightshift */
482 2, /* size (0 = byte, 1 = short, 2 = long) */
483 32, /* bitsize */
484 false, /* pc_relative */
485 0, /* bitpos */
252b5132 486 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
487 0, /* special_function */
488 "R_RTB", /* name */
489 true, /* partial_inplace */
490 0xffffffff, /* src_mask */
491 0xffffffff, /* dst_mask */
252b5132 492 false), /* pcrel_offset */
c5930ee6 493
252b5132 494 /* External TOC relative symbol. */
c5930ee6
KH
495 HOWTO (5, /* type */
496 0, /* rightshift */
497 2, /* size (0 = byte, 1 = short, 2 = long) */
498 16, /* bitsize */
499 false, /* pc_relative */
500 0, /* bitpos */
252b5132 501 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
502 0, /* special_function */
503 "R_GL", /* name */
504 true, /* partial_inplace */
505 0xffff, /* src_mask */
506 0xffff, /* dst_mask */
252b5132 507 false), /* pcrel_offset */
c5930ee6 508
252b5132 509 /* Local TOC relative symbol. */
c5930ee6
KH
510 HOWTO (6, /* type */
511 0, /* rightshift */
512 2, /* size (0 = byte, 1 = short, 2 = long) */
513 16, /* bitsize */
514 false, /* pc_relative */
515 0, /* bitpos */
252b5132 516 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
517 0, /* special_function */
518 "R_TCL", /* name */
519 true, /* partial_inplace */
520 0xffff, /* src_mask */
521 0xffff, /* dst_mask */
252b5132 522 false), /* pcrel_offset */
c5930ee6 523
5f771d47 524 EMPTY_HOWTO (7),
c5930ee6 525
252b5132 526 /* Non modifiable absolute branch. */
c5930ee6
KH
527 HOWTO (8, /* type */
528 0, /* rightshift */
529 2, /* size (0 = byte, 1 = short, 2 = long) */
530 26, /* bitsize */
531 false, /* pc_relative */
532 0, /* bitpos */
252b5132 533 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
534 0, /* special_function */
535 "R_BA", /* name */
536 true, /* partial_inplace */
537 0x3fffffc, /* src_mask */
538 0x3fffffc, /* dst_mask */
252b5132 539 false), /* pcrel_offset */
c5930ee6 540
5f771d47 541 EMPTY_HOWTO (9),
252b5132
RH
542
543 /* Non modifiable relative branch. */
c5930ee6
KH
544 HOWTO (0xa, /* type */
545 0, /* rightshift */
546 2, /* size (0 = byte, 1 = short, 2 = long) */
547 26, /* bitsize */
548 true, /* pc_relative */
549 0, /* bitpos */
252b5132 550 complain_overflow_signed, /* complain_on_overflow */
c5930ee6
KH
551 0, /* special_function */
552 "R_BR", /* name */
553 true, /* partial_inplace */
554 0x3fffffc, /* src_mask */
555 0x3fffffc, /* dst_mask */
252b5132 556 false), /* pcrel_offset */
c5930ee6 557
5f771d47 558 EMPTY_HOWTO (0xb),
252b5132
RH
559
560 /* Indirect load. */
c5930ee6
KH
561 HOWTO (0xc, /* type */
562 0, /* rightshift */
563 2, /* size (0 = byte, 1 = short, 2 = long) */
564 16, /* bitsize */
565 false, /* pc_relative */
566 0, /* bitpos */
252b5132 567 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
568 0, /* special_function */
569 "R_RL", /* name */
570 true, /* partial_inplace */
571 0xffff, /* src_mask */
572 0xffff, /* dst_mask */
252b5132 573 false), /* pcrel_offset */
c5930ee6 574
252b5132 575 /* Load address. */
c5930ee6
KH
576 HOWTO (0xd, /* type */
577 0, /* rightshift */
578 2, /* size (0 = byte, 1 = short, 2 = long) */
579 16, /* bitsize */
580 false, /* pc_relative */
581 0, /* bitpos */
252b5132 582 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
583 0, /* special_function */
584 "R_RLA", /* name */
585 true, /* partial_inplace */
586 0xffff, /* src_mask */
587 0xffff, /* dst_mask */
252b5132 588 false), /* pcrel_offset */
c5930ee6 589
5f771d47 590 EMPTY_HOWTO (0xe),
c5930ee6 591
252b5132 592 /* Non-relocating reference. */
c5930ee6
KH
593 HOWTO (0xf, /* type */
594 0, /* rightshift */
595 2, /* size (0 = byte, 1 = short, 2 = long) */
596 32, /* bitsize */
597 false, /* pc_relative */
598 0, /* bitpos */
252b5132 599 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
600 0, /* special_function */
601 "R_REF", /* name */
602 false, /* partial_inplace */
603 0, /* src_mask */
604 0, /* dst_mask */
252b5132 605 false), /* pcrel_offset */
c5930ee6 606
5f771d47
ILT
607 EMPTY_HOWTO (0x10),
608 EMPTY_HOWTO (0x11),
c5930ee6 609
252b5132 610 /* TOC relative indirect load. */
c5930ee6
KH
611 HOWTO (0x12, /* type */
612 0, /* rightshift */
613 2, /* size (0 = byte, 1 = short, 2 = long) */
614 16, /* bitsize */
615 false, /* pc_relative */
616 0, /* bitpos */
252b5132 617 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
618 0, /* special_function */
619 "R_TRL", /* name */
620 true, /* partial_inplace */
621 0xffff, /* src_mask */
622 0xffff, /* dst_mask */
252b5132 623 false), /* pcrel_offset */
c5930ee6 624
252b5132 625 /* TOC relative load address. */
c5930ee6
KH
626 HOWTO (0x13, /* type */
627 0, /* rightshift */
628 2, /* size (0 = byte, 1 = short, 2 = long) */
629 16, /* bitsize */
630 false, /* pc_relative */
631 0, /* bitpos */
252b5132 632 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
633 0, /* special_function */
634 "R_TRLA", /* name */
635 true, /* partial_inplace */
636 0xffff, /* src_mask */
637 0xffff, /* dst_mask */
252b5132 638 false), /* pcrel_offset */
c5930ee6 639
252b5132 640 /* Modifiable relative branch. */
c5930ee6
KH
641 HOWTO (0x14, /* type */
642 1, /* rightshift */
643 2, /* size (0 = byte, 1 = short, 2 = long) */
644 32, /* bitsize */
645 false, /* pc_relative */
646 0, /* bitpos */
252b5132 647 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
648 0, /* special_function */
649 "R_RRTBI", /* name */
650 true, /* partial_inplace */
651 0xffffffff, /* src_mask */
652 0xffffffff, /* dst_mask */
252b5132 653 false), /* pcrel_offset */
c5930ee6 654
252b5132 655 /* Modifiable absolute branch. */
c5930ee6
KH
656 HOWTO (0x15, /* type */
657 1, /* rightshift */
658 2, /* size (0 = byte, 1 = short, 2 = long) */
659 32, /* bitsize */
660 false, /* pc_relative */
661 0, /* bitpos */
252b5132 662 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
663 0, /* special_function */
664 "R_RRTBA", /* name */
665 true, /* partial_inplace */
666 0xffffffff, /* src_mask */
667 0xffffffff, /* dst_mask */
252b5132 668 false), /* pcrel_offset */
c5930ee6 669
252b5132 670 /* Modifiable call absolute indirect. */
c5930ee6
KH
671 HOWTO (0x16, /* type */
672 0, /* rightshift */
673 2, /* size (0 = byte, 1 = short, 2 = long) */
674 16, /* bitsize */
675 false, /* pc_relative */
676 0, /* bitpos */
252b5132 677 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
678 0, /* special_function */
679 "R_CAI", /* name */
680 true, /* partial_inplace */
681 0xffff, /* src_mask */
682 0xffff, /* dst_mask */
252b5132 683 false), /* pcrel_offset */
c5930ee6 684
252b5132 685 /* Modifiable call relative. */
c5930ee6
KH
686 HOWTO (0x17, /* type */
687 0, /* rightshift */
688 2, /* size (0 = byte, 1 = short, 2 = long) */
689 16, /* bitsize */
690 false, /* pc_relative */
691 0, /* bitpos */
252b5132 692 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
693 0, /* special_function */
694 "R_CREL", /* name */
695 true, /* partial_inplace */
696 0xffff, /* src_mask */
697 0xffff, /* dst_mask */
252b5132 698 false), /* pcrel_offset */
c5930ee6 699
252b5132 700 /* Modifiable branch absolute. */
c5930ee6
KH
701 HOWTO (0x18, /* type */
702 0, /* rightshift */
703 2, /* size (0 = byte, 1 = short, 2 = long) */
704 26, /* bitsize */
705 false, /* pc_relative */
706 0, /* bitpos */
252b5132 707 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
708 0, /* special_function */
709 "R_RBA", /* name */
710 true, /* partial_inplace */
711 0xffff, /* src_mask */
712 0xffff, /* dst_mask */
252b5132 713 false), /* pcrel_offset */
c5930ee6 714
252b5132 715 /* Modifiable branch absolute. */
c5930ee6
KH
716 HOWTO (0x19, /* type */
717 0, /* rightshift */
718 2, /* size (0 = byte, 1 = short, 2 = long) */
719 32, /* bitsize */
720 false, /* pc_relative */
721 0, /* bitpos */
252b5132 722 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
723 0, /* special_function */
724 "R_RBAC", /* name */
725 true, /* partial_inplace */
726 0xffff, /* src_mask */
727 0xffff, /* dst_mask */
252b5132 728 false), /* pcrel_offset */
c5930ee6 729
252b5132 730 /* Modifiable branch relative. */
c5930ee6
KH
731 HOWTO (0x1a, /* type */
732 0, /* rightshift */
733 2, /* size (0 = byte, 1 = short, 2 = long) */
734 26, /* bitsize */
735 false, /* pc_relative */
736 0, /* bitpos */
252b5132 737 complain_overflow_signed, /* complain_on_overflow */
c5930ee6
KH
738 0, /* special_function */
739 "R_RBR", /* name */
740 true, /* partial_inplace */
741 0xffff, /* src_mask */
742 0xffff, /* dst_mask */
252b5132 743 false), /* pcrel_offset */
c5930ee6 744
252b5132 745 /* Modifiable branch absolute. */
c5930ee6
KH
746 HOWTO (0x1b, /* type */
747 0, /* rightshift */
748 2, /* size (0 = byte, 1 = short, 2 = long) */
749 16, /* bitsize */
750 false, /* pc_relative */
751 0, /* bitpos */
252b5132 752 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
753 0, /* special_function */
754 "R_RBRC", /* name */
755 true, /* partial_inplace */
756 0xffff, /* src_mask */
757 0xffff, /* dst_mask */
7f6d05e8
CP
758 false), /* pcrel_offset */
759 HOWTO (0, /* type */
760 0, /* rightshift */
761 4, /* size (0 = byte, 1 = short, 2 = long) */
762 64, /* bitsize */
763 false, /* pc_relative */
764 0, /* bitpos */
765 complain_overflow_bitfield, /* complain_on_overflow */
766 0, /* special_function */
767 "R_POS", /* name */
768 true, /* partial_inplace */
769 MINUS_ONE, /* src_mask */
770 MINUS_ONE, /* dst_mask */
252b5132 771 false) /* pcrel_offset */
7f6d05e8 772
252b5132
RH
773};
774
5ea1af0d
GK
775/* These are the first two like the above but for 16-bit relocs. */
776static reloc_howto_type xcoff_howto_table_16[] =
777{
778 /* Standard 16 bit relocation. */
c5930ee6
KH
779 HOWTO (0, /* type */
780 0, /* rightshift */
781 2, /* size (0 = byte, 1 = short, 2 = long) */
782 16, /* bitsize */
783 false, /* pc_relative */
784 0, /* bitpos */
5ea1af0d 785 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
786 0, /* special_function */
787 "R_POS_16", /* name */
788 true, /* partial_inplace */
789 0xffffffff, /* src_mask */
790 0xffffffff, /* dst_mask */
5ea1af0d
GK
791 false), /* pcrel_offset */
792
793 /* 16 bit relocation, but store negative value. */
c5930ee6
KH
794 HOWTO (1, /* type */
795 0, /* rightshift */
796 -2, /* size (0 = byte, 1 = short, 2 = long) */
797 16, /* bitsize */
798 false, /* pc_relative */
799 0, /* bitpos */
5ea1af0d 800 complain_overflow_bitfield, /* complain_on_overflow */
c5930ee6
KH
801 0, /* special_function */
802 "R_NEG_16", /* name */
803 true, /* partial_inplace */
804 0xffffffff, /* src_mask */
805 0xffffffff, /* dst_mask */
5ea1af0d
GK
806 false), /* pcrel_offset */
807
808 /* 16 bit PC relative relocation. */
c5930ee6
KH
809 HOWTO (2, /* type */
810 0, /* rightshift */
811 2, /* size (0 = byte, 1 = short, 2 = long) */
812 32, /* bitsize */
813 true, /* pc_relative */
814 0, /* bitpos */
5ea1af0d 815 complain_overflow_signed, /* complain_on_overflow */
c5930ee6
KH
816 0, /* special_function */
817 "R_REL_16", /* name */
818 true, /* partial_inplace */
819 0xffffffff, /* src_mask */
820 0xffffffff, /* dst_mask */
7f6d05e8
CP
821 false) /* pcrel_offset */
822 };
c5930ee6 823
7f6d05e8
CP
824void
825_bfd_xcoff_rtype2howto (relent, internal)
252b5132
RH
826 arelent *relent;
827 struct internal_reloc *internal;
828{
829 relent->howto = xcoff_howto_table + internal->r_type;
830
5ea1af0d 831 if (relent->howto->bitsize != ((unsigned int) internal->r_size & 0x1f) + 1
c5930ee6
KH
832 && (internal->r_type
833 < sizeof (xcoff_howto_table_16)/sizeof (xcoff_howto_table_16[0])))
5ea1af0d
GK
834 relent->howto = xcoff_howto_table_16 + internal->r_type;
835
252b5132
RH
836 /* The r_size field of an XCOFF reloc encodes the bitsize of the
837 relocation, as well as indicating whether it is signed or not.
838 Doublecheck that the relocation information gathered from the
c5930ee6
KH
839 type matches this information. The bitsize is not significant
840 for R_REF relocs. */
841 if (relent->howto->dst_mask != 0
842 && (relent->howto->bitsize
843 != ((unsigned int) internal->r_size & 0x3f) + 1))
252b5132
RH
844 abort ();
845#if 0
846 if ((internal->r_size & 0x80) != 0
847 ? (relent->howto->complain_on_overflow != complain_overflow_signed)
848 : (relent->howto->complain_on_overflow != complain_overflow_bitfield))
849 abort ();
850#endif
851}
852
7f6d05e8
CP
853reloc_howto_type *
854_bfd_xcoff_reloc_type_lookup (abfd, code)
5f771d47 855 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
856 bfd_reloc_code_real_type code;
857{
858 switch (code)
859 {
860 case BFD_RELOC_PPC_B26:
861 return &xcoff_howto_table[0xa];
862 case BFD_RELOC_PPC_BA26:
863 return &xcoff_howto_table[8];
864 case BFD_RELOC_PPC_TOC16:
865 return &xcoff_howto_table[3];
866 case BFD_RELOC_32:
867 case BFD_RELOC_CTOR:
868 return &xcoff_howto_table[0];
7f6d05e8
CP
869 case BFD_RELOC_64:
870 return &xcoff_howto_table[0x1c];
252b5132
RH
871 default:
872 return NULL;
873 }
874}
875
252b5132
RH
876\f
877/* XCOFF archive support. The original version of this code was by
878 Damon A. Permezel. It was enhanced to permit cross support, and
879 writing archive files, by Ian Lance Taylor, Cygnus Support.
880
881 XCOFF uses its own archive format. Everything is hooked together
882 with file offset links, so it is possible to rapidly update an
883 archive in place. Of course, we don't do that. An XCOFF archive
884 has a real file header, not just an ARMAG string. The structure of
885 the file header and of each archive header appear below.
886
887 An XCOFF archive also has a member table, which is a list of
888 elements in the archive (you can get that by looking through the
889 linked list, but you have to read a lot more of the file). The
890 member table has a normal archive header with an empty name. It is
891 normally (and perhaps must be) the second to last entry in the
892 archive. The member table data is almost printable ASCII. It
893 starts with a 12 character decimal string which is the number of
894 entries in the table. For each entry it has a 12 character decimal
895 string which is the offset in the archive of that member. These
896 entries are followed by a series of null terminated strings which
897 are the member names for each entry.
898
899 Finally, an XCOFF archive has a global symbol table, which is what
900 we call the armap. The global symbol table has a normal archive
901 header with an empty name. It is normally (and perhaps must be)
902 the last entry in the archive. The contents start with a four byte
903 binary number which is the number of entries. This is followed by
904 a that many four byte binary numbers; each is the file offset of an
905 entry in the archive. These numbers are followed by a series of
5ea1af0d
GK
906 null terminated strings, which are symbol names.
907
908 AIX 4.3 introduced a new archive format which can handle larger
909 files and also 32- and 64-bit objects in the same archive. The
910 things said above remain true except that there is now more than
911 one global symbol table. The one is used to index 32-bit objects,
912 the other for 64-bit objects.
913
914 The new archives (recognizable by the new ARMAG string) has larger
915 field lengths so that we cannot really share any code. Also we have
916 to take care that we are not generating the new form of archives
917 on AIX 4.2 or earlier systems. */
252b5132 918
5ea1af0d
GK
919/* XCOFF archives use this as a magic string. Note that both strings
920 have the same length. */
252b5132 921
5ea1af0d
GK
922#define XCOFFARMAG "<aiaff>\012"
923#define XCOFFARMAGBIG "<bigaf>\012"
924#define SXCOFFARMAG 8
252b5132
RH
925
926/* This terminates an XCOFF archive member name. */
927
928#define XCOFFARFMAG "`\012"
929#define SXCOFFARFMAG 2
930
931/* XCOFF archives start with this (printable) structure. */
932
933struct xcoff_ar_file_hdr
934{
935 /* Magic string. */
936 char magic[SXCOFFARMAG];
937
938 /* Offset of the member table (decimal ASCII string). */
939 char memoff[12];
940
941 /* Offset of the global symbol table (decimal ASCII string). */
942 char symoff[12];
943
944 /* Offset of the first member in the archive (decimal ASCII string). */
945 char firstmemoff[12];
946
947 /* Offset of the last member in the archive (decimal ASCII string). */
948 char lastmemoff[12];
949
950 /* Offset of the first member on the free list (decimal ASCII
951 string). */
952 char freeoff[12];
953};
954
955#define SIZEOF_AR_FILE_HDR (5 * 12 + SXCOFFARMAG)
956
5ea1af0d
GK
957/* This is the equivalent data structure for the big archive format. */
958
959struct xcoff_ar_file_hdr_big
960{
961 /* Magic string. */
962 char magic[SXCOFFARMAG];
963
964 /* Offset of the member table (decimal ASCII string). */
965 char memoff[20];
966
967 /* Offset of the global symbol table for 32-bit objects (decimal ASCII
968 string). */
969 char symoff[20];
970
971 /* Offset of the global symbol table for 64-bit objects (decimal ASCII
972 string). */
973 char symoff64[20];
974
975 /* Offset of the first member in the archive (decimal ASCII string). */
976 char firstmemoff[20];
977
978 /* Offset of the last member in the archive (decimal ASCII string). */
979 char lastmemoff[20];
980
981 /* Offset of the first member on the free list (decimal ASCII
982 string). */
983 char freeoff[20];
984};
985
986#define SIZEOF_AR_FILE_HDR_BIG (6 * 20 + SXCOFFARMAG)
987
252b5132
RH
988/* Each XCOFF archive member starts with this (printable) structure. */
989
990struct xcoff_ar_hdr
991{
992 /* File size not including the header (decimal ASCII string). */
993 char size[12];
994
995 /* File offset of next archive member (decimal ASCII string). */
996 char nextoff[12];
997
998 /* File offset of previous archive member (decimal ASCII string). */
999 char prevoff[12];
1000
1001 /* File mtime (decimal ASCII string). */
1002 char date[12];
1003
1004 /* File UID (decimal ASCII string). */
1005 char uid[12];
1006
1007 /* File GID (decimal ASCII string). */
1008 char gid[12];
1009
1010 /* File mode (octal ASCII string). */
1011 char mode[12];
1012
1013 /* Length of file name (decimal ASCII string). */
1014 char namlen[4];
1015
1016 /* This structure is followed by the file name. The length of the
1017 name is given in the namlen field. If the length of the name is
1018 odd, the name is followed by a null byte. The name and optional
1019 null byte are followed by XCOFFARFMAG, which is not included in
1020 namlen. The contents of the archive member follow; the number of
1021 bytes is given in the size field. */
1022};
1023
1024#define SIZEOF_AR_HDR (7 * 12 + 4)
1025
5ea1af0d
GK
1026/* The equivalent for the big archive format. */
1027
1028struct xcoff_ar_hdr_big
1029{
1030 /* File size not including the header (decimal ASCII string). */
1031 char size[20];
1032
1033 /* File offset of next archive member (decimal ASCII string). */
1034 char nextoff[20];
1035
1036 /* File offset of previous archive member (decimal ASCII string). */
1037 char prevoff[20];
1038
1039 /* File mtime (decimal ASCII string). */
1040 char date[12];
1041
1042 /* File UID (decimal ASCII string). */
1043 char uid[12];
1044
1045 /* File GID (decimal ASCII string). */
1046 char gid[12];
1047
1048 /* File mode (octal ASCII string). */
1049 char mode[12];
1050
1051 /* Length of file name (decimal ASCII string). */
1052 char namlen[4];
1053
1054 /* This structure is followed by the file name. The length of the
1055 name is given in the namlen field. If the length of the name is
1056 odd, the name is followed by a null byte. The name and optional
1057 null byte are followed by XCOFFARFMAG, which is not included in
1058 namlen. The contents of the archive member follow; the number of
1059 bytes is given in the size field. */
1060};
1061
1062#define SIZEOF_AR_HDR_BIG (3 * 20 + 4 * 12 + 4)
1063
5ea1af0d
GK
1064/* We often have to distinguish between the old and big file format.
1065 Make it a bit cleaner. We can use `xcoff_ardata' here because the
1066 `hdr' member has the same size and position in both formats. */
1067#define xcoff_big_format_p(abfd) \
1068 (xcoff_ardata (abfd)->magic[1] == 'b')
1069
252b5132 1070/* We store a copy of the xcoff_ar_file_hdr in the tdata field of the
5ea1af0d 1071 artdata structure. Similar for the big archive. */
252b5132
RH
1072#define xcoff_ardata(abfd) \
1073 ((struct xcoff_ar_file_hdr *) bfd_ardata (abfd)->tdata)
5ea1af0d
GK
1074#define xcoff_ardata_big(abfd) \
1075 ((struct xcoff_ar_file_hdr_big *) bfd_ardata (abfd)->tdata)
252b5132
RH
1076
1077/* We store a copy of the xcoff_ar_hdr in the arelt_data field of an
5ea1af0d 1078 archive element. Similar for the big archive. */
252b5132
RH
1079#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
1080#define arch_xhdr(bfd) \
1081 ((struct xcoff_ar_hdr *) arch_eltdata (bfd)->arch_header)
5ea1af0d
GK
1082#define arch_xhdr_big(bfd) \
1083 ((struct xcoff_ar_hdr_big *) arch_eltdata (bfd)->arch_header)
252b5132 1084
252b5132
RH
1085/* Read in the armap of an XCOFF archive. */
1086
7f6d05e8
CP
1087boolean
1088_bfd_xcoff_slurp_armap (abfd)
252b5132
RH
1089 bfd *abfd;
1090{
1091 file_ptr off;
252b5132
RH
1092 size_t namlen;
1093 bfd_size_type sz;
1094 bfd_byte *contents, *cend;
31612ca6 1095 bfd_vma c, i;
252b5132
RH
1096 carsym *arsym;
1097 bfd_byte *p;
1098
1099 if (xcoff_ardata (abfd) == NULL)
1100 {
1101 bfd_has_map (abfd) = false;
1102 return true;
1103 }
1104
5ea1af0d 1105 if (! xcoff_big_format_p (abfd))
252b5132 1106 {
5ea1af0d
GK
1107 /* This is for the old format. */
1108 struct xcoff_ar_hdr hdr;
1109
1110 off = strtol (xcoff_ardata (abfd)->symoff, (char **) NULL, 10);
1111 if (off == 0)
1112 {
1113 bfd_has_map (abfd) = false;
1114 return true;
1115 }
1116
1117 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1118 return false;
1119
1120 /* The symbol table starts with a normal archive header. */
1121 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
1122 return false;
1123
1124 /* Skip the name (normally empty). */
1125 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1126 if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0)
1127 return false;
1128
1129 sz = strtol (hdr.size, (char **) NULL, 10);
31612ca6
GK
1130
1131 /* Read in the entire symbol table. */
1132 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1133 if (contents == NULL)
1134 return false;
1135 if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
1136 return false;
1137
1138 /* The symbol table starts with a four byte count. */
1139 c = bfd_h_get_32 (abfd, contents);
c5930ee6 1140
31612ca6
GK
1141 if (c * 4 >= sz)
1142 {
1143 bfd_set_error (bfd_error_bad_value);
1144 return false;
1145 }
c5930ee6 1146
31612ca6
GK
1147 bfd_ardata (abfd)->symdefs = ((carsym *)
1148 bfd_alloc (abfd, c * sizeof (carsym)));
1149 if (bfd_ardata (abfd)->symdefs == NULL)
1150 return false;
c5930ee6 1151
31612ca6
GK
1152 /* After the count comes a list of four byte file offsets. */
1153 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 4;
1154 i < c;
1155 ++i, ++arsym, p += 4)
1156 arsym->file_offset = bfd_h_get_32 (abfd, p);
252b5132 1157 }
5ea1af0d
GK
1158 else
1159 {
1160 /* This is for the new format. */
1161 struct xcoff_ar_hdr_big hdr;
252b5132 1162
5ea1af0d
GK
1163 off = strtol (xcoff_ardata_big (abfd)->symoff, (char **) NULL, 10);
1164 if (off == 0)
1165 {
1166 bfd_has_map (abfd) = false;
1167 return true;
1168 }
252b5132 1169
5ea1af0d
GK
1170 if (bfd_seek (abfd, off, SEEK_SET) != 0)
1171 return false;
252b5132 1172
5ea1af0d
GK
1173 /* The symbol table starts with a normal archive header. */
1174 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd)
1175 != SIZEOF_AR_HDR_BIG)
1176 return false;
1177
1178 /* Skip the name (normally empty). */
1179 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1180 if (bfd_seek (abfd, ((namlen + 1) & ~1) + SXCOFFARFMAG, SEEK_CUR) != 0)
1181 return false;
1182
1183 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1184 machines) since the field width is 20 and there numbers with more
1185 than 32 bits can be represented. */
1186 sz = strtol (hdr.size, (char **) NULL, 10);
252b5132 1187
31612ca6
GK
1188 /* Read in the entire symbol table. */
1189 contents = (bfd_byte *) bfd_alloc (abfd, sz);
1190 if (contents == NULL)
1191 return false;
1192 if (bfd_read ((PTR) contents, 1, sz, abfd) != sz)
1193 return false;
252b5132 1194
31612ca6
GK
1195 /* The symbol table starts with an eight byte count. */
1196 c = bfd_h_get_64 (abfd, contents);
252b5132 1197
31612ca6
GK
1198 if (c * 8 >= sz)
1199 {
1200 bfd_set_error (bfd_error_bad_value);
1201 return false;
1202 }
c5930ee6 1203
31612ca6
GK
1204 bfd_ardata (abfd)->symdefs = ((carsym *)
1205 bfd_alloc (abfd, c * sizeof (carsym)));
1206 if (bfd_ardata (abfd)->symdefs == NULL)
1207 return false;
c5930ee6 1208
31612ca6
GK
1209 /* After the count comes a list of eight byte file offsets. */
1210 for (i = 0, arsym = bfd_ardata (abfd)->symdefs, p = contents + 8;
1211 i < c;
1212 ++i, ++arsym, p += 8)
1213 arsym->file_offset = bfd_h_get_64 (abfd, p);
252b5132
RH
1214 }
1215
252b5132
RH
1216 /* After the file offsets come null terminated symbol names. */
1217 cend = contents + sz;
1218 for (i = 0, arsym = bfd_ardata (abfd)->symdefs;
1219 i < c;
1220 ++i, ++arsym, p += strlen ((char *) p) + 1)
1221 {
1222 if (p >= cend)
1223 {
1224 bfd_set_error (bfd_error_bad_value);
1225 return false;
1226 }
1227 arsym->name = (char *) p;
1228 }
1229
1230 bfd_ardata (abfd)->symdef_count = c;
1231 bfd_has_map (abfd) = true;
1232
1233 return true;
1234}
1235
1236/* See if this is an XCOFF archive. */
1237
7f6d05e8
CP
1238const bfd_target *
1239_bfd_xcoff_archive_p (abfd)
252b5132
RH
1240 bfd *abfd;
1241{
5ea1af0d 1242 char magic[SXCOFFARMAG];
252b5132 1243
5ea1af0d 1244 if (bfd_read ((PTR) magic, SXCOFFARMAG, 1, abfd) != SXCOFFARMAG)
252b5132
RH
1245 {
1246 if (bfd_get_error () != bfd_error_system_call)
1247 bfd_set_error (bfd_error_wrong_format);
1248 return NULL;
1249 }
1250
5ea1af0d
GK
1251 if (strncmp (magic, XCOFFARMAG, SXCOFFARMAG) != 0
1252 && strncmp (magic, XCOFFARMAGBIG, SXCOFFARMAG) != 0)
252b5132
RH
1253 {
1254 bfd_set_error (bfd_error_wrong_format);
1255 return NULL;
1256 }
1257
1258 /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
1259 involves a cast, we can't do it as the left operand of
1260 assignment. */
1261 abfd->tdata.aout_ar_data =
1262 (struct artdata *) bfd_zalloc (abfd, sizeof (struct artdata));
1263
1264 if (bfd_ardata (abfd) == (struct artdata *) NULL)
1265 return NULL;
1266
252b5132
RH
1267 bfd_ardata (abfd)->cache = NULL;
1268 bfd_ardata (abfd)->archive_head = NULL;
1269 bfd_ardata (abfd)->symdefs = NULL;
1270 bfd_ardata (abfd)->extended_names = NULL;
1271
5ea1af0d
GK
1272 /* Now handle the two formats. */
1273 if (magic[1] != 'b')
1274 {
1275 /* This is the old format. */
1276 struct xcoff_ar_file_hdr hdr;
252b5132 1277
5ea1af0d
GK
1278 /* Copy over the magic string. */
1279 memcpy (hdr.magic, magic, SXCOFFARMAG);
1280
1281 /* Now read the rest of the file header. */
1282 if (bfd_read ((PTR) &hdr.memoff, SIZEOF_AR_FILE_HDR - SXCOFFARMAG, 1,
1283 abfd) != SIZEOF_AR_FILE_HDR - SXCOFFARMAG)
1284 {
1285 if (bfd_get_error () != bfd_error_system_call)
1286 bfd_set_error (bfd_error_wrong_format);
1287 return NULL;
1288 }
1289
1290 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1291 (char **) NULL, 10);
1292
1293 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR);
1294 if (bfd_ardata (abfd)->tdata == NULL)
1295 return NULL;
1296
1297 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
1298 }
1299 else
1300 {
1301 /* This is the new format. */
1302 struct xcoff_ar_file_hdr_big hdr;
1303
1304 /* Copy over the magic string. */
1305 memcpy (hdr.magic, magic, SXCOFFARMAG);
1306
1307 /* Now read the rest of the file header. */
1308 if (bfd_read ((PTR) &hdr.memoff, SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG, 1,
1309 abfd) != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG)
1310 {
1311 if (bfd_get_error () != bfd_error_system_call)
1312 bfd_set_error (bfd_error_wrong_format);
1313 return NULL;
1314 }
1315
1316 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1317 machines) since the field width is 20 and there numbers with more
1318 than 32 bits can be represented. */
1319 bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
1320 (char **) NULL, 10);
1321
1322 bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR_BIG);
1323 if (bfd_ardata (abfd)->tdata == NULL)
1324 return NULL;
1325
1326 memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
1327 }
252b5132 1328
7f6d05e8 1329 if (! _bfd_xcoff_slurp_armap (abfd))
252b5132
RH
1330 {
1331 bfd_release (abfd, bfd_ardata (abfd));
1332 abfd->tdata.aout_ar_data = (struct artdata *) NULL;
1333 return NULL;
1334 }
1335
1336 return abfd->xvec;
1337}
1338
1339/* Read the archive header in an XCOFF archive. */
1340
7f6d05e8
CP
1341PTR
1342_bfd_xcoff_read_ar_hdr (abfd)
252b5132
RH
1343 bfd *abfd;
1344{
252b5132 1345 size_t namlen;
252b5132
RH
1346 struct areltdata *ret;
1347
252b5132
RH
1348 ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata));
1349 if (ret == NULL)
1350 return NULL;
5ea1af0d
GK
1351
1352 if (! xcoff_big_format_p (abfd))
1353 {
1354 struct xcoff_ar_hdr hdr;
1355 struct xcoff_ar_hdr *hdrp;
1356
1357 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR)
1358 {
1359 free (ret);
1360 return NULL;
1361 }
1362
1363 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1364 hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd,
1365 SIZEOF_AR_HDR + namlen + 1);
1366 if (hdrp == NULL)
1367 {
1368 free (ret);
1369 return NULL;
1370 }
1371 memcpy (hdrp, &hdr, SIZEOF_AR_HDR);
1372 if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen)
1373 {
1374 free (ret);
1375 return NULL;
1376 }
1377 ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0';
1378
1379 ret->arch_header = (char *) hdrp;
1380 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1381 ret->filename = (char *) hdrp + SIZEOF_AR_HDR;
1382 }
1383 else
1384 {
1385 struct xcoff_ar_hdr_big hdr;
1386 struct xcoff_ar_hdr_big *hdrp;
1387
1388 if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd)
1389 != SIZEOF_AR_HDR_BIG)
1390 {
1391 free (ret);
1392 return NULL;
1393 }
1394
1395 namlen = strtol (hdr.namlen, (char **) NULL, 10);
1396 hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd,
1397 SIZEOF_AR_HDR_BIG
1398 + namlen + 1);
1399 if (hdrp == NULL)
1400 {
1401 free (ret);
1402 return NULL;
1403 }
1404 memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG);
1405 if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR_BIG, 1, namlen, abfd) != namlen)
1406 {
1407 free (ret);
1408 return NULL;
1409 }
1410 ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0';
1411
1412 ret->arch_header = (char *) hdrp;
1413 /* XXX This actually has to be a call to strtoll (at least on 32-bit
1414 machines) since the field width is 20 and there numbers with more
1415 than 32 bits can be represented. */
1416 ret->parsed_size = strtol (hdr.size, (char **) NULL, 10);
1417 ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG;
1418 }
252b5132
RH
1419
1420 /* Skip over the XCOFFARFMAG at the end of the file name. */
1421 if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0)
1422 return NULL;
1423
1424 return (PTR) ret;
1425}
1426
1427/* Open the next element in an XCOFF archive. */
1428
7f6d05e8
CP
1429bfd *
1430_bfd_xcoff_openr_next_archived_file (archive, last_file)
252b5132
RH
1431 bfd *archive;
1432 bfd *last_file;
1433{
1434 file_ptr filestart;
1435
1436 if (xcoff_ardata (archive) == NULL)
1437 {
1438 bfd_set_error (bfd_error_invalid_operation);
1439 return NULL;
1440 }
1441
5ea1af0d
GK
1442 if (! xcoff_big_format_p (archive))
1443 {
1444 if (last_file == NULL)
1445 filestart = bfd_ardata (archive)->first_file_filepos;
1446 else
1447 filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL,
1448 10);
1449
1450 if (filestart == 0
1451 || filestart == strtol (xcoff_ardata (archive)->memoff,
1452 (char **) NULL, 10)
1453 || filestart == strtol (xcoff_ardata (archive)->symoff,
1454 (char **) NULL, 10))
1455 {
1456 bfd_set_error (bfd_error_no_more_archived_files);
1457 return NULL;
1458 }
1459 }
252b5132 1460 else
252b5132 1461 {
5ea1af0d
GK
1462 if (last_file == NULL)
1463 filestart = bfd_ardata (archive)->first_file_filepos;
1464 else
1465 /* XXX These actually have to be a calls to strtoll (at least
1466 on 32-bit machines) since the fields's width is 20 and
1467 there numbers with more than 32 bits can be represented. */
1468 filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
1469 10);
1470
1471 /* XXX These actually have to be calls to strtoll (at least on 32-bit
1472 machines) since the fields's width is 20 and there numbers with more
1473 than 32 bits can be represented. */
1474 if (filestart == 0
1475 || filestart == strtol (xcoff_ardata_big (archive)->memoff,
1476 (char **) NULL, 10)
1477 || filestart == strtol (xcoff_ardata_big (archive)->symoff,
1478 (char **) NULL, 10))
1479 {
1480 bfd_set_error (bfd_error_no_more_archived_files);
1481 return NULL;
1482 }
252b5132
RH
1483 }
1484
1485 return _bfd_get_elt_at_filepos (archive, filestart);
1486}
1487
1488/* Stat an element in an XCOFF archive. */
1489
7f6d05e8
CP
1490int
1491_bfd_xcoff_generic_stat_arch_elt (abfd, s)
252b5132
RH
1492 bfd *abfd;
1493 struct stat *s;
1494{
252b5132
RH
1495 if (abfd->arelt_data == NULL)
1496 {
1497 bfd_set_error (bfd_error_invalid_operation);
1498 return -1;
1499 }
1500
5ea1af0d
GK
1501 if (! xcoff_big_format_p (abfd))
1502 {
1503 struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd);
1504
1505 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1506 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1507 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1508 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1509 s->st_size = arch_eltdata (abfd)->parsed_size;
1510 }
1511 else
1512 {
1513 struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd);
252b5132 1514
5ea1af0d
GK
1515 s->st_mtime = strtol (hdrp->date, (char **) NULL, 10);
1516 s->st_uid = strtol (hdrp->uid, (char **) NULL, 10);
1517 s->st_gid = strtol (hdrp->gid, (char **) NULL, 10);
1518 s->st_mode = strtol (hdrp->mode, (char **) NULL, 8);
1519 s->st_size = arch_eltdata (abfd)->parsed_size;
1520 }
252b5132
RH
1521
1522 return 0;
1523}
1524
1525/* Normalize a file name for inclusion in an archive. */
1526
1527static const char *
1528normalize_filename (abfd)
1529 bfd *abfd;
1530{
1531 const char *file;
1532 const char *filename;
1533
1534 file = bfd_get_filename (abfd);
1535 filename = strrchr (file, '/');
1536 if (filename != NULL)
1537 filename++;
1538 else
1539 filename = file;
1540 return filename;
1541}
1542
1543/* Write out an XCOFF armap. */
1544
252b5132 1545static boolean
5ea1af0d 1546xcoff_write_armap_old (abfd, elength, map, orl_count, stridx)
252b5132 1547 bfd *abfd;
5f771d47 1548 unsigned int elength ATTRIBUTE_UNUSED;
252b5132
RH
1549 struct orl *map;
1550 unsigned int orl_count;
1551 int stridx;
1552{
1553 struct xcoff_ar_hdr hdr;
1554 char *p;
1555 unsigned char buf[4];
1556 bfd *sub;
1557 file_ptr fileoff;
1558 unsigned int i;
1559
1560 memset (&hdr, 0, sizeof hdr);
1561 sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx));
1562 sprintf (hdr.nextoff, "%d", 0);
1563 memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12);
1564 sprintf (hdr.date, "%d", 0);
1565 sprintf (hdr.uid, "%d", 0);
1566 sprintf (hdr.gid, "%d", 0);
1567 sprintf (hdr.mode, "%d", 0);
1568 sprintf (hdr.namlen, "%d", 0);
1569
1570 /* We need spaces, not null bytes, in the header. */
1571 for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++)
1572 if (*p == '\0')
1573 *p = ' ';
1574
1575 if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR
1576 || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
1577 return false;
5ea1af0d 1578
252b5132
RH
1579 bfd_h_put_32 (abfd, orl_count, buf);
1580 if (bfd_write (buf, 1, 4, abfd) != 4)
1581 return false;
1582
1583 sub = abfd->archive_head;
1584 fileoff = SIZEOF_AR_FILE_HDR;
1585 i = 0;
1586 while (sub != NULL && i < orl_count)
1587 {
1588 size_t namlen;
1589
1590 while (((bfd *) (map[i]).pos) == sub)
1591 {
1592 bfd_h_put_32 (abfd, fileoff, buf);
1593 if (bfd_write (buf, 1, 4, abfd) != 4)
1594 return false;
1595 ++i;
1596 }
1597 namlen = strlen (normalize_filename (sub));
1598 namlen = (namlen + 1) &~ 1;
1599 fileoff += (SIZEOF_AR_HDR
1600 + namlen
1601 + SXCOFFARFMAG
1602 + arelt_size (sub));
1603 fileoff = (fileoff + 1) &~ 1;
1604 sub = sub->next;
1605 }
1606
1607 for (i = 0; i < orl_count; i++)
1608 {
1609 const char *name;
1610 size_t namlen;
1611
1612 name = *map[i].name;
1613 namlen = strlen (name);
1614 if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
1615 return false;
1616 }
1617
1618 if ((stridx & 1) != 0)
1619 {
1620 char b;
1621
1622 b = '\0';
1623 if (bfd_write (&b, 1, 1, abfd) != 1)
1624 return false;
1625 }
1626
1627 return true;
1628}
1629
1a6df346 1630/* Write a single armap in the big format. */
252b5132 1631static boolean
1a6df346
GK
1632xcoff_write_one_armap_big (abfd, map, orl_count, orl_ccount, stridx, bits64,
1633 prevoff, nextoff)
252b5132 1634 bfd *abfd;
5ea1af0d
GK
1635 struct orl *map;
1636 unsigned int orl_count;
1a6df346
GK
1637 unsigned int orl_ccount;
1638 unsigned int stridx;
1639 int bits64;
1640 const char *prevoff;
1641 char *nextoff;
252b5132 1642{
5ea1af0d
GK
1643 struct xcoff_ar_hdr_big hdr;
1644 char *p;
1645 unsigned char buf[4];
252b5132 1646 bfd *sub;
5ea1af0d 1647 file_ptr fileoff;
1a6df346
GK
1648 const bfd_arch_info_type *arch_info;
1649 bfd *object_bfd;
252b5132 1650 unsigned int i;
252b5132 1651
5ea1af0d
GK
1652 memset (&hdr, 0, sizeof hdr);
1653 /* XXX This call actually should use %lld (at least on 32-bit
1654 machines) since the fields's width is 20 and there numbers with
1655 more than 32 bits can be represented. */
1a6df346
GK
1656 sprintf (hdr.size, "%ld", (long) (4 + orl_ccount * 4 + stridx));
1657 if (bits64)
1658 sprintf (hdr.nextoff, "%d", 0);
1659 else
1660 sprintf (hdr.nextoff, "%d", (strtol (prevoff, (char **) NULL, 10)
1661 + 4 + orl_ccount * 4 + stridx));
1662 memcpy (hdr.prevoff, prevoff, sizeof (hdr.prevoff));
5ea1af0d
GK
1663 sprintf (hdr.date, "%d", 0);
1664 sprintf (hdr.uid, "%d", 0);
1665 sprintf (hdr.gid, "%d", 0);
1666 sprintf (hdr.mode, "%d", 0);
1667 sprintf (hdr.namlen, "%d", 0);
252b5132 1668
5ea1af0d
GK
1669 /* We need spaces, not null bytes, in the header. */
1670 for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR_BIG; p++)
1671 if (*p == '\0')
1672 *p = ' ';
1673
1a6df346
GK
1674 memcpy (nextoff, hdr.nextoff, sizeof (hdr.nextoff));
1675
5ea1af0d
GK
1676 if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) != SIZEOF_AR_HDR_BIG
1677 || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG)
252b5132
RH
1678 return false;
1679
1a6df346 1680 bfd_h_put_32 (abfd, orl_ccount, buf);
5ea1af0d 1681 if (bfd_write (buf, 1, 4, abfd) != 4)
252b5132
RH
1682 return false;
1683
5ea1af0d
GK
1684 sub = abfd->archive_head;
1685 fileoff = SIZEOF_AR_FILE_HDR_BIG;
1686 i = 0;
1687 while (sub != NULL && i < orl_count)
252b5132 1688 {
5ea1af0d
GK
1689 size_t namlen;
1690
1a6df346
GK
1691 if ((bfd_arch_bits_per_address ((bfd *) map[i].pos) == 64) == bits64)
1692 while (((bfd *) (map[i]).pos) == sub)
1693 {
1694 bfd_h_put_32 (abfd, fileoff, buf);
1695 if (bfd_write (buf, 1, 4, abfd) != 4)
1696 return false;
1697 i++;
1698 }
1699 else
1700 while (((bfd *) (map[i]).pos) == sub)
1701 i++;
1702
5ea1af0d
GK
1703 namlen = strlen (normalize_filename (sub));
1704 namlen = (namlen + 1) &~ 1;
1705 fileoff += (SIZEOF_AR_HDR_BIG
1706 + namlen
1707 + SXCOFFARFMAG
1708 + arelt_size (sub));
1709 fileoff = (fileoff + 1) &~ 1;
1710 sub = sub->next;
1711 }
1712
1a6df346 1713 object_bfd = NULL;
5ea1af0d
GK
1714 for (i = 0; i < orl_count; i++)
1715 {
1716 const char *name;
1717 size_t namlen;
1a6df346
GK
1718 bfd *ob = (bfd *)map[i].pos;
1719
1720 if (ob != object_bfd)
1721 arch_info = bfd_get_arch_info (ob);
1722 if ((arch_info->bits_per_address == 64) != bits64)
1723 continue;
5ea1af0d
GK
1724
1725 name = *map[i].name;
1726 namlen = strlen (name);
1727 if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1)
1728 return false;
1729 }
1730
1731 if ((stridx & 1) != 0)
1732 {
1733 char b;
1734
1735 b = '\0';
1736 if (bfd_write (&b, 1, 1, abfd) != 1)
1737 return false;
1738 }
1739
1740 return true;
1741}
1742
1a6df346
GK
1743static boolean
1744xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
1745 bfd *abfd;
1746 unsigned int elength ATTRIBUTE_UNUSED;
1747 struct orl *map;
1748 unsigned int orl_count;
1749 int stridx;
1750{
1751 unsigned int i;
1752 unsigned int orl_count_32, orl_count_64;
1753 unsigned int stridx_32, stridx_64;
1754 const bfd_arch_info_type *arch_info;
1755 bfd *object_bfd;
1756
1757 /* First, we look through the symbols and work out which are
1758 from 32-bit objects and which from 64-bit ones. */
1759 orl_count_32 = 0;
1760 orl_count_64 = 0;
1761 stridx_32 = 0;
1762 stridx_64 = 0;
1763 object_bfd = NULL;
1764 for (i = 0; i < orl_count; i++)
1765 {
1766 bfd *ob = (bfd *)map[i].pos;
1767 unsigned int len;
1768 if (ob != object_bfd)
1769 arch_info = bfd_get_arch_info (ob);
1770 len = strlen (*map[i].name) + 1;
1771 if (arch_info->bits_per_address == 64)
1772 {
1773 orl_count_64++;
1774 stridx_64 += len;
1775 }
1776 else
1777 {
1778 orl_count_32++;
1779 stridx_32 += len;
1780 }
1781 object_bfd = ob;
1782 }
c5930ee6 1783 /* A quick sanity check... */
1a6df346
GK
1784 BFD_ASSERT (orl_count_64 + orl_count_32 == orl_count);
1785 BFD_ASSERT (stridx_64 + stridx_32 == stridx);
1786
1787 /* Now write out each map. */
1788 if (! xcoff_write_one_armap_big (abfd, map, orl_count, orl_count_32,
c5930ee6 1789 stridx_32, false,
1a6df346
GK
1790 xcoff_ardata_big (abfd)->memoff,
1791 xcoff_ardata_big (abfd)->symoff))
1792 return false;
1793 if (! xcoff_write_one_armap_big (abfd, map, orl_count, orl_count_64,
1794 stridx_64, true,
1795 xcoff_ardata_big (abfd)->symoff,
1796 xcoff_ardata_big (abfd)->symoff64))
1797 return false;
c5930ee6 1798
1a6df346
GK
1799 return true;
1800}
1801
7f6d05e8
CP
1802boolean
1803_bfd_xcoff_write_armap (abfd, elength, map, orl_count, stridx)
5ea1af0d
GK
1804 bfd *abfd;
1805 unsigned int elength ATTRIBUTE_UNUSED;
1806 struct orl *map;
1807 unsigned int orl_count;
1808 int stridx;
1809{
1810 if (! xcoff_big_format_p (abfd))
1811 return xcoff_write_armap_old (abfd, elength, map, orl_count, stridx);
1812 else
1813 return xcoff_write_armap_big (abfd, elength, map, orl_count, stridx);
1814}
1815
1816/* Write out an XCOFF archive. We always write an entire archive,
1817 rather than fussing with the freelist and so forth. */
1818
1819static boolean
1820xcoff_write_archive_contents_old (abfd)
1821 bfd *abfd;
1822{
1823 struct xcoff_ar_file_hdr fhdr;
1824 size_t count;
1825 size_t total_namlen;
1826 file_ptr *offsets;
1827 boolean makemap;
1828 boolean hasobjects;
1829 file_ptr prevoff, nextoff;
1830 bfd *sub;
1831 unsigned int i;
1832 struct xcoff_ar_hdr ahdr;
1833 bfd_size_type size;
1834 char *p;
1835 char decbuf[13];
1836
1837 memset (&fhdr, 0, sizeof fhdr);
1838 strncpy (fhdr.magic, XCOFFARMAG, SXCOFFARMAG);
1839 sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR);
1840 sprintf (fhdr.freeoff, "%d", 0);
1841
1842 count = 0;
1843 total_namlen = 0;
1844 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
1845 {
1846 ++count;
1847 total_namlen += strlen (normalize_filename (sub)) + 1;
1848 }
1849 offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
1850 if (offsets == NULL)
1851 return false;
1852
1853 if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
1854 return false;
1855
1856 makemap = bfd_has_map (abfd);
1857 hasobjects = false;
1858 prevoff = 0;
1859 nextoff = SIZEOF_AR_FILE_HDR;
1860 for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
1861 {
1862 const char *name;
252b5132
RH
1863 size_t namlen;
1864 struct xcoff_ar_hdr *ahdrp;
1865 bfd_size_type remaining;
1866
1867 if (makemap && ! hasobjects)
1868 {
1869 if (bfd_check_format (sub, bfd_object))
1870 hasobjects = true;
1871 }
1872
1873 name = normalize_filename (sub);
1874 namlen = strlen (name);
1875
1876 if (sub->arelt_data != NULL)
1877 ahdrp = arch_xhdr (sub);
1878 else
1879 ahdrp = NULL;
1880
1881 if (ahdrp == NULL)
1882 {
1883 struct stat s;
1884
1885 memset (&ahdr, 0, sizeof ahdr);
1886 ahdrp = &ahdr;
1887 if (stat (bfd_get_filename (sub), &s) != 0)
1888 {
1889 bfd_set_error (bfd_error_system_call);
1890 return false;
1891 }
1892
1893 sprintf (ahdrp->size, "%ld", (long) s.st_size);
1894 sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
1895 sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
1896 sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
1897 sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
1898
1899 if (sub->arelt_data == NULL)
1900 {
1901 sub->arelt_data = bfd_alloc (sub, sizeof (struct areltdata));
1902 if (sub->arelt_data == NULL)
1903 return false;
1904 }
1905
1906 arch_eltdata (sub)->parsed_size = s.st_size;
1907 }
1908
1909 sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
1910 sprintf (ahdrp->namlen, "%ld", (long) namlen);
1911
1912 /* If the length of the name is odd, we write out the null byte
1913 after the name as well. */
1914 namlen = (namlen + 1) &~ 1;
1915
1916 remaining = arelt_size (sub);
1917 size = (SIZEOF_AR_HDR
1918 + namlen
1919 + SXCOFFARFMAG
1920 + remaining);
1921
1922 BFD_ASSERT (nextoff == bfd_tell (abfd));
1923
1924 offsets[i] = nextoff;
1925
1926 prevoff = nextoff;
1927 nextoff += size + (size & 1);
1928
1929 sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
1930
1931 /* We need spaces, not null bytes, in the header. */
1932 for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
1933 if (*p == '\0')
1934 *p = ' ';
1935
1936 if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
1937 || bfd_write ((PTR) name, 1, namlen, abfd) != namlen
1938 || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
1939 != SXCOFFARFMAG))
1940 return false;
1941
1942 if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
1943 return false;
1944 while (remaining != 0)
1945 {
1946 bfd_size_type amt;
1947 bfd_byte buffer[DEFAULT_BUFFERSIZE];
1948
1949 amt = sizeof buffer;
1950 if (amt > remaining)
1951 amt = remaining;
1952 if (bfd_read (buffer, 1, amt, sub) != amt
1953 || bfd_write (buffer, 1, amt, abfd) != amt)
1954 return false;
1955 remaining -= amt;
1956 }
1957
1958 if ((size & 1) != 0)
1959 {
1960 bfd_byte b;
1961
1962 b = '\0';
1963 if (bfd_write (&b, 1, 1, abfd) != 1)
1964 return false;
1965 }
1966 }
1967
1968 sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
1969
1970 /* Write out the member table. */
1971
1972 BFD_ASSERT (nextoff == bfd_tell (abfd));
1973 sprintf (fhdr.memoff, "%ld", (long) nextoff);
1974
1975 memset (&ahdr, 0, sizeof ahdr);
1976 sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen));
1977 sprintf (ahdr.prevoff, "%ld", (long) prevoff);
1978 sprintf (ahdr.date, "%d", 0);
1979 sprintf (ahdr.uid, "%d", 0);
1980 sprintf (ahdr.gid, "%d", 0);
1981 sprintf (ahdr.mode, "%d", 0);
1982 sprintf (ahdr.namlen, "%d", 0);
1983
1984 size = (SIZEOF_AR_HDR
1985 + 12
1986 + count * 12
1987 + total_namlen
1988 + SXCOFFARFMAG);
1989
1990 prevoff = nextoff;
1991 nextoff += size + (size & 1);
1992
1993 if (makemap && hasobjects)
1994 sprintf (ahdr.nextoff, "%ld", (long) nextoff);
1995 else
1996 sprintf (ahdr.nextoff, "%d", 0);
1997
1998 /* We need spaces, not null bytes, in the header. */
1999 for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR; p++)
2000 if (*p == '\0')
2001 *p = ' ';
2002
2003 if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
2004 || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
2005 != SXCOFFARFMAG))
2006 return false;
2007
2008 sprintf (decbuf, "%-12ld", (long) count);
2009 if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
2010 return false;
2011 for (i = 0; i < count; i++)
2012 {
2013 sprintf (decbuf, "%-12ld", (long) offsets[i]);
2014 if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
2015 return false;
2016 }
2017 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2018 {
2019 const char *name;
2020 size_t namlen;
2021
2022 name = normalize_filename (sub);
2023 namlen = strlen (name);
2024 if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1)
2025 return false;
2026 }
2027 if ((size & 1) != 0)
2028 {
2029 bfd_byte b;
2030
2031 b = '\0';
2032 if (bfd_write ((PTR) &b, 1, 1, abfd) != 1)
2033 return false;
2034 }
2035
2036 /* Write out the armap, if appropriate. */
2037
2038 if (! makemap || ! hasobjects)
2039 sprintf (fhdr.symoff, "%d", 0);
2040 else
2041 {
2042 BFD_ASSERT (nextoff == bfd_tell (abfd));
2043 sprintf (fhdr.symoff, "%ld", (long) nextoff);
2044 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2045 if (! _bfd_compute_and_write_armap (abfd, 0))
2046 return false;
2047 }
2048
2049 /* Write out the archive file header. */
2050
2051 /* We need spaces, not null bytes, in the header. */
2052 for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR; p++)
2053 if (*p == '\0')
2054 *p = ' ';
2055
2056 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2057 || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR, 1, abfd) !=
2058 SIZEOF_AR_FILE_HDR))
2059 return false;
2060
2061 return true;
2062}
5ea1af0d
GK
2063
2064static boolean
2065xcoff_write_archive_contents_big (abfd)
2066 bfd *abfd;
2067{
2068 struct xcoff_ar_file_hdr_big fhdr;
2069 size_t count;
2070 size_t total_namlen;
2071 file_ptr *offsets;
2072 boolean makemap;
2073 boolean hasobjects;
2074 file_ptr prevoff, nextoff;
2075 bfd *sub;
2076 unsigned int i;
2077 struct xcoff_ar_hdr_big ahdr;
2078 bfd_size_type size;
2079 char *p;
2080 char decbuf[13];
2081
2082 memset (&fhdr, 0, sizeof fhdr);
2083 strncpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
2084 sprintf (fhdr.firstmemoff, "%d", SIZEOF_AR_FILE_HDR_BIG);
2085 sprintf (fhdr.freeoff, "%d", 0);
2086
2087 count = 0;
2088 total_namlen = 0;
2089 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2090 {
2091 ++count;
2092 total_namlen += strlen (normalize_filename (sub)) + 1;
2093 }
2094 offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2095 if (offsets == NULL)
2096 return false;
2097
2098 if (bfd_seek (abfd, SIZEOF_AR_FILE_HDR_BIG, SEEK_SET) != 0)
2099 return false;
2100
2101 makemap = bfd_has_map (abfd);
2102 hasobjects = false;
2103 prevoff = 0;
2104 nextoff = SIZEOF_AR_FILE_HDR_BIG;
2105 for (sub = abfd->archive_head, i = 0; sub != NULL; sub = sub->next, i++)
2106 {
2107 const char *name;
2108 size_t namlen;
2109 struct xcoff_ar_hdr_big *ahdrp;
2110 bfd_size_type remaining;
2111
2112 if (makemap && ! hasobjects)
2113 {
2114 if (bfd_check_format (sub, bfd_object))
2115 hasobjects = true;
2116 }
2117
2118 name = normalize_filename (sub);
2119 namlen = strlen (name);
2120
2121 if (sub->arelt_data != NULL)
2122 ahdrp = arch_xhdr_big (sub);
2123 else
2124 ahdrp = NULL;
2125
2126 if (ahdrp == NULL)
2127 {
2128 struct stat s;
2129
2130 memset (&ahdr, 0, sizeof ahdr);
2131 ahdrp = &ahdr;
2132 /* XXX This should actually be a call to stat64 (at least on
2133 32-bit machines). */
2134 if (stat (bfd_get_filename (sub), &s) != 0)
2135 {
2136 bfd_set_error (bfd_error_system_call);
2137 return false;
2138 }
2139
2140 /* XXX This call actually should use %lld (at least on 32-bit
2141 machines) since the fields's width is 20 and there numbers with
2142 more than 32 bits can be represented. */
2143 sprintf (ahdrp->size, "%ld", (long) s.st_size);
2144 sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2145 sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2146 sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2147 sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2148
2149 if (sub->arelt_data == NULL)
2150 {
2151 sub->arelt_data = bfd_alloc (sub, sizeof (struct areltdata));
2152 if (sub->arelt_data == NULL)
2153 return false;
2154 }
2155
2156 arch_eltdata (sub)->parsed_size = s.st_size;
2157 }
2158
2159 /* XXX These calls actually should use %lld (at least on 32-bit
2160 machines) since the fields's width is 20 and there numbers with
2161 more than 32 bits can be represented. */
2162 sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2163 sprintf (ahdrp->namlen, "%ld", (long) namlen);
2164
2165 /* If the length of the name is odd, we write out the null byte
2166 after the name as well. */
2167 namlen = (namlen + 1) &~ 1;
2168
2169 remaining = arelt_size (sub);
2170 size = (SIZEOF_AR_HDR_BIG
2171 + namlen
2172 + SXCOFFARFMAG
2173 + remaining);
2174
2175 BFD_ASSERT (nextoff == bfd_tell (abfd));
2176
2177 offsets[i] = nextoff;
2178
2179 prevoff = nextoff;
2180 nextoff += size + (size & 1);
2181
2182 sprintf (ahdrp->nextoff, "%ld", (long) nextoff);
2183
2184 /* We need spaces, not null bytes, in the header. */
2185 for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR_BIG; p++)
2186 if (*p == '\0')
2187 *p = ' ';
2188
2189 if (bfd_write ((PTR) ahdrp, 1, SIZEOF_AR_HDR_BIG, abfd)
2190 != SIZEOF_AR_HDR_BIG
2191 || bfd_write ((PTR) name, 1, namlen, abfd) != namlen
2192 || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
2193 != SXCOFFARFMAG))
2194 return false;
2195
2196 if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)
2197 return false;
2198 while (remaining != 0)
2199 {
2200 bfd_size_type amt;
2201 bfd_byte buffer[DEFAULT_BUFFERSIZE];
2202
2203 amt = sizeof buffer;
2204 if (amt > remaining)
2205 amt = remaining;
2206 if (bfd_read (buffer, 1, amt, sub) != amt
2207 || bfd_write (buffer, 1, amt, abfd) != amt)
2208 return false;
2209 remaining -= amt;
2210 }
2211
2212 if ((size & 1) != 0)
2213 {
2214 bfd_byte b;
2215
2216 b = '\0';
2217 if (bfd_write (&b, 1, 1, abfd) != 1)
2218 return false;
2219 }
2220 }
2221
2222 /* XXX This call actually should use %lld (at least on 32-bit
2223 machines) since the fields's width is 20 and there numbers with
2224 more than 32 bits can be represented. */
2225 sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2226
2227 /* Write out the member table. */
2228
2229 BFD_ASSERT (nextoff == bfd_tell (abfd));
2230 /* XXX This call actually should use %lld (at least on 32-bit
2231 machines) since the fields's width is 20 and there numbers with
2232 more than 32 bits can be represented. */
2233 sprintf (fhdr.memoff, "%ld", (long) nextoff);
2234
2235 memset (&ahdr, 0, sizeof ahdr);
2236 /* XXX The next two calls actually should use %lld (at least on 32-bit
2237 machines) since the fields's width is 20 and there numbers with
2238 more than 32 bits can be represented. */
2239 sprintf (ahdr.size, "%ld", (long) (12 + count * 12 + total_namlen));
2240 sprintf (ahdr.prevoff, "%ld", (long) prevoff);
2241 sprintf (ahdr.date, "%d", 0);
2242 sprintf (ahdr.uid, "%d", 0);
2243 sprintf (ahdr.gid, "%d", 0);
2244 sprintf (ahdr.mode, "%d", 0);
2245 sprintf (ahdr.namlen, "%d", 0);
2246
2247 size = (SIZEOF_AR_HDR_BIG
2248 + 12
2249 + count * 12
2250 + total_namlen
2251 + SXCOFFARFMAG);
2252
2253 prevoff = nextoff;
2254 nextoff += size + (size & 1);
2255
2256 if (makemap && hasobjects)
2257 /* XXX This call actually should use %lld (at least on 32-bit
2258 machines) since the fields's width is 20 and there numbers with
2259 more than 32 bits can be represented. */
2260 sprintf (ahdr.nextoff, "%ld", (long) nextoff);
2261 else
2262 sprintf (ahdr.nextoff, "%d", 0);
2263
2264 /* We need spaces, not null bytes, in the header. */
2265 for (p = (char *) &ahdr; p < (char *) &ahdr + SIZEOF_AR_HDR_BIG; p++)
2266 if (*p == '\0')
2267 *p = ' ';
2268
2269 if (bfd_write ((PTR) &ahdr, 1, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
2270 || (bfd_write ((PTR) XCOFFARFMAG, 1, SXCOFFARFMAG, abfd)
2271 != SXCOFFARFMAG))
2272 return false;
2273
2274 sprintf (decbuf, "%-12ld", (long) count);
2275 if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
2276 return false;
2277 for (i = 0; i < count; i++)
2278 {
2279 sprintf (decbuf, "%-12ld", (long) offsets[i]);
2280 if (bfd_write ((PTR) decbuf, 1, 12, abfd) != 12)
2281 return false;
2282 }
2283 for (sub = abfd->archive_head; sub != NULL; sub = sub->next)
2284 {
2285 const char *name;
2286 size_t namlen;
2287
2288 name = normalize_filename (sub);
2289 namlen = strlen (name);
2290 if (bfd_write ((PTR) name, 1, namlen + 1, abfd) != namlen + 1)
2291 return false;
2292 }
2293 if ((size & 1) != 0)
2294 {
2295 bfd_byte b;
2296
2297 b = '\0';
2298 if (bfd_write ((PTR) &b, 1, 1, abfd) != 1)
2299 return false;
2300 }
2301
2302 /* Write out the armap, if appropriate. */
2303
2304 if (! makemap || ! hasobjects)
2305 sprintf (fhdr.symoff, "%d", 0);
2306 else
2307 {
2308 BFD_ASSERT (nextoff == bfd_tell (abfd));
2309 /* XXX This call actually should use %lld (at least on 32-bit
2310 machines) since the fields's width is 20 and there numbers with
2311 more than 32 bits can be represented. */
5ea1af0d
GK
2312 bfd_ardata (abfd)->tdata = (PTR) &fhdr;
2313 if (! _bfd_compute_and_write_armap (abfd, 0))
2314 return false;
2315 }
2316
2317 /* Write out the archive file header. */
2318
2319 /* We need spaces, not null bytes, in the header. */
2320 for (p = (char *) &fhdr; p < (char *) &fhdr + SIZEOF_AR_FILE_HDR_BIG; p++)
2321 if (*p == '\0')
2322 *p = ' ';
2323
2324 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
2325 || (bfd_write ((PTR) &fhdr, SIZEOF_AR_FILE_HDR_BIG, 1, abfd) !=
2326 SIZEOF_AR_FILE_HDR_BIG))
2327 return false;
2328
2329 return true;
2330}
2331
7f6d05e8
CP
2332boolean
2333_bfd_xcoff_write_archive_contents (abfd)
5ea1af0d
GK
2334 bfd *abfd;
2335{
2336 if (! xcoff_big_format_p (abfd))
2337 return xcoff_write_archive_contents_old (abfd);
2338 else
2339 return xcoff_write_archive_contents_big (abfd);
2340}
252b5132
RH
2341\f
2342/* We can't use the usual coff_sizeof_headers routine, because AIX
2343 always uses an a.out header. */
2344
7f6d05e8 2345int
252b5132
RH
2346_bfd_xcoff_sizeof_headers (abfd, reloc)
2347 bfd *abfd;
5f771d47 2348 boolean reloc ATTRIBUTE_UNUSED;
252b5132
RH
2349{
2350 int size;
2351
2352 size = FILHSZ;
2353 if (xcoff_data (abfd)->full_aouthdr)
2354 size += AOUTSZ;
2355 else
2356 size += SMALL_AOUTSZ;
2357 size += abfd->section_count * SCNHSZ;
2358 return size;
2359}
This page took 0.35185 seconds and 4 git commands to generate.