| Index: bfd/elf.c
|
| diff --git a/bfd/elf.c b/bfd/elf.c
|
| index f1e4882530d1ffb6944f175b94b90336abad0d2c..48e5d68341354e0d6915c8d9659e5cc6885d71d8 100644
|
| --- a/bfd/elf.c
|
| +++ b/bfd/elf.c
|
| @@ -1,7 +1,7 @@
|
| /* ELF executable support for BFD.
|
|
|
| Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
| - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
| + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
|
| Free Software Foundation, Inc.
|
|
|
| This file is part of BFD, the Binary File Descriptor library.
|
| @@ -1025,7 +1025,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
| else
|
| {
|
| /* Normal section. Check if we should compress. */
|
| - if ((abfd->flags & BFD_COMPRESS))
|
| + if ((abfd->flags & BFD_COMPRESS) && newsect->size != 0)
|
| action = compress;
|
| }
|
|
|
| @@ -1038,7 +1038,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
| if (!bfd_init_section_compress_status (abfd, newsect))
|
| {
|
| (*_bfd_error_handler)
|
| - (_("%B: unable to initialize commpress status for section %s"),
|
| + (_("%B: unable to initialize compress status for section %s"),
|
| abfd, name);
|
| return FALSE;
|
| }
|
| @@ -1058,7 +1058,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
| if (!bfd_init_section_decompress_status (abfd, newsect))
|
| {
|
| (*_bfd_error_handler)
|
| - (_("%B: unable to initialize decommpress status for section %s"),
|
| + (_("%B: unable to initialize decompress status for section %s"),
|
| abfd, name);
|
| return FALSE;
|
| }
|
| @@ -1646,7 +1646,15 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
| if (hdr->sh_entsize != bed->s->sizeof_sym)
|
| return FALSE;
|
| if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
|
| - return FALSE;
|
| + {
|
| + if (hdr->sh_size != 0)
|
| + return FALSE;
|
| + /* Some assemblers erroneously set sh_info to one with a
|
| + zero sh_size. ld sees this as a global symbol count
|
| + of (unsigned) -1. Fix it here. */
|
| + hdr->sh_info = 0;
|
| + return TRUE;
|
| + }
|
| BFD_ASSERT (elf_onesymtab (abfd) == 0);
|
| elf_onesymtab (abfd) = shindex;
|
| elf_tdata (abfd)->symtab_hdr = *hdr;
|
| @@ -1699,6 +1707,16 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
|
|
|
| if (hdr->sh_entsize != bed->s->sizeof_sym)
|
| return FALSE;
|
| + if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
|
| + {
|
| + if (hdr->sh_size != 0)
|
| + return FALSE;
|
| + /* Some linkers erroneously set sh_info to one with a
|
| + zero sh_size. ld sees this as a global symbol count
|
| + of (unsigned) -1. Fix it here. */
|
| + hdr->sh_info = 0;
|
| + return TRUE;
|
| + }
|
| BFD_ASSERT (elf_dynsymtab (abfd) == 0);
|
| elf_dynsymtab (abfd) = shindex;
|
| elf_tdata (abfd)->dynsymtab_hdr = *hdr;
|
| @@ -2527,7 +2545,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd,
|
| rel_hdr = bfd_zalloc (abfd, amt);
|
| reldata->hdr = rel_hdr;
|
|
|
| - amt = sizeof ".rela" + strlen (asect->name);
|
| + amt = sizeof ".rela" + strlen (asect->name);
|
| name = (char *) bfd_alloc (abfd, amt);
|
| if (name == NULL)
|
| return FALSE;
|
| @@ -2996,6 +3014,13 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
|
| _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
|
| }
|
|
|
| + if (section_number >= SHN_LORESERVE)
|
| + {
|
| + _bfd_error_handler (_("%B: too many sections: %u"),
|
| + abfd, section_number);
|
| + return FALSE;
|
| + }
|
| +
|
| _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
|
| t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
|
|
|
| @@ -3071,7 +3096,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
|
| if (link_info != NULL)
|
| {
|
| /* Check discarded linkonce section. */
|
| - if (elf_discarded_section (s))
|
| + if (discarded_section (s))
|
| {
|
| asection *kept;
|
| (*_bfd_error_handler)
|
| @@ -3225,9 +3250,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
|
| return TRUE;
|
| }
|
|
|
| -/* Map symbol from it's internal number to the external number, moving
|
| - all local symbols to be at the head of the list. */
|
| -
|
| static bfd_boolean
|
| sym_is_global (bfd *abfd, asymbol *sym)
|
| {
|
| @@ -3242,7 +3264,7 @@ sym_is_global (bfd *abfd, asymbol *sym)
|
| }
|
|
|
| /* Don't output section symbols for sections that are not going to be
|
| - output. */
|
| + output, or that are duplicates. */
|
|
|
| static bfd_boolean
|
| ignore_section_sym (bfd *abfd, asymbol *sym)
|
| @@ -3250,9 +3272,13 @@ ignore_section_sym (bfd *abfd, asymbol *sym)
|
| return ((sym->flags & BSF_SECTION_SYM) != 0
|
| && !(sym->section->owner == abfd
|
| || (sym->section->output_section->owner == abfd
|
| - && sym->section->output_offset == 0)));
|
| + && sym->section->output_offset == 0)
|
| + || bfd_is_abs_section (sym->section)));
|
| }
|
|
|
| +/* Map symbol from it's internal number to the external number, moving
|
| + all local symbols to be at the head of the list. */
|
| +
|
| static bfd_boolean
|
| elf_map_symbols (bfd *abfd)
|
| {
|
| @@ -3294,7 +3320,8 @@ elf_map_symbols (bfd *abfd)
|
|
|
| if ((sym->flags & BSF_SECTION_SYM) != 0
|
| && sym->value == 0
|
| - && !ignore_section_sym (abfd, sym))
|
| + && !ignore_section_sym (abfd, sym)
|
| + && !bfd_is_abs_section (sym->section))
|
| {
|
| asection *sec = sym->section;
|
|
|
| @@ -3308,12 +3335,10 @@ elf_map_symbols (bfd *abfd)
|
| /* Classify all of the symbols. */
|
| for (idx = 0; idx < symcount; idx++)
|
| {
|
| - if (ignore_section_sym (abfd, syms[idx]))
|
| - continue;
|
| - if (!sym_is_global (abfd, syms[idx]))
|
| - num_locals++;
|
| - else
|
| + if (sym_is_global (abfd, syms[idx]))
|
| num_globals++;
|
| + else if (!ignore_section_sym (abfd, syms[idx]))
|
| + num_locals++;
|
| }
|
|
|
| /* We will be adding a section symbol for each normal BFD section. Most
|
| @@ -3343,12 +3368,12 @@ elf_map_symbols (bfd *abfd)
|
| asymbol *sym = syms[idx];
|
| unsigned int i;
|
|
|
| - if (ignore_section_sym (abfd, sym))
|
| - continue;
|
| - if (!sym_is_global (abfd, sym))
|
| + if (sym_is_global (abfd, sym))
|
| + i = num_locals + num_globals2++;
|
| + else if (!ignore_section_sym (abfd, sym))
|
| i = num_locals2++;
|
| else
|
| - i = num_locals + num_globals2++;
|
| + continue;
|
| new_syms[i] = sym;
|
| sym->udata.i = i + 1;
|
| }
|
| @@ -3744,6 +3769,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
|
| bfd_boolean no_user_phdrs;
|
|
|
| no_user_phdrs = elf_tdata (abfd)->segment_map == NULL;
|
| +
|
| + if (info != NULL)
|
| + info->user_phdrs = !no_user_phdrs;
|
| +
|
| if (no_user_phdrs && bfd_count_sections (abfd) != 0)
|
| {
|
| asection *s;
|
| @@ -4130,18 +4159,25 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
|
| {
|
| for (m = mfirst; m != NULL; m = m->next)
|
| {
|
| - if (m->p_type == PT_LOAD)
|
| + if (m->p_type == PT_LOAD
|
| + && m->count != 0
|
| + && m->sections[0]->vma >= info->relro_start
|
| + && m->sections[0]->vma < info->relro_end)
|
| {
|
| - asection *last = m->sections[m->count - 1];
|
| - bfd_vma vaddr = m->sections[0]->vma;
|
| - bfd_vma filesz = last->vma - vaddr + last->size;
|
| + i = m->count;
|
| + while (--i != (unsigned) -1)
|
| + if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS))
|
| + == (SEC_LOAD | SEC_HAS_CONTENTS))
|
| + break;
|
|
|
| - if (vaddr < info->relro_end
|
| - && vaddr >= info->relro_start
|
| - && (vaddr + filesz) >= info->relro_end)
|
| + if (i == (unsigned) -1)
|
| + continue;
|
| +
|
| + if (m->sections[i]->vma + m->sections[i]->size
|
| + >= info->relro_end)
|
| break;
|
| }
|
| - }
|
| + }
|
|
|
| /* Make a PT_GNU_RELRO segment only when it isn't empty. */
|
| if (m != NULL)
|
| @@ -4351,7 +4387,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
|
| elf_elfheader (abfd)->e_phoff = 0;
|
| elf_elfheader (abfd)->e_phentsize = 0;
|
| }
|
| -
|
| +
|
| elf_elfheader (abfd)->e_phnum = alloc;
|
|
|
| if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1)
|
| @@ -4546,8 +4582,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
|
| p->p_memsz = bed->s->sizeof_ehdr;
|
| if (m->count > 0)
|
| {
|
| - BFD_ASSERT (p->p_type == PT_LOAD);
|
| -
|
| if (p->p_vaddr < (bfd_vma) off)
|
| {
|
| (*_bfd_error_handler)
|
| @@ -4574,7 +4608,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
|
|
|
| if (m->count > 0)
|
| {
|
| - BFD_ASSERT (p->p_type == PT_LOAD);
|
| p->p_vaddr -= off - p->p_offset;
|
| if (!m->p_paddr_valid)
|
| p->p_paddr -= off - p->p_offset;
|
| @@ -4797,6 +4830,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
|
| Elf_Internal_Phdr *phdrs;
|
| Elf_Internal_Phdr *p;
|
| struct elf_segment_map *m;
|
| + struct elf_segment_map *hdrs_segment;
|
| bfd_vma filehdr_vaddr, filehdr_paddr;
|
| bfd_vma phdrs_vaddr, phdrs_paddr;
|
| file_ptr off;
|
| @@ -4820,12 +4854,13 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
|
| BFD_ASSERT (hdr->sh_offset == hdr->bfd_section->filepos);
|
| else if ((hdr->sh_flags & SHF_ALLOC) != 0)
|
| {
|
| - (*_bfd_error_handler)
|
| - (_("%B: warning: allocated section `%s' not in segment"),
|
| - abfd,
|
| - (hdr->bfd_section == NULL
|
| - ? "*unknown*"
|
| - : hdr->bfd_section->name));
|
| + if (hdr->sh_size != 0)
|
| + (*_bfd_error_handler)
|
| + (_("%B: warning: allocated section `%s' not in segment"),
|
| + abfd,
|
| + (hdr->bfd_section == NULL
|
| + ? "*unknown*"
|
| + : hdr->bfd_section->name));
|
| /* We don't need to page align empty sections. */
|
| if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
|
| off += vma_page_aligned_bias (hdr->sh_addr, off,
|
| @@ -4853,6 +4888,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
|
| filehdr_paddr = 0;
|
| phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
|
| phdrs_paddr = 0;
|
| + hdrs_segment = NULL;
|
| phdrs = elf_tdata (abfd)->phdr;
|
| for (m = elf_tdata (abfd)->segment_map, p = phdrs;
|
| m != NULL;
|
| @@ -4873,12 +4909,59 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
|
| phdrs_paddr = p->p_paddr;
|
| if (m->includes_filehdr)
|
| {
|
| + hdrs_segment = m;
|
| phdrs_vaddr += bed->s->sizeof_ehdr;
|
| phdrs_paddr += bed->s->sizeof_ehdr;
|
| }
|
| }
|
| }
|
|
|
| + if (hdrs_segment != NULL && link_info != NULL)
|
| + {
|
| + /* There is a segment that contains both the file headers and the
|
| + program headers, so provide a symbol __ehdr_start pointing there.
|
| + A program can use this to examine itself robustly. */
|
| +
|
| + struct elf_link_hash_entry *hash
|
| + = elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
|
| + FALSE, FALSE, TRUE);
|
| + /* If the symbol was referenced and not defined, define it. */
|
| + if (hash != NULL
|
| + && (hash->root.type == bfd_link_hash_new
|
| + || hash->root.type == bfd_link_hash_undefined
|
| + || hash->root.type == bfd_link_hash_undefweak
|
| + || hash->root.type == bfd_link_hash_common))
|
| + {
|
| + asection *s = NULL;
|
| + if (hdrs_segment->count != 0)
|
| + /* The segment contains sections, so use the first one. */
|
| + s = hdrs_segment->sections[0];
|
| + else
|
| + /* Use the first (i.e. lowest-addressed) section in any segment. */
|
| + for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
|
| + if (m->count != 0)
|
| + {
|
| + s = m->sections[0];
|
| + break;
|
| + }
|
| +
|
| + if (s != NULL)
|
| + {
|
| + hash->root.u.def.value = filehdr_vaddr - s->vma;
|
| + hash->root.u.def.section = s;
|
| + }
|
| + else
|
| + {
|
| + hash->root.u.def.value = filehdr_vaddr;
|
| + hash->root.u.def.section = bfd_abs_section_ptr;
|
| + }
|
| +
|
| + hash->root.type = bfd_link_hash_defined;
|
| + hash->def_regular = 1;
|
| + hash->non_elf = 0;
|
| + }
|
| + }
|
| +
|
| for (m = elf_tdata (abfd)->segment_map, p = phdrs;
|
| m != NULL;
|
| m = m->next, p++)
|
| @@ -4886,21 +4969,27 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
|
| if (p->p_type == PT_GNU_RELRO)
|
| {
|
| const Elf_Internal_Phdr *lp;
|
| -
|
| - BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
|
| + struct elf_segment_map *lm;
|
|
|
| if (link_info != NULL)
|
| {
|
| /* During linking the range of the RELRO segment is passed
|
| in link_info. */
|
| - for (lp = phdrs; lp < phdrs + count; ++lp)
|
| + for (lm = elf_tdata (abfd)->segment_map, lp = phdrs;
|
| + lm != NULL;
|
| + lm = lm->next, lp++)
|
| {
|
| if (lp->p_type == PT_LOAD
|
| - && lp->p_vaddr >= link_info->relro_start
|
| && lp->p_vaddr < link_info->relro_end
|
| - && lp->p_vaddr + lp->p_filesz >= link_info->relro_end)
|
| + && lp->p_vaddr + lp->p_filesz >= link_info->relro_end
|
| + && lm->count != 0
|
| + && lm->sections[0]->vma >= link_info->relro_start)
|
| break;
|
| }
|
| +
|
| + /* PR ld/14207. If the RELRO segment doesn't fit in the
|
| + LOAD segment, it should be removed. */
|
| + BFD_ASSERT (lm != NULL);
|
| }
|
| else
|
| {
|
| @@ -4926,8 +5015,15 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
|
| else
|
| abort ();
|
| p->p_memsz = p->p_filesz;
|
| - p->p_align = 1;
|
| - p->p_flags = (lp->p_flags & ~PF_W);
|
| + /* Preserve the alignment and flags if they are valid. The
|
| + gold linker generates RW/4 for the PT_GNU_RELRO section.
|
| + It is better for objcopy/strip to honor these attributes
|
| + otherwise gdb will choke when using separate debug files.
|
| + */
|
| + if (!m->p_align_valid)
|
| + p->p_align = 1;
|
| + if (!m->p_flags_valid)
|
| + p->p_flags = (lp->p_flags & ~PF_W);
|
| }
|
| else
|
| {
|
| @@ -5427,7 +5523,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
|
| 1. It is within the address space of the segment -- we use the LMA
|
| if that is set for the segment and the VMA otherwise,
|
| 2. It is an allocated section or a NOTE section in a PT_NOTE
|
| - segment.
|
| + segment.
|
| 3. There is an output section associated with it,
|
| 4. The section has not already been allocated to a previous segment.
|
| 5. PT_GNU_STACK segments do not include any sections.
|
| @@ -6147,7 +6243,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
|
| if (map->includes_filehdr && lowest_section != NULL)
|
| /* We need to keep the space used by the headers fixed. */
|
| map->header_size = lowest_section->vma - segment->p_vaddr;
|
| -
|
| +
|
| if (!map->includes_phdrs
|
| && !map->includes_filehdr
|
| && map->p_paddr_valid)
|
| @@ -7378,65 +7474,74 @@ elf_find_function (bfd *abfd,
|
| const char **filename_ptr,
|
| const char **functionname_ptr)
|
| {
|
| - const char *filename;
|
| - asymbol *func, *file;
|
| - bfd_vma low_func;
|
| - asymbol **p;
|
| - /* ??? Given multiple file symbols, it is impossible to reliably
|
| - choose the right file name for global symbols. File symbols are
|
| - local symbols, and thus all file symbols must sort before any
|
| - global symbols. The ELF spec may be interpreted to say that a
|
| - file symbol must sort before other local symbols, but currently
|
| - ld -r doesn't do this. So, for ld -r output, it is possible to
|
| - make a better choice of file name for local symbols by ignoring
|
| - file symbols appearing after a given local symbol. */
|
| - enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
|
| - const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
| + static asection *last_section;
|
| + static asymbol *func;
|
| + static const char *filename;
|
| + static bfd_size_type func_size;
|
|
|
| if (symbols == NULL)
|
| return FALSE;
|
|
|
| - filename = NULL;
|
| - func = NULL;
|
| - file = NULL;
|
| - low_func = 0;
|
| - state = nothing_seen;
|
| -
|
| - for (p = symbols; *p != NULL; p++)
|
| - {
|
| - elf_symbol_type *q;
|
| - unsigned int type;
|
| -
|
| - q = (elf_symbol_type *) *p;
|
| + if (last_section != section
|
| + || func == NULL
|
| + || offset < func->value
|
| + || offset >= func->value + func_size)
|
| + {
|
| + asymbol *file;
|
| + bfd_vma low_func;
|
| + asymbol **p;
|
| + /* ??? Given multiple file symbols, it is impossible to reliably
|
| + choose the right file name for global symbols. File symbols are
|
| + local symbols, and thus all file symbols must sort before any
|
| + global symbols. The ELF spec may be interpreted to say that a
|
| + file symbol must sort before other local symbols, but currently
|
| + ld -r doesn't do this. So, for ld -r output, it is possible to
|
| + make a better choice of file name for local symbols by ignoring
|
| + file symbols appearing after a given local symbol. */
|
| + enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
|
| + const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
| +
|
| + filename = NULL;
|
| + func = NULL;
|
| + file = NULL;
|
| + low_func = 0;
|
| + state = nothing_seen;
|
| + func_size = 0;
|
| + last_section = section;
|
| +
|
| + for (p = symbols; *p != NULL; p++)
|
| + {
|
| + asymbol *sym = *p;
|
| + bfd_vma code_off;
|
| + bfd_size_type size;
|
| +
|
| + if ((sym->flags & BSF_FILE) != 0)
|
| + {
|
| + file = sym;
|
| + if (state == symbol_seen)
|
| + state = file_after_symbol_seen;
|
| + continue;
|
| + }
|
|
|
| - type = ELF_ST_TYPE (q->internal_elf_sym.st_info);
|
| - switch (type)
|
| - {
|
| - case STT_FILE:
|
| - file = &q->symbol;
|
| - if (state == symbol_seen)
|
| - state = file_after_symbol_seen;
|
| - continue;
|
| - default:
|
| - if (!bed->is_function_type (type))
|
| - break;
|
| - case STT_NOTYPE:
|
| - if (bfd_get_section (&q->symbol) == section
|
| - && q->symbol.value >= low_func
|
| - && q->symbol.value <= offset)
|
| + size = bed->maybe_function_sym (sym, section, &code_off);
|
| + if (size != 0
|
| + && code_off <= offset
|
| + && (code_off > low_func
|
| + || (code_off == low_func
|
| + && size > func_size)))
|
| {
|
| - func = (asymbol *) q;
|
| - low_func = q->symbol.value;
|
| + func = sym;
|
| + func_size = size;
|
| + low_func = code_off;
|
| filename = NULL;
|
| if (file != NULL
|
| - && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL
|
| + && ((sym->flags & BSF_LOCAL) != 0
|
| || state != file_after_symbol_seen))
|
| filename = bfd_asymbol_name (file);
|
| }
|
| - break;
|
| + if (state == nothing_seen)
|
| + state = symbol_seen;
|
| }
|
| - if (state == nothing_seen)
|
| - state = symbol_seen;
|
| }
|
|
|
| if (func == NULL)
|
| @@ -7698,11 +7803,12 @@ _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
|
| bfd_boolean
|
| _bfd_elf_close_and_cleanup (bfd *abfd)
|
| {
|
| - if (bfd_get_format (abfd) == bfd_object)
|
| + struct elf_obj_tdata *tdata = elf_tdata (abfd);
|
| + if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
|
| {
|
| - if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL)
|
| + if (elf_shstrtab (abfd) != NULL)
|
| _bfd_elf_strtab_free (elf_shstrtab (abfd));
|
| - _bfd_dwarf2_cleanup_debug_info (abfd);
|
| + _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
|
| }
|
|
|
| return _bfd_generic_close_and_cleanup (abfd);
|
| @@ -8889,7 +8995,6 @@ elfcore_write_note (bfd *abfd,
|
| return buf;
|
| }
|
|
|
| -#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
|
| char *
|
| elfcore_write_prpsinfo (bfd *abfd,
|
| char *buf,
|
| @@ -8897,7 +9002,6 @@ elfcore_write_prpsinfo (bfd *abfd,
|
| const char *fname,
|
| const char *psargs)
|
| {
|
| - const char *note_name = "CORE";
|
| const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
|
|
| if (bed->elf_backend_write_core_note != NULL)
|
| @@ -8909,6 +9013,7 @@ elfcore_write_prpsinfo (bfd *abfd,
|
| return ret;
|
| }
|
|
|
| +#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
|
| #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
|
| if (bed->s->elfclass == ELFCLASS32)
|
| {
|
| @@ -8924,7 +9029,7 @@ elfcore_write_prpsinfo (bfd *abfd,
|
| strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
| strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
| return elfcore_write_note (abfd, buf, bufsiz,
|
| - note_name, note_type, &data, sizeof (data));
|
| + "CORE", note_type, &data, sizeof (data));
|
| }
|
| else
|
| #endif
|
| @@ -8941,12 +9046,14 @@ elfcore_write_prpsinfo (bfd *abfd,
|
| strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
| strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
| return elfcore_write_note (abfd, buf, bufsiz,
|
| - note_name, note_type, &data, sizeof (data));
|
| + "CORE", note_type, &data, sizeof (data));
|
| }
|
| -}
|
| #endif /* PSINFO_T or PRPSINFO_T */
|
|
|
| -#if defined (HAVE_PRSTATUS_T)
|
| + free (buf);
|
| + return NULL;
|
| +}
|
| +
|
| char *
|
| elfcore_write_prstatus (bfd *abfd,
|
| char *buf,
|
| @@ -8955,7 +9062,6 @@ elfcore_write_prstatus (bfd *abfd,
|
| int cursig,
|
| const void *gregs)
|
| {
|
| - const char *note_name = "CORE";
|
| const struct elf_backend_data *bed = get_elf_backend_data (abfd);
|
|
|
| if (bed->elf_backend_write_core_note != NULL)
|
| @@ -8968,6 +9074,7 @@ elfcore_write_prstatus (bfd *abfd,
|
| return ret;
|
| }
|
|
|
| +#if defined (HAVE_PRSTATUS_T)
|
| #if defined (HAVE_PRSTATUS32_T)
|
| if (bed->s->elfclass == ELFCLASS32)
|
| {
|
| @@ -8977,7 +9084,7 @@ elfcore_write_prstatus (bfd *abfd,
|
| prstat.pr_pid = pid;
|
| prstat.pr_cursig = cursig;
|
| memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
| - return elfcore_write_note (abfd, buf, bufsiz, note_name,
|
| + return elfcore_write_note (abfd, buf, bufsiz, "CORE",
|
| NT_PRSTATUS, &prstat, sizeof (prstat));
|
| }
|
| else
|
| @@ -8989,12 +9096,15 @@ elfcore_write_prstatus (bfd *abfd,
|
| prstat.pr_pid = pid;
|
| prstat.pr_cursig = cursig;
|
| memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
|
| - return elfcore_write_note (abfd, buf, bufsiz, note_name,
|
| + return elfcore_write_note (abfd, buf, bufsiz, "CORE",
|
| NT_PRSTATUS, &prstat, sizeof (prstat));
|
| }
|
| -}
|
| #endif /* HAVE_PRSTATUS_T */
|
|
|
| + free (buf);
|
| + return NULL;
|
| +}
|
| +
|
| #if defined (HAVE_LWPSTATUS_T)
|
| char *
|
| elfcore_write_lwpstatus (bfd *abfd,
|
| @@ -9447,7 +9557,7 @@ _bfd_elf_rela_local_sym (bfd *abfd,
|
| + sym->st_value);
|
| if ((sec->flags & SEC_MERGE)
|
| && ELF_ST_TYPE (sym->st_info) == STT_SECTION
|
| - && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
|
| + && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
|
| {
|
| rel->r_addend =
|
| _bfd_merged_section_offset (abfd, psec,
|
| @@ -9478,7 +9588,7 @@ _bfd_elf_rel_local_sym (bfd *abfd,
|
| {
|
| asection *sec = *psec;
|
|
|
| - if (sec->sec_info_type != ELF_INFO_TYPE_MERGE)
|
| + if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
|
| return sym->st_value + addend;
|
|
|
| return _bfd_merged_section_offset (abfd, psec,
|
| @@ -9494,10 +9604,10 @@ _bfd_elf_section_offset (bfd *abfd,
|
| {
|
| switch (sec->sec_info_type)
|
| {
|
| - case ELF_INFO_TYPE_STABS:
|
| + case SEC_INFO_TYPE_STABS:
|
| return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
|
| offset);
|
| - case ELF_INFO_TYPE_EH_FRAME:
|
| + case SEC_INFO_TYPE_EH_FRAME:
|
| return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
|
| default:
|
| if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
|
| @@ -9528,7 +9638,7 @@ bfd_elf_bfd_from_remote_memory
|
| (bfd *templ,
|
| bfd_vma ehdr_vma,
|
| bfd_vma *loadbasep,
|
| - int (*target_read_memory) (bfd_vma, bfd_byte *, int))
|
| + int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
|
| {
|
| return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
|
| (templ, ehdr_vma, loadbasep, target_read_memory);
|
| @@ -9633,7 +9743,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
|
| if (p->addend != 0)
|
| {
|
| char buf[30], *a;
|
| -
|
| +
|
| memcpy (names, "+0x", sizeof ("+0x") - 1);
|
| names += sizeof ("+0x") - 1;
|
| bfd_sprintf_vma (abfd, buf, p->addend);
|
| @@ -9685,3 +9795,27 @@ _bfd_elf_is_function_type (unsigned int type)
|
| return (type == STT_FUNC
|
| || type == STT_GNU_IFUNC);
|
| }
|
| +
|
| +/* If the ELF symbol SYM might be a function in SEC, return the
|
| + function size and set *CODE_OFF to the function's entry point,
|
| + otherwise return zero. */
|
| +
|
| +bfd_size_type
|
| +_bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
|
| + bfd_vma *code_off)
|
| +{
|
| + bfd_size_type size;
|
| +
|
| + if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
|
| + | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
|
| + || sym->section != sec)
|
| + return 0;
|
| +
|
| + *code_off = sym->value;
|
| + size = 0;
|
| + if (!(sym->flags & BSF_SYNTHETIC))
|
| + size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
|
| + if (size == 0)
|
| + size = 1;
|
| + return size;
|
| +}
|
|
|