Page MenuHomeFreeBSD

D40728.id123691.diff
No OneTemporary

D40728.id123691.diff

Index: usr.sbin/Makefile.aarch64
===================================================================
--- usr.sbin/Makefile.aarch64
+++ usr.sbin/Makefile.aarch64
@@ -4,3 +4,4 @@
SUBDIR+= acpi
.endif
SUBDIR+= ofwdump
+SUBDIR+= hwt
Index: usr.sbin/hwt/Makefile
===================================================================
--- /dev/null
+++ usr.sbin/hwt/Makefile
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+PROG_CXX= hwt
+MAN=
+
+CFLAGS+= -I${SRCTOP}/lib/libpmcstat
+
+LIBADD= elf opencsd pmcstat
+
+SRCS= hwt.c \
+ hwt_coresight.c \
+ hwt_elf.c \
+ hwt_process.c \
+ hwt_record.c \
+ libpmcstat_stubs.c
+
+.include <bsd.prog.mk>
Index: usr.sbin/hwt/hwt.c
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwt.c
@@ -0,0 +1,286 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/errno.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/hwt.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+#include "libpmcstat_stubs.h"
+#include <libpmcstat.h>
+
+#include "hwtvar.h"
+#include "hwt_coresight.h"
+
+#define PARENTSOCKET 0
+#define CHILDSOCKET 1
+#define NSOCKPAIRFD 2
+
+static struct trace_context tcs;
+static int ncpu;
+
+void
+hwt_sleep(void)
+{
+ struct timespec time_to_sleep;
+
+ time_to_sleep.tv_sec = 0;
+ time_to_sleep.tv_nsec = 10000000; /* 10 ms */
+
+ nanosleep(&time_to_sleep, &time_to_sleep);
+}
+
+void
+hwt_procexit(pid_t pid, int exit_status __unused)
+{
+ struct trace_context *tc;
+
+ tc = &tcs;
+
+ if (tc->pid == pid)
+ tc->terminate = 1;
+}
+
+static int
+hwt_ctx_alloc(int fd)
+{
+ struct trace_context *tc;
+ struct hwt_alloc al;
+ int error;
+
+ tc = &tcs;
+
+ al.pid = tc->pid;
+ al.bufsize = tc->bufsize;
+ al.backend_name = "coresight";
+
+ error = ioctl(fd, HWT_IOC_ALLOC, &al);
+ if (error != 0)
+ return (error);
+
+ return (0);
+}
+
+static int
+hwt_map_memory(struct trace_context *tc, int tid)
+{
+ char filename[32];
+
+ sprintf(filename, "/dev/hwt_%d_%d", tc->pid, tid);
+
+ tc->thr_fd = open(filename, O_RDONLY);
+ if (tc->thr_fd < 0) {
+ printf("Can't open %s\n", filename);
+ return (-1);
+ }
+
+ tc->base = mmap(NULL, tc->bufsize, PROT_READ, MAP_SHARED, tc->thr_fd,
+ 0);
+ if (tc->base == MAP_FAILED) {
+ printf("mmap failed: err %d\n", errno);
+ return (-1);
+ }
+
+ printf("%s: tc->base %#p\n", __func__, tc->base);
+
+ return (0);
+}
+
+size_t
+hwt_get_offs(struct trace_context *tc, size_t *offs)
+{
+ struct hwt_bufptr_get bget;
+ vm_offset_t curpage_offset;
+ int curpage;
+ int error;
+ int ptr;
+
+ bget.pid = tc->pid;
+ bget.ptr = &ptr;
+ bget.curpage = &curpage;
+ bget.curpage_offset = &curpage_offset;
+ error = ioctl(tc->thr_fd, HWT_IOC_BUFPTR_GET, &bget);
+ if (error)
+ return (error);
+
+ printf("curpage %d curpage_offset %ld\n", curpage, curpage_offset);
+
+ *offs = curpage * PAGE_SIZE + curpage_offset;
+
+ return (0);
+}
+
+static int
+hwt_get_records(uint32_t *nrec)
+{
+ struct trace_context *tc;
+ int tot_records;
+ int nrecords;
+ int error;
+
+ tc = &tcs;
+
+ tot_records = 0;
+
+ error = hwt_record_fetch(tc, &nrecords);
+ if (error)
+ return (error);
+
+ tot_records += nrecords;
+
+ *nrec = tot_records;
+
+ return (0);
+}
+
+int
+main(int argc __unused, char **argv, char **env)
+{
+ struct hwt_record_user_entry *entry;
+ struct pmcstat_process *pp;
+ struct trace_context *tc;
+ struct hwt_start s;
+ uint32_t tot_rec;
+ uint32_t nrec;
+ uint32_t nlibs;
+ char **cmd;
+ int error;
+ int fd;
+ int sockpair[NSOCKPAIRFD];
+ int pid;
+ size_t bufsize;
+
+ cmd = argv + 1;
+
+ tc = &tcs;
+
+ error = hwt_elf_count_libs(*cmd, &nlibs);
+ if (error != 0) {
+ printf("could not count libs\n");
+ return (error);
+ }
+
+ nlibs += 1; /* add binary itself. */
+
+ ncpu = sysconf(_SC_NPROCESSORS_CONF);
+
+ printf("cmd is %s, nlibs %d\n", *cmd, nlibs);
+
+ fd = open("/dev/hwt", O_RDWR);
+ if (fd < 0) {
+ printf("Can't open /dev/hwt\n");
+ return (-1);
+ }
+
+ error = hwt_process_create(sockpair, cmd, env, &pid);
+ if (error != 0)
+ return (error);
+
+ printf("%s: process pid %d created\n", __func__, pid);
+
+ pp = hwt_process_alloc();
+ pp->pp_pid = pid;
+ pp->pp_isactive = 1;
+
+ bufsize = 16 * 1024 * 1024;
+
+ tc->pp = pp;
+ tc->pid = pid;
+ tc->fd = fd;
+
+ tc->bufsize = bufsize;
+
+ error = hwt_ctx_alloc(fd);
+ if (error) {
+ printf("%s: failed to alloc ctx, pid %d error %d\n", __func__,
+ tc->pid, error);
+
+ while (1);
+
+ return (error);
+ }
+
+ error = hwt_get_records(&nrec);
+ if (error != 0)
+ return (error);
+
+ if (nrec != 1)
+ return (error);
+
+ entry = &tc->records[0];
+
+ error = hwt_map_memory(tc, entry->tid);
+ if (error != 0) {
+ printf("can't map memory");
+ return (error);
+ }
+
+ printf("starting tracing\n");
+
+ s.pid = tc->pid;
+ error = ioctl(fd, HWT_IOC_START, &s);
+ if (error) {
+ printf("%s: failed to start tracing, error %d\n", __func__,
+ error);
+ return (error);
+ }
+
+ error = hwt_process_start(sockpair);
+ if (error != 0)
+ return (error);
+
+ printf("nlibs %d\n", nlibs);
+
+ tot_rec = 0;
+
+ do {
+ error = hwt_get_records(&nrec);
+ if (error != 0)
+ return (error);
+ tot_rec += nrec;
+ } while (tot_rec < nlibs);
+
+ hwt_coresight_process(tc);
+
+ close(fd);
+
+ return (0);
+}
Index: usr.sbin/hwt/hwt_coresight.h
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwt_coresight.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _HWT_CORESIGHT_H_
+#define _HWT_CORESIGHT_H_
+
+int hwt_coresight_init(struct trace_context *tc);
+int hwt_coresight_process(struct trace_context *tcs);
+
+#endif /* !_HWT_CORESIGHT_H_ */
Index: usr.sbin/hwt/hwt_coresight.c
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwt_coresight.c
@@ -0,0 +1,616 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* ARM CoreSight tracing unit. */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/errno.h>
+#include <sys/hwt.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <opencsd/c_api/ocsd_c_api_types.h>
+#include <opencsd/c_api/opencsd_c_api.h>
+
+#include "hwtvar.h"
+#include "hwt_coresight.h"
+
+#include "libpmcstat_stubs.h"
+#include <libpmcstat.h>
+
+#define PMCTRACE_CS_DEBUG
+#undef PMCTRACE_CS_DEBUG
+
+#ifdef PMCTRACE_CS_DEBUG
+#define dprintf(fmt, ...) printf(fmt, ##__VA_ARGS__)
+#else
+#define dprintf(fmt, ...)
+#endif
+
+static dcd_tree_handle_t dcdtree_handle;
+static int cs_flags = 0;
+#define FLAG_FORMAT (1 << 0)
+#define FLAG_FRAME_RAW_UNPACKED (1 << 1)
+#define FLAG_FRAME_RAW_PACKED (1 << 2)
+#define FLAG_CALLBACK_MEM_ACC (1 << 3)
+
+#define PACKET_STR_LEN 1024
+static char packet_str[PACKET_STR_LEN];
+
+static ocsd_err_t
+attach_raw_printers(dcd_tree_handle_t dcd_tree_h)
+{
+ ocsd_err_t err;
+ int flags;
+
+ flags = 0;
+ err = OCSD_OK;
+
+ if (cs_flags & FLAG_FRAME_RAW_UNPACKED)
+ flags |= OCSD_DFRMTR_UNPACKED_RAW_OUT;
+
+ if (cs_flags & FLAG_FRAME_RAW_PACKED)
+ flags |= OCSD_DFRMTR_PACKED_RAW_OUT;
+
+ if (flags)
+ err = ocsd_dt_set_raw_frame_printer(dcd_tree_h, flags);
+
+ return err;
+}
+
+static int
+print_data_array(const uint8_t *p_array, const int array_size,
+ char *p_buffer, int buf_size)
+{
+ int bytes_processed;
+ int chars_printed;
+
+ chars_printed = 0;
+ p_buffer[0] = 0;
+
+ if (buf_size > 9) {
+ strcat(p_buffer, "[ ");
+ chars_printed += 2;
+
+ for (bytes_processed = 0; bytes_processed < array_size;
+ bytes_processed++) {
+ sprintf(p_buffer + chars_printed, "0x%02X ",
+ p_array[bytes_processed]);
+ chars_printed += 5;
+ if ((chars_printed + 5) > buf_size)
+ break;
+ }
+
+ strcat(p_buffer, "];");
+ chars_printed += 2;
+ } else if (buf_size >= 4) {
+ sprintf(p_buffer, "[];");
+ chars_printed += 3;
+ }
+
+ return (chars_printed);
+}
+
+static void
+packet_monitor(void *context __unused,
+ const ocsd_datapath_op_t op,
+ const ocsd_trc_index_t index_sop,
+ const void *p_packet_in,
+ const uint32_t size,
+ const uint8_t *p_data)
+{
+ int offset;
+
+ offset = 0;
+
+ switch (op) {
+ case OCSD_OP_DATA:
+ sprintf(packet_str, "Idx:%" OCSD_TRC_IDX_STR ";", index_sop);
+ offset = strlen(packet_str);
+ offset += print_data_array(p_data, size, packet_str + offset,
+ PACKET_STR_LEN - offset);
+
+ /*
+ * Got a packet -- convert to string and use the libraries'
+ * message output to print to file and stdoout
+ */
+
+ if (ocsd_pkt_str(OCSD_PROTOCOL_ETMV4I, p_packet_in,
+ packet_str + offset, PACKET_STR_LEN - offset) == OCSD_OK) {
+ /* add in <CR> */
+ if (strlen(packet_str) == PACKET_STR_LEN - 1)/*maxlen*/
+ packet_str[PACKET_STR_LEN - 2] = '\n';
+ else
+ strcat(packet_str,"\n");
+
+ /* print it using the library output logger. */
+ ocsd_def_errlog_msgout(packet_str);
+ }
+ break;
+
+ case OCSD_OP_EOT:
+ sprintf(packet_str,"**** END OF TRACE ****\n");
+ ocsd_def_errlog_msgout(packet_str);
+ break;
+ default:
+ printf("%s: unknown op %d\n", __func__, op);
+ break;
+ }
+}
+
+#if 0
+static uint32_t
+cs_decoder__mem_access(const void *context __unused,
+ const ocsd_vaddr_t address __unused,
+ const ocsd_mem_space_acc_t mem_space __unused,
+ const uint32_t req_size __unused, uint8_t *buffer __unused)
+{
+
+ /* TODO */
+
+ return (0);
+}
+#endif
+
+static ocsd_err_t
+create_test_memory_acc(dcd_tree_handle_t handle, struct trace_context *tc)
+{
+ ocsd_vaddr_t address;
+ uint8_t *p_mem_buffer;
+ uint32_t mem_length;
+ int ret;
+
+ dprintf("%s\n", __func__);
+
+#if 0
+ if (cs_flags & FLAG_CALLBACK_MEM_ACC)
+ ret = ocsd_dt_add_callback_mem_acc(handle, base + start,
+ base + end - 1, OCSD_MEM_SPACE_ANY,
+ cs_decoder__mem_access, NULL);
+ else
+#endif
+ {
+ address = (ocsd_vaddr_t)tc->base;
+
+ uint64_t *t;
+ t = (uint64_t *)tc->base;
+ printf("%lx %lx %lx %lx\n", t[0], t[1], t[2], t[3]);
+
+ p_mem_buffer = (uint8_t *)tc->base;
+ mem_length = tc->bufsize;
+
+ ret = ocsd_dt_add_buffer_mem_acc(handle, address,
+ OCSD_MEM_SPACE_ANY, p_mem_buffer, mem_length);
+ }
+
+ if (ret != OCSD_OK)
+ printf("%s: can't create memory accessor: ret %d\n",
+ __func__, ret);
+
+ return (ret);
+}
+
+static ocsd_err_t
+create_generic_decoder(dcd_tree_handle_t handle, const char *p_name,
+ const void *p_cfg, const void *p_context __unused,
+ struct trace_context *tc)
+{
+ ocsd_err_t ret;
+ uint8_t CSID;
+
+ CSID = 0;
+
+ dprintf("%s\n", __func__);
+
+ ret = ocsd_dt_create_decoder(handle, p_name,
+ OCSD_CREATE_FLG_FULL_DECODER, p_cfg, &CSID);
+ if (ret != OCSD_OK)
+ return (-1);
+
+ printf("%s: CSID %d\n", __func__, CSID);
+
+ if (cs_flags & FLAG_FORMAT) {
+ ret = ocsd_dt_attach_packet_callback(handle, CSID,
+ OCSD_C_API_CB_PKT_MON, packet_monitor, p_context);
+ if (ret != OCSD_OK)
+ return (-1);
+ }
+
+ /* attach a memory accessor */
+ ret = create_test_memory_acc(handle, tc);
+ if (ret != OCSD_OK)
+ ocsd_dt_remove_decoder(handle, CSID);
+
+ return (ret);
+}
+
+static ocsd_err_t
+create_decoder_etmv4(dcd_tree_handle_t dcd_tree_h, struct trace_context *tc)
+{
+ ocsd_etmv4_cfg trace_config;
+ ocsd_err_t ret;
+
+ trace_config.arch_ver = ARCH_V8;
+ trace_config.core_prof = profile_CortexA;
+
+ trace_config.reg_configr = 0x00001fc6;
+ trace_config.reg_configr = 0x000000C1;
+ trace_config.reg_traceidr = 0x00000001; /* Trace ID */
+
+ trace_config.reg_idr0 = 0x28000ea1;
+ trace_config.reg_idr1 = 0x4100f424;
+ trace_config.reg_idr2 = 0x20001088;
+ trace_config.reg_idr8 = 0x0;
+ trace_config.reg_idr9 = 0x0;
+ trace_config.reg_idr10 = 0x0;
+ trace_config.reg_idr11 = 0x0;
+ trace_config.reg_idr12 = 0x0;
+ trace_config.reg_idr13 = 0x0;
+
+ /* Instruction decoder. */
+ ret = create_generic_decoder(dcd_tree_h, OCSD_BUILTIN_DCD_ETMV4I,
+ (void *)&trace_config, 0, tc);
+
+ return (ret);
+}
+
+static int
+cs_process_chunk(struct trace_context *tc, size_t start, size_t end)
+{
+ uint32_t bytes_done;
+ uint8_t *p_block;
+ uint32_t bytes_this_time;
+ int block_index;
+ size_t block_size;
+ int dp_ret;
+ int ret;
+
+ dprintf("%s: tc->base %#p\n", __func__, tc->base);
+
+ bytes_this_time = 0;
+ block_index = start;
+ bytes_done = 0;
+ block_size = end - start;
+ p_block = (uint8_t *)((uintptr_t)tc->base + start);
+
+ ret = OCSD_OK;
+ dp_ret = OCSD_RESP_CONT;
+
+ while (bytes_done < (uint32_t)block_size && (ret == OCSD_OK)) {
+
+ if (OCSD_DATA_RESP_IS_CONT(dp_ret)) {
+ dprintf("process data, block_size %ld, bytes_done %d\n",
+ block_size, bytes_done);
+ dp_ret = ocsd_dt_process_data(dcdtree_handle,
+ OCSD_OP_DATA,
+ block_index + bytes_done,
+ block_size - bytes_done,
+ ((uint8_t *)p_block) + bytes_done,
+ &bytes_this_time);
+ bytes_done += bytes_this_time;
+ dprintf("BYTES DONE %d\n", bytes_done);
+ if (OCSD_DATA_RESP_IS_WAIT(dp_ret)) {
+printf("wait");
+ exit(12);
+ }
+
+ } else if (OCSD_DATA_RESP_IS_WAIT(dp_ret)) {
+printf("WAIT");
+exit(5);
+ dp_ret = ocsd_dt_process_data(dcdtree_handle,
+ OCSD_OP_FLUSH, 0, 0, NULL, NULL);
+ } else {
+printf("FATAL");
+exit(6);
+ ret = OCSD_ERR_DATA_DECODE_FATAL;
+ }
+ }
+
+ //ocsd_dt_process_data(dcdtree_handle, OCSD_OP_EOT, 0, 0, NULL, NULL);
+
+ return (0);
+}
+
+struct pmcstat_pcmap *
+pmcstat_process_find_map(struct pmcstat_process *p, uintfptr_t pc)
+{
+ struct pmcstat_pcmap *ppm;
+
+ TAILQ_FOREACH(ppm, &p->pp_map, ppm_next) {
+ if (pc >= ppm->ppm_lowpc && pc < ppm->ppm_highpc)
+ return (ppm);
+ if (pc < ppm->ppm_lowpc)
+ return (NULL);
+ }
+
+ return (NULL);
+}
+
+static struct pmcstat_symbol *
+symbol_lookup(const struct trace_context *tc, uint64_t ip,
+ struct pmcstat_image **img, uint64_t *newpc0)
+{
+ struct pmcstat_image *image;
+ struct pmcstat_symbol *sym;
+ struct pmcstat_pcmap *map;
+ uint64_t newpc;
+
+ map = pmcstat_process_find_map(tc->pp, ip);
+ if (map != NULL) {
+ image = map->ppm_image;
+ newpc = ip - ((unsigned long)map->ppm_lowpc +
+ (image->pi_vaddr - image->pi_start));
+ sym = pmcstat_symbol_search(image, newpc); /* Could be NULL. */
+ newpc += image->pi_vaddr;
+
+ *img = image;
+ *newpc0 = newpc;
+
+ return (sym);
+ } else
+ *img = NULL;
+
+ return (NULL);
+}
+
+
+static ocsd_datapath_resp_t
+gen_trace_elem_print_lookup(const void *p_context,
+ const ocsd_trc_index_t index_sop __unused,
+ const uint8_t trc_chan_id __unused,
+ const ocsd_generic_trace_elem *elem)
+{
+ const struct trace_context *tc;
+ struct pmcstat_image *image;
+ ocsd_datapath_resp_t resp;
+ struct pmcstat_symbol *sym;
+ unsigned long offset;
+ uint64_t newpc;
+ uint64_t ip;
+
+ tc = (const struct trace_context *)p_context;
+
+ resp = OCSD_RESP_CONT;
+
+#if 0
+ dprintf("%s: Idx:%d ELEM TYPE %d, st_addr %lx, en_addr %lx\n",
+ __func__, index_sop, elem->elem_type,
+ elem->st_addr, elem->en_addr);
+#endif
+
+#if 0
+ if (elem->st_addr == -1)
+ return (resp);
+#endif
+
+ if (elem->st_addr == 0)
+ return (resp);
+ ip = elem->st_addr;
+
+ sym = symbol_lookup(tc, ip, &image, &newpc);
+
+ static const char *ARMv8Excep[] = {
+ "PE Reset", "Debug Halt", "Call", "Trap",
+ "System Error", "Reserved", "Inst Debug", "Data Debug",
+ "Reserved", "Reserved", "Alignment", "Inst Fault",
+ "Data Fault", "Reserved", "IRQ", "FIQ"
+ };
+
+ switch (elem->elem_type) {
+ case OCSD_GEN_TRC_ELEM_UNKNOWN:
+ printf("Unknown packet.\n");
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_NO_SYNC:
+ printf("No sync.\n");
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_TRACE_ON:
+ printf("Trace on.\n");
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_EO_TRACE:
+ printf("End of Trace.\n");
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_PE_CONTEXT:
+ break;
+ case OCSD_GEN_TRC_ELEM_INSTR_RANGE:
+ case OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH:
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_ADDR_NACC:
+ break;
+ case OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN:
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_EXCEPTION:
+ printf("Exception #%d (%s)\n", elem->exception_number,
+ ARMv8Excep[elem->exception_number]);
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_EXCEPTION_RET:
+ printf("Exception RET to %lx\n", elem->st_addr);
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_TIMESTAMP:
+ printf("Timestamp: %lx\n", elem->timestamp);
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_CYCLE_COUNT:
+ printf("Cycle count: %d\n", elem->cycle_count);
+ return (resp);
+ case OCSD_GEN_TRC_ELEM_EVENT:
+ case OCSD_GEN_TRC_ELEM_SWTRACE:
+ case OCSD_GEN_TRC_ELEM_SYNC_MARKER:
+ case OCSD_GEN_TRC_ELEM_MEMTRANS:
+ case OCSD_GEN_TRC_ELEM_INSTRUMENTATION:
+ case OCSD_GEN_TRC_ELEM_CUSTOM:
+ return (resp);
+ };
+
+#if 0
+ char ts[100];
+
+ if (elem->timestamp != 0)
+ sprintf(ts, "ts %ld", elem->timestamp);
+ else
+ sprintf(ts, " ");
+#endif
+
+ if (sym) {
+ offset = newpc - (sym->ps_start + image->pi_vaddr);
+
+ printf("pc 0x%08lx (%lx)\t%12s\t%s+0x%lx\n", //elem->elem_type,
+ ip, newpc,
+ pmcstat_string_unintern(image->pi_name),
+ pmcstat_string_unintern(sym->ps_name), offset);
+ } else
+ if (image)
+ printf("pc 0x%08lx (%lx)\t%12s\n", //elem->elem_type,
+ ip, newpc,
+ pmcstat_string_unintern(image->pi_name));
+ else {
+ /* image not found. */
+ }
+
+ return (resp);
+}
+
+int
+hwt_coresight_init(struct trace_context *tc)
+{
+ int error;
+
+ ocsd_def_errlog_init(OCSD_ERR_SEV_INFO, 1);
+
+ dcdtree_handle = ocsd_create_dcd_tree(OCSD_TRC_SRC_FRAME_FORMATTED,
+ OCSD_DFRMTR_FRAME_MEM_ALIGN);
+ if (dcdtree_handle == C_API_INVALID_TREE_HANDLE) {
+ printf("can't find dcd tree\n");
+ return (-1);
+ }
+
+ //cs_flags |= FLAG_FORMAT;
+ //cs_flags |= FLAG_FRAME_RAW_UNPACKED;
+ //cs_flags |= FLAG_FRAME_RAW_PACKED;
+
+ error = create_decoder_etmv4(dcdtree_handle, tc);
+ if (error != OCSD_OK) {
+ printf("can't create decoder: tc->base %#p\n", tc->base);
+ return (-2);
+ }
+
+#ifdef PMCTRACE_CS_DEBUG
+ ocsd_tl_log_mapped_mem_ranges(dcdtree_handle);
+#endif
+
+ if (cs_flags & FLAG_FORMAT)
+ ocsd_dt_set_gen_elem_printer(dcdtree_handle);
+ else
+ ocsd_dt_set_gen_elem_outfn(dcdtree_handle,
+ gen_trace_elem_print_lookup, tc);
+
+ attach_raw_printers(dcdtree_handle);
+
+ return (0);
+}
+
+int
+hwt_coresight_process(struct trace_context *tc)
+{
+ size_t start;
+ size_t end;
+ size_t offs;
+ int error;
+
+ /* Coresight data is always on CPU0 due to funnelling by HW. */
+
+ hwt_coresight_init(tc);
+
+ error = hwt_get_offs(tc, &offs);
+printf("OFFS %ld\n", offs);
+ if (error)
+ return (-1);
+
+ printf("data to process %ld\n", offs);
+
+ start = 0;
+ end = offs;
+
+ cs_process_chunk(tc, start, end);
+
+ int t;
+
+ t = 0;
+
+ while (1) {
+ hwt_sleep();
+
+ if (tc->terminate && t++ > 2)
+ break;
+
+ error = hwt_get_offs(tc, &offs);
+printf("OFFS %ld, err %d\n", offs, error);
+ if (error)
+ return (-1);
+
+ if (offs == end) {
+ /* No new entries in trace. */
+ hwt_sleep();
+ continue;
+ }
+
+ if (offs > end) {
+ /* New entries in the trace buffer. */
+ start = end;
+ end = offs;
+ cs_process_chunk(tc, start, end);
+ hwt_sleep();
+ continue;
+ }
+
+ if (offs < end) {
+ /* New entries in the trace buffer. Buffer wrapped. */
+ start = end;
+ end = tc->bufsize;
+ cs_process_chunk(tc, start, end);
+
+ start = 0;
+ end = offs;
+ cs_process_chunk(tc, start, end);
+
+ hwt_sleep();
+ }
+ }
+
+ return (0);
+}
Index: usr.sbin/hwt/hwt_elf.c
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwt_elf.c
@@ -0,0 +1,135 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/hwt.h>
+
+#include <assert.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "hwtvar.h"
+
+int
+hwt_elf_count_libs(const char *elf_path, uint32_t *nlibs0)
+{
+ GElf_Shdr shdr;
+ GElf_Phdr ph;
+ GElf_Ehdr eh;
+ Elf_Scn *scn;
+ Elf *elf;
+ size_t sh_entsize;
+ Elf_Data *data;
+ GElf_Dyn dyn;
+ int is_dynamic;
+ uint32_t nlibs;
+ int fd;
+ size_t i;
+
+ nlibs = 0;
+
+ assert(elf_version(EV_CURRENT) != EV_NONE);
+
+ fd = open(elf_path, O_RDONLY, 0);
+
+ assert(fd >= 0);
+
+ elf = elf_begin(fd, ELF_C_READ, NULL);
+
+ assert(elf != NULL);
+ assert(elf_kind(elf) == ELF_K_ELF);
+
+ if (gelf_getehdr(elf, &eh) != &eh) {
+ printf("could not find elf header\n");
+ return (-1);
+ }
+
+ if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN) {
+ printf("unsupported image\n");
+ return (-2);
+ }
+
+ if (eh.e_ident[EI_CLASS] != ELFCLASS32 &&
+ eh.e_ident[EI_CLASS] != ELFCLASS64)
+ return (-3);
+
+ is_dynamic = 0;
+
+ for (i = 0; i < eh.e_phnum; i++) {
+ if (gelf_getphdr(elf, i, &ph) != &ph) {
+ printf("could not get program header %zu\n", i);
+ return (-4);
+ }
+ switch (ph.p_type) {
+ case PT_DYNAMIC:
+ is_dynamic = 1;
+ break;
+ case PT_INTERP:
+ nlibs++;
+ break;
+ }
+ }
+
+ if (!is_dynamic)
+ goto done;
+
+ scn = NULL;
+ data = NULL;
+
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
+ assert(gelf_getshdr(scn, &shdr) == &shdr);
+
+ if (shdr.sh_type == SHT_DYNAMIC) {
+ data = elf_getdata(scn, data);
+ assert(data != NULL);
+
+ sh_entsize = gelf_fsize(elf, ELF_T_DYN, 1, EV_CURRENT);
+
+ for (i = 0; i < shdr.sh_size / sh_entsize; i++) {
+ assert(gelf_getdyn(data, i, &dyn) == &dyn);
+ if (dyn.d_tag == DT_NEEDED)
+ nlibs++;
+ }
+ }
+ }
+
+done:
+ assert(elf_end(elf) == 0);
+ assert(close(fd) == 0);
+
+ *nlibs0 = nlibs;
+
+ return (0);
+}
Index: usr.sbin/hwt/hwt_process.c
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwt_process.c
@@ -0,0 +1,140 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/errno.h>
+#include <sys/wait.h>
+#include <sys/hwt.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sysexits.h>
+#include <string.h>
+
+#include "hwtvar.h"
+
+#include "libpmcstat_stubs.h"
+#include <libpmcstat.h>
+
+struct pmcstat_image_hash_list pmcstat_image_hash[PMCSTAT_NHASH];
+
+int
+hwt_process_start(int *sockpair)
+{
+ int error;
+
+ error = write(sockpair[PARENTSOCKET], "!", 1);
+ if (error != 1)
+ return (-1);
+
+ return (0);
+}
+
+static void
+hwt_process_onsig(int signo)
+{
+ pid_t pid;
+ int status;
+
+ assert(signo == SIGCHLD);
+
+ while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
+ if (WIFEXITED(status))
+ hwt_procexit(pid, WEXITSTATUS(status));
+}
+
+int
+hwt_process_create(int *sockpair, char **cmd, char **env __unused, int *pid0)
+{
+ char token;
+ pid_t pid;
+ int error;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockpair) < 0)
+ return (-1);
+
+ signal(SIGCHLD, hwt_process_onsig);
+
+ pid = fork();
+
+ switch (pid) {
+ case -1:
+ return (-1);
+ case 0:
+ /* Child */
+ close(sockpair[PARENTSOCKET]);
+
+ error = write(sockpair[CHILDSOCKET], "+", 1);
+ if (error != 1)
+ return (-1);
+
+ error = read(sockpair[CHILDSOCKET], &token, 1);
+ if (error < 0)
+ return (-2);
+
+ if (token != '!')
+ return (-3);
+
+ close(sockpair[CHILDSOCKET]);
+
+ execvp(cmd[0], cmd);
+
+ kill(getppid(), SIGCHLD);
+
+ exit(-3);
+ default:
+ /* Parent */
+ close(sockpair[CHILDSOCKET]);
+ break;
+ }
+
+ *pid0 = pid;
+
+ return (0);
+}
+
+struct pmcstat_process *
+hwt_process_alloc(void)
+{
+ struct pmcstat_process *pp;
+
+ pp = malloc(sizeof(struct pmcstat_process));
+ if (pp)
+ TAILQ_INIT(&pp->pp_map);
+
+ return (pp);
+}
Index: usr.sbin/hwt/hwt_record.c
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwt_record.c
@@ -0,0 +1,117 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/errno.h>
+#include <sys/hwt.h>
+#include <sys/hwt_record.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+#include "hwtvar.h"
+
+#include "libpmcstat_stubs.h"
+#include <libpmcstat.h>
+
+int
+hwt_record_fetch(struct trace_context *tc, int *nrecords)
+{
+ struct hwt_record_user_entry *entry;
+ pmcstat_interned_string path;
+ struct pmcstat_image *image;
+ struct pmc_plugins plugins;
+ struct pmcstat_args args;
+ unsigned long addr;
+ struct hwt_record_get record_get;
+ int nentries;
+ int error;
+ int j;
+
+ memset(&plugins, 0, sizeof(struct pmc_plugins));
+ memset(&args, 0, sizeof(struct pmcstat_args));
+ args.pa_fsroot = "/";
+ nentries = 256;
+
+ tc->records = malloc(sizeof(struct hwt_record_user_entry) * nentries);
+
+ record_get.pid = tc->pid;
+ record_get.records = tc->records;
+ record_get.nentries = &nentries;
+
+ error = ioctl(tc->fd, HWT_IOC_RECORD_GET, &record_get);
+ if (error != 0) {
+ printf("RECORD_GET error %d entires %d\n",
+ error, nentries);
+ return (error);
+ }
+
+ for (j = 0; j < nentries; j++) {
+ entry = &tc->records[j];
+
+ if (entry->record_type > 3) {
+ continue;
+ }
+
+ printf(" lib #%d: path %s addr %lx size %lx\n", j,
+ entry->fullpath,
+ (unsigned long)entry->addr,
+ entry->size);
+
+ path = pmcstat_string_intern(entry->fullpath);
+ if ((image = pmcstat_image_from_path(path, 0,
+ &args, &plugins)) == NULL)
+ return (-1);
+
+ if (image->pi_type == PMCSTAT_IMAGE_UNKNOWN)
+ pmcstat_image_determine_type(image, &args);
+
+ addr = (unsigned long)entry->addr & ~1;
+ addr -= (image->pi_start - image->pi_vaddr);
+ pmcstat_image_link(tc->pp, image, addr);
+#if 0
+ printf("image pi_vaddr %lx pi_start %lx pi_entry %lx\n",
+ (unsigned long)image->pi_vaddr,
+ (unsigned long)image->pi_start,
+ (unsigned long)image->pi_entry);
+#endif
+ }
+
+ *nrecords = nentries;
+
+ return (0);
+}
Index: usr.sbin/hwt/hwtvar.h
===================================================================
--- /dev/null
+++ usr.sbin/hwt/hwtvar.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ * All rights reserved.
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _HWTVAR_H_
+#define _HWTVAR_H_
+
+struct trace_context {
+ struct pmcstat_process *pp;
+ struct hwt_record_user_entry *records;
+ void *base;
+ int bufsize;
+ int pid;
+ int fd;
+ int thr_fd;
+ int terminate;
+};
+
+struct pmcstat_process *hwt_process_alloc(void);
+int hwt_process_create(int *sockpair, char **cmd, char **env, int *pid0);
+int hwt_process_start(int *sockpair);
+int hwt_record_fetch(struct trace_context *tc, int *nrecords);
+void hwt_procexit(pid_t pid, int status);
+size_t hwt_get_offs(struct trace_context *tc, size_t *offs);
+void hwt_sleep(void);
+int hwt_elf_count_libs(const char *elf_path, uint32_t *nlibs0);
+
+#endif /* !_HWTVAR_H_ */
Index: usr.sbin/hwt/libpmcstat_stubs.h
===================================================================
--- /dev/null
+++ usr.sbin/hwt/libpmcstat_stubs.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <machine/profile.h>
+
+/* These are stubs, needed for compilation only. */
+
+#ifndef _HWT_LIBPMCSTAT_STUBS_H_
+#define _HWT_LIBPMCSTAT_STUBS_H_
+
+enum pmc_mode {
+ PMC_MODE_INVALID,
+};
+
+typedef int pmc_id_t;
+typedef int pmc_value_t;
+
+struct pmclog_ev;
+
+int pmclog_read(void *cookie __unused, struct pmclog_ev *ev __unused);
+int pmc_close_logfile(void);
+int pmc_attach(pmc_id_t pmc __unused, pid_t pid __unused);
+
+#endif /* !_HWT_LIBPMCSTAT_STUBS_H_ */
Index: usr.sbin/hwt/libpmcstat_stubs.c
===================================================================
--- /dev/null
+++ usr.sbin/hwt/libpmcstat_stubs.c
@@ -0,0 +1,58 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2023 Ruslan Bukin <br@bsdpad.com>
+ *
+ * This work was supported by Innovate UK project 105694, "Digital Security
+ * by Design (DSbD) Technology Platform Prototype".
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libpmcstat_stubs.h"
+#include <libpmcstat.h>
+
+/* This is a stub file, needed for compilation only. */
+
+struct pmcstat_pmcs pmcstat_pmcs;
+struct pmcstat_process_hash_list pmcstat_process_hash[PMCSTAT_NHASH];
+
+int
+pmclog_read(void *cookie __unused, struct pmclog_ev *ev __unused)
+{
+
+ return (-1);
+}
+
+int
+pmc_close_logfile(void)
+{
+
+ return (-1);
+}
+
+int
+pmc_attach(pmc_id_t pmc __unused, pid_t pid __unused)
+{
+
+ return (-1);
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 12, 10:18 AM (6 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17117762
Default Alt Text
D40728.id123691.diff (40 KB)

Event Timeline