1da0c48c4Sopenharmony_ci/* i386 specific core note handling.
2da0c48c4Sopenharmony_ci   Copyright (C) 2007-2010 Red Hat, Inc.
3da0c48c4Sopenharmony_ci   This file is part of elfutils.
4da0c48c4Sopenharmony_ci
5da0c48c4Sopenharmony_ci   This file is free software; you can redistribute it and/or modify
6da0c48c4Sopenharmony_ci   it under the terms of either
7da0c48c4Sopenharmony_ci
8da0c48c4Sopenharmony_ci     * the GNU Lesser General Public License as published by the Free
9da0c48c4Sopenharmony_ci       Software Foundation; either version 3 of the License, or (at
10da0c48c4Sopenharmony_ci       your option) any later version
11da0c48c4Sopenharmony_ci
12da0c48c4Sopenharmony_ci   or
13da0c48c4Sopenharmony_ci
14da0c48c4Sopenharmony_ci     * the GNU General Public License as published by the Free
15da0c48c4Sopenharmony_ci       Software Foundation; either version 2 of the License, or (at
16da0c48c4Sopenharmony_ci       your option) any later version
17da0c48c4Sopenharmony_ci
18da0c48c4Sopenharmony_ci   or both in parallel, as here.
19da0c48c4Sopenharmony_ci
20da0c48c4Sopenharmony_ci   elfutils is distributed in the hope that it will be useful, but
21da0c48c4Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
22da0c48c4Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23da0c48c4Sopenharmony_ci   General Public License for more details.
24da0c48c4Sopenharmony_ci
25da0c48c4Sopenharmony_ci   You should have received copies of the GNU General Public License and
26da0c48c4Sopenharmony_ci   the GNU Lesser General Public License along with this program.  If
27da0c48c4Sopenharmony_ci   not, see <http://www.gnu.org/licenses/>.  */
28da0c48c4Sopenharmony_ci
29da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H
30da0c48c4Sopenharmony_ci# include <config.h>
31da0c48c4Sopenharmony_ci#endif
32da0c48c4Sopenharmony_ci
33da0c48c4Sopenharmony_ci#include <elf.h>
34da0c48c4Sopenharmony_ci#include <inttypes.h>
35da0c48c4Sopenharmony_ci#include <stddef.h>
36da0c48c4Sopenharmony_ci#include <stdio.h>
37da0c48c4Sopenharmony_ci#include <sys/time.h>
38da0c48c4Sopenharmony_ci
39da0c48c4Sopenharmony_ci#define BACKEND i386_
40da0c48c4Sopenharmony_ci#include "libebl_CPU.h"
41da0c48c4Sopenharmony_ci
42da0c48c4Sopenharmony_ci
43da0c48c4Sopenharmony_cistatic const Ebl_Register_Location prstatus_regs[] =
44da0c48c4Sopenharmony_ci  {
45da0c48c4Sopenharmony_ci#define GR(at, n, dwreg)						\
46da0c48c4Sopenharmony_ci    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 32 }
47da0c48c4Sopenharmony_ci#define SR(at, n, dwreg)						\
48da0c48c4Sopenharmony_ci    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 16, .pad = 2 }
49da0c48c4Sopenharmony_ci
50da0c48c4Sopenharmony_ci    GR (0, 1, 3),		/* %ebx */
51da0c48c4Sopenharmony_ci    GR (1, 2, 1),		/* %ecx-%edx */
52da0c48c4Sopenharmony_ci    GR (3, 2, 6),		/* %esi-%edi */
53da0c48c4Sopenharmony_ci    GR (5, 1, 5),		/* %ebp */
54da0c48c4Sopenharmony_ci    GR (6, 1, 0),		/* %eax */
55da0c48c4Sopenharmony_ci    SR (7, 1, 43),		/* %ds */
56da0c48c4Sopenharmony_ci    SR (8, 1, 40),		/* %es */
57da0c48c4Sopenharmony_ci    SR (9, 1, 44),		/* %fs */
58da0c48c4Sopenharmony_ci    SR (10, 1, 45),		/* %gs */
59da0c48c4Sopenharmony_ci    /*  11, 1,			   orig_eax */
60da0c48c4Sopenharmony_ci    GR (12, 1, 8),		/* %eip */
61da0c48c4Sopenharmony_ci    SR (13, 1, 41),		/* %cs */
62da0c48c4Sopenharmony_ci    GR (14, 1, 9),		/* eflags */
63da0c48c4Sopenharmony_ci    GR (15, 1, 4),		/* %esp */
64da0c48c4Sopenharmony_ci    SR (16, 1, 42),		/* %ss */
65da0c48c4Sopenharmony_ci
66da0c48c4Sopenharmony_ci#undef	GR
67da0c48c4Sopenharmony_ci#undef	SR
68da0c48c4Sopenharmony_ci  };
69da0c48c4Sopenharmony_ci#define PRSTATUS_REGS_SIZE	(17 * 4)
70da0c48c4Sopenharmony_ci
71da0c48c4Sopenharmony_ci#define	ULONG			uint32_t
72da0c48c4Sopenharmony_ci#define PID_T			int32_t
73da0c48c4Sopenharmony_ci#define	UID_T			uint16_t
74da0c48c4Sopenharmony_ci#define	GID_T			uint16_t
75da0c48c4Sopenharmony_ci#define ALIGN_ULONG		4
76da0c48c4Sopenharmony_ci#define ALIGN_PID_T		4
77da0c48c4Sopenharmony_ci#define ALIGN_UID_T		2
78da0c48c4Sopenharmony_ci#define ALIGN_GID_T		2
79da0c48c4Sopenharmony_ci#define TYPE_ULONG		ELF_T_WORD
80da0c48c4Sopenharmony_ci#define TYPE_PID_T		ELF_T_SWORD
81da0c48c4Sopenharmony_ci#define TYPE_UID_T		ELF_T_HALF
82da0c48c4Sopenharmony_ci#define TYPE_GID_T		ELF_T_HALF
83da0c48c4Sopenharmony_ci
84da0c48c4Sopenharmony_ci#define PRSTATUS_REGSET_ITEMS						      \
85da0c48c4Sopenharmony_ci  {									      \
86da0c48c4Sopenharmony_ci    .name = "orig_eax", .type = ELF_T_SWORD, .format = 'd',		      \
87da0c48c4Sopenharmony_ci    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 11),	      \
88da0c48c4Sopenharmony_ci    .group = "register"	       			  	       	 	      \
89da0c48c4Sopenharmony_ci  }
90da0c48c4Sopenharmony_ci
91da0c48c4Sopenharmony_cistatic const Ebl_Register_Location fpregset_regs[] =
92da0c48c4Sopenharmony_ci  {
93da0c48c4Sopenharmony_ci    { .offset = 0, .regno = 37, .count = 2, .bits = 32 }, /* fctrl-fstat */
94da0c48c4Sopenharmony_ci    { .offset = 7 * 4, .regno = 11, .count = 8, .bits = 80 }, /* stN */
95da0c48c4Sopenharmony_ci  };
96da0c48c4Sopenharmony_ci#define FPREGSET_SIZE	108
97da0c48c4Sopenharmony_ci
98da0c48c4Sopenharmony_cistatic const Ebl_Register_Location prxfpreg_regs[] =
99da0c48c4Sopenharmony_ci  {
100da0c48c4Sopenharmony_ci    { .offset = 0, .regno = 37, .count = 2, .bits = 16 }, /* fctrl-fstat */
101da0c48c4Sopenharmony_ci    { .offset = 24, .regno = 39, .count = 1, .bits = 32 }, /* mxcsr */
102da0c48c4Sopenharmony_ci    { .offset = 32, .regno = 11, .count = 8, .bits = 80, .pad = 6 }, /* stN */
103da0c48c4Sopenharmony_ci    { .offset = 32 + 128, .regno = 21, .count = 8, .bits = 128 }, /* xmm */
104da0c48c4Sopenharmony_ci  };
105da0c48c4Sopenharmony_ci
106da0c48c4Sopenharmony_ci#define	EXTRA_NOTES \
107da0c48c4Sopenharmony_ci  EXTRA_REGSET (NT_PRXFPREG, 512, prxfpreg_regs) \
108da0c48c4Sopenharmony_ci  case NT_386_TLS: \
109da0c48c4Sopenharmony_ci    return tls_info (nhdr->n_descsz, regs_offset, nregloc, reglocs, \
110da0c48c4Sopenharmony_ci		     nitems, items);				    \
111da0c48c4Sopenharmony_ci  EXTRA_NOTES_IOPERM
112da0c48c4Sopenharmony_ci
113da0c48c4Sopenharmony_cistatic const Ebl_Core_Item tls_items[] =
114da0c48c4Sopenharmony_ci  {
115da0c48c4Sopenharmony_ci    { .type = ELF_T_WORD, .offset = 0x0, .format = 'd', .name = "index" },
116da0c48c4Sopenharmony_ci    { .type = ELF_T_WORD, .offset = 0x4, .format = 'x', .name = "base" },
117da0c48c4Sopenharmony_ci    { .type = ELF_T_WORD, .offset = 0x8, .format = 'x', .name = "limit" },
118da0c48c4Sopenharmony_ci    { .type = ELF_T_WORD, .offset = 0xc, .format = 'x', .name = "flags" },
119da0c48c4Sopenharmony_ci  };
120da0c48c4Sopenharmony_ci
121da0c48c4Sopenharmony_cistatic int
122da0c48c4Sopenharmony_citls_info (GElf_Word descsz, GElf_Word *regs_offset,
123da0c48c4Sopenharmony_ci	  size_t *nregloc, const Ebl_Register_Location **reglocs,
124da0c48c4Sopenharmony_ci	  size_t *nitems, const Ebl_Core_Item **items)
125da0c48c4Sopenharmony_ci{
126da0c48c4Sopenharmony_ci  if (descsz % 16 != 0)
127da0c48c4Sopenharmony_ci    return 0;
128da0c48c4Sopenharmony_ci
129da0c48c4Sopenharmony_ci  *regs_offset = 0;
130da0c48c4Sopenharmony_ci  *nregloc = 0;
131da0c48c4Sopenharmony_ci  *reglocs = NULL;
132da0c48c4Sopenharmony_ci  *nitems = sizeof tls_items / sizeof tls_items[0];
133da0c48c4Sopenharmony_ci  *items = tls_items;
134da0c48c4Sopenharmony_ci  return 1;
135da0c48c4Sopenharmony_ci}
136da0c48c4Sopenharmony_ci
137da0c48c4Sopenharmony_ci#include "x86_corenote.c"
138da0c48c4Sopenharmony_ci#include "linux-core-note.c"
139