Coverage Report

Created: 2025-06-24 06:45

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