Coverage Report

Created: 2026-07-12 09:22

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