X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf.c;h=e424ce8d10eb4662f829aff6c74a609373aa27c7;hb=d1778b88f8d8444f15ecf2dbbbf680c5659efb53;hp=fea846dc66a67de1395568d77558644574311fd1;hpb=dbf481172fcc6a37508e7c1c45da7eb68c1fdf4e;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf.c b/bfd/elf.c index fea846dc66..e424ce8d10 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1,5 +1,6 @@ /* ELF executable support for BFD. - Copyright 1993, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -56,6 +57,10 @@ static INLINE int sym_is_global PARAMS ((bfd *, asymbol *)); static boolean elf_map_symbols PARAMS ((bfd *)); static bfd_size_type get_program_header_size PARAMS ((bfd *)); static boolean elfcore_read_notes PARAMS ((bfd *, bfd_vma, bfd_vma)); +static boolean elf_find_function PARAMS ((bfd *, asection *, + asymbol **, + bfd_vma, const char **, + const char **)); /* Swap version information in and out. The version information is currently size independent. If that ever changes, this code will @@ -345,6 +350,7 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) { asection *newsect; flagword flags; + struct elf_backend_data *bed; if (hdr->bfd_section != NULL) { @@ -380,6 +386,13 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) flags |= SEC_CODE; else if ((flags & SEC_LOAD) != 0) flags |= SEC_DATA; + if ((hdr->sh_flags & SHF_MERGE) != 0) + { + flags |= SEC_MERGE; + newsect->entsize = hdr->sh_entsize; + if ((hdr->sh_flags & SHF_STRINGS) != 0) + flags |= SEC_STRINGS; + } /* The debugging sections appear to be recognized only by name, not any sort of flag. */ @@ -410,6 +423,11 @@ _bfd_elf_make_section_from_shdr (abfd, hdr, name) if (strncmp (name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0) flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD; + bed = get_elf_backend_data (abfd); + if (bed->elf_backend_section_flags) + if (! bed->elf_backend_section_flags (&flags, hdr)) + return false; + if (! bfd_set_section_flags (abfd, newsect, flags)) return false; @@ -540,6 +558,18 @@ bfd_elf_generic_reloc (abfd, return bfd_reloc_continue; } +/* Finish SHF_MERGE section merging. */ + +boolean +_bfd_elf_merge_sections (abfd, info) + bfd *abfd; + struct bfd_link_info *info; +{ + if (elf_hash_table (info)->merge_info) + _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info); + return true; +} + /* Print out the program headers. */ boolean @@ -996,8 +1026,9 @@ _bfd_elf_link_hash_hide_symbol (info, h) struct elf_link_hash_entry *h; { h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; - h->dynindx = -1; h->plt.offset = (bfd_vma) -1; + if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) + h->dynindx = -1; } /* Initialize an ELF linker hash table. */ @@ -1020,6 +1051,7 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc) table->runpath = NULL; table->hgot = NULL; table->stab_info = NULL; + table->merge_info = NULL; table->dynlocal = NULL; return _bfd_link_hash_table_init (&table->root, abfd, newfunc); } @@ -1787,16 +1819,10 @@ elf_fake_sections (abfd, asect, failedptrarg) || this_hdr->sh_info == elf_tdata (abfd)->cverrefs); } else if ((asect->flags & SEC_ALLOC) != 0 - && (asect->flags & SEC_LOAD) != 0) - this_hdr->sh_type = SHT_PROGBITS; - else if ((asect->flags & SEC_ALLOC) != 0 - && ((asect->flags & SEC_LOAD) == 0)) + && ((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)) this_hdr->sh_type = SHT_NOBITS; else - { - /* Who knows? */ - this_hdr->sh_type = SHT_PROGBITS; - } + this_hdr->sh_type = SHT_PROGBITS; if ((asect->flags & SEC_ALLOC) != 0) this_hdr->sh_flags |= SHF_ALLOC; @@ -1804,6 +1830,13 @@ elf_fake_sections (abfd, asect, failedptrarg) this_hdr->sh_flags |= SHF_WRITE; if ((asect->flags & SEC_CODE) != 0) this_hdr->sh_flags |= SHF_EXECINSTR; + if ((asect->flags & SEC_MERGE) != 0) + { + this_hdr->sh_flags |= SHF_MERGE; + this_hdr->sh_entsize = asect->entsize; + if ((asect->flags & SEC_STRINGS) != 0) + this_hdr->sh_flags |= SHF_STRINGS; + } /* Check for processor-specific section types. */ if (bed->elf_backend_fake_sections) @@ -3306,7 +3339,10 @@ prep_headers (abfd) i_ehdrp->e_machine = EM_S370; break; case bfd_arch_i386: - i_ehdrp->e_machine = EM_386; + if (bfd_get_arch_size (abfd) == 64) + i_ehdrp->e_machine = EM_X86_64; + else + i_ehdrp->e_machine = EM_386; break; case bfd_arch_ia64: i_ehdrp->e_machine = EM_IA_64; @@ -3317,6 +3353,9 @@ prep_headers (abfd) case bfd_arch_m68hc12: i_ehdrp->e_machine = EM_68HC12; break; + case bfd_arch_s390: + i_ehdrp->e_machine = EM_S390; + break; case bfd_arch_m68k: i_ehdrp->e_machine = EM_68K; break; @@ -3387,7 +3426,10 @@ prep_headers (abfd) case bfd_arch_cris: i_ehdrp->e_machine = EM_CRIS; break; - /* also note that EM_M32, AT&T WE32100 is unknown to bfd */ + case bfd_arch_openrisc: + i_ehdrp->e_machine = EM_OPENRISC; + break; + /* Also note that EM_M32, AT&T WE32100 is unknown to bfd. */ default: i_ehdrp->e_machine = EM_NONE; } @@ -4352,9 +4394,11 @@ swap_out_syms (abfd, sttp, relocatable_p) flagword flags = syms[idx]->flags; int type; - if (flags & BSF_SECTION_SYM) - /* Section symbols have no names. */ - sym.st_name = 0; + if ((flags & BSF_SECTION_SYM) != 0) + { + /* Section symbols have no name. */ + sym.st_name = 0; + } else { sym.st_name = (unsigned long) _bfd_stringtab_add (stt, @@ -4722,8 +4766,8 @@ _bfd_elf_slurp_version_tables (abfd) { _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem); - if ((iverdefmem.vd_ndx & VERSYM_VERSION) > maxidx) - maxidx = iverdefmem.vd_ndx & VERSYM_VERSION; + if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx) + maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION); everdef = ((Elf_External_Verdef *) ((bfd_byte *) everdef + iverdefmem.vd_next)); @@ -4966,52 +5010,24 @@ _bfd_elf_set_arch_mach (abfd, arch, machine) return bfd_default_set_arch_mach (abfd, arch, machine); } -/* Find the nearest line to a particular section and offset, for error - reporting. */ +/* Find the function to a particular section and offset, + for error reporting. */ -boolean -_bfd_elf_find_nearest_line (abfd, - section, - symbols, - offset, - filename_ptr, - functionname_ptr, - line_ptr) - bfd *abfd; +static boolean +elf_find_function (abfd, section, symbols, offset, + filename_ptr, functionname_ptr) + bfd *abfd ATTRIBUTE_UNUSED; asection *section; asymbol **symbols; bfd_vma offset; CONST char **filename_ptr; CONST char **functionname_ptr; - unsigned int *line_ptr; { - boolean found; const char *filename; asymbol *func; bfd_vma low_func; asymbol **p; - if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr)) - return true; - - if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, - filename_ptr, functionname_ptr, - line_ptr, 0)) - return true; - - if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, - &found, filename_ptr, - functionname_ptr, line_ptr, - &elf_tdata (abfd)->line_info)) - return false; - if (found) - return true; - - if (symbols == NULL) - return false; - filename = NULL; func = NULL; low_func = 0; @@ -5048,8 +5064,70 @@ _bfd_elf_find_nearest_line (abfd, if (func == NULL) return false; - *filename_ptr = filename; - *functionname_ptr = bfd_asymbol_name (func); + if (filename_ptr) + *filename_ptr = filename; + if (functionname_ptr) + *functionname_ptr = bfd_asymbol_name (func); + + return true; +} + +/* Find the nearest line to a particular section and offset, + for error reporting. */ + +boolean +_bfd_elf_find_nearest_line (abfd, section, symbols, offset, + filename_ptr, functionname_ptr, line_ptr) + bfd *abfd; + asection *section; + asymbol **symbols; + bfd_vma offset; + CONST char **filename_ptr; + CONST char **functionname_ptr; + unsigned int *line_ptr; +{ + boolean found; + + if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset, + filename_ptr, functionname_ptr, + line_ptr)) + { + if (!*functionname_ptr) + elf_find_function (abfd, section, symbols, offset, + *filename_ptr ? NULL : filename_ptr, + functionname_ptr); + + return true; + } + + if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset, + filename_ptr, functionname_ptr, + line_ptr, 0, + &elf_tdata (abfd)->dwarf2_find_line_info)) + { + if (!*functionname_ptr) + elf_find_function (abfd, section, symbols, offset, + *filename_ptr ? NULL : filename_ptr, + functionname_ptr); + + return true; + } + + if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, + &found, filename_ptr, + functionname_ptr, line_ptr, + &elf_tdata (abfd)->line_info)) + return false; + if (found) + return true; + + if (symbols == NULL) + return false; + + if (! elf_find_function (abfd, section, symbols, offset, + filename_ptr, functionname_ptr)) + return false; + *line_ptr = 0; return true; } @@ -5559,7 +5637,11 @@ elfcore_grok_pstatus (abfd, note) bfd *abfd; Elf_Internal_Note *note; { - if (note->descsz == sizeof (pstatus_t)) + if (note->descsz == sizeof (pstatus_t) +#if defined (HAVE_PXSTATUS_T) + || note->descsz == sizeof (pxstatus_t) +#endif + ) { pstatus_t pstat; @@ -5597,7 +5679,11 @@ elfcore_grok_lwpstatus (abfd, note) char *name; asection *sect; - if (note->descsz != sizeof (lwpstat)) + if (note->descsz != sizeof (lwpstat) +#if defined (HAVE_LWPXSTATUS_T) + && note->descsz != sizeof (lwpxstatus_t) +#endif + ) return true; memcpy (&lwpstat, note->descdata, sizeof (lwpstat));