Coverage Report

Created: 2026-07-12 09:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/bfd/pepigen.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_pep
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
48
# define AOUTSZ   PEPAOUTSZ
106
2.33k
# define PEAOUTHDR  PEPAOUTHDR
107
#endif
108
109
88
#define HighBitSet(val)      ((val) & 0x80000000)
110
#define SetHighBit(val)      ((val) | 0x80000000)
111
22
#define WithoutHighBit(val)  ((val) & 0x7fffffff)
112

113
void
114
_bfd_pepi_swap_sym_in (bfd * abfd, void * ext1, void * in1)
115
62.6k
{
116
62.6k
  SYMENT *ext = (SYMENT *) ext1;
117
62.6k
  struct internal_syment *in = (struct internal_syment *) in1;
118
119
62.6k
  if (ext->e.e_name[0] == 0)
120
36.7k
    {
121
36.7k
      in->_n._n_n._n_zeroes = 0;
122
36.7k
      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
123
36.7k
    }
124
25.9k
  else
125
25.9k
    memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
126
127
62.6k
  in->n_value = H_GET_32 (abfd, ext->e_value);
128
62.6k
  in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
129
130
62.6k
  if (sizeof (ext->e_type) == 2)
131
62.6k
    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
62.6k
  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
136
62.6k
  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
137
138
62.6k
#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
62.6k
  if (in->n_sclass == C_SECTION)
148
4.21k
    {
149
4.21k
      char namebuf[SYMNMLEN + 1];
150
4.21k
      const char *name = NULL;
151
152
4.21k
      in->n_value = 0x0;
153
154
      /* Create synthetic empty sections as needed.  DJ */
155
4.21k
      if (in->n_scnum == 0)
156
2.59k
  {
157
2.59k
    asection *sec;
158
159
2.59k
    name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
160
2.59k
    if (name == NULL)
161
583
      {
162
583
        _bfd_error_handler (_("%pB: unable to find name for empty section"),
163
583
          abfd);
164
583
        bfd_set_error (bfd_error_invalid_target);
165
583
        return;
166
583
      }
167
168
2.01k
    sec = bfd_get_section_by_name (abfd, name);
169
2.01k
    if (sec != NULL)
170
633
      in->n_scnum = sec->target_index;
171
2.01k
  }
172
173
3.62k
      if (in->n_scnum == 0)
174
1.38k
  {
175
1.38k
    int unused_section_number = 0;
176
1.38k
    asection *sec;
177
1.38k
    flagword flags;
178
1.38k
    size_t name_len;
179
1.38k
    char *sec_name;
180
181
7.59k
    for (sec = abfd->sections; sec; sec = sec->next)
182
6.21k
      if (unused_section_number <= sec->target_index)
183
6.21k
        unused_section_number = sec->target_index + 1;
184
185
1.38k
    name_len = strlen (name) + 1;
186
1.38k
    sec_name = bfd_alloc (abfd, name_len);
187
1.38k
    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.38k
    memcpy (sec_name, name, name_len);
194
195
1.38k
    flags = (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD
196
1.38k
       | SEC_LINKER_CREATED);
197
1.38k
    sec = bfd_make_section_anyway_with_flags (abfd, sec_name, flags);
198
1.38k
    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.38k
    sec->alignment_power = 2;
206
1.38k
    sec->target_index = unused_section_number;
207
208
1.38k
    in->n_scnum = unused_section_number;
209
1.38k
  }
210
3.62k
      in->n_sclass = C_STAT;
211
3.62k
    }
212
62.6k
#endif
213
62.6k
}
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_pepi_swap_sym_out (bfd * abfd, void * inp, void * extp)
225
59
{
226
59
  struct internal_syment *in = (struct internal_syment *) inp;
227
59
  SYMENT *ext = (SYMENT *) extp;
228
229
59
  if (in->_n._n_name[0] == 0)
230
32
    {
231
32
      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
232
32
      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
233
32
    }
234
27
  else
235
27
    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
59
  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
59
      && 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
59
  H_PUT_32 (abfd, in->n_value, ext->e_value);
266
59
  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
267
268
59
  if (sizeof (ext->e_type) == 2)
269
59
    H_PUT_16 (abfd, in->n_type, ext->e_type);
270
0
  else
271
59
    H_PUT_32 (abfd, in->n_type, ext->e_type);
272
273
59
  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
274
59
  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
275
276
59
  return SYMESZ;
277
59
}
278
279
void
280
_bfd_pepi_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
78.0k
{
288
78.0k
  AUXENT *ext = (AUXENT *) ext1;
289
78.0k
  union internal_auxent *in = (union internal_auxent *) in1;
290
291
  /* PR 17521: Make sure that all fields in the aux structure
292
     are initialised.  */
293
78.0k
  memset (in, 0, sizeof (*in));
294
78.0k
  switch (in_class)
295
78.0k
    {
296
7.24k
    case C_FILE:
297
7.24k
      if (ext->x_file.x_fname[0] == 0)
298
3.50k
  {
299
3.50k
    in->x_file.x_n.x_n.x_zeroes = 0;
300
3.50k
    in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
301
3.50k
  }
302
3.74k
      else
303
#if FILNMLEN != E_FILNMLEN
304
#error we need to cope with truncating or extending x_fname
305
#endif
306
3.74k
  memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
307
7.24k
      return;
308
309
4.17k
    case C_STAT:
310
4.84k
    case C_LEAFSTAT:
311
5.95k
    case C_HIDDEN:
312
5.95k
      if (type == T_NULL)
313
1.81k
  {
314
1.81k
    in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
315
1.81k
    in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
316
1.81k
    in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
317
1.81k
    in->x_scn.x_checksum = H_GET_32 (abfd, ext->x_scn.x_checksum);
318
1.81k
    in->x_scn.x_associated = H_GET_16 (abfd, ext->x_scn.x_associated);
319
1.81k
    in->x_scn.x_comdat = H_GET_8 (abfd, ext->x_scn.x_comdat);
320
1.81k
    return;
321
1.81k
  }
322
4.14k
      break;
323
78.0k
    }
324
325
68.9k
  in->x_sym.x_tagndx.u32 = H_GET_32 (abfd, ext->x_sym.x_tagndx);
326
68.9k
  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
327
328
68.9k
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
329
56.4k
      || ISTAG (in_class))
330
17.7k
    {
331
17.7k
      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
332
17.7k
      in->x_sym.x_fcnary.x_fcn.x_endndx.u32 = GET_FCN_ENDNDX (abfd, ext);
333
17.7k
    }
334
51.1k
  else
335
51.1k
    {
336
51.1k
      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
337
51.1k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
338
51.1k
      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
339
51.1k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
340
51.1k
      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
341
51.1k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
342
51.1k
      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
343
51.1k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
344
51.1k
    }
345
346
68.9k
  if (ISFCN (type))
347
10.6k
    {
348
10.6k
      in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
349
10.6k
    }
350
58.3k
  else
351
58.3k
    {
352
58.3k
      in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
353
58.3k
      in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
354
58.3k
    }
355
68.9k
}
356
357
unsigned int
358
_bfd_pepi_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
33
{
366
33
  union internal_auxent *in = (union internal_auxent *) inp;
367
33
  AUXENT *ext = (AUXENT *) extp;
368
369
33
  memset (ext, 0, AUXESZ);
370
371
33
  switch (in_class)
372
33
    {
373
1
    case C_FILE:
374
1
      if (in->x_file.x_n.x_fname[0] == 0)
375
0
  {
376
0
    H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
377
0
    H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
378
0
  }
379
1
      else
380
#if FILNMLEN != E_FILNMLEN
381
#error we need to cope with truncating or extending x_fname
382
#endif
383
1
  memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, E_FILNMLEN);
384
385
1
      return AUXESZ;
386
387
10
    case C_STAT:
388
10
    case C_LEAFSTAT:
389
10
    case C_HIDDEN:
390
10
      if (type == T_NULL)
391
3
  {
392
3
    PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
393
3
    PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
394
3
    PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
395
3
    H_PUT_32 (abfd, in->x_scn.x_checksum, ext->x_scn.x_checksum);
396
3
    H_PUT_16 (abfd, in->x_scn.x_associated, ext->x_scn.x_associated);
397
3
    H_PUT_8 (abfd, in->x_scn.x_comdat, ext->x_scn.x_comdat);
398
3
    return AUXESZ;
399
3
  }
400
7
      break;
401
33
    }
402
403
29
  H_PUT_32 (abfd, in->x_sym.x_tagndx.u32, ext->x_sym.x_tagndx);
404
29
  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
405
406
29
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
407
21
      || ISTAG (in_class))
408
12
    {
409
12
      PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,  ext);
410
12
      PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.u32, ext);
411
12
    }
412
17
  else
413
17
    {
414
17
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
415
17
    ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
416
17
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
417
17
    ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
418
17
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
419
17
    ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
420
17
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
421
17
    ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
422
17
    }
423
424
29
  if (ISFCN (type))
425
29
    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
426
21
  else
427
21
    {
428
21
      PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
429
21
      PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
430
21
    }
431
432
29
  return AUXESZ;
433
33
}
434
435
void
436
_bfd_pepi_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
437
64.1k
{
438
64.1k
  LINENO *ext = (LINENO *) ext1;
439
64.1k
  struct internal_lineno *in = (struct internal_lineno *) in1;
440
441
64.1k
  in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
442
64.1k
  in->l_lnno = GET_LINENO_LNNO (abfd, ext);
443
64.1k
}
444
445
unsigned int
446
_bfd_pepi_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_pepi_swap_aouthdr_in (bfd * abfd,
458
        void * aouthdr_ext1,
459
        void * aouthdr_int1)
460
2.28k
{
461
2.28k
  PEAOUTHDR * src = (PEAOUTHDR *) aouthdr_ext1;
462
2.28k
  AOUTHDR * aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
463
2.28k
  struct internal_aouthdr *aouthdr_int
464
2.28k
    = (struct internal_aouthdr *) aouthdr_int1;
465
2.28k
  struct internal_extra_pe_aouthdr *a = &aouthdr_int->pe;
466
467
2.28k
  aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
468
2.28k
  aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
469
2.28k
  aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
470
2.28k
  aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
471
2.28k
  aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
472
2.28k
  aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
473
2.28k
  aouthdr_int->text_start =
474
2.28k
    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
2.28k
  a->Magic = aouthdr_int->magic;
484
2.28k
  a->MajorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp);
485
2.28k
  a->MinorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp + 1);
486
2.28k
  a->SizeOfCode = aouthdr_int->tsize ;
487
2.28k
  a->SizeOfInitializedData = aouthdr_int->dsize ;
488
2.28k
  a->SizeOfUninitializedData = aouthdr_int->bsize ;
489
2.28k
  a->AddressOfEntryPoint = aouthdr_int->entry;
490
2.28k
  a->BaseOfCode = aouthdr_int->text_start;
491
2.28k
  a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, src->ImageBase);
492
2.28k
  a->SectionAlignment = H_GET_32 (abfd, src->SectionAlignment);
493
2.28k
  a->FileAlignment = H_GET_32 (abfd, src->FileAlignment);
494
2.28k
  a->MajorOperatingSystemVersion =
495
2.28k
    H_GET_16 (abfd, src->MajorOperatingSystemVersion);
496
2.28k
  a->MinorOperatingSystemVersion =
497
2.28k
    H_GET_16 (abfd, src->MinorOperatingSystemVersion);
498
2.28k
  a->MajorImageVersion = H_GET_16 (abfd, src->MajorImageVersion);
499
2.28k
  a->MinorImageVersion = H_GET_16 (abfd, src->MinorImageVersion);
500
2.28k
  a->MajorSubsystemVersion = H_GET_16 (abfd, src->MajorSubsystemVersion);
501
2.28k
  a->MinorSubsystemVersion = H_GET_16 (abfd, src->MinorSubsystemVersion);
