Coverage Report

Created: 2023-06-29 07:13

/src/binutils-gdb/bfd/pe-aarch64igen.c
Line
Count
Source (jump to first uncovered line)
1
#line 1 "peXXigen.c"
2
/* Support for the generic parts of PE/PEI; the common executable parts.
3
   Copyright (C) 1995-2023 Free Software Foundation, Inc.
4
   Written by Cygnus Solutions.
5
6
   This file is part of BFD, the Binary File Descriptor library.
7
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
23
24
/* Most of this hacked by Steve Chamberlain <sac@cygnus.com>.
25
26
   PE/PEI rearrangement (and code added): Donn Terry
27
            Softway Systems, Inc.  */
28
29
/* Hey look, some documentation [and in a place you expect to find it]!
30
31
   The main reference for the pei format is "Microsoft Portable Executable
32
   and Common Object File Format Specification 4.1".  Get it if you need to
33
   do some serious hacking on this code.
34
35
   Another reference:
36
   "Peering Inside the PE: A Tour of the Win32 Portable Executable
37
   File Format", MSJ 1994, Volume 9.
38
39
   The PE/PEI format is also used by .NET. ECMA-335 describes this:
40
41
   "Standard ECMA-335 Common Language Infrastructure (CLI)", 6th Edition, June 2012.
42
43
   This is also available at
44
   https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf.
45
46
   The *sole* difference between the pe format and the pei format is that the
47
   latter has an MSDOS 2.0 .exe header on the front that prints the message
48
   "This app must be run under Windows." (or some such).
49
   (FIXME: Whether that statement is *really* true or not is unknown.
50
   Are there more subtle differences between pe and pei formats?
51
   For now assume there aren't.  If you find one, then for God sakes
52
   document it here!)
53
54
   The Microsoft docs use the word "image" instead of "executable" because
55
   the former can also refer to a DLL (shared library).  Confusion can arise
56
   because the `i' in `pei' also refers to "image".  The `pe' format can
57
   also create images (i.e. executables), it's just that to run on a win32
58
   system you need to use the pei format.
59
60
   FIXME: Please add more docs here so the next poor fool that has to hack
61
   on this code has a chance of getting something accomplished without
62
   wasting too much time.  */
63
64
/* This expands into COFF_WITH_pe, COFF_WITH_pep, COFF_WITH_pex64,
65
   COFF_WITH_peAArch64 or COFF_WITH_peLoongArch64 depending on whether we're
66
   compiling for straight PE or PE+.  */
67
#define COFF_WITH_peAArch64
68
69
#include "sysdep.h"
70
#include "bfd.h"
71
#include "libbfd.h"
72
#include "coff/internal.h"
73
#include "bfdver.h"
74
#include "libiberty.h"
75
#include <wchar.h>
76
#include <wctype.h>
77
78
/* NOTE: it's strange to be including an architecture specific header
79
   in what's supposed to be general (to PE/PEI) code.  However, that's
80
   where the definitions are, and they don't vary per architecture
81
   within PE/PEI, so we get them from there.  FIXME: The lack of
82
   variance is an assumption which may prove to be incorrect if new
83
   PE/PEI targets are created.  */
84
#if defined COFF_WITH_pex64
85
# include "coff/x86_64.h"
86
#elif defined COFF_WITH_pep
87
# include "coff/ia64.h"
88
#elif defined COFF_WITH_peAArch64
89
# include "coff/aarch64.h"
90
#elif defined COFF_WITH_peLoongArch64
91
# include "coff/loongarch64.h"
92
#else
93
# include "coff/i386.h"
94
#endif
95
96
#include "coff/pe.h"
97
#include "libcoff.h"
98
#include "libpei.h"
99
#include "safe-ctype.h"
100
101
#if defined COFF_WITH_pep || defined COFF_WITH_pex64 || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64
102
# undef AOUTSZ
103
1
# define AOUTSZ   PEPAOUTSZ
104
58.5k
# define PEAOUTHDR  PEPAOUTHDR
105
#endif
106
107
1.54k
#define HighBitSet(val)      ((val) & 0x80000000)
108
#define SetHighBit(val)      ((val) | 0x80000000)
109
171
#define WithoutHighBit(val)  ((val) & 0x7fffffff)
110

111
void
112
_bfd_peAArch64i_swap_sym_in (bfd * abfd, void * ext1, void * in1)
113
1.53M
{
114
1.53M
  SYMENT *ext = (SYMENT *) ext1;
115
1.53M
  struct internal_syment *in = (struct internal_syment *) in1;
116
117
1.53M
  if (ext->e.e_name[0] == 0)
118
1.14M
    {
119
1.14M
      in->_n._n_n._n_zeroes = 0;
120
1.14M
      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
121
1.14M
    }
122
392k
  else
123
392k
    memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
124
125
1.53M
  in->n_value = H_GET_32 (abfd, ext->e_value);
126
1.53M
  in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
127
128
1.53M
  if (sizeof (ext->e_type) == 2)
129
1.53M
    in->n_type = H_GET_16 (abfd, ext->e_type);
130
0
  else
131
0
    in->n_type = H_GET_32 (abfd, ext->e_type);
132
133
1.53M
  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
134
1.53M
  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
135
136
1.53M
#ifndef STRICT_PE_FORMAT
137
  /* This is for Gnu-created DLLs.  */
138
139
  /* The section symbols for the .idata$ sections have class 0x68
140
     (C_SECTION), which MS documentation indicates is a section
141
     symbol.  Unfortunately, the value field in the symbol is simply a
142
     copy of the .idata section's flags rather than something useful.
143
     When these symbols are encountered, change the value to 0 so that
144
     they will be handled somewhat correctly in the bfd code.  */
145
1.53M
  if (in->n_sclass == C_SECTION)
146
42.0k
    {
147
42.0k
      char namebuf[SYMNMLEN + 1];
148
42.0k
      const char *name = NULL;
149
150
42.0k
      in->n_value = 0x0;
151
152
      /* Create synthetic empty sections as needed.  DJ */
153
42.0k
      if (in->n_scnum == 0)
154
34.5k
  {
155
34.5k
    asection *sec;
156
157
34.5k
    name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
158
34.5k
    if (name == NULL)
159
5.95k
      {
160
5.95k
        _bfd_error_handler (_("%pB: unable to find name for empty section"),
161
5.95k
          abfd);
162
5.95k
        bfd_set_error (bfd_error_invalid_target);
163
5.95k
        return;
164
5.95k
      }
165
166
28.5k
    sec = bfd_get_section_by_name (abfd, name);
167
28.5k
    if (sec != NULL)
168
20.4k
      in->n_scnum = sec->target_index;
169
28.5k
  }
170
171
36.1k
      if (in->n_scnum == 0)
172
8.14k
  {
173
8.14k
    int unused_section_number = 0;
174
8.14k
    asection *sec;
175
8.14k
    flagword flags;
176
8.14k
    size_t name_len;
177
8.14k
    char *sec_name;
178
179
26.4k
    for (sec = abfd->sections; sec; sec = sec->next)
180
18.2k
      if (unused_section_number <= sec->target_index)
181
16.4k
        unused_section_number = sec->target_index + 1;
182
183
8.14k
    name_len = strlen (name) + 1;
184
8.14k
    sec_name = bfd_alloc (abfd, name_len);
185
8.14k
    if (sec_name == NULL)
186
0
      {
187
0
        _bfd_error_handler (_("%pB: out of memory creating name "
188
0
            "for empty section"), abfd);
189
0
        return;
190
0
      }
191
8.14k
    memcpy (sec_name, name, name_len);
192
193
8.14k
    flags = (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD
194
8.14k
       | SEC_LINKER_CREATED);
195
8.14k
    sec = bfd_make_section_anyway_with_flags (abfd, sec_name, flags);
196
8.14k
    if (sec == NULL)
197
0
      {
198
0
        _bfd_error_handler (_("%pB: unable to create fake empty section"),
199
0
          abfd);
200
0
        return;
201
0
      }
202
203
8.14k
    sec->alignment_power = 2;
204
8.14k
    sec->target_index = unused_section_number;
205
206
8.14k
    in->n_scnum = unused_section_number;
207
8.14k
  }
208
36.1k
      in->n_sclass = C_STAT;
209
36.1k
    }
210
1.53M
#endif
211
1.53M
}
212
213
static bool
214
abs_finder (bfd * abfd ATTRIBUTE_UNUSED, asection * sec, void * data)
215
0
{
216
0
  bfd_vma abs_val = * (bfd_vma *) data;
217
218
0
  return (sec->vma <= abs_val) && ((sec->vma + (1ULL << 32)) > abs_val);
219
0
}
220
221
unsigned int
222
_bfd_peAArch64i_swap_sym_out (bfd * abfd, void * inp, void * extp)
223
1.95k
{
224
1.95k
  struct internal_syment *in = (struct internal_syment *) inp;
225
1.95k
  SYMENT *ext = (SYMENT *) extp;
226
227
1.95k
  if (in->_n._n_name[0] == 0)
228
1.95k
    {
229
1.95k
      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
230
1.95k
      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
231
1.95k
    }
232
1
  else
233
1
    memcpy (ext->e.e_name, in->_n._n_name, SYMNMLEN);
234
235
  /* The PE32 and PE32+ formats only use 4 bytes to hold the value of a
236
     symbol.  This is a problem on 64-bit targets where we can generate
237
     absolute symbols with values >= 1^32.  We try to work around this
238
     problem by finding a section whose base address is sufficient to
239
     reduce the absolute value to < 1^32, and then transforming the
240
     symbol into a section relative symbol.  This of course is a hack.  */
241
1.95k
  if (sizeof (in->n_value) > 4
242
      /* The strange computation of the shift amount is here in order to
243
   avoid a compile time warning about the comparison always being
244
   false.  It does not matter if this test fails to work as expected
245
   as the worst that can happen is that some absolute symbols are
246
   needlessly converted into section relative symbols.  */
247
1.95k
      && in->n_value > ((1ULL << (sizeof (in->n_value) > 4 ? 32 : 31)) - 1)
248
1.95k
      && in->n_scnum == N_ABS)
249
0
    {
250
0
      asection * sec;
251
252
0
      sec = bfd_sections_find_if (abfd, abs_finder, & in->n_value);
253
0
      if (sec)
254
0
  {
255
0
    in->n_value -= sec->vma;
256
0
    in->n_scnum = sec->target_index;
257
0
  }
258
      /* else: FIXME: The value is outside the range of any section.  This
259
   happens for __image_base__ and __ImageBase and maybe some other
260
   symbols as well.  We should find a way to handle these values.  */
261
0
    }
262
263
1.95k
  H_PUT_32 (abfd, in->n_value, ext->e_value);
264
1.95k
  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
265
266
1.95k
  if (sizeof (ext->e_type) == 2)
267
1.95k
    H_PUT_16 (abfd, in->n_type, ext->e_type);
268
0
  else
269
1.95k
    H_PUT_32 (abfd, in->n_type, ext->e_type);
270
271
1.95k
  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
272
1.95k
  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
273
274
1.95k
  return SYMESZ;
275
1.95k
}
276
277
void
278
_bfd_peAArch64i_swap_aux_in (bfd *  abfd,
279
          void *  ext1,
280
          int       type,
281
          int       in_class,
282
          int indx ATTRIBUTE_UNUSED,
283
          int numaux ATTRIBUTE_UNUSED,
284
          void *  in1)
285
1.47M
{
286
1.47M
  AUXENT *ext = (AUXENT *) ext1;
287
1.47M
  union internal_auxent *in = (union internal_auxent *) in1;
288
289
  /* PR 17521: Make sure that all fields in the aux structure
290
     are initialised.  */
291
1.47M
  memset (in, 0, sizeof * in);
292
1.47M
  switch (in_class)
293
1.47M
    {
294
27.2k
    case C_FILE:
295
27.2k
      if (ext->x_file.x_fname[0] == 0)
296
12.0k
  {
297
12.0k
    in->x_file.x_n.x_n.x_zeroes = 0;
298
12.0k
    in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
299
12.0k
  }
300
15.1k
      else
301
15.1k
  memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
302
27.2k
      return;
303
304
32.7k
    case C_STAT:
305
36.1k
    case C_LEAFSTAT:
306
40.4k
    case C_HIDDEN:
307
40.4k
      if (type == T_NULL)
308
9.96k
  {
309
9.96k
    in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
310
9.96k
    in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
311
9.96k
    in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
312
9.96k
    in->x_scn.x_checksum = H_GET_32 (abfd, ext->x_scn.x_checksum);
313
9.96k
    in->x_scn.x_associated = H_GET_16 (abfd, ext->x_scn.x_associated);
314
9.96k
    in->x_scn.x_comdat = H_GET_8 (abfd, ext->x_scn.x_comdat);
315
9.96k
    return;
316
9.96k
  }
317
30.5k
      break;
318
1.47M
    }
319
320
1.43M
  in->x_sym.x_tagndx.u32 = H_GET_32 (abfd, ext->x_sym.x_tagndx);
321
1.43M
  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
322
323
1.43M
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
324
1.43M
      || ISTAG (in_class))
325
235k
    {
326
235k
      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
327
235k
      in->x_sym.x_fcnary.x_fcn.x_endndx.u32 = GET_FCN_ENDNDX (abfd, ext);
328
235k
    }
329
1.20M
  else
330
1.20M
    {
331
1.20M
      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
332
1.20M
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
333
1.20M
      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
334
1.20M
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
335
1.20M
      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
336
1.20M
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
337
1.20M
      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
338
1.20M
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
339
1.20M
    }
340
341
1.43M
  if (ISFCN (type))
342
200k
    {
343
200k
      in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
344
200k
    }
345
1.23M
  else
346
1.23M
    {
347
1.23M
      in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
348
1.23M
      in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
349
1.23M
    }
350
1.43M
}
351
352
unsigned int
353
_bfd_peAArch64i_swap_aux_out (bfd *  abfd,
354
           void * inp,
355
           int    type,
356
           int    in_class,
357
           int    indx ATTRIBUTE_UNUSED,
358
           int    numaux ATTRIBUTE_UNUSED,
359
           void * extp)
360
105
{
361
105
  union internal_auxent *in = (union internal_auxent *) inp;
362
105
  AUXENT *ext = (AUXENT *) extp;
363
364
105
  memset (ext, 0, AUXESZ);
365
366
105
  switch (in_class)
367
105
    {
368
0
    case C_FILE:
369
0
      if (in->x_file.x_n.x_fname[0] == 0)
370
0
  {
371
0
    H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
372
0
    H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
373
0
  }
374
0
      else
375
0
  memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, sizeof (ext->x_file.x_fname));
376
377
0
      return AUXESZ;
378
379
0
    case C_STAT:
380
0
    case C_LEAFSTAT:
381
0
    case C_HIDDEN:
382
0
      if (type == T_NULL)
383
0
  {
384
0
    PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
385
0
    PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
386
0
    PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
387
0
    H_PUT_32 (abfd, in->x_scn.x_checksum, ext->x_scn.x_checksum);
388
0
    H_PUT_16 (abfd, in->x_scn.x_associated, ext->x_scn.x_associated);
389
0
    H_PUT_8 (abfd, in->x_scn.x_comdat, ext->x_scn.x_comdat);
390
0
    return AUXESZ;
391
0
  }
392
0
      break;
393
105
    }
394
395
105
  H_PUT_32 (abfd, in->x_sym.x_tagndx.u32, ext->x_sym.x_tagndx);
396
105
  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
397
398
105
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
399
105
      || ISTAG (in_class))
400
105
    {
401
105
      PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,  ext);
402
105
      PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.u32, ext);
403
105
    }
404
0
  else
405
0
    {
406
0
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
407
0
    ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
408
0
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
409
0
    ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
410
0
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
411
0
    ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
412
0
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
413
0
    ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
414
0
    }
415
416
105
  if (ISFCN (type))
417
105
    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
418
0
  else
419
0
    {
420
0
      PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
421
0
      PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
422
0
    }
423
424
105
  return AUXESZ;
425
105
}
426
427
void
428
_bfd_peAArch64i_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
429
639k
{
430
639k
  LINENO *ext = (LINENO *) ext1;
431
639k
  struct internal_lineno *in = (struct internal_lineno *) in1;
432
433
639k
  in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
434
639k
  in->l_lnno = GET_LINENO_LNNO (abfd, ext);
435
639k
}
436
437
unsigned int
438
_bfd_peAArch64i_swap_lineno_out (bfd * abfd, void * inp, void * outp)
439
0
{
440
0
  struct internal_lineno *in = (struct internal_lineno *) inp;
441
0
  struct external_lineno *ext = (struct external_lineno *) outp;
442
0
  H_PUT_32 (abfd, in->l_addr.l_symndx, ext->l_addr.l_symndx);
443
444
0
  PUT_LINENO_LNNO (abfd, in->l_lnno, ext);
445
0
  return LINESZ;
446
0
}
447
448
void
449
_bfd_peAArch64i_swap_aouthdr_in (bfd * abfd,
450
        void * aouthdr_ext1,
451
        void * aouthdr_int1)
452
58.5k
{
453
58.5k
  PEAOUTHDR * src = (PEAOUTHDR *) aouthdr_ext1;
454
58.5k
  AOUTHDR * aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
455
58.5k
  struct internal_aouthdr *aouthdr_int
456
58.5k
    = (struct internal_aouthdr *) aouthdr_int1;
457
58.5k
  struct internal_extra_pe_aouthdr *a = &aouthdr_int->pe;
458
459
58.5k
  aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
460
58.5k
  aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
461
58.5k
  aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
462
58.5k
  aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
463
58.5k
  aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
464
58.5k
  aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
465
58.5k
  aouthdr_int->text_start =
466
58.5k
    GET_AOUTHDR_TEXT_START (abfd, aouthdr_ext->text_start);
467
468
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
469
  /* PE32+ does not have data_start member!  */
470
  aouthdr_int->data_start =
471
    GET_AOUTHDR_DATA_START (abfd, aouthdr_ext->data_start);
472
  a->BaseOfData = aouthdr_int->data_start;
473
#endif
474
475
58.5k
  a->Magic = aouthdr_int->magic;
476
58.5k
  a->MajorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp);
477
58.5k
  a->MinorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp + 1);
478
58.5k
  a->SizeOfCode = aouthdr_int->tsize ;
479
58.5k
  a->SizeOfInitializedData = aouthdr_int->dsize ;
480
58.5k
  a->SizeOfUninitializedData = aouthdr_int->bsize ;
481
58.5k
  a->AddressOfEntryPoint = aouthdr_int->entry;
482
58.5k
  a->BaseOfCode = aouthdr_int->text_start;
483
58.5k
  a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, src->ImageBase);
484
58.5k
  a->SectionAlignment = H_GET_32 (abfd, src->SectionAlignment);
485
58.5k
  a->FileAlignment = H_GET_32 (abfd, src->FileAlignment);
486
58.5k
  a->MajorOperatingSystemVersion =
487
58.5k
    H_GET_16 (abfd, src->MajorOperatingSystemVersion);
488
58.5k
  a->MinorOperatingSystemVersion =
489
58.5k
    H_GET_16 (abfd, src->MinorOperatingSystemVersion);
490
58.5k
  a->MajorImageVersion = H_GET_16 (abfd, src->MajorImageVersion);
491
58.5k
  a->MinorImageVersion = H_GET_16 (abfd, src->MinorImageVersion);
492
58.5k
  a->MajorSubsystemVersion = H_GET_16 (abfd, src->MajorSubsystemVersion);
493
58.5k
  a->MinorSubsystemVersion = H_GET_16 (abfd, src->MinorSubsystemVersion);
494
58.5k
  a->Reserved1 = H_GET_32 (abfd, src->Reserved1);
495
58.5k
  a->SizeOfImage = H_GET_32 (abfd, src->SizeOfImage);
496
58.5k
  a->SizeOfHeaders = H_GET_32 (abfd, src->SizeOfHeaders);
497
58.5k
  a->CheckSum = H_GET_32 (abfd, src->CheckSum);
498
58.5k
  a->Subsystem = H_GET_16 (abfd, src->Subsystem);
499
58.5k
  a->DllCharacteristics = H_GET_16 (abfd, src->DllCharacteristics);
500
58.5k
  a->SizeOfStackReserve =
501
58.5k
    GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, src->SizeOfStackReserve);
502
58.5k
  a->SizeOfStackCommit =
503
58.5k
    GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, src->SizeOfStackCommit);
504
58.5k
  a->SizeOfHeapReserve =
505
58.5k
    GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, src->SizeOfHeapReserve);
506
58.5k
  a->SizeOfHeapCommit =
507
58.5k
    GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, src->SizeOfHeapCommit);
508
58.5k
  a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
509
58.5k
  a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
510
511
  /* PR 17512: Don't blindly trust NumberOfRvaAndSizes.  */
512
58.5k
  unsigned idx;
513
58.5k
  for (idx = 0;
514
756k
       idx < a->NumberOfRvaAndSizes && idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
515
698k
       idx++)
516
698k
    {
517
      /* If data directory is empty, rva also should be 0.  */
518
698k
      int size = H_GET_32 (abfd, src->DataDirectory[idx][1]);
519
698k
      int vma = size ? H_GET_32 (abfd, src->DataDirectory[idx][0]) : 0;
520
521
698k
      a->DataDirectory[idx].Size = size;
522
698k
      a->DataDirectory[idx].VirtualAddress = vma;
523
698k
    }
524
525
297k
  while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
526
238k
    {
527
238k
      a->DataDirectory[idx].Size = 0;
528
238k
      a->DataDirectory[idx].VirtualAddress = 0;
529
238k
      idx++;
530
238k
    }
531
532
58.5k
  if (aouthdr_int->entry)
533
47.2k
    {
534
47.2k
      aouthdr_int->entry += a->ImageBase;
535
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
536
      aouthdr_int->entry &= 0xffffffff;
537
#endif
538
47.2k
    }
539
540
58.5k
  if (aouthdr_int->tsize)
541
41.1k
    {
542
41.1k
      aouthdr_int->text_start += a->ImageBase;
543
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
544
      aouthdr_int->text_start &= 0xffffffff;
545
#endif
546
41.1k
    }
547
548
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
549
  /* PE32+ does not have data_start member!  */
550
  if (aouthdr_int->dsize)
551
    {
552
      aouthdr_int->data_start += a->ImageBase;
553
      aouthdr_int->data_start &= 0xffffffff;
554
    }
555
#endif
556
58.5k
}
557
558
/* A support function for below.  */
559
560
static void
561
add_data_entry (bfd * abfd,
562
    struct internal_extra_pe_aouthdr *aout,
563
    int idx,
564
    char *name,
565
    bfd_vma base)
