Squashed 'third_party/elfutils/' content from commit 555e15e

Change-Id: I61cde98949e47e5c8c09c33260de17f30921be79
git-subtree-dir: third_party/elfutils
git-subtree-split: 555e15ebe8bf1eb33d00747173cfc80cc65648a4
diff --git a/backends/aarch64_corenote.c b/backends/aarch64_corenote.c
new file mode 100644
index 0000000..905a4b8
--- /dev/null
+++ b/backends/aarch64_corenote.c
@@ -0,0 +1,172 @@
+/* AArch64 specific core note handling.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+#define	ULONG			uint64_t
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_ULONG		8
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#define TYPE_ULONG		ELF_T_XWORD
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_WORD
+#define TYPE_GID_T		ELF_T_WORD
+
+#define PRSTATUS_REGS_SIZE	(34 * 8)
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 0, .count = 32, .bits = 64 }, /* x0..x30, sp */
+  };
+
+#define PRSTATUS_REGSET_ITEMS						\
+  {									\
+    .name = "pc", .type = ELF_T_XWORD, .format = 'x',			\
+    .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg)		\
+	       + PRSTATUS_REGS_SIZE - 16),				\
+    .group = "register",						\
+    .pc_register = true							\
+  },									\
+  {									\
+    .name = "pstate", .type = ELF_T_XWORD, .format = 'x',		\
+    .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg)		\
+	       + PRSTATUS_REGS_SIZE - 8),				\
+    .group = "register"							\
+  }
+
+static const Ebl_Register_Location aarch64_fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 64, .count = 32, .bits = 128 }, /* v0..v31 */
+  };
+
+static const Ebl_Core_Item aarch64_fpregset_items[] =
+  {
+    {
+      .name = "fpsr", .type = ELF_T_WORD, .format = 'x',
+      .offset = 512, .group = "register"
+    },
+    {
+      .name = "fpcr", .type = ELF_T_WORD, .format = 'x',
+      .offset = 516, .group = "register"
+    }
+  };
+
+static const Ebl_Core_Item aarch64_tls_items[] =
+  {
+    {
+      .name = "tls", .type = ELF_T_XWORD, .format = 'x',
+      .offset = 0, .group = "register"
+    }
+  };
+
+static const Ebl_Core_Item aarch64_syscall_items [] =
+  {
+    {
+      .name = "syscall", .type = ELF_T_WORD, .format = 'x',
+      .offset = 0, .group = "register"
+    }
+  };
+
+#define AARCH64_HWBP_REG(KIND, N)					\
+    {									\
+      .name = "DBG" KIND "VR" #N "_EL1", .type = ELF_T_XWORD, .format = 'x', \
+      .offset = 8 + N * 16, .group = "register"				\
+    },									\
+    {									\
+      .name = "DBG" KIND "CR" #N "_EL1", .type = ELF_T_WORD, .format = 'x', \
+      .offset = 16 + N * 16, .group = "register"			\
+    }
+
+#define AARCH64_BP_WP_GROUP(KIND, NAME)					\
+  static const Ebl_Core_Item NAME[] =					\
+    {									\
+      {									\
+	.name = "dbg_info", .type = ELF_T_WORD, .format = 'x',		\
+	.offset = 0, .group = "control"					\
+      },								\
+      /* N.B.: 4 bytes of padding here.  */				\
+									\
+      AARCH64_HWBP_REG(KIND, 0),					\
+      AARCH64_HWBP_REG(KIND, 1),					\
+      AARCH64_HWBP_REG(KIND, 2),					\
+      AARCH64_HWBP_REG(KIND, 3),					\
+      AARCH64_HWBP_REG(KIND, 4),					\
+      AARCH64_HWBP_REG(KIND, 5),					\
+      AARCH64_HWBP_REG(KIND, 6),					\
+      AARCH64_HWBP_REG(KIND, 7),					\
+      AARCH64_HWBP_REG(KIND, 8),					\
+      AARCH64_HWBP_REG(KIND, 9),					\
+      AARCH64_HWBP_REG(KIND, 10),					\
+      AARCH64_HWBP_REG(KIND, 11),					\
+      AARCH64_HWBP_REG(KIND, 12),					\
+      AARCH64_HWBP_REG(KIND, 13),					\
+      AARCH64_HWBP_REG(KIND, 14),					\
+      AARCH64_HWBP_REG(KIND, 15),					\
+									\
+      /* The DBGBVR+DBGBCR pair only takes 12 bytes.  There are 4 bytes	\
+	 of padding at the end of each pair.  The item formatter in	\
+	 readelf can skip those, but the missing 4 bytes at the end of	\
+	 the whole block cause it to assume the whole item bunch	\
+	 repeats, so it loops around to read more.  Insert an explicit	\
+	 (but invisible) padding word.  */				\
+      {									\
+	.name = "", .type = ELF_T_WORD, .format = 'h',			\
+	.offset = 260, .group = "register"				\
+      }									\
+    }
+
+AARCH64_BP_WP_GROUP ("B", aarch64_hw_bp_items);
+AARCH64_BP_WP_GROUP ("W", aarch64_hw_wp_items);
+
+#undef AARCH64_BP_WP_GROUP
+#undef AARCH64_HWBP_REG
+
+#define EXTRA_NOTES							\
+  EXTRA_REGSET_ITEMS (NT_FPREGSET, 528,					\
+		      aarch64_fpregset_regs, aarch64_fpregset_items)	\
+  EXTRA_ITEMS (NT_ARM_TLS, 8, aarch64_tls_items)			\
+  EXTRA_ITEMS (NT_ARM_HW_BREAK, 264, aarch64_hw_bp_items)		\
+  EXTRA_ITEMS (NT_ARM_HW_WATCH, 264, aarch64_hw_wp_items)		\
+  EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items)
+
+#include "linux-core-note.c"