/* Support for the generic parts of COFF, for BFD.
- Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#include "sysdep.h"
#include "libbfd.h"
#include "coff/internal.h"
+#include "seclet.h"
#include "libcoff.h"
static asection bfd_debug_section = { "*DEBUG*" };
return_section->target_index = target_index;
+ /* At least on i386-coff, the line number count for a shared library
+ section must be ignored. */
+ if ((return_section->flags & SEC_SHARED_LIBRARY) != 0)
+ return_section->lineno_count = 0;
+
if (hdr->s_nreloc != 0)
return_section->flags |= SEC_RELOC;
/* FIXME: should this check 'hdr->s_size > 0' */
char *external_sections;
/* Build a play area */
- tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f);
+ tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a);
if (tdata == NULL)
return 0;
if (internal_f->f_nsyms)
abfd->flags |= HAS_SYMS;
- bfd_get_start_address(abfd) = internal_f->f_opthdr ? internal_a->entry : 0;
+ if (internal_a != (struct internal_aouthdr *) NULL)
+ bfd_get_start_address (abfd) = internal_a->entry;
+ else
+ bfd_get_start_address (abfd) = 0;
return abfd->xvec;
fail:
/* Seek past the opt hdr stuff */
bfd_seek(abfd, (file_ptr) (internal_f.f_opthdr + filhsz), SEEK_SET);
- return coff_real_object_p(abfd, nscns, &internal_f, &internal_a);
+ return coff_real_object_p(abfd, nscns, &internal_f,
+ (internal_f.f_opthdr != 0
+ ? &internal_a
+ : (struct internal_aouthdr *) NULL));
}
/* Get the BFD section from a COFF symbol section number. */
/* Set lineno_count for the output sections of a COFF file. */
-void
+int
DEFUN(coff_count_linenumbers,(abfd),
bfd *abfd)
{
unsigned int limit = bfd_get_symcount(abfd);
unsigned int i;
+ int total = 0;
asymbol **p;
- {
- asection *s = abfd->sections->output_section;
- while (s) {
- BFD_ASSERT(s->lineno_count == 0);
- s = s->next;
- }
- }
+ {
+ asection *s = abfd->sections->output_section;
+ while (s) {
+ BFD_ASSERT(s->lineno_count == 0);
+ s = s->next;
+ }
+ }
for (p = abfd->outsymbols, i = 0; i < limit; i++, p++) {
*/
alent *l = q->lineno;
q->symbol.section->output_section->lineno_count++;
+ total ++;
l++;
while (l->line_number) {
+ total ++;
q->symbol.section->output_section->lineno_count++;
l++;
}
}
}
}
+ return total;
}
/* Takes a bfd and a symbol, returns a pointer to the coff specific
{
/* Normalize the symbol flags */
- if (coff_symbol_ptr->symbol.section == &bfd_com_section) {
+ if (bfd_is_com_section (coff_symbol_ptr->symbol.section)) {
/* a common symbol is undefined with a value */
syment->n_scnum = N_UNDEF;
syment->n_value = coff_symbol_ptr->symbol.value;
native->u.syment.n_scnum = N_UNDEF;
native->u.syment.n_value = symbol->value;
}
- else if (symbol->section == &bfd_com_section)
+ else if (bfd_is_com_section (symbol->section))
{
native->u.syment.n_scnum = N_UNDEF;
native->u.syment.n_value = symbol->value;
else {
/* We would normally not write anything here, but we'll write
out 4 so that any stupid coff reader which tries to read
- the string table even when there isn't one won't croak.
- */
-
- uint32e_type size = 4;
- size = size;
- bfd_write((PTR)&size, 1, sizeof(size), abfd);
+ the string table even when there isn't one won't croak. */
+ unsigned int size = 4;
+ bfd_byte buffer[4];
+ bfd_h_put_32 (abfd, size, buffer);
+ bfd_write((PTR) buffer, 1, sizeof (buffer), abfd);
}
}
/* Find all the linenumbers in this section */
while (*q) {
asymbol *p = *q;
- alent *l =
- BFD_SEND(bfd_asymbol_bfd(p), _get_lineno, (bfd_asymbol_bfd(p), p));
- if (l) {
- /* Found a linenumber entry, output */
- struct internal_lineno out;
- memset( (PTR)&out, 0, sizeof(out));
- out.l_lnno = 0;
- out.l_addr.l_symndx = l->u.offset;
- bfd_coff_swap_lineno_out(abfd, &out, buff);
- bfd_write(buff, 1, linesz, abfd);
- l++;
- while (l->line_number) {
- out.l_lnno = l->line_number;
+ if (p->section->output_section == s) {
+ alent *l =
+ BFD_SEND(bfd_asymbol_bfd(p), _get_lineno, (bfd_asymbol_bfd(p), p));
+ if (l) {
+ /* Found a linenumber entry, output */
+ struct internal_lineno out;
+ memset( (PTR)&out, 0, sizeof(out));
+ out.l_lnno = 0;
out.l_addr.l_symndx = l->u.offset;
bfd_coff_swap_lineno_out(abfd, &out, buff);
bfd_write(buff, 1, linesz, abfd);
l++;
+ while (l->line_number) {
+ out.l_lnno = l->line_number;
+ out.l_addr.l_symndx = l->u.offset;
+ bfd_coff_swap_lineno_out(abfd, &out, buff);
+ bfd_write(buff, 1, linesz, abfd);
+ l++;
+ }
}
}
q++;
internal_ptr->fix_tag = 0;
internal_ptr->fix_end = 0;
symbol_ptr = internal_ptr;
-
+
for (i = 0;
i < symbol_ptr->u.syment.n_numaux;
i++)
}
obj_raw_syments(abfd) = internal;
+ obj_raw_syment_count(abfd) = internal_ptr - internal;
return (internal);
} /* coff_get_normalized_symtab() */
return &new->symbol;
}
+/* Make a debugging symbol. */
+
asymbol *
-DEFUN (coff_make_debug_symbol, (abfd, ptr, sz),
- bfd *abfd AND
- PTR ptr AND
- unsigned long sz)
+coff_bfd_make_debug_symbol (abfd, ptr, sz)
+ bfd *abfd;
+ PTR ptr;
+ unsigned long sz;
{
coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
if (new == NULL) {
}
void
-DEFUN(coff_print_symbol,(abfd, filep, symbol, how),
- bfd *abfd AND
- PTR filep AND
- asymbol *symbol AND
- bfd_print_symbol_type how)
+coff_get_symbol_info (abfd, symbol, ret)
+ bfd *abfd;
+ asymbol *symbol;
+ symbol_info *ret;
{
- FILE *file = (FILE *)filep;
- switch (how) {
- case bfd_print_symbol_name:
- fprintf(file, "%s", symbol->name);
- break;
- case bfd_print_symbol_more:
- fprintf(file, "coff %lx %lx", (unsigned long) coffsymbol(symbol)->native,
- (unsigned long) coffsymbol(symbol)->lineno);
- break;
- case bfd_print_symbol_nm:
-
- {
- CONST char *section_name = symbol->section->name;
- bfd_print_symbol_vandf((PTR) file, symbol);
+ bfd_symbol_info (symbol, ret);
+}
-
- fprintf(file, " %-5s %s %s %s",
- section_name,
- coffsymbol(symbol)->native ? "n" : "g",
- coffsymbol(symbol)->lineno ? "l" : " ",
- symbol->name);
- }
+/* Print out information about COFF symbol. */
+void
+coff_print_symbol (abfd, filep, symbol, how)
+ bfd *abfd;
+ PTR filep;
+ asymbol *symbol;
+ bfd_print_symbol_type how;
+{
+ FILE *file = (FILE *) filep;
- break;
- case bfd_print_symbol_all:
- /* Print out the symbols in a reasonable way */
+ switch (how)
{
- CONST char *section_name = symbol->section->name;
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ case bfd_print_symbol_more:
+ fprintf (file, "coff %s %s",
+ coffsymbol(symbol)->native ? "n" : "g",
+ coffsymbol(symbol)->lineno ? "l" : " ");
+ break;
+ case bfd_print_symbol_all:
if (coffsymbol(symbol)->native)
- {
- unsigned int aux;
- combined_entry_type *combined = coffsymbol(symbol)->native;
- combined_entry_type *root = obj_raw_syments(abfd);
-
- fprintf(file,"[%3d]",
- combined - root);
-
-
- fprintf(file, "(sc %2d)(fl%4x)(ty%3x)(sc%3d) nx(%d) %08x %s",
- combined->u.syment.n_scnum,
- combined->u.syment.n_flags,
- combined->u.syment.n_type,
- combined->u.syment.n_sclass,
- combined->u.syment.n_numaux,
- combined->u.syment.n_value,
- symbol->name
- );
- for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
{
- fprintf(file,"\n");
- switch (combined->u.syment.n_sclass) {
- case C_FILE:
- fprintf(file, "File ");
- break;
- default:
- fprintf(file, "AUX lnno %x size %x tagndx %x",
- combined[aux+1].u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
- combined[aux+1].u.auxent.x_sym.x_misc.x_lnsz.x_size,
- combined[aux+1].u.auxent.x_sym.x_tagndx.l);
- break;
-
+ unsigned int aux;
+ combined_entry_type *combined = coffsymbol (symbol)->native;
+ combined_entry_type *root = obj_raw_syments (abfd);
+ struct lineno_cache_entry *l = coffsymbol(symbol)->lineno;
+
+ fprintf (file,"[%3d]", combined - root);
+
+ fprintf (file,
+ "(sc %2d)(fl 0x%02x)(ty %3x)(sc %3d) (nx %d) 0x%08x %s",
+ combined->u.syment.n_scnum,
+ combined->u.syment.n_flags,
+ combined->u.syment.n_type,
+ combined->u.syment.n_sclass,
+ combined->u.syment.n_numaux,
+ combined->u.syment.n_value,
+ symbol->name);
+
+ for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
+ {
+ combined_entry_type *auxp = combined + aux + 1;
+ long tagndx;
+
+ if (auxp->fix_tag)
+ tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
+ else
+ tagndx = auxp->u.auxent.x_sym.x_tagndx.l;
+
+ fprintf (file, "\n");
+ switch (combined->u.syment.n_sclass)
+ {
+ case C_FILE:
+ fprintf (file, "File ");
+ break;
+ default:
+
+ fprintf (file, "AUX lnno %d size 0x%x tagndx %d",
+ auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
+ auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
+ tagndx);
+ break;
+ }
}
-
- }
- {
- struct lineno_cache_entry *l = coffsymbol(symbol)->lineno;
- if (l)
+ if (l)
+ {
+ printf ("\n%s :", l->u.sym->name);
+ l++;
+ while (l->line_number)
+ {
+ printf ("\n%4d : 0x%x",
+ l->line_number,
+ l->u.offset);
+ l++;
+ }
+ }
+ }
+ else
{
- printf("\n%s :", l->u.sym->name);
- l++;
- while (l->line_number)
- {
- printf("\n%4d : %x",
- l->line_number,
- l->u.offset);
- l++;
-
- }
- }
- }
-
-
-
- }
-
- else {
- bfd_print_symbol_vandf((PTR) file, symbol);
- fprintf(file, " %-5s %s %s %s",
- section_name,
- coffsymbol(symbol)->native ? "n" : "g",
- coffsymbol(symbol)->lineno ? "l" : " ",
- symbol->name);
+ bfd_print_symbol_vandf ((PTR) file, symbol);
+ fprintf (file, " %-5s %s %s %s",
+ symbol->section->name,
+ coffsymbol(symbol)->native ? "n" : "g",
+ coffsymbol(symbol)->lineno ? "l" : " ",
+ symbol->name);
}
-
- }
-
}
}
static asection *cache_section;
static bfd_vma cache_offset;
static unsigned int cache_i;
- static alent *cache_l;
+ static CONST char *cache_function;
+ static unsigned int line_base = 0;
unsigned int i = 0;
coff_data_type *cof = coff_data(abfd);
/* Run through the raw syments if available */
combined_entry_type *p;
alent *l;
- unsigned int line_base = 0;
*filename_ptr = 0;
section == cache_section &&
offset >= cache_offset) {
i = cache_i;
- l = cache_l;
+ *functionname_ptr = cache_function;
}
else {
i = 0;
- l = section->lineno;
}
+ l = §ion->lineno[i];
for (; i < section->lineno_count; i++) {
if (l->line_number == 0) {
/* Get the symbol this line number points at */
coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
+ if (coff->symbol.value > offset)
+ break;
*functionname_ptr = coff->symbol.name;
if (coff->native) {
combined_entry_type *s = coff->native;
*/
union internal_auxent *a = &((s + 1)->u.auxent);
line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
+ *line_ptr = line_base;
}
}
}
else {
if (l->u.offset > offset)
break;
- *line_ptr = l->line_number + line_base + 1;
+ *line_ptr = l->line_number + line_base - 1;
}
l++;
}
cache_section = section;
cache_offset = offset;
cache_i = i;
- cache_l = l;
+ cache_function = *functionname_ptr;
return true;
}