566
4
{
567
4
  asection *sec = bfd_get_section_by_name (abfd, name);
568
569
  /* Add import directory information if it exists.  */
570
4
  if ((sec != NULL)
571
4
      && (coff_section_data (abfd, sec) != NULL)
572
4
      && (pei_section_data (abfd, sec) != NULL))
573
0
    {
574
      /* If data directory is empty, rva also should be 0.  */
575
0
      int size = pei_section_data (abfd, sec)->virt_size;
576
0
      aout->DataDirectory[idx].Size = size;
577
578
0
      if (size)
579
0
  {
580
0
    aout->DataDirectory[idx].VirtualAddress =
581
0
      (sec->vma - base) & 0xffffffff;
582
0
    sec->flags |= SEC_DATA;
583
0
  }
584
0
    }
585
4
}
586
587
unsigned int
588
_bfd_peAArch64i_swap_aouthdr_out (bfd * abfd, void * in, void * out)
589
1
{
590
1
  struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
591
1
  pe_data_type *pe = pe_data (abfd);
592
1
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
593
1
  PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
594
1
  bfd_vma sa, fa, ib;
595
1
  IMAGE_DATA_DIRECTORY idata2, idata5, tls;
596
597
1
  sa = extra->SectionAlignment;
598
1
  fa = extra->FileAlignment;
599
1
  ib = extra->ImageBase;
600
601
1
  idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
602
1
  idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
603
1
  tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
604
605
1
  if (aouthdr_in->tsize)
606
0
    {
607
0
      aouthdr_in->text_start -= ib;
608
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
609
      aouthdr_in->text_start &= 0xffffffff;
610
#endif
611
0
    }
612
613
1
  if (aouthdr_in->dsize)
614
0
    {
615
0
      aouthdr_in->data_start -= ib;
616
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
617
      aouthdr_in->data_start &= 0xffffffff;
618
#endif
619
0
    }
620
621
1
  if (aouthdr_in->entry)
622
1
    {
623
1
      aouthdr_in->entry -= ib;
624
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
625
      aouthdr_in->entry &= 0xffffffff;
626
#endif
627
1
    }
628
629
2
#define FA(x) (((x) + fa -1 ) & (- fa))
630
1
#define SA(x) (((x) + sa -1 ) & (- sa))
631
632
  /* We like to have the sizes aligned.  */
633
1
  aouthdr_in->bsize = FA (aouthdr_in->bsize);
634
635
1
  extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
636
637
1
  add_data_entry (abfd, extra, PE_EXPORT_TABLE, ".edata", ib);
638
1
  add_data_entry (abfd, extra, PE_RESOURCE_TABLE, ".rsrc", ib);
639
1
  add_data_entry (abfd, extra, PE_EXCEPTION_TABLE, ".pdata", ib);
640
641
  /* In theory we do not need to call add_data_entry for .idata$2 or
642
     .idata$5.  It will be done in bfd_coff_final_link where all the
643
     required information is available.  If however, we are not going
644
     to perform a final link, eg because we have been invoked by objcopy
645
     or strip, then we need to make sure that these Data Directory
646
     entries are initialised properly.
647
648
     So - we copy the input values into the output values, and then, if
649
     a final link is going to be performed, it can overwrite them.  */
650
1
  extra->DataDirectory[PE_IMPORT_TABLE]  = idata2;
651
1
  extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
652
1
  extra->DataDirectory[PE_TLS_TABLE] = tls;
653
654
1
  if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0)
655
    /* Until other .idata fixes are made (pending patch), the entry for
656
       .idata is needed for backwards compatibility.  FIXME.  */
657
1
    add_data_entry (abfd, extra, PE_IMPORT_TABLE, ".idata", ib);
658
659
  /* For some reason, the virtual size (which is what's set by
660
     add_data_entry) for .reloc is not the same as the size recorded
661
     in this slot by MSVC; it doesn't seem to cause problems (so far),
662
     but since it's the best we've got, use it.  It does do the right
663
     thing for .pdata.  */
664
1
  if (pe->has_reloc_section)
665
0
    add_data_entry (abfd, extra, PE_BASE_RELOCATION_TABLE, ".reloc", ib);
666
667
1
  {
668
1
    asection *sec;
669
1
    bfd_vma hsize = 0;
670
1
    bfd_vma dsize = 0;
671
1
    bfd_vma isize = 0;
672
1
    bfd_vma tsize = 0;
673
674
2
    for (sec = abfd->sections; sec; sec = sec->next)
675
1
      {
676
1
  int rounded = FA (sec->size);
677
678
1
  if (rounded == 0)
679
1
    continue;
680
681
  /* The first non-zero section filepos is the header size.
682
     Sections without contents will have a filepos of 0.  */
683
0
  if (hsize == 0)
684
0
    hsize = sec->filepos;
685
0
  if (sec->flags & SEC_DATA)
686
0
    dsize += rounded;
687
0
  if (sec->flags & SEC_CODE)
688
0
    tsize += rounded;
689
  /* The image size is the total VIRTUAL size (which is what is
690
     in the virt_size field).  Files have been seen (from MSVC
691
     5.0 link.exe) where the file size of the .data segment is
692
     quite small compared to the virtual size.  Without this
693
     fix, strip munges the file.
694
695
     FIXME: We need to handle holes between sections, which may
696
     happpen when we covert from another format.  We just use
697
     the virtual address and virtual size of the last section
698
     for the image size.  */
699
0
  if (coff_section_data (abfd, sec) != NULL
700
0
      && pei_section_data (abfd, sec) != NULL)
701
0
    isize = (sec->vma - extra->ImageBase
702
0
       + SA (FA (pei_section_data (abfd, sec)->virt_size)));
703
0
      }
704
705
1
    aouthdr_in->dsize = dsize;
706
1
    aouthdr_in->tsize = tsize;
707
1
    extra->SizeOfHeaders = hsize;
708
1
    extra->SizeOfImage = isize;
709
1
  }
710
711
1
  H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
712
713
1
  if (extra->MajorLinkerVersion || extra->MinorLinkerVersion)
714
0
    {
715
0
      H_PUT_8 (abfd, extra->MajorLinkerVersion,
716
0
         aouthdr_out->standard.vstamp);
717
0
      H_PUT_8 (abfd, extra->MinorLinkerVersion,
718
0
         aouthdr_out->standard.vstamp + 1);
719
0
    }
720
1
  else
721
1
    {
722
/* e.g. 219510000 is linker version 2.19  */
723
1
#define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
724
725
      /* This piece of magic sets the "linker version" field to
726
   LINKER_VERSION.  */
727
1
      H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
728
1
    aouthdr_out->standard.vstamp);
729
1
    }
730
731
1
  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
732
1
  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
733
1
  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->standard.bsize);
734
1
  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->standard.entry);
735
1
  PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
736
1
        aouthdr_out->standard.text_start);
737
738
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
739
  /* PE32+ does not have data_start member!  */
740
  PUT_AOUTHDR_DATA_START (abfd, aouthdr_in->data_start,
741
        aouthdr_out->standard.data_start);
742
#endif
743
744
1
  PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, aouthdr_out->ImageBase);
745
1
  H_PUT_32 (abfd, extra->SectionAlignment, aouthdr_out->SectionAlignment);
746
1
  H_PUT_32 (abfd, extra->FileAlignment, aouthdr_out->FileAlignment);
747
1
  H_PUT_16 (abfd, extra->MajorOperatingSystemVersion,
748
1
      aouthdr_out->MajorOperatingSystemVersion);
749
1
  H_PUT_16 (abfd, extra->MinorOperatingSystemVersion,
750
1
      aouthdr_out->MinorOperatingSystemVersion);
751
1
  H_PUT_16 (abfd, extra->MajorImageVersion, aouthdr_out->MajorImageVersion);
752
1
  H_PUT_16 (abfd, extra->MinorImageVersion, aouthdr_out->MinorImageVersion);
753
1
  H_PUT_16 (abfd, extra->MajorSubsystemVersion,
754
1
      aouthdr_out->MajorSubsystemVersion);
755
1
  H_PUT_16 (abfd, extra->MinorSubsystemVersion,
756
1
      aouthdr_out->MinorSubsystemVersion);
757
1
  H_PUT_32 (abfd, extra->Reserved1, aouthdr_out->Reserved1);
758
1
  H_PUT_32 (abfd, extra->SizeOfImage, aouthdr_out->SizeOfImage);
759
1
  H_PUT_32 (abfd, extra->SizeOfHeaders, aouthdr_out->SizeOfHeaders);
760
1
  H_PUT_32 (abfd, extra->CheckSum, aouthdr_out->CheckSum);
761
1
  H_PUT_16 (abfd, extra->Subsystem, aouthdr_out->Subsystem);
762
1
  H_PUT_16 (abfd, extra->DllCharacteristics, aouthdr_out->DllCharacteristics);
763
1
  PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve,
764
1
            aouthdr_out->SizeOfStackReserve);
765
1
  PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit,
766
1
           aouthdr_out->SizeOfStackCommit);
767
1
  PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve,
768
1
           aouthdr_out->SizeOfHeapReserve);
769
1
  PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit,
770
1
          aouthdr_out->SizeOfHeapCommit);
771
1
  H_PUT_32 (abfd, extra->LoaderFlags, aouthdr_out->LoaderFlags);
772
1
  H_PUT_32 (abfd, extra->NumberOfRvaAndSizes,
773
1
      aouthdr_out->NumberOfRvaAndSizes);
774
1
  {
775
1
    int idx;
776
777
17
    for (idx = 0; idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; idx++)
778
16
      {
779
16
  H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
780
16
      aouthdr_out->DataDirectory[idx][0]);
781
16
  H_PUT_32 (abfd, extra->DataDirectory[idx].Size,
782
16
      aouthdr_out->DataDirectory[idx][1]);
783
16
      }
784
1
  }
785
786
1
  return AOUTSZ;
787
1
}
788
789
unsigned int
790
_bfd_peAArch64i_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
791
2
{
792
2
  int idx;
793
2
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
794
2
  struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *) out;
795
796
2
  if (pe_data (abfd)->has_reloc_section
797
2
      || pe_data (abfd)->dont_strip_reloc)
798
2
    filehdr_in->f_flags &= ~F_RELFLG;
799
800
2
  if (pe_data (abfd)->dll)
801
0
    filehdr_in->f_flags |= F_DLL;
802
803
2
  filehdr_in->pe.e_magic    = IMAGE_DOS_SIGNATURE;
804
2
  filehdr_in->pe.e_cblp     = 0x90;
805
2
  filehdr_in->pe.e_cp       = 0x3;
806
2
  filehdr_in->pe.e_crlc     = 0x0;
807
2
  filehdr_in->pe.e_cparhdr  = 0x4;
808
2
  filehdr_in->pe.e_minalloc = 0x0;
809
2
  filehdr_in->pe.e_maxalloc = 0xffff;
810
2
  filehdr_in->pe.e_ss       = 0x0;
811
2
  filehdr_in->pe.e_sp       = 0xb8;
812
2
  filehdr_in->pe.e_csum     = 0x0;
813
2
  filehdr_in->pe.e_ip       = 0x0;
814
2
  filehdr_in->pe.e_cs       = 0x0;
815
2
  filehdr_in->pe.e_lfarlc   = 0x40;
816
2
  filehdr_in->pe.e_ovno     = 0x0;
817
818
10
  for (idx = 0; idx < 4; idx++)
819
8
    filehdr_in->pe.e_res[idx] = 0x0;
820
821
2
  filehdr_in->pe.e_oemid   = 0x0;
822
2
  filehdr_in->pe.e_oeminfo = 0x0;
823
824
22
  for (idx = 0; idx < 10; idx++)
825
20
    filehdr_in->pe.e_res2[idx] = 0x0;
826
827
2
  filehdr_in->pe.e_lfanew = 0x80;
828
829
  /* This next collection of data are mostly just characters.  It
830
     appears to be constant within the headers put on NT exes.  */
831
2
  memcpy (filehdr_in->pe.dos_message, pe_data (abfd)->dos_message,
832
2
    sizeof (filehdr_in->pe.dos_message));
833
834
2
  filehdr_in->pe.nt_signature = IMAGE_NT_SIGNATURE;
835
836
2
  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
837
2
  H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
838
839
  /* Use a real timestamp by default, unless the no-insert-timestamp
840
     option was chosen.  */
841
2
  if ((pe_data (abfd)->timestamp) == -1)
842
2
    H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
843
0
  else
844
2
    H_PUT_32 (abfd, pe_data (abfd)->timestamp, filehdr_out->f_timdat);
845
846
2
  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
847
2
          filehdr_out->f_symptr);
848
2
  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
849
2
  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
850
2
  H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
851
852
  /* Put in extra dos header stuff.  This data remains essentially
853
     constant, it just has to be tacked on to the beginning of all exes
854
     for NT.  */
855
2
  H_PUT_16 (abfd, filehdr_in->pe.e_magic, filehdr_out->e_magic);
856
2
  H_PUT_16 (abfd, filehdr_in->pe.e_cblp, filehdr_out->e_cblp);
857
2
  H_PUT_16 (abfd, filehdr_in->pe.e_cp, filehdr_out->e_cp);
858
2
  H_PUT_16 (abfd, filehdr_in->pe.e_crlc, filehdr_out->e_crlc);
859
2
  H_PUT_16 (abfd, filehdr_in->pe.e_cparhdr, filehdr_out->e_cparhdr);
860
2
  H_PUT_16 (abfd, filehdr_in->pe.e_minalloc, filehdr_out->e_minalloc);
861
2
  H_PUT_16 (abfd, filehdr_in->pe.e_maxalloc, filehdr_out->e_maxalloc);
862
2
  H_PUT_16 (abfd, filehdr_in->pe.e_ss, filehdr_out->e_ss);
863
2
  H_PUT_16 (abfd, filehdr_in->pe.e_sp, filehdr_out->e_sp);
864
2
  H_PUT_16 (abfd, filehdr_in->pe.e_csum, filehdr_out->e_csum);
865
2
  H_PUT_16 (abfd, filehdr_in->pe.e_ip, filehdr_out->e_ip);
866
2
  H_PUT_16 (abfd, filehdr_in->pe.e_cs, filehdr_out->e_cs);
867
2
  H_PUT_16 (abfd, filehdr_in->pe.e_lfarlc, filehdr_out->e_lfarlc);
868
2
  H_PUT_16 (abfd, filehdr_in->pe.e_ovno, filehdr_out->e_ovno);
869
870
10
  for (idx = 0; idx < 4; idx++)
871
8
    H_PUT_16 (abfd, filehdr_in->pe.e_res[idx], filehdr_out->e_res[idx]);
872
873
2
  H_PUT_16 (abfd, filehdr_in->pe.e_oemid, filehdr_out->e_oemid);
874
2
  H_PUT_16 (abfd, filehdr_in->pe.e_oeminfo, filehdr_out->e_oeminfo);
875
876
22
  for (idx = 0; idx < 10; idx++)
877
20
    H_PUT_16 (abfd, filehdr_in->pe.e_res2[idx], filehdr_out->e_res2[idx]);
878
879
2
  H_PUT_32 (abfd, filehdr_in->pe.e_lfanew, filehdr_out->e_lfanew);
880
881
34
  for (idx = 0; idx < 16; idx++)
882
32
    H_PUT_32 (abfd, filehdr_in->pe.dos_message[idx],
883
2
        filehdr_out->dos_message[idx]);
884
885
  /* Also put in the NT signature.  */
886
2
  H_PUT_32 (abfd, filehdr_in->pe.nt_signature, filehdr_out->nt_signature);
887
888
2
  return FILHSZ;
889
2
}
890
891
unsigned int
892
_bfd_peAArch64_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
893
1
{
894
1
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
895
1
  FILHDR *filehdr_out = (FILHDR *) out;
896
897
1
  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
898
1
  H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
899
1
  H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
900
1
  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
901
1
  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
902
1
  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
903
1
  H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
904
905
1
  return FILHSZ;
906
1
}
907
908
unsigned int
909
_bfd_peAArch64i_swap_scnhdr_out (bfd * abfd, void * in, void * out)
910
3
{
911
3
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
912
3
  SCNHDR *scnhdr_ext = (SCNHDR *) out;
913
3
  unsigned int ret = SCNHSZ;
914
3
  bfd_vma ps;
915
3
  bfd_vma ss;
916
917
3
  memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
918
919
3
  ss = scnhdr_int->s_vaddr - pe_data (abfd)->pe_opthdr.ImageBase;
920
3
  if (scnhdr_int->s_vaddr < pe_data (abfd)->pe_opthdr.ImageBase)
921
0
    _bfd_error_handler (_("%pB:%.8s: section below image base"),
922
0
                        abfd, scnhdr_int->s_name);
923
  /* Do not compare lower 32-bits for 64-bit vma.  */
924
#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
925
  else if(ss != (ss & 0xffffffff))
926
    _bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name);
927
  PUT_SCNHDR_VADDR (abfd, ss & 0xffffffff, scnhdr_ext->s_vaddr);
928
#else
929
3
  PUT_SCNHDR_VADDR (abfd, ss, scnhdr_ext->s_vaddr);
930
3
#endif
931
932
  /* NT wants the size data to be rounded up to the next
933
     NT_FILE_ALIGNMENT, but zero if it has no content (as in .bss,
934
     sometimes).  */
935
3
  if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
936
0
    {
937
0
      if (bfd_pei_p (abfd))
938
0
  {
939
0
    ps = scnhdr_int->s_size;
940
0
    ss = 0;
941
0
  }
942
0
      else
943
0
       {
944
0
   ps = 0;
945
0
   ss = scnhdr_int->s_size;
946
0
       }
947
0
    }
948
3
  else
949
3
    {
950
3
      if (bfd_pei_p (abfd))
951
2
  ps = scnhdr_int->s_paddr;
952
1
      else
953
1
  ps = 0;
954
955
3
      ss = scnhdr_int->s_size;
956
3
    }
957
958
3
  PUT_SCNHDR_SIZE (abfd, ss,
959
3
       scnhdr_ext->s_size);
960
961
  /* s_paddr in PE is really the virtual size.  */
962
3
  PUT_SCNHDR_PADDR (abfd, ps, scnhdr_ext->s_paddr);
963
964
3
  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
965
3
         scnhdr_ext->s_scnptr);
966
3
  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
967
3
         scnhdr_ext->s_relptr);
968
3
  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
969
3
          scnhdr_ext->s_lnnoptr);
970
971
3
  {
972
    /* Extra flags must be set when dealing with PE.  All sections should also
973
       have the IMAGE_SCN_MEM_READ (0x40000000) flag set.  In addition, the
974
       .text section must have IMAGE_SCN_MEM_EXECUTE (0x20000000) and the data
975
       sections (.idata, .data, .bss, .CRT) must have IMAGE_SCN_MEM_WRITE set
976
       (this is especially important when dealing with the .idata section since
977
       the addresses for routines from .dlls must be overwritten).  If .reloc
978
       section data is ever generated, we must add IMAGE_SCN_MEM_DISCARDABLE
979
       (0x02000000).  Also, the resource data should also be read and
980
       writable.  */
981
982
    /* FIXME: Alignment is also encoded in this field, at least on
983
       ARM-WINCE.  Although - how do we get the original alignment field
984
       back ?  */
985
986
3
    typedef struct
987
3
    {
988
3
      char section_name[SCNNMLEN];
989
3
      unsigned long must_have;
990
3
    }
991
3
    pe_required_section_flags;
992
993
3
    pe_required_section_flags known_sections [] =
994
3
      {
995
3
  { ".arch",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES },
996
3
  { ".bss",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
997
3
  { ".data",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
998
3
  { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
999
3
  { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1000
3
  { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1001
3
  { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1002
3
  { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
1003
3
  { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1004
3
  { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
1005
3
  { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1006
3
  { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1007
3
      };
1008
1009
3
    pe_required_section_flags * p;
1010
1011
    /* We have defaulted to adding the IMAGE_SCN_MEM_WRITE flag, but now
1012
       we know exactly what this specific section wants so we remove it
1013
       and then allow the must_have field to add it back in if necessary.
1014
       However, we don't remove IMAGE_SCN_MEM_WRITE flag from .text if the
1015
       default WP_TEXT file flag has been cleared.  WP_TEXT may be cleared
1016
       by ld --enable-auto-import (if auto-import is actually needed),
1017
       by ld --omagic, or by obcopy --writable-text.  */
1018
1019
3
    for (p = known_sections;
1020
39
   p < known_sections + ARRAY_SIZE (known_sections);
1021
36
   p++)
1022
36
      if (memcmp (scnhdr_int->s_name, p->section_name, SCNNMLEN) == 0)
1023
0
  {
1024
0
    if (memcmp (scnhdr_int->s_name, ".text", sizeof ".text")
1025
0
        || (bfd_get_file_flags (abfd) & WP_TEXT))
1026
0
      scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
1027
0
    scnhdr_int->s_flags |= p->must_have;
1028
0
    break;
1029
0
  }
1030
1031
3
    H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
1032
3
  }
1033
1034
3
  if (coff_data (abfd)->link_info
1035
3
      && ! bfd_link_relocatable (coff_data (abfd)->link_info)
1036
3
      && ! bfd_link_pic (coff_data (abfd)->link_info)
1037
3
      && memcmp (scnhdr_int->s_name, ".text", sizeof ".text") == 0)
1038
0
    {
1039
      /* By inference from looking at MS output, the 32 bit field
1040
   which is the combination of the number_of_relocs and
1041
   number_of_linenos is used for the line number count in
1042
   executables.  A 16-bit field won't do for cc1.  The MS
1043
   document says that the number of relocs is zero for
1044
   executables, but the 17-th bit has been observed to be there.
1045
   Overflow is not an issue: a 4G-line program will overflow a
1046
   bunch of other fields long before this!  */
1047
0
      H_PUT_16 (abfd, (scnhdr_int->s_nlnno & 0xffff), scnhdr_ext->s_nlnno);
1048
0
      H_PUT_16 (abfd, (scnhdr_int->s_nlnno >> 16), scnhdr_ext->s_nreloc);
1049
0
    }
1050
3
  else
1051
3
    {
1052
3
      if (scnhdr_int->s_nlnno <= 0xffff)
1053
3
  H_PUT_16 (abfd, scnhdr_int->s_nlnno, scnhdr_ext->s_nlnno);
1054
0
      else
1055
0
  {
1056
    /* xgettext:c-format */
1057
0
    _bfd_error_handler (_("%pB: line number overflow: 0x%lx > 0xffff"),
1058
0
            abfd, scnhdr_int->s_nlnno);
1059
0
    bfd_set_error (bfd_error_file_truncated);
1060
0
    H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nlnno);
1061
0
    ret = 0;
1062
0
  }
1063
1064
      /* Although we could encode 0xffff relocs here, we do not, to be
1065
   consistent with other parts of bfd. Also it lets us warn, as
1066
   we should never see 0xffff here w/o having the overflow flag
1067
   set.  */
1068
3
      if (scnhdr_int->s_nreloc < 0xffff)
1069
3
  H_PUT_16 (abfd, scnhdr_int->s_nreloc, scnhdr_ext->s_nreloc);
1070
0
      else
1071
0
  {
1072
    /* PE can deal with large #s of relocs, but not here.  */
1073
0
    H_PUT_16 (abfd, 0xffff, scnhdr_ext->s_nreloc);
1074
0
    scnhdr_int->s_flags |= IMAGE_SCN_LNK_NRELOC_OVFL;
1075
0
    H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
1076
0
  }
1077
3
    }
1078
3
  return ret;
1079
3
}
1080
1081
void
1082
_bfd_peAArch64i_swap_debugdir_in (bfd * abfd, void * ext1, void * in1)
1083
460k
{
1084
460k
  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) ext1;
1085
460k
  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) in1;
1086
1087
460k
  in->Characteristics = H_GET_32(abfd, ext->Characteristics);
1088
460k
  in->TimeDateStamp = H_GET_32(abfd, ext->TimeDateStamp);
1089
460k
  in->MajorVersion = H_GET_16(abfd, ext->MajorVersion);
1090
460k
  in->MinorVersion = H_GET_16(abfd, ext->MinorVersion);
1091
460k
  in->Type = H_GET_32(abfd, ext->Type);
1092
460k
  in->SizeOfData = H_GET_32(abfd, ext->SizeOfData);
1093
460k
  in->AddressOfRawData = H_GET_32(abfd, ext->AddressOfRawData);
1094
460k
  in->PointerToRawData = H_GET_32(abfd, ext->PointerToRawData);
1095
460k
}
1096
1097
unsigned int
1098
_bfd_peAArch64i_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
1099
0
{
1100
0
  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) extp;
1101
0
  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) inp;
1102
1103
0
  H_PUT_32(abfd, in->Characteristics, ext->Characteristics);
1104
0
  H_PUT_32(abfd, in->TimeDateStamp, ext->TimeDateStamp);
1105
0
  H_PUT_16(abfd, in->MajorVersion, ext->MajorVersion);
1106
0
  H_PUT_16(abfd, in->MinorVersion, ext->MinorVersion);
1107
0
  H_PUT_32(abfd, in->Type, ext->Type);
1108
0
  H_PUT_32(abfd, in->SizeOfData, ext->SizeOfData);
1109
0
  H_PUT_32(abfd, in->AddressOfRawData, ext->AddressOfRawData);
1110
0
  H_PUT_32(abfd, in->PointerToRawData, ext->PointerToRawData);
1111
1112
0
  return sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
1113
0
}
1114
1115
CODEVIEW_INFO *
1116
_bfd_peAArch64i_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo,
1117
        char **pdb)
1118
499
{
1119
499
  char buffer[256+1];
1120
499
  bfd_size_type nread;
1121
1122
499
  if (bfd_seek (abfd, where, SEEK_SET) != 0)
1123
0
    return NULL;
1124
1125
499
  if (length <= sizeof (CV_INFO_PDB70) && length <= sizeof (CV_INFO_PDB20))
1126
74
    return NULL;
1127
425
  if (length > 256)
1128
393
    length = 256;
1129
425
  nread = bfd_bread (buffer, length, abfd);
1130
425
  if (length != nread)
1131
202
    return NULL;
1132
1133
  /* Ensure null termination of filename.  */
1134
223
  memset (buffer + nread, 0, sizeof (buffer) - nread);
1135
1136
223
  cvinfo->CVSignature = H_GET_32 (abfd, buffer);
1137
223
  cvinfo->Age = 0;
1138
1139
223
  if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
1140
223
      && (length > sizeof (CV_INFO_PDB70)))
1141
0
    {
1142
0
      CV_INFO_PDB70 *cvinfo70 = (CV_INFO_PDB70 *)(buffer);
1143
1144
0
      cvinfo->Age = H_GET_32(abfd, cvinfo70->Age);
1145
1146
      /* A GUID consists of 4,2,2 byte values in little-endian order, followed
1147
   by 8 single bytes.  Byte swap them so we can conveniently treat the GUID
1148
   as 16 bytes in big-endian order.  */
1149
0
      bfd_putb32 (bfd_getl32 (cvinfo70->Signature), cvinfo->Signature);
1150
0
      bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[4])), &(cvinfo->Signature[4]));
1151
0
      bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[6])), &(cvinfo->Signature[6]));
1152
0
      memcpy (&(cvinfo->Signature[8]), &(cvinfo70->Signature[8]), 8);
1153
1154
0
      cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH;
1155
      /* cvinfo->PdbFileName = cvinfo70->PdbFileName;  */
1156
1157
0
      if (pdb)
1158
0
  *pdb = xstrdup (cvinfo70->PdbFileName);
1159
1160
0
      return cvinfo;
1161
0
    }
1162
223
  else if ((cvinfo->CVSignature == CVINFO_PDB20_CVSIGNATURE)
1163
223
     && (length > sizeof (CV_INFO_PDB20)))
1164
1
    {
1165
1
      CV_INFO_PDB20 *cvinfo20 = (CV_INFO_PDB20 *)(buffer);
1166
1
      cvinfo->Age = H_GET_32(abfd, cvinfo20->Age);
1167
1
      memcpy (cvinfo->Signature, cvinfo20->Signature, 4);
1168
1
      cvinfo->SignatureLength = 4;
1169
      /* cvinfo->PdbFileName = cvinfo20->PdbFileName;  */
1170
1171
1
      if (pdb)
1172
0
  *pdb = xstrdup (cvinfo20->PdbFileName);
1173
1174
1
      return cvinfo;
1175
1
    }
1176
1177
222
  return NULL;
1178
223
}
1179
1180
unsigned int
1181
_bfd_peAArch64i_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinfo,
1182
        const char *pdb)
1183
0
{
1184
0
  size_t pdb_len = pdb ? strlen (pdb) : 0;
1185
0
  const bfd_size_type size = sizeof (CV_INFO_PDB70) + pdb_len + 1;
1186
0
  bfd_size_type written;
1187
0
  CV_INFO_PDB70 *cvinfo70;
1188
0
  char * buffer;
1189
1190
0
  if (bfd_seek (abfd, where, SEEK_SET) != 0)
1191
0
    return 0;
1192
1193
0
  buffer = bfd_malloc (size);
1194
0
  if (buffer == NULL)
1195
0
    return 0;
1196
1197
0
  cvinfo70 = (CV_INFO_PDB70 *) buffer;
1198
0
  H_PUT_32 (abfd, CVINFO_PDB70_CVSIGNATURE, cvinfo70->CvSignature);
1199
1200
  /* Byte swap the GUID from 16 bytes in big-endian order to 4,2,2 byte values
1201
     in little-endian order, followed by 8 single bytes.  */
1202
0
  bfd_putl32 (bfd_getb32 (cvinfo->Signature), cvinfo70->Signature);
1203
0
  bfd_putl16 (bfd_getb16 (&(cvinfo->Signature[4])), &(cvinfo70->Signature[4]));
1204
0
  bfd_putl16 (bfd_getb16 (&(cvinfo->Signature[6])), &(cvinfo70->Signature[6]));
1205
0
  memcpy (&(cvinfo70->Signature[8]), &(cvinfo->Signature[8]), 8);
1206
1207
0
  H_PUT_32 (abfd, cvinfo->Age, cvinfo70->Age);
1208
1209
0
  if (pdb == NULL)
1210
0
    cvinfo70->PdbFileName[0] = '\0';
1211
0
  else
1212
0
    memcpy (cvinfo70->PdbFileName, pdb, pdb_len + 1);
1213
1214
0
  written = bfd_bwrite (buffer, size, abfd);
1215
1216
0
  free (buffer);
1217
1218
0
  return written == size ? size : 0;
1219
0
}
1220
1221
static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
1222
{
1223
  N_("Export Directory [.edata (or where ever we found it)]"),
1224
  N_("Import Directory [parts of .idata]"),
1225
  N_("Resource Directory [.rsrc]"),
1226
  N_("Exception Directory [.pdata]"),
1227
  N_("Security Directory"),
1228
  N_("Base Relocation Directory [.reloc]"),
1229
  N_("Debug Directory"),
1230
  N_("Description Directory"),
1231
  N_("Special Directory"),
1232
  N_("Thread Storage Directory [.tls]"),
1233
  N_("Load Configuration Directory"),
1234
  N_("Bound Import Directory"),
1235
  N_("Import Address Table Directory"),
1236
  N_("Delay Import Directory"),
1237
  N_("CLR Runtime Header"),
1238
  N_("Reserved")
1239
};
1240
1241
static bool
1242
get_contents_sanity_check (bfd *abfd, asection *section,
1243
         bfd_size_type dataoff, bfd_size_type datasize)
1244
769
{
1245
769
  if ((section->flags & SEC_HAS_CONTENTS) == 0)
1246
17
    return false;
1247
752
  if (dataoff > section->size
1248
752
      || datasize > section->size - dataoff)
1249
26
    return false;
1250
726
  ufile_ptr filesize = bfd_get_file_size (abfd);
1251
726
  if (filesize != 0
1252
726
      && ((ufile_ptr) section->filepos > filesize
1253
726
    || dataoff > filesize - section->filepos
1254
726
    || datasize > filesize - section->filepos - dataoff))
1255
104
    return false;
1256
622
  return true;
1257
726
}
1258
1259
static bool
1260
pe_print_idata (bfd * abfd, void * vfile)
1261
3.53k
{
1262
3.53k
  FILE *file = (FILE *) vfile;
1263
3.53k
  bfd_byte *data;
1264
3.53k
  asection *section;
1265
3.53k
  bfd_signed_vma adj;
1266
3.53k
  bfd_size_type datasize = 0;
1267
3.53k
  bfd_size_type dataoff;
1268
3.53k
  bfd_size_type i;
1269
3.53k
  int onaline = 20;
1270
1271
3.53k
  pe_data_type *pe = pe_data (abfd);
1272
3.53k
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1273
1274
3.53k
  bfd_vma addr;
1275
1276
3.53k
  addr = extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress;
1277
1278
3.53k
  if (addr == 0 && extra->DataDirectory[PE_IMPORT_TABLE].Size == 0)
1279
2.19k
    {
1280
      /* Maybe the extra header isn't there.  Look for the section.  */
1281
2.19k
      section = bfd_get_section_by_name (abfd, ".idata");
1282
2.19k
      if (section == NULL || (section->flags & SEC_HAS_CONTENTS) == 0)
1283
2.11k
  return true;
1284
1285
75
      addr = section->vma;
1286
75
      datasize = section->size;
1287
75
      if (datasize == 0)
1288
1
  return true;
1289
75
    }
1290
1.34k
  else
1291
1.34k
    {
1292
1.34k
      addr += extra->ImageBase;
1293
11.0k
      for (section = abfd->sections; section != NULL; section = section->next)
1294
10.0k
  {
1295
10.0k
    datasize = section->size;
1296
10.0k
    if (addr >= section->vma && addr < section->vma + datasize)
1297
352
      break;
1298
10.0k
  }
1299
1300
1.34k
      if (section == NULL)
1301
990
  {
1302
990
    fprintf (file,
1303
990
       _("\nThere is an import table, but the section containing it could not be found\n"));
1304
990
    return true;
1305
990
  }
1306
352
      else if (!(section->flags & SEC_HAS_CONTENTS))
1307
8
  {
1308
8
    fprintf (file,
1309
8
       _("\nThere is an import table in %s, but that section has no contents\n"),
1310
8
       section->name);
1311
8
    return true;
1312
8
  }
1313
1.34k
    }
1314
1315
  /* xgettext:c-format */
1316
418
  fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
1317
418
     section->name, (unsigned long) addr);
1318
1319
418
  dataoff = addr - section->vma;
1320
1321
418
  fprintf (file,
1322
418
     _("\nThe Import Tables (interpreted %s section contents)\n"),
1323
418
     section->name);
1324
418
  fprintf (file,
1325
418
     _("\
1326
418
 vma:            Hint    Time      Forward  DLL       First\n\
1327
418
                 Table   Stamp     Chain    Name      Thunk\n"));
1328
1329
  /* Read the whole section.  Some of the fields might be before dataoff.  */
1330
418
  if (!bfd_malloc_and_get_section (abfd, section, &data))
1331
105
    {
1332
105
      free (data);
1333
105
      return false;
1334
105
    }
1335
1336
313
  adj = section->vma - extra->ImageBase;
1337
1338
  /* Print all image import descriptors.  */
1339
855
  for (i = dataoff; i + onaline <= datasize; i += onaline)
1340
848
    {
1341
848
      bfd_vma hint_addr;
1342
848
      bfd_vma time_stamp;
1343
848
      bfd_vma forward_chain;
1344
848
      bfd_vma dll_name;
1345
848
      bfd_vma first_thunk;
1346
848
      int idx = 0;
1347
848
      bfd_size_type j;
1348
848
      char *dll;
1349
1350
      /* Print (i + extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress).  */
1351
848
      fprintf (file, " %08lx\t", (unsigned long) (i + adj));
1352
848
      hint_addr = bfd_get_32 (abfd, data + i);
1353
848
      time_stamp = bfd_get_32 (abfd, data + i + 4);
1354
848
      forward_chain = bfd_get_32 (abfd, data + i + 8);
1355
848
      dll_name = bfd_get_32 (abfd, data + i + 12);
1356
848
      first_thunk = bfd_get_32 (abfd, data + i + 16);
1357
1358
848
      fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
1359
848
         (unsigned long) hint_addr,
1360
848
         (unsigned long) time_stamp,
1361
848
         (unsigned long) forward_chain,
1362
848
         (unsigned long) dll_name,
1363
848
         (unsigned long) first_thunk);
1364
1365
848
      if (hint_addr == 0 && first_thunk == 0)
1366
4
  break;
1367
1368
844
      if (dll_name - adj >= section->size)
1369
302
  break;
1370
1371
542
      dll = (char *) data + dll_name - adj;
1372
      /* PR 17512 file: 078-12277-0.004.  */
1373
542
      bfd_size_type maxlen = (char *)(data + datasize) - dll - 1;
1374
542
      fprintf (file, _("\n\tDLL Name: %.*s\n"), (int) maxlen, dll);
1375
1376
      /* PR 21546: When the Hint Address is zero,
1377
   we try the First Thunk instead.  */
1378
542
      if (hint_addr == 0)
1379
44
  hint_addr = first_thunk;
1380
1381
542
      if (hint_addr != 0 && hint_addr - adj < datasize)
1382
149
  {
1383
149
    bfd_byte *ft_data;
1384
149
    asection *ft_section;
1385
149
    bfd_vma ft_addr;
1386
149
    bfd_size_type ft_datasize;
1387
149
    int ft_idx;
1388
149
    int ft_allocated;
1389
1390
149
    fprintf (file, _("\tvma:  Hint/Ord Member-Name Bound-To\n"));
1391
1392
149
    idx = hint_addr - adj;
1393
1394
149
    ft_addr = first_thunk + extra->ImageBase;
1395
149
    ft_idx = first_thunk - adj;
1396
149
    ft_data = data + ft_idx;
1397
149
    ft_datasize = datasize - ft_idx;
1398
149
    ft_allocated = 0;
1399
1400
149
    if (first_thunk != hint_addr)
1401
115
      {
1402
        /* Find the section which contains the first thunk.  */
1403
115
        for (ft_section = abfd->sections;
1404
290
       ft_section != NULL;
1405
175
       ft_section = ft_section->next)
1406
271
    {
1407
271
      if (ft_addr >= ft_section->vma
1408
271
          && ft_addr < ft_section->vma + ft_section->size)
1409
96
        break;
1410
271
    }
1411
1412
115
        if (ft_section == NULL)
1413
19
    {
1414
19
      fprintf (file,
1415
19
           _("\nThere is a first thunk, but the section containing it could not be found\n"));
1416
19
      continue;
1417
19
    }
1418
1419
        /* Now check to see if this section is the same as our current
1420
     section.  If it is not then we will have to load its data in.  */
1421
96
        if (ft_section != section)
1422
49
    {
1423
49
      ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
1424
49
      ft_datasize = ft_section->size - ft_idx;
1425
49
      if (!get_contents_sanity_check (abfd, ft_section,
1426
49
              ft_idx, ft_datasize))
1427
46
        continue;
1428
3
      ft_data = (bfd_byte *) bfd_malloc (ft_datasize);
1429
3
      if (ft_data == NULL)
1430
0
        continue;
1431
1432
      /* Read ft_datasize bytes starting at offset ft_idx.  */
1433
3
      if (!bfd_get_section_contents (abfd, ft_section, ft_data,
1434
3
             (bfd_vma) ft_idx, ft_datasize))
1435
0
        {
1436
0
          free (ft_data);
1437
0
          continue;
1438
0
        }
1439
3
      ft_allocated = 1;
1440
3
    }
1441
96
      }
1442
1443
    /* Print HintName vector entries.  */
1444
#ifdef COFF_WITH_pex64
1445
    for (j = 0; idx + j + 8 <= datasize; j += 8)
1446
      {
1447
        bfd_size_type amt;
1448
        unsigned long member = bfd_get_32 (abfd, data + idx + j);
1449
        unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
1450
1451
        if (!member && !member_high)
1452
    break;
1453
1454
        amt = member - adj;
1455
1456
        if (HighBitSet (member_high))
1457
    fprintf (file, "\t%lx%08lx\t %4lx%08lx  <none>",
1458
       member_high, member,
1459
       WithoutHighBit (member_high), member);
1460
        /* PR binutils/17512: Handle corrupt PE data.  */
1461
        else if (amt >= datasize || amt + 2 >= datasize)
1462
    fprintf (file, _("\t<corrupt: 0x%04lx>"), member);
1463
        else
1464
    {
1465
      int ordinal;
1466
      char *member_name;
1467
1468
      ordinal = bfd_get_16 (abfd, data + amt);
1469
      member_name = (char *) data + amt + 2;
1470
      fprintf (file, "\t%04lx\t %4d  %.*s",member, ordinal,
1471
         (int) (datasize - (amt + 2)), member_name);
1472
    }
1473
1474
        /* If the time stamp is not zero, the import address
1475
     table holds actual addresses.  */
1476
        if (time_stamp != 0
1477
      && first_thunk != 0
1478
      && first_thunk != hint_addr
1479
      && j + 4 <= ft_datasize)
1480
    fprintf (file, "\t%04lx",
1481
       (unsigned long) bfd_get_32 (abfd, ft_data + j));
1482
        fprintf (file, "\n");
1483
      }
1484
#else
1485
1.33k
    for (j = 0; idx + j + 4 <= datasize; j += 4)
1486
1.32k
      {
1487
1.32k
        bfd_size_type amt;
1488
1.32k
        unsigned long member = bfd_get_32 (abfd, data + idx + j);
1489
1490
        /* Print single IMAGE_IMPORT_BY_NAME vector.  */
1491
1.32k
        if (member == 0)
1492
70
    break;
1493
1494
1.25k
        amt = member - adj;
1495
1496
1.25k
        if (HighBitSet (member))
1497
138
    fprintf (file, "\t%04lx\t %4lu  <none>",
1498
138
       member, WithoutHighBit (member));
1499
        /* PR binutils/17512: Handle corrupt PE data.  */
1500
1.11k
        else if (amt >= datasize || amt + 2 >= datasize)
1501
1.03k
    fprintf (file, _("\t<corrupt: 0x%04lx>"), member);
1502
78
        else
1503
78
    {
1504
78
      int ordinal;
1505
78
      char *member_name;
1506
1507
78
      ordinal = bfd_get_16 (abfd, data + amt);
1508
78
      member_name = (char *) data + amt + 2;
1509
78
      fprintf (file, "\t%04lx\t %4d  %.*s",
1510
78
         member, ordinal,
1511
78
         (int) (datasize - (amt + 2)), member_name);
1512
78
    }
1513
1514
        /* If the time stamp is not zero, the import address
1515
     table holds actual addresses.  */
1516
1.25k
        if (time_stamp != 0
1517
1.25k
      && first_thunk != 0
1518
1.25k
      && first_thunk != hint_addr
1519
1.25k
      && j + 4 <= ft_datasize)
1520
508
    fprintf (file, "\t%04lx",
1521
508
       (unsigned long) bfd_get_32 (abfd, ft_data + j));
1522
1523
1.25k
        fprintf (file, "\n");
1524
1.25k
      }
1525
84
#endif
1526
84
    if (ft_allocated)
1527
3
      free (ft_data);
1528
84
  }
1529
1530
477
      fprintf (file, "\n");
1531
477
    }
1532
1533
313
  free (data);
1534
1535
313
  return true;
1536
418
}
1537
1538
static bool
1539
pe_print_edata (bfd * abfd, void * vfile)
1540
3.53k
{
1541
3.53k
  FILE *file = (FILE *) vfile;
1542
3.53k
  bfd_byte *data;
1543
3.53k
  asection *section;
1544
3.53k
  bfd_size_type datasize = 0;
1545
3.53k
  bfd_size_type dataoff;
1546
3.53k
  bfd_size_type i;
1547
3.53k
  bfd_vma       adj;
1548
3.53k
  struct EDT_type
1549
3.53k
  {
1550
3.53k
    long export_flags;    /* Reserved - should be zero.  */
1551
3.53k
    long time_stamp;
1552
3.53k
    short major_ver;
1553
3.53k
    short minor_ver;
1554
3.53k
    bfd_vma name;   /* RVA - relative to image base.  */
1555
3.53k
    long base;      /* Ordinal base.  */
1556
3.53k
    unsigned long num_functions;/* Number in the export address table.  */
1557
3.53k
    unsigned long num_names;  /* Number in the name pointer table.  */
1558
3.53k
    bfd_vma eat_addr;   /* RVA to the export address table.  */
1559
3.53k
    bfd_vma npt_addr;   /* RVA to the Export Name Pointer Table.  */
1560
3.53k
    bfd_vma ot_addr;    /* RVA to the Ordinal Table.  */
1561
3.53k
  } edt;
1562
1563
3.53k
  pe_data_type *pe = pe_data (abfd);
1564
3.53k
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1565
1566
3.53k
  bfd_vma addr;
1567
1568
3.53k
  addr = extra->DataDirectory[PE_EXPORT_TABLE].VirtualAddress;
1569
1570
3.53k
  if (addr == 0 && extra->DataDirectory[PE_EXPORT_TABLE].Size == 0)
1571
2.30k
    {
1572
      /* Maybe the extra header isn't there.  Look for the section.  */
1573
2.30k
      section = bfd_get_section_by_name (abfd, ".edata");
1574
2.30k
      if (section == NULL)
1575
2.25k
  return true;
1576
1577
51
      addr = section->vma;
1578
51
      dataoff = 0;
1579
51
      datasize = section->size;
1580
51
      if (datasize == 0)
1581
1
  return true;
1582
51
    }
1583
1.22k
  else
1584
1.22k
    {
1585
1.22k
      addr += extra->ImageBase;
1586
1587
9.85k
      for (section = abfd->sections; section != NULL; section = section->next)
1588
9.30k
  if (addr >= section->vma && addr < section->vma + section->size)
1589
673
    break;
1590
1591
1.22k
      if (section == NULL)
1592
551
  {
1593
551
    fprintf (file,
1594
551
       _("\nThere is an export table, but the section containing it could not be found\n"));
1595
551
    return true;
1596
551
  }
1597
1598
673
      dataoff = addr - section->vma;
1599
673
      datasize = extra->DataDirectory[PE_EXPORT_TABLE].Size;
1600
673
    }
1601
1602
  /* PR 17512: Handle corrupt PE binaries.  */
1603
723
  if (datasize < 40)
1604
3
    {
1605
3
      fprintf (file,
1606
         /* xgettext:c-format */
1607
3
         _("\nThere is an export table in %s, but it is too small (%d)\n"),
1608
3
         section->name, (int) datasize);
1609
3
      return true;
1610
3
    }
1611
1612
720
  if (!get_contents_sanity_check (abfd, section, dataoff, datasize))
1613
101
    {
1614
101
      fprintf (file,
1615
101
         _("\nThere is an export table in %s, but contents cannot be read\n"),
1616
101
         section->name);
1617
101
      return true;
1618
101
    }
1619
1620
  /* xgettext:c-format */
1621
619
  fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
1622
619
     section->name, (unsigned long) addr);
1623
1624
619
  data = (bfd_byte *) bfd_malloc (datasize);
1625
619
  if (data == NULL)
1626
0
    return false;
1627
1628
619
  if (! bfd_get_section_contents (abfd, section, data,
1629
619
          (file_ptr) dataoff, datasize))
1630
0
    {
1631
0
      free (data);
1632
0
      return false;
1633
0
    }
1634
1635
  /* Go get Export Directory Table.  */
1636
619
  edt.export_flags   = bfd_get_32 (abfd, data +   0);
1637
619
  edt.time_stamp     = bfd_get_32 (abfd, data +   4);
1638
619
  edt.major_ver      = bfd_get_16 (abfd, data +   8);
1639
619
  edt.minor_ver      = bfd_get_16 (abfd, data + 10);
1640
619
  edt.name       = bfd_get_32 (abfd, data + 12);
1641
619
  edt.base       = bfd_get_32 (abfd, data + 16);
1642
619
  edt.num_functions  = bfd_get_32 (abfd, data + 20);
1643
619
  edt.num_names      = bfd_get_32 (abfd, data + 24);
1644
619
  edt.eat_addr       = bfd_get_32 (abfd, data + 28);
1645
619
  edt.npt_addr       = bfd_get_32 (abfd, data + 32);
1646
619
  edt.ot_addr      = bfd_get_32 (abfd, data + 36);
1647
1648
619
  adj = section->vma - extra->ImageBase + dataoff;
1649
1650
  /* Dump the EDT first.  */
1651
619
  fprintf (file,
1652
619
     _("\nThe Export Tables (interpreted %s section contents)\n\n"),
1653
619
     section->name);
1654
1655
619
  fprintf (file,
1656
619
     _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
1657
1658
619
  fprintf (file,
1659
619
     _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
1660
1661
619
  fprintf (file,
1662
     /* xgettext:c-format */
1663
619
     _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
1664
1665
619
  fprintf (file,
1666
619
     _("Name \t\t\t\t"));
1667
619
  bfd_fprintf_vma (abfd, file, edt.name);
1668
1669
619
  if ((edt.name >= adj) && (edt.name < adj + datasize))
1670
26
    fprintf (file, " %.*s\n",
1671
26
       (int) (datasize - (edt.name - adj)),
1672
26
       data + edt.name - adj);
1673
593
  else
1674
593
    fprintf (file, "(outside .edata section)\n");
1675
1676
619
  fprintf (file,
1677
619
     _("Ordinal Base \t\t\t%ld\n"), edt.base);
1678
1679
619
  fprintf (file,
1680
619
     _("Number in:\n"));
1681
1682
619
  fprintf (file,
1683
619
     _("\tExport Address Table \t\t%08lx\n"),
1684
619
     edt.num_functions);
1685
1686
619
  fprintf (file,
1687
619
     _("\t[Name Pointer/Ordinal] Table\t%08lx\n"), edt.num_names);
1688
1689
619
  fprintf (file,
1690
619
     _("Table Addresses\n"));
1691
1692
619
  fprintf (file,
1693
619
     _("\tExport Address Table \t\t"));
1694
619
  bfd_fprintf_vma (abfd, file, edt.eat_addr);
1695
619
  fprintf (file, "\n");
1696
1697
619
  fprintf (file,
1698
619
     _("\tName Pointer Table \t\t"));
1699
619
  bfd_fprintf_vma (abfd, file, edt.npt_addr);
1700
619
  fprintf (file, "\n");
1701
1702
619
  fprintf (file,
1703
619
     _("\tOrdinal Table \t\t\t"));
1704
619
  bfd_fprintf_vma (abfd, file, edt.ot_addr);
1705
619
  fprintf (file, "\n");
1706
1707
  /* The next table to find is the Export Address Table. It's basically
1708
     a list of pointers that either locate a function in this dll, or
1709
     forward the call to another dll. Something like:
1710
      typedef union
1711
      {
1712
  long export_rva;
1713
  long forwarder_rva;
1714
      } export_address_table_entry;  */
1715
1716
619
  fprintf (file,
1717
619
    _("\nExport Address Table -- Ordinal Base %ld\n"),
1718
619
    edt.base);
1719
1720
  /* PR 17512: Handle corrupt PE binaries.  */
1721
  /* PR 17512 file: 140-165018-0.004.  */
1722
619
  if (edt.eat_addr - adj >= datasize
1723
      /* PR 17512: file: 092b1829 */
1724
619
      || (edt.num_functions + 1) * 4 < edt.num_functions
1725
619
      || edt.eat_addr - adj + (edt.num_functions + 1) * 4 > datasize)
1726
584
    fprintf (file, _("\tInvalid Export Address Table rva (0x%lx) or entry count (0x%lx)\n"),
1727
584
       (long) edt.eat_addr,
1728
584
       (long) edt.num_functions);
1729
1.40k
  else for (i = 0; i < edt.num_functions; ++i)
1730
1.37k
    {
1731
1.37k
      bfd_vma eat_member = bfd_get_32 (abfd,
1732
1.37k
               data + edt.eat_addr + (i * 4) - adj);
1733
1.37k
      if (eat_member == 0)
1734
367
  continue;
1735
1736
1.00k
      if (eat_member - adj <= datasize)
1737
118
  {
1738
    /* This rva is to a name (forwarding function) in our section.  */
1739
    /* Should locate a function descriptor.  */
1740
118
    fprintf (file,
1741
118
       "\t[%4ld] +base[%4ld] %04lx %s -- %.*s\n",
1742
118
       (long) i,
1743
118
       (long) (i + edt.base),
1744
118
       (unsigned long) eat_member,
1745
118
       _("Forwarder RVA"),
1746
118
       (int)(datasize - (eat_member - adj)),
1747
118
       data + eat_member - adj);
1748
118
  }
1749
889
      else
1750
889
  {
1751
    /* Should locate a function descriptor in the reldata section.  */
1752
889
    fprintf (file,
1753
889
       "\t[%4ld] +base[%4ld] %04lx %s\n",
1754
889
       (long) i,
1755
889
       (long) (i + edt.base),
1756
889
       (unsigned long) eat_member,
1757
889
       _("Export RVA"));
1758
889
  }
1759
1.00k
    }
1760
1761
  /* The Export Name Pointer Table is paired with the Export Ordinal Table.  */
1762
  /* Dump them in parallel for clarity.  */
1763
619
  fprintf (file,
1764
619
     _("\n[Ordinal/Name Pointer] Table\n"));
1765
1766
  /* PR 17512: Handle corrupt PE binaries.  */
1767
619
  if (edt.npt_addr + (edt.num_names * 4) - adj >= datasize
1768
      /* PR 17512: file: bb68816e.  */
1769
619
      || edt.num_names * 4 < edt.num_names
1770
619
      || (data + edt.npt_addr - adj) < data)
1771
    /* xgettext:c-format */
1772
591
    fprintf (file, _("\tInvalid Name Pointer Table rva (0x%lx) or entry count (0x%lx)\n"),
1773
591
       (long) edt.npt_addr,
1774
591
       (long) edt.num_names);
1775
  /* PR 17512: file: 140-147171-0.004.  */
1776
28
  else if (edt.ot_addr + (edt.num_names * 2) - adj >= datasize
1777
28
     || data + edt.ot_addr - adj < data)
1778
    /* xgettext:c-format */
1779
8
    fprintf (file, _("\tInvalid Ordinal Table rva (0x%lx) or entry count (0x%lx)\n"),
1780
8
       (long) edt.ot_addr,
1781
8
       (long) edt.num_names);
1782
393
  else for (i = 0; i < edt.num_names; ++i)
1783
373
    {
1784
373
      bfd_vma  name_ptr;
1785
373
      bfd_vma  ord;
1786
1787
373
      ord = bfd_get_16 (abfd, data + edt.ot_addr + (i * 2) - adj);
1788
373
      name_ptr = bfd_get_32 (abfd, data + edt.npt_addr + (i * 4) - adj);
1789
1790
373
      if ((name_ptr - adj) >= datasize)
1791
208
  {
1792
    /* xgettext:c-format */
1793
208
    fprintf (file, _("\t[%4ld] <corrupt offset: %lx>\n"),
1794
208
       (long) ord, (long) name_ptr);
1795
208
  }
1796
165
      else
1797
165
  {
1798
165
    char * name = (char *) data + name_ptr - adj;
1799
1800
165
    fprintf (file, "\t[%4ld] %.*s\n", (long) ord,
1801
165
       (int)((char *)(data + datasize) - name), name);
1802
165
  }
1803
373
    }
1804
1805
619
  free (data);
1806
1807
619
  return true;
1808
619
}
1809
1810
/* This really is architecture dependent.  On IA-64, a .pdata entry
1811
   consists of three dwords containing relative virtual addresses that
1812
   specify the start and end address of the code range the entry
1813
   covers and the address of the corresponding unwind info data.
1814
1815
   On ARM and SH-4, a compressed PDATA structure is used :
1816
   _IMAGE_CE_RUNTIME_FUNCTION_ENTRY, whereas MIPS is documented to use
1817
   _IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY.
1818
   See http://msdn2.microsoft.com/en-us/library/ms253988(VS.80).aspx .
1819
1820
   This is the version for uncompressed data.  */
1821
1822
static bool
1823
pe_print_pdata (bfd * abfd, void * vfile)
1824
3.53k
{
1825
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
1826
# define PDATA_ROW_SIZE (3 * 8)
1827
#else
1828
3.81k
# define PDATA_ROW_SIZE (5 * 4)
1829
3.53k
#endif
1830
3.53k
  FILE *file = (FILE *) vfile;
1831
3.53k
  bfd_byte *data = 0;
1832
3.53k
  asection *section = bfd_get_section_by_name (abfd, ".pdata");
1833
3.53k
  bfd_size_type datasize = 0;
1834
3.53k
  bfd_size_type i;
1835
3.53k
  bfd_size_type start, stop;
1836
3.53k
  int onaline = PDATA_ROW_SIZE;
1837
1838
3.53k
  if (section == NULL
1839
3.53k
      || (section->flags & SEC_HAS_CONTENTS) == 0
1840
3.53k
      || coff_section_data (abfd, section) == NULL
1841
3.53k
      || pei_section_data (abfd, section) == NULL)
1842
3.49k
    return true;
1843
1844
34
  stop = pei_section_data (abfd, section)->virt_size;
1845
34
  if ((stop % onaline) != 0)
1846
31
    fprintf (file,
1847
       /* xgettext:c-format */
1848
31
       _("warning, .pdata section size (%ld) is not a multiple of %d\n"),
1849
31
       (long) stop, onaline);
1850
1851
34
  fprintf (file,
1852
34
     _("\nThe Function Table (interpreted .pdata section contents)\n"));
1853
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
1854
  fprintf (file,
1855
     _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
1856
#else
1857
34
  fprintf (file, _("\
1858
34
 vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n\
1859
34
     \t\tAddress  Address  Handler  Data     Address    Mask\n"));
1860
34
#endif
1861
1862
34
  datasize = section->size;
1863
34
  if (datasize == 0)
1864
1
    return true;
1865
1866
  /* PR 17512: file: 002-193900-0.004.  */
1867
33
  if (datasize < stop)
1868
1
    {
1869
      /* xgettext:c-format */
1870
1
      fprintf (file, _("Virtual size of .pdata section (%ld) larger than real size (%ld)\n"),
1871
1
         (long) stop, (long) datasize);
1872
1
      return false;
1873
1
    }
1874
1875
32
  if (! bfd_malloc_and_get_section (abfd, section, &data))
1876
12
    {
1877
12
      free (data);
1878
12
      return false;
1879
12
    }
1880
1881
20
  start = 0;
1882
1883
285
  for (i = start; i < stop; i += onaline)
1884
283
    {
1885
283
      bfd_vma begin_addr;
1886
283
      bfd_vma end_addr;
1887
283
      bfd_vma eh_handler;
1888
283
      bfd_vma eh_data;
1889
283
      bfd_vma prolog_end_addr;
1890
283
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
1891
283
      int em_data;
1892
283
#endif
1893
1894
283
      if (i + PDATA_ROW_SIZE > stop)
1895
10
  break;
1896
1897
273
      begin_addr      = GET_PDATA_ENTRY (abfd, data + i      );
1898
273
      end_addr        = GET_PDATA_ENTRY (abfd, data + i +  4);
1899
273
      eh_handler      = GET_PDATA_ENTRY (abfd, data + i +  8);
1900
273
      eh_data       = GET_PDATA_ENTRY (abfd, data + i + 12);
1901
273
      prolog_end_addr = GET_PDATA_ENTRY (abfd, data + i + 16);
1902
1903
273
      if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1904
273
    && eh_data == 0 && prolog_end_addr == 0)
1905
  /* We are probably into the padding of the section now.  */
1906
8
  break;
1907
1908
265
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
1909
265
      em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
1910
265
#endif
1911
265
      eh_handler &= ~(bfd_vma) 0x3;
1912
265
      prolog_end_addr &= ~(bfd_vma) 0x3;
1913
1914
265
      fputc (' ', file);
1915
265
      bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
1916
265
      bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
1917
265
      bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
1918
265
      bfd_fprintf_vma (abfd, file, eh_handler);
1919
265
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64)
1920
265
      fputc (' ', file);
1921
265
      bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
1922
265
      bfd_fprintf_vma (abfd, file, prolog_end_addr);
1923
265
      fprintf (file, "   %x", em_data);
1924
265
#endif
1925
265
      fprintf (file, "\n");
1926
265
    }
1927
1928
20
  free (data);
1929
1930
20
  return true;
1931
32
#undef PDATA_ROW_SIZE
1932
32
}
1933
1934
typedef struct sym_cache
1935
{
1936
  int      symcount;
1937
  asymbol ** syms;
1938
} sym_cache;
1939
1940
static asymbol **
1941
slurp_symtab (bfd *abfd, sym_cache *psc)
1942
0
{
1943
0
  asymbol ** sy = NULL;
1944
0
  long storage;
1945
1946
0
  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
1947
0
    {
1948
0
      psc->symcount = 0;
1949
0
      return NULL;
1950
0
    }
1951
1952
0
  storage = bfd_get_symtab_upper_bound (abfd);
1953
0
  if (storage < 0)
1954
0
    return NULL;
1955
0
  if (storage)
1956
0
    {
1957
0
      sy = (asymbol **) bfd_malloc (storage);
1958
0
      if (sy == NULL)
1959
0
  return NULL;
1960
0
    }
1961
1962
0
  psc->symcount = bfd_canonicalize_symtab (abfd, sy);
1963
0
  if (psc->symcount < 0)
1964
0
    return NULL;
1965
0
  return sy;
1966
0
}
1967
1968
static const char *
1969
my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
1970
0
{
1971
0
  int i;
1972
1973
0
  if (psc->syms == 0)
1974
0
    psc->syms = slurp_symtab (abfd, psc);
1975
1976
0
  for (i = 0; i < psc->symcount; i++)
1977
0
    {
1978
0
      if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
1979
0
  return psc->syms[i]->name;
1980
0
    }
1981
1982
0
  return NULL;
1983
0
}
1984
1985
static void
1986
cleanup_syms (sym_cache *psc)
1987
0
{
1988
0
  psc->symcount = 0;
1989
0
  free (psc->syms);
1990
0
  psc->syms = NULL;
1991
0
}
1992
1993
/* This is the version for "compressed" pdata.  */
1994
1995
bool
1996
_bfd_peAArch64_print_ce_compressed_pdata (bfd * abfd, void * vfile)
1997
0
{
1998
0
# define PDATA_ROW_SIZE (2 * 4)
1999
0
  FILE *file = (FILE *) vfile;
2000
0
  bfd_byte *data = NULL;
2001
0
  asection *section = bfd_get_section_by_name (abfd, ".pdata");
2002
0
  bfd_size_type datasize = 0;
2003
0
  bfd_size_type i;
2004
0
  bfd_size_type start, stop;
2005
0
  int onaline = PDATA_ROW_SIZE;
2006
0
  struct sym_cache cache = {0, 0} ;
2007
2008
0
  if (section == NULL
2009
0
      || (section->flags & SEC_HAS_CONTENTS) == 0
2010
0
      || coff_section_data (abfd, section) == NULL
2011
0
      || pei_section_data (abfd, section) == NULL)
2012
0
    return true;
2013
2014
0
  stop = pei_section_data (abfd, section)->virt_size;
2015
0
  if ((stop % onaline) != 0)
2016
0
    fprintf (file,
2017
       /* xgettext:c-format */
2018
0
       _("warning, .pdata section size (%ld) is not a multiple of %d\n"),
2019
0
       (long) stop, onaline);
2020
2021
0
  fprintf (file,
2022
0
     _("\nThe Function Table (interpreted .pdata section contents)\n"));
2023
2024
0
  fprintf (file, _("\
2025
0
 vma:\t\tBegin    Prolog   Function Flags    Exception EH\n\
2026
0
     \t\tAddress  Length   Length   32b exc  Handler   Data\n"));
2027
2028
0
  datasize = section->size;
2029
0
  if (datasize == 0)
2030
0
    return true;
2031
2032
0
  if (! bfd_malloc_and_get_section (abfd, section, &data))
2033
0
    {
2034
0
      free (data);
2035
0
      return false;
2036
0
    }
2037
2038
0
  start = 0;
2039
0
  if (stop > datasize)
2040
0
    stop = datasize;
2041
2042
0
  for (i = start; i < stop; i += onaline)
2043
0
    {
2044
0
      bfd_vma begin_addr;
2045
0
      bfd_vma other_data;
2046
0
      bfd_vma prolog_length, function_length;
2047
0
      int flag32bit, exception_flag;
2048
0
      asection *tsection;
2049
2050
0
      if (i + PDATA_ROW_SIZE > stop)
2051
0
  break;
2052
2053
0
      begin_addr = GET_PDATA_ENTRY (abfd, data + i     );
2054
0
      other_data = GET_PDATA_ENTRY (abfd, data + i +  4);
2055
2056
0
      if (begin_addr == 0 && other_data == 0)
2057
  /* We are probably into the padding of the section now.  */
2058
0
  break;
2059
2060
0
      prolog_length = (other_data & 0x000000FF);
2061
0
      function_length = (other_data & 0x3FFFFF00) >> 8;
2062
0
      flag32bit = (int)((other_data & 0x40000000) >> 30);
2063
0
      exception_flag = (int)((other_data & 0x80000000) >> 31);
2064
2065
0
      fputc (' ', file);
2066
0
      bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
2067
0
      bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
2068
0
      bfd_fprintf_vma (abfd, file, prolog_length); fputc (' ', file);
2069
0
      bfd_fprintf_vma (abfd, file, function_length); fputc (' ', file);
2070
0
      fprintf (file, "%2d  %2d   ", flag32bit, exception_flag);
2071
2072
      /* Get the exception handler's address and the data passed from the
2073
   .text section. This is really the data that belongs with the .pdata
2074
   but got "compressed" out for the ARM and SH4 architectures.  */
2075
0
      tsection = bfd_get_section_by_name (abfd, ".text");
2076
0
      if (tsection && coff_section_data (abfd, tsection)
2077
0
    && pei_section_data (abfd, tsection))
2078
0
  {
2079
0
    bfd_vma eh_off = (begin_addr - 8) - tsection->vma;
2080
0
    bfd_byte *tdata;
2081
2082
0
    tdata = (bfd_byte *) bfd_malloc (8);
2083
0
    if (tdata)
2084
0
      {
2085
0
        if (bfd_get_section_contents (abfd, tsection, tdata, eh_off, 8))
2086
0
    {
2087
0
      bfd_vma eh, eh_data;
2088
2089
0
      eh = bfd_get_32 (abfd, tdata);
2090
0
      eh_data = bfd_get_32 (abfd, tdata + 4);
2091
0
      fprintf (file, "%08x  ", (unsigned int) eh);
2092
0
      fprintf (file, "%08x", (unsigned int) eh_data);
2093
0
      if (eh != 0)
2094
0
        {
2095
0
          const char *s = my_symbol_for_address (abfd, eh, &cache);
2096
2097
0
          if (s)
2098
0
      fprintf (file, " (%s) ", s);
2099
0
        }
2100
0
    }
2101
0
        free (tdata);
2102
0
      }
2103
0
  }
2104
2105
0
      fprintf (file, "\n");
2106
0
    }
2107
2108
0
  free (data);
2109
2110
0
  cleanup_syms (& cache);
2111
2112
0
  return true;
2113
0
#undef PDATA_ROW_SIZE
2114
0
}
2115
2116

2117
8.77k
#define IMAGE_REL_BASED_HIGHADJ 4
2118
static const char * const tbl[] =
2119
{
2120
  "ABSOLUTE",
2121
  "HIGH",
2122
  "LOW",
2123
  "HIGHLOW",
2124
  "HIGHADJ",
2125
  "MIPS_JMPADDR",
2126
  "SECTION",
2127
  "REL32",
2128
  "RESERVED1",
2129
  "MIPS_JMPADDR16",
2130
  "DIR64",
2131
  "HIGH3ADJ",
2132
  "UNKNOWN",   /* MUST be last.  */
2133
};
2134
2135
static bool
2136
pe_print_reloc (bfd * abfd, void * vfile)
2137
3.53k
{
2138
3.53k
  FILE *file = (FILE *) vfile;
2139
3.53k
  bfd_byte *data = 0;
2140
3.53k
  asection *section = bfd_get_section_by_name (abfd, ".reloc");
2141
3.53k
  bfd_byte *p, *end;
2142
2143
3.53k
  if (section == NULL
2144
3.53k
      || section->size == 0
2145
3.53k
      || (section->flags & SEC_HAS_CONTENTS) == 0)
2146
3.47k
    return true;
2147
2148
56
  fprintf (file,
2149
56
     _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
2150
2151
56
  if (! bfd_malloc_and_get_section (abfd, section, &data))
2152
10
    {
2153
10
      free (data);
2154
10
      return false;
2155
10
    }
2156
2157
46
  p = data;
2158
46
  end = data + section->size;
2159
83
  while (p + 8 <= end)
2160
60
    {
2161
60
      int j;
2162
60
      bfd_vma virtual_address;
2163
60
      unsigned long number, size;
2164
60
      bfd_byte *chunk_end;
2165
2166
      /* The .reloc section is a sequence of blocks, with a header consisting
2167
   of two 32 bit quantities, followed by a number of 16 bit entries.  */
2168
60
      virtual_address = bfd_get_32 (abfd, p);
2169
60
      size = bfd_get_32 (abfd, p + 4);
2170
60
      p += 8;
2171
60
      number = (size - 8) / 2;
2172
2173
60
      if (size == 0)
2174
23
  break;
2175
2176
37
      fprintf (file,
2177
         /* xgettext:c-format */
2178
37
         _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
2179
37
         (unsigned long) virtual_address, size, size, number);
2180
2181
37
      chunk_end = p - 8 + size;
2182
37
      if (chunk_end > end)
2183
23
  chunk_end = end;
2184
37
      j = 0;
2185
4.42k
      while (p + 2 <= chunk_end)
2186
4.38k
  {
2187
4.38k
    unsigned short e = bfd_get_16 (abfd, p);
2188
4.38k
    unsigned int t = (e & 0xF000) >> 12;
2189
4.38k
    int off = e & 0x0FFF;
2190
2191
4.38k
    if (t >= sizeof (tbl) / sizeof (tbl[0]))
2192
475
      t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
2193
2194
4.38k
    fprintf (file,
2195
       /* xgettext:c-format */
2196
4.38k
       _("\treloc %4d offset %4x [%4lx] %s"),
2197
4.38k
       j, off, (unsigned long) (off + virtual_address), tbl[t]);
2198
2199
4.38k
    p += 2;
2200
4.38k
    j++;
2201
2202
    /* HIGHADJ takes an argument, - the next record *is* the
2203
       low 16 bits of addend.  */
2204
4.38k
    if (t == IMAGE_REL_BASED_HIGHADJ && p + 2 <= chunk_end)
2205
125
      {
2206
125
        fprintf (file, " (%4x)", (unsigned int) bfd_get_16 (abfd, p));
2207
125
        p += 2;
2208
125
        j++;
2209
125
      }
2210
2211
4.38k
    fprintf (file, "\n");
2212
4.38k
  }
2213
37
    }
2214
2215
46
  free (data);
2216
2217
46
  return true;
2218
56
}
2219

2220
/* A data structure describing the regions of a .rsrc section.
2221
   Some fields are filled in as the section is parsed.  */
2222
2223
typedef struct rsrc_regions
2224
{
2225
  bfd_byte * section_start;
2226
  bfd_byte * section_end;
2227
  bfd_byte * strings_start;
2228
  bfd_byte * resource_start;
2229
} rsrc_regions;
2230
2231
static bfd_byte *
2232
rsrc_print_resource_directory (FILE * , bfd *, unsigned int, bfd_byte *,
2233
             rsrc_regions *, bfd_vma);
2234
2235
/* Print the resource entry at DATA, with the text indented by INDENT.
2236
   Recusively calls rsrc_print_resource_directory to print the contents
2237
   of directory entries.
2238
   Returns the address of the end of the data associated with the entry
2239
   or section_end + 1 upon failure.  */
2240
2241
static bfd_byte *
2242
rsrc_print_resource_entries (FILE *file,
2243
           bfd *abfd,
2244
           unsigned int indent,
2245
           bool is_name,
2246
           bfd_byte *data,
2247
           rsrc_regions *regions,
2248
           bfd_vma rva_bias)
2249
277
{
2250
277
  unsigned long entry, addr, size;
2251
277
  bfd_byte * leaf;
2252
2253
277
  if (data + 8 >= regions->section_end)
2254
1
    return regions->section_end + 1;
2255
2256
  /* xgettext:c-format */
2257
276
  fprintf (file, _("%03x %*.s Entry: "), (int)(data - regions->section_start), indent, " ");
2258
2259
276
  entry = (unsigned long) bfd_get_32 (abfd, data);
2260
276
  if (is_name)
2261
60
    {
2262
60
      bfd_byte * name;
2263
2264
      /* Note - the documentation says that this field is an RVA value
2265
   but windres appears to produce a section relative offset with
2266
   the top bit set.  Support both styles for now.  */
2267
60
      if (HighBitSet (entry))
2268
6
  name = regions->section_start + WithoutHighBit (entry);
2269
54
      else
2270
54
  name = regions->section_start + entry - rva_bias;
2271
2272
60
      if (name + 2 < regions->section_end && name > regions->section_start)
2273
23
  {
2274
23
    unsigned int len;
2275
2276
23
    if (regions->strings_start == NULL)
2277
14
      regions->strings_start = name;
2278
2279
23
    len = bfd_get_16 (abfd, name);
2280
2281
23
    fprintf (file, _("name: [val: %08lx len %d]: "), entry, len);
2282
2283
23
    if (name + 2 + len * 2 < regions->section_end)
2284
19
      {
2285
        /* This strange loop is to cope with multibyte characters.  */
2286
445
        while (len --)
2287
426
    {
2288
426
      char c;
2289
2290
426
      name += 2;
2291
426
      c = * name;
2292
      /* Avoid printing control characters.  */
2293
426
      if (c > 0 && c < 32)
2294
183
        fprintf (file, "^%c", c + 64);
2295
243
      else
2296
243
        fprintf (file, "%.1s", name);
2297
426
    }
2298
19
      }
2299
4
    else
2300
4
      {
2301
4
        fprintf (file, _("<corrupt string length: %#x>\n"), len);
2302
        /* PR binutils/17512: Do not try to continue decoding a
2303
     corrupted resource section.  It is likely to end up with
2304
     reams of extraneous output.  FIXME: We could probably
2305
     continue if we disable the printing of strings...  */
2306
4
        return regions->section_end + 1;
2307
4
      }
2308
23
  }
2309
37
      else
2310
37
  {
2311
37
    fprintf (file, _("<corrupt string offset: %#lx>\n"), entry);
2312
37
    return regions->section_end + 1;
2313
37
  }
2314
60
    }
2315
216
  else
2316
216
    fprintf (file, _("ID: %#08lx"), entry);
2317
2318
235
  entry = (long) bfd_get_32 (abfd, data + 4);
2319
235
  fprintf (file, _(", Value: %#08lx\n"), entry);
2320
2321
235
  if (HighBitSet  (entry))
2322
27
    {
2323
27
      data = regions->section_start + WithoutHighBit (entry);
2324
27
      if (data <= regions->section_start || data > regions->section_end)
2325
12
  return regions->section_end + 1;
2326
2327
      /* FIXME: PR binutils/17512: A corrupt file could contain a loop
2328
   in the resource table.  We need some way to detect this.  */
2329
15
      return rsrc_print_resource_directory (file, abfd, indent + 1, data,
2330
15
              regions, rva_bias);
2331
27
    }
2332
2333
208
  leaf = regions->section_start + entry;
2334
2335
208
  if (leaf + 16 >= regions->section_end
2336
      /* PR 17512: file: 055dff7e.  */
2337
208
      || leaf < regions->section_start)
2338
12
    return regions->section_end + 1;
2339
2340
  /* xgettext:c-format */
2341
196
  fprintf (file, _("%03x %*.s  Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"),
2342
196
     (int) (entry), indent, " ",
2343
196
     addr = (long) bfd_get_32 (abfd, leaf),
2344
196
     size = (long) bfd_get_32 (abfd, leaf + 4),
2345
196
     (int) bfd_get_32 (abfd, leaf + 8));
2346
2347
  /* Check that the reserved entry is 0.  */
2348
196
  if (bfd_get_32 (abfd, leaf + 12) != 0
2349
      /* And that the data address/size is valid too.  */
2350
196
      || (regions->section_start + (addr - rva_bias) + size > regions->section_end))
2351
8
    return regions->section_end + 1;
2352
2353
188
  if (regions->resource_start == NULL)
2354
17
    regions->resource_start = regions->section_start + (addr - rva_bias);
2355
2356
188
  return regions->section_start + (addr - rva_bias) + size;
2357
196
}
2358
2359
440
#define max(a,b) ((a) > (b) ? (a) : (b))
2360
0
#define min(a,b) ((a) < (b) ? (a) : (b))
2361
2362
static bfd_byte *
2363
rsrc_print_resource_directory (FILE *       file,
2364
             bfd *        abfd,
2365
             unsigned int   indent,
2366
             bfd_byte *     data,
2367
             rsrc_regions * regions,
2368
             bfd_vma        rva_bias)
2369
252
{
2370
252
  unsigned int num_names, num_ids;
2371
252
  bfd_byte * highest_data = data;
2372
2373
252
  if (data + 16 >= regions->section_end)
2374
2
    return regions->section_end + 1;
2375
2376
250
  fprintf (file, "%03x %*.s ", (int)(data - regions->section_start), indent, " ");
2377
250
  switch (indent)
2378
250
    {
2379
235
    case 0: fprintf (file, "Type"); break;
2380
13
    case 2: fprintf (file, "Name"); break;
2381
2
    case 4: fprintf (file, "Language"); break;
2382
0
    default:
2383
0
      fprintf (file, _("<unknown directory type: %d>\n"), indent);
2384
      /* FIXME: For now we end the printing here.  If in the
2385
   future more directory types are added to the RSRC spec
2386
   then we will need to change this.  */
2387
0
      return regions->section_end + 1;
2388
250
    }
2389
2390
  /* xgettext:c-format */
2391
250
  fprintf (file, _(" Table: Char: %d, Time: %08lx, Ver: %d/%d, Num Names: %d, IDs: %d\n"),
2392
250
     (int) bfd_get_32 (abfd, data),
2393
250
     (long) bfd_get_32 (abfd, data + 4),
2394
250
     (int)  bfd_get_16 (abfd, data + 8),
2395
250
     (int)  bfd_get_16 (abfd, data + 10),
2396
250
     num_names = (int) bfd_get_16 (abfd, data + 12),
2397
250
     num_ids =   (int) bfd_get_16 (abfd, data + 14));
2398
250
  data += 16;
2399
2400
253
  while (num_names --)
2401
61
    {
2402
61
      bfd_byte * entry_end;
2403
2404
61
      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, true,
2405
61
                 data, regions, rva_bias);
2406
61
      data += 8;
2407
61
      highest_data = max (highest_data, entry_end);
2408
61
      if (entry_end >= regions->section_end)
2409
58
  return entry_end;
2410
61
    }
2411
2412
379
  while (num_ids --)
2413
216
    {
2414
216
      bfd_byte * entry_end;
2415
2416
216
      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, false,
2417
216
                 data, regions, rva_bias);
2418
216
      data += 8;
2419
216
      highest_data = max (highest_data, entry_end);
2420
216
      if (entry_end >= regions->section_end)
2421
29
  return entry_end;
2422
216
    }
2423
2424
163
  return max (highest_data, data);
2425
192
}
2426
2427
/* Display the contents of a .rsrc section.  We do not try to
2428
   reproduce the resources, windres does that.  Instead we dump
2429
   the tables in a human readable format.  */
2430
2431
static bool
2432
rsrc_print_section (bfd * abfd, void * vfile)
2433
3.53k
{
2434
3.53k
  bfd_vma rva_bias;
2435
3.53k
  pe_data_type * pe;
2436
3.53k
  FILE * file = (FILE *) vfile;
2437
3.53k
  bfd_size_type datasize;
2438
3.53k
  asection * section;
2439
3.53k
  bfd_byte * data;
2440
3.53k
  rsrc_regions regions;
2441
2442
3.53k
  pe = pe_data (abfd);
2443
3.53k
  if (pe == NULL)
2444
0
    return true;
2445
2446
3.53k
  section = bfd_get_section_by_name (abfd, ".rsrc");
2447
3.53k
  if (section == NULL)
2448
3.42k
    return true;
2449
104
  if (!(section->flags & SEC_HAS_CONTENTS))
2450
4
    return true;
2451
2452
100
  datasize = section->size;
2453
100
  if (datasize == 0)
2454
1
    return true;
2455
2456
99
  rva_bias = section->vma - pe->pe_opthdr.ImageBase;
2457
2458
99
  if (! bfd_malloc_and_get_section (abfd, section, & data))
2459
14
    {
2460
14
      free (data);
2461
14
      return false;
2462
14
    }
2463
2464
85
  regions.section_start = data;
2465
85
  regions.section_end = data + datasize;
2466
85
  regions.strings_start = NULL;
2467
85
  regions.resource_start = NULL;
2468
2469
85
  fflush (file);
2470
85
  fprintf (file, "\nThe .rsrc Resource Directory section:\n");
2471
2472
322
  while (data < regions.section_end)
2473
237
    {
2474
237
      bfd_byte * p = data;
2475
2476
237
      data = rsrc_print_resource_directory (file, abfd, 0, data, & regions, rva_bias);
2477
2478
237
      if (data == regions.section_end + 1)
2479
76
  fprintf (file, _("Corrupt .rsrc section detected!\n"));
2480
161
      else
2481
161
  {
2482
    /* Align data before continuing.  */
2483
161
    int align = (1 << section->alignment_power) - 1;
2484
2485
161
    data = (bfd_byte *) (((ptrdiff_t) (data + align)) & ~ align);
2486
161
    rva_bias += data - p;
2487
2488
    /* For reasons that are unclear .rsrc sections are sometimes created
2489
       aligned to a 1^3 boundary even when their alignment is set at
2490
       1^2.  Catch that case here before we issue a spurious warning
2491
       message.  */
2492
161
    if (data == (regions.section_end - 4))
2493
2
      data = regions.section_end;
2494
159
    else if (data < regions.section_end)
2495
158
      {
2496
        /* If the extra data is all zeros then do not complain.
2497
     This is just padding so that the section meets the
2498
     page size requirements.  */
2499
6.62k
        while (++ data < regions.section_end)
2500
6.61k
    if (*data != 0)
2501
152
      break;
2502
158
        if (data < regions.section_end)
2503
152
    fprintf (file, _("\nWARNING: Extra data in .rsrc section - it will be ignored by Windows:\n"));
2504
158
      }
2505
161
  }
2506
237
    }
2507
2508
85
  if (regions.strings_start != NULL)
2509
14
    fprintf (file, _(" String table starts at offset: %#03x\n"),
2510
14
       (int) (regions.strings_start - regions.section_start));
2511
85
  if (regions.resource_start != NULL)
2512
17
    fprintf (file, _(" Resources start at offset: %#03x\n"),
2513
17
       (int) (regions.resource_start - regions.section_start));
2514
2515
85
  free (regions.section_start);
2516
85
  return true;
2517
99
}
2518
2519
163k
#define IMAGE_NUMBEROF_DEBUG_TYPES 17
2520
2521
static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] =
2522
{
2523
  "Unknown",
2524
  "COFF",
2525
  "CodeView",
2526
  "FPO",
2527
  "Misc",
2528
  "Exception",
2529
  "Fixup",
2530
  "OMAP-to-SRC",
2531
  "OMAP-from-SRC",
2532
  "Borland",
2533
  "Reserved",
2534
  "CLSID",
2535
  "Feature",
2536
  "CoffGrp",
2537
  "ILTCG",
2538
  "MPX",
2539
  "Repro",
2540
};
2541
2542
static bool
2543
pe_print_debugdata (bfd * abfd, void * vfile)
2544
3.53k
{
2545
3.53k
  FILE *file = (FILE *) vfile;
2546
3.53k
  pe_data_type *pe = pe_data (abfd);
2547
3.53k
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
2548
3.53k
  asection *section;
2549
3.53k
  bfd_byte *data = 0;
2550
3.53k
  bfd_size_type dataoff;
2551
3.53k
  unsigned int i, j;
2552
2553
3.53k
  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
2554
3.53k
  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
2555
2556
3.53k
  if (size == 0)
2557
1.70k
    return true;
2558
2559
1.83k
  addr += extra->ImageBase;
2560
8.99k
  for (section = abfd->sections; section != NULL; section = section->next)
2561
8.79k
    {
2562
8.79k
      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
2563
1.63k
  break;
2564
8.79k
    }
2565
2566
1.83k
  if (section == NULL)
2567
197
    {
2568
197
      fprintf (file,
2569
197
         _("\nThere is a debug directory, but the section containing it could not be found\n"));
2570
197
      return true;
2571
197
    }
2572
1.63k
  else if (!(section->flags & SEC_HAS_CONTENTS))
2573
6
    {
2574
6
      fprintf (file,
2575
6
         _("\nThere is a debug directory in %s, but that section has no contents\n"),
2576
6
         section->name);
2577
6
      return true;
2578
6
    }
2579
1.62k
  else if (section->size < size)
2580
28
    {
2581
28
      fprintf (file,
2582
28
         _("\nError: section %s contains the debug data starting address but it is too small\n"),
2583
28
         section->name);
2584
28
      return false;
2585
28
    }
2586
2587
1.59k
  fprintf (file, _("\nThere is a debug directory in %s at 0x%lx\n\n"),
2588
1.59k
     section->name, (unsigned long) addr);
2589
2590
1.59k
  dataoff = addr - section->vma;
2591
2592
1.59k
  if (size > (section->size - dataoff))
2593
27
    {
2594
27
      fprintf (file, _("The debug data size field in the data directory is too big for the section"));
2595
27
      return false;
2596
27
    }
2597
2598
1.57k
  fprintf (file,
2599
1.57k
     _("Type                Size     Rva      Offset\n"));
2600
2601
  /* Read the whole section.  */
2602
1.57k
  if (!bfd_malloc_and_get_section (abfd, section, &data))
2603
438
    {
2604
438
      free (data);
2605
438
      return false;
2606
438
    }
2607
2608
164k
  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
2609
163k
    {
2610
163k
      const char *type_name;
2611
163k
      struct external_IMAGE_DEBUG_DIRECTORY *ext
2612
163k
  = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
2613
163k
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
2614
2615
163k
      _bfd_peAArch64i_swap_debugdir_in (abfd, ext, &idd);
2616
2617
163k
      if ((idd.Type) >= IMAGE_NUMBEROF_DEBUG_TYPES)
2618
146k
  type_name = debug_type_names[0];
2619
17.4k
      else
2620
17.4k
  type_name = debug_type_names[idd.Type];
2621
2622
163k
      fprintf (file, " %2ld  %14s %08lx %08lx %08lx\n",
2623
163k
         idd.Type, type_name, idd.SizeOfData,
2624
163k
         idd.AddressOfRawData, idd.PointerToRawData);
2625
2626
163k
      if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
2627
260
  {
2628
260
    char signature[CV_INFO_SIGNATURE_LENGTH * 2 + 1];
2629
    /* PR 17512: file: 065-29434-0.001:0.1
2630
       We need to use a 32-bit aligned buffer
2631
       to safely read in a codeview record.  */
2632
260
    char buffer[256 + 1] ATTRIBUTE_ALIGNED_ALIGNOF (CODEVIEW_INFO);
2633
260
    char *pdb;
2634
2635
260
    CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer;
2636
2637
    /* The debug entry doesn't have to have to be in a section,
2638
       in which case AddressOfRawData is 0, so always use PointerToRawData.  */
2639
260
    if (!_bfd_peAArch64i_slurp_codeview_record (abfd, (file_ptr) idd.PointerToRawData,
2640
260
                 idd.SizeOfData, cvinfo, &pdb))
2641
260
      continue;
2642
2643
0
    for (j = 0; j < cvinfo->SignatureLength; j++)
2644
0
      sprintf (&signature[j*2], "%02x", cvinfo->Signature[j] & 0xff);
2645
2646
    /* xgettext:c-format */
2647
0
    fprintf (file, _("(format %c%c%c%c signature %s age %ld pdb %s)\n"),
2648
0
       buffer[0], buffer[1], buffer[2], buffer[3],
2649
0
       signature, cvinfo->Age, pdb[0] ? pdb : "(none)");
2650
2651
0
    free (pdb);
2652
0
  }
2653
163k
    }
2654
2655
1.13k
  free(data);
2656
2657
1.13k
  if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0)
2658
1.13k
    fprintf (file,
2659
1.13k
      _("The debug directory size is not a multiple of the debug directory entry size\n"));
2660
2661
1.13k
  return true;
2662
1.57k
}
2663
2664
static bool
2665
pe_is_repro (bfd * abfd)
2666
3.53k
{
2667
3.53k
  pe_data_type *pe = pe_data (abfd);
2668
3.53k
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
2669
3.53k
  asection *section;
2670
3.53k
  bfd_byte *data = 0;
2671
3.53k
  bfd_size_type dataoff;
2672
3.53k
  unsigned int i;
2673
3.53k
  bool res = false;
2674
2675
3.53k
  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
2676
3.53k
  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
2677
2678
3.53k
  if (size == 0)
2679
1.70k
    return false;
2680
2681
1.83k
  addr += extra->ImageBase;
2682
8.99k
  for (section = abfd->sections; section != NULL; section = section->next)
2683
8.79k
    {
2684
8.79k
      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
2685
1.63k
  break;
2686
8.79k
    }
2687
2688
1.83k
  if ((section == NULL)
2689
1.83k
      || (!(section->flags & SEC_HAS_CONTENTS))
2690
1.83k
      || (section->size < size))
2691
231
    {
2692
231
      return false;
2693
231
    }
2694
2695
1.59k
  dataoff = addr - section->vma;
2696
2697
1.59k
  if (size > (section->size - dataoff))
2698
27
    {
2699
27
      return false;
2700
27
    }
2701
2702
1.57k
  if (!bfd_malloc_and_get_section (abfd, section, &data))
2703
438
    {
2704
438
      free (data);
2705
438
      return false;
2706
438
    }
2707
2708
139k
  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
2709
138k
    {
2710
138k
      struct external_IMAGE_DEBUG_DIRECTORY *ext
2711
138k
  = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
2712
138k
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
2713
2714
138k
      _bfd_peAArch64i_swap_debugdir_in (abfd, ext, &idd);
2715
2716
138k
      if (idd.Type == PE_IMAGE_DEBUG_TYPE_REPRO)
2717
300
        {
2718
300
          res = true;
2719
300
          break;
2720
300
        }
2721
138k
    }
2722
2723
1.13k
  free(data);
2724
2725
1.13k
  return res;
2726
1.57k
}
2727
2728
/* Print out the program headers.  */
2729
2730
bool
2731
_bfd_peAArch64_print_private_bfd_data_common (bfd * abfd, void * vfile)
2732
3.53k
{
2733
3.53k
  FILE *file = (FILE *) vfile;
2734
3.53k
  int j;
2735
3.53k
  pe_data_type *pe = pe_data (abfd);
2736
3.53k
  struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
2737
3.53k
  const char *subsystem_name = NULL;
2738
3.53k
  const char *name;
2739
2740
  /* The MS dumpbin program reportedly ands with 0xff0f before
2741
     printing the characteristics field.  Not sure why.  No reason to
2742
     emulate it here.  */
2743
3.53k
  fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
2744
3.53k
#undef PF
2745
49.4k
#define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
2746
3.53k
  PF (IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
2747
3.53k
  PF (IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
2748
3.53k
  PF (IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
2749
3.53k
  PF (IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
2750
3.53k
  PF (IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
2751
3.53k
  PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
2752
3.53k
  PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
2753
3.53k
  PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
2754
3.53k
  PF (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, "copy to swap file if on removable media");
2755
3.53k
  PF (IMAGE_FILE_NET_RUN_FROM_SWAP, "copy to swap file if on network media");
2756
3.53k
  PF (IMAGE_FILE_SYSTEM, "system file");
2757
3.53k
  PF (IMAGE_FILE_DLL, "DLL");
2758
3.53k
  PF (IMAGE_FILE_UP_SYSTEM_ONLY, "run only on uniprocessor machine");
2759
3.53k
  PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
2760
3.53k
#undef PF
2761
2762
  /*
2763
    If a PE_IMAGE_DEBUG_TYPE_REPRO entry is present in the debug directory, the
2764
    timestamp is to be interpreted as the hash of a reproducible build.
2765
  */
2766
3.53k
  if (pe_is_repro (abfd))
2767
300
    {
2768
300
      fprintf (file, "\nTime/Date\t\t%08lx", pe->coff.timestamp);
2769
300
      fprintf (file, "\t(This is a reproducible build file hash, not a timestamp)\n");
2770
300
    }
2771
3.23k
  else
2772
3.23k
    {
2773
      /* ctime implies '\n'.  */
2774
3.23k
      time_t t = pe->coff.timestamp;
2775
3.23k
      fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
2776
3.23k
    }
2777
2778
3.53k
#ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
2779
3.53k
# define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
2780
3.53k
#endif
2781
#ifndef IMAGE_NT_OPTIONAL_HDR64_MAGIC
2782
# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
2783
#endif
2784
3.53k
#ifndef IMAGE_NT_OPTIONAL_HDRROM_MAGIC
2785
3.53k
# define IMAGE_NT_OPTIONAL_HDRROM_MAGIC 0x107
2786
3.53k
#endif
2787
2788
3.53k
  switch (i->Magic)
2789
3.53k
    {
2790
5
    case IMAGE_NT_OPTIONAL_HDR_MAGIC:
2791
5
      name = "PE32";
2792
5
      break;
2793
0
    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
2794
0
      name = "PE32+";
2795
0
      break;
2796
11
    case IMAGE_NT_OPTIONAL_HDRROM_MAGIC:
2797
11
      name = "ROM";
2798
11
      break;
2799
3.51k
    default:
2800
3.51k
      name = NULL;
2801
3.51k
      break;
2802
3.53k
    }
2803
3.53k
  fprintf (file, "Magic\t\t\t%04x", i->Magic);
2804
3.53k
  if (name)
2805
16
    fprintf (file, "\t(%s)",name);
2806
3.53k
  fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
2807
3.53k
  fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
2808
3.53k
  fprintf (file, "SizeOfCode\t\t");
2809
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfCode);
2810
3.53k
  fprintf (file, "\nSizeOfInitializedData\t");
2811
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfInitializedData);
2812
3.53k
  fprintf (file, "\nSizeOfUninitializedData\t");
2813
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfUninitializedData);
2814
3.53k
  fprintf (file, "\nAddressOfEntryPoint\t");
2815
3.53k
  bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
2816
3.53k
  fprintf (file, "\nBaseOfCode\t\t");
2817
3.53k
  bfd_fprintf_vma (abfd, file, i->BaseOfCode);
2818
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
2819
  /* PE32+ does not have BaseOfData member!  */
2820
  fprintf (file, "\nBaseOfData\t\t");
2821
  bfd_fprintf_vma (abfd, file, i->BaseOfData);
2822
#endif
2823
2824
3.53k
  fprintf (file, "\nImageBase\t\t");
2825
3.53k
  bfd_fprintf_vma (abfd, file, i->ImageBase);
2826
3.53k
  fprintf (file, "\nSectionAlignment\t%08x\n", i->SectionAlignment);
2827
3.53k
  fprintf (file, "FileAlignment\t\t%08x\n", i->FileAlignment);
2828
3.53k
  fprintf (file, "MajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
2829
3.53k
  fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
2830
3.53k
  fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
2831
3.53k
  fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
2832
3.53k
  fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
2833
3.53k
  fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
2834
3.53k
  fprintf (file, "Win32Version\t\t%08x\n", i->Reserved1);
2835
3.53k
  fprintf (file, "SizeOfImage\t\t%08x\n", i->SizeOfImage);
2836
3.53k
  fprintf (file, "SizeOfHeaders\t\t%08x\n", i->SizeOfHeaders);
2837
3.53k
  fprintf (file, "CheckSum\t\t%08x\n", i->CheckSum);
2838
2839
3.53k
  switch (i->Subsystem)
2840
3.53k
    {
2841
1.53k
    case IMAGE_SUBSYSTEM_UNKNOWN:
2842
1.53k
      subsystem_name = "unspecified";
2843
1.53k
      break;
2844
3
    case IMAGE_SUBSYSTEM_NATIVE:
2845
3
      subsystem_name = "NT native";
2846
3
      break;
2847
9
    case IMAGE_SUBSYSTEM_WINDOWS_GUI:
2848
9
      subsystem_name = "Windows GUI";
2849
9
      break;
2850
4
    case IMAGE_SUBSYSTEM_WINDOWS_CUI:
2851
4
      subsystem_name = "Windows CUI";
2852
4
      break;
2853
4
    case IMAGE_SUBSYSTEM_POSIX_CUI:
2854
4
      subsystem_name = "POSIX CUI";
2855
4
      break;
2856
3
    case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
2857
3
      subsystem_name = "Wince CUI";
2858
3
      break;
2859
    /* These are from UEFI Platform Initialization Specification 1.1.  */
2860
4
    case IMAGE_SUBSYSTEM_EFI_APPLICATION:
2861
4
      subsystem_name = "EFI application";
2862
4
      break;
2863
3
    case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
2864
3
      subsystem_name = "EFI boot service driver";
2865
3
      break;
2866
1
    case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
2867
1
      subsystem_name = "EFI runtime driver";
2868
1
      break;
2869
8
    case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
2870
8
      subsystem_name = "SAL runtime driver";
2871
8
      break;
2872
    /* This is from revision 8.0 of the MS PE/COFF spec  */
2873
1.59k
    case IMAGE_SUBSYSTEM_XBOX:
2874
1.59k
      subsystem_name = "XBOX";
2875
1.59k
      break;
2876
    /* Added default case for clarity - subsystem_name is NULL anyway.  */
2877
365
    default:
2878
365
      subsystem_name = NULL;
2879
3.53k
    }
2880
2881
3.53k
  fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
2882
3.53k
  if (subsystem_name)
2883
3.16k
    fprintf (file, "\t(%s)", subsystem_name);
2884
3.53k
  fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
2885
3.53k
  if (i->DllCharacteristics)
2886
1.98k
    {
2887
1.98k
      unsigned short dllch = i->DllCharacteristics;
2888
1.98k
      const char *indent = "\t\t\t\t\t";
2889
2890
1.98k
      if (dllch & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA)
2891
139
  fprintf (file, "%sHIGH_ENTROPY_VA\n", indent);
2892
1.98k
      if (dllch & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)
2893
199
  fprintf (file, "%sDYNAMIC_BASE\n", indent);
2894
1.98k
      if (dllch & IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY)
2895
164
  fprintf (file, "%sFORCE_INTEGRITY\n", indent);
2896
1.98k
      if (dllch & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
2897
146
  fprintf (file, "%sNX_COMPAT\n", indent);
2898
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)
2899
247
  fprintf (file, "%sNO_ISOLATION\n", indent);
2900
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_SEH)
2901
209
  fprintf (file, "%sNO_SEH\n", indent);
2902
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_BIND)
2903
150
  fprintf (file, "%sNO_BIND\n", indent);
2904
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_APPCONTAINER)
2905
1.86k
  fprintf (file, "%sAPPCONTAINER\n", indent);
2906
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)
2907
184
  fprintf (file, "%sWDM_DRIVER\n", indent);
2908
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_GUARD_CF)
2909
146
  fprintf (file, "%sGUARD_CF\n", indent);
2910
1.98k
      if (dllch & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)
2911
78
  fprintf (file, "%sTERMINAL_SERVICE_AWARE\n", indent);
2912
1.98k
    }
2913
3.53k
  fprintf (file, "SizeOfStackReserve\t");
2914
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
2915
3.53k
  fprintf (file, "\nSizeOfStackCommit\t");
2916
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
2917
3.53k
  fprintf (file, "\nSizeOfHeapReserve\t");
2918
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
2919
3.53k
  fprintf (file, "\nSizeOfHeapCommit\t");
2920
3.53k
  bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
2921
3.53k
  fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
2922
3.53k
  fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
2923
3.53k
     (unsigned long) i->NumberOfRvaAndSizes);
2924
2925
3.53k
  fprintf (file, "\nThe Data Directory\n");
2926
60.0k
  for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
2927
56.5k
    {
2928
56.5k
      fprintf (file, "Entry %1x ", j);
2929
56.5k
      bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
2930
56.5k
      fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
2931
56.5k
      fprintf (file, "%s\n", dir_names[j]);
2932
56.5k
    }
2933
2934
3.53k
  pe_print_idata (abfd, vfile);
2935
3.53k
  pe_print_edata (abfd, vfile);
2936
3.53k
  if (bfd_coff_have_print_pdata (abfd))
2937
0
    bfd_coff_print_pdata (abfd, vfile);
2938
3.53k
  else
2939
3.53k
    pe_print_pdata (abfd, vfile);
2940
3.53k
  pe_print_reloc (abfd, vfile);
2941
3.53k
  pe_print_debugdata (abfd, file);
2942
2943
3.53k
  rsrc_print_section (abfd, vfile);
2944
2945
3.53k
  return true;
2946
3.53k
}
2947
2948
static bool
2949
is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
2950
0
{
2951
0
  bfd_vma addr = * (bfd_vma *) obj;
2952
0
  return (addr >= sect->vma) && (addr < (sect->vma + sect->size));
2953
0
}
2954
2955
static asection *
2956
find_section_by_vma (bfd *abfd, bfd_vma addr)
2957
0
{
2958
0
  return bfd_sections_find_if (abfd, is_vma_in_section, (void *) & addr);
2959
0
}
2960
2961
/* Copy any private info we understand from the input bfd
2962
   to the output bfd.  */
2963
2964
bool
2965
_bfd_peAArch64_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
2966
3
{
2967
3
  pe_data_type *ipe, *ope;
2968
3
  bfd_size_type size;
2969
2970
  /* One day we may try to grok other private data.  */
2971
3
  if (ibfd->xvec->flavour != bfd_target_coff_flavour
2972
3
      || obfd->xvec->flavour != bfd_target_coff_flavour)
2973
0
    return true;
2974
2975
3
  ipe = pe_data (ibfd);
2976
3
  ope = pe_data (obfd);
2977
2978
  /* pe_opthdr is copied in copy_object.  */
2979
3
  ope->dll = ipe->dll;
2980
2981
  /* Don't copy input subsystem if output is different from input.  */
2982
3
  if (obfd->xvec != ibfd->xvec)
2983
0
    ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN;
2984
2985
  /* For strip: if we removed .reloc, we'll make a real mess of things
2986
     if we don't remove this entry as well.  */
2987
3
  if (! pe_data (obfd)->has_reloc_section)
2988
3
    {
2989
3
      pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
2990
3
      pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
2991
3
    }
2992
2993
  /* For PIE, if there is .reloc, we won't add IMAGE_FILE_RELOCS_STRIPPED.
2994
     But there is no .reloc, we make sure that IMAGE_FILE_RELOCS_STRIPPED
2995
     won't be added.  */
2996
3
  if (! pe_data (ibfd)->has_reloc_section
2997
3
      && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
2998
3
    pe_data (obfd)->dont_strip_reloc = 1;
2999
3000
3
  memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
3001
3002
  /* The file offsets contained in the debug directory need rewriting.  */
3003
3
  size = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size;
3004
3
  if (size != 0)
3005
0
    {
3006
0
      bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
3007
0
  + ope->pe_opthdr.ImageBase;
3008
      /* In particular a .buildid section may overlap (in VA space) with
3009
   whatever section comes ahead of it (largely because of section->size
3010
   representing s_size, not virt_size).  Therefore don't look for the
3011
   section containing the first byte, but for that covering the last
3012
   one.  */
3013
0
      bfd_vma last = addr + size - 1;
3014
0
      asection *section = find_section_by_vma (obfd, last);
3015
3016
0
      if (section != NULL)
3017
0
  {
3018
0
    bfd_byte *data;
3019
0
    bfd_vma dataoff = addr - section->vma;
3020
3021
    /* PR 17512: file: 0f15796a.  */
3022
0
    if (addr < section->vma
3023
0
        || section->size < dataoff
3024
0
        || section->size - dataoff < size)
3025
0
      {
3026
        /* xgettext:c-format */
3027
0
        _bfd_error_handler
3028
0
    (_("%pB: Data Directory (%lx bytes at %" PRIx64 ") "
3029
0
       "extends across section boundary at %" PRIx64),
3030
0
     obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
3031
0
     (uint64_t) addr, (uint64_t) section->vma);
3032
0
        return false;
3033
0
      }
3034
3035
0
    if ((section->flags & SEC_HAS_CONTENTS) != 0
3036
0
        && bfd_malloc_and_get_section (obfd, section, &data))
3037
0
      {
3038
0
        unsigned int i;
3039
0
        struct external_IMAGE_DEBUG_DIRECTORY *dd =
3040
0
    (struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff);
3041
3042
0
        for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
3043
0
         / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
3044
0
    {
3045
0
      asection *ddsection;
3046
0
      struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
3047
0
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
3048
0
      bfd_vma idd_vma;
3049
3050
0
      _bfd_peAArch64i_swap_debugdir_in (obfd, edd, &idd);
3051
3052
      /* RVA 0 means only offset is valid, not handled yet.  */
3053
0
      if (idd.AddressOfRawData == 0)
3054
0
        continue;
3055
3056
0
      idd_vma = idd.AddressOfRawData + ope->pe_opthdr.ImageBase;
3057
0
      ddsection = find_section_by_vma (obfd, idd_vma);
3058
0
      if (!ddsection)
3059
0
        continue; /* Not in a section! */
3060
3061
0
      idd.PointerToRawData
3062
0
        = ddsection->filepos + idd_vma - ddsection->vma;
3063
0
      _bfd_peAArch64i_swap_debugdir_out (obfd, &idd, edd);
3064
0
    }
3065
3066
0
        if (!bfd_set_section_contents (obfd, section, data, 0,
3067
0
               section->size))
3068
0
    {
3069
0
      _bfd_error_handler (_("failed to update file offsets"
3070
0
          " in debug directory"));
3071
0
      free (data);
3072
0
      return false;
3073
0
    }
3074
0
        free (data);
3075
0
      }
3076
0
    else
3077
0
      {
3078
0
        _bfd_error_handler (_("%pB: failed to read "
3079
0
            "debug data section"), obfd);
3080
0
        return false;
3081
0
      }
3082
0
  }
3083
0
    }
3084
3085
3
  return true;
3086
3
}
3087
3088
/* Copy private section data.  */
3089
3090
bool
3091
_bfd_peAArch64_bfd_copy_private_section_data (bfd *ibfd,
3092
               asection *isec,
3093
               bfd *obfd,
3094
               asection *osec)
3095
134
{
3096
134
  if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
3097
134
      || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
3098
0
    return true;
3099
3100
134
  if (coff_section_data (ibfd, isec) != NULL
3101
134
      && pei_section_data (ibfd, isec) != NULL)
3102
134
    {
3103
134
      if (coff_section_data (obfd, osec) == NULL)
3104
134
  {
3105
134
    size_t amt = sizeof (struct coff_section_tdata);
3106
134
    osec->used_by_bfd = bfd_zalloc (obfd, amt);
3107
134
    if (osec->used_by_bfd == NULL)
3108
0
      return false;
3109
134
  }
3110
3111
134
      if (pei_section_data (obfd, osec) == NULL)
3112
134
  {
3113
134
    size_t amt = sizeof (struct pei_section_tdata);
3114
134
    coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
3115
134
    if (coff_section_data (obfd, osec)->tdata == NULL)
3116
0
      return false;
3117
134
  }
3118
3119
134
      pei_section_data (obfd, osec)->virt_size =
3120
134
  pei_section_data (ibfd, isec)->virt_size;
3121
134
      pei_section_data (obfd, osec)->pe_flags =
3122
134
  pei_section_data (ibfd, isec)->pe_flags;
3123
134
    }
3124
3125
134
  return true;
3126
134
}
3127
3128
void
3129
_bfd_peAArch64_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
3130
522
{
3131
522
  coff_get_symbol_info (abfd, symbol, ret);
3132
522
}
3133
3134
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64))
3135
static int
3136
sort_x64_pdata (const void *l, const void *r)
3137
0
{
3138
0
  const char *lp = (const char *) l;
3139
0
  const char *rp = (const char *) r;
3140
0
  bfd_vma vl, vr;
3141
0
  vl = bfd_getl32 (lp); vr = bfd_getl32 (rp);
3142
0
  if (vl != vr)
3143
0
    return (vl < vr ? -1 : 1);
3144
  /* We compare just begin address.  */
3145
0
  return 0;
3146
0
}
3147
#endif
3148

3149
/* Functions to process a .rsrc section.  */
3150
3151
static unsigned int sizeof_leaves;
3152
static unsigned int sizeof_strings;
3153
static unsigned int sizeof_tables_and_entries;
3154
3155
static bfd_byte *
3156
rsrc_count_directory (bfd *, bfd_byte *, bfd_byte *, bfd_byte *, bfd_vma);
3157
3158
static bfd_byte *
3159
rsrc_count_entries (bfd *abfd,
3160
        bool is_name,
3161
        bfd_byte *datastart,
3162
        bfd_byte *data,
3163
        bfd_byte *dataend,
3164
        bfd_vma rva_bias)
3165
0
{
3166
0
  unsigned long entry, addr, size;
3167
3168
0
  if (data + 8 >= dataend)
3169
0
    return dataend + 1;
3170
3171
0
  if (is_name)
3172
0
    {
3173
0
      bfd_byte * name;
3174
3175
0
      entry = (long) bfd_get_32 (abfd, data);
3176
3177
0
      if (HighBitSet (entry))
3178
0
  name = datastart + WithoutHighBit (entry);
3179
0
      else
3180
0
  name = datastart + entry - rva_bias;
3181
3182
0
      if (name + 2 >= dataend || name < datastart)
3183
0
  return dataend + 1;
3184
3185
0
      unsigned int len = bfd_get_16 (abfd, name);
3186
0
      if (len == 0 || len > 256)
3187
0
  return dataend + 1;
3188
0
    }
3189
3190
0
  entry = (long) bfd_get_32 (abfd, data + 4);
3191
3192
0
  if (HighBitSet (entry))
3193
0
    {
3194
0
      data = datastart + WithoutHighBit (entry);
3195
3196
0
      if (data <= datastart || data >= dataend)
3197
0
  return dataend + 1;
3198
3199
0
      return rsrc_count_directory (abfd, datastart, data, dataend, rva_bias);
3200
0
    }
3201
3202
0
  if (datastart + entry + 16 >= dataend)
3203
0
    return dataend + 1;
3204
3205
0
  addr = (long) bfd_get_32 (abfd, datastart + entry);
3206
0
  size = (long) bfd_get_32 (abfd, datastart + entry + 4);
3207
3208
0
  return datastart + addr - rva_bias + size;
3209
0
}
3210
3211
static bfd_byte *
3212
rsrc_count_directory (bfd *      abfd,
3213
          bfd_byte *     datastart,
3214
          bfd_byte *     data,
3215
          bfd_byte *     dataend,
3216
          bfd_vma      rva_bias)
3217
0
{
3218
0
  unsigned int  num_entries, num_ids;
3219
0
  bfd_byte *    highest_data = data;
3220
3221
0
  if (data + 16 >= dataend)
3222
0
    return dataend + 1;
3223
3224
0
  num_entries  = (int) bfd_get_16 (abfd, data + 12);
3225
0
  num_ids      = (int) bfd_get_16 (abfd, data + 14);
3226
3227
0
  num_entries += num_ids;
3228
3229
0
  data += 16;
3230
3231
0
  while (num_entries --)
3232
0
    {
3233
0
      bfd_byte * entry_end;
3234
3235
0
      entry_end = rsrc_count_entries (abfd, num_entries >= num_ids,
3236
0
              datastart, data, dataend, rva_bias);
3237
0
      data += 8;
3238
0
      highest_data = max (highest_data, entry_end);
3239
0
      if (entry_end >= dataend)
3240
0
  break;
3241
0
    }
3242
3243
0
  return max (highest_data, data);
3244
0
}
3245
3246
typedef struct rsrc_dir_chain
3247
{
3248
  unsigned int         num_entries;
3249
  struct rsrc_entry *  first_entry;
3250
  struct rsrc_entry *  last_entry;
3251
} rsrc_dir_chain;
3252
3253
typedef struct rsrc_directory
3254
{
3255
  unsigned int characteristics;
3256
  unsigned int time;
3257
  unsigned int major;
3258
  unsigned int minor;
3259
3260
  rsrc_dir_chain names;
3261
  rsrc_dir_chain ids;
3262
3263
  struct rsrc_entry * entry;
3264
} rsrc_directory;
3265
3266
typedef struct rsrc_string
3267
{
3268
  unsigned int  len;
3269
  bfd_byte *  string;
3270
} rsrc_string;
3271
3272
typedef struct rsrc_leaf
3273
{
3274
  unsigned int  size;
3275
  unsigned int  codepage;
3276
  bfd_byte *  data;
3277
} rsrc_leaf;
3278
3279
typedef struct rsrc_entry
3280
{
3281
  bool is_name;
3282
  union
3283
  {
3284
    unsigned int    id;
3285
    struct rsrc_string    name;
3286
  } name_id;
3287
3288
  bool is_dir;
3289
  union
3290
  {
3291
    struct rsrc_directory * directory;
3292
    struct rsrc_leaf *      leaf;
3293
  } value;
3294
3295
  struct rsrc_entry *   next_entry;
3296
  struct rsrc_directory * parent;
3297
} rsrc_entry;
3298
3299
static bfd_byte *
3300
rsrc_parse_directory (bfd *, rsrc_directory *, bfd_byte *,
3301
          bfd_byte *, bfd_byte *, bfd_vma, rsrc_entry *);
3302
3303
static bfd_byte *
3304
rsrc_parse_entry (bfd *abfd,
3305
      bool is_name,
3306
      rsrc_entry *entry,
3307
      bfd_byte *datastart,
3308
      bfd_byte * data,
3309
      bfd_byte *dataend,
3310
      bfd_vma rva_bias,
3311
      rsrc_directory *parent)
3312
0
{
3313
0
  unsigned long val, addr, size;
3314
3315
0
  val = bfd_get_32 (abfd, data);
3316
3317
0
  entry->parent = parent;
3318
0
  entry->is_name = is_name;
3319
3320
0
  if (is_name)
3321
0
    {
3322
0
      bfd_byte * address;
3323
3324
0
      if (HighBitSet (val))
3325
0
  {
3326
0
    val = WithoutHighBit (val);
3327
3328
0
    address = datastart + val;
3329
0
  }
3330
0
      else
3331
0
  {
3332
0
    address = datastart + val - rva_bias;
3333
0
  }
3334
3335
0
      if (address + 3 > dataend)
3336
0
  return dataend;
3337
3338
0
      entry->name_id.name.len    = bfd_get_16 (abfd, address);
3339
0
      entry->name_id.name.string = address + 2;
3340
0
    }
3341
0
  else
3342
0
    entry->name_id.id = val;
3343
3344
0
  val = bfd_get_32 (abfd, data + 4);
3345
3346
0
  if (HighBitSet (val))
3347
0
    {
3348
0
      entry->is_dir = true;
3349
0
      entry->value.directory = bfd_malloc (sizeof (*entry->value.directory));
3350
0
      if (entry->value.directory == NULL)
3351
0
  return dataend;
3352
3353
0
      return rsrc_parse_directory (abfd, entry->value.directory,
3354
0
           datastart,
3355
0
           datastart + WithoutHighBit (val),
3356
0
           dataend, rva_bias, entry);
3357
0
    }
3358
3359
0
  entry->is_dir = false;
3360
0
  entry->value.leaf = bfd_malloc (sizeof (*entry->value.leaf));
3361
0
  if (entry->value.leaf == NULL)
3362
0
    return dataend;
3363
3364
0
  data = datastart + val;
3365
0
  if (data < datastart || data + 12 > dataend)
3366
0
    return dataend;
3367
3368
0
  addr = bfd_get_32 (abfd, data);
3369
0
  size = entry->value.leaf->size = bfd_get_32 (abfd, data + 4);
3370
0
  entry->value.leaf->codepage = bfd_get_32 (abfd, data + 8);
3371
  /* FIXME: We assume that the reserved field (data + 12) is OK.  */
3372
3373
0
  if (size > dataend - datastart - (addr - rva_bias))
3374
0
    return dataend;
3375
0
  entry->value.leaf->data = bfd_malloc (size);
3376
0
  if (entry->value.leaf->data == NULL)
3377
0
    return dataend;
3378
3379
0
  memcpy (entry->value.leaf->data, datastart + addr - rva_bias, size);
3380
0
  return datastart + (addr - rva_bias) + size;
3381
0
}
3382
3383
static bfd_byte *
3384
rsrc_parse_entries (bfd *abfd,
3385
        rsrc_dir_chain *chain,
3386
        bool is_name,
3387
        bfd_byte *highest_data,
3388
        bfd_byte *datastart,
3389
        bfd_byte *data,
3390
        bfd_byte *dataend,
3391
        bfd_vma rva_bias,
3392
        rsrc_directory *parent)
3393
0
{
3394
0
  unsigned int i;
3395
0
  rsrc_entry * entry;
3396
3397
0
  if (chain->num_entries == 0)
3398
0
    {
3399
0
      chain->first_entry = chain->last_entry = NULL;
3400
0
      return highest_data;
3401
0
    }
3402
3403
0
  entry = bfd_malloc (sizeof (*entry));
3404
0
  if (entry == NULL)
3405
0
    return dataend;
3406
3407
0
  chain->first_entry = entry;
3408
3409
0
  for (i = chain->num_entries; i--;)
3410
0
    {
3411
0
      bfd_byte * entry_end;
3412
3413
0
      entry_end = rsrc_parse_entry (abfd, is_name, entry, datastart,
3414
0
            data, dataend, rva_bias, parent);
3415
0
      data += 8;
3416
0
      highest_data = max (entry_end, highest_data);
3417
0
      if (entry_end > dataend)
3418
0
  return dataend;
3419
3420
0
      if (i)
3421
0
  {
3422
0
    entry->next_entry = bfd_malloc (sizeof (*entry));
3423
0
    entry = entry->next_entry;
3424
0
    if (entry == NULL)
3425
0
      return dataend;
3426
0
  }
3427
0
      else
3428
0
  entry->next_entry = NULL;
3429
0
    }
3430
3431
0
  chain->last_entry = entry;
3432
3433
0
  return highest_data;
3434
0
}
3435
3436
static bfd_byte *
3437
rsrc_parse_directory (bfd *        abfd,
3438
          rsrc_directory * table,
3439
          bfd_byte *       datastart,
3440
          bfd_byte *       data,
3441
          bfd_byte *       dataend,
3442
          bfd_vma        rva_bias,
3443
          rsrc_entry *     entry)
