Coverage Report

Created: 2024-05-21 06:29

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