* pe-arm-wince.c (pe_print_compressed_pdata): Define new function to
[deliverable/binutils-gdb.git] / bfd / pe-arm-wince.c
CommitLineData
7148cc28 1/* BFD back-end for ARM WINCE PE files.
2b5c217d 2 Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
7148cc28 3
d66dff94 4 This file is part of BFD, the Binary File Descriptor library.
7148cc28 5
d66dff94
NC
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
cd123cb7 8 the Free Software Foundation; either version 3 of the License, or
d66dff94 9 (at your option) any later version.
7148cc28 10
d66dff94
NC
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
7148cc28 15
d66dff94
NC
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
cd123cb7
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
7148cc28
NC
20
21#define TARGET_UNDERSCORE 0
22#define USER_LABEL_PREFIX ""
23
24#define TARGET_LITTLE_SYM arm_wince_pe_little_vec
25#define TARGET_LITTLE_NAME "pe-arm-wince-little"
26#define TARGET_BIG_SYM arm_wince_pe_big_vec
27#define TARGET_BIG_NAME "pe-arm-wince-big"
28
29#define bfd_arm_allocate_interworking_sections \
30 bfd_arm_wince_pe_allocate_interworking_sections
31#define bfd_arm_get_bfd_for_interworking \
32 bfd_arm_wince_pe_get_bfd_for_interworking
33#define bfd_arm_process_before_allocation \
34 bfd_arm_wince_pe_process_before_allocation
35
d66dff94
NC
36#define LOCAL_LABEL_PREFIX "."
37
2b5c217d
NC
38#include "sysdep.h"
39#include "bfd.h"
40
41#undef bfd_pe_print_pdata
42#define bfd_pe_print_pdata pe_print_ce_compressed_pdata
43extern bfd_boolean pe_print_ce_compressed_pdata (bfd *, void *);
44
7148cc28 45#include "pe-arm.c"
2b5c217d
NC
46
47typedef struct sym_cache
48{
49 int symcount;
50 asymbol **syms;
51} sym_cache;
52
53static asymbol **
54slurp_symtab (bfd *abfd, sym_cache *psc)
55{
56 asymbol **sy = NULL;
57 long storage;
58
59 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
60 {
61 psc->symcount = 0;
62 return NULL;
63 }
64
65 storage = bfd_get_symtab_upper_bound (abfd);
66 if (storage < 0)
67 return NULL;
68 if (storage)
69 sy = bfd_malloc (storage);
70
71 psc->symcount = bfd_canonicalize_symtab (abfd, sy);
72 if (psc->symcount < 0)
73 return NULL;
74 return sy;
75}
76
77static const char *
78my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
79{
80 int i;
81
82 if (psc->syms == 0)
83 psc->syms = slurp_symtab (abfd, psc);
84
85 for (i = 0; i < psc->symcount; i++)
86 {
87 if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
88 return psc->syms[i]->name;
89 }
90
91 return NULL;
92}
93
94static void
95cleanup_syms (sym_cache *psc)
96{
97 psc->symcount = 0;
98 free (psc->syms);
99 psc->syms = NULL;
100}
101
102/* This is the version for "compressed" pdata. */
103
104bfd_boolean
105pe_print_ce_compressed_pdata (bfd * abfd, void * vfile)
106{
107# define PDATA_ROW_SIZE (2 * 4)
108 FILE *file = (FILE *) vfile;
109 bfd_byte *data = 0;
110 asection *section = bfd_get_section_by_name (abfd, ".pdata");
111 bfd_size_type datasize = 0;
112 bfd_size_type i;
113 bfd_size_type start, stop;
114 int onaline = PDATA_ROW_SIZE;
115 struct sym_cache sym_cache = {0, 0} ;
116
117 if (section == NULL
118 || coff_section_data (abfd, section) == NULL
119 || pei_section_data (abfd, section) == NULL)
120 return TRUE;
121
122 stop = pei_section_data (abfd, section)->virt_size;
123 if ((stop % onaline) != 0)
124 fprintf (file,
125 _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
126 (long) stop, onaline);
127
128 fprintf (file,
129 _("\nThe Function Table (interpreted .pdata section contents)\n"));
130
131 fprintf (file, _("\
132 vma:\t\tBegin Prolog Function Flags Exception EH\n\
133 \t\tAddress Length Length 32b exc Handler Data\n"));
134
135 datasize = section->size;
136 if (datasize == 0)
137 return TRUE;
138
139 if (! bfd_malloc_and_get_section (abfd, section, &data))
140 {
141 if (data != NULL)
142 free (data);
143 return FALSE;
144 }
145
146 start = 0;
147
148 for (i = start; i < stop; i += onaline)
149 {
150 bfd_vma begin_addr;
151 bfd_vma other_data;
152 bfd_vma prolog_length, function_length;
153 int flag32bit, exception_flag;
154 bfd_byte *tdata = 0;
155 asection *tsection;
156
157 if (i + PDATA_ROW_SIZE > stop)
158 break;
159
160 begin_addr = GET_PDATA_ENTRY (abfd, data + i );
161 other_data = GET_PDATA_ENTRY (abfd, data + i + 4);
162
163 if (begin_addr == 0 && other_data == 0)
164 /* We are probably into the padding of the section now. */
165 break;
166
167 prolog_length = (other_data & 0x000000FF);
168 function_length = (other_data & 0x3FFFFF00) >> 8;
169 flag32bit = (int)((other_data & 0x40000000) >> 30);
170 exception_flag = (int)((other_data & 0x80000000) >> 31);
171
172 fputc (' ', file);
173 fprintf_vma (file, i + section->vma); fputc ('\t', file);
174 fprintf_vma (file, begin_addr); fputc (' ', file);
175 fprintf_vma (file, prolog_length); fputc (' ', file);
176 fprintf_vma (file, function_length); fputc (' ', file);
177 fprintf (file, "%2d %2d ", flag32bit, exception_flag);
178
179 /* Get the exception handler's address and the data passed from the
180 .text section. This is really the data that belongs with the .pdata
181 but got "compressed" out for the ARM and SH4 architectures. */
182 tsection = bfd_get_section_by_name (abfd, ".text");
183 if (tsection && coff_section_data (abfd, tsection)
184 && pei_section_data (abfd, tsection))
185 {
186 if (bfd_malloc_and_get_section (abfd, tsection, & tdata))
187 {
188 int xx = (begin_addr - 8) - tsection->vma;
189
190 tdata = bfd_malloc (8);
191 if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8))
192 {
193 bfd_vma eh, eh_data;
194
195 eh = bfd_get_32 (abfd, tdata);
196 eh_data = bfd_get_32 (abfd, tdata + 4);
197 fprintf (file, "%08x ", (unsigned int) eh);
198 fprintf (file, "%08x", (unsigned int) eh_data);
199 if (eh != 0)
200 {
201 const char *s = my_symbol_for_address (abfd, eh, &sym_cache);
202
203 if (s)
204 fprintf (file, " (%s) ", s);
205 }
206 }
207 free (tdata);
208 }
209 else
210 {
211 if (tdata)
212 free (tdata);
213 }
214 }
215
216 fprintf (file, "\n");
217 }
218
219 free (data);
220
221 cleanup_syms (& sym_cache);
222
223 return TRUE;
224#undef PDATA_ROW_SIZE
225}
This page took 0.122274 seconds and 4 git commands to generate.