502
2.28k
  a->Win32Version = H_GET_32 (abfd, src->Win32Version);
503
2.28k
  a->SizeOfImage = H_GET_32 (abfd, src->SizeOfImage);
504
2.28k
  a->SizeOfHeaders = H_GET_32 (abfd, src->SizeOfHeaders);
505
2.28k
  a->CheckSum = H_GET_32 (abfd, src->CheckSum);
506
2.28k
  a->Subsystem = H_GET_16 (abfd, src->Subsystem);
507
2.28k
  a->DllCharacteristics = H_GET_16 (abfd, src->DllCharacteristics);
508
2.28k
  a->SizeOfStackReserve =
509
2.28k
    GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, src->SizeOfStackReserve);
510
2.28k
  a->SizeOfStackCommit =
511
2.28k
    GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, src->SizeOfStackCommit);
512
2.28k
  a->SizeOfHeapReserve =
513
2.28k
    GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, src->SizeOfHeapReserve);
514
2.28k
  a->SizeOfHeapCommit =
515
2.28k
    GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, src->SizeOfHeapCommit);
516
2.28k
  a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
517
2.28k
  a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
518
519
  /* PR 17512: Don't blindly trust NumberOfRvaAndSizes.  */
520
2.28k
  unsigned idx;
521
2.28k
  for (idx = 0;
522
23.9k
       idx < a->NumberOfRvaAndSizes && idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
523
21.6k
       idx++)
524
21.6k
    {
525
      /* If data directory is empty, rva also should be 0.  */
526
21.6k
      int size = H_GET_32 (abfd, src->DataDirectory[idx][1]);
527
21.6k
      int vma = size ? H_GET_32 (abfd, src->DataDirectory[idx][0]) : 0;
528
529
21.6k
      a->DataDirectory[idx].Size = size;
530
21.6k
      a->DataDirectory[idx].VirtualAddress = vma;
531
21.6k
    }
532
533
17.1k
  while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
534
14.9k
    {
535
14.9k
      a->DataDirectory[idx].Size = 0;
536
14.9k
      a->DataDirectory[idx].VirtualAddress = 0;
537
14.9k
      idx++;
538
14.9k
    }
539
540
2.28k
  if (aouthdr_int->entry)
541
1.54k
    {
542
1.54k
      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
1.54k
    }
547
548
2.28k
  if (aouthdr_int->tsize)
549
1.84k
    {
550
1.84k
      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
1.84k
    }
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
2.28k
}
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
164
{
575
164
  asection *sec = bfd_get_section_by_name (abfd, name);
576
577
  /* Add import directory information if it exists.  */
578
164
  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
164
}
594
595
unsigned int
596
_bfd_pepi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
597
48
{
598
48
  struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
599
48
  pe_data_type *pe = pe_data (abfd);
600
48
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
601
48
  PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
602
48
  bfd_vma sa, fa, ib;
603
48
  IMAGE_DATA_DIRECTORY idata2, idata5, didat2, tls, loadcfg;
604
605
48
  sa = extra->SectionAlignment;
606
48
  fa = extra->FileAlignment;
607
48
  ib = extra->ImageBase;
608
609
48
  idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
610
48
  idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
611
48
  didat2 = pe->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR];
612
48
  tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
613
48
  loadcfg = pe->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE];
614
615
48
  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
48
  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
48
  if (aouthdr_in->entry)
632
24
    {
633
24
      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
24
    }
638
639
148
#define FA(x) (((x) + fa -1 ) & (- fa))
640
48
#define SA(x) (((x) + sa -1 ) & (- sa))
641
642
  /* We like to have the sizes aligned.  */
643
48
  aouthdr_in->bsize = FA (aouthdr_in->bsize);
644
645
48
  extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
646
647
48
  add_data_entry (abfd, extra, PE_EXPORT_TABLE, ".edata", ib);
648
48
  add_data_entry (abfd, extra, PE_RESOURCE_TABLE, ".rsrc", ib);
649
48
  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
48
  extra->DataDirectory[PE_IMPORT_TABLE]  = idata2;
661
48
  extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
662
48
  extra->DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR] = didat2;
663
48
  extra->DataDirectory[PE_TLS_TABLE] = tls;
664
48
  extra->DataDirectory[PE_LOAD_CONFIG_TABLE] = loadcfg;
665
666
48
  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
20
    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
48
  if (pe->has_reloc_section)
677
0
    add_data_entry (abfd, extra, PE_BASE_RELOCATION_TABLE, ".reloc", ib);
678
679
48
  {
680
48
    asection *sec;
681
48
    bfd_vma hsize = 0;
682
48
    bfd_vma dsize = 0;
683
48
    bfd_vma isize = 0;
684
48
    bfd_vma tsize = 0;
685
686
148
    for (sec = abfd->sections; sec; sec = sec->next)
687
100
      {
688
100
  int rounded = FA (sec->size);
689
690
100
  if (rounded == 0)
691
65
    continue;
692
693
  /* The first non-zero section filepos is the header size.
694
     Sections without contents will have a filepos of 0.  */
695
35
  if (hsize == 0)
696
25
    hsize = sec->filepos;
697
35
  if (sec->flags & SEC_DATA)
698
0
    dsize += rounded;
699
35
  if (sec->flags & SEC_CODE)
700
0
    tsize += rounded;
701
  /* The image size is the total VIRTUAL size (which is what is
702
     in the virt_size field).  Files have been seen (from MSVC
703
     5.0 link.exe) where the file size of the .data segment is
704
     quite small compared to the virtual size.  Without this
705
     fix, strip munges the file.
706
707
     FIXME: We need to handle holes between sections, which may
708
     happpen when we covert from another format.  We just use
709
     the virtual address and virtual size of the last section
710
     for the image size.  */
711
35
  if (coff_section_data (abfd, sec) != NULL
712
35
      && pei_section_data (abfd, sec) != NULL)
713
35
    isize = SA (sec->vma - extra->ImageBase
714
35
          + FA (pei_section_data (abfd, sec)->virt_size));
715
35
      }
716
717
48
    aouthdr_in->dsize = dsize;
718
48
    aouthdr_in->tsize = tsize;
719
48
    extra->SizeOfHeaders = hsize;
720
48
    extra->SizeOfImage = isize;
721
48
  }
722
723
48
  H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
724
725
48
  if (extra->MajorLinkerVersion || extra->MinorLinkerVersion)
726
32
    {
727
32
      H_PUT_8 (abfd, extra->MajorLinkerVersion,
728
32
         aouthdr_out->standard.vstamp);
729
32
      H_PUT_8 (abfd, extra->MinorLinkerVersion,
730
32
         aouthdr_out->standard.vstamp + 1);
731
32
    }
732
16
  else
733
16
    {
734
/* e.g. 219510000 is linker version 2.19  */
735
16
#define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
736
737
      /* This piece of magic sets the "linker version" field to
738
   LINKER_VERSION.  */
739
16
      H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
740
16
    aouthdr_out->standard.vstamp);
741
16
    }
742
743
48
  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
744
48
  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
745
48
  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->standard.bsize);
746
48
  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->standard.entry);
747
48
  PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
748
48
        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
48
  PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, aouthdr_out->ImageBase);
757
48
  H_PUT_32 (abfd, extra->SectionAlignment, aouthdr_out->SectionAlignment);
758
48
  H_PUT_32 (abfd, extra->FileAlignment, aouthdr_out->FileAlignment);
759
48
  H_PUT_16 (abfd, extra->MajorOperatingSystemVersion,
760
48
      aouthdr_out->MajorOperatingSystemVersion);
761
48
  H_PUT_16 (abfd, extra->MinorOperatingSystemVersion,
762
48
      aouthdr_out->MinorOperatingSystemVersion);
763
48
  H_PUT_16 (abfd, extra->MajorImageVersion, aouthdr_out->MajorImageVersion);
764
48
  H_PUT_16 (abfd, extra->MinorImageVersion, aouthdr_out->MinorImageVersion);
765
48
  H_PUT_16 (abfd, extra->MajorSubsystemVersion,
766
48
      aouthdr_out->MajorSubsystemVersion);
767
48
  H_PUT_16 (abfd, extra->MinorSubsystemVersion,
768
48
      aouthdr_out->MinorSubsystemVersion);
769
48
  H_PUT_32 (abfd, extra->Win32Version, aouthdr_out->Win32Version);
770
48
  H_PUT_32 (abfd, extra->SizeOfImage, aouthdr_out->SizeOfImage);
771
48
  H_PUT_32 (abfd, extra->SizeOfHeaders, aouthdr_out->SizeOfHeaders);
772
48
  H_PUT_32 (abfd, extra->CheckSum, aouthdr_out->CheckSum);
773
48
  H_PUT_16 (abfd, extra->Subsystem, aouthdr_out->Subsystem);
774
48
  H_PUT_16 (abfd, extra->DllCharacteristics, aouthdr_out->DllCharacteristics);
775
48
  PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve,
776
48
            aouthdr_out->SizeOfStackReserve);
777
48
  PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit,
778
48
           aouthdr_out->SizeOfStackCommit);
779
48
  PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve,
780
48
           aouthdr_out->SizeOfHeapReserve);
781
48
  PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit,
782
48
          aouthdr_out->SizeOfHeapCommit);
783
48
  H_PUT_32 (abfd, extra->LoaderFlags, aouthdr_out->LoaderFlags);
784
48
  H_PUT_32 (abfd, extra->NumberOfRvaAndSizes,
785
48
      aouthdr_out->NumberOfRvaAndSizes);
786
48
  {
787
48
    int idx;
788
789
816
    for (idx = 0; idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; idx++)
790
768
      {
791
768
  H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
792
768
      aouthdr_out->DataDirectory[idx][0]);
793
768
  H_PUT_32 (abfd, extra->DataDirectory[idx].Size,
794
768
      aouthdr_out->DataDirectory[idx][1]);
795
768
      }
796
48
  }
797
798
48
  return AOUTSZ;
799
48
}
800
801
unsigned int
802
_bfd_pepi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
803
81
{
804
81
  int idx;
805
81
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
806
81
  struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *) out;
807
808
81
  if (pe_data (abfd)->has_reloc_section
809
81
      || pe_data (abfd)->dont_strip_reloc)
810
46
    filehdr_in->f_flags &= ~F_RELFLG;
811
812
81
  if (pe_data (abfd)->dll)
813
39
    filehdr_in->f_flags |= F_DLL;
814
815
81
  filehdr_in->pe.e_magic    = IMAGE_DOS_SIGNATURE;
816
81
  filehdr_in->pe.e_cblp     = 0x90;
817
81
  filehdr_in->pe.e_cp       = 0x3;
818
81
  filehdr_in->pe.e_crlc     = 0x0;
819
81
  filehdr_in->pe.e_cparhdr  = 0x4;
820
81
  filehdr_in->pe.e_minalloc = 0x0;
821
81
  filehdr_in->pe.e_maxalloc = 0xffff;
822
81
  filehdr_in->pe.e_ss       = 0x0;
823
81
  filehdr_in->pe.e_sp       = 0xb8;
824
81
  filehdr_in->pe.e_csum     = 0x0;
825
81
  filehdr_in->pe.e_ip       = 0x0;
826
81
  filehdr_in->pe.e_cs       = 0x0;
827
81
  filehdr_in->pe.e_lfarlc   = 0x40;
828
81
  filehdr_in->pe.e_ovno     = 0x0;
829
830
405
  for (idx = 0; idx < 4; idx++)
831
324
    filehdr_in->pe.e_res[idx] = 0x0;
832
833
81
  filehdr_in->pe.e_oemid   = 0x0;
834
81
  filehdr_in->pe.e_oeminfo = 0x0;
835
836
891
  for (idx = 0; idx < 10; idx++)
