Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F112002120
D40728.id123691.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
40 KB
Referenced Files
None
Subscribers
None
D40728.id123691.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D40728: hwt(8) utility added
Attached
Detach File
Event Timeline
Log In to Comment