1 /* BFD back-end for ARM WINCE PE files.
2 Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
21 #define TARGET_UNDERSCORE 0
22 #define USER_LABEL_PREFIX ""
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"
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
36 #define LOCAL_LABEL_PREFIX "."
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 *);
47 typedef struct sym_cache
54 slurp_symtab (bfd *abfd, sym_cache *psc)
59 if (!(bfd_get_file_flags (abfd) & HAS_SYMS))
65 storage = bfd_get_symtab_upper_bound (abfd);
69 sy = bfd_malloc (storage);
71 psc->symcount = bfd_canonicalize_symtab (abfd, sy);
72 if (psc->symcount < 0)
78 my_symbol_for_address (bfd *abfd, bfd_vma func, sym_cache *psc)
83 psc->syms = slurp_symtab (abfd, psc);
85 for (i = 0; i < psc->symcount; i++)
87 if (psc->syms[i]->section->vma + psc->syms[i]->value == func)
88 return psc->syms[i]->name;
95 cleanup_syms (sym_cache *psc)
102 /* This is the version for "compressed" pdata. */
105 pe_print_ce_compressed_pdata (bfd * abfd, void * vfile)
107 # define PDATA_ROW_SIZE (2 * 4)
108 FILE *file = (FILE *) vfile;
110 asection *section = bfd_get_section_by_name (abfd, ".pdata");
111 bfd_size_type datasize = 0;
113 bfd_size_type start, stop;
114 int onaline = PDATA_ROW_SIZE;
115 struct sym_cache sym_cache = {0, 0} ;
118 || coff_section_data (abfd, section) == NULL
119 || pei_section_data (abfd, section) == NULL)
122 stop = pei_section_data (abfd, section)->virt_size;
123 if ((stop % onaline) != 0)
125 _("Warning, .pdata section size (%ld) is not a multiple of %d\n"),
126 (long) stop, onaline);
129 _("\nThe Function Table (interpreted .pdata section contents)\n"));
132 vma:\t\tBegin Prolog Function Flags Exception EH\n\
133 \t\tAddress Length Length 32b exc Handler Data\n"));
135 datasize = section->size;
139 if (! bfd_malloc_and_get_section (abfd, section, &data))
148 for (i = start; i < stop; i += onaline)
152 bfd_vma prolog_length, function_length;
153 int flag32bit, exception_flag;
157 if (i + PDATA_ROW_SIZE > stop)
160 begin_addr = GET_PDATA_ENTRY (abfd, data + i );
161 other_data = GET_PDATA_ENTRY (abfd, data + i + 4);
163 if (begin_addr == 0 && other_data == 0)
164 /* We are probably into the padding of the section now. */
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);
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);
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))
186 if (bfd_malloc_and_get_section (abfd, tsection, & tdata))
188 int xx = (begin_addr - 8) - tsection->vma;
190 tdata = bfd_malloc (8);
191 if (bfd_get_section_contents (abfd, tsection, tdata, (bfd_vma) xx, 8))
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);
201 const char *s = my_symbol_for_address (abfd, eh, &sym_cache);
204 fprintf (file, " (%s) ", s);
216 fprintf (file, "\n");
221 cleanup_syms (& sym_cache);
224 #undef PDATA_ROW_SIZE