]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/pe-arm-wince.c
* pe-arm-wince.c (pe_print_compressed_pdata): Define new function to
[thirdparty/binutils-gdb.git] / bfd / pe-arm-wince.c
1 /* BFD back-end for ARM WINCE PE files.
2 Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
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
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
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.
15
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
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
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
36 #define LOCAL_LABEL_PREFIX "."
37
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
43 extern bfd_boolean pe_print_ce_compressed_pdata (bfd *, void *);
44
45 #include "pe-arm.c"
46
47 typedef struct sym_cache
48 {
49 int symcount;
50 asymbol **syms;
51 } sym_cache;
52
53 static asymbol **
54 slurp_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
77 static const char *
78 my_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
94 static void
95 cleanup_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
104 bfd_boolean
105 pe_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 }