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; |
+} |