837
810
    filehdr_in->pe.e_res2[idx] = 0x0;
838
839
81
  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
81
  memcpy (filehdr_in->pe.dos_message, pe_data (abfd)->dos_message,
844
81
    sizeof (filehdr_in->pe.dos_message));
845
846
81
  filehdr_in->pe.nt_signature = IMAGE_NT_SIGNATURE;
847
848
81
  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
849
81
  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
81
  if ((pe_data (abfd)->timestamp) == -1)
854
81
    {
855
81
      time_t now = bfd_get_current_time (0);
856
81
      H_PUT_32 (abfd, now, filehdr_out->f_timdat);
857
81
    }
858
0
  else
859
81
    H_PUT_32 (abfd, pe_data (abfd)->timestamp, filehdr_out->f_timdat);
860
861
81
  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
862
81
          filehdr_out->f_symptr);
863
81
  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
864
81
  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
865
81
  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
81
  H_PUT_16 (abfd, filehdr_in->pe.e_magic, filehdr_out->e_magic);
871
81
  H_PUT_16 (abfd, filehdr_in->pe.e_cblp, filehdr_out->e_cblp);
872
81
  H_PUT_16 (abfd, filehdr_in->pe.e_cp, filehdr_out->e_cp);
873
81
  H_PUT_16 (abfd, filehdr_in->pe.e_crlc, filehdr_out->e_crlc);
874
81
  H_PUT_16 (abfd, filehdr_in->pe.e_cparhdr, filehdr_out->e_cparhdr);
875
81
  H_PUT_16 (abfd, filehdr_in->pe.e_minalloc, filehdr_out->e_minalloc);
876
81
  H_PUT_16 (abfd, filehdr_in->pe.e_maxalloc, filehdr_out->e_maxalloc);
877
81
  H_PUT_16 (abfd, filehdr_in->pe.e_ss, filehdr_out->e_ss);
878
81
  H_PUT_16 (abfd, filehdr_in->pe.e_sp, filehdr_out->e_sp);
879
81
  H_PUT_16 (abfd, filehdr_in->pe.e_csum, filehdr_out->e_csum);
880
81
  H_PUT_16 (abfd, filehdr_in->pe.e_ip, filehdr_out->e_ip);
881
81
  H_PUT_16 (abfd, filehdr_in->pe.e_cs, filehdr_out->e_cs);
882
81
  H_PUT_16 (abfd, filehdr_in->pe.e_lfarlc, filehdr_out->e_lfarlc);
883
81
  H_PUT_16 (abfd, filehdr_in->pe.e_ovno, filehdr_out->e_ovno);
884
885
405
  for (idx = 0; idx < 4; idx++)
886
324
    H_PUT_16 (abfd, filehdr_in->pe.e_res[idx], filehdr_out->e_res[idx]);
887
888
81
  H_PUT_16 (abfd, filehdr_in->pe.e_oemid, filehdr_out->e_oemid);
889
81
  H_PUT_16 (abfd, filehdr_in->pe.e_oeminfo, filehdr_out->e_oeminfo);
890
891
891
  for (idx = 0; idx < 10; idx++)
892
810
    H_PUT_16 (abfd, filehdr_in->pe.e_res2[idx], filehdr_out->e_res2[idx]);
893
894
81
  H_PUT_32 (abfd, filehdr_in->pe.e_lfanew, filehdr_out->e_lfanew);
895
896
81
  memcpy (filehdr_out->dos_message, filehdr_in->pe.dos_message,
897
81
    sizeof (filehdr_out->dos_message));
898
899
  /* Also put in the NT signature.  */
900
81
  H_PUT_32 (abfd, filehdr_in->pe.nt_signature, filehdr_out->nt_signature);
901
902
81
  return FILHSZ;
903
81
}
904
905
unsigned int
906
_bfd_pep_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
907
0
{
908
0
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
909
0
  FILHDR *filehdr_out = (FILHDR *) out;
910
911
0
  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
912
0
  H_PUT_16 (abfd, filehdr_in->f_nscns, filehdr_out->f_nscns);
913
0
  H_PUT_32 (abfd, filehdr_in->f_timdat, filehdr_out->f_timdat);
914
0
  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr);
915
0
  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
916
0
  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
917
0
  H_PUT_16 (abfd, filehdr_in->f_flags, filehdr_out->f_flags);
918
919
0
  return FILHSZ;
920
0
}
921
922
unsigned int
923
_bfd_pepi_swap_scnhdr_out (bfd * abfd, void * in, void * out,
924
        const asection *section)
925
88
{
926
88
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
927
88
  SCNHDR *scnhdr_ext = (SCNHDR *) out;
928
88
  unsigned int ret = SCNHSZ;
929
88
  bfd_vma ps;
930
88
  bfd_vma ss;
931
932
88
  memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
933
934
88
  ss = scnhdr_int->s_vaddr - pe_data (abfd)->pe_opthdr.ImageBase;
935
88
  if (scnhdr_int->s_vaddr < pe_data (abfd)->pe_opthdr.ImageBase)
936
45
    _bfd_error_handler (_("%pB:%.8s: section below image base"),
937
45
                        abfd, scnhdr_int->s_name);
938
  /* Do not compare lower 32-bits for 64-bit vma.  */
939
43
#if !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64)
940
43
  else if(ss != (ss & 0xffffffff))
941
0
    _bfd_error_handler (_("%pB:%.8s: RVA truncated"), abfd, scnhdr_int->s_name);
942
88
  PUT_SCNHDR_VADDR (abfd, ss & 0xffffffff, scnhdr_ext->s_vaddr);
943
#else
944
  PUT_SCNHDR_VADDR (abfd, ss, scnhdr_ext->s_vaddr);
945
#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
88
  if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
951
0
    {
952
0
      if (bfd_pei_p (abfd))
953
0
  {
954
0
    ps = scnhdr_int->s_size;
955
0
    ss = 0;
956
0
  }
957
0
      else
958
0
       {
959
0
   ps = 0;
960
0
   ss = scnhdr_int->s_size;
961
0
       }
962
0
    }
963
88
  else
964
88
    {
965
88
      if (bfd_pei_p (abfd))
966
88
  ps = scnhdr_int->s_paddr;
967
0
      else
968
0
  ps = 0;
969
970
88
      ss = scnhdr_int->s_size;
971
88
    }
972
973
88
  PUT_SCNHDR_SIZE (abfd, ss,
974
88
       scnhdr_ext->s_size);
975
976
  /* s_paddr in PE is really the virtual size.  */
977
88
  PUT_SCNHDR_PADDR (abfd, ps, scnhdr_ext->s_paddr);
978
979
88
  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
980
88
         scnhdr_ext->s_scnptr);
981
88
  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
982
88
         scnhdr_ext->s_relptr);
983
88
  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
984
88
          scnhdr_ext->s_lnnoptr);
985
986
88
  {
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
88
    typedef struct
1001
88
    {
1002
88
      char section_name[SCNNMLEN];
1003
88
      unsigned long must_have;
1004
88
    }
1005
88
    pe_required_section_flags;
1006
1007
88
    static const pe_required_section_flags known_sections [] =
1008
88
      {
1009
88
  { ".CRT",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1010
88
  { ".arch",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES },
1011
88
  { ".bss",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1012
88
  { ".data",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1013
88
  { ".didat", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1014
88
  { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1015
88
  { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1016
88
  { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1017
88
  { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1018
88
  { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
1019
88
  { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1020
88
  { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
1021
88
  { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1022
88
  { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1023
88
      };
1024
1025
88
    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
88
    for (p = known_sections;
1036
1.32k
   p < known_sections + ARRAY_SIZE (known_sections);
1037
1.23k
   p++)
1038
1.23k
      if (memcmp (scnhdr_int->s_name, p->section_name, SCNNMLEN) == 0)
1039
0
  {
1040
0
    unsigned long must_have = p->must_have;
1041
1042
0
    if (memcmp (scnhdr_int->s_name, ".text", sizeof ".text")
1043
0
        || (bfd_get_file_flags (abfd) & WP_TEXT))
1044
0
      scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
1045
    /* Avoid forcing in the discardable flag if the section itself is
1046
       allocated.  */
1047
0
    if (section->flags & SEC_ALLOC)
1048
0
      must_have &= ~IMAGE_SCN_MEM_DISCARDABLE;
1049
0
    scnhdr_int->s_flags |= must_have;
1050
0
    break;
1051
0
  }
1052
1053
88
    H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
1054
88
  }
1055
1056
88
  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
88
  else
1073
88
    {
1074
88
      if (scnhdr_int->s_nlnno <= 0xffff)
1075
88
  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
88
      if (scnhdr_int->s_nreloc < 0xffff)
1091
88
  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
88
    }
1100
88
  return ret;
1101
88
}
1102
1103
void
1104
_bfd_pepi_swap_debugdir_in (bfd * abfd, void * ext1, void * in1)
1105
4.47k
{
1106
4.47k
  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) ext1;
1107
4.47k
  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) in1;
1108
1109
4.47k
  in->Characteristics = H_GET_32(abfd, ext->Characteristics);
1110
4.47k
  in->TimeDateStamp = H_GET_32(abfd, ext->TimeDateStamp);
1111
4.47k
  in->MajorVersion = H_GET_16(abfd, ext->MajorVersion);
1112
4.47k
  in->MinorVersion = H_GET_16(abfd, ext->MinorVersion);
1113
4.47k
  in->Type = H_GET_32(abfd, ext->Type);
1114
4.47k
  in->SizeOfData = H_GET_32(abfd, ext->SizeOfData);
1115
4.47k
  in->AddressOfRawData = H_GET_32(abfd, ext->AddressOfRawData);
1116
4.47k
  in->PointerToRawData = H_GET_32(abfd, ext->PointerToRawData);
1117
4.47k
}
1118
1119
unsigned int
1120
_bfd_pepi_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
1121
5
{
1122
5
  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) extp;
1123
5
  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) inp;
1124
1125
5
  H_PUT_32(abfd, in->Characteristics, ext->Characteristics);
1126
5
  H_PUT_32(abfd, in->TimeDateStamp, ext->TimeDateStamp);
1127
5
  H_PUT_16(abfd, in->MajorVersion, ext->MajorVersion);
1128
5
  H_PUT_16(abfd, in->MinorVersion, ext->MinorVersion);
1129
5
  H_PUT_32(abfd, in->Type, ext->Type);
1130
5
  H_PUT_32(abfd, in->SizeOfData, ext->SizeOfData);
1131
5
  H_PUT_32(abfd, in->AddressOfRawData, ext->AddressOfRawData);
1132
5
  H_PUT_32(abfd, in->PointerToRawData, ext->PointerToRawData);
1133
1134
5
  return sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
1135
5
}
1136
1137
CODEVIEW_INFO *
1138
_bfd_pepi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo,
1139
        char **pdb)
1140
137
{
1141
137
  char buffer[256+1];
1142
137
  bfd_size_type nread;
1143
1144
137
  if (bfd_seek (abfd, where, SEEK_SET) != 0)
1145
0
    return NULL;
1146
1147
137
  if (length <= sizeof (CV_INFO_PDB70) && length <= sizeof (CV_INFO_PDB20))
1148
19
    return NULL;
1149
118
  if (length > 256)
1150
90
    length = 256;
1151
118
  nread = bfd_read (buffer, length, abfd);
1152
118
  if (length != nread)
1153
64
    return NULL;
1154
1155
  /* Ensure null termination of filename.  */
1156
54
  memset (buffer + nread, 0, sizeof (buffer) - nread);
1157
1158
54
  cvinfo->CVSignature = H_GET_32 (abfd, buffer);
1159
54
  cvinfo->Age = 0;
1160
1161
54
  if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
1162
1
      && (length > sizeof (CV_INFO_PDB70)))
1163
1
    {
1164
1
      CV_INFO_PDB70 *cvinfo70 = (CV_INFO_PDB70 *)(buffer);
1165
1166
1
      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
1
      bfd_putb32 (bfd_getl32 (cvinfo70->Signature), cvinfo->Signature);
1172
1
      bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[4])), &(cvinfo->Signature[4]));
1173
1
      bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[6])), &(cvinfo->Signature[6]));
1174
1
      memcpy (&(cvinfo->Signature[8]), &(cvinfo70->Signature[8]), 8);
1175
1176
1
      cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH;
1177
      /* cvinfo->PdbFileName = cvinfo70->PdbFileName;  */
1178
1179
1
      if (pdb)
1180
0
  *pdb = xstrdup (cvinfo70->PdbFileName);
1181
1182
1
      return cvinfo;
1183
1
    }
1184
53
  else if ((cvinfo->CVSignature == CVINFO_PDB20_CVSIGNATURE)
1185
0
     && (length > sizeof (CV_INFO_PDB20)))
1186
0
    {
1187
0
      CV_INFO_PDB20 *cvinfo20 = (CV_INFO_PDB20 *)(buffer);
1188
0
      cvinfo->Age = H_GET_32(abfd, cvinfo20->Age);
1189
0
      memcpy (cvinfo->Signature, cvinfo20->Signature, 4);
1190
0
      cvinfo->SignatureLength = 4;
1191
      /* cvinfo->PdbFileName = cvinfo20->PdbFileName;  */
1192
1193
0
      if (pdb)
1194
0
  *pdb = xstrdup (cvinfo20->PdbFileName);
1195
1196
0
      return cvinfo;
1197
0
    }
1198
1199
53
  return NULL;
1200
54
}
1201
1202
unsigned int
1203
_bfd_pepi_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
2
{
1267
2
  if ((section->flags & SEC_HAS_CONTENTS) == 0)
1268
0
    return false;
1269
2
  if (dataoff > section->size
1270
2
      || datasize > section->size - dataoff)
1271
0
    return false;
1272
2
  ufile_ptr filesize = bfd_get_file_size (abfd);
1273
2
  if (filesize != 0
1274
2
      && ((ufile_ptr) section->filepos > filesize
1275
2
    || dataoff > filesize - section->filepos
1276
2
    || datasize > filesize - section->filepos - dataoff))
1277
0
    return false;
1278
2
  return true;
1279
2
}
1280
1281
static bool
1282
pe_print_idata (bfd * abfd, void * vfile)
1283
263
{
1284
263
  FILE *file = (FILE *) vfile;
1285
263
  bfd_byte *data;
1286
263
  asection *section;
1287
263
  bfd_signed_vma adj;
1288
263
  bfd_size_type datasize = 0;
1289
263
  bfd_size_type dataoff;
1290
263
  bfd_size_type i;
1291
263
  int onaline = 20;
1292
1293
263
  pe_data_type *pe = pe_data (abfd);
1294
263
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1295
1296
263
  bfd_vma addr;
1297
1298
263
  addr = extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress;
1299
1300
263
  if (addr == 0 && extra->DataDirectory[PE_IMPORT_TABLE].Size == 0)
1301
83
    {
1302
      /* Maybe the extra header isn't there.  Look for the section.  */
1303
83
      section = bfd_get_section_by_name (abfd, ".idata");
1304
83
      if (section == NULL || (section->flags & SEC_HAS_CONTENTS) == 0)
1305
83
  return true;
1306
1307
0
      addr = section->vma;
1308
0
      datasize = section->size;
1309
0
      if (datasize == 0)
1310
0
  return true;
1311
0
    }
1312
180
  else
1313
180
    {
1314
180
      addr += extra->ImageBase;
1315
1.37k
      for (section = abfd->sections; section != NULL; section = section->next)
1316
1.20k
  {
1317
1.20k
    datasize = section->size;
1318
1.20k
    if (addr >= section->vma && addr < section->vma + datasize)
1319
3
      break;
1320
1.20k
  }
1321
1322
180
      if (section == NULL)
1323
177
  {
1324
177
    fprintf (file,
1325
177
       _("\nThere is an import table, but the section containing it could not be found\n"));
1326
177
    return true;
1327
177
  }
1328
3
      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
180
    }
1336
1337
  /* xgettext:c-format */
1338
3
  fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
1339
3
     section->name, (unsigned long) addr);
