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-loongarch64igen.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_peLoongArch64
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
76
# define AOUTSZ   PEPAOUTSZ
106
3.48k
# define PEAOUTHDR  PEPAOUTHDR
107
#endif
108
109
24
#define HighBitSet(val)      ((val) & 0x80000000)
110
#define SetHighBit(val)      ((val) | 0x80000000)
111
0
#define WithoutHighBit(val)  ((val) & 0x7fffffff)
112

113
void
114
_bfd_peLoongArch64i_swap_sym_in (bfd * abfd, void * ext1, void * in1)
115
50.3k
{
116
50.3k
  SYMENT *ext = (SYMENT *) ext1;
117
50.3k
  struct internal_syment *in = (struct internal_syment *) in1;
118
119
50.3k
  if (ext->e.e_name[0] == 0)
120
30.2k
    {
121
30.2k
      in->_n._n_n._n_zeroes = 0;
122
30.2k
      in->_n._n_n._n_offset = H_GET_32 (abfd, ext->e.e.e_offset);
123
30.2k
    }
124
20.1k
  else
125
20.1k
    memcpy (in->_n._n_name, ext->e.e_name, SYMNMLEN);
126
127
50.3k
  in->n_value = H_GET_32 (abfd, ext->e_value);
128
50.3k
  in->n_scnum = (short) H_GET_16 (abfd, ext->e_scnum);
129
130
50.3k
  if (sizeof (ext->e_type) == 2)
131
50.3k
    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
50.3k
  in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
136
50.3k
  in->n_numaux = H_GET_8 (abfd, ext->e_numaux);
137
138
50.3k
#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
50.3k
  if (in->n_sclass == C_SECTION)
148
3.75k
    {
149
3.75k
      char namebuf[SYMNMLEN + 1];
150
3.75k
      const char *name = NULL;
151
152
3.75k
      in->n_value = 0x0;
153
154
      /* Create synthetic empty sections as needed.  DJ */
155
3.75k
      if (in->n_scnum == 0)
156
2.61k
  {
157
2.61k
    asection *sec;
158
159
2.61k
    name = _bfd_coff_internal_syment_name (abfd, in, namebuf);
160
2.61k
    if (name == NULL)
161
720
      {
162
720
        _bfd_error_handler (_("%pB: unable to find name for empty section"),
163
720
          abfd);
164
720
        bfd_set_error (bfd_error_invalid_target);
165
720
        return;
166
720
      }
167
168
1.89k
    sec = bfd_get_section_by_name (abfd, name);
169
1.89k
    if (sec != NULL)
170
870
      in->n_scnum = sec->target_index;
171
1.89k
  }
172
173
3.03k
      if (in->n_scnum == 0)
174
1.02k
  {
175
1.02k
    int unused_section_number = 0;
176
1.02k
    asection *sec;
177
1.02k
    flagword flags;
178
1.02k
    size_t name_len;
179
1.02k
    char *sec_name;
180
181
5.62k
    for (sec = abfd->sections; sec; sec = sec->next)
182
4.60k
      if (unused_section_number <= sec->target_index)
183
4.60k
        unused_section_number = sec->target_index + 1;
184
185
1.02k
    name_len = strlen (name) + 1;
186
1.02k
    sec_name = bfd_alloc (abfd, name_len);
187
1.02k
    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.02k
    memcpy (sec_name, name, name_len);
194
195
1.02k
    flags = (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD
196
1.02k
       | SEC_LINKER_CREATED);
197
1.02k
    sec = bfd_make_section_anyway_with_flags (abfd, sec_name, flags);
198
1.02k
    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.02k
    sec->alignment_power = 2;
206
1.02k
    sec->target_index = unused_section_number;
207
208
1.02k
    in->n_scnum = unused_section_number;
209
1.02k
  }
210
3.03k
      in->n_sclass = C_STAT;
211
3.03k
    }
212
50.3k
#endif
213
50.3k
}
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_peLoongArch64i_swap_sym_out (bfd * abfd, void * inp, void * extp)
225
211
{
226
211
  struct internal_syment *in = (struct internal_syment *) inp;
227
211
  SYMENT *ext = (SYMENT *) extp;
228
229
211
  if (in->_n._n_name[0] == 0)
230
123
    {
231
123
      H_PUT_32 (abfd, 0, ext->e.e.e_zeroes);
232
123
      H_PUT_32 (abfd, in->_n._n_n._n_offset, ext->e.e.e_offset);
233
123
    }
234
88
  else
235
88
    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
211
  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
211
      && 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
211
  H_PUT_32 (abfd, in->n_value, ext->e_value);
266
211
  H_PUT_16 (abfd, in->n_scnum, ext->e_scnum);
267
268
211
  if (sizeof (ext->e_type) == 2)
269
211
    H_PUT_16 (abfd, in->n_type, ext->e_type);
270
0
  else
271
211
    H_PUT_32 (abfd, in->n_type, ext->e_type);
272
273
211
  H_PUT_8 (abfd, in->n_sclass, ext->e_sclass);
274
211
  H_PUT_8 (abfd, in->n_numaux, ext->e_numaux);
275
276
211
  return SYMESZ;
277
211
}
278
279
void
280
_bfd_peLoongArch64i_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
57.5k
{
288
57.5k
  AUXENT *ext = (AUXENT *) ext1;
289
57.5k
  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
57.5k
  memset (in, 0, sizeof (*in));
294
57.5k
  switch (in_class)
295
57.5k
    {
296
4.07k
    case C_FILE:
297
4.07k
      if (ext->x_file.x_fname[0] == 0)
298
1.93k
  {
299
1.93k
    in->x_file.x_n.x_n.x_zeroes = 0;
300
1.93k
    in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
301
1.93k
  }
302
2.14k
      else
303
#if FILNMLEN != E_FILNMLEN
304
#error we need to cope with truncating or extending x_fname
305
#endif
306
2.14k
  memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
307
4.07k
      return;
308
309
3.54k
    case C_STAT:
310
4.73k
    case C_LEAFSTAT:
311
6.05k
    case C_HIDDEN:
312
6.05k
      if (type == T_NULL)
313
1.68k
  {
314
1.68k
    in->x_scn.x_scnlen = GET_SCN_SCNLEN (abfd, ext);
315
1.68k
    in->x_scn.x_nreloc = GET_SCN_NRELOC (abfd, ext);
316
1.68k
    in->x_scn.x_nlinno = GET_SCN_NLINNO (abfd, ext);
317
1.68k
    in->x_scn.x_checksum = H_GET_32 (abfd, ext->x_scn.x_checksum);
318
1.68k
    in->x_scn.x_associated = H_GET_16 (abfd, ext->x_scn.x_associated);
319
1.68k
    in->x_scn.x_comdat = H_GET_8 (abfd, ext->x_scn.x_comdat);
320
1.68k
    return;
321
1.68k
  }
322
4.36k
      break;
323
57.5k
    }
324
325
51.7k
  in->x_sym.x_tagndx.u32 = H_GET_32 (abfd, ext->x_sym.x_tagndx);
326
51.7k
  in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx);
327
328
51.7k
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
329
41.0k
      || ISTAG (in_class))
330
15.9k
    {
331
15.9k
      in->x_sym.x_fcnary.x_fcn.x_lnnoptr = GET_FCN_LNNOPTR (abfd, ext);
332
15.9k
      in->x_sym.x_fcnary.x_fcn.x_endndx.u32 = GET_FCN_ENDNDX (abfd, ext);
333
15.9k
    }
334
35.8k
  else
335
35.8k
    {
336
35.8k
      in->x_sym.x_fcnary.x_ary.x_dimen[0] =
337
35.8k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
338
35.8k
      in->x_sym.x_fcnary.x_ary.x_dimen[1] =
339
35.8k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
340
35.8k
      in->x_sym.x_fcnary.x_ary.x_dimen[2] =
341
35.8k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
342
35.8k
      in->x_sym.x_fcnary.x_ary.x_dimen[3] =
343
35.8k
  H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
344
35.8k
    }
345
346
51.7k
  if (ISFCN (type))
347
9.11k
    {
348
9.11k
      in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize);
349
9.11k
    }
350
42.6k
  else
351
42.6k
    {
352
42.6k
      in->x_sym.x_misc.x_lnsz.x_lnno = GET_LNSZ_LNNO (abfd, ext);
353
42.6k
      in->x_sym.x_misc.x_lnsz.x_size = GET_LNSZ_SIZE (abfd, ext);
354
42.6k
    }
355
51.7k
}
356
357
unsigned int
358
_bfd_peLoongArch64i_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
132
{
366
132
  union internal_auxent *in = (union internal_auxent *) inp;
367
132
  AUXENT *ext = (AUXENT *) extp;
368
369
132
  memset (ext, 0, AUXESZ);
370
371
132
  switch (in_class)
372
132
    {
373
23
    case C_FILE:
374
23
      if (in->x_file.x_n.x_fname[0] == 0)
375
12
  {
376
12
    H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
377
12
    H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset);
378
12
  }
379
11
      else
380
#if FILNMLEN != E_FILNMLEN
381
#error we need to cope with truncating or extending x_fname
382
#endif
383
11
  memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, E_FILNMLEN);
384
385
23
      return AUXESZ;
386
387
46
    case C_STAT:
388
46
    case C_LEAFSTAT:
389
56
    case C_HIDDEN:
390
56
      if (type == T_NULL)
391
9
  {
392
9
    PUT_SCN_SCNLEN (abfd, in->x_scn.x_scnlen, ext);
393
9
    PUT_SCN_NRELOC (abfd, in->x_scn.x_nreloc, ext);
394
9
    PUT_SCN_NLINNO (abfd, in->x_scn.x_nlinno, ext);
395
9
    H_PUT_32 (abfd, in->x_scn.x_checksum, ext->x_scn.x_checksum);
396
9
    H_PUT_16 (abfd, in->x_scn.x_associated, ext->x_scn.x_associated);
397
9
    H_PUT_8 (abfd, in->x_scn.x_comdat, ext->x_scn.x_comdat);
398
9
    return AUXESZ;
399
9
  }
400
47
      break;
401
132
    }
402
403
100
  H_PUT_32 (abfd, in->x_sym.x_tagndx.u32, ext->x_sym.x_tagndx);
404
100
  H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx);
405
406
100
  if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
407
72
      || ISTAG (in_class))
408
41
    {
409
41
      PUT_FCN_LNNOPTR (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr,  ext);
410
41
      PUT_FCN_ENDNDX  (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.u32, ext);
411
41
    }
412
59
  else
413
59
    {
414
59
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0],
415
59
    ext->x_sym.x_fcnary.x_ary.x_dimen[0]);
416
59
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1],
417
59
    ext->x_sym.x_fcnary.x_ary.x_dimen[1]);
418
59
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2],
419
59
    ext->x_sym.x_fcnary.x_ary.x_dimen[2]);
420
59
      H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3],
421
59
    ext->x_sym.x_fcnary.x_ary.x_dimen[3]);
422
59
    }
423
424
100
  if (ISFCN (type))
425
100
    H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize);
426
88
  else
427
88
    {
428
88
      PUT_LNSZ_LNNO (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext);
429
88
      PUT_LNSZ_SIZE (abfd, in->x_sym.x_misc.x_lnsz.x_size, ext);
430
88
    }
