1da0c48c4Sopenharmony_ci/* S390-specific core note handling. 2da0c48c4Sopenharmony_ci Copyright (C) 2012 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#ifndef BITS 40da0c48c4Sopenharmony_ci# define BITS 32 41da0c48c4Sopenharmony_ci# define BACKEND s390_ 42da0c48c4Sopenharmony_ci#else 43da0c48c4Sopenharmony_ci# define BITS 64 44da0c48c4Sopenharmony_ci# define BACKEND s390x_ 45da0c48c4Sopenharmony_ci#endif 46da0c48c4Sopenharmony_ci#include "libebl_CPU.h" 47da0c48c4Sopenharmony_ci 48da0c48c4Sopenharmony_cistatic const Ebl_Register_Location prstatus_regs[] = 49da0c48c4Sopenharmony_ci { 50da0c48c4Sopenharmony_ci#define GR(at, n, dwreg, b...) \ 51da0c48c4Sopenharmony_ci { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = b } 52da0c48c4Sopenharmony_ci 53da0c48c4Sopenharmony_ci GR ( 0, 1, 64, BITS), /* pswm */ 54da0c48c4Sopenharmony_ci GR ( 1, 1, 65, BITS, .pc_register = true ), /* pswa */ 55da0c48c4Sopenharmony_ci GR ( 2, 16, 0, BITS), /* r0-r15 */ 56da0c48c4Sopenharmony_ci GR (18, 16, 48, 32), /* ar0-ar15 */ 57da0c48c4Sopenharmony_ci 58da0c48c4Sopenharmony_ci#undef GR 59da0c48c4Sopenharmony_ci }; 60da0c48c4Sopenharmony_ci 61da0c48c4Sopenharmony_ci /* orig_r2 is at offset (BITS == 32 ? 34 * 4 : 26 * 8). */ 62da0c48c4Sopenharmony_ci#define PRSTATUS_REGS_SIZE (BITS / 8 * (BITS == 32 ? 35 : 27)) 63da0c48c4Sopenharmony_ci 64da0c48c4Sopenharmony_cistatic const Ebl_Register_Location fpregset_regs[] = 65da0c48c4Sopenharmony_ci { 66da0c48c4Sopenharmony_ci#define FPR(at, n, dwreg) \ 67da0c48c4Sopenharmony_ci { .offset = at * 64/8, .regno = dwreg, .count = n, .bits = 64 } 68da0c48c4Sopenharmony_ci 69da0c48c4Sopenharmony_ci /* fpc is at offset 0, see fpregset_items, it has no assigned DWARF regno. 70da0c48c4Sopenharmony_ci Bytes at offsets 4 to 7 are unused. */ 71da0c48c4Sopenharmony_ci FPR (1 + 0, 1, 16), /* f0 */ 72da0c48c4Sopenharmony_ci FPR (1 + 1, 1, 20), /* f1 */ 73da0c48c4Sopenharmony_ci FPR (1 + 2, 1, 17), /* f2 */ 74da0c48c4Sopenharmony_ci FPR (1 + 3, 1, 21), /* f3 */ 75da0c48c4Sopenharmony_ci FPR (1 + 4, 1, 18), /* f4 */ 76da0c48c4Sopenharmony_ci FPR (1 + 5, 1, 22), /* f5 */ 77da0c48c4Sopenharmony_ci FPR (1 + 6, 1, 19), /* f6 */ 78da0c48c4Sopenharmony_ci FPR (1 + 7, 1, 23), /* f7 */ 79da0c48c4Sopenharmony_ci FPR (1 + 8, 1, 24), /* f8 */ 80da0c48c4Sopenharmony_ci FPR (1 + 9, 1, 28), /* f9 */ 81da0c48c4Sopenharmony_ci FPR (1 + 10, 1, 25), /* f10 */ 82da0c48c4Sopenharmony_ci FPR (1 + 11, 1, 29), /* f11 */ 83da0c48c4Sopenharmony_ci FPR (1 + 12, 1, 26), /* f12 */ 84da0c48c4Sopenharmony_ci FPR (1 + 13, 1, 30), /* f13 */ 85da0c48c4Sopenharmony_ci FPR (1 + 14, 1, 27), /* f14 */ 86da0c48c4Sopenharmony_ci FPR (1 + 15, 1, 31), /* f15 */ 87da0c48c4Sopenharmony_ci 88da0c48c4Sopenharmony_ci#undef FPR 89da0c48c4Sopenharmony_ci }; 90da0c48c4Sopenharmony_ci 91da0c48c4Sopenharmony_cistatic const Ebl_Core_Item fpregset_items[] = 92da0c48c4Sopenharmony_ci { 93da0c48c4Sopenharmony_ci { 94da0c48c4Sopenharmony_ci .name = "fpc", .group = "register", .offset = 0, .type = ELF_T_WORD, 95da0c48c4Sopenharmony_ci .format = 'x', 96da0c48c4Sopenharmony_ci }, 97da0c48c4Sopenharmony_ci }; 98da0c48c4Sopenharmony_ci 99da0c48c4Sopenharmony_ci/* Do not set FPREGSET_SIZE so that we can supply fpregset_items. */ 100da0c48c4Sopenharmony_ci#define EXTRA_NOTES_FPREGSET \ 101da0c48c4Sopenharmony_ci EXTRA_REGSET_ITEMS (NT_FPREGSET, 17 * 8, fpregset_regs, fpregset_items) 102da0c48c4Sopenharmony_ci 103da0c48c4Sopenharmony_ci#if BITS == 32 104da0c48c4Sopenharmony_ci# define ULONG uint32_t 105da0c48c4Sopenharmony_ci# define ALIGN_ULONG 4 106da0c48c4Sopenharmony_ci# define TYPE_ULONG ELF_T_WORD 107da0c48c4Sopenharmony_ci# define TYPE_LONG ELF_T_SWORD 108da0c48c4Sopenharmony_ci# define UID_T uint16_t 109da0c48c4Sopenharmony_ci# define GID_T uint16_t 110da0c48c4Sopenharmony_ci# define ALIGN_UID_T 2 111da0c48c4Sopenharmony_ci# define ALIGN_GID_T 2 112da0c48c4Sopenharmony_ci# define TYPE_UID_T ELF_T_HALF 113da0c48c4Sopenharmony_ci# define TYPE_GID_T ELF_T_HALF 114da0c48c4Sopenharmony_ci#else 115da0c48c4Sopenharmony_ci# define ULONG uint64_t 116da0c48c4Sopenharmony_ci# define ALIGN_ULONG 8 117da0c48c4Sopenharmony_ci# define TYPE_ULONG ELF_T_XWORD 118da0c48c4Sopenharmony_ci# define TYPE_LONG ELF_T_SXWORD 119da0c48c4Sopenharmony_ci# define UID_T uint32_t 120da0c48c4Sopenharmony_ci# define GID_T uint32_t 121da0c48c4Sopenharmony_ci# define ALIGN_UID_T 4 122da0c48c4Sopenharmony_ci# define ALIGN_GID_T 4 123da0c48c4Sopenharmony_ci# define TYPE_UID_T ELF_T_WORD 124da0c48c4Sopenharmony_ci# define TYPE_GID_T ELF_T_WORD 125da0c48c4Sopenharmony_ci#endif 126da0c48c4Sopenharmony_ci#define PID_T int32_t 127da0c48c4Sopenharmony_ci#define ALIGN_PID_T 4 128da0c48c4Sopenharmony_ci#define TYPE_PID_T ELF_T_SWORD 129da0c48c4Sopenharmony_ci/* s390 psw_compat_t has alignment 8 bytes where it is inherited from. */ 130da0c48c4Sopenharmony_ci#define ALIGN_PR_REG 8 131da0c48c4Sopenharmony_ci 132da0c48c4Sopenharmony_ci#define PRSTATUS_REGSET_ITEMS \ 133da0c48c4Sopenharmony_ci { \ 134da0c48c4Sopenharmony_ci .name = "orig_r2", .type = TYPE_LONG, .format = 'd', \ 135da0c48c4Sopenharmony_ci .offset = offsetof (struct EBLHOOK(prstatus), \ 136da0c48c4Sopenharmony_ci pr_reg[BITS == 32 ? 34 : 26]), \ 137da0c48c4Sopenharmony_ci .group = "register" \ 138da0c48c4Sopenharmony_ci } 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci#if BITS == 32 141da0c48c4Sopenharmony_ci 142da0c48c4Sopenharmony_cistatic const Ebl_Core_Item high_regs_items[] = 143da0c48c4Sopenharmony_ci { 144da0c48c4Sopenharmony_ci#define HR(n) \ 145da0c48c4Sopenharmony_ci { \ 146da0c48c4Sopenharmony_ci .name = "high_r" #n , .group = "register", .offset = (n) * 4, \ 147da0c48c4Sopenharmony_ci .type = ELF_T_WORD, .format = 'x', \ 148da0c48c4Sopenharmony_ci } 149da0c48c4Sopenharmony_ci 150da0c48c4Sopenharmony_ci /* Upper halves of r0-r15 are stored here. 151da0c48c4Sopenharmony_ci FIXME: They are currently not combined with the r0-r15 lower halves. */ 152da0c48c4Sopenharmony_ci HR (0), HR (1), HR (2), HR (3), HR (4), HR (5), HR (6), HR (7), 153da0c48c4Sopenharmony_ci HR (8), HR (9), HR (10), HR (11), HR (12), HR (13), HR (14), HR (15) 154da0c48c4Sopenharmony_ci 155da0c48c4Sopenharmony_ci#undef HR 156da0c48c4Sopenharmony_ci }; 157da0c48c4Sopenharmony_ci 158da0c48c4Sopenharmony_ci#define EXTRA_NOTES_HIGH_GPRS \ 159da0c48c4Sopenharmony_ci EXTRA_ITEMS (NT_S390_HIGH_GPRS, 16 * 4, high_regs_items) 160da0c48c4Sopenharmony_ci 161da0c48c4Sopenharmony_ci#else /* BITS == 64 */ 162da0c48c4Sopenharmony_ci 163da0c48c4Sopenharmony_ci#define EXTRA_NOTES_HIGH_GPRS 164da0c48c4Sopenharmony_ci 165da0c48c4Sopenharmony_ci#endif /* BITS == 64 */ 166da0c48c4Sopenharmony_ci 167da0c48c4Sopenharmony_cistatic const Ebl_Core_Item last_break_items[] = 168da0c48c4Sopenharmony_ci { 169da0c48c4Sopenharmony_ci { 170da0c48c4Sopenharmony_ci .name = "last_break", .group = "system", .offset = BITS == 32 ? 4 : 0, 171da0c48c4Sopenharmony_ci .type = BITS == 32 ? ELF_T_WORD : ELF_T_XWORD, .format = 'x', 172da0c48c4Sopenharmony_ci }, 173da0c48c4Sopenharmony_ci }; 174da0c48c4Sopenharmony_ci 175da0c48c4Sopenharmony_cistatic const Ebl_Core_Item system_call_items[] = 176da0c48c4Sopenharmony_ci { 177da0c48c4Sopenharmony_ci { 178da0c48c4Sopenharmony_ci .name = "system_call", .group = "system", .offset = 0, .type = ELF_T_WORD, 179da0c48c4Sopenharmony_ci .format = 'd', 180da0c48c4Sopenharmony_ci }, 181da0c48c4Sopenharmony_ci }; 182da0c48c4Sopenharmony_ci 183da0c48c4Sopenharmony_ci#define EXTRA_NOTES \ 184da0c48c4Sopenharmony_ci EXTRA_NOTES_FPREGSET \ 185da0c48c4Sopenharmony_ci EXTRA_NOTES_HIGH_GPRS \ 186da0c48c4Sopenharmony_ci EXTRA_ITEMS (NT_S390_LAST_BREAK, 8, last_break_items) \ 187da0c48c4Sopenharmony_ci EXTRA_ITEMS (NT_S390_SYSTEM_CALL, 4, system_call_items) 188da0c48c4Sopenharmony_ci 189da0c48c4Sopenharmony_ci#include "linux-core-note.c" 190