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