tools/testing/selftests/powerpc/ptrace/ptrace-perf-hwbreak.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/ptrace/ptrace-perf-hwbreak.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/ptrace/ptrace-perf-hwbreak.c
Extension
.c
Size
15071 bytes
Lines
446
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0+

#include <asm/unistd.h>
#include <linux/hw_breakpoint.h>
#include <linux/ptrace.h>
#include <memory.h>
#include <stdlib.h>
#include <sys/wait.h>

#include "utils.h"

/*
 * Child subroutine that performs a load on the address, then traps
 */
void same_watch_addr_child(unsigned long *addr);

/* Address of the ld instruction in same_watch_addr_child() */
extern char same_watch_addr_load[];

/* Address of the end trap instruction in same_watch_addr_child() */
extern char same_watch_addr_trap[];

/*
 * Child subroutine that performs a load on the first address, then a load on
 * the second address (with no instructions separating this from the first
 * load), then traps.
 */
void perf_then_ptrace_child(unsigned long *first_addr, unsigned long *second_addr);

/* Address of the first ld instruction in perf_then_ptrace_child() */
extern char perf_then_ptrace_load1[];

/* Address of the second ld instruction in perf_then_ptrace_child() */
extern char perf_then_ptrace_load2[];

/* Address of the end trap instruction in perf_then_ptrace_child() */
extern char perf_then_ptrace_trap[];

static inline long sys_ptrace(long request, pid_t pid, unsigned long addr, unsigned long data)
{
	return syscall(__NR_ptrace, request, pid, addr, data);
}

static long ptrace_traceme(void)
{
	return sys_ptrace(PTRACE_TRACEME, 0, 0, 0);
}

static long ptrace_getregs(pid_t pid, struct pt_regs *result)
{
	return sys_ptrace(PTRACE_GETREGS, pid, 0, (unsigned long)result);
}

static long ptrace_setregs(pid_t pid, struct pt_regs *result)
{
	return sys_ptrace(PTRACE_SETREGS, pid, 0, (unsigned long)result);
}

static long ptrace_cont(pid_t pid, long signal)
{
	return sys_ptrace(PTRACE_CONT, pid, 0, signal);
}

static long ptrace_singlestep(pid_t pid, long signal)
{
	return sys_ptrace(PTRACE_SINGLESTEP, pid, 0, signal);
}

static long ppc_ptrace_gethwdbginfo(pid_t pid, struct ppc_debug_info *dbginfo)
{
	return sys_ptrace(PPC_PTRACE_GETHWDBGINFO, pid, 0, (unsigned long)dbginfo);
}

static long ppc_ptrace_sethwdbg(pid_t pid, struct ppc_hw_breakpoint *bp_info)
{
	return sys_ptrace(PPC_PTRACE_SETHWDEBUG, pid, 0, (unsigned long)bp_info);
}

static long ppc_ptrace_delhwdbg(pid_t pid, int bp_id)
{
	return sys_ptrace(PPC_PTRACE_DELHWDEBUG, pid, 0L, bp_id);
}

static long ptrace_getreg_pc(pid_t pid, void **pc)
{
	struct pt_regs regs;
	long err;

	err = ptrace_getregs(pid, &regs);
	if (err)

Annotation

Implementation Notes