3444
0
{
3445
0
  bfd_byte * highest_data = data;
3446
3447
0
  if (table == NULL)
3448
0
    return dataend;
3449
3450
0
  table->characteristics = bfd_get_32 (abfd, data);
3451
0
  table->time = bfd_get_32 (abfd, data + 4);
3452
0
  table->major = bfd_get_16 (abfd, data + 8);
3453
0
  table->minor = bfd_get_16 (abfd, data + 10);
3454
0
  table->names.num_entries = bfd_get_16 (abfd, data + 12);
3455
0
  table->ids.num_entries = bfd_get_16 (abfd, data + 14);
3456
0
  table->entry = entry;
3457
3458
0
  data += 16;
3459
3460
0
  highest_data = rsrc_parse_entries (abfd, & table->names, true, data,
3461
0
             datastart, data, dataend, rva_bias, table);
3462
0
  data += table->names.num_entries * 8;
3463
3464
0
  highest_data = rsrc_parse_entries (abfd, & table->ids, false, highest_data,
3465
0
             datastart, data, dataend, rva_bias, table);
3466
0
  data += table->ids.num_entries * 8;
3467
3468
0
  return max (highest_data, data);
3469
0
}
3470
3471
typedef struct rsrc_write_data
3472
{
3473
  bfd *      abfd;
3474
  bfd_byte * datastart;
3475
  bfd_byte * next_table;
3476
  bfd_byte * next_leaf;
3477
  bfd_byte * next_string;
3478
  bfd_byte * next_data;
3479
  bfd_vma    rva_bias;
3480
} rsrc_write_data;
3481
3482
static void
3483
rsrc_write_string (rsrc_write_data * data,
3484
       rsrc_string *     string)
3485
0
{
3486
0
  bfd_put_16 (data->abfd, string->len, data->next_string);
3487
0
  memcpy (data->next_string + 2, string->string, string->len * 2);
3488
0
  data->next_string += (string->len + 1) * 2;
3489
0
}
3490
3491
static inline unsigned int
3492
rsrc_compute_rva (rsrc_write_data * data,
3493
      bfd_byte *      addr)
3494
0
{
3495
0
  return (addr - data->datastart) + data->rva_bias;
3496
0
}
3497
3498
static void
3499
rsrc_write_leaf (rsrc_write_data * data,
3500
     rsrc_leaf *     leaf)
3501
0
{
3502
0
  bfd_put_32 (data->abfd, rsrc_compute_rva (data, data->next_data),
3503
0
        data->next_leaf);
3504
0
  bfd_put_32 (data->abfd, leaf->size,     data->next_leaf + 4);
3505
0
  bfd_put_32 (data->abfd, leaf->codepage, data->next_leaf + 8);
3506
0
  bfd_put_32 (data->abfd, 0 /*reserved*/, data->next_leaf + 12);
3507
0
  data->next_leaf += 16;
3508
3509
0
  memcpy (data->next_data, leaf->data, leaf->size);
3510
  /* An undocumented feature of Windows resources is that each unit
3511
     of raw data is 8-byte aligned...  */
3512
0
  data->next_data += ((leaf->size + 7) & ~7);
3513
0
}
3514
3515
static void rsrc_write_directory (rsrc_write_data *, rsrc_directory *);
3516
3517
static void
3518
rsrc_write_entry (rsrc_write_data *  data,
3519
      bfd_byte *       where,
3520
      rsrc_entry *       entry)
3521
0
{
3522
0
  if (entry->is_name)
3523
0
    {
3524
0
      bfd_put_32 (data->abfd,
3525
0
      SetHighBit (data->next_string - data->datastart),
3526
0
      where);
3527
0
      rsrc_write_string (data, & entry->name_id.name);
3528
0
    }
3529
0
  else
3530
0
    bfd_put_32 (data->abfd, entry->name_id.id, where);
3531
3532
0
  if (entry->is_dir)
3533
0
    {
3534
0
      bfd_put_32 (data->abfd,
3535
0
      SetHighBit (data->next_table - data->datastart),
3536
0
      where + 4);
3537
0
      rsrc_write_directory (data, entry->value.directory);
3538
0
    }
3539
0
  else
3540
0
    {
3541
0
      bfd_put_32 (data->abfd, data->next_leaf - data->datastart, where + 4);
3542
0
      rsrc_write_leaf (data, entry->value.leaf);
3543
0
    }
3544
0
}
3545
3546
static void
3547
rsrc_compute_region_sizes (rsrc_directory * dir)
3548
0
{
3549
0
  struct rsrc_entry * entry;
3550
3551
0
  if (dir == NULL)
3552
0
    return;
3553
3554
0
  sizeof_tables_and_entries += 16;
3555
3556
0
  for (entry = dir->names.first_entry; entry != NULL; entry = entry->next_entry)
3557
0
    {
3558
0
      sizeof_tables_and_entries += 8;
3559
3560
0
      sizeof_strings += (entry->name_id.name.len + 1) * 2;
3561
3562
0
      if (entry->is_dir)
3563
0
  rsrc_compute_region_sizes (entry->value.directory);
3564
0
      else
3565
0
  sizeof_leaves += 16;
3566
0
    }
3567
3568
0
  for (entry = dir->ids.first_entry; entry != NULL; entry = entry->next_entry)
3569
0
    {
3570
0
      sizeof_tables_and_entries += 8;
3571
3572
0
      if (entry->is_dir)
3573
0
  rsrc_compute_region_sizes (entry->value.directory);
3574
0
      else
3575
0
  sizeof_leaves += 16;
3576
0
    }
3577
0
}
3578
3579
static void
3580
rsrc_write_directory (rsrc_write_data * data,
3581
          rsrc_directory *  dir)
3582
0
{
3583
0
  rsrc_entry * entry;
3584
0
  unsigned int i;
3585
0
  bfd_byte * next_entry;
3586
0
  bfd_byte * nt;
3587
3588
0
  bfd_put_32 (data->abfd, dir->characteristics, data->next_table);
3589
0
  bfd_put_32 (data->abfd, 0 /*dir->time*/, data->next_table + 4);
3590
0
  bfd_put_16 (data->abfd, dir->major, data->next_table + 8);
3591
0
  bfd_put_16 (data->abfd, dir->minor, data->next_table + 10);
3592
0
  bfd_put_16 (data->abfd, dir->names.num_entries, data->next_table + 12);
3593
0
  bfd_put_16 (data->abfd, dir->ids.num_entries, data->next_table + 14);
3594
3595
  /* Compute where the entries and the next table will be placed.  */
3596
0
  next_entry = data->next_table + 16;
3597
0
  data->next_table = next_entry + (dir->names.num_entries * 8)
3598
0
    + (dir->ids.num_entries * 8);
3599
0
  nt = data->next_table;
3600
3601
  /* Write the entries.  */
3602
0
  for (i = dir->names.num_entries, entry = dir->names.first_entry;
3603
0
       i > 0 && entry != NULL;
3604
0
       i--, entry = entry->next_entry)
3605
0
    {
3606
0
      BFD_ASSERT (entry->is_name);
3607
0
      rsrc_write_entry (data, next_entry, entry);
3608
0
      next_entry += 8;
3609
0
    }
3610
0
  BFD_ASSERT (i == 0);
3611
0
  BFD_ASSERT (entry == NULL);
3612
3613
0
  for (i = dir->ids.num_entries, entry = dir->ids.first_entry;
3614
0
       i > 0 && entry != NULL;
3615
0
       i--, entry = entry->next_entry)
3616
0
    {
3617
0
      BFD_ASSERT (! entry->is_name);
3618
0
      rsrc_write_entry (data, next_entry, entry);
3619
0
      next_entry += 8;
3620
0
    }
3621
0
  BFD_ASSERT (i == 0);
3622
0
  BFD_ASSERT (entry == NULL);
3623
0
  BFD_ASSERT (nt == next_entry);
3624
0
}
3625
3626
#if ! defined __CYGWIN__ && ! defined __MINGW32__
3627
/* Return the length (number of units) of the first character in S,
3628
   putting its 'ucs4_t' representation in *PUC.  */
3629
3630
static unsigned int
3631
u16_mbtouc (wint_t * puc, const unsigned short * s, unsigned int n)
3632
0
{
3633
0
  unsigned short c = * s;
3634
3635
0
  if (c < 0xd800 || c >= 0xe000)
3636
0
    {
3637
0
      *puc = c;
3638
0
      return 1;
3639
0
    }
3640
3641
0
  if (c < 0xdc00)
3642
0
    {
3643
0
      if (n >= 2)
3644
0
  {
3645
0
    if (s[1] >= 0xdc00 && s[1] < 0xe000)
3646
0
      {
3647
0
        *puc = 0x10000 + ((c - 0xd800) << 10) + (s[1] - 0xdc00);
3648
0
        return 2;
3649
0
      }
3650
0
  }
3651
0
      else
3652
0
  {
3653
    /* Incomplete multibyte character.  */
3654
0
    *puc = 0xfffd;
3655
0
    return n;
3656
0
  }
3657
0
    }
3658
3659
  /* Invalid multibyte character.  */
3660
0
  *puc = 0xfffd;
3661
0
  return 1;
3662
0
}
3663
#endif /* not Cygwin/Mingw */
3664
3665
/* Perform a comparison of two entries.  */
3666
static signed int
3667
rsrc_cmp (bool is_name, rsrc_entry * a, rsrc_entry * b)
3668
0
{
3669
0
  signed int    res;
3670
0
  bfd_byte *    astring;
3671
0
  unsigned int  alen;
3672
0
  bfd_byte *    bstring;
3673
0
  unsigned int  blen;
3674
3675
0
  if (! is_name)
3676
0
    return a->name_id.id - b->name_id.id;
3677
3678
  /* We have to perform a case insenstive, unicode string comparison...  */
3679
0
  astring = a->name_id.name.string;
3680
0
  alen    = a->name_id.name.len;
3681
0
  bstring = b->name_id.name.string;
3682
0
  blen    = b->name_id.name.len;
3683
3684
#if defined  __CYGWIN__ || defined __MINGW32__
3685
  /* Under Windows hosts (both Cygwin and Mingw types),
3686
     unicode == UTF-16 == wchar_t.  The case insensitive string comparison
3687
     function however goes by different names in the two environments...  */
3688
3689
#undef rscpcmp
3690
#ifdef __CYGWIN__
3691
#define rscpcmp wcsncasecmp
3692
#endif
3693
#ifdef __MINGW32__
3694
#define rscpcmp wcsnicmp
3695
#endif
3696
3697
  res = rscpcmp ((const wchar_t *) astring, (const wchar_t *) bstring,
3698
     min (alen, blen));
3699
3700
#else
3701
0
  {
3702
0
    unsigned int  i;
3703
3704
0
    res = 0;
3705
0
    for (i = min (alen, blen); i--; astring += 2, bstring += 2)
3706
0
      {
3707
0
  wint_t awc;
3708
0
  wint_t bwc;
3709
3710
  /* Convert UTF-16 unicode characters into wchar_t characters
3711
     so that we can then perform a case insensitive comparison.  */
3712
0
  unsigned int Alen = u16_mbtouc (& awc, (const unsigned short *) astring, 2);
3713
0
  unsigned int Blen = u16_mbtouc (& bwc, (const unsigned short *) bstring, 2);
3714
3715
0
  if (Alen != Blen)
3716
0
    return Alen - Blen;
3717
3718
0
  awc = towlower (awc);
3719
0
  bwc = towlower (bwc);
3720
3721
0
  res = awc - bwc;
3722
0
  if (res)
3723
0
    break;
3724
0
      }
3725
0
  }
3726
0
#endif
3727
3728
0
  if (res == 0)
3729
0
    res = alen - blen;
3730
3731
0
  return res;
3732
0
}
3733
3734
static void
3735
rsrc_print_name (char * buffer, rsrc_string string)
3736
0
{
3737
0
  unsigned int  i;
3738
0
  bfd_byte *    name = string.string;
3739
3740
0
  for (i = string.len; i--; name += 2)
3741
0
    sprintf (buffer + strlen (buffer), "%.1s", name);
3742
0
}
3743
3744
static const char *
3745
rsrc_resource_name (rsrc_entry *entry, rsrc_directory *dir, char *buffer)
3746
0
{
3747
0
  bool is_string = false;
3748
3749
0
  buffer[0] = 0;
3750
3751
0
  if (dir != NULL && dir->entry != NULL && dir->entry->parent != NULL
3752
0
      && dir->entry->parent->entry != NULL)
3753
0
    {
3754
0
      strcpy (buffer, "type: ");
3755
0
      if (dir->entry->parent->entry->is_name)
3756
0
  rsrc_print_name (buffer + strlen (buffer),
3757
0
       dir->entry->parent->entry->name_id.name);
3758
0
      else
3759
0
  {
3760
0
    unsigned int id = dir->entry->parent->entry->name_id.id;
3761
3762
0
    sprintf (buffer + strlen (buffer), "%x", id);
3763
0
    switch (id)
3764
0
      {
3765
0
      case 1: strcat (buffer, " (CURSOR)"); break;
3766
0
      case 2: strcat (buffer, " (BITMAP)"); break;
3767
0
      case 3: strcat (buffer, " (ICON)"); break;
3768
0
      case 4: strcat (buffer, " (MENU)"); break;
3769
0
      case 5: strcat (buffer, " (DIALOG)"); break;
3770
0
      case 6: strcat (buffer, " (STRING)"); is_string = true; break;
3771
0
      case 7: strcat (buffer, " (FONTDIR)"); break;
3772
0
      case 8: strcat (buffer, " (FONT)"); break;
3773
0
      case 9: strcat (buffer, " (ACCELERATOR)"); break;
3774
0
      case 10: strcat (buffer, " (RCDATA)"); break;
3775
0
      case 11: strcat (buffer, " (MESSAGETABLE)"); break;
3776
0
      case 12: strcat (buffer, " (GROUP_CURSOR)"); break;
3777
0
      case 14: strcat (buffer, " (GROUP_ICON)"); break;
3778
0
      case 16: strcat (buffer, " (VERSION)"); break;
3779
0
      case 17: strcat (buffer, " (DLGINCLUDE)"); break;
3780
0
      case 19: strcat (buffer, " (PLUGPLAY)"); break;
3781
0
      case 20: strcat (buffer, " (VXD)"); break;
3782
0
      case 21: strcat (buffer, " (ANICURSOR)"); break;
3783
0
      case 22: strcat (buffer, " (ANIICON)"); break;
3784
0
      case 23: strcat (buffer, " (HTML)"); break;
3785
0
      case 24: strcat (buffer, " (MANIFEST)"); break;
3786
0
      case 240: strcat (buffer, " (DLGINIT)"); break;
3787
0
      case 241: strcat (buffer, " (TOOLBAR)"); break;
3788
0
      }
3789
0
  }
3790
0
    }
3791
3792
0
  if (dir != NULL && dir->entry != NULL)
3793
0
    {
3794
0
      strcat (buffer, " name: ");
3795
0
      if (dir->entry->is_name)
3796
0
  rsrc_print_name (buffer + strlen (buffer), dir->entry->name_id.name);
3797
0
      else
3798
0
  {
3799
0
    unsigned int id = dir->entry->name_id.id;
3800
3801
0
    sprintf (buffer + strlen (buffer), "%x", id);
3802
3803
0
    if (is_string)
3804
0
      sprintf (buffer + strlen (buffer), " (resource id range: %d - %d)",
3805
0
         (id - 1) << 4, (id << 4) - 1);
3806
0
  }
3807
0
    }
3808
3809
0
  if (entry != NULL)
3810
0
    {
3811
0
      strcat (buffer, " lang: ");
3812
3813
0
      if (entry->is_name)
3814
0
  rsrc_print_name (buffer + strlen (buffer), entry->name_id.name);
3815
0
      else
3816
0
  sprintf (buffer + strlen (buffer), "%x", entry->name_id.id);
3817
0
    }
3818
3819
0
  return buffer;
3820
0
}
3821
3822
/* *sigh* Windows resource strings are special.  Only the top 28-bits of
3823
   their ID is stored in the NAME entry.  The bottom four bits are used as
3824
   an index into unicode string table that makes up the data of the leaf.
3825
   So identical type-name-lang string resources may not actually be
3826
   identical at all.
3827
3828
   This function is called when we have detected two string resources with
3829
   match top-28-bit IDs.  We have to scan the string tables inside the leaves
3830
   and discover if there are any real collisions.  If there are then we report
3831
   them and return FALSE.  Otherwise we copy any strings from B into A and
3832
   then return TRUE.  */
3833
3834
static bool
3835
rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
3836
         rsrc_entry * b ATTRIBUTE_UNUSED)
3837
0
{
3838
0
  unsigned int copy_needed = 0;
3839
0
  unsigned int i;
3840
0
  bfd_byte * astring;
3841
0
  bfd_byte * bstring;
3842
0
  bfd_byte * new_data;
3843
0
  bfd_byte * nstring;
3844
3845
  /* Step one: Find out what we have to do.  */
3846
0
  BFD_ASSERT (! a->is_dir);
3847
0
  astring = a->value.leaf->data;
3848
3849
0
  BFD_ASSERT (! b->is_dir);
3850
0
  bstring = b->value.leaf->data;
3851
3852
0
  for (i = 0; i < 16; i++)
3853
0
    {
3854
0
      unsigned int alen = astring[0] + (astring[1] << 8);
3855
0
      unsigned int blen = bstring[0] + (bstring[1] << 8);
3856
3857
0
      if (alen == 0)
3858
0
  {
3859
0
    copy_needed += blen * 2;
3860
0
  }
3861
0
      else if (blen == 0)
3862
0
  ;
3863
0
      else if (alen != blen)
3864
  /* FIXME: Should we continue the loop in order to report other duplicates ?  */
3865
0
  break;
3866
      /* alen == blen != 0.  We might have two identical strings.  If so we
3867
   can ignore the second one.  There is no need for wchar_t vs UTF-16
3868
   theatrics here - we are only interested in (case sensitive) equality.  */
3869
0
      else if (memcmp (astring + 2, bstring + 2, alen * 2) != 0)
3870
0
  break;
3871
3872
0
      astring += (alen + 1) * 2;
3873
0
      bstring += (blen + 1) * 2;
3874
0
    }
3875
3876
0
  if (i != 16)
3877
0
    {
3878
0
      if (a->parent != NULL
3879
0
    && a->parent->entry != NULL
3880
0
    && !a->parent->entry->is_name)
3881
0
  _bfd_error_handler (_(".rsrc merge failure: duplicate string resource: %d"),
3882
0
          ((a->parent->entry->name_id.id - 1) << 4) + i);
3883
0
      return false;
3884
0
    }
3885
3886
0
  if (copy_needed == 0)
3887
0
    return true;
3888
3889
  /* If we reach here then A and B must both have non-colliding strings.
3890
     (We never get string resources with fully empty string tables).
3891
     We need to allocate an extra COPY_NEEDED bytes in A and then bring
3892
     in B's strings.  */
3893
0
  new_data = bfd_malloc (a->value.leaf->size + copy_needed);
3894
0
  if (new_data == NULL)
3895
0
    return false;
3896
3897
0
  nstring = new_data;
3898
0
  astring = a->value.leaf->data;
3899
0
  bstring = b->value.leaf->data;
3900
3901
0
  for (i = 0; i < 16; i++)
3902
0
    {
3903
0
      unsigned int alen = astring[0] + (astring[1] << 8);
3904
0
      unsigned int blen = bstring[0] + (bstring[1] << 8);
3905
3906
0
      if (alen != 0)
3907
0
  {
3908
0
    memcpy (nstring, astring, (alen + 1) * 2);
3909
0
    nstring += (alen + 1) * 2;
3910
0
  }
3911
0
      else if (blen != 0)
3912
0
  {
3913
0
    memcpy (nstring, bstring, (blen + 1) * 2);
3914
0
    nstring += (blen + 1) * 2;
3915
0
  }
3916
0
      else
3917
0
  {
3918
0
    * nstring++ = 0;
3919
0
    * nstring++ = 0;
3920
0
  }
3921
3922
0
      astring += (alen + 1) * 2;
3923
0
      bstring += (blen + 1) * 2;
3924
0
    }
3925
3926
0
  BFD_ASSERT (nstring - new_data == (signed) (a->value.leaf->size + copy_needed));
3927
3928
0
  free (a->value.leaf->data);
3929
0
  a->value.leaf->data = new_data;
3930
0
  a->value.leaf->size += copy_needed;
3931
3932
0
  return true;
3933
0
}
3934
3935
static void rsrc_merge (rsrc_entry *, rsrc_entry *);
3936
3937
/* Sort the entries in given part of the directory.
3938
   We use an old fashioned bubble sort because we are dealing
3939
   with lists and we want to handle matches specially.  */
3940
3941
static void
3942
rsrc_sort_entries (rsrc_dir_chain *chain,
3943
       bool is_name,
3944
       rsrc_directory *dir)
