Coverage Report

Created: 2026-07-12 09:22

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