431
432
100
  return AUXESZ;
433
132
}
434
435
void
436
_bfd_peLoongArch64i_swap_lineno_in (bfd * abfd, void * ext1, void * in1)
437
49.6k
{
438
49.6k
  LINENO *ext = (LINENO *) ext1;
439
49.6k
  struct internal_lineno *in = (struct internal_lineno *) in1;
440
441
49.6k
  in->l_addr.l_symndx = H_GET_32 (abfd, ext->l_addr.l_symndx);
442
49.6k
  in->l_lnno = GET_LINENO_LNNO (abfd, ext);
443
49.6k
}
444
445
unsigned int
446
_bfd_peLoongArch64i_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_peLoongArch64i_swap_aouthdr_in (bfd * abfd,
458
        void * aouthdr_ext1,
459
        void * aouthdr_int1)
460
3.41k
{
461
3.41k
  PEAOUTHDR * src = (PEAOUTHDR *) aouthdr_ext1;
462
3.41k
  AOUTHDR * aouthdr_ext = (AOUTHDR *) aouthdr_ext1;
463
3.41k
  struct internal_aouthdr *aouthdr_int
464
3.41k
    = (struct internal_aouthdr *) aouthdr_int1;
465
3.41k
  struct internal_extra_pe_aouthdr *a = &aouthdr_int->pe;
466
467
3.41k
  aouthdr_int->magic = H_GET_16 (abfd, aouthdr_ext->magic);
468
3.41k
  aouthdr_int->vstamp = H_GET_16 (abfd, aouthdr_ext->vstamp);
469
3.41k
  aouthdr_int->tsize = GET_AOUTHDR_TSIZE (abfd, aouthdr_ext->tsize);
470
3.41k
  aouthdr_int->dsize = GET_AOUTHDR_DSIZE (abfd, aouthdr_ext->dsize);
471
3.41k
  aouthdr_int->bsize = GET_AOUTHDR_BSIZE (abfd, aouthdr_ext->bsize);
472
3.41k
  aouthdr_int->entry = GET_AOUTHDR_ENTRY (abfd, aouthdr_ext->entry);
473
3.41k
  aouthdr_int->text_start =
474
3.41k
    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.41k
  a->Magic = aouthdr_int->magic;
484
3.41k
  a->MajorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp);
485
3.41k
  a->MinorLinkerVersion = H_GET_8 (abfd, aouthdr_ext->vstamp + 1);
486
3.41k
  a->SizeOfCode = aouthdr_int->tsize ;
487
3.41k
  a->SizeOfInitializedData = aouthdr_int->dsize ;
488
3.41k
  a->SizeOfUninitializedData = aouthdr_int->bsize ;
489
3.41k
  a->AddressOfEntryPoint = aouthdr_int->entry;
490
3.41k
  a->BaseOfCode = aouthdr_int->text_start;
491
3.41k
  a->ImageBase = GET_OPTHDR_IMAGE_BASE (abfd, src->ImageBase);
492
3.41k
  a->SectionAlignment = H_GET_32 (abfd, src->SectionAlignment);
493
3.41k
  a->FileAlignment = H_GET_32 (abfd, src->FileAlignment);
494
3.41k
  a->MajorOperatingSystemVersion =
495
3.41k
    H_GET_16 (abfd, src->MajorOperatingSystemVersion);
496
3.41k
  a->MinorOperatingSystemVersion =
497
3.41k
    H_GET_16 (abfd, src->MinorOperatingSystemVersion);
498
3.41k
  a->MajorImageVersion = H_GET_16 (abfd, src->MajorImageVersion);
499
3.41k
  a->MinorImageVersion = H_GET_16 (abfd, src->MinorImageVersion);
500
3.41k
  a->MajorSubsystemVersion = H_GET_16 (abfd, src->MajorSubsystemVersion);
501
3.41k
  a->MinorSubsystemVersion = H_GET_16 (abfd, src->MinorSubsystemVersion);
502
3.41k
  a->Win32Version = H_GET_32 (abfd, src->Win32Version);
503
3.41k
  a->SizeOfImage = H_GET_32 (abfd, src->SizeOfImage);
504
3.41k
  a->SizeOfHeaders = H_GET_32 (abfd, src->SizeOfHeaders);
505
3.41k
  a->CheckSum = H_GET_32 (abfd, src->CheckSum);
506
3.41k
  a->Subsystem = H_GET_16 (abfd, src->Subsystem);
507
3.41k
  a->DllCharacteristics = H_GET_16 (abfd, src->DllCharacteristics);
508
3.41k
  a->SizeOfStackReserve =
509
3.41k
    GET_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, src->SizeOfStackReserve);
510
3.41k
  a->SizeOfStackCommit =
511
3.41k
    GET_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, src->SizeOfStackCommit);
512
3.41k
  a->SizeOfHeapReserve =
513
3.41k
    GET_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, src->SizeOfHeapReserve);
514
3.41k
  a->SizeOfHeapCommit =
515
3.41k
    GET_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, src->SizeOfHeapCommit);
516
3.41k
  a->LoaderFlags = H_GET_32 (abfd, src->LoaderFlags);
517
3.41k
  a->NumberOfRvaAndSizes = H_GET_32 (abfd, src->NumberOfRvaAndSizes);
518
519
  /* PR 17512: Don't blindly trust NumberOfRvaAndSizes.  */
520
3.41k
  unsigned idx;
521
3.41k
  for (idx = 0;
522
34.9k
       idx < a->NumberOfRvaAndSizes && idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
523
31.4k
       idx++)
524
31.4k
    {
525
      /* If data directory is empty, rva also should be 0.  */
526
31.4k
      int size = H_GET_32 (abfd, src->DataDirectory[idx][1]);
527
31.4k
      int vma = size ? H_GET_32 (abfd, src->DataDirectory[idx][0]) : 0;
528
529
31.4k
      a->DataDirectory[idx].Size = size;
530
31.4k
      a->DataDirectory[idx].VirtualAddress = vma;
531
31.4k
    }
532
533
26.4k
  while (idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
534
23.0k
    {
535
23.0k
      a->DataDirectory[idx].Size = 0;
536
23.0k
      a->DataDirectory[idx].VirtualAddress = 0;
537
23.0k
      idx++;
538
23.0k
    }
539
540
3.41k
  if (aouthdr_int->entry)
541
2.31k
    {
542
2.31k
      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.31k
    }
547
548
3.41k
  if (aouthdr_int->tsize)
549
2.48k
    {
550
2.48k
      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.48k
    }
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.41k
}
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
256
{
575
256
  asection *sec = bfd_get_section_by_name (abfd, name);
576
577
  /* Add import directory information if it exists.  */
578
256
  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
256
}
594
595
unsigned int
596
_bfd_peLoongArch64i_swap_aouthdr_out (bfd * abfd, void * in, void * out)
597
76
{
598
76
  struct internal_aouthdr *aouthdr_in = (struct internal_aouthdr *) in;
599
76
  pe_data_type *pe = pe_data (abfd);
600
76
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
601
76
  PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
602
76
  bfd_vma sa, fa, ib;
603
76
  IMAGE_DATA_DIRECTORY idata2, idata5, didat2, tls, loadcfg;
604
605
76
  sa = extra->SectionAlignment;
606
76
  fa = extra->FileAlignment;
607
76
  ib = extra->ImageBase;
608
609
76
  idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
610
76
  idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
611
76
  didat2 = pe->pe_opthdr.DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR];
612
76
  tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
613
76
  loadcfg = pe->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE];
614
615
76
  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
76
  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
76
  if (aouthdr_in->entry)
632
31
    {
633
31
      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
31
    }
638
639
234
#define FA(x) (((x) + fa -1 ) & (- fa))
640
76
#define SA(x) (((x) + sa -1 ) & (- sa))
641
642
  /* We like to have the sizes aligned.  */
643
76
  aouthdr_in->bsize = FA (aouthdr_in->bsize);
644
645
76
  extra->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
646
647
76
  add_data_entry (abfd, extra, PE_EXPORT_TABLE, ".edata", ib);
648
76
  add_data_entry (abfd, extra, PE_RESOURCE_TABLE, ".rsrc", ib);
649
76
  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
76
  extra->DataDirectory[PE_IMPORT_TABLE]  = idata2;
661
76
  extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
662
76
  extra->DataDirectory[PE_DELAY_IMPORT_DESCRIPTOR] = didat2;
663
76
  extra->DataDirectory[PE_TLS_TABLE] = tls;
664
76
  extra->DataDirectory[PE_LOAD_CONFIG_TABLE] = loadcfg;
665
666
76
  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
28
    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
76
  if (pe->has_reloc_section)
677
0
    add_data_entry (abfd, extra, PE_BASE_RELOCATION_TABLE, ".reloc", ib);
678
679
76
  {
680
76
    asection *sec;
681
76
    bfd_vma hsize = 0;
682
76
    bfd_vma dsize = 0;
683
76
    bfd_vma isize = 0;
684
76
    bfd_vma tsize = 0;
685
686
234
    for (sec = abfd->sections; sec; sec = sec->next)
687
158
      {
688
158
  int rounded = FA (sec->size);
689
690
158
  if (rounded == 0)
691
110
    continue;
692
693
  /* The first non-zero section filepos is the header size.
694
     Sections without contents will have a filepos of 0.  */
695
48
  if (hsize == 0)
696
29
    hsize = sec->filepos;
697
48
  if (sec->flags & SEC_DATA)
698
0
    dsize += rounded;
699
48
  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
48
  if (coff_section_data (abfd, sec) != NULL
712
48
      && pei_section_data (abfd, sec) != NULL)
713
48
    isize = SA (sec->vma - extra->ImageBase
714
48
          + FA (pei_section_data (abfd, sec)->virt_size));
715
48
      }
716
717
76
    aouthdr_in->dsize = dsize;
718
76
    aouthdr_in->tsize = tsize;
719
76
    extra->SizeOfHeaders = hsize;
720
76
    extra->SizeOfImage = isize;
721
76
  }
722
723
76
  H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
724
725
76
  if (extra->MajorLinkerVersion || extra->MinorLinkerVersion)
726
59
    {
727
59
      H_PUT_8 (abfd, extra->MajorLinkerVersion,
728
59
         aouthdr_out->standard.vstamp);
729
59
      H_PUT_8 (abfd, extra->MinorLinkerVersion,
730
59
         aouthdr_out->standard.vstamp + 1);
731
59
    }
732
17
  else
733
17
    {
734
/* e.g. 219510000 is linker version 2.19  */
735
17
#define LINKER_VERSION ((short) (BFD_VERSION / 1000000))
736
737
      /* This piece of magic sets the "linker version" field to
738
   LINKER_VERSION.  */
739
17
      H_PUT_16 (abfd, (LINKER_VERSION / 100 + (LINKER_VERSION % 100) * 256),
740
17
    aouthdr_out->standard.vstamp);
741
17
    }
742
743
76
  PUT_AOUTHDR_TSIZE (abfd, aouthdr_in->tsize, aouthdr_out->standard.tsize);
744
76
  PUT_AOUTHDR_DSIZE (abfd, aouthdr_in->dsize, aouthdr_out->standard.dsize);
745
76
  PUT_AOUTHDR_BSIZE (abfd, aouthdr_in->bsize, aouthdr_out->standard.bsize);
