diff options
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/bfd/elf.c b/bfd/elf.c index 66383e7c0d4..906e13d8796 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1070,6 +1070,7 @@ _bfd_elf_print_private_bfd_data (abfd, farg) case PT_PHDR: pt = "PHDR"; break; case PT_TLS: pt = "TLS"; break; case PT_GNU_EH_FRAME: pt = "EH_FRAME"; break; + case PT_GNU_STACK: pt = "STACK"; break; default: sprintf (buf, "0x%lx", p->p_type); pt = buf; break; } fprintf (f, "%8s off 0x", pt); @@ -2296,6 +2297,9 @@ bfd_section_from_phdr (abfd, hdr, index) return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "eh_frame_hdr"); + case PT_GNU_STACK: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "stack"); + default: /* Check for any processor-specific program segment types. If no handler for them, default to making "segment" sections. */ @@ -3513,6 +3517,21 @@ map_sections_to_segments (abfd) pm = &m->next; } + if (elf_tdata (abfd)->stack_flags) + { + amt = sizeof (struct elf_segment_map); + m = (struct elf_segment_map *) bfd_zalloc (abfd, amt); + if (m == NULL) + goto error_return; + m->next = NULL; + m->p_type = PT_GNU_STACK; + m->p_flags = elf_tdata (abfd)->stack_flags; + m->p_flags_valid = 1; + + *pm = m; + pm = &m->next; + } + free (sections); sections = NULL; @@ -4099,6 +4118,12 @@ get_program_header_size (abfd) ++segs; } + if (elf_tdata (abfd)->stack_flags) + { + /* We need a PT_GNU_STACK segment. */ + ++segs; + } + for (s = abfd->sections; s != NULL; s = s->next) { if ((s->flags & SEC_LOAD) != 0 @@ -7015,18 +7040,30 @@ elfcore_grok_nto_status (abfd, note, tid) char buf[100]; char *name; asection *sect; + short sig; + unsigned flags; /* nto_procfs_status 'pid' field is at offset 0. */ elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata); - /* nto_procfs_status 'tid' field is at offset 4. */ - elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); + /* nto_procfs_status 'tid' field is at offset 4. Pass it back. */ + *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4); + + /* nto_procfs_status 'flags' field is at offset 8. */ + flags = bfd_get_32 (abfd, (bfd_byte *) ddata + 8); /* nto_procfs_status 'what' field is at offset 14. */ - elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, (bfd_byte *) ddata + 14); + if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0) + { + elf_tdata (abfd)->core_signal = sig; + elf_tdata (abfd)->core_lwpid = *tid; + } - /* Pass tid back. */ - *tid = elf_tdata (abfd)->core_lwpid; + /* _DEBUG_FLAG_CURTID (current thread) is 0x80. Some cores + do not come from signals so we make sure we set the current + thread just in case. */ + if (flags & 0x00000080) + elf_tdata (abfd)->core_lwpid = *tid; /* Make a ".qnx_core_status/%d" section. */ sprintf (buf, ".qnx_core_status/%d", *tid); @@ -7075,7 +7112,11 @@ elfcore_grok_nto_gregs (abfd, note, tid) sect->flags = SEC_HAS_CONTENTS; sect->alignment_power = 2; - return elfcore_maybe_make_sect (abfd, ".reg", sect); + /* This is the current thread. */ + if (elf_tdata (abfd)->core_lwpid == tid) + return elfcore_maybe_make_sect (abfd, ".reg", sect); + + return TRUE; } #define BFD_QNT_CORE_INFO 7 |