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");
2723 PF (IMAGE_FILE_SYSTEM, "system file");
2724 PF (IMAGE_FILE_DLL, "DLL");
2725 PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian");
277d1b5e
ILT
2726#undef PF
2727
b5d36aaa
JT
2728 /*
2729 If a PE_IMAGE_DEBUG_TYPE_REPRO entry is present in the debug directory, the
2730 timestamp is to be interpreted as the hash of a reproducible build.
2731 */
2732 if (pe_is_repro (abfd))
2733 {
2734 fprintf (file, "\nTime/Date\t\t%08lx", pe->coff.timestamp);
2735 fprintf (file, "\t(This is a reproducible build file hash, not a timestamp)\n");
2736 }
2737 else
2738 {
2739 /* ctime implies '\n'. */
2740 time_t t = pe->coff.timestamp;
2741 fprintf (file, "\nTime/Date\t\t%s", ctime (&t));
2742 }
d13c9dc6
L
2743
2744#ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC
2745# define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
2746#endif
2747#ifndef IMAGE_NT_OPTIONAL_HDR64_MAGIC
2748# define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
2749#endif
2750#ifndef IMAGE_NT_OPTIONAL_HDRROM_MAGIC
2751# define IMAGE_NT_OPTIONAL_HDRROM_MAGIC 0x107
2752#endif
2753
2754 switch (i->Magic)
2755 {
2756 case IMAGE_NT_OPTIONAL_HDR_MAGIC:
2757 name = "PE32";
2758 break;
2759 case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
2760 name = "PE32+";
2761 break;
2762 case IMAGE_NT_OPTIONAL_HDRROM_MAGIC:
2763 name = "ROM";
2764 break;
2765 default:
2766 name = NULL;
2767 break;
2768 }
2769 fprintf (file, "Magic\t\t\t%04x", i->Magic);
2770 if (name)
2771 fprintf (file, "\t(%s)",name);
2772 fprintf (file, "\nMajorLinkerVersion\t%d\n", i->MajorLinkerVersion);
2773 fprintf (file, "MinorLinkerVersion\t%d\n", i->MinorLinkerVersion);
b24cc414
AM
2774 fprintf (file, "SizeOfCode\t\t");
2775 bfd_fprintf_vma (abfd, file, i->SizeOfCode);
2776 fprintf (file, "\nSizeOfInitializedData\t");
2777 bfd_fprintf_vma (abfd, file, i->SizeOfInitializedData);
2778 fprintf (file, "\nSizeOfUninitializedData\t");
2779 bfd_fprintf_vma (abfd, file, i->SizeOfUninitializedData);
2780 fprintf (file, "\nAddressOfEntryPoint\t");
ebf12fbe 2781 bfd_fprintf_vma (abfd, file, i->AddressOfEntryPoint);
d13c9dc6 2782 fprintf (file, "\nBaseOfCode\t\t");
ebf12fbe 2783 bfd_fprintf_vma (abfd, file, i->BaseOfCode);
d13c9dc6
L
2784#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
2785 /* PE32+ does not have BaseOfData member! */
2786 fprintf (file, "\nBaseOfData\t\t");
ebf12fbe 2787 bfd_fprintf_vma (abfd, file, i->BaseOfData);
d13c9dc6
L
2788#endif
2789
9602af51 2790 fprintf (file, "\nImageBase\t\t");
ebf12fbe 2791 bfd_fprintf_vma (abfd, file, i->ImageBase);
b24cc414
AM
2792 fprintf (file, "\nSectionAlignment\t%08x\n", i->SectionAlignment);
2793 fprintf (file, "FileAlignment\t\t%08x\n", i->FileAlignment);
2794 fprintf (file, "MajorOSystemVersion\t%d\n", i->MajorOperatingSystemVersion);
9602af51
KH
2795 fprintf (file, "MinorOSystemVersion\t%d\n", i->MinorOperatingSystemVersion);
2796 fprintf (file, "MajorImageVersion\t%d\n", i->MajorImageVersion);
2797 fprintf (file, "MinorImageVersion\t%d\n", i->MinorImageVersion);
2798 fprintf (file, "MajorSubsystemVersion\t%d\n", i->MajorSubsystemVersion);
2799 fprintf (file, "MinorSubsystemVersion\t%d\n", i->MinorSubsystemVersion);
b24cc414
AM
2800 fprintf (file, "Win32Version\t\t%08x\n", i->Reserved1);
2801 fprintf (file, "SizeOfImage\t\t%08x\n", i->SizeOfImage);
2802 fprintf (file, "SizeOfHeaders\t\t%08x\n", i->SizeOfHeaders);
2803 fprintf (file, "CheckSum\t\t%08x\n", i->CheckSum);
1725a96e 2804
fac41780
JW
2805 switch (i->Subsystem)
2806 {
2807 case IMAGE_SUBSYSTEM_UNKNOWN:
2808 subsystem_name = "unspecified";
2809 break;
2810 case IMAGE_SUBSYSTEM_NATIVE:
2811 subsystem_name = "NT native";
2812 break;
2813 case IMAGE_SUBSYSTEM_WINDOWS_GUI:
2814 subsystem_name = "Windows GUI";
2815 break;
2816 case IMAGE_SUBSYSTEM_WINDOWS_CUI:
2817 subsystem_name = "Windows CUI";
2818 break;
2819 case IMAGE_SUBSYSTEM_POSIX_CUI:
2820 subsystem_name = "POSIX CUI";
2821 break;
2822 case IMAGE_SUBSYSTEM_WINDOWS_CE_GUI:
2823 subsystem_name = "Wince CUI";
2824 break;
279edac5 2825 /* These are from UEFI Platform Initialization Specification 1.1. */
fac41780
JW
2826 case IMAGE_SUBSYSTEM_EFI_APPLICATION:
2827 subsystem_name = "EFI application";
2828 break;
2829 case IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
2830 subsystem_name = "EFI boot service driver";
2831 break;
2832 case IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
9602af51 2833 subsystem_name = "EFI runtime driver";
fac41780 2834 break;
d9118602
L
2835 case IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
2836 subsystem_name = "SAL runtime driver";
6c73cbb1 2837 break;
279edac5 2838 /* This is from revision 8.0 of the MS PE/COFF spec */
6c73cbb1
NC
2839 case IMAGE_SUBSYSTEM_XBOX:
2840 subsystem_name = "XBOX";
2841 break;
279edac5 2842 /* Added default case for clarity - subsystem_name is NULL anyway. */
6c73cbb1
NC
2843 default:
2844 subsystem_name = NULL;
fac41780 2845 }
1725a96e 2846
9602af51 2847 fprintf (file, "Subsystem\t\t%08x", i->Subsystem);
fac41780
JW
2848 if (subsystem_name)
2849 fprintf (file, "\t(%s)", subsystem_name);
9602af51
KH
2850 fprintf (file, "\nDllCharacteristics\t%08x\n", i->DllCharacteristics);
2851 fprintf (file, "SizeOfStackReserve\t");
ebf12fbe 2852 bfd_fprintf_vma (abfd, file, i->SizeOfStackReserve);
9602af51 2853 fprintf (file, "\nSizeOfStackCommit\t");
ebf12fbe 2854 bfd_fprintf_vma (abfd, file, i->SizeOfStackCommit);
9602af51 2855 fprintf (file, "\nSizeOfHeapReserve\t");
ebf12fbe 2856 bfd_fprintf_vma (abfd, file, i->SizeOfHeapReserve);
9602af51 2857 fprintf (file, "\nSizeOfHeapCommit\t");
ebf12fbe 2858 bfd_fprintf_vma (abfd, file, i->SizeOfHeapCommit);
0af1713e
AM
2859 fprintf (file, "\nLoaderFlags\t\t%08lx\n", (unsigned long) i->LoaderFlags);
2860 fprintf (file, "NumberOfRvaAndSizes\t%08lx\n",
2861 (unsigned long) i->NumberOfRvaAndSizes);
277d1b5e 2862
9602af51 2863 fprintf (file, "\nThe Data Directory\n");
277d1b5e
ILT
2864 for (j = 0; j < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; j++)
2865 {
2866 fprintf (file, "Entry %1x ", j);
ebf12fbe 2867 bfd_fprintf_vma (abfd, file, i->DataDirectory[j].VirtualAddress);
0af1713e 2868 fprintf (file, " %08lx ", (unsigned long) i->DataDirectory[j].Size);
277d1b5e
ILT
2869 fprintf (file, "%s\n", dir_names[j]);
2870 }
2871
2872 pe_print_idata (abfd, vfile);
2873 pe_print_edata (abfd, vfile);
2b5c217d
NC
2874 if (bfd_coff_have_print_pdata (abfd))
2875 bfd_coff_print_pdata (abfd, vfile);
2876 else
2877 pe_print_pdata (abfd, vfile);
277d1b5e 2878 pe_print_reloc (abfd, vfile);
61e2488c 2879 pe_print_debugdata (abfd, file);
277d1b5e 2880
5879bb8f 2881 rsrc_print_section (abfd, vfile);
9373215c 2882
0a1b45a2 2883 return true;
277d1b5e
ILT
2884}
2885
0a1b45a2 2886static bool
6e6e7cfc
JT
2887is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
2888{
2889 bfd_vma addr = * (bfd_vma *) obj;
2890 return (addr >= sect->vma) && (addr < (sect->vma + sect->size));
2891}
2892
2893static asection *
2894find_section_by_vma (bfd *abfd, bfd_vma addr)
2895{
2896 return bfd_sections_find_if (abfd, is_vma_in_section, (void *) & addr);
2897}
2898
277d1b5e
ILT
2899/* Copy any private info we understand from the input bfd
2900 to the output bfd. */
2901
0a1b45a2 2902bool
7920ce38 2903_bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
277d1b5e 2904{
4be8cddc
L
2905 pe_data_type *ipe, *ope;
2906
277d1b5e
ILT
2907 /* One day we may try to grok other private data. */
2908 if (ibfd->xvec->flavour != bfd_target_coff_flavour
2909 || obfd->xvec->flavour != bfd_target_coff_flavour)
0a1b45a2 2910 return true;
277d1b5e 2911
4be8cddc
L
2912 ipe = pe_data (ibfd);
2913 ope = pe_data (obfd);
4e1fc599 2914
325c681d 2915 /* pe_opthdr is copied in copy_object. */
4be8cddc
L
2916 ope->dll = ipe->dll;
2917
2918 /* Don't copy input subsystem if output is different from input. */
2919 if (obfd->xvec != ibfd->xvec)
2920 ope->pe_opthdr.Subsystem = IMAGE_SUBSYSTEM_UNKNOWN;
277d1b5e 2921
1725a96e 2922 /* For strip: if we removed .reloc, we'll make a real mess of things
5933bdc9
ILT
2923 if we don't remove this entry as well. */
2924 if (! pe_data (obfd)->has_reloc_section)
2925 {
6c73cbb1
NC
2926 pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].VirtualAddress = 0;
2927 pe_data (obfd)->pe_opthdr.DataDirectory[PE_BASE_RELOCATION_TABLE].Size = 0;
5933bdc9 2928 }
441f34fa
L
2929
2930 /* For PIE, if there is .reloc, we won't add IMAGE_FILE_RELOCS_STRIPPED.
2931 But there is no .reloc, we make sure that IMAGE_FILE_RELOCS_STRIPPED
2932 won't be added. */
2933 if (! pe_data (ibfd)->has_reloc_section
2934 && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
2935 pe_data (obfd)->dont_strip_reloc = 1;
2936
70cf6834
AE
2937 memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message));
2938
6e6e7cfc
JT
2939 /* The file offsets contained in the debug directory need rewriting. */
2940 if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0)
2941 {
2942 bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress
2943 + ope->pe_opthdr.ImageBase;
610ed3e0
JB
2944 /* In particular a .buildid section may overlap (in VA space) with
2945 whatever section comes ahead of it (largely because of section->size
2946 representing s_size, not virt_size). Therefore don't look for the
2947 section containing the first byte, but for that covering the last
2948 one. */
2949 bfd_vma last = addr + ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size - 1;
2950 asection *section = find_section_by_vma (obfd, last);
6e6e7cfc
JT
2951 bfd_byte *data;
2952
610ed3e0
JB
2953 /* PR 17512: file: 0f15796a. */
2954 if (section && addr < section->vma)
2955 {
2956 /* xgettext:c-format */
2957 _bfd_error_handler
2958 (_("%pB: Data Directory (%lx bytes at %" PRIx64 ") "
2959 "extends across section boundary at %" PRIx64),
2960 obfd, ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size,
2961 (uint64_t) addr, (uint64_t) section->vma);
0a1b45a2 2962 return false;
610ed3e0
JB
2963 }
2964
6e6e7cfc 2965 if (section && bfd_malloc_and_get_section (obfd, section, &data))
07d6d2b8
AM
2966 {
2967 unsigned int i;
2968 struct external_IMAGE_DEBUG_DIRECTORY *dd =
6e6e7cfc
JT
2969 (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
2970
07d6d2b8 2971 for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size
6e6e7cfc 2972 / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
07d6d2b8
AM
2973 {
2974 asection *ddsection;
2975 struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
2976 struct internal_IMAGE_DEBUG_DIRECTORY idd;
6e6e7cfc 2977
07d6d2b8 2978 _bfd_XXi_swap_debugdir_in (obfd, edd, &idd);
6e6e7cfc 2979
07d6d2b8
AM
2980 if (idd.AddressOfRawData == 0)
2981 continue; /* RVA 0 means only offset is valid, not handled yet. */
6e6e7cfc 2982
07d6d2b8
AM
2983 ddsection = find_section_by_vma (obfd, idd.AddressOfRawData + ope->pe_opthdr.ImageBase);
2984 if (!ddsection)
2985 continue; /* Not in a section! */
6e6e7cfc 2986
07d6d2b8 2987 idd.PointerToRawData = ddsection->filepos + (idd.AddressOfRawData
6e6e7cfc
JT
2988 + ope->pe_opthdr.ImageBase) - ddsection->vma;
2989
07d6d2b8
AM
2990 _bfd_XXi_swap_debugdir_out (obfd, &idd, edd);
2991 }
6e6e7cfc 2992
07d6d2b8 2993 if (!bfd_set_section_contents (obfd, section, data, 0, section->size))
86eafac0 2994 {
59d08d6c 2995 _bfd_error_handler (_("failed to update file offsets in debug directory"));
8df73d5c 2996 free (data);
0a1b45a2 2997 return false;
86eafac0 2998 }
8df73d5c 2999 free (data);
07d6d2b8 3000 }
86eafac0
NC
3001 else if (section)
3002 {
59d08d6c 3003 _bfd_error_handler (_("%pB: failed to read debug data section"), obfd);
0a1b45a2 3004 return false;
86eafac0 3005 }
6e6e7cfc
JT
3006 }
3007
0a1b45a2 3008 return true;
277d1b5e
ILT
3009}
3010
9602af51 3011/* Copy private section data. */
1725a96e 3012
0a1b45a2 3013bool
7920ce38
NC
3014_bfd_XX_bfd_copy_private_section_data (bfd *ibfd,
3015 asection *isec,
3016 bfd *obfd,
3017 asection *osec)
277d1b5e
ILT
3018{
3019 if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour
3020 || bfd_get_flavour (obfd) != bfd_target_coff_flavour)
0a1b45a2 3021 return true;
277d1b5e
ILT
3022
3023 if (coff_section_data (ibfd, isec) != NULL
3024 && pei_section_data (ibfd, isec) != NULL)
3025 {
3026 if (coff_section_data (obfd, osec) == NULL)
3027 {
986f0783 3028 size_t amt = sizeof (struct coff_section_tdata);
7920ce38 3029 osec->used_by_bfd = bfd_zalloc (obfd, amt);
277d1b5e 3030 if (osec->used_by_bfd == NULL)
0a1b45a2 3031 return false;
277d1b5e 3032 }
1725a96e 3033
277d1b5e
ILT
3034 if (pei_section_data (obfd, osec) == NULL)
3035 {
986f0783 3036 size_t amt = sizeof (struct pei_section_tdata);
7920ce38 3037 coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt);
277d1b5e 3038 if (coff_section_data (obfd, osec)->tdata == NULL)
0a1b45a2 3039 return false;
277d1b5e 3040 }
1725a96e 3041
277d1b5e
ILT
3042 pei_section_data (obfd, osec)->virt_size =
3043 pei_section_data (ibfd, isec)->virt_size;
5933bdc9 3044 pei_section_data (obfd, osec)->pe_flags =
6fa957a9 3045 pei_section_data (ibfd, isec)->pe_flags;
277d1b5e
ILT
3046 }
3047
0a1b45a2 3048 return true;
277d1b5e 3049}
7d2b58d6
ILT
3050
3051void
7920ce38 3052_bfd_XX_get_symbol_info (bfd * abfd, asymbol *symbol, symbol_info *ret)
7d2b58d6
ILT
3053{
3054 coff_get_symbol_info (abfd, symbol, ret);
7d2b58d6 3055}
2fbadf2c 3056
5174d0fb
KT
3057#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
3058static int
3059sort_x64_pdata (const void *l, const void *r)
3060{
3061 const char *lp = (const char *) l;
3062 const char *rp = (const char *) r;
3063 bfd_vma vl, vr;
3064 vl = bfd_getl32 (lp); vr = bfd_getl32 (rp);
3065 if (vl != vr)
3066 return (vl < vr ? -1 : 1);
3067 /* We compare just begin address. */
3068 return 0;
3069}
3070#endif
5879bb8f
NC
3071\f
3072/* Functions to process a .rsrc section. */
3073
3074static unsigned int sizeof_leaves;
3075static unsigned int sizeof_strings;
3076static unsigned int sizeof_tables_and_entries;
3077
3078static bfd_byte *
3079rsrc_count_directory (bfd *, bfd_byte *, bfd_byte *, bfd_byte *, bfd_vma);
3080
3081static bfd_byte *
0a1b45a2
AM
3082rsrc_count_entries (bfd *abfd,
3083 bool is_name,
3084 bfd_byte *datastart,
3085 bfd_byte *data,
3086 bfd_byte *dataend,
3087 bfd_vma rva_bias)
5879bb8f
NC
3088{
3089 unsigned long entry, addr, size;
3090
3091 if (data + 8 >= dataend)
3092 return dataend + 1;
3093
3094 if (is_name)
3095 {
3096 bfd_byte * name;
3097
3098 entry = (long) bfd_get_32 (abfd, data);
3099
3100 if (HighBitSet (entry))
3101 name = datastart + WithoutHighBit (entry);
3102 else
3103 name = datastart + entry - rva_bias;
3104
20ad5e28 3105 if (name + 2 >= dataend || name < datastart)
5879bb8f
NC
3106 return dataend + 1;
3107
3108 unsigned int len = bfd_get_16 (abfd, name);
3109 if (len == 0 || len > 256)
3110 return dataend + 1;
5879bb8f
NC
3111 }
3112
3113 entry = (long) bfd_get_32 (abfd, data + 4);
3114
3115 if (HighBitSet (entry))
20ad5e28
NC
3116 {
3117 data = datastart + WithoutHighBit (entry);
3118
3119 if (data <= datastart || data >= dataend)
3120 return dataend + 1;
3121
3122 return rsrc_count_directory (abfd, datastart, data, dataend, rva_bias);
3123 }
5879bb8f
NC
3124
3125 if (datastart + entry + 16 >= dataend)
3126 return dataend + 1;
3127
3128 addr = (long) bfd_get_32 (abfd, datastart + entry);
3129 size = (long) bfd_get_32 (abfd, datastart + entry + 4);
3130
5879bb8f
NC
3131 return datastart + addr - rva_bias + size;
3132}
9373215c 3133
5879bb8f 3134static bfd_byte *
07d6d2b8 3135rsrc_count_directory (bfd * abfd,
5879bb8f
NC
3136 bfd_byte * datastart,
3137 bfd_byte * data,
3138 bfd_byte * dataend,
07d6d2b8 3139 bfd_vma rva_bias)
5879bb8f
NC
3140{
3141 unsigned int num_entries, num_ids;
3142 bfd_byte * highest_data = data;
3143
3144 if (data + 16 >= dataend)
3145 return dataend + 1;
3146
3147 num_entries = (int) bfd_get_16 (abfd, data + 12);
3148 num_ids = (int) bfd_get_16 (abfd, data + 14);
3149
3150 num_entries += num_ids;
3151
3152 data += 16;
5879bb8f
NC
3153
3154 while (num_entries --)
3155 {
3156 bfd_byte * entry_end;
3157
3158 entry_end = rsrc_count_entries (abfd, num_entries >= num_ids,
3159 datastart, data, dataend, rva_bias);
3160 data += 8;
5879bb8f
NC
3161 highest_data = max (highest_data, entry_end);
3162 if (entry_end >= dataend)
3163 break;
3164 }
3165
3166 return max (highest_data, data);
3167}
3168
3169typedef struct rsrc_dir_chain
3170{
07d6d2b8 3171 unsigned int num_entries;
5879bb8f
NC
3172 struct rsrc_entry * first_entry;
3173 struct rsrc_entry * last_entry;
3174} rsrc_dir_chain;
3175
3176typedef struct rsrc_directory
3177{
3178 unsigned int characteristics;
3179 unsigned int time;
3180 unsigned int major;
3181 unsigned int minor;
3182
3183 rsrc_dir_chain names;
3184 rsrc_dir_chain ids;
3185
3186 struct rsrc_entry * entry;
3187} rsrc_directory;
3188
3189typedef struct rsrc_string
3190{
07d6d2b8
AM
3191 unsigned int len;
3192 bfd_byte * string;
5879bb8f 3193} rsrc_string;
9373215c 3194
5879bb8f
NC
3195typedef struct rsrc_leaf
3196{
07d6d2b8
AM
3197 unsigned int size;
3198 unsigned int codepage;
3199 bfd_byte * data;
5879bb8f
NC
3200} rsrc_leaf;
3201
3202typedef struct rsrc_entry
3203{
0a1b45a2 3204 bool is_name;
5879bb8f
NC
3205 union
3206 {
07d6d2b8
AM
3207 unsigned int id;
3208 struct rsrc_string name;
5879bb8f
NC
3209 } name_id;
3210
0a1b45a2 3211 bool is_dir;
5879bb8f
NC
3212 union
3213 {
3214 struct rsrc_directory * directory;
07d6d2b8 3215 struct rsrc_leaf * leaf;
5879bb8f
NC
3216 } value;
3217
07d6d2b8 3218 struct rsrc_entry * next_entry;
5879bb8f
NC
3219 struct rsrc_directory * parent;
3220} rsrc_entry;
3221
3222static bfd_byte *
3223rsrc_parse_directory (bfd *, rsrc_directory *, bfd_byte *,
3224 bfd_byte *, bfd_byte *, bfd_vma, rsrc_entry *);
3225
3226static bfd_byte *
0a1b45a2
AM
3227rsrc_parse_entry (bfd *abfd,
3228 bool is_name,
3229 rsrc_entry *entry,
3230 bfd_byte *datastart,
3231 bfd_byte * data,
3232 bfd_byte *dataend,
3233 bfd_vma rva_bias,
3234 rsrc_directory *parent)
5879bb8f
NC
3235{
3236 unsigned long val, addr, size;
3237
3238 val = bfd_get_32 (abfd, data);
3239
3240 entry->parent = parent;
3241 entry->is_name = is_name;
3242
3243 if (is_name)
3244 {
20ad5e28
NC
3245 bfd_byte * address;
3246
5879bb8f
NC
3247 if (HighBitSet (val))
3248 {
3249 val = WithoutHighBit (val);
3250
20ad5e28 3251 address = datastart + val;
5879bb8f
NC
3252 }
3253 else
3254 {
20ad5e28 3255 address = datastart + val - rva_bias;
5879bb8f 3256 }
20ad5e28
NC
3257
3258 if (address + 3 > dataend)
3259 return dataend;
3260
3261 entry->name_id.name.len = bfd_get_16 (abfd, address);
3262 entry->name_id.name.string = address + 2;
5879bb8f
NC
3263 }
3264 else
3265 entry->name_id.id = val;
3266
3267 val = bfd_get_32 (abfd, data + 4);
3268
3269 if (HighBitSet (val))
3270 {
0a1b45a2 3271 entry->is_dir = true;
5879bb8f
NC
3272 entry->value.directory = bfd_malloc (sizeof * entry->value.directory);
3273 if (entry->value.directory == NULL)
3274 return dataend;
3275
3276 return rsrc_parse_directory (abfd, entry->value.directory,
3277 datastart,
3278 datastart + WithoutHighBit (val),
3279 dataend, rva_bias, entry);
3280 }
3281
0a1b45a2 3282 entry->is_dir = false;
5879bb8f
NC
3283 entry->value.leaf = bfd_malloc (sizeof * entry->value.leaf);
3284 if (entry->value.leaf == NULL)
3285 return dataend;
3286
5929c344
NC
3287 data = datastart + val;
3288 if (data < datastart || data >= dataend)
3289 return dataend;
3290
3291 addr = bfd_get_32 (abfd, data);
3292 size = entry->value.leaf->size = bfd_get_32 (abfd, data + 4);
3293 entry->value.leaf->codepage = bfd_get_32 (abfd, data + 8);
3294 /* FIXME: We assume that the reserved field (data + 12) is OK. */
5879bb8f
NC
3295
3296 entry->value.leaf->data = bfd_malloc (size);
3297 if (entry->value.leaf->data == NULL)
3298 return dataend;
3299
3300 memcpy (entry->value.leaf->data, datastart + addr - rva_bias, size);
3301 return datastart + (addr - rva_bias) + size;
3302}
3303
3304static bfd_byte *
0a1b45a2
AM
3305rsrc_parse_entries (bfd *abfd,
3306 rsrc_dir_chain *chain,
3307 bool is_name,
3308 bfd_byte *highest_data,
3309 bfd_byte *datastart,
3310 bfd_byte *data,
3311 bfd_byte *dataend,
3312 bfd_vma rva_bias,
3313 rsrc_directory *parent)
5879bb8f 3314{
9373215c 3315 unsigned int i;
5879bb8f
NC
3316 rsrc_entry * entry;
3317
3318 if (chain->num_entries == 0)
3319 {
3320 chain->first_entry = chain->last_entry = NULL;
3321 return highest_data;
3322 }
3323
3324 entry = bfd_malloc (sizeof * entry);
3325 if (entry == NULL)
3326 return dataend;
3327
3328 chain->first_entry = entry;
3329
5879bb8f
NC
3330 for (i = chain->num_entries; i--;)
3331 {
3332 bfd_byte * entry_end;
3333
3334 entry_end = rsrc_parse_entry (abfd, is_name, entry, datastart,
3335 data, dataend, rva_bias, parent);
3336 data += 8;
3337 highest_data = max (entry_end, highest_data);
3338 if (entry_end > dataend)
3339 return dataend;
3340
3341 if (i)
3342 {
3343 entry->next_entry = bfd_malloc (sizeof * entry);
3344 entry = entry->next_entry;
3345 if (entry == NULL)
3346 return dataend;
3347 }
3348 else
3349 entry->next_entry = NULL;
3350 }
3351
3352 chain->last_entry = entry;
3353
3354 return highest_data;
3355}
3356
3357static bfd_byte *
07d6d2b8 3358rsrc_parse_directory (bfd * abfd,
5879bb8f
NC
3359 rsrc_directory * table,
3360 bfd_byte * datastart,
3361 bfd_byte * data,
3362 bfd_byte * dataend,
07d6d2b8 3363 bfd_vma rva_bias,
5879bb8f
NC
3364 rsrc_entry * entry)
3365{
3366 bfd_byte * highest_data = data;
3367
3368 if (table == NULL)
3369 return dataend;
3370
3371 table->characteristics = bfd_get_32 (abfd, data);
3372 table->time = bfd_get_32 (abfd, data + 4);
3373 table->major = bfd_get_16 (abfd, data + 8);
3374 table->minor = bfd_get_16 (abfd, data + 10);
3375 table->names.num_entries = bfd_get_16 (abfd, data + 12);
3376 table->ids.num_entries = bfd_get_16 (abfd, data + 14);
3377 table->entry = entry;
3378
3379 data += 16;
3380
0a1b45a2 3381 highest_data = rsrc_parse_entries (abfd, & table->names, true, data,
5879bb8f
NC
3382 datastart, data, dataend, rva_bias, table);
3383 data += table->names.num_entries * 8;
3384
0a1b45a2 3385 highest_data = rsrc_parse_entries (abfd, & table->ids, false, highest_data,
5879bb8f
NC
3386 datastart, data, dataend, rva_bias, table);
3387 data += table->ids.num_entries * 8;
3388
3389 return max (highest_data, data);
3390}
3391
3392typedef struct rsrc_write_data
3393{
3394 bfd * abfd;
3395 bfd_byte * datastart;
3396 bfd_byte * next_table;
3397 bfd_byte * next_leaf;
3398 bfd_byte * next_string;
3399 bfd_byte * next_data;
3400 bfd_vma rva_bias;
9373215c
PM
3401} rsrc_write_data;
3402
5879bb8f
NC
3403static void
3404rsrc_write_string (rsrc_write_data * data,
3405 rsrc_string * string)
3406{
3407 bfd_put_16 (data->abfd, string->len, data->next_string);
3408 memcpy (data->next_string + 2, string->string, string->len * 2);
3409 data->next_string += (string->len + 1) * 2;
3410}
3411
3412static inline unsigned int
3413rsrc_compute_rva (rsrc_write_data * data,
07d6d2b8 3414 bfd_byte * addr)
5879bb8f
NC
3415{
3416 return (addr - data->datastart) + data->rva_bias;
3417}
3418
3419static void
3420rsrc_write_leaf (rsrc_write_data * data,
07d6d2b8 3421 rsrc_leaf * leaf)
5879bb8f 3422{
9373215c
PM
3423 bfd_put_32 (data->abfd, rsrc_compute_rva (data, data->next_data),
3424 data->next_leaf);
5879bb8f
NC
3425 bfd_put_32 (data->abfd, leaf->size, data->next_leaf + 4);
3426 bfd_put_32 (data->abfd, leaf->codepage, data->next_leaf + 8);
3427 bfd_put_32 (data->abfd, 0 /*reserved*/, data->next_leaf + 12);
3428 data->next_leaf += 16;
3429
3430 memcpy (data->next_data, leaf->data, leaf->size);
3714081c
NC
3431 /* An undocumented feature of Windows resources is that each unit
3432 of raw data is 8-byte aligned... */
3433 data->next_data += ((leaf->size + 7) & ~7);
5879bb8f
NC
3434}
3435
3436static void rsrc_write_directory (rsrc_write_data *, rsrc_directory *);
3437
3438static void
3439rsrc_write_entry (rsrc_write_data * data,
07d6d2b8
AM
3440 bfd_byte * where,
3441 rsrc_entry * entry)
5879bb8f
NC
3442{
3443 if (entry->is_name)
3444 {
3445 bfd_put_32 (data->abfd,
3446 SetHighBit (data->next_string - data->datastart),
3447 where);
3448 rsrc_write_string (data, & entry->name_id.name);
3449 }
3450 else
3451 bfd_put_32 (data->abfd, entry->name_id.id, where);
3452
3453 if (entry->is_dir)
3454 {
3455 bfd_put_32 (data->abfd,
3456 SetHighBit (data->next_table - data->datastart),
3457 where + 4);
3458 rsrc_write_directory (data, entry->value.directory);
3459 }
3460 else
3461 {
3462 bfd_put_32 (data->abfd, data->next_leaf - data->datastart, where + 4);
3463 rsrc_write_leaf (data, entry->value.leaf);
3464 }
3465}
3466
3714081c
NC
3467static void
3468rsrc_compute_region_sizes (rsrc_directory * dir)
3469{
3470 struct rsrc_entry * entry;
3471
3472 if (dir == NULL)
3473 return;
3474
3475 sizeof_tables_and_entries += 16;
3476
3477 for (entry = dir->names.first_entry; entry != NULL; entry = entry->next_entry)
3478 {
3479 sizeof_tables_and_entries += 8;
3480
3481 sizeof_strings += (entry->name_id.name.len + 1) * 2;
1b786873 3482
3714081c
NC
3483 if (entry->is_dir)
3484 rsrc_compute_region_sizes (entry->value.directory);
3485 else
3486 sizeof_leaves += 16;
3487 }
3488
3489 for (entry = dir->ids.first_entry; entry != NULL; entry = entry->next_entry)
3490 {
3491 sizeof_tables_and_entries += 8;
3492
3493 if (entry->is_dir)
3494 rsrc_compute_region_sizes (entry->value.directory);
3495 else
3496 sizeof_leaves += 16;
3497 }
3498}
3499
5879bb8f
NC
3500static void
3501rsrc_write_directory (rsrc_write_data * data,
3502 rsrc_directory * dir)
3503{
3504 rsrc_entry * entry;
3505 unsigned int i;
9373215c
PM
3506 bfd_byte * next_entry;
3507 bfd_byte * nt;
5879bb8f
NC
3508
3509 bfd_put_32 (data->abfd, dir->characteristics, data->next_table);
3510 bfd_put_32 (data->abfd, 0 /*dir->time*/, data->next_table + 4);
3511 bfd_put_16 (data->abfd, dir->major, data->next_table + 8);
3512 bfd_put_16 (data->abfd, dir->minor, data->next_table + 10);
3513 bfd_put_16 (data->abfd, dir->names.num_entries, data->next_table + 12);
3514 bfd_put_16 (data->abfd, dir->ids.num_entries, data->next_table + 14);
3515
3516 /* Compute where the entries and the next table will be placed. */
9373215c
PM
3517 next_entry = data->next_table + 16;
3518 data->next_table = next_entry + (dir->names.num_entries * 8)
3519 + (dir->ids.num_entries * 8);
3520 nt = data->next_table;
3521
5879bb8f
NC
3522 /* Write the entries. */
3523 for (i = dir->names.num_entries, entry = dir->names.first_entry;
3524 i > 0 && entry != NULL;
3525 i--, entry = entry->next_entry)
3526 {
3714081c 3527 BFD_ASSERT (entry->is_name);
5879bb8f
NC
3528 rsrc_write_entry (data, next_entry, entry);
3529 next_entry += 8;
3530 }
3531 BFD_ASSERT (i == 0);
3532 BFD_ASSERT (entry == NULL);
3533
3534 for (i = dir->ids.num_entries, entry = dir->ids.first_entry;
3535 i > 0 && entry != NULL;
3536 i--, entry = entry->next_entry)
3537 {
3714081c 3538 BFD_ASSERT (! entry->is_name);
5879bb8f
NC
3539 rsrc_write_entry (data, next_entry, entry);
3540 next_entry += 8;
3541 }
3542 BFD_ASSERT (i == 0);
3543 BFD_ASSERT (entry == NULL);
3544 BFD_ASSERT (nt == next_entry);
3545}
3546
83c79df8 3547#if ! defined __CYGWIN__ && ! defined __MINGW32__
5879bb8f
NC
3548/* Return the length (number of units) of the first character in S,
3549 putting its 'ucs4_t' representation in *PUC. */
3550
3551static unsigned int
31593e1b 3552u16_mbtouc (wint_t * puc, const unsigned short * s, unsigned int n)
5879bb8f
NC
3553{
3554 unsigned short c = * s;
3555
3556 if (c < 0xd800 || c >= 0xe000)
3557 {
3558 *puc = c;
3559 return 1;
3560 }
3561
3562 if (c < 0xdc00)
3563 {
3564 if (n >= 2)
07d6d2b8
AM
3565 {
3566 if (s[1] >= 0xdc00 && s[1] < 0xe000)
3567 {
3568 *puc = 0x10000 + ((c - 0xd800) << 10) + (s[1] - 0xdc00);
3569 return 2;
3570 }
3571 }
5879bb8f 3572 else
07d6d2b8
AM
3573 {
3574 /* Incomplete multibyte character. */
3575 *puc = 0xfffd;
3576 return n;
3577 }
5879bb8f
NC
3578 }
3579
3580 /* Invalid multibyte character. */
3581 *puc = 0xfffd;
3582 return 1;
3583}
83c79df8 3584#endif /* not Cygwin/Mingw */
5879bb8f
NC
3585
3586/* Perform a comparison of two entries. */
3587static signed int
0a1b45a2 3588rsrc_cmp (bool is_name, rsrc_entry * a, rsrc_entry * b)
5879bb8f 3589{
9373215c 3590 signed int res;
9373215c
PM
3591 bfd_byte * astring;
3592 unsigned int alen;
3593 bfd_byte * bstring;
3594 unsigned int blen;
3595
5879bb8f 3596 if (! is_name)
9373215c 3597 return a->name_id.id - b->name_id.id;
5879bb8f
NC
3598
3599 /* We have to perform a case insenstive, unicode string comparison... */
9373215c
PM
3600 astring = a->name_id.name.string;
3601 alen = a->name_id.name.len;
3602 bstring = b->name_id.name.string;
3603 blen = b->name_id.name.len;
5879bb8f 3604
9373215c
PM
3605#if defined __CYGWIN__ || defined __MINGW32__
3606 /* Under Windows hosts (both Cygwin and Mingw types),
3607 unicode == UTF-16 == wchar_t. The case insensitive string comparison
3608 function however goes by different names in the two environments... */
3609
3610#undef rscpcmp
5879bb8f 3611#ifdef __CYGWIN__
9373215c
PM
3612#define rscpcmp wcsncasecmp
3613#endif
3614#ifdef __MINGW32__
3615#define rscpcmp wcsnicmp
3616#endif
3617
3618 res = rscpcmp ((const wchar_t *) astring, (const wchar_t *) bstring,
3619 min (alen, blen));
5879bb8f 3620
83c79df8 3621#else
3f10b67a
PM
3622 {
3623 unsigned int i;
31593e1b 3624
3f10b67a
PM
3625 res = 0;
3626 for (i = min (alen, blen); i--; astring += 2, bstring += 2)
3627 {
31593e1b
NC
3628 wint_t awc;
3629 wint_t bwc;
3f10b67a 3630
31593e1b
NC
3631 /* Convert UTF-16 unicode characters into wchar_t characters
3632 so that we can then perform a case insensitive comparison. */
3633 unsigned int Alen = u16_mbtouc (& awc, (const unsigned short *) astring, 2);
3634 unsigned int Blen = u16_mbtouc (& bwc, (const unsigned short *) bstring, 2);
3f10b67a
PM
3635
3636 if (Alen != Blen)
3637 return Alen - Blen;
31593e1b 3638
31593e1b
NC
3639 awc = towlower (awc);
3640 bwc = towlower (bwc);
3641
3642 res = awc - bwc;
3f10b67a
PM
3643 if (res)
3644 break;
3645 }
3646 }
5879bb8f
NC
3647#endif
3648
3649 if (res == 0)
3650 res = alen - blen;
3651
3652 return res;
3653}
3654
3655static void
3656rsrc_print_name (char * buffer, rsrc_string string)
3657{
3658 unsigned int i;
3659 bfd_byte * name = string.string;
3660
3661 for (i = string.len; i--; name += 2)
3662 sprintf (buffer + strlen (buffer), "%.1s", name);
3663}
3664
3665static const char *
7fbd5f4e 3666rsrc_resource_name (rsrc_entry *entry, rsrc_directory *dir, char *buffer)
5879bb8f 3667{
0a1b45a2 3668 bool is_string = false;
5879bb8f
NC
3669
3670 buffer[0] = 0;
3671
9373215c
PM
3672 if (dir != NULL && dir->entry != NULL && dir->entry->parent != NULL
3673 && dir->entry->parent->entry != NULL)
5879bb8f
NC
3674 {
3675 strcpy (buffer, "type: ");
3676 if (dir->entry->parent->entry->is_name)
9373215c
PM
3677 rsrc_print_name (buffer + strlen (buffer),
3678 dir->entry->parent->entry->name_id.name);
5879bb8f
NC
3679 else
3680 {
3681 unsigned int id = dir->entry->parent->entry->name_id.id;
3682
3683 sprintf (buffer + strlen (buffer), "%x", id);
3684 switch (id)
3685 {
3686 case 1: strcat (buffer, " (CURSOR)"); break;
3687 case 2: strcat (buffer, " (BITMAP)"); break;
3688 case 3: strcat (buffer, " (ICON)"); break;
07d6d2b8 3689 case 4: strcat (buffer, " (MENU)"); break;
5879bb8f 3690 case 5: strcat (buffer, " (DIALOG)"); break;
0a1b45a2 3691 case 6: strcat (buffer, " (STRING)"); is_string = true; break;
5879bb8f
NC
3692 case 7: strcat (buffer, " (FONTDIR)"); break;
3693 case 8: strcat (buffer, " (FONT)"); break;
3694 case 9: strcat (buffer, " (ACCELERATOR)"); break;
3695 case 10: strcat (buffer, " (RCDATA)"); break;
3696 case 11: strcat (buffer, " (MESSAGETABLE)"); break;
3697 case 12: strcat (buffer, " (GROUP_CURSOR)"); break;
3698 case 14: strcat (buffer, " (GROUP_ICON)"); break;
3699 case 16: strcat (buffer, " (VERSION)"); break;
3700 case 17: strcat (buffer, " (DLGINCLUDE)"); break;
3701 case 19: strcat (buffer, " (PLUGPLAY)"); break;
3702 case 20: strcat (buffer, " (VXD)"); break;
3703 case 21: strcat (buffer, " (ANICURSOR)"); break;
3704 case 22: strcat (buffer, " (ANIICON)"); break;
3705 case 23: strcat (buffer, " (HTML)"); break;
3706 case 24: strcat (buffer, " (MANIFEST)"); break;
3707 case 240: strcat (buffer, " (DLGINIT)"); break;
3708 case 241: strcat (buffer, " (TOOLBAR)"); break;
3709 }
3710 }
3711 }
3712
3713 if (dir != NULL && dir->entry != NULL)
3714 {
3715 strcat (buffer, " name: ");
3716 if (dir->entry->is_name)
3717 rsrc_print_name (buffer + strlen (buffer), dir->entry->name_id.name);
3718 else
3719 {
3720 unsigned int id = dir->entry->name_id.id;
3721
3722 sprintf (buffer + strlen (buffer), "%x", id);
3723
3724 if (is_string)
3725 sprintf (buffer + strlen (buffer), " (resource id range: %d - %d)",
3726 (id - 1) << 4, (id << 4) - 1);
3727 }
3728 }
3729
3730 if (entry != NULL)
3731 {
3732 strcat (buffer, " lang: ");
3733
3734 if (entry->is_name)
3735 rsrc_print_name (buffer + strlen (buffer), entry->name_id.name);
3736 else
3737 sprintf (buffer + strlen (buffer), "%x", entry->name_id.id);
3738 }
3739
3740 return buffer;
3741}
3742
3743/* *sigh* Windows resource strings are special. Only the top 28-bits of
3744 their ID is stored in the NAME entry. The bottom four bits are used as
3745 an index into unicode string table that makes up the data of the leaf.
3746 So identical type-name-lang string resources may not actually be
3747 identical at all.
3748
3749 This function is called when we have detected two string resources with
3750 match top-28-bit IDs. We have to scan the string tables inside the leaves
3751 and discover if there are any real collisions. If there are then we report
9373215c
PM
3752 them and return FALSE. Otherwise we copy any strings from B into A and
3753 then return TRUE. */
5879bb8f 3754
0a1b45a2 3755static bool
5879bb8f
NC
3756rsrc_merge_string_entries (rsrc_entry * a ATTRIBUTE_UNUSED,
3757 rsrc_entry * b ATTRIBUTE_UNUSED)
3758{
3759 unsigned int copy_needed = 0;
3760 unsigned int i;
9373215c
PM
3761 bfd_byte * astring;
3762 bfd_byte * bstring;
3763 bfd_byte * new_data;
3764 bfd_byte * nstring;
5879bb8f
NC
3765
3766 /* Step one: Find out what we have to do. */
3767 BFD_ASSERT (! a->is_dir);
9373215c 3768 astring = a->value.leaf->data;
5879bb8f
NC
3769
3770 BFD_ASSERT (! b->is_dir);
9373215c 3771 bstring = b->value.leaf->data;
5879bb8f
NC
3772
3773 for (i = 0; i < 16; i++)
3774 {
3775 unsigned int alen = astring[0] + (astring[1] << 8);
3776 unsigned int blen = bstring[0] + (bstring[1] << 8);
3777
3778 if (alen == 0)
3779 {
3780 copy_needed += blen * 2;
3781 }
3782 else if (blen == 0)
3783 ;
3784 else if (alen != blen)
3785 /* FIXME: Should we continue the loop in order to report other duplicates ? */
3786 break;
3787 /* alen == blen != 0. We might have two identical strings. If so we
3788 can ignore the second one. There is no need for wchar_t vs UTF-16
3789 theatrics here - we are only interested in (case sensitive) equality. */
3790 else if (memcmp (astring + 2, bstring + 2, alen * 2) != 0)
3791 break;
3792
3793 astring += (alen + 1) * 2;
3794 bstring += (blen + 1) * 2;
3795 }
3796
3797 if (i != 16)
3798 {
3799 if (a->parent != NULL
3800 && a->parent->entry != NULL
535b785f 3801 && !a->parent->entry->is_name)
5879bb8f
NC
3802 _bfd_error_handler (_(".rsrc merge failure: duplicate string resource: %d"),
3803 ((a->parent->entry->name_id.id - 1) << 4) + i);
0a1b45a2 3804 return false;
5879bb8f
NC
3805 }
3806
3807 if (copy_needed == 0)
0a1b45a2 3808 return true;
5879bb8f
NC
3809
3810 /* If we reach here then A and B must both have non-colliding strings.
3811 (We never get string resources with fully empty string tables).
3812 We need to allocate an extra COPY_NEEDED bytes in A and then bring
3813 in B's strings. */
9373215c 3814 new_data = bfd_malloc (a->value.leaf->size + copy_needed);
5879bb8f 3815 if (new_data == NULL)
0a1b45a2 3816 return false;
5879bb8f 3817
9373215c 3818 nstring = new_data;
5879bb8f
NC
3819 astring = a->value.leaf->data;
3820 bstring = b->value.leaf->data;
3821
3822 for (i = 0; i < 16; i++)
3823 {
3824 unsigned int alen = astring[0] + (astring[1] << 8);
3825 unsigned int blen = bstring[0] + (bstring[1] << 8);
3826
3827 if (alen != 0)
3828 {
3829 memcpy (nstring, astring, (alen + 1) * 2);
3830 nstring += (alen + 1) * 2;
3831 }
3832 else if (blen != 0)
3833 {
3834 memcpy (nstring, bstring, (blen + 1) * 2);
3835 nstring += (blen + 1) * 2;
3836 }
3837 else
3838 {
3839 * nstring++ = 0;
3840 * nstring++ = 0;
3841 }
9373215c 3842
5879bb8f
NC
3843 astring += (alen + 1) * 2;
3844 bstring += (blen + 1) * 2;
3845 }
3846
3847 BFD_ASSERT (nstring - new_data == (signed) (a->value.leaf->size + copy_needed));
9373215c 3848
5879bb8f
NC
3849 free (a->value.leaf->data);
3850 a->value.leaf->data = new_data;
3851 a->value.leaf->size += copy_needed;
3852
0a1b45a2 3853 return true;
5879bb8f
NC
3854}
3855
3856static void rsrc_merge (rsrc_entry *, rsrc_entry *);
3857
3858/* Sort the entries in given part of the directory.
3859 We use an old fashioned bubble sort because we are dealing
9373215c 3860 with lists and we want to handle matches specially. */
5879bb8f
NC
3861
3862static void
0a1b45a2
AM
3863rsrc_sort_entries (rsrc_dir_chain *chain,
3864 bool is_name,
3865 rsrc_directory *dir)
5879bb8f
NC
3866{
3867 rsrc_entry * entry;
3868 rsrc_entry * next;
3869 rsrc_entry ** points_to_entry;
0a1b45a2 3870 bool swapped;
5879bb8f
NC
3871
3872 if (chain->num_entries < 2)
3873 return;
3874
3875 do
3876 {
0a1b45a2 3877 swapped = false;
5879bb8f
NC
3878 points_to_entry = & chain->first_entry;
3879 entry = * points_to_entry;
3880 next = entry->next_entry;
3881
3882 do
3883 {
3884 signed int cmp = rsrc_cmp (is_name, entry, next);
3885
3886 if (cmp > 0)
3887 {
3888 entry->next_entry = next->next_entry;
3889 next->next_entry = entry;
3890 * points_to_entry = next;
3891 points_to_entry = & next->next_entry;
3892 next = entry->next_entry;
0a1b45a2 3893 swapped = true;
5879bb8f
NC
3894 }
3895 else if (cmp == 0)
3896 {
3897 if (entry->is_dir && next->is_dir)
3898 {
3899 /* When we encounter identical directory entries we have to
3900 merge them together. The exception to this rule is for
3901 resource manifests - there can only be one of these,
3902 even if they differ in language. Zero-language manifests
3903 are assumed to be default manifests (provided by the
3714081c 3904 Cygwin/MinGW build system) and these can be silently dropped,
5879bb8f
NC
3905 unless that would reduce the number of manifests to zero.
3906 There should only ever be one non-zero lang manifest -
3907 if there are more it is an error. A non-zero lang
3908 manifest takes precedence over a default manifest. */
535b785f 3909 if (!entry->is_name
5879bb8f
NC
3910 && entry->name_id.id == 1
3911 && dir != NULL
3912 && dir->entry != NULL
535b785f 3913 && !dir->entry->is_name
5879bb8f
NC
3914 && dir->entry->name_id.id == 0x18)
3915 {
3916 if (next->value.directory->names.num_entries == 0
3917 && next->value.directory->ids.num_entries == 1
535b785f 3918 && !next->value.directory->ids.first_entry->is_name
5879bb8f
NC
3919 && next->value.directory->ids.first_entry->name_id.id == 0)
3920 /* Fall through so that NEXT is dropped. */
3921 ;
3922 else if (entry->value.directory->names.num_entries == 0
3923 && entry->value.directory->ids.num_entries == 1
535b785f 3924 && !entry->value.directory->ids.first_entry->is_name
5879bb8f
NC
3925 && entry->value.directory->ids.first_entry->name_id.id == 0)
3926 {
3927 /* Swap ENTRY and NEXT. Then fall through so that the old ENTRY is dropped. */
3928 entry->next_entry = next->next_entry;
3929 next->next_entry = entry;
3930 * points_to_entry = next;
3931 points_to_entry = & next->next_entry;
3932 next = entry->next_entry;
0a1b45a2 3933 swapped = true;
5879bb8f
NC
3934 }
3935 else
3936 {
3937 _bfd_error_handler (_(".rsrc merge failure: multiple non-default manifests"));
3938 bfd_set_error (bfd_error_file_truncated);
3939 return;
3940 }
9373215c 3941
5879bb8f
NC
3942 /* Unhook NEXT from the chain. */
3943 /* FIXME: memory loss here. */
3944 entry->next_entry = next->next_entry;
3945 chain->num_entries --;
3946 if (chain->num_entries < 2)
3947 return;
3948 next = next->next_entry;
3949 }
3950 else
3951 rsrc_merge (entry, next);
3952 }
3953 else if (entry->is_dir != next->is_dir)
3954 {
3955 _bfd_error_handler (_(".rsrc merge failure: a directory matches a leaf"));
3956 bfd_set_error (bfd_error_file_truncated);
3957 return;
3958 }
3959 else
3960 {
3961 /* Otherwise with identical leaves we issue an error
3962 message - because there should never be duplicates.
3963 The exception is Type 18/Name 1/Lang 0 which is the
3964 defaul manifest - this can just be dropped. */
535b785f 3965 if (!entry->is_name
5879bb8f
NC
3966 && entry->name_id.id == 0
3967 && dir != NULL
3968 && dir->entry != NULL
535b785f 3969 && !dir->entry->is_name
5879bb8f
NC
3970 && dir->entry->name_id.id == 1
3971 && dir->entry->parent != NULL
3972 && dir->entry->parent->entry != NULL
535b785f 3973 && !dir->entry->parent->entry->is_name
5879bb8f
NC
3974 && dir->entry->parent->entry->name_id.id == 0x18 /* RT_MANIFEST */)
3975 ;
3976 else if (dir != NULL
3977 && dir->entry != NULL
3978 && dir->entry->parent != NULL
3979 && dir->entry->parent->entry != NULL
535b785f 3980 && !dir->entry->parent->entry->is_name
5879bb8f
NC
3981 && dir->entry->parent->entry->name_id.id == 0x6 /* RT_STRING */)
3982 {
3983 /* Strings need special handling. */
3984 if (! rsrc_merge_string_entries (entry, next))
3985 {
3986 /* _bfd_error_handler should have been called inside merge_strings. */
3987 bfd_set_error (bfd_error_file_truncated);
3988 return;
3989 }
3990 }
3991 else
3992 {
3993 if (dir == NULL
3994 || dir->entry == NULL
3995 || dir->entry->parent == NULL
3996 || dir->entry->parent->entry == NULL)
3997 _bfd_error_handler (_(".rsrc merge failure: duplicate leaf"));
3998 else
7fbd5f4e
AM
3999 {
4000 char buff[256];
4001
4002 _bfd_error_handler (_(".rsrc merge failure: duplicate leaf: %s"),
4003 rsrc_resource_name (entry, dir, buff));
4004 }
5879bb8f
NC
4005 bfd_set_error (bfd_error_file_truncated);
4006 return;
4007 }
4008 }
4009
4010 /* Unhook NEXT from the chain. */
4011 entry->next_entry = next->next_entry;
4012 chain->num_entries --;
4013 if (chain->num_entries < 2)
4014 return;
4015 next = next->next_entry;
4016 }
4017 else
4018 {
4019 points_to_entry = & entry->next_entry;
4020 entry = next;
4021 next = next->next_entry;
4022 }
4023 }
4024 while (next);
4025
4026 chain->last_entry = entry;
4027 }
4028 while (swapped);
4029}
4030
4031/* Attach B's chain onto A. */
4032static void
9373215c 4033rsrc_attach_chain (rsrc_dir_chain * achain, rsrc_dir_chain * bchain)
5879bb8f
NC
4034{
4035 if (bchain->num_entries == 0)
4036 return;
4037
4038 achain->num_entries += bchain->num_entries;
4039
4040 if (achain->first_entry == NULL)
4041 {
4042 achain->first_entry = bchain->first_entry;
4043 achain->last_entry = bchain->last_entry;
4044 }
4045 else
4046 {
4047 achain->last_entry->next_entry = bchain->first_entry;
4048 achain->last_entry = bchain->last_entry;
4049 }
9373215c 4050
5879bb8f
NC
4051 bchain->num_entries = 0;
4052 bchain->first_entry = bchain->last_entry = NULL;
4053}
4054
4055static void
4056rsrc_merge (struct rsrc_entry * a, struct rsrc_entry * b)
4057{
9373215c
PM
4058 rsrc_directory * adir;
4059 rsrc_directory * bdir;
4060
5879bb8f
NC
4061 BFD_ASSERT (a->is_dir);
4062 BFD_ASSERT (b->is_dir);
4063
9373215c
PM
4064 adir = a->value.directory;
4065 bdir = b->value.directory;
4066
5879bb8f
NC
4067 if (adir->characteristics != bdir->characteristics)
4068 {
59d08d6c 4069 _bfd_error_handler (_(".rsrc merge failure: dirs with differing characteristics"));
5879bb8f
NC
4070 bfd_set_error (bfd_error_file_truncated);
4071 return;
4072 }
9373215c 4073
5879bb8f
NC
4074 if (adir->major != bdir->major || adir->minor != bdir->minor)
4075 {
59d08d6c 4076 _bfd_error_handler (_(".rsrc merge failure: differing directory versions"));
5879bb8f
NC
4077 bfd_set_error (bfd_error_file_truncated);
4078 return;
4079 }
4080
4081 /* Attach B's name chain to A. */
4082 rsrc_attach_chain (& adir->names, & bdir->names);
4083
4084 /* Attach B's ID chain to A. */
4085 rsrc_attach_chain (& adir->ids, & bdir->ids);
4086
4087 /* Now sort A's entries. */
0a1b45a2
AM
4088 rsrc_sort_entries (& adir->names, true, adir);
4089 rsrc_sort_entries (& adir->ids, false, adir);
5879bb8f
NC
4090}
4091
4092/* Check the .rsrc section. If it contains multiple concatenated
4093 resources then we must merge them properly. Otherwise Windows
4094 will ignore all but the first set. */
4095
4096static void
4097rsrc_process_section (bfd * abfd,
4098 struct coff_final_link_info * pfinfo)
4099{
9373215c 4100 rsrc_directory new_table;
07d6d2b8
AM
4101 bfd_size_type size;
4102 asection * sec;
9373215c 4103 pe_data_type * pe;
07d6d2b8
AM
4104 bfd_vma rva_bias;
4105 bfd_byte * data;
4106 bfd_byte * datastart;
4107 bfd_byte * dataend;
4108 bfd_byte * new_data;
4109 unsigned int num_resource_sets;
9373215c
PM
4110 rsrc_directory * type_tables;
4111 rsrc_write_data write_data;
07d6d2b8
AM
4112 unsigned int indx;
4113 bfd * input;
4114 unsigned int num_input_rsrc = 0;
4115 unsigned int max_num_input_rsrc = 4;
4116 ptrdiff_t * rsrc_sizes = NULL;
5879bb8f
NC
4117
4118 new_table.names.num_entries = 0;
4119 new_table.ids.num_entries = 0;
9373215c 4120
5879bb8f
NC
4121 sec = bfd_get_section_by_name (abfd, ".rsrc");
4122 if (sec == NULL || (size = sec->rawsize) == 0)
4123 return;
4124
9373215c 4125 pe = pe_data (abfd);
5879bb8f
NC
4126 if (pe == NULL)
4127 return;
4128
5879bb8f
NC
4129 rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
4130
9373215c 4131 data = bfd_malloc (size);
5879bb8f
NC
4132 if (data == NULL)
4133 return;
c32abae8 4134
9373215c 4135 datastart = data;
5879bb8f
NC
4136
4137 if (! bfd_get_section_contents (abfd, sec, data, 0, size))
4138 goto end;
4139
6caf7111
NC
4140 /* Step zero: Scan the input bfds looking for .rsrc sections and record
4141 their lengths. Note - we rely upon the fact that the linker script
4142 does *not* sort the input .rsrc sections, so that the order in the
4143 linkinfo list matches the order in the output .rsrc section.
4144
4145 We need to know the lengths because each input .rsrc section has padding
4146 at the end of a variable amount. (It does not appear to be based upon
4147 the section alignment or the file alignment). We need to skip any
4148 padding bytes when parsing the input .rsrc sections. */
4149 rsrc_sizes = bfd_malloc (max_num_input_rsrc * sizeof * rsrc_sizes);
4150 if (rsrc_sizes == NULL)
4151 goto end;
4152
4153 for (input = pfinfo->info->input_bfds;
4154 input != NULL;
c72f2fb2 4155 input = input->link.next)
6caf7111
NC
4156 {
4157 asection * rsrc_sec = bfd_get_section_by_name (input, ".rsrc");
4158
9ac47a43
TS
4159 /* PR 18372 - skip discarded .rsrc sections. */
4160 if (rsrc_sec != NULL && !discarded_section (rsrc_sec))
6caf7111
NC
4161 {
4162 if (num_input_rsrc == max_num_input_rsrc)
4163 {
4164 max_num_input_rsrc += 10;
4165 rsrc_sizes = bfd_realloc (rsrc_sizes, max_num_input_rsrc
4166 * sizeof * rsrc_sizes);
4167 if (rsrc_sizes == NULL)
4168 goto end;
4169 }
4170
4171 BFD_ASSERT (rsrc_sec->size > 0);
4172 rsrc_sizes [num_input_rsrc ++] = rsrc_sec->size;
4173 }
4174 }
4175
4176 if (num_input_rsrc < 2)
4177 goto end;
61e2488c 4178
5879bb8f
NC
4179 /* Step one: Walk the section, computing the size of the tables,
4180 leaves and data and decide if we need to do anything. */
1d63324c 4181 dataend = data + size;
9373215c 4182 num_resource_sets = 0;
5879bb8f
NC
4183
4184 while (data < dataend)
4185 {
4186 bfd_byte * p = data;
4187
4188 data = rsrc_count_directory (abfd, data, data, dataend, rva_bias);
1d63324c 4189
5879bb8f
NC
4190 if (data > dataend)
4191 {
4192 /* Corrupted .rsrc section - cannot merge. */
871b3ab2 4193 _bfd_error_handler (_("%pB: .rsrc merge failure: corrupt .rsrc section"),
dae82561 4194 abfd);
5879bb8f
NC
4195 bfd_set_error (bfd_error_file_truncated);
4196 goto end;
4197 }
4198
6caf7111
NC
4199 if ((data - p) > rsrc_sizes [num_resource_sets])
4200 {
871b3ab2 4201 _bfd_error_handler (_("%pB: .rsrc merge failure: unexpected .rsrc size"),
dae82561 4202 abfd);
6caf7111
NC
4203 bfd_set_error (bfd_error_file_truncated);
4204 goto end;
4205 }
4206 /* FIXME: Should we add a check for "data - p" being much smaller
4207 than rsrc_sizes[num_resource_sets] ? */
4208
4209 data = p + rsrc_sizes[num_resource_sets];
5879bb8f 4210 rva_bias += data - p;
5879bb8f
NC
4211 ++ num_resource_sets;
4212 }
6caf7111 4213 BFD_ASSERT (num_resource_sets == num_input_rsrc);
5879bb8f
NC
4214
4215 /* Step two: Walk the data again, building trees of the resources. */
4216 data = datastart;
4217 rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
4218
9373215c 4219 type_tables = bfd_malloc (num_resource_sets * sizeof * type_tables);
5879bb8f
NC
4220 if (type_tables == NULL)
4221 goto end;
4222
9373215c 4223 indx = 0;
5879bb8f
NC
4224 while (data < dataend)
4225 {
4226 bfd_byte * p = data;
4227
6caf7111 4228 (void) rsrc_parse_directory (abfd, type_tables + indx, data, data,
9373215c 4229 dataend, rva_bias, NULL);
6caf7111 4230 data = p + rsrc_sizes[indx];
5879bb8f 4231 rva_bias += data - p;
6caf7111 4232 ++ indx;
5879bb8f 4233 }
337e86d7 4234 BFD_ASSERT (indx == num_resource_sets);
9373215c 4235
5879bb8f 4236 /* Step three: Merge the top level tables (there can be only one).
9373215c 4237
5879bb8f 4238 We must ensure that the merged entries are in ascending order.
9373215c 4239
5879bb8f
NC
4240 We also thread the top level table entries from the old tree onto
4241 the new table, so that they can be pulled off later. */
4242
4243 /* FIXME: Should we verify that all type tables are the same ? */
4244 new_table.characteristics = type_tables[0].characteristics;
07d6d2b8
AM
4245 new_table.time = type_tables[0].time;
4246 new_table.major = type_tables[0].major;
4247 new_table.minor = type_tables[0].minor;
5879bb8f
NC
4248
4249 /* Chain the NAME entries onto the table. */
4250 new_table.names.first_entry = NULL;
4251 new_table.names.last_entry = NULL;
4252
337e86d7
L
4253 for (indx = 0; indx < num_resource_sets; indx++)
4254 rsrc_attach_chain (& new_table.names, & type_tables[indx].names);
5879bb8f 4255
0a1b45a2 4256 rsrc_sort_entries (& new_table.names, true, & new_table);
9373215c 4257
5879bb8f
NC
4258 /* Chain the ID entries onto the table. */
4259 new_table.ids.first_entry = NULL;
4260 new_table.ids.last_entry = NULL;
4261
337e86d7
L
4262 for (indx = 0; indx < num_resource_sets; indx++)
4263 rsrc_attach_chain (& new_table.ids, & type_tables[indx].ids);
5879bb8f 4264
0a1b45a2 4265 rsrc_sort_entries (& new_table.ids, false, & new_table);
5879bb8f
NC
4266
4267 /* Step four: Create new contents for the .rsrc section. */
3714081c
NC
4268 /* Step four point one: Compute the size of each region of the .rsrc section.
4269 We do this now, rather than earlier, as the merging above may have dropped
4270 some entries. */
4271 sizeof_leaves = sizeof_strings = sizeof_tables_and_entries = 0;
4272 rsrc_compute_region_sizes (& new_table);
4273 /* We increment sizeof_strings to make sure that resource data
4274 starts on an 8-byte boundary. FIXME: Is this correct ? */
4275 sizeof_strings = (sizeof_strings + 7) & ~ 7;
4276
c32abae8 4277 new_data = bfd_zalloc (abfd, size);
5879bb8f
NC
4278 if (new_data == NULL)
4279 goto end;
4280
07d6d2b8
AM
4281 write_data.abfd = abfd;
4282 write_data.datastart = new_data;
4283 write_data.next_table = new_data;
4284 write_data.next_leaf = new_data + sizeof_tables_and_entries;
5879bb8f 4285 write_data.next_string = write_data.next_leaf + sizeof_leaves;
07d6d2b8
AM
4286 write_data.next_data = write_data.next_string + sizeof_strings;
4287 write_data.rva_bias = sec->vma - pe->pe_opthdr.ImageBase;
5879bb8f
NC
4288
4289 rsrc_write_directory (& write_data, & new_table);
4290
4291 /* Step five: Replace the old contents with the new.
ec8f7688
JT
4292 We don't recompute the size as it's too late here to shrink section.
4293 See PR ld/20193 for more details. */
5879bb8f
NC
4294 bfd_set_section_contents (pfinfo->output_bfd, sec, new_data, 0, size);
4295 sec->size = sec->rawsize = size;
9373215c 4296
5879bb8f 4297 end:
3714081c 4298 /* Step six: Free all the memory that we have used. */
5879bb8f
NC
4299 /* FIXME: Free the resource tree, if we have one. */
4300 free (datastart);
6caf7111 4301 free (rsrc_sizes);
5879bb8f 4302}
5174d0fb 4303
2fbadf2c
ILT
4304/* Handle the .idata section and other things that need symbol table
4305 access. */
4306
0a1b45a2 4307bool
7920ce38 4308_bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
2fbadf2c
ILT
4309{
4310 struct coff_link_hash_entry *h1;
4311 struct bfd_link_info *info = pfinfo->info;
0a1b45a2 4312 bool result = true;
2fbadf2c
ILT
4313
4314 /* There are a few fields that need to be filled in now while we
4315 have symbol table access.
4316
4317 The .idata subsections aren't directly available as sections, but
4318 they are in the symbol table, so get them from there. */
4319
4320 /* The import directory. This is the address of .idata$2, with size
4321 of .idata$2 + .idata$3. */
4322 h1 = coff_link_hash_lookup (coff_hash_table (info),
0a1b45a2 4323 ".idata$2", false, false, true);
2fbadf2c
ILT
4324 if (h1 != NULL)
4325 {
4e1fc599 4326 /* PR ld/2729: We cannot rely upon all the output sections having been
4e22f78d
NC
4327 created properly, so check before referencing them. Issue a warning
4328 message for any sections tht could not be found. */
b92997d6
AM
4329 if ((h1->root.type == bfd_link_hash_defined
4330 || h1->root.type == bfd_link_hash_defweak)
4331 && h1->root.u.def.section != NULL
4e22f78d 4332 && h1->root.u.def.section->output_section != NULL)
6c73cbb1 4333 pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress =
4e22f78d
NC
4334 (h1->root.u.def.value
4335 + h1->root.u.def.section->output_section->vma
4336 + h1->root.u.def.section->output_offset);
4337 else
4338 {
4339 _bfd_error_handler
871b3ab2 4340 (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"),
4e22f78d 4341 abfd);
0a1b45a2 4342 result = false;
4e22f78d
NC
4343 }
4344
2fbadf2c 4345 h1 = coff_link_hash_lookup (coff_hash_table (info),
0a1b45a2 4346 ".idata$4", false, false, true);
4e22f78d 4347 if (h1 != NULL
b92997d6
AM
4348 && (h1->root.type == bfd_link_hash_defined
4349 || h1->root.type == bfd_link_hash_defweak)
4e22f78d
NC
4350 && h1->root.u.def.section != NULL
4351 && h1->root.u.def.section->output_section != NULL)
6c73cbb1 4352 pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].Size =
4e22f78d
NC
4353 ((h1->root.u.def.value
4354 + h1->root.u.def.section->output_section->vma
4355 + h1->root.u.def.section->output_offset)
6c73cbb1 4356 - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_TABLE].VirtualAddress);
4e22f78d
NC
4357 else
4358 {
4359 _bfd_error_handler
871b3ab2 4360 (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"),
4e22f78d 4361 abfd);
0a1b45a2 4362 result = false;
4e22f78d 4363 }
2fbadf2c
ILT
4364
4365 /* The import address table. This is the size/address of
07d6d2b8 4366 .idata$5. */
2fbadf2c 4367 h1 = coff_link_hash_lookup (coff_hash_table (info),
0a1b45a2 4368 ".idata$5", false, false, true);
4e22f78d 4369 if (h1 != NULL
b92997d6
AM
4370 && (h1->root.type == bfd_link_hash_defined
4371 || h1->root.type == bfd_link_hash_defweak)
4e22f78d
NC
4372 && h1->root.u.def.section != NULL
4373 && h1->root.u.def.section->output_section != NULL)
6c73cbb1 4374 pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
4e22f78d
NC
4375 (h1->root.u.def.value
4376 + h1->root.u.def.section->output_section->vma
4377 + h1->root.u.def.section->output_offset);
4378 else
4379 {
4380 _bfd_error_handler
871b3ab2 4381 (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"),
4e22f78d 4382 abfd);
0a1b45a2 4383 result = false;
4e22f78d
NC
4384 }
4385
2fbadf2c 4386 h1 = coff_link_hash_lookup (coff_hash_table (info),
0a1b45a2 4387 ".idata$6", false, false, true);
4e22f78d 4388 if (h1 != NULL
b92997d6
AM
4389 && (h1->root.type == bfd_link_hash_defined
4390 || h1->root.type == bfd_link_hash_defweak)
4e22f78d
NC
4391 && h1->root.u.def.section != NULL
4392 && h1->root.u.def.section->output_section != NULL)
6c73cbb1 4393 pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
4e22f78d
NC
4394 ((h1->root.u.def.value
4395 + h1->root.u.def.section->output_section->vma
4396 + h1->root.u.def.section->output_offset)
4e1fc599 4397 - pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress);
4e22f78d
NC
4398 else
4399 {
4400 _bfd_error_handler
871b3ab2 4401 (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
4e22f78d 4402 abfd);
0a1b45a2 4403 result = false;
4e22f78d 4404 }
2fbadf2c 4405 }
cb2f80e6
KT
4406 else
4407 {
4408 h1 = coff_link_hash_lookup (coff_hash_table (info),
0a1b45a2 4409 "__IAT_start__", false, false, true);
cb2f80e6
KT
4410 if (h1 != NULL
4411 && (h1->root.type == bfd_link_hash_defined
4412 || h1->root.type == bfd_link_hash_defweak)
4413 && h1->root.u.def.section != NULL
4414 && h1->root.u.def.section->output_section != NULL)
4415 {
4416 bfd_vma iat_va;
4417
4418 iat_va =
4419 (h1->root.u.def.value
4420 + h1->root.u.def.section->output_section->vma
4421 + h1->root.u.def.section->output_offset);
4422
4423 h1 = coff_link_hash_lookup (coff_hash_table (info),
0a1b45a2 4424 "__IAT_end__", false, false, true);
cb2f80e6
KT
4425 if (h1 != NULL
4426 && (h1->root.type == bfd_link_hash_defined
4427 || h1->root.type == bfd_link_hash_defweak)
4428 && h1->root.u.def.section != NULL
4429 && h1->root.u.def.section->output_section != NULL)
4430 {
4431 pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size =
4432 ((h1->root.u.def.value
4433 + h1->root.u.def.section->output_section->vma
4434 + h1->root.u.def.section->output_offset)
4435 - iat_va);
4436 if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].Size != 0)
4437 pe_data (abfd)->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE].VirtualAddress =
4438 iat_va - pe_data (abfd)->pe_opthdr.ImageBase;
4439 }
4440 else
4441 {
4442 _bfd_error_handler
871b3ab2 4443 (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
cb2f80e6 4444 " because .idata$6 is missing"), abfd);
0a1b45a2 4445 result = false;
cb2f80e6 4446 }
07d6d2b8 4447 }
cb2f80e6 4448 }
ca6dee30
NC
4449
4450 h1 = coff_link_hash_lookup (coff_hash_table (info),
61e2488c 4451 (bfd_get_symbol_leading_char (abfd) != 0
c91a930c 4452 ? "__tls_used" : "_tls_used"),
0a1b45a2 4453 false, false, true);
ca6dee30
NC
4454 if (h1 != NULL)
4455 {
b92997d6
AM
4456 if ((h1->root.type == bfd_link_hash_defined
4457 || h1->root.type == bfd_link_hash_defweak)
4458 && h1->root.u.def.section != NULL
4e22f78d 4459 && h1->root.u.def.section->output_section != NULL)
6c73cbb1 4460 pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].VirtualAddress =
4e22f78d
NC
4461 (h1->root.u.def.value
4462 + h1->root.u.def.section->output_section->vma
4463 + h1->root.u.def.section->output_offset
4464 - pe_data (abfd)->pe_opthdr.ImageBase);
4465 else
4466 {
4467 _bfd_error_handler
871b3ab2 4468 (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"),
4e22f78d 4469 abfd);
0a1b45a2 4470 result = false;
4e22f78d 4471 }
bc2b2990
PM
4472 /* According to PECOFF sepcifications by Microsoft version 8.2
4473 the TLS data directory consists of 4 pointers, followed
4474 by two 4-byte integer. This implies that the total size
68ffbac6 4475 is different for 32-bit and 64-bit executables. */
bc2b2990 4476#if !defined(COFF_WITH_pep) && !defined(COFF_WITH_pex64)
6c73cbb1 4477 pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x18;
bc2b2990
PM
4478#else
4479 pe_data (abfd)->pe_opthdr.DataDirectory[PE_TLS_TABLE].Size = 0x28;
4480#endif
ca6dee30
NC
4481 }
4482
5174d0fb
KT
4483/* If there is a .pdata section and we have linked pdata finally, we
4484 need to sort the entries ascending. */
4485#if !defined(COFF_WITH_pep) && defined(COFF_WITH_pex64)
4486 {
4487 asection *sec = bfd_get_section_by_name (abfd, ".pdata");
4488
4489 if (sec)
4490 {
21e68916
KT
4491 bfd_size_type x = sec->rawsize;
4492 bfd_byte *tmp_data = NULL;
5174d0fb 4493
21e68916
KT
4494 if (x)
4495 tmp_data = bfd_malloc (x);
4496
4497 if (tmp_data != NULL)
5174d0fb 4498 {
21e68916
KT
4499 if (bfd_get_section_contents (abfd, sec, tmp_data, 0, x))
4500 {
4501 qsort (tmp_data,
4502 (size_t) (x / 12),
4503 12, sort_x64_pdata);
4504 bfd_set_section_contents (pfinfo->output_bfd, sec,
4505 tmp_data, 0, x);
4506 }
4507 free (tmp_data);
5174d0fb 4508 }
86eafac0 4509 else
0a1b45a2 4510 result = false;
5174d0fb
KT
4511 }
4512 }
4513#endif
4514
5879bb8f
NC
4515 rsrc_process_section (abfd, pfinfo);
4516
2fbadf2c
ILT
4517 /* If we couldn't find idata$2, we either have an excessively
4518 trivial program or are in DEEP trouble; we have to assume trivial
4519 program.... */
4e22f78d 4520 return result;
2fbadf2c 4521}
This page took 1.560707 seconds and 4 git commands to generate.