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