Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  perf_regs.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <regex.h>
#include <string.h>
#include <sys/auxv.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>

#include "perf_regs.h"
#include "../../../perf-sys.h"
#include "../../../util/debug.h"
#include "../../../util/event.h"
#include "../../../util/perf_regs.h"

#ifndef HWCAP_SVE
#define HWCAP_SVE (1 << 22)
#endif

static const struct sample_reg sample_reg_masks[] = {
 SMPL_REG(x0, PERF_REG_ARM64_X0),
 SMPL_REG(x1, PERF_REG_ARM64_X1),
 SMPL_REG(x2, PERF_REG_ARM64_X2),
 SMPL_REG(x3, PERF_REG_ARM64_X3),
 SMPL_REG(x4, PERF_REG_ARM64_X4),
 SMPL_REG(x5, PERF_REG_ARM64_X5),
 SMPL_REG(x6, PERF_REG_ARM64_X6),
 SMPL_REG(x7, PERF_REG_ARM64_X7),
 SMPL_REG(x8, PERF_REG_ARM64_X8),
 SMPL_REG(x9, PERF_REG_ARM64_X9),
 SMPL_REG(x10, PERF_REG_ARM64_X10),
 SMPL_REG(x11, PERF_REG_ARM64_X11),
 SMPL_REG(x12, PERF_REG_ARM64_X12),
 SMPL_REG(x13, PERF_REG_ARM64_X13),
 SMPL_REG(x14, PERF_REG_ARM64_X14),
 SMPL_REG(x15, PERF_REG_ARM64_X15),
 SMPL_REG(x16, PERF_REG_ARM64_X16),
 SMPL_REG(x17, PERF_REG_ARM64_X17),
 SMPL_REG(x18, PERF_REG_ARM64_X18),
 SMPL_REG(x19, PERF_REG_ARM64_X19),
 SMPL_REG(x20, PERF_REG_ARM64_X20),
 SMPL_REG(x21, PERF_REG_ARM64_X21),
 SMPL_REG(x22, PERF_REG_ARM64_X22),
 SMPL_REG(x23, PERF_REG_ARM64_X23),
 SMPL_REG(x24, PERF_REG_ARM64_X24),
 SMPL_REG(x25, PERF_REG_ARM64_X25),
 SMPL_REG(x26, PERF_REG_ARM64_X26),
 SMPL_REG(x27, PERF_REG_ARM64_X27),
 SMPL_REG(x28, PERF_REG_ARM64_X28),
 SMPL_REG(x29, PERF_REG_ARM64_X29),
 SMPL_REG(lr, PERF_REG_ARM64_LR),
 SMPL_REG(sp, PERF_REG_ARM64_SP),
 SMPL_REG(pc, PERF_REG_ARM64_PC),
 SMPL_REG(vg, PERF_REG_ARM64_VG),
 SMPL_REG_END
};

/* %xNUM */
#define SDT_OP_REGEX1  "^(x[1-2]?[0-9]|3[0-1])$"

/* [sp], [sp, NUM] */
#define SDT_OP_REGEX2  "^\\[sp(, )?([0-9]+)?\\]$"

static regex_t sdt_op_regex1, sdt_op_regex2;

static int sdt_init_op_regex(void)
{
 static int initialized;
 int ret = 0;

 if (initialized)
  return 0;

 ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED);
 if (ret)
  goto error;

 ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED);
 if (ret)
  goto free_regex1;

 initialized = 1;
 return 0;

free_regex1:
 regfree(&sdt_op_regex1);
error:
 pr_debug4("Regex compilation error.\n");
 return ret;
}

/*
 * SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently
 * support these two formats.
 */

int arch_sdt_arg_parse_op(char *old_op, char **new_op)
{
 int ret, new_len;
 regmatch_t rm[5];

 ret = sdt_init_op_regex();
 if (ret < 0)
  return ret;

 if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) {
  /* Extract xNUM */
  new_len = 2; /* % NULL */
  new_len += (int)(rm[1].rm_eo - rm[1].rm_so);

  *new_op = zalloc(new_len);
  if (!*new_op)
   return -ENOMEM;

  scnprintf(*new_op, new_len, "%%%.*s",
   (int)(rm[1].rm_eo - rm[1].rm_so), old_op + rm[1].rm_so);
 } else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) {
  /* [sp], [sp, NUM] or [sp,NUM] */
  new_len = 7; /* + ( % s p ) NULL */

  /* If the argument is [sp], need to fill offset '0' */
  if (rm[2].rm_so == -1)
   new_len += 1;
  else
   new_len += (int)(rm[2].rm_eo - rm[2].rm_so);

  *new_op = zalloc(new_len);
  if (!*new_op)
   return -ENOMEM;

  if (rm[2].rm_so == -1)
   scnprintf(*new_op, new_len, "+0(%%sp)");
  else
   scnprintf(*new_op, new_len, "+%.*s(%%sp)",
      (int)(rm[2].rm_eo - rm[2].rm_so),
      old_op + rm[2].rm_so);
 } else {
  pr_debug4("Skipping unsupported SDT argument: %s\n", old_op);
  return SDT_ARG_SKIP;
 }

 return SDT_ARG_VALID;
}

uint64_t arch__intr_reg_mask(void)
{
 return PERF_REGS_MASK;
}

uint64_t arch__user_reg_mask(void)
{
 struct perf_event_attr attr = {
  .type                   = PERF_TYPE_HARDWARE,
  .config                 = PERF_COUNT_HW_CPU_CYCLES,
  .sample_type            = PERF_SAMPLE_REGS_USER,
  .disabled               = 1,
  .exclude_kernel         = 1,
  .sample_period  = 1,
  .sample_regs_user = PERF_REGS_MASK
 };
 int fd;

 if (getauxval(AT_HWCAP) & HWCAP_SVE)
  attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG);

 /*
 * Check if the pmu supports perf extended regs, before
 * returning the register mask to sample.
 */

 if (attr.sample_regs_user != PERF_REGS_MASK) {
  event_attr_init(&attr);
  fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
  if (fd != -1) {
   close(fd);
   return attr.sample_regs_user;
  }
 }
 return PERF_REGS_MASK;
}

const struct sample_reg *arch__sample_reg_masks(void)
{
 return sample_reg_masks;
}

Messung V0.5
C=98 H=97 G=97

¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge