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