From c7e76b5eeacef4d01d6f2b9469bd28ba8a8d3deb Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 7 Jul 1995 21:40:56 +0000 Subject: * coffgen.c (coff_renumber_symbols): Sort defined symbols that are neither BSF_FUNCTION not BSF_NOT_AT_END just before undefined symbols. * coffcode.h (coff_slurp_symbol_table): Set BSF_FUNCTION as well as BSF_NOT_AT_END. PR 5491. --- bfd/coffgen.c | 87 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 29 deletions(-) (limited to 'bfd/coffgen.c') diff --git a/bfd/coffgen.c b/bfd/coffgen.c index bdea220..f5b2cc0 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -88,6 +88,7 @@ make_a_section_from_file (abfd, hdr, target_index) /* s_paddr is presumed to be = to s_vaddr */ return_section->vma = hdr->s_vaddr; + return_section->lma = return_section->vma; return_section->_raw_size = hdr->s_size; return_section->filepos = hdr->s_scnptr; return_section->rel_filepos = hdr->s_relptr; @@ -127,12 +128,37 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) struct internal_filehdr *internal_f; struct internal_aouthdr *internal_a; { + flagword oflags = abfd->flags; + bfd_vma ostart = bfd_get_start_address (abfd); PTR tdata; size_t readsize; /* length of file_info */ unsigned int scnhsz; char *external_sections; - /* Build a play area */ + if (!(internal_f->f_flags & F_RELFLG)) + abfd->flags |= HAS_RELOC; + if ((internal_f->f_flags & F_EXEC)) + abfd->flags |= EXEC_P; + if (!(internal_f->f_flags & F_LNNO)) + abfd->flags |= HAS_LINENO; + if (!(internal_f->f_flags & F_LSYMS)) + abfd->flags |= HAS_LOCALS; + + /* FIXME: How can we set D_PAGED correctly? */ + if ((internal_f->f_flags & F_EXEC) != 0) + abfd->flags |= D_PAGED; + + bfd_get_symcount (abfd) = internal_f->f_nsyms; + if (internal_f->f_nsyms) + abfd->flags |= HAS_SYMS; + + if (internal_a != (struct internal_aouthdr *) NULL) + bfd_get_start_address (abfd) = internal_a->entry; + else + bfd_get_start_address (abfd) = 0; + + /* Set up the tdata area. ECOFF uses its own routine, and overrides + abfd->flags. */ tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a); if (tdata == NULL) return 0; @@ -156,7 +182,8 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) for (i = 0; i < nscns; i++) { struct internal_scnhdr tmp; - bfd_coff_swap_scnhdr_in (abfd, (PTR) (external_sections + i * scnhsz), + bfd_coff_swap_scnhdr_in (abfd, + (PTR) (external_sections + i * scnhsz), (PTR) & tmp); make_a_section_from_file (abfd, &tmp, i + 1); } @@ -167,31 +194,12 @@ coff_real_object_p (abfd, nscns, internal_f, internal_a) if (bfd_coff_set_arch_mach_hook (abfd, (PTR) internal_f) == false) goto fail; - if (!(internal_f->f_flags & F_RELFLG)) - abfd->flags |= HAS_RELOC; - if ((internal_f->f_flags & F_EXEC)) - abfd->flags |= EXEC_P; - if (!(internal_f->f_flags & F_LNNO)) - abfd->flags |= HAS_LINENO; - if (!(internal_f->f_flags & F_LSYMS)) - abfd->flags |= HAS_LOCALS; - - /* FIXME: How can we set D_PAGED correctly? */ - if ((internal_f->f_flags & F_EXEC) != 0) - abfd->flags |= D_PAGED; - - bfd_get_symcount (abfd) = internal_f->f_nsyms; - if (internal_f->f_nsyms) - abfd->flags |= HAS_SYMS; - - 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: bfd_release (abfd, tdata); + abfd->flags = oflags; + bfd_get_start_address (abfd) = ostart; return (const bfd_target *) NULL; } @@ -446,8 +454,9 @@ fixup_symbol_value (coff_symbol_ptr, syment) do that here too. */ boolean -coff_renumber_symbols (bfd_ptr) +coff_renumber_symbols (bfd_ptr, first_undef) bfd *bfd_ptr; + int *first_undef; { unsigned int symbol_count = bfd_get_symcount (bfd_ptr); asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols; @@ -456,9 +465,12 @@ coff_renumber_symbols (bfd_ptr) unsigned int symbol_index; /* COFF demands that undefined symbols come after all other symbols. - Since we don't need to impose this extra knowledge on all our client - programs, deal with that here. Sort the symbol table; just move the - undefined symbols to the end, leaving the rest alone. */ + Since we don't need to impose this extra knowledge on all our + client programs, deal with that here. Sort the symbol table; + just move the undefined symbols to the end, leaving the rest + alone. The O'Reilly book says that defined global symbols come + at the end before the undefined symbols, so we do that here as + well. */ /* @@ Do we have some condition we could test for, so we don't always have to do this? I don't think relocatability is quite right, but I'm not certain. [raeburn:19920508.1711EST] */ @@ -476,8 +488,23 @@ coff_renumber_symbols (bfd_ptr) } bfd_ptr->outsymbols = newsyms; for (i = 0; i < symbol_count; i++) - if (!bfd_is_und_section (symbol_ptr_ptr[i]->section)) + if (!bfd_is_und_section (symbol_ptr_ptr[i]->section) + && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL + | BSF_NOT_AT_END + | BSF_FUNCTION)) + != BSF_GLOBAL)) *newsyms++ = symbol_ptr_ptr[i]; + + for (i = 0; i < symbol_count; i++) + if (!bfd_is_und_section (symbol_ptr_ptr[i]->section) + && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL + | BSF_NOT_AT_END + | BSF_FUNCTION)) + == BSF_GLOBAL)) + *newsyms++ = symbol_ptr_ptr[i]; + + *first_undef = newsyms - bfd_ptr->outsymbols; + for (i = 0; i < symbol_count; i++) if (bfd_is_und_section (symbol_ptr_ptr[i]->section)) *newsyms++ = symbol_ptr_ptr[i]; @@ -488,6 +515,7 @@ coff_renumber_symbols (bfd_ptr) for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) { coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); + symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; if (coff_symbol_ptr && coff_symbol_ptr->native) { combined_entry_type *s = coff_symbol_ptr->native; @@ -516,6 +544,7 @@ coff_renumber_symbols (bfd_ptr) } } obj_conv_table_size (bfd_ptr) = native_index; + return true; } -- cgit v1.1