pef.c revision 1.1 1 1.1 skrll /* PEF support for BFD.
2 1.1 skrll Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 1.1 skrll Free Software Foundation, Inc.
4 1.1 skrll
5 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
6 1.1 skrll
7 1.1 skrll This program is free software; you can redistribute it and/or modify
8 1.1 skrll it under the terms of the GNU General Public License as published by
9 1.1 skrll the Free Software Foundation; either version 3 of the License, or
10 1.1 skrll (at your option) any later version.
11 1.1 skrll
12 1.1 skrll This program is distributed in the hope that it will be useful,
13 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 skrll GNU General Public License for more details.
16 1.1 skrll
17 1.1 skrll You should have received a copy of the GNU General Public License
18 1.1 skrll along with this program; if not, write to the Free Software
19 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 skrll MA 02110-1301, USA. */
21 1.1 skrll
22 1.1 skrll #include "sysdep.h"
23 1.1 skrll #include "safe-ctype.h"
24 1.1 skrll #include "pef.h"
25 1.1 skrll #include "pef-traceback.h"
26 1.1 skrll #include "bfd.h"
27 1.1 skrll #include "libbfd.h"
28 1.1 skrll #include "libiberty.h"
29 1.1 skrll
30 1.1 skrll #ifndef BFD_IO_FUNCS
31 1.1 skrll #define BFD_IO_FUNCS 0
32 1.1 skrll #endif
33 1.1 skrll
34 1.1 skrll #define bfd_pef_close_and_cleanup _bfd_generic_close_and_cleanup
35 1.1 skrll #define bfd_pef_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
36 1.1 skrll #define bfd_pef_new_section_hook _bfd_generic_new_section_hook
37 1.1 skrll #define bfd_pef_bfd_is_local_label_name bfd_generic_is_local_label_name
38 1.1 skrll #define bfd_pef_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
39 1.1 skrll #define bfd_pef_get_lineno _bfd_nosymbols_get_lineno
40 1.1 skrll #define bfd_pef_find_nearest_line _bfd_nosymbols_find_nearest_line
41 1.1 skrll #define bfd_pef_find_inliner_info _bfd_nosymbols_find_inliner_info
42 1.1 skrll #define bfd_pef_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
43 1.1 skrll #define bfd_pef_read_minisymbols _bfd_generic_read_minisymbols
44 1.1 skrll #define bfd_pef_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
45 1.1 skrll #define bfd_pef_set_arch_mach _bfd_generic_set_arch_mach
46 1.1 skrll #define bfd_pef_get_section_contents _bfd_generic_get_section_contents
47 1.1 skrll #define bfd_pef_set_section_contents _bfd_generic_set_section_contents
48 1.1 skrll #define bfd_pef_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
49 1.1 skrll #define bfd_pef_bfd_relax_section bfd_generic_relax_section
50 1.1 skrll #define bfd_pef_bfd_gc_sections bfd_generic_gc_sections
51 1.1 skrll #define bfd_pef_bfd_merge_sections bfd_generic_merge_sections
52 1.1 skrll #define bfd_pef_bfd_is_group_section bfd_generic_is_group_section
53 1.1 skrll #define bfd_pef_bfd_discard_group bfd_generic_discard_group
54 1.1 skrll #define bfd_pef_section_already_linked _bfd_generic_section_already_linked
55 1.1 skrll #define bfd_pef_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
56 1.1 skrll #define bfd_pef_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
57 1.1 skrll #define bfd_pef_bfd_link_add_symbols _bfd_generic_link_add_symbols
58 1.1 skrll #define bfd_pef_bfd_link_just_syms _bfd_generic_link_just_syms
59 1.1 skrll #define bfd_pef_bfd_final_link _bfd_generic_final_link
60 1.1 skrll #define bfd_pef_bfd_link_split_section _bfd_generic_link_split_section
61 1.1 skrll #define bfd_pef_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
62 1.1 skrll
63 1.1 skrll static int
64 1.1 skrll bfd_pef_parse_traceback_table (bfd *abfd,
65 1.1 skrll asection *section,
66 1.1 skrll unsigned char *buf,
67 1.1 skrll size_t len,
68 1.1 skrll size_t pos,
69 1.1 skrll asymbol *sym,
70 1.1 skrll FILE *file)
71 1.1 skrll {
72 1.1 skrll struct traceback_table table;
73 1.1 skrll size_t offset;
74 1.1 skrll const char *s;
75 1.1 skrll asymbol tmpsymbol;
76 1.1 skrll
77 1.1 skrll if (sym == NULL)
78 1.1 skrll sym = & tmpsymbol;
79 1.1 skrll
80 1.1 skrll sym->name = NULL;
81 1.1 skrll sym->value = 0;
82 1.1 skrll sym->the_bfd = abfd;
83 1.1 skrll sym->section = section;
84 1.1 skrll sym->flags = 0;
85 1.1 skrll sym->udata.i = 0;
86 1.1 skrll
87 1.1 skrll /* memcpy is fine since all fields are unsigned char. */
88 1.1 skrll if ((pos + 8) > len)
89 1.1 skrll return -1;
90 1.1 skrll memcpy (&table, buf + pos, 8);
91 1.1 skrll
92 1.1 skrll /* Calling code relies on returned symbols having a name and
93 1.1 skrll correct offset. */
94 1.1 skrll if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
95 1.1 skrll return -1;
96 1.1 skrll
97 1.1 skrll if (! (table.flags2 & TB_NAME_PRESENT))
98 1.1 skrll return -1;
99 1.1 skrll
100 1.1 skrll if (! table.flags1 & TB_HAS_TBOFF)
101 1.1 skrll return -1;
102 1.1 skrll
103 1.1 skrll offset = 8;
104 1.1 skrll
105 1.1 skrll if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
106 1.1 skrll offset += 4;
107 1.1 skrll
108 1.1 skrll if (table.flags1 & TB_HAS_TBOFF)
109 1.1 skrll {
110 1.1 skrll struct traceback_table_tboff off;
111 1.1 skrll
112 1.1 skrll if ((pos + offset + 4) > len)
113 1.1 skrll return -1;
114 1.1 skrll off.tb_offset = bfd_getb32 (buf + pos + offset);
115 1.1 skrll offset += 4;
116 1.1 skrll
117 1.1 skrll /* Need to subtract 4 because the offset includes the 0x0L
118 1.1 skrll preceding the table. */
119 1.1 skrll if (file != NULL)
120 1.1 skrll fprintf (file, " [offset = 0x%lx]", off.tb_offset);
121 1.1 skrll
122 1.1 skrll if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
123 1.1 skrll return -1;
124 1.1 skrll
125 1.1 skrll sym->value = pos - off.tb_offset - 4;
126 1.1 skrll }
127 1.1 skrll
128 1.1 skrll if (table.flags2 & TB_INT_HNDL)
129 1.1 skrll offset += 4;
130 1.1 skrll
131 1.1 skrll if (table.flags1 & TB_HAS_CTL)
132 1.1 skrll {
133 1.1 skrll struct traceback_table_anchors anchors;
134 1.1 skrll
135 1.1 skrll if ((pos + offset + 4) > len)
136 1.1 skrll return -1;
137 1.1 skrll anchors.ctl_info = bfd_getb32 (buf + pos + offset);
138 1.1 skrll offset += 4;
139 1.1 skrll
140 1.1 skrll if (anchors.ctl_info > 1024)
141 1.1 skrll return -1;
142 1.1 skrll
143 1.1 skrll offset += anchors.ctl_info * 4;
144 1.1 skrll }
145 1.1 skrll
146 1.1 skrll if (table.flags2 & TB_NAME_PRESENT)
147 1.1 skrll {
148 1.1 skrll struct traceback_table_routine name;
149 1.1 skrll char *namebuf;
150 1.1 skrll
151 1.1 skrll if ((pos + offset + 2) > len)
152 1.1 skrll return -1;
153 1.1 skrll name.name_len = bfd_getb16 (buf + pos + offset);
154 1.1 skrll offset += 2;
155 1.1 skrll
156 1.1 skrll if (name.name_len > 4096)
157 1.1 skrll return -1;
158 1.1 skrll
159 1.1 skrll if ((pos + offset + name.name_len) > len)
160 1.1 skrll return -1;
161 1.1 skrll
162 1.1 skrll namebuf = bfd_alloc (abfd, name.name_len + 1);
163 1.1 skrll if (namebuf == NULL)
164 1.1 skrll return -1;
165 1.1 skrll
166 1.1 skrll memcpy (namebuf, buf + pos + offset, name.name_len);
167 1.1 skrll namebuf[name.name_len] = '\0';
168 1.1 skrll
169 1.1 skrll /* Strip leading period inserted by compiler. */
170 1.1 skrll if (namebuf[0] == '.')
171 1.1 skrll memmove (namebuf, namebuf + 1, name.name_len + 1);
172 1.1 skrll
173 1.1 skrll sym->name = namebuf;
174 1.1 skrll
175 1.1 skrll for (s = sym->name; (*s != '\0'); s++)
176 1.1 skrll if (! ISPRINT (*s))
177 1.1 skrll return -1;
178 1.1 skrll
179 1.1 skrll offset += name.name_len;
180 1.1 skrll }
181 1.1 skrll
182 1.1 skrll if (table.flags2 & TB_USES_ALLOCA)
183 1.1 skrll offset += 4;
184 1.1 skrll
185 1.1 skrll if (table.flags4 & TB_HAS_VEC_INFO)
186 1.1 skrll offset += 4;
187 1.1 skrll
188 1.1 skrll if (file != NULL)
189 1.1 skrll fprintf (file, " [length = 0x%lx]", (unsigned long) offset);
190 1.1 skrll
191 1.1 skrll return offset;
192 1.1 skrll }
193 1.1 skrll
194 1.1 skrll static void
195 1.1 skrll bfd_pef_print_symbol (bfd *abfd,
196 1.1 skrll void * afile,
197 1.1 skrll asymbol *symbol,
198 1.1 skrll bfd_print_symbol_type how)
199 1.1 skrll {
200 1.1 skrll FILE *file = (FILE *) afile;
201 1.1 skrll
202 1.1 skrll switch (how)
203 1.1 skrll {
204 1.1 skrll case bfd_print_symbol_name:
205 1.1 skrll fprintf (file, "%s", symbol->name);
206 1.1 skrll break;
207 1.1 skrll default:
208 1.1 skrll bfd_print_symbol_vandf (abfd, (void *) file, symbol);
209 1.1 skrll fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
210 1.1 skrll if (CONST_STRNEQ (symbol->name, "__traceback_"))
211 1.1 skrll {
212 1.1 skrll unsigned char *buf = alloca (symbol->udata.i);
213 1.1 skrll size_t offset = symbol->value + 4;
214 1.1 skrll size_t len = symbol->udata.i;
215 1.1 skrll int ret;
216 1.1 skrll
217 1.1 skrll bfd_get_section_contents (abfd, symbol->section, buf, offset, len);
218 1.1 skrll ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf,
219 1.1 skrll len, 0, NULL, file);
220 1.1 skrll if (ret < 0)
221 1.1 skrll fprintf (file, " [ERROR]");
222 1.1 skrll }
223 1.1 skrll }
224 1.1 skrll }
225 1.1 skrll
226 1.1 skrll static void
227 1.1 skrll bfd_pef_convert_architecture (unsigned long architecture,
228 1.1 skrll enum bfd_architecture *type,
229 1.1 skrll unsigned long *subtype)
230 1.1 skrll {
231 1.1 skrll const unsigned long ARCH_POWERPC = 0x70777063; /* 'pwpc'. */
232 1.1 skrll const unsigned long ARCH_M68K = 0x6d36386b; /* 'm68k'. */
233 1.1 skrll
234 1.1 skrll *subtype = bfd_arch_unknown;
235 1.1 skrll *type = bfd_arch_unknown;
236 1.1 skrll
237 1.1 skrll if (architecture == ARCH_POWERPC)
238 1.1 skrll *type = bfd_arch_powerpc;
239 1.1 skrll else if (architecture == ARCH_M68K)
240 1.1 skrll *type = bfd_arch_m68k;
241 1.1 skrll }
242 1.1 skrll
243 1.1 skrll static bfd_boolean
244 1.1 skrll bfd_pef_mkobject (bfd *abfd ATTRIBUTE_UNUSED)
245 1.1 skrll {
246 1.1 skrll return TRUE;
247 1.1 skrll }
248 1.1 skrll
249 1.1 skrll static const char *bfd_pef_section_name (bfd_pef_section *section)
250 1.1 skrll {
251 1.1 skrll switch (section->section_kind)
252 1.1 skrll {
253 1.1 skrll case BFD_PEF_SECTION_CODE: return "code";
254 1.1 skrll case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
255 1.1 skrll case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
256 1.1 skrll case BFD_PEF_SECTION_CONSTANT: return "constant";
257 1.1 skrll case BFD_PEF_SECTION_LOADER: return "loader";
258 1.1 skrll case BFD_PEF_SECTION_DEBUG: return "debug";
259 1.1 skrll case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
260 1.1 skrll case BFD_PEF_SECTION_EXCEPTION: return "exception";
261 1.1 skrll case BFD_PEF_SECTION_TRACEBACK: return "traceback";
262 1.1 skrll default: return "unknown";
263 1.1 skrll }
264 1.1 skrll }
265 1.1 skrll
266 1.1 skrll static unsigned long bfd_pef_section_flags (bfd_pef_section *section)
267 1.1 skrll {
268 1.1 skrll switch (section->section_kind)
269 1.1 skrll {
270 1.1 skrll case BFD_PEF_SECTION_CODE:
271 1.1 skrll return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
272 1.1 skrll case BFD_PEF_SECTION_UNPACKED_DATA:
273 1.1 skrll case BFD_PEF_SECTION_PACKED_DATA:
274 1.1 skrll case BFD_PEF_SECTION_CONSTANT:
275 1.1 skrll case BFD_PEF_SECTION_LOADER:
276 1.1 skrll case BFD_PEF_SECTION_DEBUG:
277 1.1 skrll case BFD_PEF_SECTION_EXEC_DATA:
278 1.1 skrll case BFD_PEF_SECTION_EXCEPTION:
279 1.1 skrll case BFD_PEF_SECTION_TRACEBACK:
280 1.1 skrll default:
281 1.1 skrll return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
282 1.1 skrll }
283 1.1 skrll }
284 1.1 skrll
285 1.1 skrll static asection *
286 1.1 skrll bfd_pef_make_bfd_section (bfd *abfd, bfd_pef_section *section)
287 1.1 skrll {
288 1.1 skrll asection *bfdsec;
289 1.1 skrll const char *name = bfd_pef_section_name (section);
290 1.1 skrll
291 1.1 skrll bfdsec = bfd_make_section_anyway (abfd, name);
292 1.1 skrll if (bfdsec == NULL)
293 1.1 skrll return NULL;
294 1.1 skrll
295 1.1 skrll bfdsec->vma = section->default_address + section->container_offset;
296 1.1 skrll bfdsec->lma = section->default_address + section->container_offset;
297 1.1 skrll bfdsec->size = section->container_length;
298 1.1 skrll bfdsec->filepos = section->container_offset;
299 1.1 skrll bfdsec->alignment_power = section->alignment;
300 1.1 skrll
301 1.1 skrll bfdsec->flags = bfd_pef_section_flags (section);
302 1.1 skrll
303 1.1 skrll return bfdsec;
304 1.1 skrll }
305 1.1 skrll
306 1.1 skrll int
307 1.1 skrll bfd_pef_parse_loader_header (bfd *abfd ATTRIBUTE_UNUSED,
308 1.1 skrll unsigned char *buf,
309 1.1 skrll size_t len,
310 1.1 skrll bfd_pef_loader_header *header)
311 1.1 skrll {
312 1.1 skrll BFD_ASSERT (len == 56);
313 1.1 skrll
314 1.1 skrll header->main_section = bfd_getb32 (buf);
315 1.1 skrll header->main_offset = bfd_getb32 (buf + 4);
316 1.1 skrll header->init_section = bfd_getb32 (buf + 8);
317 1.1 skrll header->init_offset = bfd_getb32 (buf + 12);
318 1.1 skrll header->term_section = bfd_getb32 (buf + 16);
319 1.1 skrll header->term_offset = bfd_getb32 (buf + 20);
320 1.1 skrll header->imported_library_count = bfd_getb32 (buf + 24);
321 1.1 skrll header->total_imported_symbol_count = bfd_getb32 (buf + 28);
322 1.1 skrll header->reloc_section_count = bfd_getb32 (buf + 32);
323 1.1 skrll header->reloc_instr_offset = bfd_getb32 (buf + 36);
324 1.1 skrll header->loader_strings_offset = bfd_getb32 (buf + 40);
325 1.1 skrll header->export_hash_offset = bfd_getb32 (buf + 44);
326 1.1 skrll header->export_hash_table_power = bfd_getb32 (buf + 48);
327 1.1 skrll header->exported_symbol_count = bfd_getb32 (buf + 52);
328 1.1 skrll
329 1.1 skrll return 0;
330 1.1 skrll }
331 1.1 skrll
332 1.1 skrll int
333 1.1 skrll bfd_pef_parse_imported_library (bfd *abfd ATTRIBUTE_UNUSED,
334 1.1 skrll unsigned char *buf,
335 1.1 skrll size_t len,
336 1.1 skrll bfd_pef_imported_library *header)
337 1.1 skrll {
338 1.1 skrll BFD_ASSERT (len == 24);
339 1.1 skrll
340 1.1 skrll header->name_offset = bfd_getb32 (buf);
341 1.1 skrll header->old_implementation_version = bfd_getb32 (buf + 4);
342 1.1 skrll header->current_version = bfd_getb32 (buf + 8);
343 1.1 skrll header->imported_symbol_count = bfd_getb32 (buf + 12);
344 1.1 skrll header->first_imported_symbol = bfd_getb32 (buf + 16);
345 1.1 skrll header->options = buf[20];
346 1.1 skrll header->reserved_a = buf[21];
347 1.1 skrll header->reserved_b = bfd_getb16 (buf + 22);
348 1.1 skrll
349 1.1 skrll return 0;
350 1.1 skrll }
351 1.1 skrll
352 1.1 skrll int
353 1.1 skrll bfd_pef_parse_imported_symbol (bfd *abfd ATTRIBUTE_UNUSED,
354 1.1 skrll unsigned char *buf,
355 1.1 skrll size_t len,
356 1.1 skrll bfd_pef_imported_symbol *symbol)
357 1.1 skrll {
358 1.1 skrll unsigned long value;
359 1.1 skrll
360 1.1 skrll BFD_ASSERT (len == 4);
361 1.1 skrll
362 1.1 skrll value = bfd_getb32 (buf);
363 1.1 skrll symbol->class = value >> 24;
364 1.1 skrll symbol->name = value & 0x00ffffff;
365 1.1 skrll
366 1.1 skrll return 0;
367 1.1 skrll }
368 1.1 skrll
369 1.1 skrll int
370 1.1 skrll bfd_pef_scan_section (bfd *abfd, bfd_pef_section *section)
371 1.1 skrll {
372 1.1 skrll unsigned char buf[28];
373 1.1 skrll
374 1.1 skrll bfd_seek (abfd, section->header_offset, SEEK_SET);
375 1.1 skrll if (bfd_bread ((void *) buf, 28, abfd) != 28)
376 1.1 skrll return -1;
377 1.1 skrll
378 1.1 skrll section->name_offset = bfd_h_get_32 (abfd, buf);
379 1.1 skrll section->default_address = bfd_h_get_32 (abfd, buf + 4);
380 1.1 skrll section->total_length = bfd_h_get_32 (abfd, buf + 8);
381 1.1 skrll section->unpacked_length = bfd_h_get_32 (abfd, buf + 12);
382 1.1 skrll section->container_length = bfd_h_get_32 (abfd, buf + 16);
383 1.1 skrll section->container_offset = bfd_h_get_32 (abfd, buf + 20);
384 1.1 skrll section->section_kind = buf[24];
385 1.1 skrll section->share_kind = buf[25];
386 1.1 skrll section->alignment = buf[26];
387 1.1 skrll section->reserved = buf[27];
388 1.1 skrll
389 1.1 skrll section->bfd_section = bfd_pef_make_bfd_section (abfd, section);
390 1.1 skrll if (section->bfd_section == NULL)
391 1.1 skrll return -1;
392 1.1 skrll
393 1.1 skrll return 0;
394 1.1 skrll }
395 1.1 skrll
396 1.1 skrll void
397 1.1 skrll bfd_pef_print_loader_header (bfd *abfd ATTRIBUTE_UNUSED,
398 1.1 skrll bfd_pef_loader_header *header,
399 1.1 skrll FILE *file)
400 1.1 skrll {
401 1.1 skrll fprintf (file, "main_section: %ld\n", header->main_section);
402 1.1 skrll fprintf (file, "main_offset: %lu\n", header->main_offset);
403 1.1 skrll fprintf (file, "init_section: %ld\n", header->init_section);
404 1.1 skrll fprintf (file, "init_offset: %lu\n", header->init_offset);
405 1.1 skrll fprintf (file, "term_section: %ld\n", header->term_section);
406 1.1 skrll fprintf (file, "term_offset: %lu\n", header->term_offset);
407 1.1 skrll fprintf (file, "imported_library_count: %lu\n",
408 1.1 skrll header->imported_library_count);
409 1.1 skrll fprintf (file, "total_imported_symbol_count: %lu\n",
410 1.1 skrll header->total_imported_symbol_count);
411 1.1 skrll fprintf (file, "reloc_section_count: %lu\n", header->reloc_section_count);
412 1.1 skrll fprintf (file, "reloc_instr_offset: %lu\n", header->reloc_instr_offset);
413 1.1 skrll fprintf (file, "loader_strings_offset: %lu\n",
414 1.1 skrll header->loader_strings_offset);
415 1.1 skrll fprintf (file, "export_hash_offset: %lu\n", header->export_hash_offset);
416 1.1 skrll fprintf (file, "export_hash_table_power: %lu\n",
417 1.1 skrll header->export_hash_table_power);
418 1.1 skrll fprintf (file, "exported_symbol_count: %lu\n",
419 1.1 skrll header->exported_symbol_count);
420 1.1 skrll }
421 1.1 skrll
422 1.1 skrll int
423 1.1 skrll bfd_pef_print_loader_section (bfd *abfd, FILE *file)
424 1.1 skrll {
425 1.1 skrll bfd_pef_loader_header header;
426 1.1 skrll asection *loadersec = NULL;
427 1.1 skrll unsigned char *loaderbuf = NULL;
428 1.1 skrll size_t loaderlen = 0;
429 1.1 skrll
430 1.1 skrll loadersec = bfd_get_section_by_name (abfd, "loader");
431 1.1 skrll if (loadersec == NULL)
432 1.1 skrll return -1;
433 1.1 skrll
434 1.1 skrll loaderlen = loadersec->size;
435 1.1 skrll loaderbuf = bfd_malloc (loaderlen);
436 1.1 skrll
437 1.1 skrll if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0
438 1.1 skrll || bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen
439 1.1 skrll || loaderlen < 56
440 1.1 skrll || bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header) < 0)
441 1.1 skrll {
442 1.1 skrll free (loaderbuf);
443 1.1 skrll return -1;
444 1.1 skrll }
445 1.1 skrll
446 1.1 skrll bfd_pef_print_loader_header (abfd, &header, file);
447 1.1 skrll return 0;
448 1.1 skrll }
449 1.1 skrll
450 1.1 skrll int
451 1.1 skrll bfd_pef_scan_start_address (bfd *abfd)
452 1.1 skrll {
453 1.1 skrll bfd_pef_loader_header header;
454 1.1 skrll asection *section;
455 1.1 skrll
456 1.1 skrll asection *loadersec = NULL;
457 1.1 skrll unsigned char *loaderbuf = NULL;
458 1.1 skrll size_t loaderlen = 0;
459 1.1 skrll int ret;
460 1.1 skrll
461 1.1 skrll loadersec = bfd_get_section_by_name (abfd, "loader");
462 1.1 skrll if (loadersec == NULL)
463 1.1 skrll goto end;
464 1.1 skrll
465 1.1 skrll loaderlen = loadersec->size;
466 1.1 skrll loaderbuf = bfd_malloc (loaderlen);
467 1.1 skrll if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
468 1.1 skrll goto error;
469 1.1 skrll if (bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen)
470 1.1 skrll goto error;
471 1.1 skrll
472 1.1 skrll if (loaderlen < 56)
473 1.1 skrll goto error;
474 1.1 skrll ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
475 1.1 skrll if (ret < 0)
476 1.1 skrll goto error;
477 1.1 skrll
478 1.1 skrll if (header.main_section < 0)
479 1.1 skrll goto end;
480 1.1 skrll
481 1.1 skrll for (section = abfd->sections; section != NULL; section = section->next)
482 1.1 skrll if ((section->index + 1) == header.main_section)
483 1.1 skrll break;
484 1.1 skrll
485 1.1 skrll if (section == NULL)
486 1.1 skrll goto error;
487 1.1 skrll
488 1.1 skrll abfd->start_address = section->vma + header.main_offset;
489 1.1 skrll
490 1.1 skrll end:
491 1.1 skrll if (loaderbuf != NULL)
492 1.1 skrll free (loaderbuf);
493 1.1 skrll return 0;
494 1.1 skrll
495 1.1 skrll error:
496 1.1 skrll if (loaderbuf != NULL)
497 1.1 skrll free (loaderbuf);
498 1.1 skrll return -1;
499 1.1 skrll }
500 1.1 skrll
501 1.1 skrll int
502 1.1 skrll bfd_pef_scan (abfd, header, mdata)
503 1.1 skrll bfd *abfd;
504 1.1 skrll bfd_pef_header *header;
505 1.1 skrll bfd_pef_data_struct *mdata;
506 1.1 skrll {
507 1.1 skrll unsigned int i;
508 1.1 skrll enum bfd_architecture cputype;
509 1.1 skrll unsigned long cpusubtype;
510 1.1 skrll
511 1.1 skrll mdata->header = *header;
512 1.1 skrll
513 1.1 skrll bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype);
514 1.1 skrll if (cputype == bfd_arch_unknown)
515 1.1 skrll {
516 1.1 skrll fprintf (stderr, "bfd_pef_scan: unknown architecture 0x%lx\n",
517 1.1 skrll header->architecture);
518 1.1 skrll return -1;
519 1.1 skrll }
520 1.1 skrll bfd_set_arch_mach (abfd, cputype, cpusubtype);
521 1.1 skrll
522 1.1 skrll mdata->header = *header;
523 1.1 skrll
524 1.1 skrll abfd->flags = (abfd->xvec->object_flags
525 1.1 skrll | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
526 1.1 skrll
527 1.1 skrll if (header->section_count != 0)
528 1.1 skrll {
529 1.1 skrll mdata->sections = bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section));
530 1.1 skrll
531 1.1 skrll if (mdata->sections == NULL)
532 1.1 skrll return -1;
533 1.1 skrll
534 1.1 skrll for (i = 0; i < header->section_count; i++)
535 1.1 skrll {
536 1.1 skrll bfd_pef_section *cur = &mdata->sections[i];
537 1.1 skrll cur->header_offset = 40 + (i * 28);
538 1.1 skrll if (bfd_pef_scan_section (abfd, cur) < 0)
539 1.1 skrll return -1;
540 1.1 skrll }
541 1.1 skrll }
542 1.1 skrll
543 1.1 skrll if (bfd_pef_scan_start_address (abfd) < 0)
544 1.1 skrll return -1;
545 1.1 skrll
546 1.1 skrll abfd->tdata.pef_data = mdata;
547 1.1 skrll
548 1.1 skrll return 0;
549 1.1 skrll }
550 1.1 skrll
551 1.1 skrll static int
552 1.1 skrll bfd_pef_read_header (bfd *abfd, bfd_pef_header *header)
553 1.1 skrll {
554 1.1 skrll unsigned char buf[40];
555 1.1 skrll
556 1.1 skrll bfd_seek (abfd, 0, SEEK_SET);
557 1.1 skrll
558 1.1 skrll if (bfd_bread ((void *) buf, 40, abfd) != 40)
559 1.1 skrll return -1;
560 1.1 skrll
561 1.1 skrll header->tag1 = bfd_getb32 (buf);
562 1.1 skrll header->tag2 = bfd_getb32 (buf + 4);
563 1.1 skrll header->architecture = bfd_getb32 (buf + 8);
564 1.1 skrll header->format_version = bfd_getb32 (buf + 12);
565 1.1 skrll header->timestamp = bfd_getb32 (buf + 16);
566 1.1 skrll header->old_definition_version = bfd_getb32 (buf + 20);
567 1.1 skrll header->old_implementation_version = bfd_getb32 (buf + 24);
568 1.1 skrll header->current_version = bfd_getb32 (buf + 28);
569 1.1 skrll header->section_count = bfd_getb32 (buf + 32) + 1;
570 1.1 skrll header->instantiated_section_count = bfd_getb32 (buf + 34);
571 1.1 skrll header->reserved = bfd_getb32 (buf + 36);
572 1.1 skrll
573 1.1 skrll return 0;
574 1.1 skrll }
575 1.1 skrll
576 1.1 skrll static const bfd_target *
577 1.1 skrll bfd_pef_object_p (bfd *abfd)
578 1.1 skrll {
579 1.1 skrll struct bfd_preserve preserve;
580 1.1 skrll bfd_pef_header header;
581 1.1 skrll
582 1.1 skrll preserve.marker = NULL;
583 1.1 skrll if (bfd_pef_read_header (abfd, &header) != 0)
584 1.1 skrll goto wrong;
585 1.1 skrll
586 1.1 skrll if (header.tag1 != BFD_PEF_TAG1 || header.tag2 != BFD_PEF_TAG2)
587 1.1 skrll goto wrong;
588 1.1 skrll
589 1.1 skrll preserve.marker = bfd_zalloc (abfd, sizeof (bfd_pef_data_struct));
590 1.1 skrll if (preserve.marker == NULL
591 1.1 skrll || !bfd_preserve_save (abfd, &preserve))
592 1.1 skrll goto fail;
593 1.1 skrll
594 1.1 skrll if (bfd_pef_scan (abfd, &header,
595 1.1 skrll (bfd_pef_data_struct *) preserve.marker) != 0)
596 1.1 skrll goto wrong;
597 1.1 skrll
598 1.1 skrll bfd_preserve_finish (abfd, &preserve);
599 1.1 skrll return abfd->xvec;
600 1.1 skrll
601 1.1 skrll wrong:
602 1.1 skrll bfd_set_error (bfd_error_wrong_format);
603 1.1 skrll
604 1.1 skrll fail:
605 1.1 skrll if (preserve.marker != NULL)
606 1.1 skrll bfd_preserve_restore (abfd, &preserve);
607 1.1 skrll return NULL;
608 1.1 skrll }
609 1.1 skrll
610 1.1 skrll static int
611 1.1 skrll bfd_pef_parse_traceback_tables (bfd *abfd,
612 1.1 skrll asection *sec,
613 1.1 skrll unsigned char *buf,
614 1.1 skrll size_t len,
615 1.1 skrll long *nsym,
616 1.1 skrll asymbol **csym)
617 1.1 skrll {
618 1.1 skrll char *name;
619 1.1 skrll
620 1.1 skrll asymbol function;
621 1.1 skrll asymbol traceback;
622 1.1 skrll
623 1.1 skrll const char *const tbprefix = "__traceback_";
624 1.1 skrll size_t tbnamelen;
625 1.1 skrll
626 1.1 skrll size_t pos = 0;
627 1.1 skrll unsigned long count = 0;
628 1.1 skrll int ret;
629 1.1 skrll
630 1.1 skrll for (;;)
631 1.1 skrll {
632 1.1 skrll /* We're reading symbols two at a time. */
633 1.1 skrll if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL)))
634 1.1 skrll break;
635 1.1 skrll
636 1.1 skrll pos += 3;
637 1.1 skrll pos -= (pos % 4);
638 1.1 skrll
639 1.1 skrll while ((pos + 4) <= len)
640 1.1 skrll {
641 1.1 skrll if (bfd_getb32 (buf + pos) == 0)
642 1.1 skrll break;
643 1.1 skrll pos += 4;
644 1.1 skrll }
645 1.1 skrll
646 1.1 skrll if ((pos + 4) > len)
647 1.1 skrll break;
648 1.1 skrll
649 1.1 skrll ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4,
650 1.1 skrll &function, 0);
651 1.1 skrll if (ret < 0)
652 1.1 skrll {
653 1.1 skrll /* Skip over 0x0L to advance to next possible traceback table. */
654 1.1 skrll pos += 4;
655 1.1 skrll continue;
656 1.1 skrll }
657 1.1 skrll
658 1.1 skrll BFD_ASSERT (function.name != NULL);
659 1.1 skrll
660 1.1 skrll /* Don't bother to compute the name if we are just
661 1.1 skrll counting symbols. */
662 1.1 skrll if (csym)
663 1.1 skrll {
664 1.1 skrll tbnamelen = strlen (tbprefix) + strlen (function.name);
665 1.1 skrll name = bfd_alloc (abfd, tbnamelen + 1);
666 1.1 skrll if (name == NULL)
667 1.1 skrll {
668 1.1 skrll bfd_release (abfd, (void *) function.name);
669 1.1 skrll function.name = NULL;
670 1.1 skrll break;
671 1.1 skrll }
672 1.1 skrll snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
673 1.1 skrll traceback.name = name;
674 1.1 skrll traceback.value = pos;
675 1.1 skrll traceback.the_bfd = abfd;
676 1.1 skrll traceback.section = sec;
677 1.1 skrll traceback.flags = 0;
678 1.1 skrll traceback.udata.i = ret;
679 1.1 skrll
680 1.1 skrll *(csym[count]) = function;
681 1.1 skrll *(csym[count + 1]) = traceback;
682 1.1 skrll }
683 1.1 skrll
684 1.1 skrll pos += ret;
685 1.1 skrll count += 2;
686 1.1 skrll }
687 1.1 skrll
688 1.1 skrll *nsym = count;
689 1.1 skrll return 0;
690 1.1 skrll }
691 1.1 skrll
692 1.1 skrll static int
693 1.1 skrll bfd_pef_parse_function_stub (bfd *abfd ATTRIBUTE_UNUSED,
694 1.1 skrll unsigned char *buf,
695 1.1 skrll size_t len,
696 1.1 skrll unsigned long *offset)
697 1.1 skrll {
698 1.1 skrll BFD_ASSERT (len == 24);
699 1.1 skrll
700 1.1 skrll if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000)
701 1.1 skrll return -1;
702 1.1 skrll if (bfd_getb32 (buf + 4) != 0x90410014)
703 1.1 skrll return -1;
704 1.1 skrll if (bfd_getb32 (buf + 8) != 0x800c0000)
705 1.1 skrll return -1;
706 1.1 skrll if (bfd_getb32 (buf + 12) != 0x804c0004)
707 1.1 skrll return -1;
708 1.1 skrll if (bfd_getb32 (buf + 16) != 0x7c0903a6)
709 1.1 skrll return -1;
710 1.1 skrll if (bfd_getb32 (buf + 20) != 0x4e800420)
711 1.1 skrll return -1;
712 1.1 skrll
713 1.1 skrll if (offset != NULL)
714 1.1 skrll *offset = (bfd_getb32 (buf) & 0x0000ffff) / 4;
715 1.1 skrll
716 1.1 skrll return 0;
717 1.1 skrll }
718 1.1 skrll
719 1.1 skrll static int
720 1.1 skrll bfd_pef_parse_function_stubs (bfd *abfd,
721 1.1 skrll asection *codesec,
722 1.1 skrll unsigned char *codebuf,
723 1.1 skrll size_t codelen,
724 1.1 skrll unsigned char *loaderbuf,
725 1.1 skrll size_t loaderlen,
726 1.1 skrll unsigned long *nsym,
727 1.1 skrll asymbol **csym)
728 1.1 skrll {
729 1.1 skrll const char *const sprefix = "__stub_";
730 1.1 skrll
731 1.1 skrll size_t codepos = 0;
732 1.1 skrll unsigned long count = 0;
733 1.1 skrll
734 1.1 skrll bfd_pef_loader_header header;
735 1.1 skrll bfd_pef_imported_library *libraries = NULL;
736 1.1 skrll bfd_pef_imported_symbol *imports = NULL;
737 1.1 skrll
738 1.1 skrll unsigned long i;
739 1.1 skrll int ret;
740 1.1 skrll
741 1.1 skrll if (loaderlen < 56)
742 1.1 skrll goto error;
743 1.1 skrll
744 1.1 skrll ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
745 1.1 skrll if (ret < 0)
746 1.1 skrll goto error;
747 1.1 skrll
748 1.1 skrll libraries = bfd_malloc
749 1.1 skrll (header.imported_library_count * sizeof (bfd_pef_imported_library));
750 1.1 skrll imports = bfd_malloc
751 1.1 skrll (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
752 1.1 skrll
753 1.1 skrll if (loaderlen < (56 + (header.imported_library_count * 24)))
754 1.1 skrll goto error;
755 1.1 skrll for (i = 0; i < header.imported_library_count; i++)
756 1.1 skrll {
757 1.1 skrll ret = bfd_pef_parse_imported_library
758 1.1 skrll (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
759 1.1 skrll if (ret < 0)
760 1.1 skrll goto error;
761 1.1 skrll }
762 1.1 skrll
763 1.1 skrll if (loaderlen < (56 + (header.imported_library_count * 24)
764 1.1 skrll + (header.total_imported_symbol_count * 4)))
765 1.1 skrll goto error;
766 1.1 skrll for (i = 0; i < header.total_imported_symbol_count; i++)
767 1.1 skrll {
768 1.1 skrll ret = (bfd_pef_parse_imported_symbol
769 1.1 skrll (abfd,
770 1.1 skrll loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4),
771 1.1 skrll 4, &imports[i]));
772 1.1 skrll if (ret < 0)
773 1.1 skrll goto error;
774 1.1 skrll }
775 1.1 skrll
776 1.1 skrll codepos = 0;
777 1.1 skrll
778 1.1 skrll for (;;)
779 1.1 skrll {
780 1.1 skrll asymbol sym;
781 1.1 skrll const char *symname;
782 1.1 skrll char *name;
783 1.1 skrll unsigned long index;
784 1.1 skrll int ret;
785 1.1 skrll
786 1.1 skrll if (csym && (csym[count] == NULL))
787 1.1 skrll break;
788 1.1 skrll
789 1.1 skrll codepos += 3;
790 1.1 skrll codepos -= (codepos % 4);
791 1.1 skrll
792 1.1 skrll while ((codepos + 4) <= codelen)
793 1.1 skrll {
794 1.1 skrll if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000)
795 1.1 skrll break;
796 1.1 skrll codepos += 4;
797 1.1 skrll }
798 1.1 skrll
799 1.1 skrll if ((codepos + 4) > codelen)
800 1.1 skrll break;
801 1.1 skrll
802 1.1 skrll ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &index);
803 1.1 skrll if (ret < 0)
804 1.1 skrll {
805 1.1 skrll codepos += 24;
806 1.1 skrll continue;
807 1.1 skrll }
808 1.1 skrll
809 1.1 skrll if (index >= header.total_imported_symbol_count)
810 1.1 skrll {
811 1.1 skrll codepos += 24;
812 1.1 skrll continue;
813 1.1 skrll }
814 1.1 skrll
815 1.1 skrll {
816 1.1 skrll size_t max, namelen;
817 1.1 skrll const char *s;
818 1.1 skrll
819 1.1 skrll if (loaderlen < (header.loader_strings_offset + imports[index].name))
820 1.1 skrll goto error;
821 1.1 skrll
822 1.1 skrll max = loaderlen - (header.loader_strings_offset + imports[index].name);
823 1.1 skrll symname = (char *) loaderbuf;
824 1.1 skrll symname += header.loader_strings_offset + imports[index].name;
825 1.1 skrll namelen = 0;
826 1.1 skrll for (s = symname; s < (symname + max); s++)
827 1.1 skrll {
828 1.1 skrll if (*s == '\0')
829 1.1 skrll break;
830 1.1 skrll if (! ISPRINT (*s))
831 1.1 skrll goto error;
832 1.1 skrll namelen++;
833 1.1 skrll }
834 1.1 skrll if (*s != '\0')
835 1.1 skrll goto error;
836 1.1 skrll
837 1.1 skrll name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
838 1.1 skrll if (name == NULL)
839 1.1 skrll break;
840 1.1 skrll
841 1.1 skrll snprintf (name, strlen (sprefix) + namelen + 1, "%s%s",
842 1.1 skrll sprefix, symname);
843 1.1 skrll sym.name = name;
844 1.1 skrll }
845 1.1 skrll
846 1.1 skrll sym.value = codepos;
847 1.1 skrll sym.the_bfd = abfd;
848 1.1 skrll sym.section = codesec;
849 1.1 skrll sym.flags = 0;
850 1.1 skrll sym.udata.i = 0;
851 1.1 skrll
852 1.1 skrll codepos += 24;
853 1.1 skrll
854 1.1 skrll if (csym != NULL)
855 1.1 skrll *(csym[count]) = sym;
856 1.1 skrll
857 1.1 skrll count++;
858 1.1 skrll }
859 1.1 skrll
860 1.1 skrll goto end;
861 1.1 skrll
862 1.1 skrll end:
863 1.1 skrll if (libraries != NULL)
864 1.1 skrll free (libraries);
865 1.1 skrll if (imports != NULL)
866 1.1 skrll free (imports);
867 1.1 skrll *nsym = count;
868 1.1 skrll return 0;
869 1.1 skrll
870 1.1 skrll error:
871 1.1 skrll if (libraries != NULL)
872 1.1 skrll free (libraries);
873 1.1 skrll if (imports != NULL)
874 1.1 skrll free (imports);
875 1.1 skrll *nsym = count;
876 1.1 skrll return -1;
877 1.1 skrll }
878 1.1 skrll
879 1.1 skrll static long
880 1.1 skrll bfd_pef_parse_symbols (bfd *abfd, asymbol **csym)
881 1.1 skrll {
882 1.1 skrll unsigned long count = 0;
883 1.1 skrll
884 1.1 skrll asection *codesec = NULL;
885 1.1 skrll unsigned char *codebuf = NULL;
886 1.1 skrll size_t codelen = 0;
887 1.1 skrll
888 1.1 skrll asection *loadersec = NULL;
889 1.1 skrll unsigned char *loaderbuf = NULL;
890 1.1 skrll size_t loaderlen = 0;
891 1.1 skrll
892 1.1 skrll codesec = bfd_get_section_by_name (abfd, "code");
893 1.1 skrll if (codesec != NULL)
894 1.1 skrll {
895 1.1 skrll codelen = codesec->size;
896 1.1 skrll codebuf = bfd_malloc (codelen);
897 1.1 skrll if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0)
898 1.1 skrll goto end;
899 1.1 skrll if (bfd_bread ((void *) codebuf, codelen, abfd) != codelen)
900 1.1 skrll goto end;
901 1.1 skrll }
902 1.1 skrll
903 1.1 skrll loadersec = bfd_get_section_by_name (abfd, "loader");
904 1.1 skrll if (loadersec != NULL)
905 1.1 skrll {
906 1.1 skrll loaderlen = loadersec->size;
907 1.1 skrll loaderbuf = bfd_malloc (loaderlen);
908 1.1 skrll if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
909 1.1 skrll goto end;
910 1.1 skrll if (bfd_bread ((void *) loaderbuf, loaderlen, abfd) != loaderlen)
911 1.1 skrll goto end;
912 1.1 skrll }
913 1.1 skrll
914 1.1 skrll count = 0;
915 1.1 skrll if (codesec != NULL)
916 1.1 skrll {
917 1.1 skrll long ncount = 0;
918 1.1 skrll bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen,
919 1.1 skrll &ncount, csym);
920 1.1 skrll count += ncount;
921 1.1 skrll }
922 1.1 skrll
923 1.1 skrll if ((codesec != NULL) && (loadersec != NULL))
924 1.1 skrll {
925 1.1 skrll unsigned long ncount = 0;
926 1.1 skrll bfd_pef_parse_function_stubs
927 1.1 skrll (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, &ncount,
928 1.1 skrll (csym != NULL) ? (csym + count) : NULL);
929 1.1 skrll count += ncount;
930 1.1 skrll }
931 1.1 skrll
932 1.1 skrll if (csym != NULL)
933 1.1 skrll csym[count] = NULL;
934 1.1 skrll
935 1.1 skrll end:
936 1.1 skrll if (codebuf != NULL)
937 1.1 skrll free (codebuf);
938 1.1 skrll
939 1.1 skrll if (loaderbuf != NULL)
940 1.1 skrll free (loaderbuf);
941 1.1 skrll
942 1.1 skrll return count;
943 1.1 skrll }
944 1.1 skrll
945 1.1 skrll static long
946 1.1 skrll bfd_pef_count_symbols (bfd *abfd)
947 1.1 skrll {
948 1.1 skrll return bfd_pef_parse_symbols (abfd, NULL);
949 1.1 skrll }
950 1.1 skrll
951 1.1 skrll static long
952 1.1 skrll bfd_pef_get_symtab_upper_bound (bfd *abfd)
953 1.1 skrll {
954 1.1 skrll long nsyms = bfd_pef_count_symbols (abfd);
955 1.1 skrll
956 1.1 skrll if (nsyms < 0)
957 1.1 skrll return nsyms;
958 1.1 skrll return ((nsyms + 1) * sizeof (asymbol *));
959 1.1 skrll }
960 1.1 skrll
961 1.1 skrll static long
962 1.1 skrll bfd_pef_canonicalize_symtab (bfd *abfd, asymbol **alocation)
963 1.1 skrll {
964 1.1 skrll long i;
965 1.1 skrll asymbol *syms;
966 1.1 skrll long ret;
967 1.1 skrll long nsyms = bfd_pef_count_symbols (abfd);
968 1.1 skrll
969 1.1 skrll if (nsyms < 0)
970 1.1 skrll return nsyms;
971 1.1 skrll
972 1.1 skrll syms = bfd_alloc (abfd, nsyms * sizeof (asymbol));
973 1.1 skrll if (syms == NULL)
974 1.1 skrll return -1;
975 1.1 skrll
976 1.1 skrll for (i = 0; i < nsyms; i++)
977 1.1 skrll alocation[i] = &syms[i];
978 1.1 skrll
979 1.1 skrll alocation[nsyms] = NULL;
980 1.1 skrll
981 1.1 skrll ret = bfd_pef_parse_symbols (abfd, alocation);
982 1.1 skrll if (ret != nsyms)
983 1.1 skrll return 0;
984 1.1 skrll
985 1.1 skrll return ret;
986 1.1 skrll }
987 1.1 skrll
988 1.1 skrll #define bfd_pef_make_empty_symbol _bfd_generic_make_empty_symbol
989 1.1 skrll
990 1.1 skrll static void
991 1.1 skrll bfd_pef_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
992 1.1 skrll asymbol *symbol,
993 1.1 skrll symbol_info *ret)
994 1.1 skrll {
995 1.1 skrll bfd_symbol_info (symbol, ret);
996 1.1 skrll }
997 1.1 skrll
998 1.1 skrll static int
999 1.1 skrll bfd_pef_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
1000 1.1 skrll struct bfd_link_info *info ATTRIBUTE_UNUSED)
1001 1.1 skrll {
1002 1.1 skrll return 0;
1003 1.1 skrll }
1004 1.1 skrll
1005 1.1 skrll const bfd_target pef_vec =
1006 1.1 skrll {
1007 1.1 skrll "pef", /* Name. */
1008 1.1 skrll bfd_target_pef_flavour, /* Flavour. */
1009 1.1 skrll BFD_ENDIAN_BIG, /* Byteorder. */
1010 1.1 skrll BFD_ENDIAN_BIG, /* Header_byteorder. */
1011 1.1 skrll (HAS_RELOC | EXEC_P | /* Object flags. */
1012 1.1 skrll HAS_LINENO | HAS_DEBUG |
1013 1.1 skrll HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1014 1.1 skrll (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
1015 1.1 skrll | SEC_ROM | SEC_HAS_CONTENTS), /* Section_flags. */
1016 1.1 skrll 0, /* Symbol_leading_char. */
1017 1.1 skrll ' ', /* AR_pad_char. */
1018 1.1 skrll 16, /* AR_max_namelen. */
1019 1.1 skrll bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1020 1.1 skrll bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1021 1.1 skrll bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
1022 1.1 skrll bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1023 1.1 skrll bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1024 1.1 skrll bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
1025 1.1 skrll { /* bfd_check_format. */
1026 1.1 skrll _bfd_dummy_target,
1027 1.1 skrll bfd_pef_object_p, /* bfd_check_format. */
1028 1.1 skrll _bfd_dummy_target,
1029 1.1 skrll _bfd_dummy_target,
1030 1.1 skrll },
1031 1.1 skrll { /* bfd_set_format. */
1032 1.1 skrll bfd_false,
1033 1.1 skrll bfd_pef_mkobject,
1034 1.1 skrll bfd_false,
1035 1.1 skrll bfd_false,
1036 1.1 skrll },
1037 1.1 skrll { /* bfd_write_contents. */
1038 1.1 skrll bfd_false,
1039 1.1 skrll bfd_true,
1040 1.1 skrll bfd_false,
1041 1.1 skrll bfd_false,
1042 1.1 skrll },
1043 1.1 skrll
1044 1.1 skrll BFD_JUMP_TABLE_GENERIC (bfd_pef),
1045 1.1 skrll BFD_JUMP_TABLE_COPY (_bfd_generic),
1046 1.1 skrll BFD_JUMP_TABLE_CORE (_bfd_nocore),
1047 1.1 skrll BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1048 1.1 skrll BFD_JUMP_TABLE_SYMBOLS (bfd_pef),
1049 1.1 skrll BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1050 1.1 skrll BFD_JUMP_TABLE_WRITE (bfd_pef),
1051 1.1 skrll BFD_JUMP_TABLE_LINK (bfd_pef),
1052 1.1 skrll BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1053 1.1 skrll
1054 1.1 skrll NULL,
1055 1.1 skrll
1056 1.1 skrll NULL
1057 1.1 skrll };
1058 1.1 skrll
1059 1.1 skrll #define bfd_pef_xlib_close_and_cleanup _bfd_generic_close_and_cleanup
1060 1.1 skrll #define bfd_pef_xlib_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1061 1.1 skrll #define bfd_pef_xlib_new_section_hook _bfd_generic_new_section_hook
1062 1.1 skrll #define bfd_pef_xlib_get_section_contents _bfd_generic_get_section_contents
1063 1.1 skrll #define bfd_pef_xlib_set_section_contents _bfd_generic_set_section_contents
1064 1.1 skrll #define bfd_pef_xlib_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1065 1.1 skrll #define bfd_pef_xlib_set_section_contents_in_window _bfd_generic_set_section_contents_in_window
1066 1.1 skrll
1067 1.1 skrll static int
1068 1.1 skrll bfd_pef_xlib_read_header (bfd *abfd, bfd_pef_xlib_header *header)
1069 1.1 skrll {
1070 1.1 skrll unsigned char buf[76];
1071 1.1 skrll
1072 1.1 skrll bfd_seek (abfd, 0, SEEK_SET);
1073 1.1 skrll
1074 1.1 skrll if (bfd_bread ((void *) buf, 76, abfd) != 76)
1075 1.1 skrll return -1;
1076 1.1 skrll
1077 1.1 skrll header->tag1 = bfd_getb32 (buf);
1078 1.1 skrll header->tag2 = bfd_getb32 (buf + 4);
1079 1.1 skrll header->current_format = bfd_getb32 (buf + 8);
1080 1.1 skrll header->container_strings_offset = bfd_getb32 (buf + 12);
1081 1.1 skrll header->export_hash_offset = bfd_getb32 (buf + 16);
1082 1.1 skrll header->export_key_offset = bfd_getb32 (buf + 20);
1083 1.1 skrll header->export_symbol_offset = bfd_getb32 (buf + 24);
1084 1.1 skrll header->export_names_offset = bfd_getb32 (buf + 28);
1085 1.1 skrll header->export_hash_table_power = bfd_getb32 (buf + 32);
1086 1.1 skrll header->exported_symbol_count = bfd_getb32 (buf + 36);
1087 1.1 skrll header->frag_name_offset = bfd_getb32 (buf + 40);
1088 1.1 skrll header->frag_name_length = bfd_getb32 (buf + 44);
1089 1.1 skrll header->dylib_path_offset = bfd_getb32 (buf + 48);
1090 1.1 skrll header->dylib_path_length = bfd_getb32 (buf + 52);
1091 1.1 skrll header->cpu_family = bfd_getb32 (buf + 56);
1092 1.1 skrll header->cpu_model = bfd_getb32 (buf + 60);
1093 1.1 skrll header->date_time_stamp = bfd_getb32 (buf + 64);
1094 1.1 skrll header->current_version = bfd_getb32 (buf + 68);
1095 1.1 skrll header->old_definition_version = bfd_getb32 (buf + 72);
1096 1.1 skrll header->old_implementation_version = bfd_getb32 (buf + 76);
1097 1.1 skrll
1098 1.1 skrll return 0;
1099 1.1 skrll }
1100 1.1 skrll
1101 1.1 skrll static int
1102 1.1 skrll bfd_pef_xlib_scan (bfd *abfd, bfd_pef_xlib_header *header)
1103 1.1 skrll {
1104 1.1 skrll bfd_pef_xlib_data_struct *mdata = NULL;
1105 1.1 skrll
1106 1.1 skrll mdata = bfd_alloc (abfd, sizeof (* mdata));
1107 1.1 skrll if (mdata == NULL)
1108 1.1 skrll return -1;
1109 1.1 skrll
1110 1.1 skrll mdata->header = *header;
1111 1.1 skrll
1112 1.1 skrll abfd->flags = (abfd->xvec->object_flags
1113 1.1 skrll | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
1114 1.1 skrll
1115 1.1 skrll abfd->tdata.pef_xlib_data = mdata;
1116 1.1 skrll
1117 1.1 skrll return 0;
1118 1.1 skrll }
1119 1.1 skrll
1120 1.1 skrll static const bfd_target *
1121 1.1 skrll bfd_pef_xlib_object_p (bfd *abfd)
1122 1.1 skrll {
1123 1.1 skrll struct bfd_preserve preserve;
1124 1.1 skrll bfd_pef_xlib_header header;
1125 1.1 skrll
1126 1.1 skrll if (bfd_pef_xlib_read_header (abfd, &header) != 0)
1127 1.1 skrll {
1128 1.1 skrll bfd_set_error (bfd_error_wrong_format);
1129 1.1 skrll return NULL;
1130 1.1 skrll }
1131 1.1 skrll
1132 1.1 skrll if ((header.tag1 != BFD_PEF_XLIB_TAG1)
1133 1.1 skrll || ((header.tag2 != BFD_PEF_VLIB_TAG2)
1134 1.1 skrll && (header.tag2 != BFD_PEF_BLIB_TAG2)))
1135 1.1 skrll {
1136 1.1 skrll bfd_set_error (bfd_error_wrong_format);
1137 1.1 skrll return NULL;
1138 1.1 skrll }
1139 1.1 skrll
1140 1.1 skrll if (! bfd_preserve_save (abfd, &preserve))
1141 1.1 skrll {
1142 1.1 skrll bfd_set_error (bfd_error_wrong_format);
1143 1.1 skrll return NULL;
1144 1.1 skrll }
1145 1.1 skrll
1146 1.1 skrll if (bfd_pef_xlib_scan (abfd, &header) != 0)
1147 1.1 skrll {
1148 1.1 skrll bfd_preserve_restore (abfd, &preserve);
1149 1.1 skrll bfd_set_error (bfd_error_wrong_format);
1150 1.1 skrll return NULL;
1151 1.1 skrll }
1152 1.1 skrll
1153 1.1 skrll bfd_preserve_finish (abfd, &preserve);
1154 1.1 skrll return abfd->xvec;
1155 1.1 skrll }
1156 1.1 skrll
1157 1.1 skrll const bfd_target pef_xlib_vec =
1158 1.1 skrll {
1159 1.1 skrll "pef-xlib", /* Name. */
1160 1.1 skrll bfd_target_pef_xlib_flavour, /* Flavour. */
1161 1.1 skrll BFD_ENDIAN_BIG, /* Byteorder */
1162 1.1 skrll BFD_ENDIAN_BIG, /* Header_byteorder. */
1163 1.1 skrll (HAS_RELOC | EXEC_P | /* Object flags. */
1164 1.1 skrll HAS_LINENO | HAS_DEBUG |
1165 1.1 skrll HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1166 1.1 skrll (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_DATA
1167 1.1 skrll | SEC_ROM | SEC_HAS_CONTENTS),/* Section_flags. */
1168 1.1 skrll 0, /* Symbol_leading_char. */
1169 1.1 skrll ' ', /* AR_pad_char. */
1170 1.1 skrll 16, /* AR_max_namelen. */
1171 1.1 skrll bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1172 1.1 skrll bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1173 1.1 skrll bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Data. */
1174 1.1 skrll bfd_getb64, bfd_getb_signed_64, bfd_putb64,
1175 1.1 skrll bfd_getb32, bfd_getb_signed_32, bfd_putb32,
1176 1.1 skrll bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* Headers. */
1177 1.1 skrll { /* bfd_check_format. */
1178 1.1 skrll _bfd_dummy_target,
1179 1.1 skrll bfd_pef_xlib_object_p, /* bfd_check_format. */
1180 1.1 skrll _bfd_dummy_target,
1181 1.1 skrll _bfd_dummy_target,
1182 1.1 skrll },
1183 1.1 skrll { /* bfd_set_format. */
1184 1.1 skrll bfd_false,
1185 1.1 skrll bfd_pef_mkobject,
1186 1.1 skrll bfd_false,
1187 1.1 skrll bfd_false,
1188 1.1 skrll },
1189 1.1 skrll { /* bfd_write_contents. */
1190 1.1 skrll bfd_false,
1191 1.1 skrll bfd_true,
1192 1.1 skrll bfd_false,
1193 1.1 skrll bfd_false,
1194 1.1 skrll },
1195 1.1 skrll
1196 1.1 skrll BFD_JUMP_TABLE_GENERIC (bfd_pef_xlib),
1197 1.1 skrll BFD_JUMP_TABLE_COPY (_bfd_generic),
1198 1.1 skrll BFD_JUMP_TABLE_CORE (_bfd_nocore),
1199 1.1 skrll BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
1200 1.1 skrll BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
1201 1.1 skrll BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
1202 1.1 skrll BFD_JUMP_TABLE_WRITE (_bfd_nowrite),
1203 1.1 skrll BFD_JUMP_TABLE_LINK (_bfd_nolink),
1204 1.1 skrll BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
1205 1.1 skrll
1206 1.1 skrll NULL,
1207 1.1 skrll
1208 1.1 skrll NULL
1209 1.1 skrll };
1210