From 32951ffb0bc0ae18c566c33be1e8f66ab5d28279 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 12 Mar 2015 14:51:42 -0700
Subject: [PATCH 3/3] Add x32_corenote.c

This patch adds x32_corenote.c to support x32 coredump.  X32 coredump is
a hybrid between ia32 coredump and x86-64 coredump.  The exact formats
are described in bfd/hosts/x86-64linux.h in GNU binutils source tree.
---
 backends/Makefile.am       |  2 +-
 backends/linux-core-note.c | 17 ++++++++++++++---
 backends/x32_corenote.c    |  2 ++
 backends/x86_64_corenote.c | 27 ++++++++++++++++++++++++---
 backends/x86_64_init.c     |  7 ++++++-
 5 files changed, 47 insertions(+), 8 deletions(-)
 create mode 100644 backends/x32_corenote.c

diff --git a/backends/Makefile.am b/backends/Makefile.am
index 687c089..21d7bd2 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -58,7 +58,7 @@ am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
 
 x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
 	      x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c \
-	      x86_64_initreg.c
+	      x86_64_initreg.c x32_corenote.c
 cpu_x86_64 = ../libcpu/libcpu_x86_64.a
 libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
 am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
diff --git a/backends/linux-core-note.c b/backends/linux-core-note.c
index e3c0109..08fd09f 100644
--- a/backends/linux-core-note.c
+++ b/backends/linux-core-note.c
@@ -42,9 +42,20 @@
 #define	INT			int32_t
 #define ALIGN_INT		4
 #define TYPE_INT		ELF_T_SWORD
+#ifndef PR_REG
+# define PR_REG			ULONG
+#endif
 #ifndef ALIGN_PR_REG
 # define ALIGN_PR_REG		ALIGN_ULONG
 #endif
+#ifndef PRPSINFO_UID_T
+# define PRPSINFO_UID_T		UID_T
+# define ALIGN_PRPSINFO_UID_T	ALIGN_UID_T
+#endif
+#ifndef PRPSINFO_GID_T
+# define PRPSINFO_GID_T		GID_T
+# define ALIGN_PRPSINFO_GID_T	ALIGN_GID_T
+#endif
 
 #define FIELD(type, name) type name __attribute__ ((aligned (ALIGN_##type)))
 
@@ -86,7 +97,7 @@ struct EBLHOOK(prstatus)
   struct EBLHOOK(timeval) pr_cstime;
   struct
   {
-    FIELD (ULONG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (ULONG)]);
+    FIELD (PR_REG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (PR_REG)]);
   }
 #ifdef ALIGN_PR_REG
     __attribute__ ((aligned (ALIGN_PR_REG)))
@@ -105,8 +116,8 @@ struct EBLHOOK(prpsinfo)
   FIELD (CHAR, pr_zomb);
   FIELD (CHAR, pr_nice);
   FIELD (ULONG, pr_flag);
-  FIELD (UID_T, pr_uid);
-  FIELD (GID_T, pr_gid);
+  FIELD (PRPSINFO_UID_T, pr_uid);
+  FIELD (PRPSINFO_GID_T, pr_gid);
   FIELD (PID_T, pr_pid);
   FIELD (PID_T, pr_ppid);
   FIELD (PID_T, pr_pgrp);
diff --git a/backends/x32_corenote.c b/backends/x32_corenote.c
new file mode 100644
index 0000000..bd6560d
--- /dev/null
+++ b/backends/x32_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 32
+#include "x86_64_corenote.c"
diff --git a/backends/x86_64_corenote.c b/backends/x86_64_corenote.c
index f9d8db4..3fbb0d9 100644
--- a/backends/x86_64_corenote.c
+++ b/backends/x86_64_corenote.c
@@ -36,7 +36,13 @@
 #include <stdio.h>
 #include <sys/time.h>
 
-#define BACKEND		x86_64_
+#ifndef BITS
+# define BITS 		64
+# define BACKEND	x86_64_
+#else
+# define BITS 		32
+# define BACKEND	x32_
+#endif
 #include "libebl_CPU.h"
 
 
@@ -77,11 +83,26 @@ static const Ebl_Register_Location prstatus_regs[] =
   };
 #define PRSTATUS_REGS_SIZE	(27 * 8)
 
-#define	ULONG			uint64_t
+#if BITS == 32
+# define ULONG			uint32_t
+# define ALIGN_ULONG		4
+# define PRPSINFO_UID_T		uint16_t
+# define ALIGN_PRPSINFO_UID_T	2
+# define PRPSINFO_GID_T		uint16_t
+# define ALIGN_PRPSINFO_GID_T	2
+#else
+# define ULONG			uint64_t
+# define ALIGN_ULONG		8
+# define PRPSINFO_UID_T		uint32_t
+# define ALIGN_PRPSINFO_UID_T	4
+# define PRPSINFO_GID_T		uint32_t
+# define ALIGN_PRPSINFO_GID_T	4
+#endif
+#define PR_REG			uint64_t
+#define ALIGN_PR_REG		8
 #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
diff --git a/backends/x86_64_init.c b/backends/x86_64_init.c
index b885558..1197cc0 100644
--- a/backends/x86_64_init.c
+++ b/backends/x86_64_init.c
@@ -38,6 +38,8 @@
 /* This defines the common reloc hooks based on x86_64_reloc.def.  */
 #include "common-reloc.c"
 
+extern __typeof (EBLHOOK (core_note)) x32_core_note attribute_hidden;
+
 const char *
 x86_64_init (elf, machine, eh, ehlen)
      Elf *elf __attribute__ ((unused));
@@ -53,7 +55,10 @@ x86_64_init (elf, machine, eh, ehlen)
   eh->name = "AMD x86-64";
   x86_64_init_reloc (eh);
   HOOK (eh, reloc_simple_type);
-  HOOK (eh, core_note);
+  if (eh->class == ELFCLASS32)
+    eh->core_note = x32_core_note;
+  else
+    HOOK (eh, core_note);
   HOOK (eh, return_value_location);
   HOOK (eh, register_info);
   HOOK (eh, syscall_abi);
-- 
1.9.3

