cris: Check UNDEFWEAK_NO_DYNAMIC_RELOC
[deliverable/binutils-gdb.git] / gdb / fbsd-tdep.c
index 24a3c20dd60716028afeab23d77d7df4fe6e5739..fa70f7c20beb85db2be31664c6426a08e903989c 100644 (file)
 #include "fbsd-tdep.h"
 
 
+/* FreeBSD kernels 12.0 and later include a copy of the
+   'ptrace_lwpinfo' structure returned by the PT_LWPINFO ptrace
+   operation in an ELF core note (NT_FREEBSD_PTLWPINFO) for each LWP.
+   The constants below define the offset of field members and flags in
+   this structure used by methods in this file.  Note that the
+   'ptrace_lwpinfo' struct in the note is preceded by a 4 byte integer
+   containing the size of the structure.  */
+
+#define        LWPINFO_OFFSET          0x4
+
+/* Offsets in ptrace_lwpinfo.  */
+#define        LWPINFO_PL_FLAGS        0x8
+#define        LWPINFO64_PL_SIGINFO    0x30
+#define        LWPINFO32_PL_SIGINFO    0x2c
+
+/* Flags in pl_flags.  */
+#define        PL_FLAG_SI      0x20    /* siginfo is valid */
+
+/* Sizes of siginfo_t. */
+#define        SIZE64_SIGINFO_T        80
+#define        SIZE32_SIGINFO_T        64
+
 static struct gdbarch_data *fbsd_gdbarch_data_handle;
 
 struct fbsd_gdbarch_data
@@ -75,7 +97,6 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
   static char buf[80];
   struct bfd_section *section;
   bfd_size_type size;
-  char sectionstr[32];
 
   if (ptid_get_lwp (thr->ptid) != 0)
     {
@@ -86,9 +107,9 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
         structure.  Rather than define the full structure here, just
         extract the null-terminated name from the start of the
         note.  */
-      xsnprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld",
-               ptid_get_lwp (thr->ptid));
-      section = bfd_get_section_by_name (core_bfd, sectionstr);
+      thread_section_name section_name (".thrmisc", thr->ptid);
+
+      section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
       if (section != NULL && bfd_section_size (core_bfd, section) > 0)
        {
          /* Truncate the name if it is longer than "buf".  */
@@ -114,6 +135,51 @@ fbsd_core_thread_name (struct gdbarch *gdbarch, struct thread_info *thr)
   return NULL;
 }
 
+/* Implement the "core_xfer_siginfo" gdbarch method.  */
+
+static LONGEST
+fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
+                       ULONGEST offset, ULONGEST len)
+{
+  size_t siginfo_size;
+
+  if (gdbarch_long_bit (gdbarch) == 32)
+    siginfo_size = SIZE32_SIGINFO_T;
+  else
+    siginfo_size = SIZE64_SIGINFO_T;
+  if (offset > siginfo_size)
+    return -1;
+
+  thread_section_name section_name (".note.freebsdcore.lwpinfo", inferior_ptid);
+  asection *section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
+  if (section == NULL)
+    return -1;
+
+  gdb_byte buf[4];
+  if (!bfd_get_section_contents (core_bfd, section, buf,
+                                LWPINFO_OFFSET + LWPINFO_PL_FLAGS, 4))
+    return -1;
+
+  int pl_flags = extract_signed_integer (buf, 4, gdbarch_byte_order (gdbarch));
+  if (!(pl_flags & PL_FLAG_SI))
+    return -1;
+
+  if (offset + len > siginfo_size)
+    len = siginfo_size - offset;
+
+  ULONGEST siginfo_offset;
+  if (gdbarch_long_bit (gdbarch) == 32)
+    siginfo_offset = LWPINFO_OFFSET + LWPINFO32_PL_SIGINFO;
+  else
+    siginfo_offset = LWPINFO_OFFSET + LWPINFO64_PL_SIGINFO;
+
+  if (!bfd_get_section_contents (core_bfd, section, readbuf,
+                                siginfo_offset + offset, len))
+    return -1;
+
+  return len;
+}
+
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
@@ -326,6 +392,8 @@ fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
       TAG (PAGESIZESLEN, _("Number of pagesizes"), AUXV_FORMAT_DEC);
       TAG (TIMEKEEP, _("Pointer to timehands"), AUXV_FORMAT_HEX);
       TAG (STACKPROT, _("Initial stack protection"), AUXV_FORMAT_HEX);
+      TAG (EHDRFLAGS, _("ELF header e_flags"), AUXV_FORMAT_HEX);
+      TAG (HWCAP, _("Machine-dependent CPU capability hints"), AUXV_FORMAT_HEX);
     default:
       default_print_auxv_entry (gdbarch, file, type, val);
       return;
@@ -366,13 +434,14 @@ fbsd_get_siginfo_type (struct gdbarch *gdbarch)
 
   /* __pid_t */
   pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
-                       TYPE_LENGTH (int32_type), "__pid_t");
+                       TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT, "__pid_t");
   TYPE_TARGET_TYPE (pid_type) = int32_type;
   TYPE_TARGET_STUB (pid_type) = 1;
 
   /* __uid_t */
   uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF,
-                       TYPE_LENGTH (uint32_type), "__uid_t");
+                       TYPE_LENGTH (uint32_type) * TARGET_CHAR_BIT,
+                       "__uid_t");
   TYPE_TARGET_TYPE (uid_type) = uint32_type;
   TYPE_TARGET_STUB (uid_type) = 1;
 
@@ -448,6 +517,7 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
   set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str);
   set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
+  set_gdbarch_core_xfer_siginfo (gdbarch, fbsd_core_xfer_siginfo);
   set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
   set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry);
   set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type);
@@ -457,9 +527,6 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number);
 }
 
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_fbsd_tdep;
-
 void
 _initialize_fbsd_tdep (void)
 {
This page took 0.024648 seconds and 4 git commands to generate.