1340
1341
3
  dataoff = addr - section->vma;
1342
1343
3
  fprintf (file,
1344
3
     _("\nThe Import Tables (interpreted %s section contents)\n"),
1345
3
     section->name);
1346
3
  fprintf (file,
1347
3
     _("\
1348
3
 vma:            Hint    Time      Forward  DLL       First\n\
1349
3
                 Table   Stamp     Chain    Name      Thunk\n"));
1350
1351
  /* Read the whole section.  Some of the fields might be before dataoff.  */
1352
3
  if (!bfd_malloc_and_get_section (abfd, section, &data))
1353
1
    {
1354
1
      free (data);
1355
1
      return false;
1356
1
    }
1357
1358
2
  adj = section->vma - extra->ImageBase;
1359
1360
  /* Print all image import descriptors.  */
1361
3
  for (i = dataoff; i + onaline <= datasize; i += onaline)
1362
3
    {
1363
3
      bfd_vma hint_addr;
1364
3
      bfd_vma time_stamp;
1365
3
      bfd_vma forward_chain;
1366
3
      bfd_vma dll_name;
1367
3
      bfd_vma first_thunk;
1368
3
      int idx = 0;
1369
3
      bfd_size_type j;
1370
3
      char *dll;
1371
1372
      /* Print (i + extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress).  */
1373
3
      fprintf (file, " %08lx\t", (unsigned long) (i + adj));
1374
3
      hint_addr = bfd_get_32 (abfd, data + i);
1375
3
      time_stamp = bfd_get_32 (abfd, data + i + 4);
1376
3
      forward_chain = bfd_get_32 (abfd, data + i + 8);
1377
3
      dll_name = bfd_get_32 (abfd, data + i + 12);
1378
3
      first_thunk = bfd_get_32 (abfd, data + i + 16);
1379
1380
3
      fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
1381
3
         (unsigned long) hint_addr,
1382
3
         (unsigned long) time_stamp,
1383
3
         (unsigned long) forward_chain,
1384
3
         (unsigned long) dll_name,
1385
3
         (unsigned long) first_thunk);
1386
1387
3
      if (hint_addr == 0 && first_thunk == 0)
1388
0
  break;
1389
1390
3
      if (dll_name - adj >= section->size)
1391
2
  break;
1392
1393
1
      dll = (char *) data + dll_name - adj;
1394
      /* PR 17512 file: 078-12277-0.004.  */
1395
1
      bfd_size_type maxlen = (char *)(data + datasize) - dll - 1;
1396
1
      fprintf (file, _("\n\tDLL Name: %.*s\n"), (int) maxlen, dll);
1397
1398
      /* PR 21546: When the Hint Address is zero,
1399
   we try the First Thunk instead.  */
1400
1
      if (hint_addr == 0)
1401
1
  hint_addr = first_thunk;
1402
1403
1
      if (hint_addr != 0 && hint_addr - adj < datasize)
1404
0
  {
1405
0
    bfd_byte *ft_data;
1406
0
    asection *ft_section;
1407
0
    bfd_vma ft_addr;
1408
0
    bfd_size_type ft_datasize;
1409
0
    int ft_idx;
1410
0
    int ft_allocated;
1411
1412
0
    fprintf (file, _("\tvma:     Ordinal  Hint  Member-Name  Bound-To\n"));
1413
1414
0
    idx = hint_addr - adj;
1415
1416
0
    ft_addr = first_thunk + extra->ImageBase;
1417
0
    ft_idx = first_thunk - adj;
1418
0
    ft_data = data + ft_idx;
1419
0
    ft_datasize = datasize - ft_idx;
1420
0
    ft_allocated = 0;
1421
1422
0
    if (first_thunk != hint_addr)
1423
0
      {
1424
        /* Find the section which contains the first thunk.  */
1425
0
        for (ft_section = abfd->sections;
1426
0
       ft_section != NULL;
1427
0
       ft_section = ft_section->next)
1428
0
    {
1429
0
      if (ft_addr >= ft_section->vma
1430
0
          && ft_addr < ft_section->vma + ft_section->size)
1431
0
        break;
1432
0
    }
1433
1434
0
        if (ft_section == NULL)
1435
0
    {
1436
0
      fprintf (file,
1437
0
           _("\nThere is a first thunk, but the section containing it could not be found\n"));
1438
0
      continue;
1439
0
    }
1440
1441
        /* Now check to see if this section is the same as our current
1442
     section.  If it is not then we will have to load its data in.  */
1443
0
        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
0
      }
1464
1465
    /* Print HintName vector entries.  */
1466
0
#if defined COFF_WITH_pep || defined COFF_WITH_pex64 \
1467
0
    || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64 \
1468
0
    || defined COFF_WITH_peRiscV64
1469
0
    for (j = 0; idx + j + 8 <= datasize; j += 8)
1470
0
      {
1471
0
        bfd_size_type amt;
1472
0
        unsigned long member = bfd_get_32 (abfd, data + idx + j);
1473
0
        unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
1474
1475
0
        if (!member && !member_high)
1476
0
    break;
1477
1478
0
        amt = member - adj;
1479
1480
0
        if (HighBitSet (member_high))
1481
0
          {
1482
      /* in low 16 bits is ordinal number, other bits are reserved */
1483
0
      unsigned int ordinal = member & 0xffff;
1484
0
      fprintf (file, "\t%08lx  %5u  <none> <none>",
1485
0
         (unsigned long)(first_thunk + j), ordinal);
1486
0
          }
1487
        /* PR binutils/17512: Handle corrupt PE data.  */
1488
0
        else if (amt >= datasize || amt + 2 >= datasize)
1489
0
    fprintf (file, _("\t<corrupt: 0x%08lx>"), member);
1490
0
        else
1491
0
    {
1492
0
      unsigned int hint;
1493
0
      char *member_name;
1494
1495
      /* First 16 bits is hint name index, rest is the name */
1496
0
      hint = bfd_get_16 (abfd, data + amt);
1497
0
      member_name = (char *) data + amt + 2;
1498
0
      fprintf (file, "\t%08lx  <none>  %04x  %.*s",
1499
0
         (unsigned long)(first_thunk + j), hint,
1500
0
         (int) (datasize - (amt + 2)), member_name);
1501
0
    }
1502
1503
        /* If the time stamp is not zero, the import address
1504
     table holds actual addresses.  */
1505
0
        if (time_stamp != 0
1506
0
      && first_thunk != 0
1507
0
      && first_thunk != hint_addr
1508
0
      && j + 4 <= ft_datasize)
1509
0
    fprintf (file, "\t%08lx",
1510
0
       (unsigned long) bfd_get_32 (abfd, ft_data + j));
1511
1512
0
        fprintf (file, "\n");
1513
0
      }
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
0
    if (ft_allocated)
1561
0
      free (ft_data);
1562
0
  }
1563
1564
1
      fprintf (file, "\n");
1565
1
    }
1566
1567
2
  free (data);
1568
1569
2
  return true;
1570
3
}
1571
1572
static bool
1573
pe_print_edata (bfd * abfd, void * vfile)
1574
263
{
1575
263
  FILE *file = (FILE *) vfile;
1576
263
  bfd_byte *data;
1577
263
  asection *section;
1578
263
  bfd_size_type datasize = 0;
1579
263
  bfd_size_type dataoff;
1580
263
  bfd_size_type i;
1581
263
  bfd_vma       adj;
1582
263
  struct EDT_type
1583
263
  {
1584
263
    long export_flags;    /* Reserved - should be zero.  */
1585
263
    long time_stamp;
1586
263
    short major_ver;
1587
263
    short minor_ver;
1588
263
    bfd_vma name;   /* RVA - relative to image base.  */
1589
263
    long base;      /* Ordinal base.  */
1590
263
    unsigned long num_functions;/* Number in the export address table.  */
1591
263
    unsigned long num_names;  /* Number in the name pointer table.  */
1592
263
    bfd_vma eat_addr;   /* RVA to the export address table.  */
1593
263
    bfd_vma npt_addr;   /* RVA to the Export Name Pointer Table.  */
1594
263
    bfd_vma ot_addr;    /* RVA to the Ordinal Table.  */
1595
263
  } edt;
1596
1597
263
  pe_data_type *pe = pe_data (abfd);
1598
263
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1599
1600
263
  bfd_vma addr;
1601
1602
263
  addr = extra->DataDirectory[PE_EXPORT_TABLE].VirtualAddress;
1603
1604
263
  if (addr == 0 && extra->DataDirectory[PE_EXPORT_TABLE].Size == 0)
1605
67
    {
1606
      /* Maybe the extra header isn't there.  Look for the section.  */
1607
67
      section = bfd_get_section_by_name (abfd, ".edata");
1608
67
      if (section == NULL)
1609
67
  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
196
  else
1618
196
    {
1619
196
      addr += extra->ImageBase;
1620
1621
1.43k
      for (section = abfd->sections; section != NULL; section = section->next)
1622
1.24k
  if (addr >= section->vma && addr < section->vma + section->size)
1623
3
    break;
1624
1625
196
      if (section == NULL)
1626
193
  {
1627
193
    fprintf (file,
1628
193
       _("\nThere is an export table, but the section containing it could not be found\n"));
1629
193
    return true;
1630
193
  }
1631
1632
3
      dataoff = addr - section->vma;
1633
3
      datasize = extra->DataDirectory[PE_EXPORT_TABLE].Size;
1634
3
    }
1635
1636
  /* PR 17512: Handle corrupt PE binaries.  */
1637
3
  if (datasize < 40)
1638
1
    {
1639
1
      fprintf (file,
1640
         /* xgettext:c-format */
1641
1
         _("\nThere is an export table in %s, but it is too small (%d)\n"),
1642
1
         section->name, (int) datasize);
1643
1
      return true;
1644
1
    }
1645
1646
2
  if (!get_contents_sanity_check (abfd, section, dataoff, datasize))
1647
0
    {
1648
0
      fprintf (file,
1649
0
         _("\nThere is an export table in %s, but contents cannot be read\n"),
1650
0
         section->name);
1651
0
      return true;
1652
0
    }
1653
1654
  /* xgettext:c-format */
1655
2
  fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
1656
2
     section->name, (unsigned long) addr);
1657
1658
2
  data = (bfd_byte *) bfd_malloc (datasize);
1659
2
  if (data == NULL)
1660
0
    return false;
1661
1662
2
  if (! bfd_get_section_contents (abfd, section, data,
1663
2
          (file_ptr) dataoff, datasize))
1664
0
    {
1665
0
      free (data);
1666
0
      return false;
1667
0
    }
1668
1669
  /* Go get Export Directory Table.  */
1670
2
  edt.export_flags   = bfd_get_32 (abfd, data +   0);
1671
2
  edt.time_stamp     = bfd_get_32 (abfd, data +   4);
1672
2
  edt.major_ver      = bfd_get_16 (abfd, data +   8);
1673
2
  edt.minor_ver      = bfd_get_16 (abfd, data + 10);
1674
2
  edt.name       = bfd_get_32 (abfd, data + 12);
1675
2
  edt.base       = bfd_get_32 (abfd, data + 16);
1676
2
  edt.num_functions  = bfd_get_32 (abfd, data + 20);
1677
2
  edt.num_names      = bfd_get_32 (abfd, data + 24);
1678
2
  edt.eat_addr       = bfd_get_32 (abfd, data + 28);
1679
2
  edt.npt_addr       = bfd_get_32 (abfd, data + 32);
1680
2
  edt.ot_addr      = bfd_get_32 (abfd, data + 36);
1681
1682
2
  adj = section->vma - extra->ImageBase + dataoff;
1683
1684
  /* Dump the EDT first.  */
1685
2
  fprintf (file,
1686
2
     _("\nThe Export Tables (interpreted %s section contents)\n\n"),
1687
2
     section->name);
1688
1689
2
  fprintf (file,
1690
2
     _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
1691
1692
2
  fprintf (file,
1693
2
     _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
1694
1695
2
  fprintf (file,
1696
     /* xgettext:c-format */
1697
2
     _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
1698
1699
2
  fprintf (file,
1700
2
     _("Name \t\t\t\t"));
1701
2
  bfd_fprintf_vma (abfd, file, edt.name);
1702
1703
2
  if ((edt.name >= adj) && (edt.name < adj + datasize))
1704
1
    fprintf (file, " %.*s\n",
1705
1
       (int) (datasize - (edt.name - adj)),
1706
1
       data + edt.name - adj);
1707
1
  else
1708
1
    fprintf (file, "(outside .edata section)\n");
1709
1710
2
  fprintf (file,
1711
2
     _("Ordinal Base \t\t\t%ld\n"), edt.base);
1712
1713
2
  fprintf (file,
1714
2
     _("Number in:\n"));
1715
1716
2
  fprintf (file,
1717
2
     _("\tExport Address Table \t\t%08lx\n"),
1718
2
     edt.num_functions);
1719
1720
2
  fprintf (file,
1721
2
     _("\t[Name Pointer/Ordinal] Table\t%08lx\n"), edt.num_names);
1722
1723
2
  fprintf (file,
1724
2
     _("Table Addresses\n"));
1725
1726
2
  fprintf (file,
1727
2
     _("\tExport Address Table \t\t"));
1728
2
  bfd_fprintf_vma (abfd, file, edt.eat_addr);
1729
2
  fprintf (file, "\n");
1730
1731
2
  fprintf (file,
1732
2
     _("\tName Pointer Table \t\t"));
1733
2
  bfd_fprintf_vma (abfd, file, edt.npt_addr);
1734
2
  fprintf (file, "\n");
1735
1736
2
  fprintf (file,
1737
2
     _("\tOrdinal Table \t\t\t"));
1738
2
  bfd_fprintf_vma (abfd, file, edt.ot_addr);
1739
2
  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
2
  fprintf (file,
1751
2
    _("\nExport Address Table -- Ordinal Base %ld\n"),
1752
2
    edt.base);
1753
2
  fprintf (file, "\t          Ordinal  Address  Type\n");
1754
1755
  /* PR 17512: Handle corrupt PE binaries.  */
1756
  /* PR 17512 file: 140-165018-0.004.  */
1757
2
  if (edt.eat_addr - adj >= datasize
1758
      /* PR 17512: file: 092b1829 */
1759
1
      || (edt.num_functions + 1) * 4 < edt.num_functions
1760
1
      || edt.eat_addr - adj + (edt.num_functions + 1) * 4 > datasize)
1761
1
    fprintf (file, _("\tInvalid Export Address Table rva (0x%lx) or entry count (0x%lx)\n"),
1762
1
       (long) edt.eat_addr,
1763
1
       (long) edt.num_functions);
1764
57
  else for (i = 0; i < edt.num_functions; ++i)
1765
56
    {
1766
56
      bfd_vma eat_member = bfd_get_32 (abfd,
1767
56
               data + edt.eat_addr + (i * 4) - adj);
1768
56
      if (eat_member == 0)
1769
44
  continue;
1770
1771
12
      if (eat_member - adj <= datasize)
1772
1
  {
1773
    /* This rva is to a name (forwarding function) in our section.  */
1774
    /* Should locate a function descriptor.  */
1775
1
    fprintf (file,
1776
1
       "\t[%4ld] +base[%4ld] %08lx %s -- %.*s\n",
1777
1
       (long) i,
1778
1
       (long) (i + edt.base),
1779
1
       (unsigned long) eat_member,
1780
1
       _("Forwarder RVA"),
1781
1
       (int)(datasize - (eat_member - adj)),
1782
1
       data + eat_member - adj);
1783
1
  }
1784
11
      else
1785
11
  {
1786
    /* Should locate a function descriptor in the reldata section.  */
1787
11
    fprintf (file,
1788
11
       "\t[%4ld] +base[%4ld] %08lx %s\n",
1789
11
       (long) i,
1790
11
       (long) (i + edt.base),
1791
11
       (unsigned long) eat_member,
1792
11
       _("Export RVA"));
1793
11
  }
1794
12
    }
1795
1796
  /* The Export Name Pointer Table is paired with the Export Ordinal Table.  */
1797
  /* Dump them in parallel for clarity.  */
1798
2
  fprintf (file,
1799
2
     _("\n[Ordinal/Name Pointer] Table -- Ordinal Base %ld\n"),
1800
2
    edt.base);
1801
2
  fprintf (file, "\t          Ordinal   Hint Name\n");
1802
1803
  /* PR 17512: Handle corrupt PE binaries.  */
1804
2
  if (edt.npt_addr + (edt.num_names * 4) - adj >= datasize
1805
      /* PR 17512: file: bb68816e.  */
1806
1
      || edt.num_names * 4 < edt.num_names
1807
1
      || (data + edt.npt_addr - adj) < data)
1808
    /* xgettext:c-format */
1809
1
    fprintf (file, _("\tInvalid Name Pointer Table rva (0x%lx) or entry count (0x%lx)\n"),
1810
1
       (long) edt.npt_addr,
1811
1
       (long) edt.num_names);
1812
  /* PR 17512: file: 140-147171-0.004.  */
1813
1
  else if (edt.ot_addr + (edt.num_names * 2) - adj >= datasize
1814
0
     || data + edt.ot_addr - adj < data)
1815
    /* xgettext:c-format */
1816
1
    fprintf (file, _("\tInvalid Ordinal Table rva (0x%lx) or entry count (0x%lx)\n"),
1817
1
       (long) edt.ot_addr,
1818
1
       (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
2
  free (data);
1845
1846
2
  return true;
1847
2
}
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
263
{
1864
263
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64)
1865
1.05k
# define PDATA_ROW_SIZE (3 * 8)
1866
#else
1867
# define PDATA_ROW_SIZE (5 * 4)
1868
#endif
1869
263
  FILE *file = (FILE *) vfile;
1870
263
  bfd_byte *data = 0;
1871
263
  asection *section = bfd_get_section_by_name (abfd, ".pdata");
1872
263
  bfd_size_type datasize = 0;
1873
263
  bfd_size_type i;
1874
263
  bfd_size_type start, stop;
1875
263
  int onaline = PDATA_ROW_SIZE;
1876
1877
263
  if (section == NULL
1878
144
      || (section->flags & SEC_HAS_CONTENTS) == 0
1879
144
      || coff_section_data (abfd, section) == NULL
1880
144
      || pei_section_data (abfd, section) == NULL)
1881
119
    return true;
1882
1883
144
  stop = pei_section_data (abfd, section)->virt_size;
1884
144
  if ((stop % onaline) != 0)
1885
1
    fprintf (file,
1886
       /* xgettext:c-format */
1887
1
       _("warning, .pdata section size (%ld) is not a multiple of %d\n"),
1888
1
       (long) stop, onaline);
1889
1890
144
  fprintf (file,
1891
144
     _("\nThe Function Table (interpreted .pdata section contents)\n"));
1892
144
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64)
1893
144
  fprintf (file,
1894
144
     _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
1895
#else
1896
  fprintf (file, _("\
1897
 vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n\
1898
     \t\tAddress  Address  Handler  Data     Address    Mask\n"));
1899
#endif
1900
1901
144
  datasize = section->size;
1902
144
  if (datasize == 0)
1903
1
    return true;
1904
1905
  /* PR 17512: file: 002-193900-0.004.  */
1906
143
  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
143
  if (! bfd_malloc_and_get_section (abfd, section, &data))
1915
11
    {
1916
11
      free (data);
1917
11
      return false;
1918
11
    }
1919
1920
132
  start = 0;
1921
1922
902
  for (i = start; i < stop; i += onaline)
1923
791
    {
1924
791
      bfd_vma begin_addr;
1925
791
      bfd_vma end_addr;
1926
791
      bfd_vma eh_handler;
1927
791
      bfd_vma eh_data;
1928
791
      bfd_vma prolog_end_addr;
1929
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
1930
      int em_data;
1931
#endif
1932
1933
791
      if (i + PDATA_ROW_SIZE > stop)
1934
1
  break;
1935
1936
790
      begin_addr      = GET_PDATA_ENTRY (abfd, data + i      );
1937
790
      end_addr        = GET_PDATA_ENTRY (abfd, data + i +  4);
1938
790
      eh_handler      = GET_PDATA_ENTRY (abfd, data + i +  8);
1939
790
      eh_data       = GET_PDATA_ENTRY (abfd, data + i + 12);
1940
790
      prolog_end_addr = GET_PDATA_ENTRY (abfd, data + i + 16);
1941
1942
790
      if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1943
40
    && eh_data == 0 && prolog_end_addr == 0)
1944
  /* We are probably into the padding of the section now.  */
1945
20
  break;
1946
1947
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
1948
      em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
1949
#endif
1950
770
      eh_handler &= ~(bfd_vma) 0x3;
1951
770
      prolog_end_addr &= ~(bfd_vma) 0x3;
1952
1953
770
      fputc (' ', file);
1954
770
      bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
1955
770
      bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
1956
770
      bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
1957
770
      bfd_fprintf_vma (abfd, file, eh_handler);
1958
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
1959
      fputc (' ', file);
1960
      bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
1961
      bfd_fprintf_vma (abfd, file, prolog_end_addr);
1962
      fprintf (file, "   %x", em_data);
1963
#endif
1964
770
      fprintf (file, "\n");
1965
770
    }
1966
1967
132
  free (data);
1968
1969
132
  return true;
1970
143
#undef PDATA_ROW_SIZE
1971
143
}
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_pep_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
4.21k
#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
263
{
2177
263
  FILE *file = (FILE *) vfile;
2178
263
  bfd_byte *data = 0;
2179
263
  asection *section = bfd_get_section_by_name (abfd, ".reloc");
2180
263
  bfd_byte *p, *end;
2181
2182
263
  if (section == NULL
2183
37
      || section->size == 0
2184
37
      || (section->flags & SEC_HAS_CONTENTS) == 0)
2185
226
    return true;
2186
2187
37
  fprintf (file,
2188
37
     _("\n\nPE File Base Relocations (interpreted .reloc section contents)\n"));
2189
2190
37
  if (! bfd_malloc_and_get_section (abfd, section, &data))
2191
2
    {
2192
2
      free (data);
2193
2
      return false;
2194
2
    }
2195
2196
35
  p = data;
2197
35
  end = data + section->size;
2198
96
  while (p + 8 <= end)
2199
64
    {
2200
64
      int j;
2201
64
      bfd_vma virtual_address;
2202
64
      unsigned long number, size;
2203
64
      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
64
      virtual_address = bfd_get_32 (abfd, p);
2208
64
      size = bfd_get_32 (abfd, p + 4);
2209
64
      p += 8;
2210
64
      number = (size - 8) / 2;
2211
2212
64
      if (size == 0)
2213
3
  break;
2214
2215
61
      fprintf (file,
2216
         /* xgettext:c-format */
2217
61
         _("\nVirtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"),
2218
61
         (unsigned long) virtual_address, size, size, number);
2219
2220
61
      chunk_end = p - 8 + size;
2221
61
      if (chunk_end > end)
2222
32
  chunk_end = end;
2223
61
      j = 0;
2224
2.16k
      while (p + 2 <= chunk_end)
2225
2.10k
  {
2226
2.10k
    unsigned short e = bfd_get_16 (abfd, p);
2227
2.10k
    unsigned int t = (e & 0xF000) >> 12;
2228
2.10k
    int off = e & 0x0FFF;
2229
2230
2.10k
    if (t >= sizeof (tbl) / sizeof (tbl[0]))
2231
459
      t = (sizeof (tbl) / sizeof (tbl[0])) - 1;
2232
2233
2.10k
    fprintf (file,
2234
       /* xgettext:c-format */
2235
2.10k
       _("\treloc %4d offset %4x [%4lx] %s"),
2236
2.10k
       j, off, (unsigned long) (off + virtual_address), tbl[t]);
2237
2238
2.10k
    p += 2;
2239
2.10k
    j++;
2240
2241
    /* HIGHADJ takes an argument, - the next record *is* the
2242
       low 16 bits of addend.  */
2243
2.10k
    if (t == IMAGE_REL_BASED_HIGHADJ && p + 2 <= chunk_end)
2244
138
      {
2245
138
        fprintf (file, " (%4x)", (unsigned int) bfd_get_16 (abfd, p));
2246
138
        p += 2;
2247
138
        j++;
2248
138
      }
2249
2250
2.10k
    fprintf (file, "\n");
2251
2.10k
  }
2252
61
    }
2253
2254
35
  free (data);
2255
2256
35
  return true;
2257
37
}
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
87
{
2289
87
  unsigned long entry, addr, size;
2290
87
  bfd_byte * leaf;
2291
2292
87
  if (data + 8 >= regions->section_end)
2293
0
    return regions->section_end + 1;
2294
2295
  /* xgettext:c-format */
2296
87
  fprintf (file, _("%03x %*.s Entry: "), (int)(data - regions->section_start), indent, " ");
2297
2298
87
  entry = (unsigned long) bfd_get_32 (abfd, data);
2299
87
  if (is_name)
2300
64
    {
2301
64
      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
64
      if (HighBitSet (entry))
2307
18
  name = regions->section_start + WithoutHighBit (entry);
2308
46
      else
2309
46
  name = regions->section_start + entry - rva_bias;
2310
2311
64
      if (name + 2 < regions->section_end && name > regions->section_start)
2312
1
  {
2313
1
    unsigned int len;
2314
2315
1
    if (regions->strings_start == NULL)
2316
1
      regions->strings_start = name;
2317
2318
1
    len = bfd_get_16 (abfd, name);
2319
2320
1
    fprintf (file, _("name: [val: %08lx len %d]: "), entry, len);
2321
2322
1
    if (name + 2 + len * 2 < regions->section_end)
2323
1
      {
2324
        /* This strange loop is to cope with multibyte characters.  */
2325
1
        while (len --)
2326
0
    {
2327
0
      char c;
2328
2329
0
      name += 2;
2330
0
      c = * name;
2331
      /* Avoid printing control characters.  */
2332
0
      if (c > 0 && c < 32)
2333
0
        fprintf (file, "^%c", c + 64);
2334
0
      else
2335
0
        fprintf (file, "%.1s", name);
2336
0
    }
2337
1
      }
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
1
  }
2348
63
      else
2349
63
  {
2350
63
    fprintf (file, _("<corrupt string offset: %#lx>\n"), entry);
2351
63
    return regions->section_end + 1;
2352
63
  }
2353
64
    }
2354
23
  else
2355
23
    fprintf (file, _("ID: %#08lx"), entry);
2356
2357
24
  entry = (long) bfd_get_32 (abfd, data + 4);
2358
24
  fprintf (file, _(", Value: %#08lx\n"), entry);
2359
2360
24
  if (HighBitSet  (entry))
2361
4
    {
2362
4
      data = regions->section_start + WithoutHighBit (entry);
2363
4
      if (data <= regions->section_start || data > regions->section_end)
2364
4
  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
0
      return rsrc_print_resource_directory (file, abfd, indent + 1, data,
2369
0
              regions, rva_bias);
2370
4
    }
2371
2372
20
  leaf = regions->section_start + entry;
2373
2374
20
  if (leaf + 16 >= regions->section_end
2375
      /* PR 17512: file: 055dff7e.  */
2376
6
      || leaf < regions->section_start)
2377
14
    return regions->section_end + 1;
2378
2379
  /* xgettext:c-format */
2380
6
  fprintf (file, _("%03x %*.s  Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"),
2381
6
     (int) (entry), indent, " ",
2382
6
     addr = (long) bfd_get_32 (abfd, leaf),
2383
6
     size = (long) bfd_get_32 (abfd, leaf + 4),
2384
6
     (int) bfd_get_32 (abfd, leaf + 8));
2385
2386
  /* Check that the reserved entry is 0.  */
2387
6
  if (bfd_get_32 (abfd, leaf + 12) != 0
2388
      /* And that the data address/size is valid too.  */
2389
3
      || (regions->section_start + (addr - rva_bias) + size > regions->section_end))
2390
3
    return regions->section_end + 1;
2391
2392
3
  if (regions->resource_start == NULL)
2393
1
    regions->resource_start = regions->section_start + (addr - rva_bias);
2394
2395
3
  return regions->section_start + (addr - rva_bias) + size;
2396
6
}
2397
2398
181
#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
179
{
2409
179
  unsigned int num_names, num_ids;
2410
179
  bfd_byte * highest_data = data;
2411
2412
179
  if (data + 16 >= regions->section_end)
2413
1
    return regions->section_end + 1;
2414
2415
178
  fprintf (file, "%03x %*.s ", (int)(data - regions->section_start), indent, " ");
2416
178
  switch (indent)
2417
178
    {
2418
178
    case 0: fprintf (file, "Type"); break;
2419
0
    case 2: fprintf (file, "Name"); break;
2420
0
    case 4: fprintf (file, "Language"); break;
2421
0
    default:
2422
0
      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
0
      return regions->section_end + 1;
2427
178
    }
2428
2429
  /* xgettext:c-format */
2430
178
  fprintf (file, _(" Table: Char: %d, Time: %08lx, Ver: %d/%d, Num Names: %d, IDs: %d\n"),
2431
178
     (int) bfd_get_32 (abfd, data),
2432
178
     (long) bfd_get_32 (abfd, data + 4),
2433
178
     (int)  bfd_get_16 (abfd, data + 8),
2434
178
     (int)  bfd_get_16 (abfd, data + 10),
2435
178
     num_names = (int) bfd_get_16 (abfd, data + 12),
2436
178
     num_ids =   (int) bfd_get_16 (abfd, data + 14));
2437
178
  data += 16;
2438
2439
178
  while (num_names --)
2440
64
    {
2441
64
      bfd_byte * entry_end;
2442
2443
64
      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, true,
2444
64
                 data, regions, rva_bias);
2445
64
      data += 8;
2446
64
      highest_data = max (highest_data, entry_end);
2447
64
      if (entry_end >= regions->section_end)
2448
64
  return entry_end;
2449
64
    }
2450
2451
117
  while (num_ids --)
2452
23
    {
2453
23
      bfd_byte * entry_end;
2454
2455
23
      entry_end = rsrc_print_resource_entries (file, abfd, indent + 1, false,
2456
23
                 data, regions, rva_bias);
2457
23
      data += 8;
2458
23
      highest_data = max (highest_data, entry_end);
2459
23
      if (entry_end >= regions->section_end)
2460
20
  return entry_end;
2461
23
    }
2462
2463
94
  return max (highest_data, data);
2464
114
}
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
263
{
2473
263
  bfd_vma rva_bias;
2474
263
  pe_data_type * pe;
2475
263
  FILE * file = (FILE *) vfile;
2476
263
  bfd_size_type datasize;
2477
263
  asection * section;
2478
263
  bfd_byte * data;
2479
263
  rsrc_regions regions;
2480
2481
263
  pe = pe_data (abfd);
2482
263
  if (pe == NULL)
2483
0
    return true;
2484
2485
263
  section = bfd_get_section_by_name (abfd, ".rsrc");
2486
263
  if (section == NULL)
2487
120
    return true;
2488
143
  if (!(section->flags & SEC_HAS_CONTENTS))
2489
0
    return true;
2490
2491
143
  datasize = section->size;
2492
143
  if (datasize == 0)
2493
1
    return true;
2494
2495
142
  rva_bias = section->vma - pe->pe_opthdr.ImageBase;
2496
2497
142
  if (! bfd_malloc_and_get_section (abfd, section, & data))
2498
53
    {
2499
53
      free (data);
2500
53
      return false;
2501
53
    }
2502
2503
89
  regions.section_start = data;
2504
89
  regions.section_end = data + datasize;
2505
89
  regions.strings_start = NULL;
2506
89
  regions.resource_start = NULL;
2507
2508
89
  fflush (file);
2509
89
  fprintf (file, "\nThe .rsrc Resource Directory section:\n");
2510
2511
268
  while (data < regions.section_end)
2512
179
    {
2513
179
      bfd_byte * p = data;
2514
2515
179
      data = rsrc_print_resource_directory (file, abfd, 0, data, & regions, rva_bias);
2516
2517
179
      if (data == regions.section_end + 1)
2518
85
  fprintf (file, _("Corrupt .rsrc section detected!\n"));
2519
94
      else
2520
94
  {
2521
    /* Align data before continuing.  */
2522
94
    int align = (1 << section->alignment_power) - 1;
2523
2524
94
    data = (bfd_byte *) (((ptrdiff_t) (data + align)) & ~ align);
2525
94
    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
94
    if (data == (regions.section_end - 4))
2532
2
      data = regions.section_end;
2533
92
    else if (data < regions.section_end)
2534
91
      {
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
2.09k
        while (++ data < regions.section_end)
2539
2.09k
    if (*data != 0)
2540
90
      break;
2541
91
        if (data < regions.section_end)
2542
90
    fprintf (file, _("\nWARNING: Extra data in .rsrc section - it will be ignored by Windows:\n"));
2543
91
      }
2544
94
  }
2545
179
    }
2546
2547
89
  if (regions.strings_start != NULL)
2548
1
    fprintf (file, _(" String table starts at offset: %#03x\n"),
2549
1
       (int) (regions.strings_start - regions.section_start));
2550
89
  if (regions.resource_start != NULL)
2551
1
    fprintf (file, _(" Resources start at offset: %#03x\n"),
2552
1
       (int) (regions.resource_start - regions.section_start));
2553
2554
89
  free (regions.section_start);
2555
89
  return true;
2556
142
}
2557
2558
1.02k
#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
263
{
2584
263
  FILE *file = (FILE *) vfile;
2585
263
  pe_data_type *pe = pe_data (abfd);
2586
263
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
2587
263
  asection *section;
2588
263
  bfd_byte *data = 0;
2589
263
  bfd_size_type dataoff;
2590
263
  unsigned int i, j;
2591
2592
263
  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
2593
263
  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
2594
2595
263
  if (size == 0)
2596
183
    return true;
2597
2598
80
  addr += extra->ImageBase;
2599
666
  for (section = abfd->sections; section != NULL; section = section->next)
2600
593
    {
2601
593
      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
2602
7
  break;
2603
593
    }
2604
2605
80
  if (section == NULL)
2606
73
    {
2607
73
      fprintf (file,
2608
73
         _("\nThere is a debug directory, but the section containing it could not be found\n"));
2609
73
      return true;
2610
73
    }
2611
7
  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
7
  else if (section->size < size)
2619
0
    {
2620
0
      fprintf (file,
2621
0
         _("\nError: section %s contains the debug data starting address but it is too small\n"),
2622
0
         section->name);
2623
0
      return false;
2624
0
    }
2625
2626
7
  fprintf (file, _("\nThere is a debug directory in %s at 0x%lx\n\n"),
2627
7
     section->name, (unsigned long) addr);
2628
2629
7
  dataoff = addr - section->vma;
2630
2631
7
  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
7
  fprintf (file,
2638
7
     _("Type                Size     Rva      Offset\n"));
2639
2640
  /* Read the whole section.  */
2641
7
  if (!bfd_malloc_and_get_section (abfd, section, &data))
2642
0
    {
2643
0
      free (data);
2644
0
      return false;
2645
0
    }
2646
2647
1.02k
  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
2648
1.02k
    {
2649
1.02k
      const char *type_name;
2650
1.02k
      struct external_IMAGE_DEBUG_DIRECTORY *ext
2651
1.02k
  = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
2652
1.02k
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
2653
2654
1.02k
      _bfd_pepi_swap_debugdir_in (abfd, ext, &idd);
2655
2656
1.02k
      if ((idd.Type) >= IMAGE_NUMBEROF_DEBUG_TYPES)
2657
686
  type_name = debug_type_names[0];
2658
336
      else
2659
336
  type_name = debug_type_names[idd.Type];
2660
2661
1.02k
      fprintf (file, " %2ld  %14s %08lx %08lx %08lx\n",
2662
1.02k
         idd.Type, type_name, idd.SizeOfData,
2663
1.02k
         idd.AddressOfRawData, idd.PointerToRawData);
2664
2665
1.02k
      if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
2666
18
  {
2667
18
    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
18
    char buffer[256 + 1] ATTRIBUTE_ALIGNED_ALIGNOF (CODEVIEW_INFO);
2672
18
    char *pdb;
2673
2674
18
    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
18
    if (!_bfd_pepi_slurp_codeview_record (abfd, (file_ptr) idd.PointerToRawData,
2679
18
                 idd.SizeOfData, cvinfo, &pdb))
2680
18
      continue;
2681
2682
0
    for (j = 0; j < cvinfo->SignatureLength; j++)
2683
0
      sprintf (&signature[j*2], "%02x", cvinfo->Signature[j] & 0xff);
2684
2685
    /* xgettext:c-format */
2686
0
    fprintf (file, _("(format %c%c%c%c signature %s age %ld pdb %s)\n"),
2687
0
       buffer[0], buffer[1], buffer[2], buffer[3],
2688
0
       signature, cvinfo->Age, pdb[0] ? pdb : "(none)");
2689
2690
0
    free (pdb);
2691
0
  }
2692
1.02k
    }
2693
2694
7
  free(data);
2695
2696
7
  if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0)
2697
7
    fprintf (file,
2698
7
      _("The debug directory size is not a multiple of the debug directory entry size\n"));
2699
2700
7
  return true;
2701
7
}
2702
2703
static bool
2704
pe_is_repro (bfd * abfd)
2705
263
{
2706
263
  pe_data_type *pe = pe_data (abfd);
2707
263
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
2708
263
  asection *section;
2709
263
  bfd_byte *data = 0;
2710
263
  bfd_size_type dataoff;
2711
263
  unsigned int i;
2712
263
  bool res = false;
2713
2714
263
  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
2715
263
  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
2716
2717
263
  if (size == 0)
2718
183
    return false;
2719
2720
80
  addr += extra->ImageBase;
2721
666
  for (section = abfd->sections; section != NULL; section = section->next)
2722
593
    {
2723
593
      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
2724
7
  break;
2725
593
    }
2726
2727
80
  if ((section == NULL)
2728
7
      || (!(section->flags & SEC_HAS_CONTENTS))
2729
7
      || (section->size < size))
2730
73
    {
2731
73
      return false;
2732
73
    }
2733
2734
7
  dataoff = addr - section->vma;
2735
2736
7
  if (size > (section->size - dataoff))
2737
0
    {
2738
0
      return false;
2739
0
    }
2740
2741
7
  if (!bfd_malloc_and_get_section (abfd, section, &data))
2742
0
    {
2743
0
      free (data);
2744
0
      return false;
2745
0
    }
2746
2747
863
  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
2748
858
    {
2749
858
      struct external_IMAGE_DEBUG_DIRECTORY *ext
2750
858
  = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
2751
858
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
2752
2753
858
      _bfd_pepi_swap_debugdir_in (abfd, ext, &idd);
2754
2755
858
      if (idd.Type == PE_IMAGE_DEBUG_TYPE_REPRO)
2756
2
        {
2757
2
          res = true;
2758
2
          break;
2759
2
        }
2760
858
    }
2761
2762
7
  free(data);
2763
2764
7
  return res;
2765
7
}
2766
2767
/* Print out the program headers.  */
2768
2769
bool
2770
_bfd_pep_print_private_bfd_data_common (bfd * abfd, void * vfile)
2771
263
{
2772
263
  FILE *file = (FILE *) vfile;
2773
263
  int j;
2774
263
  pe_data_type *pe = pe_data (abfd);
2775
263
  struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
2776
263
  const char *subsystem_name = NULL;
2777
263
  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
263
  fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
2783
263
#undef PF
2784
3.68k
#define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
2785
263
  PF (IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
2786
263
  PF (IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
2787
263
  PF (IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
2788
263
  PF (IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
2789
263
  PF (IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
2790
263
  PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
2791
263
  PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
2792
263
  PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
2793
263
  PF (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, "copy to swap file if on removable media");
2794
263
  PF (IMAGE_FILE_NET_RUN_FROM_SWAP, "copy to swap file if on network media");
2795
263
  PF (IMAGE_FILE_SYSTEM, "system file");
2796
263
  PF (IMAGE_FILE_DLL, "DLL");
2797
263
  PF (IMAGE_FILE_UP_SYSTEM_ONLY, "run only on uniprocessor machine");
2798
263
  PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
2799
263
#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
263
  if (pe_is_repro (abfd))
2806
2
    {
2807
2
      fprintf (file, "\nTime/Date\t\t%08lx", pe->coff.timestamp);
2808
2
      fprintf (file, "\t(This is a reproducible build file hash, not a timestamp)\n");
2809
2
    }
2810
261
  else
2811
261
    {
2812
      /* ctime implies '\n'.  */
2813
261
      time_t t = pe->coff.timestamp;
2814
261
      fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
2815
261
    }
2816
2817
263
#ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
2818
263
# define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
2819
263
#endif
2820
263
#ifndef IMAGE_NT_OPTIONAL_HDR64_MAGIC
2821
263
# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
2822
263
#endif
2823
263
#ifndef IMAGE_NT_OPTIONAL_HDRROM_MAGIC
2824
263
# define IMAGE_NT_OPTIONAL_HDRROM_MAGIC 0x107
2825
263
#endif
2826
2827
263
  switch (i->Magic)
2828
263
    {
2829
27
    case IMAGE_NT_OPTIONAL_HDR_MAGIC:
2830
27
      name = "PE32";
2831
27
      break;
2832
0
    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
2833
0
      name = "PE32+";
2834
0
      break;
2835
0
    case IMAGE_NT_OPTIONAL_HDRROM_MAGIC:
2836
0
      name = "ROM";
2837
0
      break;
2838
236
    default:
2839
236
      name = NULL;
2840
236
      break;
2841
263
    }
2842
263
  fprintf (file, "Magic\t\t\t%04x", i->Magic);
2843
263
  if (name)
2844
27
    fprintf (file, "\t(%s)",name);
2845
263
  fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
2846
263
  fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
2847
263
  fprintf (file, "SizeOfCode\t\t");
2848
263
  bfd_fprintf_vma (abfd, file, i->SizeOfCode);
2849
263
  fprintf (file, "\nSizeOfInitializedData\t");
2850
263
  bfd_fprintf_vma (abfd, file, i->SizeOfInitializedData);
2851
263
  fprintf (file, "\nSizeOfUninitializedData\t");
2852
263
  bfd_fprintf_vma (abfd, file, i->SizeOfUninitializedData);
2853
263
  fprintf (file, "\nAddressOfEntryPoint\t");
2854
263
  bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
2855
263
  fprintf (file, "\nBaseOfCode\t\t");
2856
263
  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
263
  fprintf (file, "\nImageBase\t\t");
2864
263
  bfd_fprintf_vma (abfd, file, i->ImageBase);
2865
263
  fprintf (file, "\nSectionAlignment\t%08x\n", i->SectionAlignment);
2866
263
  fprintf (file, "FileAlignment\t\t%08x\n", i->FileAlignment);
2867
263
  fprintf (file, "MajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
2868
263
  fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
2869
263
  fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
2870
263
  fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
2871
263
  fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
2872
263
  fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
2873
263
  fprintf (file, "Win32Version\t\t%08x\n", i->Win32Version);
2874
263
  fprintf (file, "SizeOfImage\t\t%08x\n", i->SizeOfImage);
2875
263
  fprintf (file, "SizeOfHeaders\t\t%08x\n", i->SizeOfHeaders);
2876
263
  fprintf (file, "CheckSum\t\t%08x\n", i->CheckSum);
2877
2878
263
  switch (i->Subsystem)
2879
263
    {
2880
59
    case IMAGE_SUBSYSTEM_UNKNOWN:
2881
59
      subsystem_name = "unspecified";
2882
59
      break;
2883
0
    case IMAGE_SUBSYSTEM_NATIVE:
2884
0
      subsystem_name = "NT native";
2885
0
      break;
2886
79
    case IMAGE_SUBSYSTEM_WINDOWS_GUI:
2887
79
      subsystem_name = "Windows GUI";
2888
79
      break;
2889
29
    case IMAGE_SUBSYSTEM_WINDOWS_CUI:
2890
29
      subsystem_name = "Windows CUI";
2891
29
      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
96
    default:
2917
96
      subsystem_name = NULL;
2918
263
    }
2919
2920
263
  fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
2921
263
  if (subsystem_name)
2922
167
    fprintf (file, "\t(%s)", subsystem_name);
2923
263
  fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
2924
263
  if (i->DllCharacteristics)
2925
191
    {
2926
191
      unsigned short dllch = i->DllCharacteristics;
2927
191
      const char *indent = "\t\t\t\t\t";
2928
2929
191
      if (dllch & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA)
2930
18
  fprintf (file, "%sHIGH_ENTROPY_VA\n", indent);
2931
191
      if (dllch & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)
2932
128
  fprintf (file, "%sDYNAMIC_BASE\n", indent);
2933
191
      if (dllch & IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY)
2934
55
  fprintf (file, "%sFORCE_INTEGRITY\n", indent);
2935
191
      if (dllch & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
2936
134
  fprintf (file, "%sNX_COMPAT\n", indent);
2937
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)
2938
63
  fprintf (file, "%sNO_ISOLATION\n", indent);
2939
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_SEH)
2940
75
  fprintf (file, "%sNO_SEH\n", indent);
2941
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_BIND)
2942
42
  fprintf (file, "%sNO_BIND\n", indent);
2943
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_APPCONTAINER)
2944
61
  fprintf (file, "%sAPPCONTAINER\n", indent);
2945
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)
2946
26
  fprintf (file, "%sWDM_DRIVER\n", indent);
2947
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_GUARD_CF)
2948
39
  fprintf (file, "%sGUARD_CF\n", indent);
2949
191
      if (dllch & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)
2950
170
  fprintf (file, "%sTERMINAL_SERVICE_AWARE\n", indent);
2951
191
    }
2952
263
  fprintf (file, "SizeOfStackReserve\t");
2953
263
  bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
2954
263
  fprintf (file, "\nSizeOfStackCommit\t");
2955
263
  bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
2956
263
  fprintf (file, "\nSizeOfHeapReserve\t");
2957
263
  bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
2958
263
  fprintf (file, "\nSizeOfHeapCommit\t");
2959
263
  bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
2960
263
  fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
2961
263
  fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
2962
263
     (unsigned long) i->NumberOfRvaAndSizes);
2963
2964
263
  fprintf (file, "\nThe Data Directory\n");
2965
4.47k
  for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
2966
4.20k
    {
2967
4.20k
      fprintf (file, "Entry %1x ", j);
2968
4.20k
      bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
2969
4.20k
      fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
2970
4.20k
      fprintf (file, "%s\n", dir_names[j]);
2971
4.20k
    }
2972
2973
263
  pe_print_idata (abfd, vfile);
2974
263
  pe_print_edata (abfd, vfile);
2975
263
  if (bfd_coff_have_print_pdata (abfd))
2976
0
    bfd_coff_print_pdata (abfd, vfile);
2977
263
  else
2978
263
    pe_print_pdata (abfd, vfile);
2979
263
  pe_print_reloc (abfd, vfile);
2980
263
  pe_print_debugdata (abfd, file);
2981
2982
263
  rsrc_print_section (abfd, vfile);
2983
2984
263
  return true;
2985
263
}
2986
2987
static bool
2988
is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
2989
123
{
2990
123
  bfd_vma addr = * (bfd_vma *) obj;
2991
123
  return (addr >= sect->vma) && (addr < (sect->vma + sect->size));
2992
123
}
2993
2994
static asection *
2995
find_section_by_vma (bfd *abfd, bfd_vma addr)
2996
87
{
2997
87
  return bfd_sections_find_if (abfd, is_vma_in_section, (void *) & addr);
2998
87
}
2999
3000
/* Copy any private info we understand from the input bfd
3001
   to the output bfd.  */
3002
3003
bool
3004
_bfd_pep_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
3005
83
{
3006
83
  pe_data_type *ipe, *ope;
3007
83
  bfd_size_type size;
3008
3009
  /* One day we may try to grok other private data.  */
3010
83
  if (ibfd->xvec->flavour != bfd_target_coff_flavour)
3011
0
    return true;
3012
3013
83
  ipe = pe_data (ibfd);
3014
83
  ope = pe_data (obfd);
3015
3016
  /* pe_opthdr is copied in copy_object.  */
3017
83
  ope->dll = ipe->dll;
3018
3019
  /* Don't copy input subsystem if output is different from input.  */
3020
83
  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
83
  if (! pe_data (obfd)->has_reloc_section)
3026
83
    {
3027
83
      pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
3028
83
      pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
3029
83
    }
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
83
  if (! pe_data (ibfd)->has_reloc_section
3035
83
      && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
3036
46
    pe_data (obfd)->dont_strip_reloc = 1;
3037
3038
83
  memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
3039
3040
  /* The file offsets contained in the debug directory need rewriting.  */
3041
83
  size = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size;
3042
83
  if (size != 0)
3043
48
    {
3044
48
      bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
3045
48
  + 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
48
      bfd_vma last = addr + size - 1;
3052
48
      asection *section = find_section_by_vma (obfd, last);
3053
3054
48
      if (section != NULL)
3055
14
  {
3056
14
    bfd_byte *data;
3057
14
    bfd_vma dataoff = addr - section->vma;
3058
3059
    /* PR 17512: file: 0f15796a.  */
3060
14
    if (addr < section->vma
3061
14
        || section->size < dataoff
3062
14
        || 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
14
    if ((section->flags & SEC_HAS_CONTENTS) != 0
3074
12
        && bfd_malloc_and_get_section (obfd, section, &data))
3075
12
      {
3076
12
        unsigned int i;
3077
12
        struct external_IMAGE_DEBUG_DIRECTORY *dd =
3078
12
    (struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff);
3079
3080
72
        for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
3081
72
         / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
3082
60
    {
3083
60
      asection *ddsection;
3084
60
      struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
3085
60
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
3086
60
      bfd_vma idd_vma;
3087
3088
60
      _bfd_pepi_swap_debugdir_in (obfd, edd, &idd);
3089
3090
      /* RVA 0 means only offset is valid, not handled yet.  */
3091
60
      if (idd.AddressOfRawData == 0)
3092
21
        continue;
3093
3094
39
      idd_vma = idd.AddressOfRawData + ope->pe_opthdr.ImageBase;
3095
39
      ddsection = find_section_by_vma (obfd, idd_vma);
3096
39
      if (!ddsection)
3097
34
        continue; /* Not in a section! */
3098
3099
5
      idd.PointerToRawData
3100
5
        = ddsection->filepos + idd_vma - ddsection->vma;
3101
5
      _bfd_pepi_swap_debugdir_out (obfd, &idd, edd);
3102
5
    }
3103
3104
12
        if (!bfd_set_section_contents (obfd, section, data, 0,
3105
12
               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
12
        free (data);
3113
12
      }
3114
2
    else
3115
2
      {
3116
2
        _bfd_error_handler (_("%pB: failed to read "
3117
2
            "debug data section"), obfd);
3118
2
        return false;
3119
2
      }
3120
14
  }
3121
48
    }
3122
3123
81
  return true;
3124
83
}
3125
3126
/* Copy private section data.  */
3127
3128
bool
3129
_bfd_pep_bfd_copy_private_section_data (bfd *ibfd,
3130
               asection *isec,
3131
               bfd *obfd,
3132
               asection *osec,
3133
               struct bfd_link_info *link_info)
3134
151
{
3135
151
  if (link_info != NULL
3136
151
      || bfd_get_flavour (ibfd) != bfd_target_coff_flavour)
3137
0
    return true;
3138
3139
151
  if (coff_section_data (ibfd, isec) != NULL
3140
149
      && pei_section_data (ibfd, isec) != NULL)
3141
149
    {
3142
149
      if (coff_section_data (obfd, osec) == NULL)
3143
149
  {
3144
149
    size_t amt = sizeof (struct coff_section_tdata);
3145
149
    osec->used_by_bfd = bfd_zalloc (obfd, amt);
3146
149
    if (osec->used_by_bfd == NULL)
3147
0
      return false;
3148
149
  }
3149
3150
149
      if (pei_section_data (obfd, osec) == NULL)
3151
149
  {
3152
149
    size_t amt = sizeof (struct pei_section_tdata);
3153
149
    coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
3154
149
    if (coff_section_data (obfd, osec)->tdata == NULL)
3155
0
      return false;
3156
149
  }
3157
3158
149
      pei_section_data (obfd, osec)->virt_size =
3159
149
  pei_section_data (ibfd, isec)->virt_size;
3160
149
      pei_section_data (obfd, osec)->pe_flags =
3161
149
  pei_section_data (ibfd, isec)->pe_flags;
3162
149
    }
3163
3164
151
  return true;
3165
151
}
3166
3167
void
3168
_bfd_pep_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
3169
296
{
3170
296
  coff_get_symbol_info (abfd, symbol, ret);
3171
296
}
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
{
3177
  const char *lp = (const char *) l;
3178
  const char *rp = (const char *) r;
3179
  bfd_vma vl, vr;
3180
  vl = bfd_getl32 (lp); vr = bfd_getl32 (rp);
3181
  if (vl != vr)
3182
    return (vl < vr ? -1 : 1);
3183
  /* We compare just begin address.  */
3184
  return 0;
3185
}
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_pepi_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
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64))
4720
  {
4721
    asection *sec = bfd_get_section_by_name (abfd, ".pdata");
4722
4723
    if (sec)
4724
      {
4725
  bfd_size_type x = sec->rawsize;
4726
  bfd_byte *tmp_data;
4727
4728
  if (bfd_malloc_and_get_section (abfd, sec, &tmp_data))
4729
    {
4730
      /* The size of a .pdata entry that describes a function that is used
4731
         for exception handling.  */
4732
      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
      function_table_entry_size = 12;
4739
#endif
4740
      /* .pdata entries should be sorted by the function start
4741
         address.  */
4742
      qsort (tmp_data,
4743
       (size_t) (x / function_table_entry_size),
4744
       function_table_entry_size, sort_pdata);
4745
      bfd_set_section_contents (pfinfo->output_bfd, sec,
4746
              tmp_data, 0, x);
4747
      free (tmp_data);
4748
    }
4749
  else
4750
    result = false;
4751
      }
4752
  }
4753
#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
}