Coverage Report

Created: 2026-04-04 08:16

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