3945
0
{
3946
0
  rsrc_entry * entry;
3947
0
  rsrc_entry * next;
3948
0
  rsrc_entry ** points_to_entry;
3949
0
  bool swapped;
3950
3951
0
  if (chain->num_entries < 2)
3952
0
    return;
3953
3954
0
  do
3955
0
    {
3956
0
      swapped = false;
3957
0
      points_to_entry = & chain->first_entry;
3958
0
      entry = * points_to_entry;
3959
0
      next  = entry->next_entry;
3960
3961
0
      do
3962
0
  {
3963
0
    signed int cmp = rsrc_cmp (is_name, entry, next);
3964
3965
0
    if (cmp > 0)
3966
0
      {
3967
0
        entry->next_entry = next->next_entry;
3968
0
        next->next_entry = entry;
3969
0
        * points_to_entry = next;
3970
0
        points_to_entry = & next->next_entry;
3971
0
        next = entry->next_entry;
3972
0
        swapped = true;
3973
0
      }
3974
0
    else if (cmp == 0)
3975
0
      {
3976
0
        if (entry->is_dir && next->is_dir)
3977
0
    {
3978
      /* When we encounter identical directory entries we have to
3979
         merge them together.  The exception to this rule is for
3980
         resource manifests - there can only be one of these,
3981
         even if they differ in language.  Zero-language manifests
3982
         are assumed to be default manifests (provided by the
3983
         Cygwin/MinGW build system) and these can be silently dropped,
3984
         unless that would reduce the number of manifests to zero.
3985
         There should only ever be one non-zero lang manifest -
3986
         if there are more it is an error.  A non-zero lang
3987
         manifest takes precedence over a default manifest.  */
3988
0
      if (!entry->is_name
3989
0
          && entry->name_id.id == 1
3990
0
          && dir != NULL
3991
0
          && dir->entry != NULL
3992
0
          && !dir->entry->is_name
3993
0
          && dir->entry->name_id.id == 0x18)
3994
0
        {
3995
0
          if (next->value.directory->names.num_entries == 0
3996
0
        && next->value.directory->ids.num_entries == 1
3997
0
        && !next->value.directory->ids.first_entry->is_name
3998
0
        && next->value.directory->ids.first_entry->name_id.id == 0)
3999
      /* Fall through so that NEXT is dropped.  */
4000
0
      ;
4001
0
          else if (entry->value.directory->names.num_entries == 0
4002
0
             && entry->value.directory->ids.num_entries == 1
4003
0
             && !entry->value.directory->ids.first_entry->is_name
4004
0
             && entry->value.directory->ids.first_entry->name_id.id == 0)
4005
0
      {
4006
        /* Swap ENTRY and NEXT.  Then fall through so that the old ENTRY is dropped.  */
4007
0
        entry->next_entry = next->next_entry;
4008
0
        next->next_entry = entry;
4009
0
        * points_to_entry = next;
4010
0
        points_to_entry = & next->next_entry;
4011
0
        next = entry->next_entry;
4012
0
        swapped = true;
4013
0
      }
4014
0
          else
4015
0
      {
4016
0
        _bfd_error_handler (_(".rsrc merge failure: multiple non-default manifests"));
4017
0
        bfd_set_error (bfd_error_file_truncated);
4018
0
        return;
4019
0
      }
4020
4021
          /* Unhook NEXT from the chain.  */
4022
          /* FIXME: memory loss here.  */
4023
0
          entry->next_entry = next->next_entry;
4024
0
          chain->num_entries --;
4025
0
          if (chain->num_entries < 2)
4026
0
      return;
4027
0
          next = next->next_entry;
4028
0
        }
4029
0
      else
4030
0
        rsrc_merge (entry, next);
4031
0
    }
4032
0
        else if (entry->is_dir != next->is_dir)
4033
0
    {
4034
0
      _bfd_error_handler (_(".rsrc merge failure: a directory matches a leaf"));
4035
0
      bfd_set_error (bfd_error_file_truncated);
4036
0
      return;
4037
0
    }
4038
0
        else
4039
0
    {
4040
      /* Otherwise with identical leaves we issue an error
4041
         message - because there should never be duplicates.
4042
         The exception is Type 18/Name 1/Lang 0 which is the
4043
         defaul manifest - this can just be dropped.  */
4044
0
      if (!entry->is_name
4045
0
          && entry->name_id.id == 0
4046
0
          && dir != NULL
4047
0
          && dir->entry != NULL
4048
0
          && !dir->entry->is_name
4049
0
          && dir->entry->name_id.id == 1
4050
0
          && dir->entry->parent != NULL
4051
0
          && dir->entry->parent->entry != NULL
4052
0
          && !dir->entry->parent->entry->is_name
4053
0
          && dir->entry->parent->entry->name_id.id == 0x18 /* RT_MANIFEST */)
4054
0
        ;
4055
0
      else if (dir != NULL
4056
0
         && dir->entry != NULL
4057
0
         && dir->entry->parent != NULL
4058
0
         && dir->entry->parent->entry != NULL
4059
0
         && !dir->entry->parent->entry->is_name
4060
0
         && dir->entry->parent->entry->name_id.id == 0x6 /* RT_STRING */)
4061
0
        {
4062
          /* Strings need special handling.  */
4063
0
          if (! rsrc_merge_string_entries (entry, next))
4064
0
      {
4065
        /* _bfd_error_handler should have been called inside merge_strings.  */
4066
0
        bfd_set_error (bfd_error_file_truncated);
4067
0
        return;
4068
0
      }
4069
0
        }
4070
0
      else
4071
0
        {
4072
0
          if (dir == NULL
4073
0
        || dir->entry == NULL
4074
0
        || dir->entry->parent == NULL
4075
0
        || dir->entry->parent->entry == NULL)
4076
0
      _bfd_error_handler (_(".rsrc merge failure: duplicate leaf"));
4077
0
          else
4078
0
      {
4079
0
        char buff[256];
4080
4081
0
        _bfd_error_handler (_(".rsrc merge failure: duplicate leaf: %s"),
4082
0
                rsrc_resource_name (entry, dir, buff));
4083
0
      }
4084
0
          bfd_set_error (bfd_error_file_truncated);
4085
0
          return;
4086
0
        }
4087
0
    }
4088
4089
        /* Unhook NEXT from the chain.  */
4090
0
        entry->next_entry = next->next_entry;
4091
0
        chain->num_entries --;
4092
0
        if (chain->num_entries < 2)
4093
0
    return;
4094
0
        next = next->next_entry;
4095
0
      }
4096
0
    else
4097
0
      {
4098
0
        points_to_entry = & entry->next_entry;
4099
0
        entry = next;
4100
0
        next = next->next_entry;
4101
0
      }
4102
0
  }
4103
0
      while (next);
4104
4105
0
      chain->last_entry = entry;
4106
0
    }
4107
0
  while (swapped);
4108
0
}
4109
4110
/* Attach B's chain onto A.  */
4111
static void
4112
rsrc_attach_chain (rsrc_dir_chain * achain, rsrc_dir_chain * bchain)
4113
0
{
4114
0
  if (bchain->num_entries == 0)
4115
0
    return;
4116
4117
0
  achain->num_entries += bchain->num_entries;
4118
4119
0
  if (achain->first_entry == NULL)
4120
0
    {
4121
0
      achain->first_entry = bchain->first_entry;
4122
0
      achain->last_entry  = bchain->last_entry;
4123
0
    }
4124
0
  else
4125
0
    {
4126
0
      achain->last_entry->next_entry = bchain->first_entry;
4127
0
      achain->last_entry = bchain->last_entry;
4128
0
    }
4129
4130
0
  bchain->num_entries = 0;
4131
0
  bchain->first_entry = bchain->last_entry = NULL;
4132
0
}
4133
4134
static void
4135
rsrc_merge (struct rsrc_entry * a, struct rsrc_entry * b)
4136
0
{
4137
0
  rsrc_directory * adir;
4138
0
  rsrc_directory * bdir;
4139
4140
0
  BFD_ASSERT (a->is_dir);
4141
0
  BFD_ASSERT (b->is_dir);
4142
4143
0
  adir = a->value.directory;
4144
0
  bdir = b->value.directory;
4145
4146
0
  if (adir->characteristics != bdir->characteristics)
4147
0
    {
4148
0
      _bfd_error_handler (_(".rsrc merge failure: dirs with differing characteristics"));
4149
0
      bfd_set_error (bfd_error_file_truncated);
4150
0
      return;
4151
0
    }
4152
4153
0
  if (adir->major != bdir->major || adir->minor != bdir->minor)
4154
0
    {
4155
0
      _bfd_error_handler (_(".rsrc merge failure: differing directory versions"));
4156
0
      bfd_set_error (bfd_error_file_truncated);
4157
0
      return;
4158
0
    }
4159
4160
  /* Attach B's name chain to A.  */
4161
0
  rsrc_attach_chain (& adir->names, & bdir->names);
4162
4163
  /* Attach B's ID chain to A.  */
4164
0
  rsrc_attach_chain (& adir->ids, & bdir->ids);
4165
4166
  /* Now sort A's entries.  */
4167
0
  rsrc_sort_entries (& adir->names, true, adir);
4168
0
  rsrc_sort_entries (& adir->ids, false, adir);
4169
0
}
4170
4171
/* Check the .rsrc section.  If it contains multiple concatenated
4172
   resources then we must merge them properly.  Otherwise Windows
4173
   will ignore all but the first set.  */
4174
4175
static void
4176
rsrc_process_section (bfd * abfd,
4177
          struct coff_final_link_info * pfinfo)
4178
0
{
4179
0
  rsrc_directory    new_table;
4180
0
  bfd_size_type     size;
4181
0
  asection *      sec;
4182
0
  pe_data_type *    pe;
4183
0
  bfd_vma     rva_bias;
4184
0
  bfd_byte *      data;
4185
0
  bfd_byte *      datastart;
4186
0
  bfd_byte *      dataend;
4187
0
  bfd_byte *      new_data;
4188
0
  unsigned int      num_resource_sets;
4189
0
  rsrc_directory *  type_tables;
4190
0
  rsrc_write_data   write_data;
4191
0
  unsigned int      indx;
4192
0
  bfd *       input;
4193
0
  unsigned int      num_input_rsrc = 0;
4194
0
  unsigned int      max_num_input_rsrc = 4;
4195
0
  ptrdiff_t *     rsrc_sizes = NULL;
4196
4197
0
  new_table.names.num_entries = 0;
4198
0
  new_table.ids.num_entries = 0;
4199
4200
0
  sec = bfd_get_section_by_name (abfd, ".rsrc");
4201
0
  if (sec == NULL || (size = sec->rawsize) == 0)
4202
0
    return;
4203
4204
0
  pe = pe_data (abfd);
4205
0
  if (pe == NULL)
4206
0
    return;
4207
4208
0
  rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
4209
4210
0
  if (! bfd_malloc_and_get_section (abfd, sec, &datastart))
4211
0
    goto end;
4212
4213
  /* Step zero: Scan the input bfds looking for .rsrc sections and record
4214
     their lengths.  Note - we rely upon the fact that the linker script
4215
     does *not* sort the input .rsrc sections, so that the order in the
4216
     linkinfo list matches the order in the output .rsrc section.
4217
4218
     We need to know the lengths because each input .rsrc section has padding
4219
     at the end of a variable amount.  (It does not appear to be based upon
4220
     the section alignment or the file alignment).  We need to skip any
4221
     padding bytes when parsing the input .rsrc sections.  */
4222
0
  data = datastart;
4223
0
  rsrc_sizes = bfd_malloc (max_num_input_rsrc * sizeof (*rsrc_sizes));
4224
0
  if (rsrc_sizes == NULL)
4225
0
    goto end;
4226
4227
0
  for (input = pfinfo->info->input_bfds;
4228
0
       input != NULL;
4229
0
       input = input->link.next)
4230
0
    {
4231
0
      asection * rsrc_sec = bfd_get_section_by_name (input, ".rsrc");
4232
4233
      /* PR 18372 - skip discarded .rsrc sections.  */
4234
0
      if (rsrc_sec != NULL && !discarded_section (rsrc_sec))
4235
0
  {
4236
0
    if (num_input_rsrc == max_num_input_rsrc)
4237
0
      {
4238
0
        max_num_input_rsrc += 10;
4239
0
        rsrc_sizes = bfd_realloc (rsrc_sizes, max_num_input_rsrc
4240
0
          * sizeof (*rsrc_sizes));
4241
0
        if (rsrc_sizes == NULL)
4242
0
    goto end;
4243
0
      }
4244
4245
0
    BFD_ASSERT (rsrc_sec->size > 0);
4246
0
    rsrc_sizes [num_input_rsrc ++] = rsrc_sec->size;
4247
0
  }
4248
0
    }
4249
4250
0
  if (num_input_rsrc < 2)
4251
0
    goto end;
4252
4253
  /* Step one: Walk the section, computing the size of the tables,
4254
     leaves and data and decide if we need to do anything.  */
4255
0
  dataend = data + size;
4256
0
  num_resource_sets = 0;
4257
4258
0
  while (data < dataend)
4259
0
    {
4260
0
      bfd_byte * p = data;
4261
4262
0
      data = rsrc_count_directory (abfd, data, data, dataend, rva_bias);
4263
4264
0
      if (data > dataend)
4265
0
  {
4266
    /* Corrupted .rsrc section - cannot merge.  */
4267
0
    _bfd_error_handler (_("%pB: .rsrc merge failure: corrupt .rsrc section"),
4268
0
            abfd);
4269
0
    bfd_set_error (bfd_error_file_truncated);
4270
0
    goto end;
4271
0
  }
4272
4273
0
      if ((data - p) > rsrc_sizes [num_resource_sets])
4274
0
  {
4275
0
    _bfd_error_handler (_("%pB: .rsrc merge failure: unexpected .rsrc size"),
4276
0
            abfd);
4277
0
    bfd_set_error (bfd_error_file_truncated);
4278
0
    goto end;
4279
0
  }
4280
      /* FIXME: Should we add a check for "data - p" being much smaller
4281
   than rsrc_sizes[num_resource_sets] ?  */
4282
4283
0
      data = p + rsrc_sizes[num_resource_sets];
4284
0
      rva_bias += data - p;
4285
0
      ++ num_resource_sets;
4286
0
    }
4287
0
  BFD_ASSERT (num_resource_sets == num_input_rsrc);
4288
4289
  /* Step two: Walk the data again, building trees of the resources.  */
4290
0
  data = datastart;
4291
0
  rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
4292
4293
0
  type_tables = bfd_malloc (num_resource_sets * sizeof (*type_tables));
4294
0
  if (type_tables == NULL)
4295
0
    goto end;
4296
4297
0
  indx = 0;
4298
0
  while (data < dataend)
4299
0
    {
4300
0
      bfd_byte * p = data;
4301
4302
0
      (void) rsrc_parse_directory (abfd, type_tables + indx, data, data,
4303
0
           dataend, rva_bias, NULL);
4304
0
      data = p + rsrc_sizes[indx];
4305
0
      rva_bias += data - p;
4306
0
      ++ indx;
4307
0
    }
4308
0
  BFD_ASSERT (indx == num_resource_sets);
4309
4310
  /* Step three: Merge the top level tables (there can be only one).
4311
4312
     We must ensure that the merged entries are in ascending order.
4313
4314
     We also thread the top level table entries from the old tree onto
4315
     the new table, so that they can be pulled off later.  */
4316
4317
  /* FIXME: Should we verify that all type tables are the same ?  */
4318
0
  new_table.characteristics = type_tables[0].characteristics;
4319
0
  new_table.time      = type_tables[0].time;
4320
0
  new_table.major     = type_tables[0].major;
4321
0
  new_table.minor     = type_tables[0].minor;
4322
4323
  /* Chain the NAME entries onto the table.  */
4324
0
  new_table.names.first_entry = NULL;
4325
0
  new_table.names.last_entry = NULL;
4326
4327
0
  for (indx = 0; indx < num_resource_sets; indx++)
4328
0
    rsrc_attach_chain (& new_table.names, & type_tables[indx].names);
4329
4330
0
  rsrc_sort_entries (& new_table.names, true, & new_table);
4331
4332
  /* Chain the ID entries onto the table.  */
4333
0
  new_table.ids.first_entry = NULL;
4334
0
  new_table.ids.last_entry = NULL;
4335
4336
0
  for (indx = 0; indx < num_resource_sets; indx++)
4337
0
    rsrc_attach_chain (& new_table.ids, & type_tables[indx].ids);
4338
4339
0
  rsrc_sort_entries (& new_table.ids, false, & new_table);
4340
4341
  /* Step four: Create new contents for the .rsrc section.  */
4342
  /* Step four point one: Compute the size of each region of the .rsrc section.
4343
     We do this now, rather than earlier, as the merging above may have dropped
4344
     some entries.  */
4345
0
  sizeof_leaves = sizeof_strings = sizeof_tables_and_entries = 0;
4346
0
  rsrc_compute_region_sizes (& new_table);
4347
  /* We increment sizeof_strings to make sure that resource data
4348
     starts on an 8-byte boundary.  FIXME: Is this correct ?  */
4349
0
  sizeof_strings = (sizeof_strings + 7) & ~ 7;
4350
4351
0
  new_data = bfd_zalloc (abfd, size);
4352
0
  if (new_data == NULL)
4353
0
    goto end;
4354
4355
0
  write_data.abfd  = abfd;
4356
0
  write_data.datastart   = new_data;
4357
0
  write_data.next_table  = new_data;
4358
0
  write_data.next_leaf   = new_data + sizeof_tables_and_entries;
4359
0
  write_data.next_string = write_data.next_leaf + sizeof_leaves;
4360
0
  write_data.next_data   = write_data.next_string + sizeof_strings;
4361
0
  write_data.rva_bias  = sec->vma - pe->pe_opthdr.ImageBase;
4362
4363
0
  rsrc_write_directory (& write_data, & new_table);
4364
4365
  /* Step five: Replace the old contents with the new.
4366
     We don't recompute the size as it's too late here to shrink section.
4367
     See PR ld/20193 for more details.  */
4368
0
  bfd_set_section_contents (pfinfo->output_bfd, sec, new_data, 0, size);
4369
0
  sec->size = sec->rawsize = size;
4370
4371
0
 end:
4372
  /* Step six: Free all the memory that we have used.  */
4373
  /* FIXME: Free the resource tree, if we have one.  */
4374
0
  free (datastart);
4375
0
  free (rsrc_sizes);
4376
0
}
4377
4378
/* Handle the .idata section and other things that need symbol table
4379
   access.  */
4380
4381
bool
4382
_bfd_peAArch64i_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
4383
0
{
4384
0
  struct coff_link_hash_entry *h1;
4385
0
  struct bfd_link_info *info = pfinfo->info;
4386
0
  bool result = true;
4387
4388
  /* There are a few fields that need to be filled in now while we
4389
     have symbol table access.
4390
4391
     The .idata subsections aren't directly available as sections, but
4392
     they are in the symbol table, so get them from there.  */
4393
4394
  /* The import directory.  This is the address of .idata$2, with size
4395
     of .idata$2 + .idata$3.  */
4396
0
  h1 = coff_link_hash_lookup (coff_hash_table (info),
4397
0
            ".idata$2", false, false, true);
4398
0
  if (h1 != NULL)
4399
0
    {
4400
      /* PR ld/2729: We cannot rely upon all the output sections having been
4401
   created properly, so check before referencing them.  Issue a warning
4402
   message for any sections tht could not be found.  */
4403
0
      if ((h1->root.type == bfd_link_hash_defined
4404
0
     || h1->root.type == bfd_link_hash_defweak)
4405
0
    && h1->root.u.def.section != NULL
4406
0
    && h1->root.u.def.section->output_section != NULL)
4407
0
  pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
4408
0
    (h1->root.u.def.value
4409
0
     + h1->root.u.def.section->output_section->vma
4410
0
     + h1->root.u.def.section->output_offset);
4411
0
      else
4412
0
  {
4413
0
    _bfd_error_handler
4414
0
      (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"),
4415
0
       abfd);
4416
0
    result = false;
4417
0
  }
4418
4419
0
      h1 = coff_link_hash_lookup (coff_hash_table (info),
4420
0
          ".idata$4", false, false, true);
4421
0
      if (h1 != NULL
4422
0
    && (h1->root.type == bfd_link_hash_defined
4423
0
     || h1->root.type == bfd_link_hash_defweak)
4424
0
    && h1->root.u.def.section != NULL
4425
0
    && h1->root.u.def.section->output_section != NULL)
4426
0
  pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
4427
0
    ((h1->root.u.def.value
4428
0
      + h1->root.u.def.section->output_section->vma
4429
0
      + h1->root.u.def.section->output_offset)
4430
0
     - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress);
4431
0
      else
4432
0
  {
4433
0
    _bfd_error_handler
4434
0
      (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"),
4435
0
       abfd);
4436
0
    result = false;
4437
0
  }
4438
4439
      /* The import address table.  This is the size/address of
4440
   .idata$5.  */
4441
0
      h1 = coff_link_hash_lookup (coff_hash_table (info),
4442
0
          ".idata$5", false, false, true);
4443
0
      if (h1 != NULL
4444
0
    && (h1->root.type == bfd_link_hash_defined
4445
0
     || h1->root.type == bfd_link_hash_defweak)
4446
0
    && h1->root.u.def.section != NULL
4447
0
    && h1->root.u.def.section->output_section != NULL)
4448
0
  pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
4449
0
    (h1->root.u.def.value
4450
0
     + h1->root.u.def.section->output_section->vma
4451
0
     + h1->root.u.def.section->output_offset);
4452
0
      else
4453
0
  {
4454
0
    _bfd_error_handler
4455
0
      (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"),
4456
0
       abfd);
4457
0
    result = false;
4458
0
  }
4459
4460
0
      h1 = coff_link_hash_lookup (coff_hash_table (info),
4461
0
          ".idata$6", false, false, true);
4462
0
      if (h1 != NULL
4463
0
    && (h1->root.type == bfd_link_hash_defined
4464
0
     || h1->root.type == bfd_link_hash_defweak)
4465
0
    && h1->root.u.def.section != NULL
4466
0
    && h1->root.u.def.section->output_section != NULL)
4467
0
  pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
4468
0
    ((h1->root.u.def.value
4469
0
      + h1->root.u.def.section->output_section->vma
4470
0
      + h1->root.u.def.section->output_offset)
4471
0
     - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress);
4472
0
      else
4473
0
  {
4474
0
    _bfd_error_handler
4475
0
      (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
4476
0
       abfd);
4477
0
    result = false;
4478
0
  }
4479
0
    }
4480
0
  else
4481
0
    {
4482
0
      h1 = coff_link_hash_lookup (coff_hash_table (info),
4483
0
          "__IAT_start__", false, false, true);
4484
0
      if (h1 != NULL
4485
0
    && (h1->root.type == bfd_link_hash_defined
4486
0
     || h1->root.type == bfd_link_hash_defweak)
4487
0
    && h1->root.u.def.section != NULL
4488
0
    && h1->root.u.def.section->output_section != NULL)
4489
0
  {
4490
0
    bfd_vma iat_va;
4491
4492
0
    iat_va =
4493
0
      (h1->root.u.def.value
4494
0
       + h1->root.u.def.section->output_section->vma
4495
0
       + h1->root.u.def.section->output_offset);
4496
4497
0
    h1 = coff_link_hash_lookup (coff_hash_table (info),
4498
0
              "__IAT_end__", false, false, true);
4499
0
    if (h1 != NULL
4500
0
        && (h1->root.type == bfd_link_hash_defined
4501
0
         || h1->root.type == bfd_link_hash_defweak)
4502
0
        && h1->root.u.def.section != NULL
4503
0
        && h1->root.u.def.section->output_section != NULL)
4504
0
      {
4505
0
        pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
4506
0
    ((h1->root.u.def.value
4507
0
      + h1->root.u.def.section->output_section->vma
4508
0
      + h1->root.u.def.section->output_offset)
4509
0
     - iat_va);
4510
0
        if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size != 0)
4511
0
    pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
4512
0
      iat_va - pe_data (abfd)->pe_opthdr.ImageBase;
4513
0
      }
4514
0
    else
4515
0
      {
4516
0
        _bfd_error_handler
4517
0
    (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
4518
0
       " because .idata$6 is missing"), abfd);
4519
0
        result = false;
4520
0
      }
4521
0
  }
4522
0
    }
4523
4524
0
  h1 = coff_link_hash_lookup (coff_hash_table (info),
4525
0
            (bfd_get_symbol_leading_char (abfd) != 0
4526
0
             ? "__tls_used" : "_tls_used"),
4527
0
            false, false, true);
4528
0
  if (h1 != NULL)
4529
0
    {
4530
0
      if ((h1->root.type == bfd_link_hash_defined
4531
0
     || h1->root.type == bfd_link_hash_defweak)
4532
0
    && h1->root.u.def.section != NULL
4533
0
    && h1->root.u.def.section->output_section != NULL)
4534
0
  pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
4535
0
    (h1->root.u.def.value
4536
0
     + h1->root.u.def.section->output_section->vma
4537
0
     + h1->root.u.def.section->output_offset
4538
0
     - pe_data (abfd)->pe_opthdr.ImageBase);
4539
0
      else
4540
0
  {
4541
0
    _bfd_error_handler
4542
0
      (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"),
4543
0
       abfd);
4544
0
    result = false;
4545
0
  }
4546
     /* According to PECOFF sepcifications by Microsoft version 8.2
4547
  the TLS data directory consists of 4 pointers, followed
4548
  by two 4-byte integer. This implies that the total size
4549
  is different for 32-bit and 64-bit executables.  */
4550
#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64)
4551
      pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
4552
#else
4553
0
      pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
4554
0
#endif
4555
0
    }
4556
4557
/* If there is a .pdata section and we have linked pdata finally, we
4558
     need to sort the entries ascending.  */
4559
0
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64))
4560
0
  {
4561
0
    asection *sec = bfd_get_section_by_name (abfd, ".pdata");
4562
4563
0
    if (sec)
4564
0
      {
4565
0
  bfd_size_type x = sec->rawsize;
4566
0
  bfd_byte *tmp_data;
4567
4568
0
  if (bfd_malloc_and_get_section (abfd, sec, &tmp_data))
4569
0
    {
4570
0
      qsort (tmp_data,
4571
0
       (size_t) (x / 12),
4572
0
       12, sort_x64_pdata);
4573
0
      bfd_set_section_contents (pfinfo->output_bfd, sec,
4574
0
              tmp_data, 0, x);
4575
0
      free (tmp_data);
4576
0
    }
4577
0
  else
4578
0
    result = false;
4579
0
      }
4580
0
  }
4581
0
#endif
4582
4583
0
  rsrc_process_section (abfd, pfinfo);
4584
4585
  /* If we couldn't find idata$2, we either have an excessively
4586
     trivial program or are in DEEP trouble; we have to assume trivial
4587
     program....  */
4588
0
  return result;
4589
0
}