summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2021-08-12 04:01:49 +0200
committerEugene Syromyatnikov <evgsyr@gmail.com>2021-08-19 12:37:43 +0200
commitbd4138da59b84d65a61d557d8b48cee52319a4c8 (patch)
treef394a7131880ee9b425c33886506e89bd70b77e8
parentd94f7d647de757a4ac369c8d6e5d6fb8c99fe9c8 (diff)
downloadstrace-esyr/linux-5.14.tar.gz
prctl: enhance PR_SET_MM decodingesyr/linux-5.14
-rw-r--r--src/Makefile.am2
-rw-r--r--src/defs.h3
-rw-r--r--src/prctl.c34
-rw-r--r--src/print_auxv.c291
-rw-r--r--src/print_struct_prctl_mm_map.c66
-rw-r--r--src/xlat/auxvec_types.in59
-rw-r--r--src/xlat/hwcaps.in166
-rw-r--r--src/xlat/hwcaps2.in31
8 files changed, 649 insertions, 3 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b7e74a76e..17f002abc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -247,6 +247,7 @@ libstrace_a_SOURCES = \
poke.h \
poll.c \
prctl.c \
+ print_auxv.c \
print_dev_t.c \
print_fields.h \
print_group_req.c \
@@ -261,6 +262,7 @@ libstrace_a_SOURCES = \
print_sigevent.c \
print_statfs.c \
print_struct_stat.c \
+ print_struct_prctl_mm_map.c \
print_syscall_number.c \
print_time.c \
print_timespec.h \
diff --git a/src/defs.h b/src/defs.h
index b2dcd0350..ec2aa8a93 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -924,6 +924,9 @@ extern void print_dev_t(unsigned long long dev);
extern void print_kernel_version(unsigned long version);
extern void print_abnormal_hi(kernel_ulong_t);
extern void print_ioprio(unsigned int ioprio);
+extern void print_auxv32(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size);
+extern void print_auxv64(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size);
+extern void print_auxv(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size);
extern bool print_int8_array_member(struct tcb *, void *elem_buf,
size_t elem_size, void *data);
diff --git a/src/prctl.c b/src/prctl.c
index 0d44b5fd7..436b73c46 100644
--- a/src/prctl.c
+++ b/src/prctl.c
@@ -375,9 +375,37 @@ SYS_FUNC(prctl)
#endif
case PR_SET_MM:
- tprint_arg_next();
- printxval(pr_set_mm, arg2, "PR_SET_MM_???");
- print_prctl_args(tcp, 2);
+ if (entering(tcp)) {
+ tprint_arg_next();
+ printxval(pr_set_mm, arg2, "PR_SET_MM_???");
+ tprint_arg_next();
+
+ switch (arg2) {
+ case PR_SET_MM_AUXV:
+ print_auxv(tcp, arg3, arg4);
+ break;
+ case PR_SET_MM_EXE_FILE:
+ printfd(tcp, arg3);
+ break;
+ case PR_SET_MM_MAP:
+ print_struct_prctl_mm_map(tcp, arg3, arg4);
+ print_prctl_args(tcp, 3);
+ break;
+ case PR_SET_MM_MAP_SIZE:
+ return 0;
+ default:
+ PRINT_VAL_X(arg3);
+ }
+
+ print_prctl_args(tcp, 3);
+ } else {
+ /* PR_SET_MM_MAP_SIZE */
+ if (syserror(tcp))
+ printaddr(arg3);
+ else
+ printnum_int(tcp, arg3, "%u");
+ print_prctl_args(tcp, 3);
+ }
return RVAL_DECODED;
case PR_SET_PDEATHSIG:
diff --git a/src/print_auxv.c b/src/print_auxv.c
new file mode 100644
index 000000000..2fb71e58b
--- /dev/null
+++ b/src/print_auxv.c
@@ -0,0 +1,291 @@
+/*
+ * Decode auxv.
+ *
+ * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+
+#include <elf.h>
+
+#include "print_fields.h"
+
+#include "xlat.h"
+#include "xlat/auxvec_types.h"
+#include "xlat/hwcaps.h"
+#include "xlat/hwcaps2.h"
+
+static inline void
+print_hwcap(uint64_t a_val)
+{
+ static const char *dflt =
+#if defined ARM
+ "HWCAP_???"
+#elif defined MIPS
+ "HWCAP_???"
+#elif defined NDS32
+ "HWCAP_???"
+#elif defined POWERPC || defined POWERPC64 || defined POWERPC64LE
+ "PPC_FEATURE_???"
+#elif defined RISCV64
+ "COMPAT_HWCAP_???"
+#elif defined S390 || defined S390X
+ "HWCAP_S390_???"
+#elif defined SH || defined SH64
+ NULL
+#elif defined SPARC || defined SPARC64
+ "HWCAP_SPARC_???"
+#elif defined I386 || defined X86_64 || defined X32
+ NULL
+#else
+ NULL
+#endif
+ ;
+ static const bool uapi =
+#if defined ARM
+ true
+#elif defined MIPS
+ true
+#elif defined NDS32
+ false
+#elif defined POWERPC || defined POWERPC64 || defined POWERPC64LE
+ true
+#elif defined RISCV64
+ true
+#elif defined S390 || defined S390X
+ false
+#elif defined SH || defined SH64
+ false
+#elif defined SPARC || defined SPARC64
+ false
+#elif defined I386 || defined X86_64 || defined X32
+ false
+#else
+ false
+#endif
+ ;
+
+ if (dflt) {
+ printflags_ex(a_val, dflt,
+ uapi || (xlat_verbose(xlat_verbosity) ==
+ XLAT_STYLE_RAW) ? XLAT_STYLE_DEFAULT
+ : XLAT_STYLE_VERBOSE,
+ hwcaps, NULL);
+ } else {
+ PRINT_VAL_X(a_val);
+ }
+}
+
+static inline void
+print_hwcap2(uint64_t a_val)
+{
+ static const char *dflt =
+#if defined ARM
+ "HWCAP2_???"
+#elif defined POWERPC || defined POWERPC64 || defined POWERPC64LE
+ "PPC_FEATURE"
+#elif defined I386 || defined X86_64 || defined X32
+ "HWCAP2_???"
+#else
+ NULL
+#endif
+ ;
+
+ if (dflt)
+ printflags64(hwcaps2, a_val, dflt);
+ else
+ PRINT_VAL_X(a_val);
+}
+
+static inline void
+print_cshape(uint64_t a_val)
+{
+ tprintf_comment("CSHAPE(totalsize=%" PRIu64
+ ", linesize=ilog2(%u)"
+ ", assoc=%" PRIu64")",
+ a_val & ~0xff,
+ 1 << ((a_val & 0xf0) >> 4),
+ a_val & 0xf);
+}
+
+static inline void
+print_cache_geometry(uint64_t a_val)
+{
+ tprintf_comment("line size %" PRIu64 " B, associativity %" PRIu64,
+ a_val & 0xffff, a_val >> 16);
+}
+
+static inline void
+print_auxv_val(struct tcb *tcp, uint32_t a_type, uint64_t a_val)
+{
+ switch (a_type) {
+ case AT_NULL:
+ case AT_IGNORE:
+ PRINT_VAL_X(a_val);
+ break;
+ case AT_EXECFD:
+ printfd(tcp, a_val);
+ break;
+ case AT_PHDR:
+ printaddr(a_val);
+ break;
+ case AT_PHENT:
+ case AT_PHNUM:
+ case AT_PAGESZ:
+ PRINT_VAL_U(a_val);
+ break;
+ case AT_BASE:
+ printaddr(a_val);
+ break;
+ case AT_FLAGS:
+ PRINT_VAL_X(a_val);
+ break;
+ case AT_ENTRY:
+ printaddr(a_val);
+ break;
+ case AT_NOTELF:
+ PRINT_VAL_X(a_val);
+ break;
+ case AT_UID:
+ case AT_EUID:
+ case AT_GID:
+ case AT_EGID:
+ printuid(a_val);
+ break;
+ case AT_PLATFORM:
+ printstr(tcp, a_val);
+ break;
+ case AT_HWCAP:
+ print_hwcap(a_val);
+ break;
+ case AT_CLKTCK:
+ PRINT_VAL_U(a_val);
+ break;
+ case AT_FPUCW:
+ PRINT_VAL_X(a_val);
+ break;
+ case AT_DCACHEBSIZE:
+ case AT_ICACHEBSIZE:
+ case AT_UCACHEBSIZE:
+ case AT_IGNOREPPC:
+ PRINT_VAL_U(a_val);
+ break;
+ case AT_SECURE:
+ PRINT_VAL_U(a_val);
+ break;
+ case AT_BASE_PLATFORM:
+ printstr(tcp, a_val);
+ break;
+ case AT_RANDOM: /* 16 random bytes */
+ printstr_ex(tcp, a_val, 16, QUOTE_FORCE_HEX);
+ break;
+ case AT_HWCAP2:
+ print_hwcap2(a_val);
+ break;
+ case AT_EXECFN:
+ printstr(tcp, a_val);
+ break;
+ case AT_SYSINFO:
+ case AT_SYSINFO_EHDR:
+ printaddr(a_val);
+ break;
+ case AT_L1I_CACHESHAPE:
+ case AT_L1D_CACHESHAPE:
+ case AT_L2_CACHESHAPE:
+ case AT_L3_CACHESHAPE:
+ PRINT_VAL_X(a_val);
+ print_cshape(a_val);
+ break;
+ case AT_L1I_CACHESIZE:
+ case AT_L1D_CACHESIZE:
+ case AT_L2_CACHESIZE:
+ case AT_L3_CACHESIZE:
+ PRINT_VAL_U(a_val);
+ break;
+ case AT_L1I_CACHEGEOMETRY:
+ case AT_L1D_CACHEGEOMETRY:
+ case AT_L2_CACHEGEOMETRY:
+ case AT_L3_CACHEGEOMETRY:
+ PRINT_VAL_X(a_val);
+ print_cache_geometry(a_val);
+ break;
+ case AT_ADI_BLKSZ:
+ case AT_ADI_NBITS:
+ case AT_ADI_UEONADI:
+ PRINT_VAL_U(a_val);
+ break;
+ case AT_MINSIGSTKSZ:
+ PRINT_VAL_X(a_val);
+ break;
+ default:
+ PRINT_VAL_X(a_val);
+ }
+}
+
+static inline bool
+print_auxv32_elem(struct tcb *tcp, void *elem_buf, size_t elem_size,
+ void *opaque_data)
+{
+ Elf32_auxv_t *memb = (Elf32_auxv_t *) elem_buf;
+
+ tprint_struct_begin();
+ PRINT_FIELD_XVAL(*memb, a_type, auxvec_types, "AT_???");
+ tprint_struct_next();
+ tprints_field_name("a_un.a_val");
+ print_auxv_val(tcp, memb->a_type, memb->a_un.a_val);
+ tprint_struct_end();
+
+ return true;
+}
+
+void
+print_auxv32(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size)
+{
+ Elf32_auxv_t memb;
+
+ print_array_ex(tcp, addr, size / sizeof(memb), &memb, sizeof(memb),
+ tfetch_mem, print_auxv32_elem, NULL,
+ size % sizeof(memb) ? PAF_ARRAY_TRUNCATED
+ : XLAT_STYLE_DEFAULT,
+ NULL, NULL);
+}
+
+static inline bool
+print_auxv64_elem(struct tcb *tcp, void *elem_buf, size_t elem_size,
+ void *opaque_data)
+{
+ Elf64_auxv_t *memb = (Elf64_auxv_t *) elem_buf;
+
+ tprint_struct_begin();
+ PRINT_FIELD_XVAL(*memb, a_type, auxvec_types, "AT_???");
+ tprint_struct_next();
+ tprints_field_name("a_un.a_val");
+ print_auxv_val(tcp, memb->a_type, memb->a_un.a_val);
+ tprint_struct_end();
+
+ return true;
+}
+
+void
+print_auxv64(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size)
+{
+ Elf64_auxv_t memb;
+
+ print_array_ex(tcp, addr, size / sizeof(memb), &memb, sizeof(memb),
+ tfetch_mem, print_auxv64_elem, NULL,
+ size % sizeof(memb) ? PAF_ARRAY_TRUNCATED
+ : XLAT_STYLE_DEFAULT,
+ NULL, NULL);
+}
+
+void
+print_auxv(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size)
+{
+ switch (current_wordsize) {
+ case 4: print_auxv32(tcp, addr, size); break;
+ case 8: print_auxv64(tcp, addr, size); break;
+ }
+}
diff --git a/src/print_struct_prctl_mm_map.c b/src/print_struct_prctl_mm_map.c
new file mode 100644
index 000000000..0cdf773ca
--- /dev/null
+++ b/src/print_struct_prctl_mm_map.c
@@ -0,0 +1,66 @@
+/*
+ * Decode struct sg_req_info.
+ *
+ * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+
+#include DEF_MPERS_TYPE(struct_prctl_mm_map)
+
+#include <linux/prctl.h>
+
+typedef struct prctl_mm_map struct_prctl_mm_map;
+
+#include MPERS_DEFS
+
+MPERS_PRINTER_DECL(void, print_struct_prctl_mm_map,
+ struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t size)
+{
+ struct_prctl_mm_map arg;
+
+ if (size < offsetofend(struct_prctl_mm_map, exe_fd)) {
+ printaddr(addr);
+ return;
+ }
+ if (umoven_or_printaddr(tcp, addr, MIN(size, sizeof(arg)), &arg))
+ return;
+
+ tprint_struct_begin();
+ PRINT_FIELD_X(arg, start_code);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, end_code);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, start_data);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, end_data);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, start_brk);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, brk);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, start_stack);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, arg_start);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, arg_end);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, env_start);
+ tprint_struct_next();
+ PRINT_FIELD_X(arg, env_end);
+ tprint_struct_next();
+ tprints_field_name("auxv");
+ print_auxv(tcp, (mpers_ptr_t) arg.auxv, arg.auxv_size);
+ tprint_struct_next();
+ PRINT_FIELD_U(arg, auxv_size);
+ tprint_struct_next();
+ PRINT_FIELD_FD(arg, exe_fd, tcp);
+ if (size > sizeof(arg)) {
+ tprint_struct_next();
+ tprint_more_data_follows();
+ }
+ tprint_struct_end();
+}
diff --git a/src/xlat/auxvec_types.in b/src/xlat/auxvec_types.in
new file mode 100644
index 000000000..29b533f34
--- /dev/null
+++ b/src/xlat/auxvec_types.in
@@ -0,0 +1,59 @@
+/* arch-independent */
+AT_NULL 0
+AT_IGNORE 1
+AT_EXECFD 2
+AT_PHDR 3
+AT_PHENT 4
+AT_PHNUM 5
+AT_PAGESZ 6
+AT_BASE 7
+AT_FLAGS 8
+AT_ENTRY 9
+AT_NOTELF 10
+AT_UID 11
+AT_EUID 12
+AT_GID 13
+AT_EGID 14
+AT_PLATFORM 15
+AT_HWCAP 16
+AT_CLKTCK 17
+/* nds32, sh */
+AT_FPUCW 18
+/* powerpc */
+AT_DCACHEBSIZE 19
+AT_ICACHEBSIZE 20
+AT_UCACHEBSIZE 21
+AT_IGNOREPPC 22
+/* arch-independent */
+AT_SECURE 23
+AT_BASE_PLATFORM 24
+AT_RANDOM 25
+AT_HWCAP2 26
+/* arch-independent */
+AT_EXECFN 31
+/* alpha, ia64, x86 */
+AT_SYSINFO 32
+/* alpha, arm, arm64, ia64, mips, nds32, powerpc, riscv, s390, sh, sparc, x86 */
+AT_SYSINFO_EHDR 33
+/* alpha, sh */
+AT_L1I_CACHESHAPE 34
+AT_L1D_CACHESHAPE 35
+AT_L2_CACHESHAPE 36
+/* alpha */
+AT_L3_CACHESHAPE 37
+/* powerpc, riscv */
+AT_L1I_CACHESIZE 40
+AT_L1I_CACHEGEOMETRY 41
+AT_L1D_CACHESIZE 42
+AT_L1D_CACHEGEOMETRY 43
+AT_L2_CACHESIZE 44
+AT_L2_CACHEGEOMETRY 45
+/* powerpc */
+AT_L3_CACHESIZE 46
+AT_L3_CACHEGEOMETRY 47
+/* sparc */
+AT_ADI_BLKSZ 48
+AT_ADI_NBITS 49
+AT_ADI_UEONADI 50
+/* arch-independent */
+AT_MINSIGSTKSZ 51
diff --git a/src/xlat/hwcaps.in b/src/xlat/hwcaps.in
new file mode 100644
index 000000000..d9d3af1a9
--- /dev/null
+++ b/src/xlat/hwcaps.in
@@ -0,0 +1,166 @@
+#if defined ARM
+/* arch/arm/include/uapi/asm/hwcap.h */
+HWCAP_SWP (1 << 0)
+HWCAP_HALF (1 << 1)
+HWCAP_THUMB (1 << 2)
+HWCAP_26BIT (1 << 3)
+HWCAP_FAST_MULT (1 << 4)
+HWCAP_FPA (1 << 5)
+HWCAP_VFP (1 << 6)
+HWCAP_EDSP (1 << 7)
+HWCAP_JAVA (1 << 8)
+HWCAP_IWMMXT (1 << 9)
+HWCAP_CRUNCH (1 << 10)
+HWCAP_THUMBEE (1 << 11)
+HWCAP_NEON (1 << 12)
+HWCAP_VFPv3 (1 << 13)
+HWCAP_VFPv3D16 (1 << 14)
+HWCAP_TLS (1 << 15)
+HWCAP_VFPv4 (1 << 16)
+HWCAP_IDIVA (1 << 17)
+HWCAP_IDIVT (1 << 18)
+HWCAP_VFPD32 (1 << 19)
+HWCAP_LPAE (1 << 20)
+HWCAP_EVTSTRM (1 << 21)
+
+#elif defined MIPS
+/* arch/mips/include/uapi/asm/hwcap.h */
+HWCAP_MIPS_R6 (1 << 0)
+HWCAP_MIPS_MSA (1 << 1)
+HWCAP_MIPS_CRC32 (1 << 2)
+HWCAP_MIPS_MIPS16 (1 << 3)
+HWCAP_MIPS_MDMX (1 << 4)
+HWCAP_MIPS_MIPS3D (1 << 5)
+HWCAP_MIPS_SMARTMIPS (1 << 6)
+HWCAP_MIPS_DSP (1 << 7)
+HWCAP_MIPS_DSP2 (1 << 8)
+HWCAP_MIPS_DSP3 (1 << 9)
+HWCAP_MIPS_MIPS16E2 (1 << 10)
+HWCAP_LOONGSON_MMI (1 << 11)
+HWCAP_LOONGSON_EXT (1 << 12)
+HWCAP_LOONGSON_EXT2 (1 << 13)
+HWCAP_LOONGSON_CPUCFG (1 << 14)
+
+#elif defined NDS32
+/* arch/nds32/kernel/setup.c */
+HWCAP_MFUSR_PC 0x000001
+HWCAP_EXT 0x000002
+HWCAP_EXT2 0x000004
+HWCAP_FPU 0x000008
+HWCAP_AUDIO 0x000010
+HWCAP_BASE16 0x000020
+HWCAP_STRING 0x000040
+HWCAP_REDUCED_REGS 0x000080
+HWCAP_VIDEO 0x000100
+HWCAP_ENCRYPT 0x000200
+HWCAP_EDM 0x000400
+HWCAP_LMDMA 0x000800
+HWCAP_PFM 0x001000
+HWCAP_HSMP 0x002000
+HWCAP_TRACE 0x004000
+HWCAP_DIV 0x008000
+HWCAP_MAC 0x010000
+HWCAP_L2C 0x020000
+HWCAP_FPU_DP 0x040000
+HWCAP_V2 0x080000
+HWCAP_DX_REGS 0x100000
+HWCAP_HWPRE 0x200000
+
+#elif defined POWERPC || defined POWERPC64 || defined POWERPC64LE
+/* include/uapi/asm/cputable.h */
+PPC_FEATURE_32 0x80000000
+PPC_FEATURE_64 0x40000000
+PPC_FEATURE_601_INSTR 0x20000000
+PPC_FEATURE_HAS_ALTIVEC 0x10000000
+PPC_FEATURE_HAS_FPU 0x08000000
+PPC_FEATURE_HAS_MMU 0x04000000
+PPC_FEATURE_HAS_4xxMAC 0x02000000
+PPC_FEATURE_UNIFIED_CACHE 0x01000000
+PPC_FEATURE_HAS_SPE 0x00800000
+PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
+PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
+PPC_FEATURE_NO_TB 0x00100000
+PPC_FEATURE_POWER4 0x00080000
+PPC_FEATURE_POWER5 0x00040000
+PPC_FEATURE_POWER5_PLUS 0x00020000
+PPC_FEATURE_CELL 0x00010000
+PPC_FEATURE_BOOKE 0x00008000
+PPC_FEATURE_SMT 0x00004000
+PPC_FEATURE_ICACHE_SNOOP 0x00002000
+PPC_FEATURE_ARCH_2_05 0x00001000
+PPC_FEATURE_PA6T 0x00000800
+PPC_FEATURE_HAS_DFP 0x00000400
+PPC_FEATURE_POWER6_EXT 0x00000200
+PPC_FEATURE_ARCH_2_06 0x00000100
+PPC_FEATURE_HAS_VSX 0x00000080
+PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040
+PPC_FEATURE_TRUE_LE 0x00000002
+PPC_FEATURE_PPC_LE 0x00000001
+
+#elif defined RISCV64
+/* arch/riscv/include/uapi/asm/hwcap.h */
+COMPAT_HWCAP_ISA_I (1 << ('I' - 'A'))
+COMPAT_HWCAP_ISA_M (1 << ('M' - 'A'))
+COMPAT_HWCAP_ISA_A (1 << ('A' - 'A'))
+COMPAT_HWCAP_ISA_F (1 << ('F' - 'A'))
+COMPAT_HWCAP_ISA_D (1 << ('D' - 'A'))
+COMPAT_HWCAP_ISA_C (1 << ('C' - 'A'))
+
+#elif defined S390 || defined S390X
+/* arch/s390/include/asm/elf.h */
+HWCAP_S390_ESAN3 1
+HWCAP_S390_ZARCH 2
+HWCAP_S390_STFLE 4
+HWCAP_S390_MSA 8
+HWCAP_S390_LDISP 16
+HWCAP_S390_EIMM 32
+HWCAP_S390_DFP 64
+HWCAP_S390_HPAGE 128
+HWCAP_S390_ETF3EH 256
+HWCAP_S390_HIGH_GPRS 512
+HWCAP_S390_TE 1024
+HWCAP_S390_VXRS 2048
+HWCAP_S390_VXRS_BCD 4096
+HWCAP_S390_VXRS_EXT 8192
+HWCAP_S390_GS 16384
+HWCAP_S390_VXRS_EXT2 32768
+HWCAP_S390_VXRS_PDE 65536
+HWCAP_S390_SORT 131072
+HWCAP_S390_DFLT 262144
+
+#elif defined SH || defined SH64
+
+#elif defined SPARC || defined SPARC64
+/* arch/sparc/include/asm/elf_64.h */
+HWCAP_SPARC_FLUSH 0x00000001
+HWCAP_SPARC_STBAR 0x00000002
+HWCAP_SPARC_SWAP 0x00000004
+HWCAP_SPARC_MULDIV 0x00000008
+HWCAP_SPARC_V9 0x00000010
+HWCAP_SPARC_ULTRA3 0x00000020
+HWCAP_SPARC_BLKINIT 0x00000040
+HWCAP_SPARC_N2 0x00000080
+AV_SPARC_MUL32 0x00000100
+AV_SPARC_DIV32 0x00000200
+AV_SPARC_FSMULD 0x00000400
+AV_SPARC_V8PLUS 0x00000800
+AV_SPARC_POPC 0x00001000
+AV_SPARC_VIS 0x00002000
+AV_SPARC_VIS2 0x00004000
+AV_SPARC_ASI_BLK_INIT 0x00008000
+AV_SPARC_FMAF 0x00010000
+AV_SPARC_VIS3 0x00020000
+AV_SPARC_HPC 0x00040000
+AV_SPARC_RANDOM 0x00080000
+AV_SPARC_TRANS 0x00100000
+AV_SPARC_FJFMAU 0x00200000
+AV_SPARC_IMA 0x00400000
+AV_SPARC_ASI_CACHE_SPARING 0x00800000
+AV_SPARC_PAUSE 0x01000000
+AV_SPARC_CBCOND 0x02000000
+HWCAP_SPARC_CRYPTO 0x04000000
+HWCAP_SPARC_ADI 0x08000000
+
+#elif defined I386 || defined X86_64 || defined X32
+
+#endif
diff --git a/src/xlat/hwcaps2.in b/src/xlat/hwcaps2.in
new file mode 100644
index 000000000..2ddf9b87b
--- /dev/null
+++ b/src/xlat/hwcaps2.in
@@ -0,0 +1,31 @@
+#if defined ARM
+/* arch/arm/include/uapi/asm/hwcap.h */
+HWCAP2_AES (1 << 0)
+HWCAP2_PMULL (1 << 1)
+HWCAP2_SHA1 (1 << 2)
+HWCAP2_SHA2 (1 << 3)
+HWCAP2_CRC32 (1 << 4)
+
+#elif defined POWERPC || defined POWERPC64 || defined POWERPC64LE
+/* arch/powerpc/include/uapi/asm/cputable.h */
+PPC_FEATURE2_ARCH_2_07 0x80000000
+PPC_FEATURE2_HTM 0x40000000
+PPC_FEATURE2_DSCR 0x20000000
+PPC_FEATURE2_EBB 0x10000000
+PPC_FEATURE2_ISEL 0x08000000
+PPC_FEATURE2_TAR 0x04000000
+PPC_FEATURE2_VEC_CRYPTO 0x02000000
+PPC_FEATURE2_HTM_NOSC 0x01000000
+PPC_FEATURE2_ARCH_3_00 0x00800000
+PPC_FEATURE2_HAS_IEEE128 0x00400000
+PPC_FEATURE2_DARN 0x00200000
+PPC_FEATURE2_SCV 0x00100000
+PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000
+PPC_FEATURE2_ARCH_3_1 0x00040000
+PPC_FEATURE2_MMA 0x00020000
+
+#elif defined I386 || defined X86_64 || defined X32
+/* arch/x86/include/uapi/asm/hwcap2.h */
+HWCAP2_RING3MWAIT (1 << 0)
+HWCAP2_FSGSBASE (1 << 1)
+#endif