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