1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41: #include "sysdep.h"
42: #include "bfd.h"
43: #include "libbfd.h"
44: #include "coff/internal.h"
45: #include "libcoff.h"
46:
47:
48:
49:
50: static bfd_boolean
51: make_a_section_from_file (bfd *abfd,
52: struct internal_scnhdr *hdr,
53: unsigned int target_index)
54: {
55: asection *return_section;
56: char *name;
57: bfd_boolean result = TRUE;
58: flagword flags;
59:
60: name = NULL;
61:
62:
63: if (bfd_coff_long_section_names (abfd)
64: && hdr->s_name[0] == '/')
65: {
66: char buf[SCNNMLEN];
67: long strindex;
68: char *p;
69: const char *strings;
70:
71: memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
72: buf[SCNNMLEN - 1] = '\0';
73: strindex = strtol (buf, &p, 10);
74: if (*p == '\0' && strindex >= 0)
75: {
76: strings = _bfd_coff_read_string_table (abfd);
77: if (strings == NULL)
78: return FALSE;
79:
80:
81:
82: strings += strindex;
83: name = bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1);
84: if (name == NULL)
85: return FALSE;
86: strcpy (name, strings);
87: }
88: }
89:
90: if (name == NULL)
91: {
92:
93: name = bfd_alloc (abfd, (bfd_size_type) sizeof (hdr->s_name) + 1);
94: if (name == NULL)
95: return FALSE;
96: strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
97: name[sizeof (hdr->s_name)] = 0;
98: }
99:
100: return_section = bfd_make_section_anyway (abfd, name);
101: if (return_section == NULL)
102: return FALSE;
103:
104: return_section->vma = hdr->s_vaddr;
105: return_section->lma = hdr->s_paddr;
106: return_section->size = hdr->s_size;
107: return_section->filepos = hdr->s_scnptr;
108: return_section->rel_filepos = hdr->s_relptr;
109: return_section->reloc_count = hdr->s_nreloc;
110:
111: bfd_coff_set_alignment_hook (abfd, return_section, hdr);
112:
113: return_section->line_filepos = hdr->s_lnnoptr;
114:
115: return_section->lineno_count = hdr->s_nlnno;
116: return_section->userdata = NULL;
117: return_section->next = NULL;
118: return_section->target_index = target_index;
119:
120: if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
121: & flags))
122: result = FALSE;
123:
124: return_section->flags = flags;
125:
126:
127:
128: if ((return_section->flags & SEC_COFF_SHARED_LIBRARY) != 0)
129: return_section->lineno_count = 0;
130:
131: if (hdr->s_nreloc != 0)
132: return_section->flags |= SEC_RELOC;
133:
134: if (hdr->s_scnptr != 0)
135: return_section->flags |= SEC_HAS_CONTENTS;
136:
137: return result;
138: }
139:
140:
141:
142:
143: static const bfd_target *
144: coff_real_object_p (bfd *abfd,
145: unsigned nscns,
146: struct internal_filehdr *internal_f,
147: struct internal_aouthdr *internal_a)
148: {
149: flagword oflags = abfd->flags;
150: bfd_vma ostart = bfd_get_start_address (abfd);
151: void * tdata;
152: void * tdata_save;
153: bfd_size_type readsize;
154: unsigned int scnhsz;
155: char *external_sections;
156:
157: if (!(internal_f->f_flags & F_RELFLG))
158: abfd->flags |= HAS_RELOC;
159: if ((internal_f->f_flags & F_EXEC))
160: abfd->flags |= EXEC_P;
161: if (!(internal_f->f_flags & F_LNNO))
162: abfd->flags |= HAS_LINENO;
163: if (!(internal_f->f_flags & F_LSYMS))
164: abfd->flags |= HAS_LOCALS;
165:
166:
167: if ((internal_f->f_flags & F_EXEC) != 0)
168: abfd->flags |= D_PAGED;
169:
170: bfd_get_symcount (abfd) = internal_f->f_nsyms;
171: if (internal_f->f_nsyms)
172: abfd->flags |= HAS_SYMS;
173:
174: if (internal_a != (struct internal_aouthdr *) NULL)
175: bfd_get_start_address (abfd) = internal_a->entry;
176: else
177: bfd_get_start_address (abfd) = 0;
178:
179:
180:
181: tdata_save = abfd->tdata.any;
182: tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a);
183: if (tdata == NULL)
184: goto fail2;
185:
186: scnhsz = bfd_coff_scnhsz (abfd);
187: readsize = (bfd_size_type) nscns * scnhsz;
188: external_sections = bfd_alloc (abfd, readsize);
189: if (!external_sections)
190: goto fail;
191:
192: if (bfd_bread ((void *) external_sections, readsize, abfd) != readsize)
193: goto fail;
194:
195:
196:
197: if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f))
198: goto fail;
199:
200:
201: if (nscns != 0)
202: {
203: unsigned int i;
204: for (i = 0; i < nscns; i++)
205: {
206: struct internal_scnhdr tmp;
207: bfd_coff_swap_scnhdr_in (abfd,
208: (void *) (external_sections + i * scnhsz),
209: (void *) & tmp);
210: if (! make_a_section_from_file (abfd, &tmp, i + 1))
211: goto fail;
212: }
213: }
214:
215: return abfd->xvec;
216:
217: fail:
218: bfd_release (abfd, tdata);
219: fail2:
220: abfd->tdata.any = tdata_save;
221: abfd->flags = oflags;
222: bfd_get_start_address (abfd) = ostart;
223: return (const bfd_target *) NULL;
224: }
225:
226:
227:
228:
229: const bfd_target *
230: coff_object_p (bfd *abfd)
231: {
232: bfd_size_type filhsz;
233: bfd_size_type aoutsz;
234: unsigned int nscns;
235: void * filehdr;
236: struct internal_filehdr internal_f;
237: struct internal_aouthdr internal_a;
238:
239:
240: filhsz = bfd_coff_filhsz (abfd);
241: aoutsz = bfd_coff_aoutsz (abfd);
242:
243: filehdr = bfd_alloc (abfd, filhsz);
244: if (filehdr == NULL)
245: return NULL;
246: if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
247: {
248: if (bfd_get_error () != bfd_error_system_call)
249: bfd_set_error (bfd_error_wrong_format);
250: bfd_release (abfd, filehdr);
251: return NULL;
252: }
253: bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
254: bfd_release (abfd, filehdr);
255:
256:
257:
258:
259:
260:
261:
262:
263:
264: if (! bfd_coff_bad_format_hook (abfd, &internal_f)
265: || internal_f.f_opthdr > aoutsz)
266: {
267: bfd_set_error (bfd_error_wrong_format);
268: return NULL;
269: }
270: nscns = internal_f.f_nscns;
271:
272: if (internal_f.f_opthdr)
273: {
274: void * opthdr;
275:
276: opthdr = bfd_alloc (abfd, aoutsz);
277: if (opthdr == NULL)
278: return NULL;
279: if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
280: != internal_f.f_opthdr)
281: {
282: bfd_release (abfd, opthdr);
283: return NULL;
284: }
285: bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
286: bfd_release (abfd, opthdr);
287: }
288:
289: return coff_real_object_p (abfd, nscns, &internal_f,
290: (internal_f.f_opthdr != 0
291: ? &internal_a
292: : (struct internal_aouthdr *) NULL));
293: }
294:
295:
296:
297: asection *
298: coff_section_from_bfd_index (bfd *abfd, int index)
299: {
300: struct bfd_section *answer = abfd->sections;
301:
302: if (index == N_ABS)
303: return bfd_abs_section_ptr;
304: if (index == N_UNDEF)
305: return bfd_und_section_ptr;
306: if (index == N_DEBUG)
307: return bfd_abs_section_ptr;
308:
309: while (answer)
310: {
311: if (answer->target_index == index)
312: return answer;
313: answer = answer->next;
314: }
315:
316:
317:
318: return bfd_und_section_ptr;
319: }
320:
321:
322:
323: long
324: coff_get_symtab_upper_bound (bfd *abfd)
325: {
326: if (!bfd_coff_slurp_symbol_table (abfd))
327: return -1;
328:
329: return (bfd_get_symcount (abfd) + 1) * (sizeof (coff_symbol_type *));
330: }
331:
332:
333:
334: long
335: coff_canonicalize_symtab (bfd *abfd, asymbol **alocation)
336: {
337: unsigned int counter;
338: coff_symbol_type *symbase;
339: coff_symbol_type **location = (coff_symbol_type **) alocation;
340:
341: if (!bfd_coff_slurp_symbol_table (abfd))
342: return -1;
343:
344: symbase = obj_symbols (abfd);
345: counter = bfd_get_symcount (abfd);
346: while (counter-- > 0)
347: *location++ = symbase++;
348:
349: *location = NULL;
350:
351: return bfd_get_symcount (abfd);
352: }
353:
354:
355:
356:
357: const char *
358: _bfd_coff_internal_syment_name (bfd *abfd,
359: const struct internal_syment *sym,
360: char *buf)
361: {
362:
363:
364: if (sym->_n._n_n._n_zeroes != 0
365: || sym->_n._n_n._n_offset == 0)
366: {
367: memcpy (buf, sym->_n._n_name, SYMNMLEN);
368: buf[SYMNMLEN] = '\0';
369: return buf;
370: }
371: else
372: {
373: const char *strings;
374:
375: BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE);
376: strings = obj_coff_strings (abfd);
377: if (strings == NULL)
378: {
379: strings = _bfd_coff_read_string_table (abfd);
380: if (strings == NULL)
381: return NULL;
382: }
383: return strings + sym->_n._n_n._n_offset;
384: }
385: }
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396: struct internal_reloc *
397: _bfd_coff_read_internal_relocs (bfd *abfd,
398: asection *sec,
399: bfd_boolean cache,
400: bfd_byte *external_relocs,
401: bfd_boolean require_internal,
402: struct internal_reloc *internal_relocs)
403: {
404: bfd_size_type relsz;
405: bfd_byte *free_external = NULL;
406: struct internal_reloc *free_internal = NULL;
407: bfd_byte *erel;
408: bfd_byte *erel_end;
409: struct internal_reloc *irel;
410: bfd_size_type amt;
411:
412: if (sec->reloc_count == 0)
413: return internal_relocs;
414:
415: if (coff_section_data (abfd, sec) != NULL
416: && coff_section_data (abfd, sec)->relocs != NULL)
417: {
418: if (! require_internal)
419: return coff_section_data (abfd, sec)->relocs;
420: memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs,
421: sec->reloc_count * sizeof (struct internal_reloc));
422: return internal_relocs;
423: }
424:
425: relsz = bfd_coff_relsz (abfd);
426:
427: amt = sec->reloc_count * relsz;
428: if (external_relocs == NULL)
429: {
430: free_external = bfd_malloc (amt);
431: if (free_external == NULL)
432: goto error_return;
433: external_relocs = free_external;
434: }
435:
436: if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
437: || bfd_bread (external_relocs, amt, abfd) != amt)
438: goto error_return;
439:
440: if (internal_relocs == NULL)
441: {
442: amt = sec->reloc_count;
443: amt *= sizeof (struct internal_reloc);
444: free_internal = bfd_malloc (amt);
445: if (free_internal == NULL)
446: goto error_return;
447: internal_relocs = free_internal;
448: }
449:
450:
451: erel = external_relocs;
452: erel_end = erel + relsz * sec->reloc_count;
453: irel = internal_relocs;
454: for (; erel < erel_end; erel += relsz, irel++)
455: bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel);
456:
457: if (free_external != NULL)
458: {
459: free (free_external);
460: free_external = NULL;
461: }
462:
463: if (cache && free_internal != NULL)
464: {
465: if (coff_section_data (abfd, sec) == NULL)
466: {
467: amt = sizeof (struct coff_section_tdata);
468: sec->used_by_bfd = bfd_zalloc (abfd, amt);
469: if (sec->used_by_bfd == NULL)
470: goto error_return;
471: coff_section_data (abfd, sec)->contents = NULL;
472: }
473: coff_section_data (abfd, sec)->relocs = free_internal;
474: }
475:
476: return internal_relocs;
477:
478: error_return:
479: if (free_external != NULL)
480: free (free_external);
481: if (free_internal != NULL)
482: free (free_internal);
483: return NULL;
484: }
485:
486:
487:
488: int
489: coff_count_linenumbers (bfd *abfd)
490: {
491: unsigned int limit = bfd_get_symcount (abfd);
492: unsigned int i;
493: int total = 0;
494: asymbol **p;
495: asection *s;
496:
497: if (limit == 0)
498: {
499:
500:
501: for (s = abfd->sections; s != NULL; s = s->next)
502: total += s->lineno_count;
503: return total;
504: }
505:
506: for (s = abfd->sections; s != NULL; s = s->next)
507: BFD_ASSERT (s->lineno_count == 0);
508:
509: for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
510: {
511: asymbol *q_maybe = *p;
512:
513: if (bfd_family_coff (bfd_asymbol_bfd (q_maybe)))
514: {
515: coff_symbol_type *q = coffsymbol (q_maybe);
516:
517:
518:
519:
520: if (q->lineno != NULL
521: && q->symbol.section->owner != NULL)
522: {
523:
524:
525: alent *l = q->lineno;
526:
527: do
528: {
529: asection * sec = q->symbol.section->output_section;
530:
531:
532: if (! bfd_is_const_section (sec))
533: sec->lineno_count ++;
534:
535: ++total;
536: ++l;
537: }
538: while (l->line_number != 0);
539: }
540: }
541: }
542:
543: return total;
544: }
545:
546:
547:
548:
549: coff_symbol_type *
550: coff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED,
551: asymbol *symbol)
552: {
553: if (!bfd_family_coff (bfd_asymbol_bfd (symbol)))
554: return (coff_symbol_type *) NULL;
555:
556: if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL)
557: return (coff_symbol_type *) NULL;
558:
559: return (coff_symbol_type *) symbol;
560: }
561:
562: static void
563: fixup_symbol_value (bfd *abfd,
564: coff_symbol_type *coff_symbol_ptr,
565: struct internal_syment *syment)
566: {
567:
568: if (coff_symbol_ptr->symbol.section
569: && bfd_is_com_section (coff_symbol_ptr->symbol.section))
570: {
571:
572: syment->n_scnum = N_UNDEF;
573: syment->n_value = coff_symbol_ptr->symbol.value;
574: }
575: else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0
576: && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0)
577: {
578: syment->n_value = coff_symbol_ptr->symbol.value;
579: }
580: else if (bfd_is_und_section (coff_symbol_ptr->symbol.section))
581: {
582: syment->n_scnum = N_UNDEF;
583: syment->n_value = 0;
584: }
585:
586: else
587: {
588: if (coff_symbol_ptr->symbol.section)
589: {
590: syment->n_scnum =
591: coff_symbol_ptr->symbol.section->