746
76
  PUT_AOUTHDR_ENTRY (abfd, aouthdr_in->entry, aouthdr_out->standard.entry);
747
76
  PUT_AOUTHDR_TEXT_START (abfd, aouthdr_in->text_start,
748
76
        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
76
  PUT_OPTHDR_IMAGE_BASE (abfd, extra->ImageBase, aouthdr_out->ImageBase);
757
76
  H_PUT_32 (abfd, extra->SectionAlignment, aouthdr_out->SectionAlignment);
758
76
  H_PUT_32 (abfd, extra->FileAlignment, aouthdr_out->FileAlignment);
759
76
  H_PUT_16 (abfd, extra->MajorOperatingSystemVersion,
760
76
      aouthdr_out->MajorOperatingSystemVersion);
761
76
  H_PUT_16 (abfd, extra->MinorOperatingSystemVersion,
762
76
      aouthdr_out->MinorOperatingSystemVersion);
763
76
  H_PUT_16 (abfd, extra->MajorImageVersion, aouthdr_out->MajorImageVersion);
764
76
  H_PUT_16 (abfd, extra->MinorImageVersion, aouthdr_out->MinorImageVersion);
765
76
  H_PUT_16 (abfd, extra->MajorSubsystemVersion,
766
76
      aouthdr_out->MajorSubsystemVersion);
767
76
  H_PUT_16 (abfd, extra->MinorSubsystemVersion,
768
76
      aouthdr_out->MinorSubsystemVersion);
769
76
  H_PUT_32 (abfd, extra->Win32Version, aouthdr_out->Win32Version);
770
76
  H_PUT_32 (abfd, extra->SizeOfImage, aouthdr_out->SizeOfImage);
771
76
  H_PUT_32 (abfd, extra->SizeOfHeaders, aouthdr_out->SizeOfHeaders);
772
76
  H_PUT_32 (abfd, extra->CheckSum, aouthdr_out->CheckSum);
773
76
  H_PUT_16 (abfd, extra->Subsystem, aouthdr_out->Subsystem);
774
76
  H_PUT_16 (abfd, extra->DllCharacteristics, aouthdr_out->DllCharacteristics);
775
76
  PUT_OPTHDR_SIZE_OF_STACK_RESERVE (abfd, extra->SizeOfStackReserve,
776
76
            aouthdr_out->SizeOfStackReserve);
777
76
  PUT_OPTHDR_SIZE_OF_STACK_COMMIT (abfd, extra->SizeOfStackCommit,
778
76
           aouthdr_out->SizeOfStackCommit);
779
76
  PUT_OPTHDR_SIZE_OF_HEAP_RESERVE (abfd, extra->SizeOfHeapReserve,
780
76
           aouthdr_out->SizeOfHeapReserve);
781
76
  PUT_OPTHDR_SIZE_OF_HEAP_COMMIT (abfd, extra->SizeOfHeapCommit,
782
76
          aouthdr_out->SizeOfHeapCommit);
783
76
  H_PUT_32 (abfd, extra->LoaderFlags, aouthdr_out->LoaderFlags);
784
76
  H_PUT_32 (abfd, extra->NumberOfRvaAndSizes,
785
76
      aouthdr_out->NumberOfRvaAndSizes);
786
76
  {
787
76
    int idx;
788
789
1.29k
    for (idx = 0; idx < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; idx++)
790
1.21k
      {
791
1.21k
  H_PUT_32 (abfd, extra->DataDirectory[idx].VirtualAddress,
792
1.21k
      aouthdr_out->DataDirectory[idx][0]);
793
1.21k
  H_PUT_32 (abfd, extra->DataDirectory[idx].Size,
794
1.21k
      aouthdr_out->DataDirectory[idx][1]);
795
1.21k
      }
796
76
  }
797
798
76
  return AOUTSZ;
799
76
}
800
801
unsigned int
802
_bfd_peLoongArch64i_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
803
126
{
804
126
  int idx;
805
126
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
806
126
  struct external_PEI_filehdr *filehdr_out = (struct external_PEI_filehdr *) out;
807
808
126
  if (pe_data (abfd)->has_reloc_section
809
126
      || pe_data (abfd)->dont_strip_reloc)
810
83
    filehdr_in->f_flags &= ~F_RELFLG;
811
812
126
  if (pe_data (abfd)->dll)
813
22
    filehdr_in->f_flags |= F_DLL;
814
815
126
  filehdr_in->pe.e_magic    = IMAGE_DOS_SIGNATURE;
816
126
  filehdr_in->pe.e_cblp     = 0x90;
817
126
  filehdr_in->pe.e_cp       = 0x3;
818
126
  filehdr_in->pe.e_crlc     = 0x0;
819
126
  filehdr_in->pe.e_cparhdr  = 0x4;
820
126
  filehdr_in->pe.e_minalloc = 0x0;
821
126
  filehdr_in->pe.e_maxalloc = 0xffff;
822
126
  filehdr_in->pe.e_ss       = 0x0;
823
126
  filehdr_in->pe.e_sp       = 0xb8;
824
126
  filehdr_in->pe.e_csum     = 0x0;
825
126
  filehdr_in->pe.e_ip       = 0x0;
826
126
  filehdr_in->pe.e_cs       = 0x0;
827
126
  filehdr_in->pe.e_lfarlc   = 0x40;
828
126
  filehdr_in->pe.e_ovno     = 0x0;
829
830
630
  for (idx = 0; idx < 4; idx++)
831
504
    filehdr_in->pe.e_res[idx] = 0x0;
832
833
126
  filehdr_in->pe.e_oemid   = 0x0;
834
126
  filehdr_in->pe.e_oeminfo = 0x0;
835
836
1.38k
  for (idx = 0; idx < 10; idx++)
837
1.26k
    filehdr_in->pe.e_res2[idx] = 0x0;
838
839
126
  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
126
  memcpy (filehdr_in->pe.dos_message, pe_data (abfd)->dos_message,
844
126
    sizeof (filehdr_in->pe.dos_message));
845
846
126
  filehdr_in->pe.nt_signature = IMAGE_NT_SIGNATURE;
847
848
126
  H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic);
849
126
  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
126
  if ((pe_data (abfd)->timestamp) == -1)
854
126
    {
855
126
      time_t now = bfd_get_current_time (0);
856
126
      H_PUT_32 (abfd, now, filehdr_out->f_timdat);
857
126
    }
858
0
  else
859
126
    H_PUT_32 (abfd, pe_data (abfd)->timestamp, filehdr_out->f_timdat);
860
861
126
  PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
862
126
          filehdr_out->f_symptr);
863
126
  H_PUT_32 (abfd, filehdr_in->f_nsyms, filehdr_out->f_nsyms);
864
126
  H_PUT_16 (abfd, filehdr_in->f_opthdr, filehdr_out->f_opthdr);
865
126
  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
126
  H_PUT_16 (abfd, filehdr_in->pe.e_magic, filehdr_out->e_magic);
871
126
  H_PUT_16 (abfd, filehdr_in->pe.e_cblp, filehdr_out->e_cblp);
872
126
  H_PUT_16 (abfd, filehdr_in->pe.e_cp, filehdr_out->e_cp);
873
126
  H_PUT_16 (abfd, filehdr_in->pe.e_crlc, filehdr_out->e_crlc);
874
126
  H_PUT_16 (abfd, filehdr_in->pe.e_cparhdr, filehdr_out->e_cparhdr);
875
126
  H_PUT_16 (abfd, filehdr_in->pe.e_minalloc, filehdr_out->e_minalloc);
876
126
  H_PUT_16 (abfd, filehdr_in->pe.e_maxalloc, filehdr_out->e_maxalloc);
877
126
  H_PUT_16 (abfd, filehdr_in->pe.e_ss, filehdr_out->e_ss);
878
126
  H_PUT_16 (abfd, filehdr_in->pe.e_sp, filehdr_out->e_sp);
879
126
  H_PUT_16 (abfd, filehdr_in->pe.e_csum, filehdr_out->e_csum);
880
126
  H_PUT_16 (abfd, filehdr_in->pe.e_ip, filehdr_out->e_ip);
881
126
  H_PUT_16 (abfd, filehdr_in->pe.e_cs, filehdr_out->e_cs);
882
126
  H_PUT_16 (abfd, filehdr_in->pe.e_lfarlc, filehdr_out->e_lfarlc);
883
126
  H_PUT_16 (abfd, filehdr_in->pe.e_ovno, filehdr_out->e_ovno);
884
885
630
  for (idx = 0; idx < 4; idx++)
886
504
    H_PUT_16 (abfd, filehdr_in->pe.e_res[idx], filehdr_out->e_res[idx]);
887
888
126
  H_PUT_16 (abfd, filehdr_in->pe.e_oemid, filehdr_out->e_oemid);
889
126
  H_PUT_16 (abfd, filehdr_in->pe.e_oeminfo, filehdr_out->e_oeminfo);
890
891
1.38k
  for (idx = 0; idx < 10; idx++)
892
1.26k
    H_PUT_16 (abfd, filehdr_in->pe.e_res2[idx], filehdr_out->e_res2[idx]);
893
894
126
  H_PUT_32 (abfd, filehdr_in->pe.e_lfanew, filehdr_out->e_lfanew);
895
896
126
  memcpy (filehdr_out->dos_message, filehdr_in->pe.dos_message,
897
126
    sizeof (filehdr_out->dos_message));
898
899
  /* Also put in the NT signature.  */
900
126
  H_PUT_32 (abfd, filehdr_in->pe.nt_signature, filehdr_out->nt_signature);
901
902
126
  return FILHSZ;
903
126
}
904
905
unsigned int
906
_bfd_peLoongArch64_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_peLoongArch64i_swap_scnhdr_out (bfd * abfd, void * in, void * out,
924
        const asection *section)
