CONST char *section_name;
CONST char *name = NULL;
struct elf_backend_data *bed;
+ unsigned char st_other;
section_name = symbol->section ? symbol->section->name : "(*none*)";
}
/* If the st_other field is not zero, print it. */
- if (((elf_symbol_type *) symbol)->internal_elf_sym.st_other != 0)
- fprintf (file, " 0x%02x",
- ((unsigned int)
- ((elf_symbol_type *) symbol)->internal_elf_sym.st_other));
+ st_other = ((elf_symbol_type *) symbol)->internal_elf_sym.st_other;
+
+ switch (st_other)
+ {
+ case 0: break;
+ case STV_INTERNAL: fprintf (file, " .internal"); break;
+ case STV_HIDDEN: fprintf (file, " .hidden"); break;
+ case STV_PROTECTED: fprintf (file, " .protected"); break;
+ default:
+ /* Some other non-defined flags are also present, so print
+ everything hex. */
+ fprintf (file, " 0x%02x", (unsigned int) st_other);
+ }
fprintf (file, " %s", name);
}
#endif /* defined (HAVE_PRSTATUS_T) */
-/* There isn't a consistent prfpregset_t across platforms,
- but it doesn't matter, because we don't have to pick this
- data structure apart. */
+/* Create a pseudosection containing the exact contents of NOTE. This
+ actually creates up to two pseudosections:
+ - For the single-threaded case, a section named NAME, unless
+ such a section already exists.
+ - For the multi-threaded case, a section named "NAME/PID", where
+ PID is elfcore_make_pid (abfd).
+ Both pseudosections have identical contents: the contents of NOTE. */
static boolean
-elfcore_grok_prfpreg (abfd, note)
+elfcore_make_note_pseudosection (abfd, name, note)
bfd* abfd;
+ char *name;
Elf_Internal_Note* note;
{
char buf[100];
- char* name;
+ char *threaded_name;
asection* sect;
- /* Make a ".reg2/999" section. */
+ /* Build the section name. */
- sprintf (buf, ".reg2/%d", elfcore_make_pid (abfd));
- name = bfd_alloc (abfd, strlen (buf) + 1);
- if (name == NULL)
+ sprintf (buf, "%s/%d", name, elfcore_make_pid (abfd));
+ threaded_name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (threaded_name == NULL)
return false;
- strcpy (name, buf);
+ strcpy (threaded_name, buf);
- sect = bfd_make_section (abfd, name);
+ sect = bfd_make_section (abfd, threaded_name);
if (sect == NULL)
return false;
sect->_raw_size = note->descsz;
sect->flags = SEC_HAS_CONTENTS;
sect->alignment_power = 2;
- if (! elfcore_maybe_make_sect (abfd, ".reg2", sect))
+ if (! elfcore_maybe_make_sect (abfd, name, sect))
return false;
return true;
}
+
+/* There isn't a consistent prfpregset_t across platforms,
+ but it doesn't matter, because we don't have to pick this
+ data structure apart. */
+static boolean
+elfcore_grok_prfpreg (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg2", note);
+}
+
+
+/* Linux dumps the Intel SSE regs in a note named "LINUX" with a note
+ type of 5 (NT_PRXFPREG). Just include the whole note's contents
+ literally. */
+static boolean
+elfcore_grok_prxfpreg (abfd, note)
+ bfd* abfd;
+ Elf_Internal_Note* note;
+{
+ return elfcore_make_note_pseudosection (abfd, ".reg-xfp", note);
+}
+
+
#if defined (HAVE_PRPSINFO_T)
# define elfcore_psinfo_t prpsinfo_t
#endif
}
#endif /* defined (HAVE_LWPSTATUS_T) */
+#if defined (HAVE_WIN32_PSTATUS_T)
+static boolean
+elfcore_grok_win32pstatus (abfd, note)
+ bfd * abfd;
+ Elf_Internal_Note * note;
+{
+ char buf[30];
+ char * name;
+ asection * sect;
+ win32_pstatus_t pstatus;
+ if (note->descsz < sizeof (pstatus))
+ return true;
+
+ memcpy (& pstatus, note->descdata, note->descsz);
+
+ switch (pstatus.data_type)
+ {
+ case NOTE_INFO_PROCESS:
+ /* FIXME: need to add ->core_command. */
+ elf_tdata (abfd)->core_signal = pstatus.data.process_info.signal;
+ elf_tdata (abfd)->core_pid = pstatus.data.process_info.pid;
+ break ;
+
+ case NOTE_INFO_THREAD:
+ /* Make a ".reg/999" section. */
+ sprintf (buf, ".reg/%d", pstatus.data.thread_info.tid);
+
+ name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return false;
+
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return false;
+
+ sect->_raw_size = sizeof (pstatus.data.thread_info.thread_context);
+ sect->filepos = note->descpos + offsetof (struct win32_pstatus,
+ data.thread_info.thread_context);
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ if (pstatus.data.thread_info.is_active_thread)
+ if (! elfcore_maybe_make_sect (abfd, ".reg", sect))
+ return false;
+ break;
+
+ case NOTE_INFO_MODULE:
+ /* Make a ".module/xxxxxxxx" section. */
+ sprintf (buf, ".module/%08x" , pstatus.data.module_info.base_address);
+
+ name = bfd_alloc (abfd, strlen (buf) + 1);
+ if (name == NULL)
+ return false;
+
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+
+ if (sect == NULL)
+ return false;
+
+ sect->_raw_size = note->descsz;
+ sect->filepos = note->descpos;
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+ break;
+
+ default:
+ return true;
+ }
+
+ return true;
+}
+#endif /* HAVE_WIN32_PSTATUS_T */
static boolean
elfcore_grok_note (abfd, note)
case NT_FPREGSET: /* FIXME: rename to NT_PRFPREG */
return elfcore_grok_prfpreg (abfd, note);
+#if defined (HAVE_WIN32_PSTATUS_T)
+ case NT_WIN32PSTATUS:
+ return elfcore_grok_win32pstatus (abfd, note);
+#endif
+
+ case NT_PRXFPREG: /* Linux SSE extension */
+ if (note->namesz == 5
+ && ! strcmp (note->namedata, "LINUX"))
+ return elfcore_grok_prxfpreg (abfd, note);
+ else
+ return true;
+
#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
case NT_PRPSINFO:
case NT_PSINFO: