File: | src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c |
Warning: | line 1604, column 9 Dereference of null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Support for the generic parts of COFF, for BFD. | |||
2 | Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | |||
3 | 2000, 2001, 2002, 2003, 2004, 2005 | |||
4 | Free Software Foundation, Inc. | |||
5 | Written by Cygnus Support. | |||
6 | ||||
7 | This file is part of BFD, the Binary File Descriptor library. | |||
8 | ||||
9 | This program is free software; you can redistribute it and/or modify | |||
10 | it under the terms of the GNU General Public License as published by | |||
11 | the Free Software Foundation; either version 2 of the License, or | |||
12 | (at your option) any later version. | |||
13 | ||||
14 | This program is distributed in the hope that it will be useful, | |||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
17 | GNU General Public License for more details. | |||
18 | ||||
19 | You should have received a copy of the GNU General Public License | |||
20 | along with this program; if not, write to the Free Software | |||
21 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ | |||
22 | ||||
23 | /* Most of this hacked by Steve Chamberlain, sac@cygnus.com. | |||
24 | Split out of coffcode.h by Ian Taylor, ian@cygnus.com. */ | |||
25 | ||||
26 | /* This file contains COFF code that is not dependent on any | |||
27 | particular COFF target. There is only one version of this file in | |||
28 | libbfd.a, so no target specific code may be put in here. Or, to | |||
29 | put it another way, | |||
30 | ||||
31 | ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE ********** | |||
32 | ||||
33 | If you need to add some target specific behaviour, add a new hook | |||
34 | function to bfd_coff_backend_data. | |||
35 | ||||
36 | Some of these functions are also called by the ECOFF routines. | |||
37 | Those functions may not use any COFF specific information, such as | |||
38 | coff_data (abfd). */ | |||
39 | ||||
40 | #include "bfd.h" | |||
41 | #include "sysdep.h" | |||
42 | #include "libbfd.h" | |||
43 | #include "coff/internal.h" | |||
44 | #include "libcoff.h" | |||
45 | ||||
46 | /* Take a section header read from a coff file (in HOST byte order), | |||
47 | and make a BFD "section" out of it. This is used by ECOFF. */ | |||
48 | ||||
49 | static bfd_boolean | |||
50 | make_a_section_from_file (bfd *abfd, | |||
51 | struct internal_scnhdr *hdr, | |||
52 | unsigned int target_index) | |||
53 | { | |||
54 | asection *return_section; | |||
55 | char *name; | |||
56 | bfd_boolean result = TRUE1; | |||
57 | flagword flags; | |||
58 | ||||
59 | name = NULL((void*)0); | |||
60 | ||||
61 | /* Handle long section names as in PE. */ | |||
62 | if (bfd_coff_long_section_names (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_long_section_names) | |||
63 | && hdr->s_name[0] == '/') | |||
64 | { | |||
65 | char buf[SCNNMLEN(8)]; | |||
66 | long strindex; | |||
67 | char *p; | |||
68 | const char *strings; | |||
69 | ||||
70 | memcpy (buf, hdr->s_name + 1, SCNNMLEN(8) - 1); | |||
71 | buf[SCNNMLEN(8) - 1] = '\0'; | |||
72 | strindex = strtol (buf, &p, 10); | |||
73 | if (*p == '\0' && strindex >= 0) | |||
74 | { | |||
75 | strings = _bfd_coff_read_string_table (abfd); | |||
76 | if (strings == NULL((void*)0)) | |||
77 | return FALSE0; | |||
78 | /* FIXME: For extra safety, we should make sure that | |||
79 | strindex does not run us past the end, but right now we | |||
80 | don't know the length of the string table. */ | |||
81 | strings += strindex; | |||
82 | name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1); | |||
83 | if (name == NULL((void*)0)) | |||
84 | return FALSE0; | |||
85 | strcpy (name, strings); | |||
86 | } | |||
87 | } | |||
88 | ||||
89 | if (name == NULL((void*)0)) | |||
90 | { | |||
91 | /* Assorted wastage to null-terminate the name, thanks AT&T! */ | |||
92 | name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1); | |||
93 | if (name == NULL((void*)0)) | |||
94 | return FALSE0; | |||
95 | strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name)); | |||
96 | name[sizeof (hdr->s_name)] = 0; | |||
97 | } | |||
98 | ||||
99 | return_section = bfd_make_section_anyway (abfd, name); | |||
100 | if (return_section == NULL((void*)0)) | |||
101 | return FALSE0; | |||
102 | ||||
103 | return_section->vma = hdr->s_vaddr; | |||
104 | return_section->lma = hdr->s_paddr; | |||
105 | return_section->size = hdr->s_size; | |||
106 | return_section->filepos = hdr->s_scnptr; | |||
107 | return_section->rel_filepos = hdr->s_relptr; | |||
108 | return_section->reloc_count = hdr->s_nreloc; | |||
109 | ||||
110 | bfd_coff_set_alignment_hook (abfd, return_section, hdr)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_set_alignment_hook) (abfd, return_section, hdr)); | |||
111 | ||||
112 | return_section->line_filepos = hdr->s_lnnoptr; | |||
113 | ||||
114 | return_section->lineno_count = hdr->s_nlnno; | |||
115 | return_section->userdata = NULL((void*)0); | |||
116 | return_section->next = NULL((void*)0); | |||
117 | return_section->target_index = target_index; | |||
118 | ||||
119 | if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_styp_to_sec_flags_hook) (abfd, hdr, name, return_section , & flags)) | |||
120 | & flags)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_styp_to_sec_flags_hook) (abfd, hdr, name, return_section , & flags))) | |||
121 | result = FALSE0; | |||
122 | ||||
123 | return_section->flags = flags; | |||
124 | ||||
125 | /* At least on i386-coff, the line number count for a shared library | |||
126 | section must be ignored. */ | |||
127 | if ((return_section->flags & SEC_COFF_SHARED_LIBRARY0x10000000) != 0) | |||
128 | return_section->lineno_count = 0; | |||
129 | ||||
130 | if (hdr->s_nreloc != 0) | |||
131 | return_section->flags |= SEC_RELOC0x004; | |||
132 | /* FIXME: should this check 'hdr->s_size > 0'. */ | |||
133 | if (hdr->s_scnptr != 0) | |||
134 | return_section->flags |= SEC_HAS_CONTENTS0x100; | |||
135 | ||||
136 | return result; | |||
137 | } | |||
138 | ||||
139 | /* Read in a COFF object and make it into a BFD. This is used by | |||
140 | ECOFF as well. */ | |||
141 | ||||
142 | static const bfd_target * | |||
143 | coff_real_object_p (bfd *abfd, | |||
144 | unsigned nscns, | |||
145 | struct internal_filehdr *internal_f, | |||
146 | struct internal_aouthdr *internal_a) | |||
147 | { | |||
148 | flagword oflags = abfd->flags; | |||
149 | bfd_vma ostart = bfd_get_start_address (abfd)((abfd)->start_address); | |||
150 | void * tdata; | |||
151 | void * tdata_save; | |||
152 | bfd_size_type readsize; /* Length of file_info. */ | |||
153 | unsigned int scnhsz; | |||
154 | char *external_sections; | |||
155 | ||||
156 | if (!(internal_f->f_flags & F_RELFLG(0x0001))) | |||
157 | abfd->flags |= HAS_RELOC0x01; | |||
158 | if ((internal_f->f_flags & F_EXEC(0x0002))) | |||
159 | abfd->flags |= EXEC_P0x02; | |||
160 | if (!(internal_f->f_flags & F_LNNO(0x0004))) | |||
161 | abfd->flags |= HAS_LINENO0x04; | |||
162 | if (!(internal_f->f_flags & F_LSYMS(0x0008))) | |||
163 | abfd->flags |= HAS_LOCALS0x20; | |||
164 | ||||
165 | /* FIXME: How can we set D_PAGED correctly? */ | |||
166 | if ((internal_f->f_flags & F_EXEC(0x0002)) != 0) | |||
167 | abfd->flags |= D_PAGED0x100; | |||
168 | ||||
169 | bfd_get_symcount (abfd)((abfd)->symcount) = internal_f->f_nsyms; | |||
170 | if (internal_f->f_nsyms) | |||
171 | abfd->flags |= HAS_SYMS0x10; | |||
172 | ||||
173 | if (internal_a != (struct internal_aouthdr *) NULL((void*)0)) | |||
174 | bfd_get_start_address (abfd)((abfd)->start_address) = internal_a->entry; | |||
175 | else | |||
176 | bfd_get_start_address (abfd)((abfd)->start_address) = 0; | |||
177 | ||||
178 | /* Set up the tdata area. ECOFF uses its own routine, and overrides | |||
179 | abfd->flags. */ | |||
180 | tdata_save = abfd->tdata.any; | |||
181 | tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_mkobject_hook) (abfd, (void *) internal_f, (void *) internal_a)); | |||
182 | if (tdata == NULL((void*)0)) | |||
183 | goto fail2; | |||
184 | ||||
185 | scnhsz = bfd_coff_scnhsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_scnhsz); | |||
186 | readsize = (bfd_size_type) nscns * scnhsz; | |||
187 | external_sections = bfd_alloc (abfd, readsize); | |||
188 | if (!external_sections) | |||
189 | goto fail; | |||
190 | ||||
191 | if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize) | |||
192 | goto fail; | |||
193 | ||||
194 | /* Set the arch/mach *before* swapping in sections; section header swapping | |||
195 | may depend on arch/mach info. */ | |||
196 | if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_set_arch_mach_hook) (abfd, (void *) internal_f ))) | |||
197 | goto fail; | |||
198 | ||||
199 | /* Now copy data as required; construct all asections etc. */ | |||
200 | if (nscns != 0) | |||
201 | { | |||
202 | unsigned int i; | |||
203 | for (i = 0; i < nscns; i++) | |||
204 | { | |||
205 | struct internal_scnhdr tmp; | |||
206 | bfd_coff_swap_scnhdr_in (abfd,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_scnhdr_in) (abfd, (void *) (external_sections + i * scnhsz), (void *) & tmp)) | |||
207 | (void *) (external_sections + i * scnhsz),((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_scnhdr_in) (abfd, (void *) (external_sections + i * scnhsz), (void *) & tmp)) | |||
208 | (void *) & tmp)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_scnhdr_in) (abfd, (void *) (external_sections + i * scnhsz), (void *) & tmp)); | |||
209 | if (! make_a_section_from_file (abfd, &tmp, i + 1)) | |||
210 | goto fail; | |||
211 | } | |||
212 | } | |||
213 | ||||
214 | return abfd->xvec; | |||
215 | ||||
216 | fail: | |||
217 | bfd_release (abfd, tdata); | |||
218 | fail2: | |||
219 | abfd->tdata.any = tdata_save; | |||
220 | abfd->flags = oflags; | |||
221 | bfd_get_start_address (abfd)((abfd)->start_address) = ostart; | |||
222 | return (const bfd_target *) NULL((void*)0); | |||
223 | } | |||
224 | ||||
225 | /* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is | |||
226 | not a COFF file. This is also used by ECOFF. */ | |||
227 | ||||
228 | const bfd_target * | |||
229 | coff_object_p (bfd *abfd) | |||
230 | { | |||
231 | bfd_size_type filhsz; | |||
232 | bfd_size_type aoutsz; | |||
233 | unsigned int nscns; | |||
234 | void * filehdr; | |||
235 | struct internal_filehdr internal_f; | |||
236 | struct internal_aouthdr internal_a; | |||
237 | ||||
238 | /* Figure out how much to read. */ | |||
239 | filhsz = bfd_coff_filhsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_filhsz); | |||
240 | aoutsz = bfd_coff_aoutsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_aoutsz); | |||
241 | ||||
242 | filehdr = bfd_alloc (abfd, filhsz); | |||
243 | if (filehdr == NULL((void*)0)) | |||
244 | return NULL((void*)0); | |||
245 | if (bfd_bread (filehdr, filhsz, abfd) != filhsz) | |||
246 | { | |||
247 | if (bfd_get_error () != bfd_error_system_call) | |||
248 | bfd_set_error (bfd_error_wrong_format); | |||
249 | bfd_release (abfd, filehdr); | |||
250 | return NULL((void*)0); | |||
251 | } | |||
252 | bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_filehdr_in) (abfd, filehdr, &internal_f )); | |||
253 | bfd_release (abfd, filehdr); | |||
254 | ||||
255 | /* The XCOFF format has two sizes for the f_opthdr. SMALL_AOUTSZ | |||
256 | (less than aoutsz) used in object files and AOUTSZ (equal to | |||
257 | aoutsz) in executables. The bfd_coff_swap_aouthdr_in function | |||
258 | expects this header to be aoutsz bytes in length, so we use that | |||
259 | value in the call to bfd_alloc below. But we must be careful to | |||
260 | only read in f_opthdr bytes in the call to bfd_bread. We should | |||
261 | also attempt to catch corrupt or non-COFF binaries with a strange | |||
262 | value for f_opthdr. */ | |||
263 | if (! bfd_coff_bad_format_hook (abfd, &internal_f)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_bad_format_hook) (abfd, &internal_f)) | |||
264 | || internal_f.f_opthdr > aoutsz) | |||
265 | { | |||
266 | bfd_set_error (bfd_error_wrong_format); | |||
267 | return NULL((void*)0); | |||
268 | } | |||
269 | nscns = internal_f.f_nscns; | |||
270 | ||||
271 | if (internal_f.f_opthdr) | |||
272 | { | |||
273 | void * opthdr; | |||
274 | ||||
275 | opthdr = bfd_alloc (abfd, aoutsz); | |||
276 | if (opthdr == NULL((void*)0)) | |||
277 | return NULL((void*)0); | |||
278 | if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd) | |||
279 | != internal_f.f_opthdr) | |||
280 | { | |||
281 | bfd_release (abfd, opthdr); | |||
282 | return NULL((void*)0); | |||
283 | } | |||
284 | bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aouthdr_in) (abfd, opthdr, (void *) & internal_a)); | |||
285 | bfd_release (abfd, opthdr); | |||
286 | } | |||
287 | ||||
288 | return coff_real_object_p (abfd, nscns, &internal_f, | |||
289 | (internal_f.f_opthdr != 0 | |||
290 | ? &internal_a | |||
291 | : (struct internal_aouthdr *) NULL((void*)0))); | |||
292 | } | |||
293 | ||||
294 | /* Get the BFD section from a COFF symbol section number. */ | |||
295 | ||||
296 | asection * | |||
297 | coff_section_from_bfd_index (bfd *abfd, int index) | |||
298 | { | |||
299 | struct bfd_section *answer = abfd->sections; | |||
300 | ||||
301 | if (index == N_ABS((short)-1)) | |||
302 | return bfd_abs_section_ptr((asection *) &bfd_abs_section); | |||
303 | if (index == N_UNDEF((short)0)) | |||
304 | return bfd_und_section_ptr((asection *) &bfd_und_section); | |||
305 | if (index == N_DEBUG((short)-2)) | |||
306 | return bfd_abs_section_ptr((asection *) &bfd_abs_section); | |||
307 | ||||
308 | while (answer) | |||
309 | { | |||
310 | if (answer->target_index == index) | |||
311 | return answer; | |||
312 | answer = answer->next; | |||
313 | } | |||
314 | ||||
315 | /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a | |||
316 | has a bad symbol table in biglitpow.o. */ | |||
317 | return bfd_und_section_ptr((asection *) &bfd_und_section); | |||
318 | } | |||
319 | ||||
320 | /* Get the upper bound of a COFF symbol table. */ | |||
321 | ||||
322 | long | |||
323 | coff_get_symtab_upper_bound (bfd *abfd) | |||
324 | { | |||
325 | if (!bfd_coff_slurp_symbol_table (abfd)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_slurp_symbol_table) (abfd))) | |||
326 | return -1; | |||
327 | ||||
328 | return (bfd_get_symcount (abfd)((abfd)->symcount) + 1) * (sizeof (coff_symbol_type *)); | |||
329 | } | |||
330 | ||||
331 | /* Canonicalize a COFF symbol table. */ | |||
332 | ||||
333 | long | |||
334 | coff_canonicalize_symtab (bfd *abfd, asymbol **alocation) | |||
335 | { | |||
336 | unsigned int counter; | |||
337 | coff_symbol_type *symbase; | |||
338 | coff_symbol_type **location = (coff_symbol_type **) alocation; | |||
339 | ||||
340 | if (!bfd_coff_slurp_symbol_table (abfd)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_slurp_symbol_table) (abfd))) | |||
341 | return -1; | |||
342 | ||||
343 | symbase = obj_symbols (abfd)(((abfd)->tdata.coff_obj_data)->symbols); | |||
344 | counter = bfd_get_symcount (abfd)((abfd)->symcount); | |||
345 | while (counter-- > 0) | |||
346 | *location++ = symbase++; | |||
347 | ||||
348 | *location = NULL((void*)0); | |||
349 | ||||
350 | return bfd_get_symcount (abfd)((abfd)->symcount); | |||
351 | } | |||
352 | ||||
353 | /* Get the name of a symbol. The caller must pass in a buffer of size | |||
354 | >= SYMNMLEN + 1. */ | |||
355 | ||||
356 | const char * | |||
357 | _bfd_coff_internal_syment_name (bfd *abfd, | |||
358 | const struct internal_syment *sym, | |||
359 | char *buf) | |||
360 | { | |||
361 | /* FIXME: It's not clear this will work correctly if sizeof | |||
362 | (_n_zeroes) != 4. */ | |||
363 | if (sym->_n._n_n._n_zeroes != 0 | |||
364 | || sym->_n._n_n._n_offset == 0) | |||
365 | { | |||
366 | memcpy (buf, sym->_n._n_name, SYMNMLEN8); | |||
367 | buf[SYMNMLEN8] = '\0'; | |||
368 | return buf; | |||
369 | } | |||
370 | else | |||
371 | { | |||
372 | const char *strings; | |||
373 | ||||
374 | BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE)do { if (!(sym->_n._n_n._n_offset >= 4)) bfd_assert("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" ,374); } while (0); | |||
375 | strings = obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings); | |||
376 | if (strings == NULL((void*)0)) | |||
377 | { | |||
378 | strings = _bfd_coff_read_string_table (abfd); | |||
379 | if (strings == NULL((void*)0)) | |||
380 | return NULL((void*)0); | |||
381 | } | |||
382 | return strings + sym->_n._n_n._n_offset; | |||
383 | } | |||
384 | } | |||
385 | ||||
386 | /* Read in and swap the relocs. This returns a buffer holding the | |||
387 | relocs for section SEC in file ABFD. If CACHE is TRUE and | |||
388 | INTERNAL_RELOCS is NULL, the relocs read in will be saved in case | |||
389 | the function is called again. If EXTERNAL_RELOCS is not NULL, it | |||
390 | is a buffer large enough to hold the unswapped relocs. If | |||
391 | INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold | |||
392 | the swapped relocs. If REQUIRE_INTERNAL is TRUE, then the return | |||
393 | value must be INTERNAL_RELOCS. The function returns NULL on error. */ | |||
394 | ||||
395 | struct internal_reloc * | |||
396 | _bfd_coff_read_internal_relocs (bfd *abfd, | |||
397 | asection *sec, | |||
398 | bfd_boolean cache, | |||
399 | bfd_byte *external_relocs, | |||
400 | bfd_boolean require_internal, | |||
401 | struct internal_reloc *internal_relocs) | |||
402 | { | |||
403 | bfd_size_type relsz; | |||
404 | bfd_byte *free_external = NULL((void*)0); | |||
405 | struct internal_reloc *free_internal = NULL((void*)0); | |||
406 | bfd_byte *erel; | |||
407 | bfd_byte *erel_end; | |||
408 | struct internal_reloc *irel; | |||
409 | bfd_size_type amt; | |||
410 | ||||
411 | if (coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd) != NULL((void*)0) | |||
412 | && coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd)->relocs != NULL((void*)0)) | |||
413 | { | |||
414 | if (! require_internal) | |||
415 | return coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd)->relocs; | |||
416 | memcpy (internal_relocs, coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd)->relocs, | |||
417 | sec->reloc_count * sizeof (struct internal_reloc)); | |||
418 | return internal_relocs; | |||
419 | } | |||
420 | ||||
421 | relsz = bfd_coff_relsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_relsz); | |||
422 | ||||
423 | amt = sec->reloc_count * relsz; | |||
424 | if (external_relocs == NULL((void*)0)) | |||
425 | { | |||
426 | free_external = bfd_malloc (amt); | |||
427 | if (free_external == NULL((void*)0) && sec->reloc_count > 0) | |||
428 | goto error_return; | |||
429 | external_relocs = free_external; | |||
430 | } | |||
431 | ||||
432 | if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET0) != 0 | |||
433 | || bfd_bread (external_relocs, amt, abfd) != amt) | |||
434 | goto error_return; | |||
435 | ||||
436 | if (internal_relocs == NULL((void*)0)) | |||
437 | { | |||
438 | amt = sec->reloc_count; | |||
439 | amt *= sizeof (struct internal_reloc); | |||
440 | free_internal = bfd_malloc (amt); | |||
441 | if (free_internal == NULL((void*)0) && sec->reloc_count > 0) | |||
442 | goto error_return; | |||
443 | internal_relocs = free_internal; | |||
444 | } | |||
445 | ||||
446 | /* Swap in the relocs. */ | |||
447 | erel = external_relocs; | |||
448 | erel_end = erel + relsz * sec->reloc_count; | |||
449 | irel = internal_relocs; | |||
450 | for (; erel < erel_end; erel += relsz, irel++) | |||
451 | bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_reloc_in) (abfd, (void *) erel, (void *) irel)); | |||
452 | ||||
453 | if (free_external != NULL((void*)0)) | |||
454 | { | |||
455 | free (free_external); | |||
456 | free_external = NULL((void*)0); | |||
457 | } | |||
458 | ||||
459 | if (cache && free_internal != NULL((void*)0)) | |||
460 | { | |||
461 | if (coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd) == NULL((void*)0)) | |||
462 | { | |||
463 | amt = sizeof (struct coff_section_tdata); | |||
464 | sec->used_by_bfd = bfd_zalloc (abfd, amt); | |||
465 | if (sec->used_by_bfd == NULL((void*)0)) | |||
466 | goto error_return; | |||
467 | coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd)->contents = NULL((void*)0); | |||
468 | } | |||
469 | coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd)->relocs = free_internal; | |||
470 | } | |||
471 | ||||
472 | return internal_relocs; | |||
473 | ||||
474 | error_return: | |||
475 | if (free_external != NULL((void*)0)) | |||
476 | free (free_external); | |||
477 | if (free_internal != NULL((void*)0)) | |||
478 | free (free_internal); | |||
479 | return NULL((void*)0); | |||
480 | } | |||
481 | ||||
482 | /* Set lineno_count for the output sections of a COFF file. */ | |||
483 | ||||
484 | int | |||
485 | coff_count_linenumbers (bfd *abfd) | |||
486 | { | |||
487 | unsigned int limit = bfd_get_symcount (abfd)((abfd)->symcount); | |||
488 | unsigned int i; | |||
489 | int total = 0; | |||
490 | asymbol **p; | |||
491 | asection *s; | |||
492 | ||||
493 | if (limit == 0) | |||
494 | { | |||
495 | /* This may be from the backend linker, in which case the | |||
496 | lineno_count in the sections is correct. */ | |||
497 | for (s = abfd->sections; s != NULL((void*)0); s = s->next) | |||
498 | total += s->lineno_count; | |||
499 | return total; | |||
500 | } | |||
501 | ||||
502 | for (s = abfd->sections; s != NULL((void*)0); s = s->next) | |||
503 | BFD_ASSERT (s->lineno_count == 0)do { if (!(s->lineno_count == 0)) bfd_assert("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" ,503); } while (0); | |||
504 | ||||
505 | for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) | |||
506 | { | |||
507 | asymbol *q_maybe = *p; | |||
508 | ||||
509 | if (bfd_family_coff (bfd_asymbol_bfd (q_maybe))(((((q_maybe)->the_bfd))->xvec->flavour) == bfd_target_coff_flavour || ((((q_maybe)->the_bfd))->xvec->flavour) == bfd_target_xcoff_flavour )) | |||
510 | { | |||
511 | coff_symbol_type *q = coffsymbol (q_maybe)((coff_symbol_type *)(&((q_maybe)->the_bfd))); | |||
512 | ||||
513 | /* The AIX 4.1 compiler can sometimes generate line numbers | |||
514 | attached to debugging symbols. We try to simply ignore | |||
515 | those here. */ | |||
516 | if (q->lineno != NULL((void*)0) | |||
517 | && q->symbol.section->owner != NULL((void*)0)) | |||
518 | { | |||
519 | /* This symbol has line numbers. Increment the owning | |||
520 | section's linenumber count. */ | |||
521 | alent *l = q->lineno; | |||
522 | ||||
523 | do | |||
524 | { | |||
525 | asection * sec = q->symbol.section->output_section; | |||
526 | ||||
527 | /* Do not try to update fields in read-only sections. */ | |||
528 | if (! bfd_is_const_section (sec)( ((sec) == ((asection *) &bfd_abs_section)) || ((sec) == ((asection *) &bfd_und_section)) || ((sec) == ((asection *) &bfd_com_section)) || ((sec) == ((asection *) &bfd_ind_section )))) | |||
529 | sec->lineno_count ++; | |||
530 | ||||
531 | ++total; | |||
532 | ++l; | |||
533 | } | |||
534 | while (l->line_number != 0); | |||
535 | } | |||
536 | } | |||
537 | } | |||
538 | ||||
539 | return total; | |||
540 | } | |||
541 | ||||
542 | /* Takes a bfd and a symbol, returns a pointer to the coff specific | |||
543 | area of the symbol if there is one. */ | |||
544 | ||||
545 | coff_symbol_type * | |||
546 | coff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | |||
547 | asymbol *symbol) | |||
548 | { | |||
549 | if (!bfd_family_coff (bfd_asymbol_bfd (symbol))(((((symbol)->the_bfd))->xvec->flavour) == bfd_target_coff_flavour || ((((symbol)->the_bfd))->xvec->flavour) == bfd_target_xcoff_flavour )) | |||
550 | return (coff_symbol_type *) NULL((void*)0); | |||
551 | ||||
552 | if (bfd_asymbol_bfd (symbol)((symbol)->the_bfd)->tdata.coff_obj_data == (coff_data_type *) NULL((void*)0)) | |||
553 | return (coff_symbol_type *) NULL((void*)0); | |||
554 | ||||
555 | return (coff_symbol_type *) symbol; | |||
556 | } | |||
557 | ||||
558 | static void | |||
559 | fixup_symbol_value (bfd *abfd, | |||
560 | coff_symbol_type *coff_symbol_ptr, | |||
561 | struct internal_syment *syment) | |||
562 | { | |||
563 | /* Normalize the symbol flags. */ | |||
564 | if (bfd_is_com_section (coff_symbol_ptr->symbol.section)(((coff_symbol_ptr->symbol.section)->flags & 0x1000 ) != 0)) | |||
565 | { | |||
566 | /* A common symbol is undefined with a value. */ | |||
567 | syment->n_scnum = N_UNDEF((short)0); | |||
568 | syment->n_value = coff_symbol_ptr->symbol.value; | |||
569 | } | |||
570 | else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING0x08) != 0 | |||
571 | && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC0x20000) == 0) | |||
572 | { | |||
573 | syment->n_value = coff_symbol_ptr->symbol.value; | |||
574 | } | |||
575 | else if (bfd_is_und_section (coff_symbol_ptr->symbol.section)((coff_symbol_ptr->symbol.section) == ((asection *) &bfd_und_section ))) | |||
576 | { | |||
577 | syment->n_scnum = N_UNDEF((short)0); | |||
578 | syment->n_value = 0; | |||
579 | } | |||
580 | /* FIXME: Do we need to handle the absolute section here? */ | |||
581 | else | |||
582 | { | |||
583 | if (coff_symbol_ptr->symbol.section) | |||
584 | { | |||
585 | syment->n_scnum = | |||
586 | coff_symbol_ptr->symbol.section->output_section->target_index; | |||
587 | ||||
588 | syment->n_value = (coff_symbol_ptr->symbol.value | |||
589 | + coff_symbol_ptr->symbol.section->output_offset); | |||
590 | if (! obj_pe (abfd)(((abfd)->tdata.coff_obj_data)->pe)) | |||
591 | { | |||
592 | syment->n_value += (syment->n_sclass == C_STATLAB20) | |||
593 | ? coff_symbol_ptr->symbol.section->output_section->lma | |||
594 | : coff_symbol_ptr->symbol.section->output_section->vma; | |||
595 | } | |||
596 | } | |||
597 | else | |||
598 | { | |||
599 | BFD_ASSERT (0)do { if (!(0)) bfd_assert("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" ,599); } while (0); | |||
600 | /* This can happen, but I don't know why yet (steve@cygnus.com) */ | |||
601 | syment->n_scnum = N_ABS((short)-1); | |||
602 | syment->n_value = coff_symbol_ptr->symbol.value; | |||
603 | } | |||
604 | } | |||
605 | } | |||
606 | ||||
607 | /* Run through all the symbols in the symbol table and work out what | |||
608 | their indexes into the symbol table will be when output. | |||
609 | ||||
610 | Coff requires that each C_FILE symbol points to the next one in the | |||
611 | chain, and that the last one points to the first external symbol. We | |||
612 | do that here too. */ | |||
613 | ||||
614 | bfd_boolean | |||
615 | coff_renumber_symbols (bfd *bfd_ptr, int *first_undef) | |||
616 | { | |||
617 | unsigned int symbol_count = bfd_get_symcount (bfd_ptr)((bfd_ptr)->symcount); | |||
618 | asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; | |||
619 | unsigned int native_index = 0; | |||
620 | struct internal_syment *last_file = NULL((void*)0); | |||
621 | unsigned int symbol_index; | |||
622 | ||||
623 | /* COFF demands that undefined symbols come after all other symbols. | |||
624 | Since we don't need to impose this extra knowledge on all our | |||
625 | client programs, deal with that here. Sort the symbol table; | |||
626 | just move the undefined symbols to the end, leaving the rest | |||
627 | alone. The O'Reilly book says that defined global symbols come | |||
628 | at the end before the undefined symbols, so we do that here as | |||
629 | well. */ | |||
630 | /* @@ Do we have some condition we could test for, so we don't always | |||
631 | have to do this? I don't think relocatability is quite right, but | |||
632 | I'm not certain. [raeburn:19920508.1711EST] */ | |||
633 | { | |||
634 | asymbol **newsyms; | |||
635 | unsigned int i; | |||
636 | bfd_size_type amt; | |||
637 | ||||
638 | amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1); | |||
639 | newsyms = bfd_alloc (bfd_ptr, amt); | |||
640 | if (!newsyms) | |||
641 | return FALSE0; | |||
642 | bfd_ptr->outsymbols = newsyms; | |||
643 | for (i = 0; i < symbol_count; i++) | |||
644 | if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END0x400) != 0 | |||
645 | || (!bfd_is_und_section (symbol_ptr_ptr[i]->section)((symbol_ptr_ptr[i]->section) == ((asection *) &bfd_und_section )) | |||
646 | && !bfd_is_com_section (symbol_ptr_ptr[i]->section)(((symbol_ptr_ptr[i]->section)->flags & 0x1000) != 0 ) | |||
647 | && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION0x10) != 0 | |||
648 | || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL0x02 | BSF_WEAK0x80)) | |||
649 | == 0)))) | |||
650 | *newsyms++ = symbol_ptr_ptr[i]; | |||
651 | ||||
652 | for (i = 0; i < symbol_count; i++) | |||
653 | if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END0x400) == 0 | |||
654 | && !bfd_is_und_section (symbol_ptr_ptr[i]->section)((symbol_ptr_ptr[i]->section) == ((asection *) &bfd_und_section )) | |||
655 | && (bfd_is_com_section (symbol_ptr_ptr[i]->section)(((symbol_ptr_ptr[i]->section)->flags & 0x1000) != 0 ) | |||
656 | || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION0x10) == 0 | |||
657 | && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL0x02 | BSF_WEAK0x80)) | |||
658 | != 0)))) | |||
659 | *newsyms++ = symbol_ptr_ptr[i]; | |||
660 | ||||
661 | *first_undef = newsyms - bfd_ptr->outsymbols; | |||
662 | ||||
663 | for (i = 0; i < symbol_count; i++) | |||
664 | if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END0x400) == 0 | |||
665 | && bfd_is_und_section (symbol_ptr_ptr[i]->section)((symbol_ptr_ptr[i]->section) == ((asection *) &bfd_und_section ))) | |||
666 | *newsyms++ = symbol_ptr_ptr[i]; | |||
667 | *newsyms = (asymbol *) NULL((void*)0); | |||
668 | symbol_ptr_ptr = bfd_ptr->outsymbols; | |||
669 | } | |||
670 | ||||
671 | for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) | |||
672 | { | |||
673 | coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); | |||
674 | symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; | |||
675 | if (coff_symbol_ptr && coff_symbol_ptr->native) | |||
676 | { | |||
677 | combined_entry_type *s = coff_symbol_ptr->native; | |||
678 | int i; | |||
679 | ||||
680 | if (s->u.syment.n_sclass == C_FILE103) | |||
681 | { | |||
682 | if (last_file != NULL((void*)0)) | |||
683 | last_file->n_value = native_index; | |||
684 | last_file = &(s->u.syment); | |||
685 | } | |||
686 | else | |||
687 | /* Modify the symbol values according to their section and | |||
688 | type. */ | |||
689 | fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment)); | |||
690 | ||||
691 | for (i = 0; i < s->u.syment.n_numaux + 1; i++) | |||
692 | s[i].offset = native_index++; | |||
693 | } | |||
694 | else | |||
695 | native_index++; | |||
696 | } | |||
697 | ||||
698 | obj_conv_table_size (bfd_ptr)(((bfd_ptr)->tdata.coff_obj_data)->conv_table_size) = native_index; | |||
699 | ||||
700 | return TRUE1; | |||
701 | } | |||
702 | ||||
703 | /* Run thorough the symbol table again, and fix it so that all | |||
704 | pointers to entries are changed to the entries' index in the output | |||
705 | symbol table. */ | |||
706 | ||||
707 | void | |||
708 | coff_mangle_symbols (bfd *bfd_ptr) | |||
709 | { | |||
710 | unsigned int symbol_count = bfd_get_symcount (bfd_ptr)((bfd_ptr)->symcount); | |||
711 | asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; | |||
712 | unsigned int symbol_index; | |||
713 | ||||
714 | for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) | |||
715 | { | |||
716 | coff_symbol_type *coff_symbol_ptr = | |||
717 | coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); | |||
718 | ||||
719 | if (coff_symbol_ptr && coff_symbol_ptr->native) | |||
720 | { | |||
721 | int i; | |||
722 | combined_entry_type *s = coff_symbol_ptr->native; | |||
723 | ||||
724 | if (s->fix_value) | |||
725 | { | |||
726 | /* FIXME: We should use a union here. */ | |||
727 | s->u.syment.n_value = | |||
728 | (bfd_vma)((combined_entry_type *) | |||
729 | ((unsigned long) s->u.syment.n_value))->offset; | |||
730 | s->fix_value = 0; | |||
731 | } | |||
732 | if (s->fix_line) | |||
733 | { | |||
734 | /* The value is the offset into the line number entries | |||
735 | for the symbol's section. On output, the symbol's | |||
736 | section should be N_DEBUG. */ | |||
737 | s->u.syment.n_value = | |||
738 | (coff_symbol_ptr->symbol.section->output_section->line_filepos | |||
739 | + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr)(((bfd_coff_backend_data *) (bfd_ptr)->xvec->backend_data )->_bfd_linesz)); | |||
740 | coff_symbol_ptr->symbol.section = | |||
741 | coff_section_from_bfd_index (bfd_ptr, N_DEBUG((short)-2)); | |||
742 | BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING)do { if (!(coff_symbol_ptr->symbol.flags & 0x08)) bfd_assert ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c",742); } while (0); | |||
743 | } | |||
744 | for (i = 0; i < s->u.syment.n_numaux; i++) | |||
745 | { | |||
746 | combined_entry_type *a = s + i + 1; | |||
747 | if (a->fix_tag) | |||
748 | { | |||
749 | a->u.auxent.x_sym.x_tagndx.l = | |||
750 | a->u.auxent.x_sym.x_tagndx.p->offset; | |||
751 | a->fix_tag = 0; | |||
752 | } | |||
753 | if (a->fix_end) | |||
754 | { | |||
755 | a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l = | |||
756 | a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset; | |||
757 | a->fix_end = 0; | |||
758 | } | |||
759 | if (a->fix_scnlen) | |||
760 | { | |||
761 | a->u.auxent.x_csect.x_scnlen.l = | |||
762 | a->u.auxent.x_csect.x_scnlen.p->offset; | |||
763 | a->fix_scnlen = 0; | |||
764 | } | |||
765 | } | |||
766 | } | |||
767 | } | |||
768 | } | |||
769 | ||||
770 | static void | |||
771 | coff_fix_symbol_name (bfd *abfd, | |||
772 | asymbol *symbol, | |||
773 | combined_entry_type *native, | |||
774 | bfd_size_type *string_size_p, | |||
775 | asection **debug_string_section_p, | |||
776 | bfd_size_type *debug_string_size_p) | |||
777 | { | |||
778 | unsigned int name_length; | |||
779 | union internal_auxent *auxent; | |||
780 | char *name = (char *) (symbol->name); | |||
781 | ||||
782 | if (name == NULL((void*)0)) | |||
783 | { | |||
784 | /* COFF symbols always have names, so we'll make one up. */ | |||
785 | symbol->name = "strange"; | |||
786 | name = (char *) symbol->name; | |||
787 | } | |||
788 | name_length = strlen (name); | |||
789 | ||||
790 | if (native->u.syment.n_sclass == C_FILE103 | |||
791 | && native->u.syment.n_numaux > 0) | |||
792 | { | |||
793 | unsigned int filnmlen; | |||
794 | ||||
795 | if (bfd_coff_force_symnames_in_strings (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_force_symnames_in_strings)) | |||
796 | { | |||
797 | native->u.syment._n._n_n._n_offset = | |||
798 | (*string_size_p + STRING_SIZE_SIZE4); | |||
799 | native->u.syment._n._n_n._n_zeroes = 0; | |||
800 | *string_size_p += 6; /* strlen(".file") + 1 */ | |||
801 | } | |||
802 | else | |||
803 | strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN8); | |||
804 | ||||
805 | auxent = &(native + 1)->u.auxent; | |||
806 | ||||
807 | filnmlen = bfd_coff_filnmlen (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_filnmlen); | |||
808 | ||||
809 | if (bfd_coff_long_filenames (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_long_filenames)) | |||
810 | { | |||
811 | if (name_length <= filnmlen) | |||
812 | strncpy (auxent->x_file.x_fname, name, filnmlen); | |||
813 | else | |||
814 | { | |||
815 | auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE4; | |||
816 | auxent->x_file.x_n.x_zeroes = 0; | |||
817 | *string_size_p += name_length + 1; | |||
818 | } | |||
819 | } | |||
820 | else | |||
821 | { | |||
822 | strncpy (auxent->x_file.x_fname, name, filnmlen); | |||
823 | if (name_length > filnmlen) | |||
824 | name[filnmlen] = '\0'; | |||
825 | } | |||
826 | } | |||
827 | else | |||
828 | { | |||
829 | if (name_length <= SYMNMLEN8 && !bfd_coff_force_symnames_in_strings (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_force_symnames_in_strings)) | |||
830 | /* This name will fit into the symbol neatly. */ | |||
831 | strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN8); | |||
832 | ||||
833 | else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_symname_in_debug) (abfd, &native->u.syment ))) | |||
834 | { | |||
835 | native->u.syment._n._n_n._n_offset = (*string_size_p | |||
836 | + STRING_SIZE_SIZE4); | |||
837 | native->u.syment._n._n_n._n_zeroes = 0; | |||
838 | *string_size_p += name_length + 1; | |||
839 | } | |||
840 | else | |||
841 | { | |||
842 | file_ptr filepos; | |||
843 | bfd_byte buf[4]; | |||
844 | int prefix_len = bfd_coff_debug_string_prefix_length (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_debug_string_prefix_length); | |||
845 | ||||
846 | /* This name should be written into the .debug section. For | |||
847 | some reason each name is preceded by a two byte length | |||
848 | and also followed by a null byte. FIXME: We assume that | |||
849 | the .debug section has already been created, and that it | |||
850 | is large enough. */ | |||
851 | if (*debug_string_section_p == (asection *) NULL((void*)0)) | |||
852 | *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug"); | |||
853 | filepos = bfd_tell (abfd); | |||
854 | if (prefix_len == 4) | |||
855 | bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf)((*((abfd)->xvec->bfd_putx32)) (((bfd_vma) (name_length + 1)),(buf))); | |||
856 | else | |||
857 | bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf)((*((abfd)->xvec->bfd_putx16)) (((bfd_vma) (name_length + 1)),(buf))); | |||
858 | ||||
859 | if (!bfd_set_section_contents (abfd, | |||
860 | *debug_string_section_p, | |||
861 | (void *) buf, | |||
862 | (file_ptr) *debug_string_size_p, | |||
863 | (bfd_size_type) prefix_len) | |||
864 | || !bfd_set_section_contents (abfd, | |||
865 | *debug_string_section_p, | |||
866 | (void *) symbol->name, | |||
867 | (file_ptr) (*debug_string_size_p | |||
868 | + prefix_len), | |||
869 | (bfd_size_type) name_length + 1)) | |||
870 | abort ()_bfd_abort ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" , 870, __PRETTY_FUNCTION__); | |||
871 | if (bfd_seek (abfd, filepos, SEEK_SET0) != 0) | |||
872 | abort ()_bfd_abort ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" , 872, __PRETTY_FUNCTION__); | |||
873 | native->u.syment._n._n_n._n_offset = | |||
874 | *debug_string_size_p + prefix_len; | |||
875 | native->u.syment._n._n_n._n_zeroes = 0; | |||
876 | *debug_string_size_p += name_length + 1 + prefix_len; | |||
877 | } | |||
878 | } | |||
879 | } | |||
880 | ||||
881 | /* We need to keep track of the symbol index so that when we write out | |||
882 | the relocs we can get the index for a symbol. This method is a | |||
883 | hack. FIXME. */ | |||
884 | ||||
885 | #define set_index(symbol, idx)((symbol)->udata.i = (idx)) ((symbol)->udata.i = (idx)) | |||
886 | ||||
887 | /* Write a symbol out to a COFF file. */ | |||
888 | ||||
889 | static bfd_boolean | |||
890 | coff_write_symbol (bfd *abfd, | |||
891 | asymbol *symbol, | |||
892 | combined_entry_type *native, | |||
893 | bfd_vma *written, | |||
894 | bfd_size_type *string_size_p, | |||
895 | asection **debug_string_section_p, | |||
896 | bfd_size_type *debug_string_size_p) | |||
897 | { | |||
898 | unsigned int numaux = native->u.syment.n_numaux; | |||
899 | int type = native->u.syment.n_type; | |||
900 | int class = native->u.syment.n_sclass; | |||
901 | void * buf; | |||
902 | bfd_size_type symesz; | |||
903 | ||||
904 | if (native->u.syment.n_sclass == C_FILE103) | |||
905 | symbol->flags |= BSF_DEBUGGING0x08; | |||
906 | ||||
907 | if (symbol->flags & BSF_DEBUGGING0x08 | |||
908 | && bfd_is_abs_section (symbol->section)((symbol->section) == ((asection *) &bfd_abs_section))) | |||
909 | native->u.syment.n_scnum = N_DEBUG((short)-2); | |||
910 | ||||
911 | else if (bfd_is_abs_section (symbol->section)((symbol->section) == ((asection *) &bfd_abs_section))) | |||
912 | native->u.syment.n_scnum = N_ABS((short)-1); | |||
913 | ||||
914 | else if (bfd_is_und_section (symbol->section)((symbol->section) == ((asection *) &bfd_und_section))) | |||
915 | native->u.syment.n_scnum = N_UNDEF((short)0); | |||
916 | ||||
917 | else | |||
918 | native->u.syment.n_scnum = | |||
919 | symbol->section->output_section->target_index; | |||
920 | ||||
921 | coff_fix_symbol_name (abfd, symbol, native, string_size_p, | |||
922 | debug_string_section_p, debug_string_size_p); | |||
923 | ||||
924 | symesz = bfd_coff_symesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_symesz); | |||
925 | buf = bfd_alloc (abfd, symesz); | |||
926 | if (!buf) | |||
927 | return FALSE0; | |||
928 | bfd_coff_swap_sym_out (abfd, &native->u.syment, buf)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_sym_out) (abfd, &native->u.syment , buf)); | |||
929 | if (bfd_bwrite (buf, symesz, abfd) != symesz) | |||
930 | return FALSE0; | |||
931 | bfd_release (abfd, buf); | |||
932 | ||||
933 | if (native->u.syment.n_numaux > 0) | |||
934 | { | |||
935 | bfd_size_type auxesz; | |||
936 | unsigned int j; | |||
937 | ||||
938 | auxesz = bfd_coff_auxesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_auxesz); | |||
939 | buf = bfd_alloc (abfd, auxesz); | |||
940 | if (!buf) | |||
941 | return FALSE0; | |||
942 | for (j = 0; j < native->u.syment.n_numaux; j++) | |||
943 | { | |||
944 | bfd_coff_swap_aux_out (abfd,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_out) (abfd,&((native + j + 1)-> u.auxent),type,class,(int) j,native->u.syment.n_numaux,buf )) | |||
945 | &((native + j + 1)->u.auxent),((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_out) (abfd,&((native + j + 1)-> u.auxent),type,class,(int) j,native->u.syment.n_numaux,buf )) | |||
946 | type, class, (int) j,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_out) (abfd,&((native + j + 1)-> u.auxent),type,class,(int) j,native->u.syment.n_numaux,buf )) | |||
947 | native->u.syment.n_numaux,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_out) (abfd,&((native + j + 1)-> u.auxent),type,class,(int) j,native->u.syment.n_numaux,buf )) | |||
948 | buf)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_out) (abfd,&((native + j + 1)-> u.auxent),type,class,(int) j,native->u.syment.n_numaux,buf )); | |||
949 | if (bfd_bwrite (buf, auxesz, abfd) != auxesz) | |||
950 | return FALSE0; | |||
951 | } | |||
952 | bfd_release (abfd, buf); | |||
953 | } | |||
954 | ||||
955 | /* Store the index for use when we write out the relocs. */ | |||
956 | set_index (symbol, *written)((symbol)->udata.i = (*written)); | |||
957 | ||||
958 | *written += numaux + 1; | |||
959 | return TRUE1; | |||
960 | } | |||
961 | ||||
962 | /* Write out a symbol to a COFF file that does not come from a COFF | |||
963 | file originally. This symbol may have been created by the linker, | |||
964 | or we may be linking a non COFF file to a COFF file. */ | |||
965 | ||||
966 | static bfd_boolean | |||
967 | coff_write_alien_symbol (bfd *abfd, | |||
968 | asymbol *symbol, | |||
969 | bfd_vma *written, | |||
970 | bfd_size_type *string_size_p, | |||
971 | asection **debug_string_section_p, | |||
972 | bfd_size_type *debug_string_size_p) | |||
973 | { | |||
974 | combined_entry_type *native; | |||
975 | combined_entry_type dummy; | |||
976 | ||||
977 | native = &dummy; | |||
978 | native->u.syment.n_type = T_NULL0; | |||
979 | native->u.syment.n_flags = 0; | |||
980 | if (bfd_is_und_section (symbol->section)((symbol->section) == ((asection *) &bfd_und_section))) | |||
981 | { | |||
982 | native->u.syment.n_scnum = N_UNDEF((short)0); | |||
983 | native->u.syment.n_value = symbol->value; | |||
984 | } | |||
985 | else if (bfd_is_com_section (symbol->section)(((symbol->section)->flags & 0x1000) != 0)) | |||
986 | { | |||
987 | native->u.syment.n_scnum = N_UNDEF((short)0); | |||
988 | native->u.syment.n_value = symbol->value; | |||
989 | } | |||
990 | else if (symbol->flags & BSF_DEBUGGING0x08) | |||
991 | { | |||
992 | /* There isn't much point to writing out a debugging symbol | |||
993 | unless we are prepared to convert it into COFF debugging | |||
994 | format. So, we just ignore them. We must clobber the symbol | |||
995 | name to keep it from being put in the string table. */ | |||
996 | symbol->name = ""; | |||
997 | return TRUE1; | |||
998 | } | |||
999 | else | |||
1000 | { | |||
1001 | native->u.syment.n_scnum = | |||
1002 | symbol->section->output_section->target_index; | |||
1003 | native->u.syment.n_value = (symbol->value | |||
1004 | + symbol->section->output_offset); | |||
1005 | if (! obj_pe (abfd)(((abfd)->tdata.coff_obj_data)->pe)) | |||
1006 | native->u.syment.n_value += symbol->section->output_section->vma; | |||
1007 | ||||
1008 | /* Copy the any flags from the file header into the symbol. | |||
1009 | FIXME: Why? */ | |||
1010 | { | |||
1011 | coff_symbol_type *c = coff_symbol_from (abfd, symbol); | |||
1012 | if (c != (coff_symbol_type *) NULL((void*)0)) | |||
1013 | native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)((&c->symbol)->the_bfd)->flags; | |||
1014 | } | |||
1015 | } | |||
1016 | ||||
1017 | native->u.syment.n_type = 0; | |||
1018 | if (symbol->flags & BSF_LOCAL0x01) | |||
1019 | native->u.syment.n_sclass = C_STAT3; | |||
1020 | else if (symbol->flags & BSF_WEAK0x80) | |||
1021 | native->u.syment.n_sclass = obj_pe (abfd)(((abfd)->tdata.coff_obj_data)->pe) ? C_NT_WEAK105 : C_WEAKEXT127; | |||
1022 | else | |||
1023 | native->u.syment.n_sclass = C_EXT2; | |||
1024 | native->u.syment.n_numaux = 0; | |||
1025 | ||||
1026 | return coff_write_symbol (abfd, symbol, native, written, string_size_p, | |||
1027 | debug_string_section_p, debug_string_size_p); | |||
1028 | } | |||
1029 | ||||
1030 | /* Write a native symbol to a COFF file. */ | |||
1031 | ||||
1032 | static bfd_boolean | |||
1033 | coff_write_native_symbol (bfd *abfd, | |||
1034 | coff_symbol_type *symbol, | |||
1035 | bfd_vma *written, | |||
1036 | bfd_size_type *string_size_p, | |||
1037 | asection **debug_string_section_p, | |||
1038 | bfd_size_type *debug_string_size_p) | |||
1039 | { | |||
1040 | combined_entry_type *native = symbol->native; | |||
1041 | alent *lineno = symbol->lineno; | |||
1042 | ||||
1043 | /* If this symbol has an associated line number, we must store the | |||
1044 | symbol index in the line number field. We also tag the auxent to | |||
1045 | point to the right place in the lineno table. */ | |||
1046 | if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL((void*)0)) | |||
1047 | { | |||
1048 | unsigned int count = 0; | |||
1049 | ||||
1050 | lineno[count].u.offset = *written; | |||
1051 | if (native->u.syment.n_numaux) | |||
1052 | { | |||
1053 | union internal_auxent *a = &((native + 1)->u.auxent); | |||
1054 | ||||
1055 | a->x_sym.x_fcnary.x_fcn.x_lnnoptr = | |||
1056 | symbol->symbol.section->output_section->moving_line_filepos; | |||
1057 | } | |||
1058 | ||||
1059 | /* Count and relocate all other linenumbers. */ | |||
1060 | count++; | |||
1061 | while (lineno[count].line_number != 0) | |||
1062 | { | |||
1063 | lineno[count].u.offset += | |||
1064 | (symbol->symbol.section->output_section->vma | |||
1065 | + symbol->symbol.section->output_offset); | |||
1066 | count++; | |||
1067 | } | |||
1068 | symbol->done_lineno = TRUE1; | |||
1069 | ||||
1070 | if (! bfd_is_const_section (symbol->symbol.section->output_section)( ((symbol->symbol.section->output_section) == ((asection *) &bfd_abs_section)) || ((symbol->symbol.section-> output_section) == ((asection *) &bfd_und_section)) || (( symbol->symbol.section->output_section) == ((asection * ) &bfd_com_section)) || ((symbol->symbol.section->output_section ) == ((asection *) &bfd_ind_section)))) | |||
1071 | symbol->symbol.section->output_section->moving_line_filepos += | |||
1072 | count * bfd_coff_linesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_linesz); | |||
1073 | } | |||
1074 | ||||
1075 | return coff_write_symbol (abfd, &(symbol->symbol), native, written, | |||
1076 | string_size_p, debug_string_section_p, | |||
1077 | debug_string_size_p); | |||
1078 | } | |||
1079 | ||||
1080 | /* Write out the COFF symbols. */ | |||
1081 | ||||
1082 | bfd_boolean | |||
1083 | coff_write_symbols (bfd *abfd) | |||
1084 | { | |||
1085 | bfd_size_type string_size; | |||
1086 | asection *debug_string_section; | |||
1087 | bfd_size_type debug_string_size; | |||
1088 | unsigned int i; | |||
1089 | unsigned int limit = bfd_get_symcount (abfd)((abfd)->symcount); | |||
1090 | bfd_vma written = 0; | |||
1091 | asymbol **p; | |||
1092 | ||||
1093 | string_size = 0; | |||
1094 | debug_string_section = NULL((void*)0); | |||
1095 | debug_string_size = 0; | |||
1096 | ||||
1097 | /* If this target supports long section names, they must be put into | |||
1098 | the string table. This is supported by PE. This code must | |||
1099 | handle section names just as they are handled in | |||
1100 | coff_write_object_contents. */ | |||
1101 | if (bfd_coff_long_section_names (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_long_section_names)) | |||
1102 | { | |||
1103 | asection *o; | |||
1104 | ||||
1105 | for (o = abfd->sections; o != NULL((void*)0); o = o->next) | |||
1106 | { | |||
1107 | size_t len; | |||
1108 | ||||
1109 | len = strlen (o->name); | |||
1110 | if (len > SCNNMLEN(8)) | |||
1111 | string_size += len + 1; | |||
1112 | } | |||
1113 | } | |||
1114 | ||||
1115 | /* Seek to the right place. */ | |||
1116 | if (bfd_seek (abfd, obj_sym_filepos (abfd)(((abfd)->tdata.coff_obj_data)->sym_filepos), SEEK_SET0) != 0) | |||
1117 | return FALSE0; | |||
1118 | ||||
1119 | /* Output all the symbols we have. */ | |||
1120 | written = 0; | |||
1121 | for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) | |||
1122 | { | |||
1123 | asymbol *symbol = *p; | |||
1124 | coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol); | |||
1125 | ||||
1126 | if (c_symbol == (coff_symbol_type *) NULL((void*)0) | |||
1127 | || c_symbol->native == (combined_entry_type *) NULL((void*)0)) | |||
1128 | { | |||
1129 | if (!coff_write_alien_symbol (abfd, symbol, &written, &string_size, | |||
1130 | &debug_string_section, | |||
1131 | &debug_string_size)) | |||
1132 | return FALSE0; | |||
1133 | } | |||
1134 | else | |||
1135 | { | |||
1136 | if (!coff_write_native_symbol (abfd, c_symbol, &written, | |||
1137 | &string_size, &debug_string_section, | |||
1138 | &debug_string_size)) | |||
1139 | return FALSE0; | |||
1140 | } | |||
1141 | } | |||
1142 | ||||
1143 | obj_raw_syment_count (abfd)(((abfd)->tdata.coff_obj_data)->raw_syment_count) = written; | |||
1144 | ||||
1145 | /* Now write out strings. */ | |||
1146 | if (string_size != 0) | |||
1147 | { | |||
1148 | unsigned int size = string_size + STRING_SIZE_SIZE4; | |||
1149 | bfd_byte buffer[STRING_SIZE_SIZE4]; | |||
1150 | ||||
1151 | #if STRING_SIZE_SIZE4 == 4 | |||
1152 | H_PUT_32 (abfd, size, buffer)((*((abfd)->xvec->bfd_h_putx32)) (size, buffer)); | |||
1153 | #else | |||
1154 | #error Change H_PUT_32bfd_h_put_32 | |||
1155 | #endif | |||
1156 | if (bfd_bwrite ((void *) buffer, (bfd_size_type) sizeof (buffer), abfd) | |||
1157 | != sizeof (buffer)) | |||
1158 | return FALSE0; | |||
1159 | ||||
1160 | /* Handle long section names. This code must handle section | |||
1161 | names just as they are handled in coff_write_object_contents. */ | |||
1162 | if (bfd_coff_long_section_names (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_long_section_names)) | |||
1163 | { | |||
1164 | asection *o; | |||
1165 | ||||
1166 | for (o = abfd->sections; o != NULL((void*)0); o = o->next) | |||
1167 | { | |||
1168 | size_t len; | |||
1169 | ||||
1170 | len = strlen (o->name); | |||
1171 | if (len > SCNNMLEN(8)) | |||
1172 | { | |||
1173 | if (bfd_bwrite (o->name, (bfd_size_type) (len + 1), abfd) | |||
1174 | != len + 1) | |||
1175 | return FALSE0; | |||
1176 | } | |||
1177 | } | |||
1178 | } | |||
1179 | ||||
1180 | for (p = abfd->outsymbols, i = 0; | |||
1181 | i < limit; | |||
1182 | i++, p++) | |||
1183 | { | |||
1184 | asymbol *q = *p; | |||
1185 | size_t name_length = strlen (q->name); | |||
1186 | coff_symbol_type *c_symbol = coff_symbol_from (abfd, q); | |||
1187 | size_t maxlen; | |||
1188 | ||||
1189 | /* Figure out whether the symbol name should go in the string | |||
1190 | table. Symbol names that are short enough are stored | |||
1191 | directly in the syment structure. File names permit a | |||
1192 | different, longer, length in the syment structure. On | |||
1193 | XCOFF, some symbol names are stored in the .debug section | |||
1194 | rather than in the string table. */ | |||
1195 | ||||
1196 | if (c_symbol == NULL((void*)0) | |||
1197 | || c_symbol->native == NULL((void*)0)) | |||
1198 | /* This is not a COFF symbol, so it certainly is not a | |||
1199 | file name, nor does it go in the .debug section. */ | |||
1200 | maxlen = bfd_coff_force_symnames_in_strings (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_force_symnames_in_strings) ? 0 : SYMNMLEN8; | |||
1201 | ||||
1202 | else if (bfd_coff_symname_in_debug (abfd,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_symname_in_debug) (abfd, &c_symbol->native ->u.syment)) | |||
1203 | &c_symbol->native->u.syment)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_symname_in_debug) (abfd, &c_symbol->native ->u.syment))) | |||
1204 | /* This symbol name is in the XCOFF .debug section. | |||
1205 | Don't write it into the string table. */ | |||
1206 | maxlen = name_length; | |||
1207 | ||||
1208 | else if (c_symbol->native->u.syment.n_sclass == C_FILE103 | |||
1209 | && c_symbol->native->u.syment.n_numaux > 0) | |||
1210 | { | |||
1211 | if (bfd_coff_force_symnames_in_strings (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_force_symnames_in_strings)) | |||
1212 | { | |||
1213 | if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) | |||
1214 | return FALSE0; | |||
1215 | } | |||
1216 | maxlen = bfd_coff_filnmlen (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_filnmlen); | |||
1217 | } | |||
1218 | else | |||
1219 | maxlen = bfd_coff_force_symnames_in_strings (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_coff_force_symnames_in_strings) ? 0 : SYMNMLEN8; | |||
1220 | ||||
1221 | if (name_length > maxlen) | |||
1222 | { | |||
1223 | if (bfd_bwrite ((void *) (q->name), (bfd_size_type) name_length + 1, | |||
1224 | abfd) != name_length + 1) | |||
1225 | return FALSE0; | |||
1226 | } | |||
1227 | } | |||
1228 | } | |||
1229 | else | |||
1230 | { | |||
1231 | /* We would normally not write anything here, but we'll write | |||
1232 | out 4 so that any stupid coff reader which tries to read the | |||
1233 | string table even when there isn't one won't croak. */ | |||
1234 | unsigned int size = STRING_SIZE_SIZE4; | |||
1235 | bfd_byte buffer[STRING_SIZE_SIZE4]; | |||
1236 | ||||
1237 | #if STRING_SIZE_SIZE4 == 4 | |||
1238 | H_PUT_32 (abfd, size, buffer)((*((abfd)->xvec->bfd_h_putx32)) (size, buffer)); | |||
1239 | #else | |||
1240 | #error Change H_PUT_32bfd_h_put_32 | |||
1241 | #endif | |||
1242 | if (bfd_bwrite ((void *) buffer, (bfd_size_type) STRING_SIZE_SIZE4, abfd) | |||
1243 | != STRING_SIZE_SIZE4) | |||
1244 | return FALSE0; | |||
1245 | } | |||
1246 | ||||
1247 | /* Make sure the .debug section was created to be the correct size. | |||
1248 | We should create it ourselves on the fly, but we don't because | |||
1249 | BFD won't let us write to any section until we know how large all | |||
1250 | the sections are. We could still do it by making another pass | |||
1251 | over the symbols. FIXME. */ | |||
1252 | BFD_ASSERT (debug_string_size == 0do { if (!(debug_string_size == 0 || (debug_string_section != (asection *) ((void*)0) && (((((bfd_vma) (debug_string_size ) + (1 << debug_string_section->alignment_power) - 1 ) >= (bfd_vma) (debug_string_size)) ? (((bfd_vma) (debug_string_size ) + ((1 << debug_string_section->alignment_power) - 1 )) & ~ (bfd_vma) ((1 << debug_string_section->alignment_power )-1)) : ~ (bfd_vma) 0) == debug_string_section->size)))) bfd_assert ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c",1256); } while (0) | |||
1253 | || (debug_string_section != (asection *) NULLdo { if (!(debug_string_size == 0 || (debug_string_section != (asection *) ((void*)0) && (((((bfd_vma) (debug_string_size ) + (1 << debug_string_section->alignment_power) - 1 ) >= (bfd_vma) (debug_string_size)) ? (((bfd_vma) (debug_string_size ) + ((1 << debug_string_section->alignment_power) - 1 )) & ~ (bfd_vma) ((1 << debug_string_section->alignment_power )-1)) : ~ (bfd_vma) 0) == debug_string_section->size)))) bfd_assert ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c",1256); } while (0) | |||
1254 | && (BFD_ALIGN (debug_string_size,do { if (!(debug_string_size == 0 || (debug_string_section != (asection *) ((void*)0) && (((((bfd_vma) (debug_string_size ) + (1 << debug_string_section->alignment_power) - 1 ) >= (bfd_vma) (debug_string_size)) ? (((bfd_vma) (debug_string_size ) + ((1 << debug_string_section->alignment_power) - 1 )) & ~ (bfd_vma) ((1 << debug_string_section->alignment_power )-1)) : ~ (bfd_vma) 0) == debug_string_section->size)))) bfd_assert ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c",1256); } while (0) | |||
1255 | 1 << debug_string_section->alignment_power)do { if (!(debug_string_size == 0 || (debug_string_section != (asection *) ((void*)0) && (((((bfd_vma) (debug_string_size ) + (1 << debug_string_section->alignment_power) - 1 ) >= (bfd_vma) (debug_string_size)) ? (((bfd_vma) (debug_string_size ) + ((1 << debug_string_section->alignment_power) - 1 )) & ~ (bfd_vma) ((1 << debug_string_section->alignment_power )-1)) : ~ (bfd_vma) 0) == debug_string_section->size)))) bfd_assert ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c",1256); } while (0) | |||
1256 | == debug_string_section->size)))do { if (!(debug_string_size == 0 || (debug_string_section != (asection *) ((void*)0) && (((((bfd_vma) (debug_string_size ) + (1 << debug_string_section->alignment_power) - 1 ) >= (bfd_vma) (debug_string_size)) ? (((bfd_vma) (debug_string_size ) + ((1 << debug_string_section->alignment_power) - 1 )) & ~ (bfd_vma) ((1 << debug_string_section->alignment_power )-1)) : ~ (bfd_vma) 0) == debug_string_section->size)))) bfd_assert ("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c",1256); } while (0); | |||
1257 | ||||
1258 | return TRUE1; | |||
1259 | } | |||
1260 | ||||
1261 | bfd_boolean | |||
1262 | coff_write_linenumbers (bfd *abfd) | |||
1263 | { | |||
1264 | asection *s; | |||
1265 | bfd_size_type linesz; | |||
1266 | void * buff; | |||
1267 | ||||
1268 | linesz = bfd_coff_linesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_linesz); | |||
1269 | buff = bfd_alloc (abfd, linesz); | |||
1270 | if (!buff) | |||
1271 | return FALSE0; | |||
1272 | for (s = abfd->sections; s != (asection *) NULL((void*)0); s = s->next) | |||
1273 | { | |||
1274 | if (s->lineno_count) | |||
1275 | { | |||
1276 | asymbol **q = abfd->outsymbols; | |||
1277 | if (bfd_seek (abfd, s->line_filepos, SEEK_SET0) != 0) | |||
1278 | return FALSE0; | |||
1279 | /* Find all the linenumbers in this section. */ | |||
1280 | while (*q) | |||
1281 | { | |||
1282 | asymbol *p = *q; | |||
1283 | if (p->section->output_section == s) | |||
1284 | { | |||
1285 | alent *l = | |||
1286 | BFD_SEND (bfd_asymbol_bfd (p), _get_lineno,((*((((p)->the_bfd))->xvec->_get_lineno)) (((p)-> the_bfd), p)) | |||
1287 | (bfd_asymbol_bfd (p), p))((*((((p)->the_bfd))->xvec->_get_lineno)) (((p)-> the_bfd), p)); | |||
1288 | if (l) | |||
1289 | { | |||
1290 | /* Found a linenumber entry, output. */ | |||
1291 | struct internal_lineno out; | |||
1292 | memset ((void *) & out, 0, sizeof (out)); | |||
1293 | out.l_lnno = 0; | |||
1294 | out.l_addr.l_symndx = l->u.offset; | |||
1295 | bfd_coff_swap_lineno_out (abfd, &out, buff)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_lineno_out) (abfd, &out, buff)); | |||
1296 | if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) | |||
1297 | != linesz) | |||
1298 | return FALSE0; | |||
1299 | l++; | |||
1300 | while (l->line_number) | |||
1301 | { | |||
1302 | out.l_lnno = l->line_number; | |||
1303 | out.l_addr.l_symndx = l->u.offset; | |||
1304 | bfd_coff_swap_lineno_out (abfd, &out, buff)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_lineno_out) (abfd, &out, buff)); | |||
1305 | if (bfd_bwrite (buff, (bfd_size_type) linesz, abfd) | |||
1306 | != linesz) | |||
1307 | return FALSE0; | |||
1308 | l++; | |||
1309 | } | |||
1310 | } | |||
1311 | } | |||
1312 | q++; | |||
1313 | } | |||
1314 | } | |||
1315 | } | |||
1316 | bfd_release (abfd, buff); | |||
1317 | return TRUE1; | |||
1318 | } | |||
1319 | ||||
1320 | alent * | |||
1321 | coff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED__attribute__ ((__unused__)), asymbol *symbol) | |||
1322 | { | |||
1323 | return coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->lineno; | |||
1324 | } | |||
1325 | ||||
1326 | /* This function transforms the offsets into the symbol table into | |||
1327 | pointers to syments. */ | |||
1328 | ||||
1329 | static void | |||
1330 | coff_pointerize_aux (bfd *abfd, | |||
1331 | combined_entry_type *table_base, | |||
1332 | combined_entry_type *symbol, | |||
1333 | unsigned int indaux, | |||
1334 | combined_entry_type *auxent) | |||
1335 | { | |||
1336 | unsigned int type = symbol->u.syment.n_type; | |||
1337 | unsigned int class = symbol->u.syment.n_sclass; | |||
1338 | ||||
1339 | if (coff_backend_info (abfd)((bfd_coff_backend_data *) (abfd)->xvec->backend_data)->_bfd_coff_pointerize_aux_hook) | |||
1340 | { | |||
1341 | if ((*coff_backend_info (abfd)((bfd_coff_backend_data *) (abfd)->xvec->backend_data)->_bfd_coff_pointerize_aux_hook) | |||
1342 | (abfd, table_base, symbol, indaux, auxent)) | |||
1343 | return; | |||
1344 | } | |||
1345 | ||||
1346 | /* Don't bother if this is a file or a section. */ | |||
1347 | if (class == C_STAT3 && type == T_NULL0) | |||
1348 | return; | |||
1349 | if (class == C_FILE103) | |||
1350 | return; | |||
1351 | ||||
1352 | /* Otherwise patch up. */ | |||
1353 | #define N_TMASK((abfd)->tdata.coff_obj_data)->local_n_tmask coff_data (abfd)((abfd)->tdata.coff_obj_data)->local_n_tmask | |||
1354 | #define N_BTSHFT((abfd)->tdata.coff_obj_data)->local_n_btshft coff_data (abfd)((abfd)->tdata.coff_obj_data)->local_n_btshft | |||
1355 | ||||
1356 | if ((ISFCN (type)(((unsigned long) (type) & ((abfd)->tdata.coff_obj_data )->local_n_tmask) == ((unsigned long) (2) << ((abfd) ->tdata.coff_obj_data)->local_n_btshft)) || ISTAG (class)((class) == 10 || (class) == 12 || (class) == 15) || class == C_BLOCK100 || class == C_FCN101) | |||
1357 | && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l > 0) | |||
1358 | { | |||
1359 | auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = | |||
1360 | table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; | |||
1361 | auxent->fix_end = 1; | |||
1362 | } | |||
1363 | /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can | |||
1364 | generate one, so we must be careful to ignore it. */ | |||
1365 | if (auxent->u.auxent.x_sym.x_tagndx.l > 0) | |||
1366 | { | |||
1367 | auxent->u.auxent.x_sym.x_tagndx.p = | |||
1368 | table_base + auxent->u.auxent.x_sym.x_tagndx.l; | |||
1369 | auxent->fix_tag = 1; | |||
1370 | } | |||
1371 | } | |||
1372 | ||||
1373 | /* Allocate space for the ".debug" section, and read it. | |||
1374 | We did not read the debug section until now, because | |||
1375 | we didn't want to go to the trouble until someone needed it. */ | |||
1376 | ||||
1377 | static char * | |||
1378 | build_debug_section (bfd *abfd) | |||
1379 | { | |||
1380 | char *debug_section; | |||
1381 | file_ptr position; | |||
1382 | bfd_size_type sec_size; | |||
1383 | ||||
1384 | asection *sect = bfd_get_section_by_name (abfd, ".debug"); | |||
1385 | ||||
1386 | if (!sect) | |||
1387 | { | |||
1388 | bfd_set_error (bfd_error_no_debug_section); | |||
1389 | return NULL((void*)0); | |||
1390 | } | |||
1391 | ||||
1392 | sec_size = sect->size; | |||
1393 | debug_section = bfd_alloc (abfd, sec_size); | |||
1394 | if (debug_section == NULL((void*)0)) | |||
1395 | return NULL((void*)0); | |||
1396 | ||||
1397 | /* Seek to the beginning of the `.debug' section and read it. | |||
1398 | Save the current position first; it is needed by our caller. | |||
1399 | Then read debug section and reset the file pointer. */ | |||
1400 | ||||
1401 | position = bfd_tell (abfd); | |||
1402 | if (bfd_seek (abfd, sect->filepos, SEEK_SET0) != 0 | |||
1403 | || bfd_bread (debug_section, sec_size, abfd) != sec_size | |||
1404 | || bfd_seek (abfd, position, SEEK_SET0) != 0) | |||
1405 | return NULL((void*)0); | |||
1406 | return debug_section; | |||
1407 | } | |||
1408 | ||||
1409 | /* Return a pointer to a malloc'd copy of 'name'. 'name' may not be | |||
1410 | \0-terminated, but will not exceed 'maxlen' characters. The copy *will* | |||
1411 | be \0-terminated. */ | |||
1412 | ||||
1413 | static char * | |||
1414 | copy_name (bfd *abfd, char *name, size_t maxlen) | |||
1415 | { | |||
1416 | size_t len; | |||
1417 | char *newname; | |||
1418 | ||||
1419 | for (len = 0; len < maxlen; ++len) | |||
1420 | if (name[len] == '\0') | |||
1421 | break; | |||
1422 | ||||
1423 | if ((newname = bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL((void*)0)) | |||
1424 | return NULL((void*)0); | |||
1425 | ||||
1426 | strncpy (newname, name, len); | |||
1427 | newname[len] = '\0'; | |||
1428 | return newname; | |||
1429 | } | |||
1430 | ||||
1431 | /* Read in the external symbols. */ | |||
1432 | ||||
1433 | bfd_boolean | |||
1434 | _bfd_coff_get_external_symbols (bfd *abfd) | |||
1435 | { | |||
1436 | bfd_size_type symesz; | |||
1437 | bfd_size_type size; | |||
1438 | void * syms; | |||
1439 | ||||
1440 | if (obj_coff_external_syms (abfd)(((abfd)->tdata.coff_obj_data)->external_syms) != NULL((void*)0)) | |||
1441 | return TRUE1; | |||
1442 | ||||
1443 | symesz = bfd_coff_symesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_symesz); | |||
1444 | ||||
1445 | size = obj_raw_syment_count (abfd)(((abfd)->tdata.coff_obj_data)->raw_syment_count) * symesz; | |||
1446 | ||||
1447 | syms = bfd_malloc (size); | |||
1448 | if (syms == NULL((void*)0) && size != 0) | |||
1449 | return FALSE0; | |||
1450 | ||||
1451 | if (bfd_seek (abfd, obj_sym_filepos (abfd)(((abfd)->tdata.coff_obj_data)->sym_filepos), SEEK_SET0) != 0 | |||
1452 | || bfd_bread (syms, size, abfd) != size) | |||
1453 | { | |||
1454 | if (syms != NULL((void*)0)) | |||
1455 | free (syms); | |||
1456 | return FALSE0; | |||
1457 | } | |||
1458 | ||||
1459 | obj_coff_external_syms (abfd)(((abfd)->tdata.coff_obj_data)->external_syms) = syms; | |||
1460 | ||||
1461 | return TRUE1; | |||
1462 | } | |||
1463 | ||||
1464 | /* Read in the external strings. The strings are not loaded until | |||
1465 | they are needed. This is because we have no simple way of | |||
1466 | detecting a missing string table in an archive. */ | |||
1467 | ||||
1468 | const char * | |||
1469 | _bfd_coff_read_string_table (bfd *abfd) | |||
1470 | { | |||
1471 | char extstrsize[STRING_SIZE_SIZE4]; | |||
1472 | bfd_size_type strsize; | |||
1473 | char *strings; | |||
1474 | file_ptr pos; | |||
1475 | ||||
1476 | if (obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings) != NULL((void*)0)) | |||
1477 | return obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings); | |||
1478 | ||||
1479 | if (obj_sym_filepos (abfd)(((abfd)->tdata.coff_obj_data)->sym_filepos) == 0) | |||
1480 | { | |||
1481 | bfd_set_error (bfd_error_no_symbols); | |||
1482 | return NULL((void*)0); | |||
1483 | } | |||
1484 | ||||
1485 | pos = obj_sym_filepos (abfd)(((abfd)->tdata.coff_obj_data)->sym_filepos); | |||
1486 | pos += obj_raw_syment_count (abfd)(((abfd)->tdata.coff_obj_data)->raw_syment_count) * bfd_coff_symesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_symesz); | |||
1487 | if (bfd_seek (abfd, pos, SEEK_SET0) != 0) | |||
1488 | return NULL((void*)0); | |||
1489 | ||||
1490 | if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd) | |||
1491 | != sizeof extstrsize) | |||
1492 | { | |||
1493 | if (bfd_get_error () != bfd_error_file_truncated) | |||
1494 | return NULL((void*)0); | |||
1495 | ||||
1496 | /* There is no string table. */ | |||
1497 | strsize = STRING_SIZE_SIZE4; | |||
1498 | } | |||
1499 | else | |||
1500 | { | |||
1501 | #if STRING_SIZE_SIZE4 == 4 | |||
1502 | strsize = H_GET_32 (abfd, extstrsize)((*((abfd)->xvec->bfd_h_getx32)) (extstrsize)); | |||
1503 | #else | |||
1504 | #error Change H_GET_32bfd_h_get_32 | |||
1505 | #endif | |||
1506 | } | |||
1507 | ||||
1508 | if (strsize < STRING_SIZE_SIZE4) | |||
1509 | { | |||
1510 | (*_bfd_error_handler) | |||
1511 | (_("%B: bad string table size %lu")("%B: bad string table size %lu"), abfd, (unsigned long) strsize); | |||
1512 | bfd_set_error (bfd_error_bad_value); | |||
1513 | return NULL((void*)0); | |||
1514 | } | |||
1515 | ||||
1516 | strings = bfd_malloc (strsize); | |||
1517 | if (strings == NULL((void*)0)) | |||
1518 | return NULL((void*)0); | |||
1519 | ||||
1520 | if (bfd_bread (strings + STRING_SIZE_SIZE4, strsize - STRING_SIZE_SIZE4, abfd) | |||
1521 | != strsize - STRING_SIZE_SIZE4) | |||
1522 | { | |||
1523 | free (strings); | |||
1524 | return NULL((void*)0); | |||
1525 | } | |||
1526 | ||||
1527 | obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings) = strings; | |||
1528 | ||||
1529 | return strings; | |||
1530 | } | |||
1531 | ||||
1532 | /* Free up the external symbols and strings read from a COFF file. */ | |||
1533 | ||||
1534 | bfd_boolean | |||
1535 | _bfd_coff_free_symbols (bfd *abfd) | |||
1536 | { | |||
1537 | if (obj_coff_external_syms (abfd)(((abfd)->tdata.coff_obj_data)->external_syms) != NULL((void*)0) | |||
1538 | && ! obj_coff_keep_syms (abfd)(((abfd)->tdata.coff_obj_data)->keep_syms)) | |||
1539 | { | |||
1540 | free (obj_coff_external_syms (abfd)(((abfd)->tdata.coff_obj_data)->external_syms)); | |||
1541 | obj_coff_external_syms (abfd)(((abfd)->tdata.coff_obj_data)->external_syms) = NULL((void*)0); | |||
1542 | } | |||
1543 | if (obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings) != NULL((void*)0) | |||
1544 | && ! obj_coff_keep_strings (abfd)(((abfd)->tdata.coff_obj_data)->keep_strings)) | |||
1545 | { | |||
1546 | free (obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings)); | |||
1547 | obj_coff_strings (abfd)(((abfd)->tdata.coff_obj_data)->strings) = NULL((void*)0); | |||
1548 | } | |||
1549 | return TRUE1; | |||
1550 | } | |||
1551 | ||||
1552 | /* Read a symbol table into freshly bfd_allocated memory, swap it, and | |||
1553 | knit the symbol names into a normalized form. By normalized here I | |||
1554 | mean that all symbols have an n_offset pointer that points to a null- | |||
1555 | terminated string. */ | |||
1556 | ||||
1557 | combined_entry_type * | |||
1558 | coff_get_normalized_symtab (bfd *abfd) | |||
1559 | { | |||
1560 | combined_entry_type *internal; | |||
1561 | combined_entry_type *internal_ptr; | |||
1562 | combined_entry_type *symbol_ptr; | |||
1563 | combined_entry_type *internal_end; | |||
1564 | size_t symesz; | |||
1565 | char *raw_src; | |||
1566 | char *raw_end; | |||
1567 | const char *string_table = NULL((void*)0); | |||
1568 | char *debug_section = NULL((void*)0); | |||
1569 | bfd_size_type size; | |||
1570 | ||||
1571 | if (obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments) != NULL((void*)0)) | |||
| ||||
1572 | return obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments); | |||
1573 | ||||
1574 | size = obj_raw_syment_count (abfd)(((abfd)->tdata.coff_obj_data)->raw_syment_count) * sizeof (combined_entry_type); | |||
1575 | internal = bfd_zalloc (abfd, size); | |||
1576 | if (internal == NULL((void*)0) && size != 0) | |||
1577 | return NULL((void*)0); | |||
1578 | internal_end = internal + obj_raw_syment_count (abfd)(((abfd)->tdata.coff_obj_data)->raw_syment_count); | |||
1579 | ||||
1580 | if (! _bfd_coff_get_external_symbols (abfd)) | |||
1581 | return NULL((void*)0); | |||
1582 | ||||
1583 | raw_src = (char *) obj_coff_external_syms (abfd)(((abfd)->tdata.coff_obj_data)->external_syms); | |||
1584 | ||||
1585 | /* Mark the end of the symbols. */ | |||
1586 | symesz = bfd_coff_symesz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_symesz); | |||
1587 | raw_end = (char *) raw_src + obj_raw_syment_count (abfd)(((abfd)->tdata.coff_obj_data)->raw_syment_count) * symesz; | |||
1588 | ||||
1589 | /* FIXME SOMEDAY. A string table size of zero is very weird, but | |||
1590 | probably possible. If one shows up, it will probably kill us. */ | |||
1591 | ||||
1592 | /* Swap all the raw entries. */ | |||
1593 | for (internal_ptr = internal; | |||
1594 | raw_src < raw_end; | |||
1595 | raw_src += symesz, internal_ptr++) | |||
1596 | { | |||
1597 | ||||
1598 | unsigned int i; | |||
1599 | bfd_coff_swap_sym_in (abfd, (void *) raw_src,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_sym_in) (abfd,(void *) raw_src,(void *) & internal_ptr->u.syment)) | |||
1600 | (void *) & internal_ptr->u.syment)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_sym_in) (abfd,(void *) raw_src,(void *) & internal_ptr->u.syment)); | |||
1601 | symbol_ptr = internal_ptr; | |||
1602 | ||||
1603 | for (i = 0; | |||
1604 | i < symbol_ptr->u.syment.n_numaux; | |||
| ||||
1605 | i++) | |||
1606 | { | |||
1607 | internal_ptr++; | |||
1608 | raw_src += symesz; | |||
1609 | bfd_coff_swap_aux_in (abfd, (void *) raw_src,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_in) (abfd,(void *) raw_src,symbol_ptr ->u.syment.n_type,symbol_ptr->u.syment.n_sclass,(int) i ,symbol_ptr->u.syment.n_numaux,&(internal_ptr->u.auxent ))) | |||
1610 | symbol_ptr->u.syment.n_type,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_in) (abfd,(void *) raw_src,symbol_ptr ->u.syment.n_type,symbol_ptr->u.syment.n_sclass,(int) i ,symbol_ptr->u.syment.n_numaux,&(internal_ptr->u.auxent ))) | |||
1611 | symbol_ptr->u.syment.n_sclass,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_in) (abfd,(void *) raw_src,symbol_ptr ->u.syment.n_type,symbol_ptr->u.syment.n_sclass,(int) i ,symbol_ptr->u.syment.n_numaux,&(internal_ptr->u.auxent ))) | |||
1612 | (int) i, symbol_ptr->u.syment.n_numaux,((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_in) (abfd,(void *) raw_src,symbol_ptr ->u.syment.n_type,symbol_ptr->u.syment.n_sclass,(int) i ,symbol_ptr->u.syment.n_numaux,&(internal_ptr->u.auxent ))) | |||
1613 | &(internal_ptr->u.auxent))((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_swap_aux_in) (abfd,(void *) raw_src,symbol_ptr ->u.syment.n_type,symbol_ptr->u.syment.n_sclass,(int) i ,symbol_ptr->u.syment.n_numaux,&(internal_ptr->u.auxent ))); | |||
1614 | coff_pointerize_aux (abfd, internal, symbol_ptr, i, | |||
1615 | internal_ptr); | |||
1616 | } | |||
1617 | } | |||
1618 | ||||
1619 | /* Free the raw symbols, but not the strings (if we have them). */ | |||
1620 | obj_coff_keep_strings (abfd)(((abfd)->tdata.coff_obj_data)->keep_strings) = TRUE1; | |||
1621 | if (! _bfd_coff_free_symbols (abfd)) | |||
1622 | return NULL((void*)0); | |||
1623 | ||||
1624 | for (internal_ptr = internal; internal_ptr < internal_end; | |||
1625 | internal_ptr++) | |||
1626 | { | |||
1627 | if (internal_ptr->u.syment.n_sclass == C_FILE103 | |||
1628 | && internal_ptr->u.syment.n_numaux > 0) | |||
1629 | { | |||
1630 | /* Make a file symbol point to the name in the auxent, since | |||
1631 | the text ".file" is redundant. */ | |||
1632 | if ((internal_ptr + 1)->u.auxent.x_file.x_n.x_zeroes == 0) | |||
1633 | { | |||
1634 | /* The filename is a long one, point into the string table. */ | |||
1635 | if (string_table == NULL((void*)0)) | |||
1636 | { | |||
1637 | string_table = _bfd_coff_read_string_table (abfd); | |||
1638 | if (string_table == NULL((void*)0)) | |||
1639 | return NULL((void*)0); | |||
1640 | } | |||
1641 | ||||
1642 | internal_ptr->u.syment._n._n_n._n_offset = | |||
1643 | ((long) | |||
1644 | (string_table | |||
1645 | + (internal_ptr + 1)->u.auxent.x_file.x_n.x_offset)); | |||
1646 | } | |||
1647 | else | |||
1648 | { | |||
1649 | /* Ordinary short filename, put into memory anyway. The | |||
1650 | Microsoft PE tools sometimes store a filename in | |||
1651 | multiple AUX entries. */ | |||
1652 | if (internal_ptr->u.syment.n_numaux > 1 | |||
1653 | && coff_data (abfd)((abfd)->tdata.coff_obj_data)->pe) | |||
1654 | internal_ptr->u.syment._n._n_n._n_offset = | |||
1655 | ((long) | |||
1656 | copy_name (abfd, | |||
1657 | (internal_ptr + 1)->u.auxent.x_file.x_fname, | |||
1658 | internal_ptr->u.syment.n_numaux * symesz)); | |||
1659 | else | |||
1660 | internal_ptr->u.syment._n._n_n._n_offset = | |||
1661 | ((long) | |||
1662 | copy_name (abfd, | |||
1663 | (internal_ptr + 1)->u.auxent.x_file.x_fname, | |||
1664 | (size_t) bfd_coff_filnmlen (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_filnmlen))); | |||
1665 | } | |||
1666 | } | |||
1667 | else | |||
1668 | { | |||
1669 | if (internal_ptr->u.syment._n._n_n._n_zeroes != 0) | |||
1670 | { | |||
1671 | /* This is a "short" name. Make it long. */ | |||
1672 | size_t i; | |||
1673 | char *newstring; | |||
1674 | ||||
1675 | /* Find the length of this string without walking into memory | |||
1676 | that isn't ours. */ | |||
1677 | for (i = 0; i < 8; ++i) | |||
1678 | if (internal_ptr->u.syment._n._n_name[i] == '\0') | |||
1679 | break; | |||
1680 | ||||
1681 | newstring = bfd_zalloc (abfd, (bfd_size_type) (i + 1)); | |||
1682 | if (newstring == NULL((void*)0)) | |||
1683 | return NULL((void*)0); | |||
1684 | strncpy (newstring, internal_ptr->u.syment._n._n_name, i); | |||
1685 | internal_ptr->u.syment._n._n_n._n_offset = (long int) newstring; | |||
1686 | internal_ptr->u.syment._n._n_n._n_zeroes = 0; | |||
1687 | } | |||
1688 | else if (internal_ptr->u.syment._n._n_n._n_offset == 0) | |||
1689 | internal_ptr->u.syment._n._n_n._n_offset = (long int) ""; | |||
1690 | else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_symname_in_debug) (abfd, &internal_ptr-> u.syment))) | |||
1691 | { | |||
1692 | /* Long name already. Point symbol at the string in the | |||
1693 | table. */ | |||
1694 | if (string_table == NULL((void*)0)) | |||
1695 | { | |||
1696 | string_table = _bfd_coff_read_string_table (abfd); | |||
1697 | if (string_table == NULL((void*)0)) | |||
1698 | return NULL((void*)0); | |||
1699 | } | |||
1700 | internal_ptr->u.syment._n._n_n._n_offset = | |||
1701 | ((long int) | |||
1702 | (string_table | |||
1703 | + internal_ptr->u.syment._n._n_n._n_offset)); | |||
1704 | } | |||
1705 | else | |||
1706 | { | |||
1707 | /* Long name in debug section. Very similar. */ | |||
1708 | if (debug_section == NULL((void*)0)) | |||
1709 | debug_section = build_debug_section (abfd); | |||
1710 | internal_ptr->u.syment._n._n_n._n_offset = (long int) | |||
1711 | (debug_section + internal_ptr->u.syment._n._n_n._n_offset); | |||
1712 | } | |||
1713 | } | |||
1714 | internal_ptr += internal_ptr->u.syment.n_numaux; | |||
1715 | } | |||
1716 | ||||
1717 | obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments) = internal; | |||
1718 | BFD_ASSERT (obj_raw_syment_count (abfd)do { if (!((((abfd)->tdata.coff_obj_data)->raw_syment_count ) == (unsigned int) (internal_ptr - internal))) bfd_assert("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" ,1719); } while (0) | |||
1719 | == (unsigned int) (internal_ptr - internal))do { if (!((((abfd)->tdata.coff_obj_data)->raw_syment_count ) == (unsigned int) (internal_ptr - internal))) bfd_assert("/usr/src/gnu/usr.bin/binutils-2.17/bfd/coffgen.c" ,1719); } while (0); | |||
1720 | ||||
1721 | return internal; | |||
1722 | } | |||
1723 | ||||
1724 | long | |||
1725 | coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect) | |||
1726 | { | |||
1727 | if (bfd_get_format (abfd)((abfd)->format) != bfd_object) | |||
1728 | { | |||
1729 | bfd_set_error (bfd_error_invalid_operation); | |||
1730 | return -1; | |||
1731 | } | |||
1732 | return (asect->reloc_count + 1) * sizeof (arelent *); | |||
1733 | } | |||
1734 | ||||
1735 | asymbol * | |||
1736 | coff_make_empty_symbol (bfd *abfd) | |||
1737 | { | |||
1738 | bfd_size_type amt = sizeof (coff_symbol_type); | |||
1739 | coff_symbol_type *new = bfd_zalloc (abfd, amt); | |||
1740 | ||||
1741 | if (new == NULL((void*)0)) | |||
1742 | return NULL((void*)0); | |||
1743 | new->symbol.section = 0; | |||
1744 | new->native = 0; | |||
1745 | new->lineno = NULL((void*)0); | |||
1746 | new->done_lineno = FALSE0; | |||
1747 | new->symbol.the_bfd = abfd; | |||
1748 | ||||
1749 | return & new->symbol; | |||
1750 | } | |||
1751 | ||||
1752 | /* Make a debugging symbol. */ | |||
1753 | ||||
1754 | asymbol * | |||
1755 | coff_bfd_make_debug_symbol (bfd *abfd, | |||
1756 | void * ptr ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | |||
1757 | unsigned long sz ATTRIBUTE_UNUSED__attribute__ ((__unused__))) | |||
1758 | { | |||
1759 | bfd_size_type amt = sizeof (coff_symbol_type); | |||
1760 | coff_symbol_type *new = bfd_alloc (abfd, amt); | |||
1761 | ||||
1762 | if (new == NULL((void*)0)) | |||
1763 | return NULL((void*)0); | |||
1764 | /* @@ The 10 is a guess at a plausible maximum number of aux entries | |||
1765 | (but shouldn't be a constant). */ | |||
1766 | amt = sizeof (combined_entry_type) * 10; | |||
1767 | new->native = bfd_zalloc (abfd, amt); | |||
1768 | if (!new->native) | |||
1769 | return NULL((void*)0); | |||
1770 | new->symbol.section = bfd_abs_section_ptr((asection *) &bfd_abs_section); | |||
1771 | new->symbol.flags = BSF_DEBUGGING0x08; | |||
1772 | new->lineno = NULL((void*)0); | |||
1773 | new->done_lineno = FALSE0; | |||
1774 | new->symbol.the_bfd = abfd; | |||
1775 | ||||
1776 | return & new->symbol; | |||
1777 | } | |||
1778 | ||||
1779 | void | |||
1780 | coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret) | |||
1781 | { | |||
1782 | bfd_symbol_info (symbol, ret); | |||
1783 | ||||
1784 | if (coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native != NULL((void*)0) | |||
1785 | && coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native->fix_value) | |||
1786 | ret->value = coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native->u.syment.n_value - | |||
1787 | (unsigned long) obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments); | |||
1788 | } | |||
1789 | ||||
1790 | /* Return the COFF syment for a symbol. */ | |||
1791 | ||||
1792 | bfd_boolean | |||
1793 | bfd_coff_get_syment (bfd *abfd, | |||
1794 | asymbol *symbol, | |||
1795 | struct internal_syment *psyment) | |||
1796 | { | |||
1797 | coff_symbol_type *csym; | |||
1798 | ||||
1799 | csym = coff_symbol_from (abfd, symbol); | |||
1800 | if (csym == NULL((void*)0) || csym->native == NULL((void*)0)) | |||
1801 | { | |||
1802 | bfd_set_error (bfd_error_invalid_operation); | |||
1803 | return FALSE0; | |||
1804 | } | |||
1805 | ||||
1806 | *psyment = csym->native->u.syment; | |||
1807 | ||||
1808 | if (csym->native->fix_value) | |||
1809 | psyment->n_value = psyment->n_value - | |||
1810 | (unsigned long) obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments); | |||
1811 | ||||
1812 | /* FIXME: We should handle fix_line here. */ | |||
1813 | ||||
1814 | return TRUE1; | |||
1815 | } | |||
1816 | ||||
1817 | /* Return the COFF auxent for a symbol. */ | |||
1818 | ||||
1819 | bfd_boolean | |||
1820 | bfd_coff_get_auxent (bfd *abfd, | |||
1821 | asymbol *symbol, | |||
1822 | int indx, | |||
1823 | union internal_auxent *pauxent) | |||
1824 | { | |||
1825 | coff_symbol_type *csym; | |||
1826 | combined_entry_type *ent; | |||
1827 | ||||
1828 | csym = coff_symbol_from (abfd, symbol); | |||
1829 | ||||
1830 | if (csym == NULL((void*)0) | |||
1831 | || csym->native == NULL((void*)0) | |||
1832 | || indx >= csym->native->u.syment.n_numaux) | |||
1833 | { | |||
1834 | bfd_set_error (bfd_error_invalid_operation); | |||
1835 | return FALSE0; | |||
1836 | } | |||
1837 | ||||
1838 | ent = csym->native + indx + 1; | |||
1839 | ||||
1840 | *pauxent = ent->u.auxent; | |||
1841 | ||||
1842 | if (ent->fix_tag) | |||
1843 | pauxent->x_sym.x_tagndx.l = | |||
1844 | ((combined_entry_type *) pauxent->x_sym.x_tagndx.p | |||
1845 | - obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments)); | |||
1846 | ||||
1847 | if (ent->fix_end) | |||
1848 | pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l = | |||
1849 | ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p | |||
1850 | - obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments)); | |||
1851 | ||||
1852 | if (ent->fix_scnlen) | |||
1853 | pauxent->x_csect.x_scnlen.l = | |||
1854 | ((combined_entry_type *) pauxent->x_csect.x_scnlen.p | |||
1855 | - obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments)); | |||
1856 | ||||
1857 | return TRUE1; | |||
1858 | } | |||
1859 | ||||
1860 | /* Print out information about COFF symbol. */ | |||
1861 | ||||
1862 | void | |||
1863 | coff_print_symbol (bfd *abfd, | |||
1864 | void * filep, | |||
1865 | asymbol *symbol, | |||
1866 | bfd_print_symbol_type how) | |||
1867 | { | |||
1868 | FILE * file = (FILE *) filep; | |||
1869 | ||||
1870 | switch (how) | |||
1871 | { | |||
1872 | case bfd_print_symbol_name: | |||
1873 | fprintf (file, "%s", symbol->name); | |||
1874 | break; | |||
1875 | ||||
1876 | case bfd_print_symbol_more: | |||
1877 | fprintf (file, "coff %s %s", | |||
1878 | coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native ? "n" : "g", | |||
1879 | coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->lineno ? "l" : " "); | |||
1880 | break; | |||
1881 | ||||
1882 | case bfd_print_symbol_all: | |||
1883 | if (coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native) | |||
1884 | { | |||
1885 | bfd_vma val; | |||
1886 | unsigned int aux; | |||
1887 | combined_entry_type *combined = coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native; | |||
1888 | combined_entry_type *root = obj_raw_syments (abfd)(((abfd)->tdata.coff_obj_data)->raw_syments); | |||
1889 | struct lineno_cache_entry *l = coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->lineno; | |||
1890 | ||||
1891 | fprintf (file, "[%3ld]", (long) (combined - root)); | |||
1892 | ||||
1893 | if (! combined->fix_value) | |||
1894 | val = (bfd_vma) combined->u.syment.n_value; | |||
1895 | else | |||
1896 | val = combined->u.syment.n_value - (unsigned long) root; | |||
1897 | ||||
1898 | fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x", | |||
1899 | combined->u.syment.n_scnum, | |||
1900 | combined->u.syment.n_flags, | |||
1901 | combined->u.syment.n_type, | |||
1902 | combined->u.syment.n_sclass, | |||
1903 | combined->u.syment.n_numaux); | |||
1904 | fprintf_vma (file, val)fprintf (file, "%016lx", val); | |||
1905 | fprintf (file, " %s", symbol->name); | |||
1906 | ||||
1907 | for (aux = 0; aux < combined->u.syment.n_numaux; aux++) | |||
1908 | { | |||
1909 | combined_entry_type *auxp = combined + aux + 1; | |||
1910 | long tagndx; | |||
1911 | ||||
1912 | if (auxp->fix_tag) | |||
1913 | tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root; | |||
1914 | else | |||
1915 | tagndx = auxp->u.auxent.x_sym.x_tagndx.l; | |||
1916 | ||||
1917 | fprintf (file, "\n"); | |||
1918 | ||||
1919 | if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux)((((bfd_coff_backend_data *) (abfd)->xvec->backend_data )->_bfd_coff_print_aux) (abfd, file, root, combined, auxp, aux))) | |||
1920 | continue; | |||
1921 | ||||
1922 | switch (combined->u.syment.n_sclass) | |||
1923 | { | |||
1924 | case C_FILE103: | |||
1925 | fprintf (file, "File "); | |||
1926 | break; | |||
1927 | ||||
1928 | case C_STAT3: | |||
1929 | if (combined->u.syment.n_type == T_NULL0) | |||
1930 | /* Probably a section symbol ? */ | |||
1931 | { | |||
1932 | fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d", | |||
1933 | (long) auxp->u.auxent.x_scn.x_scnlen, | |||
1934 | auxp->u.auxent.x_scn.x_nreloc, | |||
1935 | auxp->u.auxent.x_scn.x_nlinno); | |||
1936 | if (auxp->u.auxent.x_scn.x_checksum != 0 | |||
1937 | || auxp->u.auxent.x_scn.x_associated != 0 | |||
1938 | || auxp->u.auxent.x_scn.x_comdat != 0) | |||
1939 | fprintf (file, " checksum 0x%lx assoc %d comdat %d", | |||
1940 | auxp->u.auxent.x_scn.x_checksum, | |||
1941 | auxp->u.auxent.x_scn.x_associated, | |||
1942 | auxp->u.auxent.x_scn.x_comdat); | |||
1943 | break; | |||
1944 | } | |||
1945 | /* Otherwise fall through. */ | |||
1946 | case C_EXT2: | |||
1947 | if (ISFCN (combined->u.syment.n_type)(((unsigned long) (combined->u.syment.n_type) & ((abfd )->tdata.coff_obj_data)->local_n_tmask) == ((unsigned long ) (2) << ((abfd)->tdata.coff_obj_data)->local_n_btshft ))) | |||
1948 | { | |||
1949 | long next, llnos; | |||
1950 | ||||
1951 | if (auxp->fix_end) | |||
1952 | next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p | |||
1953 | - root); | |||
1954 | else | |||
1955 | next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l; | |||
1956 | llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr; | |||
1957 | fprintf (file, | |||
1958 | "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld", | |||
1959 | tagndx, auxp->u.auxent.x_sym.x_misc.x_fsize, | |||
1960 | llnos, next); | |||
1961 | break; | |||
1962 | } | |||
1963 | /* Otherwise fall through. */ | |||
1964 | default: | |||
1965 | fprintf (file, "AUX lnno %d size 0x%x tagndx %ld", | |||
1966 | auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno, | |||
1967 | auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size, | |||
1968 | tagndx); | |||
1969 | if (auxp->fix_end) | |||
1970 | fprintf (file, " endndx %ld", | |||
1971 | ((long) | |||
1972 | (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p | |||
1973 | - root))); | |||
1974 | break; | |||
1975 | } | |||
1976 | } | |||
1977 | ||||
1978 | if (l) | |||
1979 | { | |||
1980 | fprintf (file, "\n%s :", l->u.sym->name); | |||
1981 | l++; | |||
1982 | while (l->line_number) | |||
1983 | { | |||
1984 | fprintf (file, "\n%4d : ", l->line_number); | |||
1985 | fprintf_vma (file, l->u.offset + symbol->section->vma)fprintf (file, "%016lx", l->u.offset + symbol->section-> vma); | |||
1986 | l++; | |||
1987 | } | |||
1988 | } | |||
1989 | } | |||
1990 | else | |||
1991 | { | |||
1992 | bfd_print_symbol_vandf (abfd, (void *) file, symbol); | |||
1993 | fprintf (file, " %-5s %s %s %s", | |||
1994 | symbol->section->name, | |||
1995 | coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->native ? "n" : "g", | |||
1996 | coffsymbol (symbol)((coff_symbol_type *)(&((symbol)->the_bfd)))->lineno ? "l" : " ", | |||
1997 | symbol->name); | |||
1998 | } | |||
1999 | } | |||
2000 | } | |||
2001 | ||||
2002 | /* Return whether a symbol name implies a local symbol. In COFF, | |||
2003 | local symbols generally start with ``.L''. Most targets use this | |||
2004 | function for the is_local_label_name entry point, but some may | |||
2005 | override it. */ | |||
2006 | ||||
2007 | bfd_boolean | |||
2008 | _bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED__attribute__ ((__unused__)), | |||
2009 | const char *name) | |||
2010 | { | |||
2011 | return name[0] == '.' && name[1] == 'L'; | |||
2012 | } | |||
2013 | ||||
2014 | /* Provided a BFD, a section and an offset (in bytes, not octets) into the | |||
2015 | section, calculate and return the name of the source file and the line | |||
2016 | nearest to the wanted location. */ | |||
2017 | ||||
2018 | bfd_boolean | |||
2019 | coff_find_nearest_line (bfd *abfd, | |||
2020 | asection *section, | |||
2021 | asymbol **symbols, | |||
2022 | bfd_vma offset, | |||
2023 | const char **filename_ptr, | |||
2024 | const char **functionname_ptr, | |||
2025 | unsigned int *line_ptr) | |||
2026 | { | |||
2027 | bfd_boolean found; | |||
2028 | unsigned int i; | |||
2029 | unsigned int line_base; | |||
2030 | coff_data_type *cof = coff_data (abfd)((abfd)->tdata.coff_obj_data); | |||
2031 | /* Run through the raw syments if available. */ | |||
2032 | combined_entry_type *p; | |||
2033 | combined_entry_type *pend; | |||
2034 | alent *l; | |||
2035 | struct coff_section_tdata *sec_data; | |||
2036 | bfd_size_type amt; | |||
2037 | ||||
2038 | /* Before looking through the symbol table, try to use a .stab | |||
2039 | section to find the information. */ | |||
2040 | if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, | |||
2041 | &found, filename_ptr, | |||
2042 | functionname_ptr, line_ptr, | |||
2043 | &coff_data(abfd)((abfd)->tdata.coff_obj_data)->line_info)) | |||
2044 | return FALSE0; | |||
2045 | ||||
2046 | if (found) | |||
2047 | return TRUE1; | |||
2048 | ||||
2049 | /* Also try examining DWARF2 debugging information. */ | |||
2050 | if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, | |||
2051 | filename_ptr, functionname_ptr, | |||
2052 | line_ptr, 0, | |||
2053 | &coff_data(abfd)((abfd)->tdata.coff_obj_data)->dwarf2_find_line_info)) | |||
2054 | return TRUE1; | |||
2055 | ||||
2056 | *filename_ptr = 0; | |||
2057 | *functionname_ptr = 0; | |||
2058 | *line_ptr = 0; | |||
2059 | ||||
2060 | /* Don't try and find line numbers in a non coff file. */ | |||
2061 | if (!bfd_family_coff (abfd)(((abfd)->xvec->flavour) == bfd_target_coff_flavour || ( (abfd)->xvec->flavour) == bfd_target_xcoff_flavour)) | |||
2062 | return FALSE0; | |||
2063 | ||||
2064 | if (cof == NULL((void*)0)) | |||
2065 | return FALSE0; | |||
2066 | ||||
2067 | /* Find the first C_FILE symbol. */ | |||
2068 | p = cof->raw_syments; | |||
2069 | if (!p) | |||
2070 | return FALSE0; | |||
2071 | ||||
2072 | pend = p + cof->raw_syment_count; | |||
2073 | while (p < pend) | |||
2074 | { | |||
2075 | if (p->u.syment.n_sclass == C_FILE103) | |||
2076 | break; | |||
2077 | p += 1 + p->u.syment.n_numaux; | |||
2078 | } | |||
2079 | ||||
2080 | if (p < pend) | |||
2081 | { | |||
2082 | bfd_vma sec_vma; | |||
2083 | bfd_vma maxdiff; | |||
2084 | ||||
2085 | /* Look through the C_FILE symbols to find the best one. */ | |||
2086 | sec_vma = bfd_get_section_vma (abfd, section)((section)->vma + 0); | |||
2087 | *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; | |||
2088 | maxdiff = (bfd_vma) 0 - (bfd_vma) 1; | |||
2089 | while (1) | |||
2090 | { | |||
2091 | combined_entry_type *p2; | |||
2092 | ||||
2093 | for (p2 = p + 1 + p->u.syment.n_numaux; | |||
2094 | p2 < pend; | |||
2095 | p2 += 1 + p2->u.syment.n_numaux) | |||
2096 | { | |||
2097 | if (p2->u.syment.n_scnum > 0 | |||
2098 | && (section | |||
2099 | == coff_section_from_bfd_index (abfd, | |||
2100 | p2->u.syment.n_scnum))) | |||
2101 | break; | |||
2102 | if (p2->u.syment.n_sclass == C_FILE103) | |||
2103 | { | |||
2104 | p2 = pend; | |||
2105 | break; | |||
2106 | } | |||
2107 | } | |||
2108 | ||||
2109 | /* We use <= MAXDIFF here so that if we get a zero length | |||
2110 | file, we actually use the next file entry. */ | |||
2111 | if (p2 < pend | |||
2112 | && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value | |||
2113 | && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff) | |||
2114 | { | |||
2115 | *filename_ptr = (char *) p->u.syment._n._n_n._n_offset; | |||
2116 | maxdiff = offset + sec_vma - p2->u.syment.n_value; | |||
2117 | } | |||
2118 | ||||
2119 | /* Avoid endless loops on erroneous files by ensuring that | |||
2120 | we always move forward in the file. */ | |||
2121 | if (p >= cof->raw_syments + p->u.syment.n_value) | |||
2122 | break; | |||
2123 | ||||
2124 | p = cof->raw_syments + p->u.syment.n_value; | |||
2125 | if (p > pend || p->u.syment.n_sclass != C_FILE103) | |||
2126 | break; | |||
2127 | } | |||
2128 | } | |||
2129 | ||||
2130 | /* Now wander though the raw linenumbers of the section. */ | |||
2131 | /* If we have been called on this section before, and th. e offset we | |||
2132 | want is further down then we can prime the lookup loop. */ | |||
2133 | sec_data = coff_section_data (abfd, section)((struct coff_section_tdata *) (section)->used_by_bfd); | |||
2134 | if (sec_data != NULL((void*)0) | |||
2135 | && sec_data->i > 0 | |||
2136 | && offset >= sec_data->offset) | |||
2137 | { | |||
2138 | i = sec_data->i; | |||
2139 | *functionname_ptr = sec_data->function; | |||
2140 | line_base = sec_data->line_base; | |||
2141 | } | |||
2142 | else | |||
2143 | { | |||
2144 | i = 0; | |||
2145 | line_base = 0; | |||
2146 | } | |||
2147 | ||||
2148 | if (section->lineno != NULL((void*)0)) | |||
2149 | { | |||
2150 | bfd_vma last_value = 0; | |||
2151 | ||||
2152 | l = §ion->lineno[i]; | |||
2153 | ||||
2154 | for (; i < section->lineno_count; i++) | |||
2155 | { | |||
2156 | if (l->line_number == 0) | |||
2157 | { | |||
2158 | /* Get the symbol this line number points at. */ | |||
2159 | coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym); | |||
2160 | if (coff->symbol.value > offset) | |||
2161 | break; | |||
2162 | *functionname_ptr = coff->symbol.name; | |||
2163 | last_value = coff->symbol.value; | |||
2164 | if (coff->native) | |||
2165 | { | |||
2166 | combined_entry_type *s = coff->native; | |||
2167 | s = s + 1 + s->u.syment.n_numaux; | |||
2168 | ||||
2169 | /* In XCOFF a debugging symbol can follow the | |||
2170 | function symbol. */ | |||
2171 | if (s->u.syment.n_scnum == N_DEBUG((short)-2)) | |||
2172 | s = s + 1 + s->u.syment.n_numaux; | |||
2173 | ||||
2174 | /* S should now point to the .bf of the function. */ | |||
2175 | if (s->u.syment.n_numaux) | |||
2176 | { | |||
2177 | /* The linenumber is stored in the auxent. */ | |||
2178 | union internal_auxent *a = &((s + 1)->u.auxent); | |||
2179 | line_base = a->x_sym.x_misc.x_lnsz.x_lnno; | |||
2180 | *line_ptr = line_base; | |||
2181 | } | |||
2182 | } | |||
2183 | } | |||
2184 | else | |||
2185 | { | |||
2186 | if (l->u.offset > offset) | |||
2187 | break; | |||
2188 | *line_ptr = l->line_number + line_base - 1; | |||
2189 | } | |||
2190 | l++; | |||
2191 | } | |||
2192 | ||||
2193 | /* If we fell off the end of the loop, then assume that this | |||
2194 | symbol has no line number info. Otherwise, symbols with no | |||
2195 | line number info get reported with the line number of the | |||
2196 | last line of the last symbol which does have line number | |||
2197 | info. We use 0x100 as a slop to account for cases where the | |||
2198 | last line has executable code. */ | |||
2199 | if (i >= section->lineno_count | |||
2200 | && last_value != 0 | |||
2201 | && offset - last_value > 0x100) | |||
2202 | { | |||
2203 | *functionname_ptr = NULL((void*)0); | |||
2204 | *line_ptr = 0; | |||
2205 | } | |||
2206 | } | |||
2207 | ||||
2208 | /* Cache the results for the next call. */ | |||
2209 | if (sec_data == NULL((void*)0) && section->owner == abfd) | |||
2210 | { | |||
2211 | amt = sizeof (struct coff_section_tdata); | |||
2212 | section->used_by_bfd = bfd_zalloc (abfd, amt); | |||
2213 | sec_data = (struct coff_section_tdata *) section->used_by_bfd; | |||
2214 | } | |||
2215 | if (sec_data != NULL((void*)0)) | |||
2216 | { | |||
2217 | sec_data->offset = offset; | |||
2218 | sec_data->i = i; | |||
2219 | sec_data->function = *functionname_ptr; | |||
2220 | sec_data->line_base = line_base; | |||
2221 | } | |||
2222 | ||||
2223 | return TRUE1; | |||
2224 | } | |||
2225 | ||||
2226 | bfd_boolean | |||
2227 | coff_find_inliner_info (bfd *abfd, | |||
2228 | const char **filename_ptr, | |||
2229 | const char **functionname_ptr, | |||
2230 | unsigned int *line_ptr) | |||
2231 | { | |||
2232 | bfd_boolean found; | |||
2233 | ||||
2234 | found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr, | |||
2235 | functionname_ptr, line_ptr, | |||
2236 | &coff_data(abfd)((abfd)->tdata.coff_obj_data)->dwarf2_find_line_info); | |||
2237 | return (found); | |||
2238 | } | |||
2239 | ||||
2240 | int | |||
2241 | coff_sizeof_headers (bfd *abfd, bfd_boolean reloc) | |||
2242 | { | |||
2243 | size_t size; | |||
2244 | ||||
2245 | if (! reloc) | |||
2246 | size = bfd_coff_filhsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_filhsz) + bfd_coff_aoutsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_aoutsz); | |||
2247 | else | |||
2248 | size = bfd_coff_filhsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_filhsz); | |||
2249 | ||||
2250 | size += abfd->section_count * bfd_coff_scnhsz (abfd)(((bfd_coff_backend_data *) (abfd)->xvec->backend_data) ->_bfd_scnhsz); | |||
2251 | return size; | |||
2252 | } | |||
2253 | ||||
2254 | /* Change the class of a coff symbol held by BFD. */ | |||
2255 | ||||
2256 | bfd_boolean | |||
2257 | bfd_coff_set_symbol_class (bfd * abfd, | |||
2258 | asymbol * symbol, | |||
2259 | unsigned int class) | |||
2260 | { | |||
2261 | coff_symbol_type * csym; | |||
2262 | ||||
2263 | csym = coff_symbol_from (abfd, symbol); | |||
2264 | if (csym == NULL((void*)0)) | |||
2265 | { | |||
2266 | bfd_set_error (bfd_error_invalid_operation); | |||
2267 | return FALSE0; | |||
2268 | } | |||
2269 | else if (csym->native == NULL((void*)0)) | |||
2270 | { | |||
2271 | /* This is an alien symbol which no native coff backend data. | |||
2272 | We cheat here by creating a fake native entry for it and | |||
2273 | then filling in the class. This code is based on that in | |||
2274 | coff_write_alien_symbol(). */ | |||
2275 | ||||
2276 | combined_entry_type * native; | |||
2277 | bfd_size_type amt = sizeof (* native); | |||
2278 | ||||
2279 | native = bfd_zalloc (abfd, amt); | |||
2280 | if (native == NULL((void*)0)) | |||
2281 | return FALSE0; | |||
2282 | ||||
2283 | native->u.syment.n_type = T_NULL0; | |||
2284 | native->u.syment.n_sclass = class; | |||
2285 | ||||
2286 | if (bfd_is_und_section (symbol->section)((symbol->section) == ((asection *) &bfd_und_section))) | |||
2287 | { | |||
2288 | native->u.syment.n_scnum = N_UNDEF((short)0); | |||
2289 | native->u.syment.n_value = symbol->value; | |||
2290 | } | |||
2291 | else if (bfd_is_com_section (symbol->section)(((symbol->section)->flags & 0x1000) != 0)) | |||
2292 | { | |||
2293 | native->u.syment.n_scnum = N_UNDEF((short)0); | |||
2294 | native->u.syment.n_value = symbol->value; | |||
2295 | } | |||
2296 | else | |||
2297 | { | |||
2298 | native->u.syment.n_scnum = | |||
2299 | symbol->section->output_section->target_index; | |||
2300 | native->u.syment.n_value = (symbol->value | |||
2301 | + symbol->section->output_offset); | |||
2302 | if (! obj_pe (abfd)(((abfd)->tdata.coff_obj_data)->pe)) | |||
2303 | native->u.syment.n_value += symbol->section->output_section->vma; | |||
2304 | ||||
2305 | /* Copy the any flags from the file header into the symbol. | |||
2306 | FIXME: Why? */ | |||
2307 | native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)((& csym->symbol)->the_bfd)->flags; | |||
2308 | } | |||
2309 | ||||
2310 | csym->native = native; | |||
2311 | } | |||
2312 | else | |||
2313 | csym->native->u.syment.n_sclass = class; | |||
2314 | ||||
2315 | return TRUE1; | |||
2316 | } | |||
2317 | ||||
2318 | struct coff_comdat_info * | |||
2319 | bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec) | |||
2320 | { | |||
2321 | if (bfd_get_flavour (abfd)((abfd)->xvec->flavour) == bfd_target_coff_flavour | |||
2322 | && coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd) != NULL((void*)0)) | |||
2323 | return coff_section_data (abfd, sec)((struct coff_section_tdata *) (sec)->used_by_bfd)->comdat; | |||
2324 | else | |||
2325 | return NULL((void*)0); | |||
2326 | } |