925
161
{
926
161
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
927
161
  SCNHDR *scnhdr_ext = (SCNHDR *) out;
928
161
  unsigned int ret = SCNHSZ;
929
161
  bfd_vma ps;
930
161
  bfd_vma ss;
931
932
161
  memcpy (scnhdr_ext->s_name, scnhdr_int->s_name, sizeof (scnhdr_int->s_name));
933
934
161
  ss = scnhdr_int->s_vaddr - pe_data (abfd)->pe_opthdr.ImageBase;
935
161
  if (scnhdr_int->s_vaddr < pe_data (abfd)->pe_opthdr.ImageBase)
936
70
    _bfd_error_handler (_("%pB:%.8s: section below image base"),
937
70
                        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
161
  PUT_SCNHDR_VADDR (abfd, ss, scnhdr_ext->s_vaddr);
945
161
#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
161
  if ((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0)
951
2
    {
952
2
      if (bfd_pei_p (abfd))
953
2
  {
954
2
    ps = scnhdr_int->s_size;
955
2
    ss = 0;
956
2
  }
957
0
      else
958
0
       {
959
0
   ps = 0;
960
0
   ss = scnhdr_int->s_size;
961
0
       }
962
2
    }
963
159
  else
964
159
    {
965
159
      if (bfd_pei_p (abfd))
966
159
  ps = scnhdr_int->s_paddr;
967
0
      else
968
0
  ps = 0;
969
970
159
      ss = scnhdr_int->s_size;
971
159
    }
972
973
161
  PUT_SCNHDR_SIZE (abfd, ss,
974
161
       scnhdr_ext->s_size);
975
976
  /* s_paddr in PE is really the virtual size.  */
977
161
  PUT_SCNHDR_PADDR (abfd, ps, scnhdr_ext->s_paddr);
978
979
161
  PUT_SCNHDR_SCNPTR (abfd, scnhdr_int->s_scnptr,
980
161
         scnhdr_ext->s_scnptr);
981
161
  PUT_SCNHDR_RELPTR (abfd, scnhdr_int->s_relptr,
982
161
         scnhdr_ext->s_relptr);
983
161
  PUT_SCNHDR_LNNOPTR (abfd, scnhdr_int->s_lnnoptr,
984
161
          scnhdr_ext->s_lnnoptr);
985
986
161
  {
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
161
    typedef struct
1001
161
    {
1002
161
      char section_name[SCNNMLEN];
1003
161
      unsigned long must_have;
1004
161
    }
1005
161
    pe_required_section_flags;
1006
1007
161
    static const pe_required_section_flags known_sections [] =
1008
161
      {
1009
161
  { ".CRT",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1010
161
  { ".arch",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_ALIGN_8BYTES },
1011
161
  { ".bss",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1012
161
  { ".data",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1013
161
  { ".didat", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1014
161
  { ".edata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1015
161
  { ".idata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1016
161
  { ".pdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1017
161
  { ".rdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1018
161
  { ".reloc", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_DISCARDABLE },
1019
161
  { ".rsrc",  IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1020
161
  { ".text" , IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE },
1021
161
  { ".tls",   IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_WRITE },
1022
161
  { ".xdata", IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA },
1023
161
      };
1024
1025
161
    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
161
    for (p = known_sections;
1036
2.39k
   p < known_sections + ARRAY_SIZE (known_sections);
1037
2.23k
   p++)
1038
2.24k
      if (memcmp (scnhdr_int->s_name, p->section_name, SCNNMLEN) == 0)
1039
7
  {
1040
7
    unsigned long must_have = p->must_have;
1041
1042
7
    if (memcmp (scnhdr_int->s_name, ".text", sizeof ".text")
1043
7
        || (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
7
    if (section->flags & SEC_ALLOC)
1048
7
      must_have &= ~IMAGE_SCN_MEM_DISCARDABLE;
1049
7
    scnhdr_int->s_flags |= must_have;
1050
7
    break;
1051
7
  }
1052
1053
161
    H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
1054
161
  }
1055
1056
161
  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
161
  else
1073
161
    {
1074
161
      if (scnhdr_int->s_nlnno <= 0xffff)
1075
161
  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
161
      if (scnhdr_int->s_nreloc < 0xffff)
1091
161
  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
161
    }
1100
161
  return ret;
1101
161
}
1102
1103
void
1104
_bfd_peLoongArch64i_swap_debugdir_in (bfd * abfd, void * ext1, void * in1)
1105
14.5k
{
1106
14.5k
  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) ext1;
1107
14.5k
  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) in1;
1108
1109
14.5k
  in->Characteristics = H_GET_32(abfd, ext->Characteristics);
1110
14.5k
  in->TimeDateStamp = H_GET_32(abfd, ext->TimeDateStamp);
1111
14.5k
  in->MajorVersion = H_GET_16(abfd, ext->MajorVersion);
1112
14.5k
  in->MinorVersion = H_GET_16(abfd, ext->MinorVersion);
1113
14.5k
  in->Type = H_GET_32(abfd, ext->Type);
1114
14.5k
  in->SizeOfData = H_GET_32(abfd, ext->SizeOfData);
1115
14.5k
  in->AddressOfRawData = H_GET_32(abfd, ext->AddressOfRawData);
1116
14.5k
  in->PointerToRawData = H_GET_32(abfd, ext->PointerToRawData);
1117
14.5k
}
1118
1119
unsigned int
1120
_bfd_peLoongArch64i_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
1121
2
{
1122
2
  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) extp;
1123
2
  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) inp;
1124
1125
2
  H_PUT_32(abfd, in->Characteristics, ext->Characteristics);
1126
2
  H_PUT_32(abfd, in->TimeDateStamp, ext->TimeDateStamp);
1127
2
  H_PUT_16(abfd, in->MajorVersion, ext->MajorVersion);
1128
2
  H_PUT_16(abfd, in->MinorVersion, ext->MinorVersion);
1129
2
  H_PUT_32(abfd, in->Type, ext->Type);
1130
2
  H_PUT_32(abfd, in->SizeOfData, ext->SizeOfData);
1131
2
  H_PUT_32(abfd, in->AddressOfRawData, ext->AddressOfRawData);
1132
2
  H_PUT_32(abfd, in->PointerToRawData, ext->PointerToRawData);
1133
1134
2
  return sizeof (struct external_IMAGE_DEBUG_DIRECTORY);
1135
2
}
1136
1137
CODEVIEW_INFO *
1138
_bfd_peLoongArch64i_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo,
1139
        char **pdb)
1140
213
{
1141
213
  char buffer[256+1];
1142
213
  bfd_size_type nread;
1143
1144
213
  if (bfd_seek (abfd, where, SEEK_SET) != 0)
1145
0
    return NULL;
1146
1147
213
  if (length <= sizeof (CV_INFO_PDB70) && length <= sizeof (CV_INFO_PDB20))
1148
28
    return NULL;
1149
185
  if (length > 256)
1150
112
    length = 256;
1151
185
  nread = bfd_read (buffer, length, abfd);
1152
185
  if (length != nread)
1153
62
    return NULL;
1154
1155
  /* Ensure null termination of filename.  */
1156
123
  memset (buffer + nread, 0, sizeof (buffer) - nread);
1157
1158
123
  cvinfo->CVSignature = H_GET_32 (abfd, buffer);
1159
123
  cvinfo->Age = 0;
1160
1161
123
  if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
1162
7
      && (length > sizeof (CV_INFO_PDB70)))
1163
4
    {
1164
4
      CV_INFO_PDB70 *cvinfo70 = (CV_INFO_PDB70 *)(buffer);
1165
1166
4
      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
4
      bfd_putb32 (bfd_getl32 (cvinfo70->Signature), cvinfo->Signature);
1172
4
      bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[4])), &(cvinfo->Signature[4]));
1173
4
      bfd_putb16 (bfd_getl16 (&(cvinfo70->Signature[6])), &(cvinfo->Signature[6]));
1174
4
      memcpy (&(cvinfo->Signature[8]), &(cvinfo70->Signature[8]), 8);
1175
1176
4
      cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH;
1177
      /* cvinfo->PdbFileName = cvinfo70->PdbFileName;  */
1178
1179
4
      if (pdb)
1180
0
  *pdb = xstrdup (cvinfo70->PdbFileName);
1181
1182
4
      return cvinfo;
1183
4
    }
1184
119
  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
116
  return NULL;
1200
123
}
1201
1202
unsigned int
1203
_bfd_peLoongArch64i_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
45
{
1267
45
  if ((section->flags & SEC_HAS_CONTENTS) == 0)
1268
0
    return false;
1269
45
  if (dataoff > section->size
1270
45
      || datasize > section->size - dataoff)
1271
1
    return false;
1272
44
  ufile_ptr filesize = bfd_get_file_size (abfd);
1273
44
  if (filesize != 0
1274
44
      && ((ufile_ptr) section->filepos > filesize
1275
41
    || dataoff > filesize - section->filepos
1276
40
    || datasize > filesize - section->filepos - dataoff))
1277
5
    return false;
1278
39
  return true;
1279
44
}
1280
1281
static bool
1282
pe_print_idata (bfd * abfd, void * vfile)
1283
137
{
1284
137
  FILE *file = (FILE *) vfile;
1285
137
  bfd_byte *data;
1286
137
  asection *section;
1287
137
  bfd_signed_vma adj;
1288
137
  bfd_size_type datasize = 0;
1289
137
  bfd_size_type dataoff;
1290
137
  bfd_size_type i;
1291
137
  int onaline = 20;
1292
1293
137
  pe_data_type *pe = pe_data (abfd);
1294
137
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1295
1296
137
  bfd_vma addr;
1297
1298
137
  addr = extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress;
1299
1300
137
  if (addr == 0 && extra->DataDirectory[PE_IMPORT_TABLE].Size == 0)
1301
75
    {
1302
      /* Maybe the extra header isn't there.  Look for the section.  */
1303
75
      section = bfd_get_section_by_name (abfd, ".idata");
1304
75
      if (section == NULL || (section->flags & SEC_HAS_CONTENTS) == 0)
1305
75
  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
62
  else
1313
62
    {
1314
62
      addr += extra->ImageBase;
1315
761
      for (section = abfd->sections; section != NULL; section = section->next)
1316
721
  {
1317
721
    datasize = section->size;
1318
721
    if (addr >= section->vma && addr < section->vma + datasize)
1319
22
      break;
1320
721
  }
1321
1322
62
      if (section == NULL)
1323
40
  {
1324
40
    fprintf (file,
1325
40
       _("\nThere is an import table, but the section containing it could not be found\n"));
1326
40
    return true;
1327
40
  }
1328
22
      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
62
    }
1336
1337
  /* xgettext:c-format */
1338
22
  fprintf (file, _("\nThere is an import table in %s at 0x%lx\n"),
1339
22
     section->name, (unsigned long) addr);
1340
1341
22
  dataoff = addr - section->vma;
1342
1343
22
  fprintf (file,
1344
22
     _("\nThe Import Tables (interpreted %s section contents)\n"),
1345
22
     section->name);
1346
22
  fprintf (file,
1347
22
     _("\
1348
22
 vma:            Hint    Time      Forward  DLL       First\n\
1349
22
                 Table   Stamp     Chain    Name      Thunk\n"));
1350
1351
  /* Read the whole section.  Some of the fields might be before dataoff.  */
1352
22
  if (!bfd_malloc_and_get_section (abfd, section, &data))
1353
7
    {
1354
7
      free (data);
1355
7
      return false;
1356
7
    }
1357
1358
15
  adj = section->vma - extra->ImageBase;
1359
1360
  /* Print all image import descriptors.  */
1361
20
  for (i = dataoff; i + onaline <= datasize; i += onaline)
1362
20
    {
1363
20
      bfd_vma hint_addr;
1364
20
      bfd_vma time_stamp;
1365
20
      bfd_vma forward_chain;
1366
20
      bfd_vma dll_name;
1367
20
      bfd_vma first_thunk;
1368
20
      int idx = 0;
1369
20
      bfd_size_type j;
1370
20
      char *dll;
1371
1372
      /* Print (i + extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress).  */
1373
20
      fprintf (file, " %08lx\t", (unsigned long) (i + adj));
1374
20
      hint_addr = bfd_get_32 (abfd, data + i);
1375
20
      time_stamp = bfd_get_32 (abfd, data + i + 4);
1376
20
      forward_chain = bfd_get_32 (abfd, data + i + 8);
1377
20
      dll_name = bfd_get_32 (abfd, data + i + 12);
1378
20
      first_thunk = bfd_get_32 (abfd, data + i + 16);
1379
1380
20
      fprintf (file, "%08lx %08lx %08lx %08lx %08lx\n",
1381
20
         (unsigned long) hint_addr,
1382
20
         (unsigned long) time_stamp,
1383
20
         (unsigned long) forward_chain,
1384
20
         (unsigned long) dll_name,
1385
20
         (unsigned long) first_thunk);
1386
1387
20
      if (hint_addr == 0 && first_thunk == 0)
1388
0
  break;
1389
1390
20
      if (dll_name - adj >= section->size)
1391
15
  break;
1392
1393
5
      dll = (char *) data + dll_name - adj;
1394
      /* PR 17512 file: 078-12277-0.004.  */
1395
5
      bfd_size_type maxlen = (char *)(data + datasize) - dll - 1;
1396
5
      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
5
      if (hint_addr == 0)
1401
0
  hint_addr = first_thunk;
1402
1403
5
      if (hint_addr != 0 && hint_addr - adj < datasize)
1404
3
  {
1405
3
    bfd_byte *ft_data;
1406
3
    asection *ft_section;
1407
3
    bfd_vma ft_addr;
1408
3
    bfd_size_type ft_datasize;
1409
3
    int ft_idx;
1410
3
    int ft_allocated;
1411
1412
3
    fprintf (file, _("\tvma:     Ordinal  Hint  Member-Name  Bound-To\n"));
1413
1414
3
    idx = hint_addr - adj;
1415
1416
3
    ft_addr = first_thunk + extra->ImageBase;
1417
3
    ft_idx = first_thunk - adj;
1418
3
    ft_data = data + ft_idx;
1419
3
    ft_datasize = datasize - ft_idx;
1420
3
    ft_allocated = 0;
1421
1422
3
    if (first_thunk != hint_addr)
1423
3
      {
1424
        /* Find the section which contains the first thunk.  */
1425
3
        for (ft_section = abfd->sections;
1426
7
       ft_section != NULL;
1427
4
       ft_section = ft_section->next)
1428
7
    {
1429
7
      if (ft_addr >= ft_section->vma
1430
4
          && ft_addr < ft_section->vma + ft_section->size)
1431
3
        break;
1432
7
    }
1433
1434
3
        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
3
        if (ft_section != section)
1444
1
    {
1445
1
      ft_idx = first_thunk - (ft_section->vma - extra->ImageBase);
1446
1
      ft_datasize = ft_section->size - ft_idx;
1447
1
      if (!get_contents_sanity_check (abfd, ft_section,
1448
1
              ft_idx, ft_datasize))
1449
1
        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
3
      }
1464
1465
    /* Print HintName vector entries.  */
1466
2
#if defined COFF_WITH_pep || defined COFF_WITH_pex64 \
1467
2
    || defined COFF_WITH_peAArch64 || defined COFF_WITH_peLoongArch64 \
1468
2
    || defined COFF_WITH_peRiscV64
1469
26
    for (j = 0; idx + j + 8 <= datasize; j += 8)
1470
25
      {
1471
25
        bfd_size_type amt;
1472
25
        unsigned long member = bfd_get_32 (abfd, data + idx + j);
1473
25
        unsigned long member_high = bfd_get_32 (abfd, data + idx + j + 4);
1474
1475
25
        if (!member && !member_high)
1476
1
    break;
1477
1478
24
        amt = member - adj;
1479
1480
24
        if (HighBitSet (member_high))
1481
1
          {
1482
      /* in low 16 bits is ordinal number, other bits are reserved */
1483
1
      unsigned int ordinal = member & 0xffff;
1484
1
      fprintf (file, "\t%08lx  %5u  <none> <none>",
1485
1
         (unsigned long)(first_thunk + j), ordinal);
1486
1
          }
1487
        /* PR binutils/17512: Handle corrupt PE data.  */
1488
23
        else if (amt >= datasize || amt + 2 >= datasize)
1489
7
    fprintf (file, _("\t<corrupt: 0x%08lx>"), member);
1490
16
        else
1491
16
    {
1492
16
      unsigned int hint;
1493
16
      char *member_name;
1494
1495
      /* First 16 bits is hint name index, rest is the name */
1496
16
      hint = bfd_get_16 (abfd, data + amt);
1497
16
      member_name = (char *) data + amt + 2;
1498
16
      fprintf (file, "\t%08lx  <none>  %04x  %.*s",
1499
16
         (unsigned long)(first_thunk + j), hint,
1500
16
         (int) (datasize - (amt + 2)), member_name);
1501
16
    }
1502
1503
        /* If the time stamp is not zero, the import address
1504
     table holds actual addresses.  */
1505
24
        if (time_stamp != 0
1506
17
      && first_thunk != 0
1507
17
      && first_thunk != hint_addr
1508
17
      && j + 4 <= ft_datasize)
1509
17
    fprintf (file, "\t%08lx",
1510
17
       (unsigned long) bfd_get_32 (abfd, ft_data + j));
1511
1512
24
        fprintf (file, "\n");
1513
24
      }
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
2
    if (ft_allocated)
1561
0
      free (ft_data);
1562
2
  }
1563
1564
4
      fprintf (file, "\n");
1565
4
    }
1566
1567
15
  free (data);
1568
1569
15
  return true;
1570
22
}
1571
1572
static bool
1573
pe_print_edata (bfd * abfd, void * vfile)
1574
137
{
1575
137
  FILE *file = (FILE *) vfile;
1576
137
  bfd_byte *data;
1577
137
  asection *section;
1578
137
  bfd_size_type datasize = 0;
1579
137
  bfd_size_type dataoff;
1580
137
  bfd_size_type i;
1581
137
  bfd_vma       adj;
1582
137
  struct EDT_type
1583
137
  {
1584
137
    long export_flags;    /* Reserved - should be zero.  */
1585
137
    long time_stamp;
1586
137
    short major_ver;
1587
137
    short minor_ver;
1588
137
    bfd_vma name;   /* RVA - relative to image base.  */
1589
137
    long base;      /* Ordinal base.  */
1590
137
    unsigned long num_functions;/* Number in the export address table.  */
1591
137
    unsigned long num_names;  /* Number in the name pointer table.  */
1592
137
    bfd_vma eat_addr;   /* RVA to the export address table.  */
1593
137
    bfd_vma npt_addr;   /* RVA to the Export Name Pointer Table.  */
1594
137
    bfd_vma ot_addr;    /* RVA to the Ordinal Table.  */
1595
137
  } edt;
1596
1597
137
  pe_data_type *pe = pe_data (abfd);
1598
137
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
1599
1600
137
  bfd_vma addr;
1601
1602
137
  addr = extra->DataDirectory[PE_EXPORT_TABLE].VirtualAddress;
1603
1604
137
  if (addr == 0 && extra->DataDirectory[PE_EXPORT_TABLE].Size == 0)
1605
61
    {
1606
      /* Maybe the extra header isn't there.  Look for the section.  */
1607
61
      section = bfd_get_section_by_name (abfd, ".edata");
1608
61
      if (section == NULL)
1609
61
  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
76
  else
1618
76
    {
1619
76
      addr += extra->ImageBase;
1620
1621
432
      for (section = abfd->sections; section != NULL; section = section->next)
1622
402
  if (addr >= section->vma && addr < section->vma + section->size)
1623
46
    break;
1624
1625
76
      if (section == NULL)
1626
30
  {
1627
30
    fprintf (file,
1628
30
       _("\nThere is an export table, but the section containing it could not be found\n"));
1629
30
    return true;
1630
30
  }
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
2
    {
1639
2
      fprintf (file,
1640
         /* xgettext:c-format */
1641
2
         _("\nThere is an export table in %s, but it is too small (%d)\n"),
1642
2
         section->name, (int) datasize);
1643
2
      return true;
1644
2
    }
1645
1646
44
  if (!get_contents_sanity_check (abfd, section, dataoff, datasize))
1647
5
    {
1648
5
      fprintf (file,
1649
5
         _("\nThere is an export table in %s, but contents cannot be read\n"),
1650
5
         section->name);
1651
5
      return true;
1652
5
    }
1653
1654
  /* xgettext:c-format */
1655
39
  fprintf (file, _("\nThere is an export table in %s at 0x%lx\n"),
1656
39
     section->name, (unsigned long) addr);
1657
1658
39
  data = (bfd_byte *) bfd_malloc (datasize);
1659
39
  if (data == NULL)
1660
0
    return false;
1661
1662
39
  if (! bfd_get_section_contents (abfd, section, data,
1663
39
          (file_ptr) dataoff, datasize))
1664
0
    {
1665
0
      free (data);
1666
0
      return false;
1667
0
    }
1668
1669
  /* Go get Export Directory Table.  */
1670
39
  edt.export_flags   = bfd_get_32 (abfd, data +   0);
1671
39
  edt.time_stamp     = bfd_get_32 (abfd, data +   4);
1672
39
  edt.major_ver      = bfd_get_16 (abfd, data +   8);
1673
39
  edt.minor_ver      = bfd_get_16 (abfd, data + 10);
1674
39
  edt.name       = bfd_get_32 (abfd, data + 12);
1675
39
  edt.base       = bfd_get_32 (abfd, data + 16);
1676
39
  edt.num_functions  = bfd_get_32 (abfd, data + 20);
1677
39
  edt.num_names      = bfd_get_32 (abfd, data + 24);
1678
39
  edt.eat_addr       = bfd_get_32 (abfd, data + 28);
1679
39
  edt.npt_addr       = bfd_get_32 (abfd, data + 32);
1680
39
  edt.ot_addr      = bfd_get_32 (abfd, data + 36);
1681
1682
39
  adj = section->vma - extra->ImageBase + dataoff;
1683
1684
  /* Dump the EDT first.  */
1685
39
  fprintf (file,
1686
39
     _("\nThe Export Tables (interpreted %s section contents)\n\n"),
1687
39
     section->name);
1688
1689
39
  fprintf (file,
1690
39
     _("Export Flags \t\t\t%lx\n"), (unsigned long) edt.export_flags);
1691
1692
39
  fprintf (file,
1693
39
     _("Time/Date stamp \t\t%lx\n"), (unsigned long) edt.time_stamp);
1694
1695
39
  fprintf (file,
1696
     /* xgettext:c-format */
1697
39
     _("Major/Minor \t\t\t%d/%d\n"), edt.major_ver, edt.minor_ver);
1698
1699
39
  fprintf (file,
1700
39
     _("Name \t\t\t\t"));
1701
39
  bfd_fprintf_vma (abfd, file, edt.name);
1702
1703
39
  if ((edt.name >= adj) && (edt.name < adj + datasize))
1704
17
    fprintf (file, " %.*s\n",
1705
17
       (int) (datasize - (edt.name - adj)),
1706
17
       data + edt.name - adj);
1707
22
  else
1708
22
    fprintf (file, "(outside .edata section)\n");
1709
1710
39
  fprintf (file,
1711
39
     _("Ordinal Base \t\t\t%ld\n"), edt.base);
1712
1713
39
  fprintf (file,
1714
39
     _("Number in:\n"));
1715
1716
39
  fprintf (file,
1717
39
     _("\tExport Address Table \t\t%08lx\n"),
1718
39
     edt.num_functions);
1719
1720
39
  fprintf (file,
1721
39
     _("\t[Name Pointer/Ordinal] Table\t%08lx\n"), edt.num_names);
1722
1723
39
  fprintf (file,
1724
39
     _("Table Addresses\n"));
1725
1726
39
  fprintf (file,
1727
39
     _("\tExport Address Table \t\t"));
1728
39
  bfd_fprintf_vma (abfd, file, edt.eat_addr);
1729
39
  fprintf (file, "\n");
1730
1731
39
  fprintf (file,
1732
39
     _("\tName Pointer Table \t\t"));
1733
39
  bfd_fprintf_vma (abfd, file, edt.npt_addr);
1734
39
  fprintf (file, "\n");
1735
1736
39
  fprintf (file,
1737
39
     _("\tOrdinal Table \t\t\t"));
1738
39
  bfd_fprintf_vma (abfd, file, edt.ot_addr);
1739
39
  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
39
  fprintf (file,
1751
39
    _("\nExport Address Table -- Ordinal Base %ld\n"),
1752
39
    edt.base);
1753
39
  fprintf (file, "\t          Ordinal  Address  Type\n");
1754
1755
  /* PR 17512: Handle corrupt PE binaries.  */
1756
  /* PR 17512 file: 140-165018-0.004.  */
1757
39
  if (edt.eat_addr - adj >= datasize
1758
      /* PR 17512: file: 092b1829 */
1759
22
      || (edt.num_functions + 1) * 4 < edt.num_functions
1760
22
      || 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
1.76k
  else for (i = 0; i < edt.num_functions; ++i)
1765
1.74k
    {
1766
1.74k
      bfd_vma eat_member = bfd_get_32 (abfd,
1767
1.74k
               data + edt.eat_addr + (i * 4) - adj);
1768
1.74k
      if (eat_member == 0)
1769
231
  continue;
1770
1771
1.51k
      if (eat_member - adj <= datasize)
1772
84
  {
1773
    /* This rva is to a name (forwarding function) in our section.  */
1774
    /* Should locate a function descriptor.  */
1775
84
    fprintf (file,
1776
84
       "\t[%4ld] +base[%4ld] %08lx %s -- %.*s\n",
1777
84
       (long) i,
1778
84
       (long) (i + edt.base),
1779
84
       (unsigned long) eat_member,
1780
84
       _("Forwarder RVA"),
1781
84
       (int)(datasize - (eat_member - adj)),
1782
84
       data + eat_member - adj);
1783
84
  }
1784
1.43k
      else
1785
1.43k
  {
1786
    /* Should locate a function descriptor in the reldata section.  */
1787
1.43k
    fprintf (file,
1788
1.43k
       "\t[%4ld] +base[%4ld] %08lx %s\n",
1789
1.43k
       (long) i,
1790
1.43k
       (long) (i + edt.base),
1791
1.43k
       (unsigned long) eat_member,
1792
1.43k
       _("Export RVA"));
1793
1.43k
  }
1794
1.51k
    }
1795
1796
  /* The Export Name Pointer Table is paired with the Export Ordinal Table.  */
1797
  /* Dump them in parallel for clarity.  */
1798
39
  fprintf (file,
1799
39
     _("\n[Ordinal/Name Pointer] Table -- Ordinal Base %ld\n"),
1800
39
    edt.base);
1801
39
  fprintf (file, "\t          Ordinal   Hint Name\n");
1802
1803
  /* PR 17512: Handle corrupt PE binaries.  */
1804
39
  if (edt.npt_addr + (edt.num_names * 4) - adj >= datasize
1805
      /* PR 17512: file: bb68816e.  */
1806
19
      || edt.num_names * 4 < edt.num_names
1807
19
      || (data + edt.npt_addr - adj) < data)
1808
    /* xgettext:c-format */
1809
30
    fprintf (file, _("\tInvalid Name Pointer Table rva (0x%lx) or entry count (0x%lx)\n"),
1810
30
       (long) edt.npt_addr,
1811
30
       (long) edt.num_names);
1812
  /* PR 17512: file: 140-147171-0.004.  */
1813
9
  else if (edt.ot_addr + (edt.num_names * 2) - adj >= datasize
1814
8
     || data + edt.ot_addr - adj < data)
1815
    /* xgettext:c-format */
1816
2
    fprintf (file, _("\tInvalid Ordinal Table rva (0x%lx) or entry count (0x%lx)\n"),
1817
2
       (long) edt.ot_addr,
1818
2
       (long) edt.num_names);
1819
508
  else for (i = 0; i < edt.num_names; ++i)
1820
501
    {
1821
501
      bfd_vma  name_ptr;
1822
501
      bfd_vma  ord;
1823
1824
501
      ord = bfd_get_16 (abfd, data + edt.ot_addr + (i * 2) - adj);
1825
501
      name_ptr = bfd_get_32 (abfd, data + edt.npt_addr + (i * 4) - adj);
1826
1827
501
      if ((name_ptr - adj) >= datasize)
1828
446
  {
1829
    /* xgettext:c-format */
1830
446
    fprintf (file, _("\t[%4ld] +base[%4ld]  %04lx <corrupt offset: %lx>\n"),
1831
446
       (long) ord, (long) (ord + edt.base), (long) i, (long) name_ptr);
1832
446
  }
1833
55
      else
1834
55
  {
1835
55
    char * name = (char *) data + name_ptr - adj;
1836
1837
55
    fprintf (file,
1838
55
       "\t[%4ld] +base[%4ld]  %04lx %.*s\n",
1839
55
       (long) ord, (long) (ord + edt.base), (long) i,
1840
55
       (int)((char *)(data + datasize) - name), name);
1841
55
  }
1842
501
    }
1843
1844
39
  free (data);
1845
1846
39
  return true;
1847
39
}
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
137
{
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
137
# define PDATA_ROW_SIZE (5 * 4)
1868
137
#endif
1869
137
  FILE *file = (FILE *) vfile;
1870
137
  bfd_byte *data = 0;
1871
137
  asection *section = bfd_get_section_by_name (abfd, ".pdata");
1872
137
  bfd_size_type datasize = 0;
1873
137
  bfd_size_type i;
1874
137
  bfd_size_type start, stop;
1875
137
  int onaline = PDATA_ROW_SIZE;
1876
1877
137
  if (section == NULL
1878
0
      || (section->flags & SEC_HAS_CONTENTS) == 0
1879
0
      || coff_section_data (abfd, section) == NULL
1880
0
      || pei_section_data (abfd, section) == NULL)
1881
137
    return true;
1882
1883
0
  stop = pei_section_data (abfd, section)->virt_size;
1884
0
  if ((stop % onaline) != 0)
1885
0
    fprintf (file,
1886
       /* xgettext:c-format */
1887
0
       _("warning, .pdata section size (%ld) is not a multiple of %d\n"),
1888
0
       (long) stop, onaline);
1889
1890
0
  fprintf (file,
1891
0
     _("\nThe Function Table (interpreted .pdata section contents)\n"));
1892
#if defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64) && !defined(COFF_WITH_peAArch64) && !defined(COFF_WITH_peLoongArch64) && !defined (COFF_WITH_peRiscV64)
1893
  fprintf (file,
1894
     _(" vma:\t\t\tBegin Address    End Address      Unwind Info\n"));
1895
#else
1896
0
  fprintf (file, _("\
1897
0
 vma:\t\tBegin    End      EH       EH       PrologEnd  Exception\n\
1898
0
     \t\tAddress  Address  Handler  Data     Address    Mask\n"));
1899
0
#endif
1900
1901
0
  datasize = section->size;
1902
0
  if (datasize == 0)
1903
0
    return true;
1904
1905
  /* PR 17512: file: 002-193900-0.004.  */
1906
0
  if (datasize < stop)
1907
0
    {
1908
      /* xgettext:c-format */
1909
0
      fprintf (file, _("Virtual size of .pdata section (%ld) larger than real size (%ld)\n"),
1910
0
         (long) stop, (long) datasize);
1911
0
      return false;
1912
0
    }
1913
1914
0
  if (! bfd_malloc_and_get_section (abfd, section, &data))
1915
0
    {
1916
0
      free (data);
1917
0
      return false;
1918
0
    }
1919
1920
0
  start = 0;
1921
1922
0
  for (i = start; i < stop; i += onaline)
1923
0
    {
1924
0
      bfd_vma begin_addr;
1925
0
      bfd_vma end_addr;
1926
0
      bfd_vma eh_handler;
1927
0
      bfd_vma eh_data;
1928
0
      bfd_vma prolog_end_addr;
1929
0
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
1930
0
      int em_data;
1931
0
#endif
1932
1933
0
      if (i + PDATA_ROW_SIZE > stop)
1934
0
  break;
1935
1936
0
      begin_addr      = GET_PDATA_ENTRY (abfd, data + i      );
1937
0
      end_addr        = GET_PDATA_ENTRY (abfd, data + i +  4);
1938
0
      eh_handler      = GET_PDATA_ENTRY (abfd, data + i +  8);
1939
0
      eh_data       = GET_PDATA_ENTRY (abfd, data + i + 12);
1940
0
      prolog_end_addr = GET_PDATA_ENTRY (abfd, data + i + 16);
1941
1942
0
      if (begin_addr == 0 && end_addr == 0 && eh_handler == 0
1943
0
    && eh_data == 0 && prolog_end_addr == 0)
1944
  /* We are probably into the padding of the section now.  */
1945
0
  break;
1946
1947
0
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
1948
0
      em_data = ((eh_handler & 0x1) << 2) | (prolog_end_addr & 0x3);
1949
0
#endif
1950
0
      eh_handler &= ~(bfd_vma) 0x3;
1951
0
      prolog_end_addr &= ~(bfd_vma) 0x3;
1952
1953
0
      fputc (' ', file);
1954
0
      bfd_fprintf_vma (abfd, file, i + section->vma); fputc ('\t', file);
1955
0
      bfd_fprintf_vma (abfd, file, begin_addr); fputc (' ', file);
1956
0
      bfd_fprintf_vma (abfd, file, end_addr); fputc (' ', file);
1957
0
      bfd_fprintf_vma (abfd, file, eh_handler);
1958
0
#if !defined(COFF_WITH_pep) || defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64)
1959
0
      fputc (' ', file);
1960
0
      bfd_fprintf_vma (abfd, file, eh_data); fputc (' ', file);
1961
0
      bfd_fprintf_vma (abfd, file, prolog_end_addr);
1962
0
      fprintf (file, "   %x", em_data);
1963
0
#endif
1964
0
      fprintf (file, "\n");
1965
0
    }
1966
1967
0
  free (data);
1968
1969
0
  return true;
1970
0
#undef PDATA_ROW_SIZE
1971
0
}
1972
1973
typedef struct sym_cache
1974
{
1975
  int      symcount;
1976
  asymbol ** syms;
1977
} sym_cache;
1978
1979
static asymbol **
1980
slurp_symtab (bfd *abfd, sym_cache *psc)
1981
0
{
1982
0
  asymbol ** sy = NULL;
1983
0
  long storage;
1984
1985
0
  if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
1986
0
    {
1987
0
      psc->symcount = 0;
1988
0
      return NULL;
1989
0
    }
1990
1991
0
  storage = bfd_get_symtab_upper_bound (abfd);
1992
0
  if (storage < 0)
1993
0
    return NULL;
1994
0
  if (storage)
1995
0
    {
1996
0
      sy = (asymbol **) bfd_malloc (storage);
1997
0
      if (sy == NULL)
1998
0
  return NULL;
1999
0
    }
2000
2001
0
  psc->symcount = bfd_canonicalize_symtab (abfd, sy);
2002
0
  if (psc->symcount < 0)
2003
0
    return NULL;
2004
0
  return sy;
2005
0
}
2006
2007
static const char *
2008
my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
2009
0
{
2010
0
  int i;
2011
2012
0
  if (psc->syms == 0)
2013
0
    psc->syms = slurp_symtab (abfd, psc);
2014
2015
0
  for (i = 0; i < psc->symcount; i++)
2016
0
    {
2017
0
      if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
2018
0
  return psc->syms[i]->name;
2019
0
    }
2020
2021
0
  return NULL;
2022
0
}
2023
2024
static void
2025
cleanup_syms (sym_cache *psc)
2026
0
{
2027
0
  psc->symcount = 0;
2028
0
  free (psc->syms);
2029
0
  psc->syms = NULL;
2030
0
}
2031
2032
/* This is the version for "compressed" pdata.  */
2033
2034
bool
2035
_bfd_peLoongArch64_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
137
{
2177
137
  FILE *file = (FILE *) vfile;
2178
137
  bfd_byte *data = 0;
2179
137
  asection *section = bfd_get_section_by_name (abfd, ".reloc");
2180
137
  bfd_byte *p, *end;
2181
2182
137
  if (section == NULL
2183
0
      || section->size == 0
2184
0
      || (section->flags & SEC_HAS_CONTENTS) == 0)
2185
137
    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
137
{
2473
137
  bfd_vma rva_bias;
2474
137
  pe_data_type * pe;
2475
137
  FILE * file = (FILE *) vfile;
2476
137
  bfd_size_type datasize;
2477
137
  asection * section;
2478
137
  bfd_byte * data;
2479
137
  rsrc_regions regions;
2480
2481
137
  pe = pe_data (abfd);
2482
137
  if (pe == NULL)
2483
0
    return true;
2484
2485
137
  section = bfd_get_section_by_name (abfd, ".rsrc");
2486
137
  if (section == NULL)
2487
137
    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
5.32k
#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
137
{
2584
137
  FILE *file = (FILE *) vfile;
2585
137
  pe_data_type *pe = pe_data (abfd);
2586
137
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
2587
137
  asection *section;
2588
137
  bfd_byte *data = 0;
2589
137
  bfd_size_type dataoff;
2590
137
  unsigned int i, j;
2591
2592
137
  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
2593
137
  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
2594
2595
137
  if (size == 0)
2596
82
    return true;
2597
2598
55
  addr += extra->ImageBase;
2599
725
  for (section = abfd->sections; section != NULL; section = section->next)
2600
719
    {
2601
719
      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
2602
49
  break;
2603
719
    }
2604
2605
55
  if (section == NULL)
2606
6
    {
2607
6
      fprintf (file,
2608
6
         _("\nThere is a debug directory, but the section containing it could not be found\n"));
2609
6
      return true;
2610
6
    }
2611
49
  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
49
  else if (section->size < size)
2619
1
    {
2620
1
      fprintf (file,
2621
1
         _("\nError: section %s contains the debug data starting address but it is too small\n"),
2622
1
         section->name);
2623
1
      return false;
2624
1
    }
2625
2626
48
  fprintf (file, _("\nThere is a debug directory in %s at 0x%lx\n\n"),
2627
48
     section->name, (unsigned long) addr);
2628
2629
48
  dataoff = addr - section->vma;
2630
2631
48
  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
48
  fprintf (file,
2638
48
     _("Type                Size     Rva      Offset\n"));
2639
2640
  /* Read the whole section.  */
2641
48
  if (!bfd_malloc_and_get_section (abfd, section, &data))
2642
6
    {
2643
6
      free (data);
2644
6
      return false;
2645
6
    }
2646
2647
5.36k
  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
2648
5.32k
    {
2649
5.32k
      const char *type_name;
2650
5.32k
      struct external_IMAGE_DEBUG_DIRECTORY *ext
2651
5.32k
  = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
2652
5.32k
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
2653
2654
5.32k
      _bfd_peLoongArch64i_swap_debugdir_in (abfd, ext, &idd);
2655
2656
5.32k
      if ((idd.Type) >= IMAGE_NUMBEROF_DEBUG_TYPES)
2657
3.56k
  type_name = debug_type_names[0];
2658
1.76k
      else
2659
1.76k
  type_name = debug_type_names[idd.Type];
2660
2661
5.32k
      fprintf (file, " %2ld  %14s %08lx %08lx %08lx\n",
2662
5.32k
         idd.Type, type_name, idd.SizeOfData,
2663
5.32k
         idd.AddressOfRawData, idd.PointerToRawData);
2664
2665
5.32k
      if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW)
2666
36
  {
2667
36
    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
36
    char buffer[256 + 1] ATTRIBUTE_ALIGNED_ALIGNOF (CODEVIEW_INFO);
2672
36
    char *pdb;
2673
2674
36
    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
36
    if (!_bfd_peLoongArch64i_slurp_codeview_record (abfd, (file_ptr) idd.PointerToRawData,
2679
36
                 idd.SizeOfData, cvinfo, &pdb))
2680
36
      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
5.32k
    }
2693
2694
42
  free(data);
2695
2696
42
  if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0)
2697
42
    fprintf (file,
2698
42
      _("The debug directory size is not a multiple of the debug directory entry size\n"));
2699
2700
42
  return true;
2701
48
}
2702
2703
static bool
2704
pe_is_repro (bfd * abfd)
2705
137
{
2706
137
  pe_data_type *pe = pe_data (abfd);
2707
137
  struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
2708
137
  asection *section;
2709
137
  bfd_byte *data = 0;
2710
137
  bfd_size_type dataoff;
2711
137
  unsigned int i;
2712
137
  bool res = false;
2713
2714
137
  bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress;
2715
137
  bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size;
2716
2717
137
  if (size == 0)
2718
82
    return false;
2719
2720
55
  addr += extra->ImageBase;
2721
725
  for (section = abfd->sections; section != NULL; section = section->next)
2722
719
    {
2723
719
      if ((addr >= section->vma) && (addr < (section->vma + section->size)))
2724
49
  break;
2725
719
    }
2726
2727
55
  if ((section == NULL)
2728
49
      || (!(section->flags & SEC_HAS_CONTENTS))
2729
49
      || (section->size < size))
2730
7
    {
2731
7
      return false;
2732
7
    }
2733
2734
48
  dataoff = addr - section->vma;
2735
2736
48
  if (size > (section->size - dataoff))
2737
0
    {
2738
0
      return false;
2739
0
    }
2740
2741
48
  if (!bfd_malloc_and_get_section (abfd, section, &data))
2742
6
    {
2743
6
      free (data);
2744
6
      return false;
2745
6
    }
2746
2747
2.53k
  for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
2748
2.51k
    {
2749
2.51k
      struct external_IMAGE_DEBUG_DIRECTORY *ext
2750
2.51k
  = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i];
2751
2.51k
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
2752
2753
2.51k
      _bfd_peLoongArch64i_swap_debugdir_in (abfd, ext, &idd);
2754
2755
2.51k
      if (idd.Type == PE_IMAGE_DEBUG_TYPE_REPRO)
2756
28
        {
2757
28
          res = true;
2758
28
          break;
2759
28
        }
2760
2.51k
    }
2761
2762
42
  free(data);
2763
2764
42
  return res;
2765
48
}
2766
2767
/* Print out the program headers.  */
2768
2769
bool
2770
_bfd_peLoongArch64_print_private_bfd_data_common (bfd * abfd, void * vfile)
2771
137
{
2772
137
  FILE *file = (FILE *) vfile;
2773
137
  int j;
2774
137
  pe_data_type *pe = pe_data (abfd);
2775
137
  struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
2776
137
  const char *subsystem_name = NULL;
2777
137
  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
137
  fprintf (file, _("\nCharacteristics 0x%x\n"), pe->real_flags);
2783
137
#undef PF
2784
1.91k
#define PF(x, y) if (pe->real_flags & x) { fprintf (file, "\t%s\n", y); }
2785
137
  PF (IMAGE_FILE_RELOCS_STRIPPED, "relocations stripped");
2786
137
  PF (IMAGE_FILE_EXECUTABLE_IMAGE, "executable");
2787
137
  PF (IMAGE_FILE_LINE_NUMS_STRIPPED, "line numbers stripped");
2788
137
  PF (IMAGE_FILE_LOCAL_SYMS_STRIPPED, "symbols stripped");
2789
137
  PF (IMAGE_FILE_LARGE_ADDRESS_AWARE, "large address aware");
2790
137
  PF (IMAGE_FILE_BYTES_REVERSED_LO, "little endian");
2791
137
  PF (IMAGE_FILE_32BIT_MACHINE, "32 bit words");
2792
137
  PF (IMAGE_FILE_DEBUG_STRIPPED, "debugging information removed");
2793
137
  PF (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, "copy to swap file if on removable media");
2794
137
  PF (IMAGE_FILE_NET_RUN_FROM_SWAP, "copy to swap file if on network media");
2795
137
  PF (IMAGE_FILE_SYSTEM, "system file");
2796
137
  PF (IMAGE_FILE_DLL, "DLL");
2797
137
  PF (IMAGE_FILE_UP_SYSTEM_ONLY, "run only on uniprocessor machine");
2798
137
  PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
2799
137
#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
137
  if (pe_is_repro (abfd))
2806
28
    {
2807
28
      fprintf (file, "\nTime/Date\t\t%08lx", pe->coff.timestamp);
2808
28
      fprintf (file, "\t(This is a reproducible build file hash, not a timestamp)\n");
2809
28
    }
2810
109
  else
2811
109
    {
2812
      /* ctime implies '\n'.  */
2813
109
      time_t t = pe->coff.timestamp;
2814
109
      fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
2815
109
    }
2816
2817
137
#ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
2818
137
# define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
2819
137
#endif
2820
#ifndef IMAGE_NT_OPTIONAL_HDR64_MAGIC
2821
# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
2822
#endif
2823
137
#ifndef IMAGE_NT_OPTIONAL_HDRROM_MAGIC
2824
137
# define IMAGE_NT_OPTIONAL_HDRROM_MAGIC 0x107
2825
137
#endif
2826
2827
137
  switch (i->Magic)
2828
137
    {
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
137
    default:
2839
137
      name = NULL;
2840
137
      break;
2841
137
    }
2842
137
  fprintf (file, "Magic\t\t\t%04x", i->Magic);
2843
137
  if (name)
2844
0
    fprintf (file, "\t(%s)",name);
2845
137
  fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
2846
137
  fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
2847
137
  fprintf (file, "SizeOfCode\t\t");
2848
137
  bfd_fprintf_vma (abfd, file, i->SizeOfCode);
2849
137
  fprintf (file, "\nSizeOfInitializedData\t");
2850
137
  bfd_fprintf_vma (abfd, file, i->SizeOfInitializedData);
2851
137
  fprintf (file, "\nSizeOfUninitializedData\t");
2852
137
  bfd_fprintf_vma (abfd, file, i->SizeOfUninitializedData);
2853
137
  fprintf (file, "\nAddressOfEntryPoint\t");
2854
137
  bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
2855
137
  fprintf (file, "\nBaseOfCode\t\t");
2856
137
  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
137
  fprintf (file, "\nImageBase\t\t");
2864
137
  bfd_fprintf_vma (abfd, file, i->ImageBase);
2865
137
  fprintf (file, "\nSectionAlignment\t%08x\n", i->SectionAlignment);
2866
137
  fprintf (file, "FileAlignment\t\t%08x\n", i->FileAlignment);
2867
137
  fprintf (file, "MajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
2868
137
  fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
2869
137
  fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
2870
137
  fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
2871
137
  fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
2872
137
  fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
2873
137
  fprintf (file, "Win32Version\t\t%08x\n", i->Win32Version);
2874
137
  fprintf (file, "SizeOfImage\t\t%08x\n", i->SizeOfImage);
2875
137
  fprintf (file, "SizeOfHeaders\t\t%08x\n", i->SizeOfHeaders);
2876
137
  fprintf (file, "CheckSum\t\t%08x\n", i->CheckSum);
2877
2878
137
  switch (i->Subsystem)
2879
137
    {
2880
58
    case IMAGE_SUBSYSTEM_UNKNOWN:
2881
58
      subsystem_name = "unspecified";
2882
58
      break;
2883
27
    case IMAGE_SUBSYSTEM_NATIVE:
2884
27
      subsystem_name = "NT native";
2885
27
      break;
2886
0
    case IMAGE_SUBSYSTEM_WINDOWS_GUI:
2887
0
      subsystem_name = "Windows GUI";
2888
0
      break;
2889
0
    case IMAGE_SUBSYSTEM_WINDOWS_CUI:
2890
0
      subsystem_name = "Windows CUI";
2891
0
      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
2
    case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
2909
2
      subsystem_name = "SAL runtime driver";
2910
2
      break;
2911
    /* This is from revision 8.0 of the MS PE/COFF spec  */
2912
24
    case IMAGE_SUBSYSTEM_XBOX:
2913
24
      subsystem_name = "XBOX";
2914
24
      break;
2915
    /* Added default case for clarity - subsystem_name is NULL anyway.  */
2916
26
    default:
2917
26
      subsystem_name = NULL;
2918
137
    }
2919
2920
137
  fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
2921
137
  if (subsystem_name)
2922
111
    fprintf (file, "\t(%s)", subsystem_name);
2923
137
  fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
2924
137
  if (i->DllCharacteristics)
2925
60
    {
2926
60
      unsigned short dllch = i->DllCharacteristics;
2927
60
      const char *indent = "\t\t\t\t\t";
2928
2929
60
      if (dllch & IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA)
2930
17
  fprintf (file, "%sHIGH_ENTROPY_VA\n", indent);
2931
60
      if (dllch & IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE)
2932
0
  fprintf (file, "%sDYNAMIC_BASE\n", indent);
2933
60
      if (dllch & IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY)
2934
13
  fprintf (file, "%sFORCE_INTEGRITY\n", indent);
2935
60
      if (dllch & IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
2936
0
  fprintf (file, "%sNX_COMPAT\n", indent);
2937
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_ISOLATION)
2938
14
  fprintf (file, "%sNO_ISOLATION\n", indent);
2939
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_SEH)
2940
6
  fprintf (file, "%sNO_SEH\n", indent);
2941
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_NO_BIND)
2942
2
  fprintf (file, "%sNO_BIND\n", indent);
2943
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_APPCONTAINER)
2944
23
  fprintf (file, "%sAPPCONTAINER\n", indent);
2945
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)
2946
5
  fprintf (file, "%sWDM_DRIVER\n", indent);
2947
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_GUARD_CF)
2948
4
  fprintf (file, "%sGUARD_CF\n", indent);
2949
60
      if (dllch & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE)
2950
2
  fprintf (file, "%sTERMINAL_SERVICE_AWARE\n", indent);
2951
60
    }
2952
137
  fprintf (file, "SizeOfStackReserve\t");
2953
137
  bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
2954
137
  fprintf (file, "\nSizeOfStackCommit\t");
2955
137
  bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
2956
137
  fprintf (file, "\nSizeOfHeapReserve\t");
2957
137
  bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
2958
137
  fprintf (file, "\nSizeOfHeapCommit\t");
2959
137
  bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
2960
137
  fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
2961
137
  fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
2962
137
     (unsigned long) i->NumberOfRvaAndSizes);
2963
2964
137
  fprintf (file, "\nThe Data Directory\n");
2965
2.32k
  for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
2966
2.19k
    {
2967
2.19k
      fprintf (file, "Entry %1x ", j);
2968
2.19k
      bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
2969
2.19k
      fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
2970
2.19k
      fprintf (file, "%s\n", dir_names[j]);
2971
2.19k
    }
2972
2973
137
  pe_print_idata (abfd, vfile);
2974
137
  pe_print_edata (abfd, vfile);
2975
137
  if (bfd_coff_have_print_pdata (abfd))
2976
0
    bfd_coff_print_pdata (abfd, vfile);
2977
137
  else
2978
137
    pe_print_pdata (abfd, vfile);
2979
137
  pe_print_reloc (abfd, vfile);
2980
137
  pe_print_debugdata (abfd, file);
2981
2982
137
  rsrc_print_section (abfd, vfile);
2983
2984
137
  return true;
2985
137
}
2986
2987
static bool
2988
is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
2989
130
{
2990
130
  bfd_vma addr = * (bfd_vma *) obj;
2991
130
  return (addr >= sect->vma) && (addr < (sect->vma + sect->size));
2992
130
}
2993
2994
static asection *
2995
find_section_by_vma (bfd *abfd, bfd_vma addr)
2996
79
{
2997
79
  return bfd_sections_find_if (abfd, is_vma_in_section, (void *) & addr);
2998
79
}
2999
3000
/* Copy any private info we understand from the input bfd
3001
   to the output bfd.  */
3002
3003
bool
3004
_bfd_peLoongArch64_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
3005
130
{
3006
130
  pe_data_type *ipe, *ope;
3007
130
  bfd_size_type size;
3008
3009
  /* One day we may try to grok other private data.  */
3010
130
  if (ibfd->xvec->flavour != bfd_target_coff_flavour)
3011
0
    return true;
3012
3013
130
  ipe = pe_data (ibfd);
3014
130
  ope = pe_data (obfd);
3015
3016
  /* pe_opthdr is copied in copy_object.  */
3017
130
  ope->dll = ipe->dll;
3018
3019
  /* Don't copy input subsystem if output is different from input.  */
3020
130
  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
130
  if (! pe_data (obfd)->has_reloc_section)
3026
130
    {
3027
130
      pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
3028
130
      pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
3029
130
    }
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
130
  if (! pe_data (ibfd)->has_reloc_section
3035
130
      && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
3036
85
    pe_data (obfd)->dont_strip_reloc = 1;
3037
3038
130
  memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
3039
3040
  /* The file offsets contained in the debug directory need rewriting.  */
3041
130
  size = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size;
3042
130
  if (size != 0)
3043
73
    {
3044
73
      bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
3045
73
  + 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
73
      bfd_vma last = addr + size - 1;
3052
73
      asection *section = find_section_by_vma (obfd, last);
3053
3054
73
      if (section != NULL)
3055
8
  {
3056
8
    bfd_byte *data;
3057
8
    bfd_vma dataoff = addr - section->vma;
3058
3059
    /* PR 17512: file: 0f15796a.  */
3060
8
    if (addr < section->vma
3061
7
        || section->size < dataoff
3062
5
        || section->size - dataoff < size)
3063
3
      {
3064
        /* xgettext:c-format */
3065
3
        _bfd_error_handler
3066
3
    (_("%pB: Data Directory (%lx bytes at %" PRIx64 ") "
3067
3
       "extends across section boundary at %" PRIx64),
3068
3
     obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
3069
3
     (uint64_t) addr, (uint64_t) section->vma);
3070
3
        return false;
3071
3
      }
3072
3073
5
    if ((section->flags & SEC_HAS_CONTENTS) != 0
3074
4
        && bfd_malloc_and_get_section (obfd, section, &data))
3075
4
      {
3076
4
        unsigned int i;
3077
4
        struct external_IMAGE_DEBUG_DIRECTORY *dd =
3078
4
    (struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff);
3079
3080
22
        for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
3081
22
         / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
3082
18
    {
3083
18
      asection *ddsection;
3084
18
      struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
3085
18
      struct internal_IMAGE_DEBUG_DIRECTORY idd;
3086
18
      bfd_vma idd_vma;
3087
3088
18
      _bfd_peLoongArch64i_swap_debugdir_in (obfd, edd, &idd);
3089
3090
      /* RVA 0 means only offset is valid, not handled yet.  */
3091
18
      if (idd.AddressOfRawData == 0)
3092
12
        continue;
3093
3094
6
      idd_vma = idd.AddressOfRawData + ope->pe_opthdr.ImageBase;
3095
6
      ddsection = find_section_by_vma (obfd, idd_vma);
3096
6
      if (!ddsection)
3097
4
        continue; /* Not in a section! */
3098
3099
2
      idd.PointerToRawData
3100
2
        = ddsection->filepos + idd_vma - ddsection->vma;
3101
2
      _bfd_peLoongArch64i_swap_debugdir_out (obfd, &idd, edd);
3102
2
    }
3103
3104
4
        if (!bfd_set_section_contents (obfd, section, data, 0,
3105
4
               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
4
        free (data);
3113
4
      }
3114
1
    else
3115
1
      {
3116
1
        _bfd_error_handler (_("%pB: failed to read "
3117
1
            "debug data section"), obfd);
3118
1
        return false;
3119
1
      }
3120
5
  }
3121
73
    }
3122
3123
126
  return true;
3124
130
}
3125
3126
/* Copy private section data.  */
3127
3128
bool
3129
_bfd_peLoongArch64_bfd_copy_private_section_data (bfd *ibfd,
3130
               asection *isec,
3131
               bfd *obfd,
3132
               asection *osec,
3133
               struct bfd_link_info *link_info)
3134
180
{
3135
180
  if (link_info != NULL
3136
180
      || bfd_get_flavour (ibfd) != bfd_target_coff_flavour)
3137
0
    return true;
3138
3139
180
  if (coff_section_data (ibfd, isec) != NULL
3140
173
      && pei_section_data (ibfd, isec) != NULL)
3141
130
    {
3142
130
      if (coff_section_data (obfd, osec) == NULL)
3143
130
  {
3144
130
    size_t amt = sizeof (struct coff_section_tdata);
3145
130
    osec->used_by_bfd = bfd_zalloc (obfd, amt);
3146
130
    if (osec->used_by_bfd == NULL)
3147
0
      return false;
3148
130
  }
3149
3150
130
      if (pei_section_data (obfd, osec) == NULL)
3151
130
  {
3152
130
    size_t amt = sizeof (struct pei_section_tdata);
3153
130
    coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
3154
130
    if (coff_section_data (obfd, osec)->tdata == NULL)
3155
0
      return false;
3156
130
  }
3157
3158
130
      pei_section_data (obfd, osec)->virt_size =
3159
130
  pei_section_data (ibfd, isec)->virt_size;
3160
130
      pei_section_data (obfd, osec)->pe_flags =
3161
130
  pei_section_data (ibfd, isec)->pe_flags;
3162
130
    }
3163
3164
180
  return true;
3165
180
}
3166
3167
void
3168
_bfd_peLoongArch64_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
3169
156
{
3170
156
  coff_get_symbol_info (abfd, symbol, ret);
3171
156
}
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_peLoongArch64i_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
}