From d24928c05b015102d55d24e783244751095eefa9 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 20 Aug 1993 22:21:49 +0000 Subject: [PATCH] * elfcode.h (elf_build_phdrs): Unused function deleted. (bfd_shdr_from_section): Ditto. (write_relocs): Don't change section contents for addend. (elf_locate_sh): Return type is now always elf_internal_shdr, since the other types were really aliases for this type anyways. Don't compile this function, since it is static and doesn't appear to be used in this file. (sym_is_global): Return non-zero for weak symbols. Abort if sec ptr is null. (swap_out_syms): Reorder tests so function symbols can be weak. (elf_slurp_symbol_table): Don't use BSF_EXPORT. (elf_slurp_reloca_table): Make RELOC_PROCESSING section smaller by extracting out some common code. Abort if BFD section symbol has null name. (elf_slurp_reloc_table): Translate ELF section symbols into BFD section symbols. Don't read section contents to fill in addend field. * Merged from OSF: Tue Jun 15 14:38:32 1993 Michael Meissner (meissner@osf.org) * libelf.h (struct Elf_Sym_Extra): New structure to contain ELF specific information for a symbol. Put in elf_sym_num, which gives the external symbol number in the elf object file, since local symbols must come before global symbols. (elf_sym_extra): New macro. (elf_symtab_map): Delete, in favor of using Elf_Sym_Extra. * elfcode.h (elf_map_symbols): Use Elf_Sym_Extra to map internal symbol number to external number. Store the address of the Elf_Sym_Extra field for the symbol in the udata field. (elf_write_object_contents): Use Elf_Sym_Extra to map out symbols. Sun Jun 20 16:30:11 1993 Michael Meissner (meissner@osf.org) * elfcode.h (elf_obj_tdata): Add field to count the size of the array of pointers to section symbols. (elf_map_symbols): Bump the max index of the section symbols so that we don't overwrite memory. Store the max index into the elf_obj_tdata field. Sat Jun 19 10:12:27 1993 Michael Meissner (meissner@osf.org) * elfcode.h (elf_obj_tdata): Add pointer to an array of pointers to the section symbols we created. Remove unused field internal_syms. (elf_map_symbols): Fill in array of pointers to section symbols. Only create section symbols for sections that have SEC_ALLOC set, and have non-zero size. (elf_symbol_from_bfd_symbol): If udata is NULL, and this is a section symbol, look up the section in the list of section symbols, and set the udata pointer appropriately. Otherwise, if udata is still NULL, fail an assertion, and use 0, instead of dropping core. --- bfd/ChangeLog | 55 +++++ bfd/elfcode.h | 597 ++++++++++++++------------------------------------ bfd/libelf.h | 16 +- 3 files changed, 237 insertions(+), 431 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0b818d90358..605141afca2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,8 +1,63 @@ Fri Aug 20 15:16:58 1993 Ken Raeburn (raeburn@cambridge.cygnus.com) + * elfcode.h (elf_build_phdrs): Unused function deleted. + (bfd_shdr_from_section): Ditto. + (write_relocs): Don't change section contents for addend. + (elf_locate_sh): Return type is now always elf_internal_shdr, + since the other types were really aliases for this type anyways. + Don't compile this function, since it is static and doesn't appear + to be used in this file. + (sym_is_global): Return non-zero for weak symbols. Abort if + section pointer is null. + (swap_out_syms): Reorder tests so function symbols can be weak. + (elf_slurp_symbol_table): Don't use BSF_EXPORT. + (elf_slurp_reloca_table): Make RELOC_PROCESSING section smaller by + extracting out some common code. Abort if BFD section symbol has + null name. + (elf_slurp_reloc_table): Translate ELF section symbols into BFD + section symbols. Don't read section contents to fill in addend + field. + * elf32-i386.c (elf_howto_table): All partial_inplace fields should be "true". + * Merged from OSF: + + Tue Jun 15 14:38:32 1993 Michael Meissner (meissner@osf.org) + + * libelf.h (struct Elf_Sym_Extra): New structure to contain ELF + specific information for a symbol. Put in elf_sym_num, which + gives the external symbol number in the elf object file, since + local symbols must come before global symbols. + (elf_sym_extra): New macro. + (elf_symtab_map): Delete, in favor of using Elf_Sym_Extra. + * elfcode.h (elf_map_symbols): Use Elf_Sym_Extra to map internal + symbol number to external number. Store the address of the + Elf_Sym_Extra field for the symbol in the udata field. + (elf_write_object_contents): Use Elf_Sym_Extra to map out symbols. + + Sun Jun 20 16:30:11 1993 Michael Meissner (meissner@osf.org) + + * elfcode.h (elf_obj_tdata): Add field to count the size of the + array of pointers to section symbols. + (elf_map_symbols): Bump the max index of the section symbols so + that we don't overwrite memory. Store the max index into the + elf_obj_tdata field. + + Sat Jun 19 10:12:27 1993 Michael Meissner (meissner@osf.org) + + * elfcode.h (elf_obj_tdata): Add pointer to an array of pointers + to the section symbols we created. Remove unused field + internal_syms. + (elf_map_symbols): Fill in array of pointers to section symbols. + Only create section symbols for sections that have SEC_ALLOC set, + and have non-zero size. + (elf_symbol_from_bfd_symbol): If udata is NULL, and this is a + section symbol, look up the section in the list of section + symbols, and set the udata pointer appropriately. Otherwise, if + udata is still NULL, fail an assertion, and use 0, instead of + dropping core. + Fri Aug 20 12:18:05 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com) * config.bfd (mips-*-elfl*, mips-*-elf*): New targets, using diff --git a/bfd/elfcode.h b/bfd/elfcode.h index fb00ae05e23..ee5c4540e11 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -54,7 +54,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ once in 64-bit mode. More of it should be made size-independent and moved into elf.c. -*/ + (3) ELF section symbols are handled rather sloppily now. This should + be cleaned up, and ELF section symbols reconciled with BFD section + symbols. + */ #include #include /* For strrchr and friends */ @@ -776,6 +779,20 @@ DEFUN (elf_file_p, (x_ehdrp), Elf_External_Ehdr * x_ehdrp) && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); } +/* Check to see if the file associated with ABFD matches the target vector + that ABFD points to. + + Note that we may be called several times with the same ABFD, but different + target vectors, most of which will not match. We have to avoid leaving + any side effects in ABFD, or any data it points to (like tdata), if the + file does not match the target vector. + + FIXME: There is memory leak if we are called more than once with the same + ABFD, and that bfd already has tdata allocated, since we allocate more tdata + and the old tdata is orphaned. Since it's in the bfd obstack, there isn't + much we can do about this except possibly rewrite the code. There are + also other bfd_allocs that may be the source of memory leaks as well. */ + bfd_target * DEFUN (elf_object_p, (abfd), bfd * abfd) { @@ -786,14 +803,12 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) int shindex; char *shstrtab; /* Internal copy of section header stringtab */ struct elf_backend_data *ebd; /* Use to get ELF_ARCH stored in xvec */ + struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd); /* Read in the ELF header in external format. */ if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr)) - { - bfd_error = system_call_error; - return NULL; - } + goto got_system_call_error; /* Now check to see if we have a valid ELF file, and one that BFD can make use of. The magic number must match, the address size ('class') @@ -801,46 +816,34 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) section header table (FIXME: See comments re sections at top of this file). */ - if (elf_file_p (&x_ehdr) == false) - { - wrong: - bfd_error = wrong_format; - return NULL; - } - - if (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) - goto wrong; + if ((elf_file_p (&x_ehdr) == false) || + (x_ehdr.e_ident[EI_VERSION] != EV_CURRENT) || + (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)) + goto got_wrong_format_error; - if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS) - goto wrong; - - /* Switch xvec to match the specified byte order. */ + /* Check that file's byte order matches xvec's */ switch (x_ehdr.e_ident[EI_DATA]) { case ELFDATA2MSB: /* Big-endian */ if (!abfd->xvec->header_byteorder_big_p) - goto wrong; + goto got_wrong_format_error; break; case ELFDATA2LSB: /* Little-endian */ if (abfd->xvec->header_byteorder_big_p) - goto wrong; + goto got_wrong_format_error; break; case ELFDATANONE: /* No data encoding specified */ default: /* Unknown data encoding specified */ - goto wrong; + goto got_wrong_format_error; } /* Allocate an instance of the elf_obj_tdata structure and hook it up to - the tdata pointer in the bfd. */ - - if (NULL == (elf_tdata (abfd) = (struct elf_obj_tdata *) - bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)))) - { - bfd_error = no_memory; - return NULL; - } + the tdata pointer in the bfd. FIXME: memory leak, see above. */ - /* FIXME: Any `wrong' exits below here will leak memory (tdata). */ + elf_tdata (abfd) = + (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata)); + if (elf_tdata (abfd) == NULL) + goto got_no_memory_error; /* Now that we know the byte order, swap in the rest of the header */ i_ehdrp = elf_elfheader (abfd); @@ -851,7 +854,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) /* If there is no section header table, we're hosed. */ if (i_ehdrp->e_shoff == 0) - goto wrong; + goto got_wrong_format_error; if (i_ehdrp->e_type == ET_EXEC || i_ehdrp->e_type == ET_DYN) abfd->flags |= EXEC_P; @@ -884,7 +887,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) arch = bfd_arch_sparc; /* end-sanitize-v9 */ if (ebd->arch != arch) - goto wrong; + goto got_wrong_format_error; bfd_default_set_arch_mach (abfd, arch, 0); } @@ -895,29 +898,19 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) header table entry actually matches the size recorded in the file. */ if (i_ehdrp->e_shentsize != sizeof (x_shdr)) - goto wrong; + goto got_wrong_format_error; i_shdrp = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum); elf_elfsections (abfd) = (Elf_Internal_Shdr **) bfd_alloc (abfd, sizeof (i_shdrp) * i_ehdrp->e_shnum); if (!i_shdrp || !elf_elfsections(abfd)) - { - bfd_error = no_memory; - return NULL; - } + goto got_no_memory_error; if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) == -1) - { - bfd_error = system_call_error; - return NULL; - } + goto got_system_call_error; for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++) { - if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) - != sizeof (x_shdr)) - { - bfd_error = system_call_error; - return NULL; - } + if (bfd_read ((PTR) & x_shdr, sizeof x_shdr, 1, abfd) != sizeof (x_shdr)) + goto got_system_call_error; elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex); elf_elfsections(abfd)[shindex] = i_shdrp + shindex; } @@ -955,7 +948,7 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) shstrtab = elf_get_str_section (abfd, i_ehdrp->e_shstrndx); if (!shstrtab) - return NULL; + goto got_wrong_format_error; /* Once all of the section headers have been read and converted, we can start processing them. Note that the first section header is @@ -974,75 +967,30 @@ DEFUN (elf_object_p, (abfd), bfd * abfd) bfd_get_start_address (abfd) = i_ehdrp->e_entry; - return abfd->xvec; + return (abfd->xvec); + + /* If we are going to use goto's to avoid duplicating error setting + and return(NULL) code, then this at least makes it more maintainable. */ + + got_system_call_error: + bfd_error = system_call_error; + goto got_no_match; + got_wrong_format_error: + bfd_error = wrong_format; + goto got_no_match; + got_no_memory_error: + bfd_error = no_memory; + goto got_no_match; + got_no_match: + elf_tdata (abfd) = preserved_tdata; + return (NULL); } /* ELF .o/exec file writing */ -/* Create a new ELF section from a bfd section. */ - -#if 0 /* not used */ -static boolean -DEFUN (bfd_shdr_from_section, (abfd, hdr, shstrtab, indx), - bfd * abfd AND - Elf_Internal_Shdr * hdr AND - struct strtab *shstrtab AND - int indx) -{ - asection *sect; - int ndx; - - sect = abfd->sections; - for (ndx = indx; --ndx;) - { - sect = sect->next; - } - hdr[indx].sh_name = bfd_add_to_strtab (abfd, shstrtab, - bfd_section_name (abfd, sect)); - hdr[indx].sh_addr = sect->vma; - hdr[indx].sh_size = sect->_raw_size; - hdr[indx].sh_addralign = 1 << sect->alignment_power; - hdr[indx].sh_flags = 0; - /* these need to be preserved on */ - hdr[indx].sh_link = 0; - hdr[indx].sh_info = 0; - hdr[indx].sh_entsize = 0; - - hdr[indx].sh_type = 0; - if (sect->flags & SEC_RELOC) - { - int use_rela_p = get_elf_backend_data (abfd)->use_rela_p; - hdr[indx].sh_type = use_rela_p ? SHT_RELA : SHT_REL; - } - - if (sect->flags & SEC_HAS_CONTENTS) - { - hdr[indx].sh_offset = sect->filepos; - hdr[indx].sh_size = sect->_raw_size; - } - if (sect->flags & SEC_ALLOC) - { - hdr[indx].sh_flags |= SHF_ALLOC; - if (sect->flags & SEC_LOAD) - { - /* do something with sh_type ? */ - } - } - if (!(sect->flags & SEC_READONLY)) - hdr[indx].sh_flags |= SHF_WRITE; - - if (sect->flags & SEC_CODE) - hdr[indx].sh_flags |= SHF_EXECINSTR; - - return true; -} -#endif - -/* - Takes a bfd and a symbol, returns a pointer to the elf specific area - of the symbol if there is one. - */ +/* Takes a bfd and a symbol, returns a pointer to the elf specific area + of the symbol if there is one. */ static INLINE elf_symbol_type * DEFUN (elf_symbol_from, (ignore_abfd, symbol), bfd * ignore_abfd AND @@ -1057,13 +1005,10 @@ DEFUN (elf_symbol_from, (ignore_abfd, symbol), return (elf_symbol_type *) symbol; } -/* - Create ELF output from BFD sections. - - Essentially, just create the section header and forget about the program - header for now. +/* Create ELF output from BFD sections. -*/ + Essentially, just create the section header and forget about the program + header for now. */ static void DEFUN (elf_make_sections, (abfd, asect, obj), @@ -1215,11 +1160,6 @@ write_relocs (abfd, sec, xxx) dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type); elf_swap_reloc_out (abfd, &dst_rel, src_rel); - - /* Update the addend -- FIXME add 64 bit support. */ - bfd_put_32 (abfd, ptr->addend, - (unsigned char *) (elf_section_data (sec)->this_hdr.contents) - + dst_rel.r_offset); } } } @@ -1331,6 +1271,7 @@ DEFUN (elf_fake_sections, (abfd, asect, obj), } +#if 0 /* xxxINTERNAL_FUNCTION bfd_elf_locate_sh @@ -1346,11 +1287,11 @@ xxxDESCRIPTION name of a BFD section. */ -static struct elfNAME (internal_shdr) * +static struct elf_internal_shdr * DEFUN (elf_locate_sh, (abfd, strtab, shdrp, name), bfd * abfd AND struct strtab *strtab AND - struct elfNAME (internal_shdr) *shdrp AND + struct elf_internal_shdr *shdrp AND CONST char *name) { Elf_Internal_Shdr *gotit = NULL; @@ -1369,6 +1310,7 @@ DEFUN (elf_locate_sh, (abfd, strtab, shdrp, name), } return gotit; } +#endif /* Map symbol from it's internal number to the external number, moving all local symbols to be at the head of the list. */ @@ -1377,12 +1319,19 @@ static INLINE int sym_is_global (sym) asymbol *sym; { - if (sym->flags & BSF_GLOBAL) + if (sym->flags & (BSF_GLOBAL | BSF_WEAK)) { if (sym->flags & BSF_LOCAL) abort (); return 1; } + if (sym->section == 0) + { + /* Is this valid? */ + abort (); + + return 1; + } if (sym->section == &bfd_und_section) return 1; if (bfd_is_com_section (sym->section)) @@ -1397,12 +1346,14 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd) { int symcount = bfd_get_symcount (abfd); asymbol **syms = bfd_get_outsymbols (abfd); + asymbol **sect_syms; int num_locals = 0; int num_globals = 0; int num_locals2 = 0; int num_globals2 = 0; + int max_index = 0; int num_sections = 0; - int *symtab_map; + Elf_Sym_Extra *sym_extra; int idx; asection *asect; @@ -1411,15 +1362,40 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd) fflush (stderr); #endif - /* Add local symbols for each allocated section + /* Add local symbols for each allocated section. FIXME -- we should only put out symbols for sections that are actually relocated against. */ for (asect = abfd->sections; asect; asect = asect->next) { - if (/*asect->flags & (SEC_LOAD | SEC_DATA | SEC_CODE)*/1) - num_sections++; + if (max_index < asect->index) + max_index = asect->index; } + max_index++; + elf_num_section_syms (abfd) = max_index; + sect_syms = (asymbol **) bfd_zalloc (abfd, max_index * sizeof (asymbol *)); + elf_section_syms (abfd) = sect_syms; + + BFD_ASSERT (sect_syms != 0); + + for (asect = abfd->sections; asect; asect = asect->next) + if ((asect->flags & SEC_ALLOC) && asect->_raw_size > 0) + { + asymbol *sym = bfd_make_empty_symbol (abfd); + sym->the_bfd = abfd; + sym->name = asect->name; + sym->value = asect->vma; + sym->flags = BSF_SECTION_SYM; + sym->section = asect; + sect_syms[asect->index] = sym; + num_sections++; +#ifdef DEBUG + fprintf (stderr, + "creating section symbol, name = %s, value = 0x%.8lx, index = %d, section = 0x%.8lx\n", + asect->name, (long) asect->vma, asect->index, (long) asect); +#endif + } + if (num_sections) { if (syms) @@ -1432,23 +1408,16 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd) for (asect = abfd->sections; asect; asect = asect->next) { - if (/* asect->flags & (SEC_LOAD | SEC_DATA | SEC_CODE) */ 1) - { - asymbol *sym = syms[symcount++] = bfd_make_empty_symbol (abfd); - sym->the_bfd = abfd; - sym->name = asect->name; - sym->value = asect->vma; - sym->flags = BSF_SECTION_SYM; - sym->section = asect; - } + if (sect_syms[asect->index]) + syms[symcount++] = sect_syms[asect->index]; } syms[symcount] = (asymbol *) 0; bfd_set_symtab (abfd, syms, symcount); } - elf_symtab_map (abfd) = symtab_map - = (int *) bfd_alloc (abfd, symcount * sizeof (int *)); + elf_sym_extra (abfd) = sym_extra + = (Elf_Sym_Extra *) bfd_alloc (abfd, symcount * sizeof (Elf_Sym_Extra)); /* Identify and classify all of the symbols. */ for (idx = 0; idx < symcount; idx++) @@ -1463,10 +1432,11 @@ DEFUN (elf_map_symbols, (abfd), bfd * abfd) dummy symbol. */ for (idx = 0; idx < symcount; idx++) { + syms[idx]->udata = (PTR) &sym_extra[idx]; if (!sym_is_global (syms[idx])) - symtab_map[idx] = 1 + num_locals2++; + sym_extra[idx].elf_sym_num = 1 + num_locals2++; else - symtab_map[idx] = 1 + num_locals + num_globals2++; + sym_extra[idx].elf_sym_num = 1 + num_locals + num_globals2++; } elf_num_locals (abfd) = num_locals; @@ -1522,183 +1492,6 @@ DEFUN (elf_write_phdrs, (abfd, i_ehdrp, i_phdrp, phdr_cnt), return true; } -#if 0 -static Elf_Internal_Phdr * -DEFUN (elf_build_phdrs, (abfd, i_ehdrp, i_shdrp, phdr_cnt), - bfd * abfd AND - Elf_Internal_Ehdr * i_ehdrp AND - Elf_Internal_Shdr * i_shdrp AND - Elf32_Half * phdr_cnt) -{ - Elf_Internal_Phdr *phdr_buf; - int idx; - /* NOTES: - 1. The program header table is *not* loaded as part - of the memory image of the program. If this - changes later, the PT_PHDR entry must come first. - 2. there is currently no support for program header - entries of type PT_PHDR, PT_DYNAMIC, PT_INTERP, - or PT_SHLIB. */ - - /* A. Figure out how many program header table entries are needed - 1. PT_LOAD for the text segment - 2. PT_LOAD for the data segment - Then, reserve space for one more pointer. This will be NULL - to indicate the end of the program header table. */ - -#ifdef PHDRS_INCLUDED - *phdr_cnt = 4; -#else - /* XXX right now, execve() expects exactly 3 PT entries on HPPA-OSF. */ - *phdr_cnt = 3; -#endif - - phdr_buf = (Elf_Internal_Phdr *) bfd_xmalloc (((*phdr_cnt) + 1) - * - sizeof (Elf_Internal_Phdr)); - - idx = 0; -#ifdef PHDRS_INCLUDED - /* B. Fill in the PT_PHDR entry. */ - - idx++; -#endif - - /* C. Fill in the PT_LOAD entry for the text segment. */ - - phdr_buf[idx].p_type = PT_LOAD; - - /* get virtual/physical address from .text section */ - phdr_buf[idx].p_vaddr = bfd_get_section_by_name (abfd, ".text")->vma; - phdr_buf[idx].p_paddr = 0; /* XXX */ - - /* Ultimately, we would like the size of the .text load - segment to be the sum of the following sections: - the program header table itself - .interp - .hash - .dynsym - .dynstr - .rela.bss - .rela.plt - .init - .text - .fini - .rodata - But, right now, it will be the sum of the following sections: - .text - .rodata */ - - { - static char *CONST ld_sect_names[] = - {".text", ".rodata", NULL}; - int i; - int ld_size = 0; - - for (i = 0; ld_sect_names[i]; i++) - { - asection *asect = bfd_get_section_by_name (abfd, - ld_sect_names[i]); - - if (asect) - ld_size += bfd_section_size (abfd, asect); - } - phdr_buf[idx].p_filesz = ld_size; - /* XXX: need to fix this */ - phdr_buf[idx].p_memsz = ld_size; - } - phdr_buf[idx].p_flags = PF_R + PF_X; - phdr_buf[idx].p_align = - bfd_get_section_by_name (abfd, ".text")->alignment_power; - - idx++; - - /* D. Fill in the PT_LOAD entry for the data segment. */ - - phdr_buf[idx].p_type = PT_LOAD; - - /* get virtual/physical address from .data section */ - phdr_buf[idx].p_vaddr = bfd_get_section_by_name (abfd, ".data")->vma; - phdr_buf[idx].p_paddr = 0; /* XXX */ - - /* Ultimately, we would like the size of the data load segment - to be the sum of the following sections: - the PT_DYNAMIC program header table entry - .plt - .data - .data1 - .got - .dynamic - But, right now, it will be the sum of the following sections: - .data */ - - { - static char *CONST ld_sect_names[] = - {".data", NULL}; - int i; - int ld_size = 0; - - for (i = 0; ld_sect_names[i]; i++) - { - asection *asect = bfd_get_section_by_name (abfd, - ld_sect_names[i]); - - if (asect) - ld_size += bfd_section_size (abfd, asect); - } - phdr_buf[idx].p_filesz = ld_size; - /* XXX: need to fix this */ - phdr_buf[idx].p_memsz = ld_size; - } - phdr_buf[idx].p_flags = PF_R + PF_W + PF_X; - phdr_buf[idx].p_align - = bfd_get_section_by_name (abfd, ".data")->alignment_power; - - idx++; - - /* E. Fill in the PT_LOAD entry for the bss segment. */ - - phdr_buf[idx].p_type = PT_LOAD; - - /* get virtual/physical address from .data section */ - phdr_buf[idx].p_vaddr = bfd_get_section_by_name (abfd, ".bss")->vma; - phdr_buf[idx].p_paddr = 0; /* XXX */ - - { - static char *CONST ld_sect_names[] = - {".bss", NULL}; - int i; - int ld_size = 0; - - for (i = 0; ld_sect_names[i]; i++) - { - asection *asect = bfd_get_section_by_name (abfd, - ld_sect_names[i]); - - if (asect) - ld_size += bfd_section_size (abfd, asect); - } - phdr_buf[idx].p_filesz = 0; - /* XXX: need to fix this */ - phdr_buf[idx].p_memsz = ld_size; - } - phdr_buf[idx].p_flags = PF_R + PF_W + PF_X; - phdr_buf[idx].p_align - = bfd_get_section_by_name (abfd, ".bss")->alignment_power; - - idx++; - - /* F. Set up the "end of program header table" sentinel. */ - - memset ((char *) (phdr_buf + idx), 0, sizeof (Elf_Internal_Phdr)); - idx++; - - BFD_ASSERT (idx - 1 == *phdr_cnt); - - return phdr_buf; -} -#endif - static const Elf_Internal_Shdr null_shdr; /* Assign all ELF section numbers. The dummy first section is handled here @@ -2287,33 +2080,33 @@ swap_out_syms (abfd) sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE); else if (syms[idx]->section == &bfd_und_section) sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_NOTYPE); - else if (syms[idx]->flags & BSF_WEAK) - sym.st_info = ELF_ST_INFO (STB_WEAK, STT_OBJECT); else if (syms[idx]->flags & BSF_SECTION_SYM) sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); else if (syms[idx]->flags & BSF_FILE) sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - else if (syms[idx]->flags & (BSF_GLOBAL | BSF_EXPORT)) - { - if (syms[idx]->flags & BSF_FUNCTION) - sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_FUNC); - else - sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_OBJECT); - } - else if (syms[idx]->flags & BSF_LOCAL) + else { - if (syms[idx]->flags & BSF_FUNCTION) - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FUNC); - else - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT); + int bind = STB_LOCAL; + int type = STT_OBJECT; + unsigned int flags = syms[idx]->flags; + + if (flags & BSF_LOCAL) + bind = STB_LOCAL; + else if (flags & BSF_WEAK) + bind = STB_WEAK; + else if (flags & BSF_GLOBAL) + bind = STB_GLOBAL; + + if (flags & BSF_FUNCTION) + type = STT_FUNC; + + sym.st_info = ELF_ST_INFO (bind, type); } - else - /* Default to local if flag isn't set at all. */ - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_OBJECT); sym.st_other = 0; elf_swap_symbol_out (abfd, &sym, - outbound_syms + elf_symtab_map (abfd)[idx]); + (outbound_syms + + elf_sym_extra (abfd)[idx].elf_sym_num)); } symtab_hdr->contents = (PTR) outbound_syms; @@ -2537,85 +2330,31 @@ DEFUN (elf_symbol_from_bfd_symbol, (abfd, asym_ptr_ptr), CONST char *name = asym_ptr->name; int idx; int symcount = bfd_get_symcount (abfd); + flagword flags = asym_ptr->flags; asymbol **syms = bfd_get_outsymbols (abfd); - /* FIXME -- there has to be a better way than linear search. */ - for (idx = 0; idx < symcount; idx++) - { - if (syms[idx] == asym_ptr - || (name == syms[idx]->name && name) - || ((asym_ptr->flags & BSF_SECTION_SYM) - && (syms[idx]->flags & BSF_SECTION_SYM) - && asym_ptr->section == syms[idx]->section)) - break; - } - - if (idx >= symcount) + /* When gas creates relocations against local labels, it creates its + own symbol for the section, but does put the symbol into the + symbol chain, so udata is 0. */ + if (asym_ptr->udata == (PTR) 0 + && (flags & BSF_SECTION_SYM) + && asym_ptr->section + && elf_section_syms (abfd)[asym_ptr->section->index]) + asym_ptr->udata = elf_section_syms (abfd)[asym_ptr->section->index]->udata; + + if (asym_ptr->udata) + idx = ((Elf_Sym_Extra *)asym_ptr->udata)->elf_sym_num; + else { - /* badness... */ - fprintf (stderr, "bfd app err: can't find sym `%s' in symtab\n", - name); abort (); } - idx = elf_symtab_map (abfd)[idx]; #if DEBUG & 4 { - flagword flags = asym_ptr->flags; fprintf (stderr, - "elfsym<-bfdsym %.8lx `%s' sec=%s symnum=%d {", - (long) asym_ptr, asym_ptr->name, asym_ptr->section->name, idx); - - if (flags == BSF_NO_FLAGS) - fprintf (stderr, " none"); - - if (flags & BSF_LOCAL) - fprintf (stderr, " local"); - - if (flags & BSF_GLOBAL) - fprintf (stderr, " global"); - - if (flags & BSF_EXPORT) - fprintf (stderr, " export"); - - if (flags & BSF_DEBUGGING) - fprintf (stderr, " debugging"); - - if (flags & BSF_KEEP) - fprintf (stderr, " keep"); - - if (flags & BSF_KEEP_G) - fprintf (stderr, " keep_g"); - - if (flags & BSF_WEAK) - fprintf (stderr, " weak"); - - if (flags & BSF_SECTION_SYM) - fprintf (stderr, " section_sym"); - - if (flags & BSF_OLD_COMMON) - fprintf (stderr, " old_common"); - - if (flags & BSF_NOT_AT_END) - fprintf (stderr, " not_at_end"); - - if (flags & BSF_CONSTRUCTOR) - fprintf (stderr, " constructor"); - - if (flags & BSF_WARNING) - fprintf (stderr, " warning"); - - if (flags & BSF_INDIRECT) - fprintf (stderr, " indirect"); - - if (flags & BSF_FILE) - fprintf (stderr, " file"); - - if (flags & BSF_FUNCTION) - fprintf (stderr, " function"); - - fputs (" }\n", stderr); + "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx %s\n", + (long) asym_ptr, asym_ptr->name, idx, flags, elf_symbol_flags (flags)); fflush (stderr); } #endif @@ -2722,7 +2461,7 @@ DEFUN (elf_slurp_symbol_table, (abfd, symptrs), sym->symbol.flags |= BSF_LOCAL; break; case STB_GLOBAL: - sym->symbol.flags |= (BSF_GLOBAL | BSF_EXPORT); + sym->symbol.flags |= BSF_GLOBAL; break; case STB_WEAK: sym->symbol.flags |= BSF_WEAK; @@ -2743,7 +2482,7 @@ DEFUN (elf_slurp_symbol_table, (abfd, symptrs), } /* Is this a definition of $global$? If so, keep it because it will be - needd if any relocations are performed. */ + needed if any relocations are performed. */ if (!strcmp (sym->symbol.name, "$global$") && sym->symbol.section != &bfd_und_section) { @@ -2853,7 +2592,6 @@ DEFUN (elf_slurp_reloca_table, (abfd, asect, symbols), for (idx = 0; idx < asect->reloc_count; idx++) { -#ifdef RELOC_PROCESSING Elf_Internal_Rela dst; Elf_External_Rela *src; @@ -2861,16 +2599,9 @@ DEFUN (elf_slurp_reloca_table, (abfd, asect, symbols), src = native_relocs + idx; elf_swap_reloca_in (abfd, src, &dst); +#ifdef RELOC_PROCESSING RELOC_PROCESSING (cache_ptr, &dst, symbols, abfd, asect); #else - Elf_Internal_Rela dst; - Elf_External_Rela *src; - - cache_ptr = reloc_cache + idx; - src = native_relocs + idx; - - elf_swap_reloca_in (abfd, src, &dst); - if (asect->flags & SEC_RELOC) { /* relocatable, so the offset is off of the section */ @@ -2889,7 +2620,12 @@ DEFUN (elf_slurp_reloca_table, (abfd, asect, symbols), BFD section symbol. */ asymbol *s = *(cache_ptr->sym_ptr_ptr); if (s->flags & BSF_SECTION_SYM) - cache_ptr->sym_ptr_ptr = s->section->symbol_ptr_ptr; + { + cache_ptr->sym_ptr_ptr = s->section->symbol_ptr_ptr; + s = *cache_ptr->sym_ptr_ptr; + if (s->name == 0 || s->name[0] == 0) + abort (); + } } cache_ptr->addend = dst.r_addend; @@ -3029,17 +2765,22 @@ DEFUN (elf_slurp_reloc_table, (abfd, asect, symbols), cache_ptr->address = dst.r_offset; } /* ELF_R_SYM(dst.r_info) is the symbol table offset... - -1 is to skip the dummy symbol table entry */ + -1 is to skip the dummy symbol table entry */ cache_ptr->sym_ptr_ptr = symbols + ELF_R_SYM (dst.r_info) - 1; + { + /* Is it an ELF section symbol? If so, translate it into a + BFD section symbol. */ + asymbol *s = *(cache_ptr->sym_ptr_ptr); + if (s->flags & BSF_SECTION_SYM) + { + cache_ptr->sym_ptr_ptr = s->section->symbol_ptr_ptr; + s = *cache_ptr->sym_ptr_ptr; + if (s->name == 0 || s->name[0] == 0) + abort (); + } + } BFD_ASSERT (dst.r_offset <= data_max); - if (bfd_seek (abfd, data_off + dst.r_offset, SEEK_SET) != 0 - || bfd_read ((PTR) buf, sizeof (buf), 1, abfd) != sizeof (buf)) - { - bfd_error = system_call_error; - return false; - } - - cache_ptr->addend = (*abfd->xvec->bfd_getx_signed_32) ((bfd_byte *) buf); + cache_ptr->addend = 0; /* Fill in the cache_ptr->howto field from dst.r_type */ { diff --git a/bfd/libelf.h b/bfd/libelf.h index 1f0f1a5078f..f5bc2c88f4a 100644 --- a/bfd/libelf.h +++ b/bfd/libelf.h @@ -98,6 +98,13 @@ struct elf_backend_data PTR global_sym; }; +struct elf_sym_extra +{ + int elf_sym_num; /* sym# after locals/globals are reordered */ +}; + +typedef struct elf_sym_extra Elf_Sym_Extra; + struct bfd_elf_arch_map { enum bfd_architecture bfd_arch; int elf_arch; @@ -139,11 +146,12 @@ struct elf_obj_tdata struct strtab *strtab_ptr; int num_locals; int num_globals; - int *symtab_map; PTR raw_syms; /* Elf_External_Sym* */ Elf_Internal_Sym *internal_syms; PTR symbols; /* elf_symbol_type */ -/* struct strtab *shstrtab;*/ + Elf_Sym_Extra *sym_extra; + asymbol **section_syms; /* STT_SECTION symbols for each section */ + int num_section_syms; /* number of section_syms allocated */ Elf_Internal_Shdr symtab_hdr; Elf_Internal_Shdr shstrtab_hdr; Elf_Internal_Shdr strtab_hdr; @@ -160,7 +168,9 @@ struct elf_obj_tdata #define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) #define elf_num_locals(bfd) (elf_tdata(bfd) -> num_locals) #define elf_num_globals(bfd) (elf_tdata(bfd) -> num_globals) -#define elf_symtab_map(bfd) (elf_tdata(bfd) -> symtab_map) +#define elf_sym_extra(bfd) (elf_tdata(bfd) -> sym_extra) +#define elf_section_syms(bfd) (elf_tdata(bfd) -> section_syms) +#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms) #define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo) #define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus) #define obj_symbols(bfd) ((elf_symbol_type*)(elf_tdata(bfd) -> symbols)) -- 2.30.2