Coverage Report

Created: 2023-08-28 06:31

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