|
Packit |
0021fb |
/*
|
|
Packit |
0021fb |
* This file is part of ltrace.
|
|
Packit |
0021fb |
* Copyright (C) 2012,2013 Petr Machata, Red Hat Inc.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This program is free software; you can redistribute it and/or
|
|
Packit |
0021fb |
* modify it under the terms of the GNU General Public License as
|
|
Packit |
0021fb |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
0021fb |
* License, or (at your option) any later version.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
0021fb |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0021fb |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0021fb |
* General Public License for more details.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* You should have received a copy of the GNU General Public License
|
|
Packit |
0021fb |
* along with this program; if not, write to the Free Software
|
|
Packit |
0021fb |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
Packit |
0021fb |
* 02110-1301 USA
|
|
Packit |
0021fb |
*/
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
#ifndef BACKEND_H
|
|
Packit |
0021fb |
#define BACKEND_H
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
#include "forward.h"
|
|
Packit |
0021fb |
#include "sysdep.h"
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
#include <gelf.h>
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
enum process_status {
|
|
Packit |
0021fb |
PS_INVALID, /* Failure. */
|
|
Packit |
0021fb |
PS_STOP, /* Job-control stop. */
|
|
Packit |
0021fb |
PS_TRACING_STOP,
|
|
Packit |
0021fb |
PS_SLEEPING,
|
|
Packit |
0021fb |
PS_ZOMBIE,
|
|
Packit |
0021fb |
PS_OTHER, /* Necessary other states can be added as needed. */
|
|
Packit |
0021fb |
};
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/*
|
|
Packit |
0021fb |
* This file contains documentation of back end interface. Some of
|
|
Packit |
0021fb |
* these may be implemented on an OS level (i.e. they are the same
|
|
Packit |
0021fb |
* e.g. on all Linux architectures), some may differ per architecture
|
|
Packit |
0021fb |
* on the same OS (e.g. a way to insert a breakpoint into the process
|
|
Packit |
0021fb |
* image is a likely candidate).
|
|
Packit |
0021fb |
*/
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Convert a PID to a path to the corresponding binary. */
|
|
Packit |
0021fb |
char *pid2name(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Given a PID, find a leader of thread group. */
|
|
Packit |
0021fb |
pid_t process_leader(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Given a PID of leader thread, fill in PIDs of all the tasks. The
|
|
Packit |
0021fb |
* function will initialize the pointer *RET_TASKS to a
|
|
Packit |
0021fb |
* newly-allocated array, and will store number of elements in that
|
|
Packit |
0021fb |
* array to *RET_N. You have to free that buffer when you don't need
|
|
Packit |
0021fb |
* it anymore. */
|
|
Packit |
0021fb |
int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Answer whether the process PID is stopped. Returns 0 when not
|
|
Packit |
0021fb |
* stopped, 1 when stopped, or -1 when there was an error. */
|
|
Packit |
0021fb |
int process_stopped(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Answer a status of the task PID. See enum process_status. */
|
|
Packit |
0021fb |
enum process_status process_status(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Wait for PID to be ready for tracing. */
|
|
Packit |
0021fb |
int wait_for_proc(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Send a signal SIG to the task PID. */
|
|
Packit |
0021fb |
int task_kill(pid_t pid, int sig);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after PID is attached, but before it is continued. */
|
|
Packit |
0021fb |
void trace_set_options(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after ltrace forks. Should attach the newly created child,
|
|
Packit |
0021fb |
* in whose context this function is called. */
|
|
Packit |
0021fb |
void trace_me(void);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called when ltrace needs to attach to PID, such as when it attaches
|
|
Packit |
0021fb |
* to a running process, whose PID is given on the command line. */
|
|
Packit |
0021fb |
int trace_pid(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Stop tracing PID. */
|
|
Packit |
0021fb |
void untrace_pid(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The back end may need to store arbitrary data to a process. This
|
|
Packit |
0021fb |
* is a place where it can initialize PROC->arch_dep. XXX this should
|
|
Packit |
0021fb |
* be dropped in favor of arhc_process_init on pmachata/libs. */
|
|
Packit |
0021fb |
void get_arch_dep(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Return current instruction pointer of PROC.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* XXX note that the IP must fit into an arch pointer. This prevents
|
|
Packit |
0021fb |
* us to use 32-bit ltrace to trace 64-bit process, even on arches
|
|
Packit |
0021fb |
* that would otherwise support this. Above we have a definition of
|
|
Packit |
0021fb |
* arch_addr_t. This should be converted to an integral type and
|
|
Packit |
0021fb |
* used for target addresses throughout. */
|
|
Packit |
0021fb |
void *get_instruction_pointer(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Set instruction pointer of PROC to ADDR. XXX see above. */
|
|
Packit |
0021fb |
void set_instruction_pointer(struct process *proc, void *addr);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Return current stack pointer of PROC. XXX see above. */
|
|
Packit |
0021fb |
void *get_stack_pointer(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Find and return caller address, i.e. the address where the current
|
|
Packit |
0021fb |
* function returns. */
|
|
Packit |
0021fb |
void *get_return_addr(struct process *proc, void *stack_pointer);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Enable breakpoint SBP in process PROC. */
|
|
Packit |
0021fb |
void enable_breakpoint(struct process *proc, struct breakpoint *sbp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Disable breakpoint SBP in process PROC. */
|
|
Packit |
0021fb |
void disable_breakpoint(struct process *proc, struct breakpoint *sbp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Determine whether the event that we have just seen (and that is
|
|
Packit |
0021fb |
* recorded in STATUS) was a syscall. If it was, return 1. If it was
|
|
Packit |
0021fb |
* a return from syscall, return 2. In both cases, set *SYSNUM to the
|
|
Packit |
0021fb |
* number of said syscall. If it wasn't a syscall, return 0. If
|
|
Packit |
0021fb |
* there was an error, return -1. */
|
|
Packit |
0021fb |
int syscall_p(struct process *proc, int status, int *sysnum);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Continue execution of the process with given PID. */
|
|
Packit |
0021fb |
void continue_process(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after we received a signal SIGNUM. Should do whatever
|
|
Packit |
0021fb |
* book-keeping is necessary and continue the process if
|
|
Packit |
0021fb |
* necessary. */
|
|
Packit |
0021fb |
void continue_after_signal(pid_t pid, int signum);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after we received a system call SYSNUM. RET_P is 0 if this
|
|
Packit |
0021fb |
* is system call, otherwise it's return from a system call. The
|
|
Packit |
0021fb |
* callback should do whatever book-keeping is necessary and continue
|
|
Packit |
0021fb |
* the process if necessary. */
|
|
Packit |
0021fb |
void continue_after_syscall(struct process *proc, int sysnum, int ret_p);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after we hit a breakpoint SBP. Should do whatever
|
|
Packit |
0021fb |
* book-keeping is necessary and then continue the process. */
|
|
Packit |
0021fb |
void continue_after_breakpoint(struct process *proc, struct breakpoint *sbp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after we received a vfork. Should do whatever book-keeping
|
|
Packit |
0021fb |
* is necessary and continue the process if necessary. N.B. right
|
|
Packit |
0021fb |
* now, with Linux/GNU the only back end, this is not necessary. I
|
|
Packit |
0021fb |
* imagine other systems may be different. */
|
|
Packit |
0021fb |
void continue_after_vfork(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called after the process exec's. Should do whatever book-keeping
|
|
Packit |
0021fb |
* is necessary and then continue the process. */
|
|
Packit |
0021fb |
void continue_after_exec(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called when trace_me or primary trace_pid fail. This may plug in
|
|
Packit |
0021fb |
* any platform-specific knowledge of why it could be so. */
|
|
Packit |
0021fb |
void trace_fail_warning(pid_t pid);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* A pair of functions called to initiate a detachment request when
|
|
Packit |
0021fb |
* ltrace is about to exit. Their job is to undo any effects that
|
|
Packit |
0021fb |
* tracing had and eventually detach process, perhaps by way of
|
|
Packit |
0021fb |
* installing a process handler.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* OS_LTRACE_EXITING_SIGHANDLER is called from a signal handler
|
|
Packit |
0021fb |
* context right after the signal was captured. It returns 1 if the
|
|
Packit |
0021fb |
* request was handled or 0 if it wasn't.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* If the call to OS_LTRACE_EXITING_SIGHANDLER didn't handle the
|
|
Packit |
0021fb |
* request, OS_LTRACE_EXITING is called when the next event is
|
|
Packit |
0021fb |
* generated. Therefore it's called in "safe" context, without
|
|
Packit |
0021fb |
* re-entrancy concerns, but it's only called after an even is
|
|
Packit |
0021fb |
* generated. */
|
|
Packit |
0021fb |
int os_ltrace_exiting_sighandler(void);
|
|
Packit |
0021fb |
void os_ltrace_exiting(void);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Should copy COUNT bytes from address ADDR of process PROC to local
|
|
Packit |
0021fb |
* buffer BUF. */
|
|
Packit |
0021fb |
size_t umovebytes(struct process *proc, void *addr, void *buf, size_t count);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Find out an address of symbol SYM in process PROC, and return.
|
|
Packit |
0021fb |
* Returning NULL delays breakpoint insertion and enables heaps of
|
|
Packit |
0021fb |
* arch-specific black magic that we should clean up some day.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* XXX the same points as for get_instruction_pointer apply. */
|
|
Packit |
0021fb |
void *sym2addr(struct process *proc, struct library_symbol *sym);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Obtain address of PLT entry corresponding to relocation RELA in
|
|
Packit |
0021fb |
* file LTE. This is NDX-th PLT entry in the file.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* XXX should this return arch_addr_t? */
|
|
Packit |
0021fb |
GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called at some point after we have attached to PROC. This callback
|
|
Packit |
0021fb |
* should insert an introspection breakpoint for handling dynamic
|
|
Packit |
0021fb |
* linker library loads. */
|
|
Packit |
0021fb |
int linkmap_init(struct process *proc, arch_addr_t dyn_addr);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This should produce and return the next event of one of the traced
|
|
Packit |
0021fb |
* processes. The returned pointer will not be freed by the core and
|
|
Packit |
0021fb |
* should be either statically allocated, or the management should be
|
|
Packit |
0021fb |
* done some other way. */
|
|
Packit |
0021fb |
struct Event *next_event(void);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Called when process PROC was removed. */
|
|
Packit |
0021fb |
void process_removed(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This should extract entry point address and interpreter (dynamic
|
|
Packit |
0021fb |
* linker) bias if possible. Returns 0 if there were no errors, -1
|
|
Packit |
0021fb |
* otherwise. Sets *ENTRYP and *INTERP_BIASP to non-zero values if
|
|
Packit |
0021fb |
* the corresponding value is known, or zero otherwise; this is not
|
|
Packit |
0021fb |
* done for pointers that are NULL. */
|
|
Packit |
0021fb |
int process_get_entry(struct process *proc,
|
|
Packit |
0021fb |
arch_addr_t *entryp,
|
|
Packit |
0021fb |
arch_addr_t *interp_biasp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Optional callbacks
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* Some callbacks are only available if backend (arch.h) has a certain
|
|
Packit |
0021fb |
* define. If such a define is not present, default implementation
|
|
Packit |
0021fb |
* (most often doing nothing at all) us used instead. This is used
|
|
Packit |
0021fb |
* for gradual extensions of ltrace, so that backends that are not
|
|
Packit |
0021fb |
* fully up to date, or that don't need certain functionality, keep
|
|
Packit |
0021fb |
* working, while other backends take advantage of the optional
|
|
Packit |
0021fb |
* features. */
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_LTELF_DATA. Those are used to init and destroy
|
|
Packit |
0021fb |
* LTE->arch. arch_elf_init returns 0 on success or a negative value
|
|
Packit |
0021fb |
* on failure. */
|
|
Packit |
0021fb |
int arch_elf_init(struct ltelf *lte, struct library *lib);
|
|
Packit |
0021fb |
void arch_elf_destroy(struct ltelf *lte);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in OS backend if
|
|
Packit |
0021fb |
* os.h defines OS_HAVE_BREAKPOINT_DATA. Those are used to init,
|
|
Packit |
0021fb |
* destroy, and clone SBP->os. os_breakpoint_init and
|
|
Packit |
0021fb |
* os_breakpoint_clone return 0 on success or a negative value on
|
|
Packit |
0021fb |
* failure. */
|
|
Packit |
0021fb |
int os_breakpoint_init(struct process *proc, struct breakpoint *sbp);
|
|
Packit |
0021fb |
void os_breakpoint_destroy(struct breakpoint *sbp);
|
|
Packit |
0021fb |
int os_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_BREAKPOINT_DATA. Those are used to init,
|
|
Packit |
0021fb |
* destroy, and clone SBP->arch. arch_breakpoint_init and
|
|
Packit |
0021fb |
* arch_breakpoint_clone return 0 on success or a negative value on
|
|
Packit |
0021fb |
* failure. */
|
|
Packit |
0021fb |
int arch_breakpoint_init(struct process *proc, struct breakpoint *sbp);
|
|
Packit |
0021fb |
void arch_breakpoint_destroy(struct breakpoint *sbp);
|
|
Packit |
0021fb |
int arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in OS backend if
|
|
Packit |
0021fb |
* os.h defines OS_HAVE_LIBRARY_DATA. Those are used to init, destroy
|
|
Packit |
0021fb |
* and clone LIB->os. os_library_init and os_library_clone return 0
|
|
Packit |
0021fb |
* on success or a negative value on failure. */
|
|
Packit |
0021fb |
int os_library_init(struct library *lib);
|
|
Packit |
0021fb |
void os_library_destroy(struct library *lib);
|
|
Packit |
0021fb |
int os_library_clone(struct library *retp, struct library *lib);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_LIBRARY_DATA. Those are used to init, destroy
|
|
Packit |
0021fb |
* and clone LIB->arch. arch_library_init and arch_library_clone
|
|
Packit |
0021fb |
* return 0 on success or a negative value on failure. */
|
|
Packit |
0021fb |
int arch_library_init(struct library *lib);
|
|
Packit |
0021fb |
void arch_library_destroy(struct library *lib);
|
|
Packit |
0021fb |
int arch_library_clone(struct library *retp, struct library *lib);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in OS backend if
|
|
Packit |
0021fb |
* os.h defines OS_HAVE_LIBRARY_SYMBOL_DATA. Those are used to init,
|
|
Packit |
0021fb |
* destroy and clone LIBSYM->os. os_library_symbol_init and
|
|
Packit |
0021fb |
* os_library_symbol_clone return 0 on success or a negative value on
|
|
Packit |
0021fb |
* failure. */
|
|
Packit |
0021fb |
int os_library_symbol_init(struct library_symbol *libsym);
|
|
Packit |
0021fb |
void os_library_symbol_destroy(struct library_symbol *libsym);
|
|
Packit |
0021fb |
int os_library_symbol_clone(struct library_symbol *retp,
|
|
Packit |
0021fb |
struct library_symbol *libsym);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_LIBRARY_SYMBOL_DATA. Those are used to init,
|
|
Packit |
0021fb |
* destroy and clone LIBSYM->arch. arch_library_symbol_init and
|
|
Packit |
0021fb |
* arch_library_symbol_clone return 0 on success or a negative value
|
|
Packit |
0021fb |
* on failure. */
|
|
Packit |
0021fb |
int arch_library_symbol_init(struct library_symbol *libsym);
|
|
Packit |
0021fb |
void arch_library_symbol_destroy(struct library_symbol *libsym);
|
|
Packit |
0021fb |
int arch_library_symbol_clone(struct library_symbol *retp,
|
|
Packit |
0021fb |
struct library_symbol *libsym);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in OS backend if
|
|
Packit |
0021fb |
* os.h defines OS_HAVE_PROCESS_DATA. The protocol is same as for,
|
|
Packit |
0021fb |
* respectively, arch_process_init, arch_process_destroy,
|
|
Packit |
0021fb |
* arch_process_clone and arch_process_exec. */
|
|
Packit |
0021fb |
int os_process_init(struct process *proc);
|
|
Packit |
0021fb |
void os_process_destroy(struct process *proc);
|
|
Packit |
0021fb |
int os_process_clone(struct process *retp, struct process *proc);
|
|
Packit |
0021fb |
int os_process_exec(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callbacks have to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_PROCESS_DATA. Those are used to init, destroy
|
|
Packit |
0021fb |
* and clone PROC->arch. arch_process_exec is called to update
|
|
Packit |
0021fb |
* PROC->arch in case that PROC underwent an exec. See notes at
|
|
Packit |
0021fb |
* process_init, process_destroy, process_clone and process_exec in
|
|
Packit |
0021fb |
* proc.h. */
|
|
Packit |
0021fb |
int arch_process_init(struct process *proc);
|
|
Packit |
0021fb |
void arch_process_destroy(struct process *proc);
|
|
Packit |
0021fb |
int arch_process_clone(struct process *retp, struct process *proc);
|
|
Packit |
0021fb |
int arch_process_exec(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callback has to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_GET_SYM_INFO.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This is called for every PLT relocation RELA in ELF file LTE (which
|
|
Packit |
0021fb |
* is named FILENAME), that ltrace is about to add. The corresponding
|
|
Packit |
0021fb |
* PLT entry is for SYM_INDEX-th relocation in the file. This call is
|
|
Packit |
0021fb |
* supposed to initialize SYM and RELA. It returns 0 if there were no
|
|
Packit |
0021fb |
* errors and given symbol should be used, 1 if the symbol should not
|
|
Packit |
0021fb |
* be used, or a negative value if there were errors. */
|
|
Packit |
0021fb |
int arch_get_sym_info(struct ltelf *lte, const char *filename, size_t sym_index,
|
|
Packit |
0021fb |
GElf_Rela *rela, GElf_Sym *sym);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
enum plt_status {
|
|
Packit |
0021fb |
PLT_FAIL,
|
|
Packit |
0021fb |
PLT_OK,
|
|
Packit |
0021fb |
PLT_DEFAULT,
|
|
Packit |
0021fb |
};
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callback has to be implemented in OS backend if os.h
|
|
Packit |
0021fb |
* defines OS_HAVE_ADD_PLT_ENTRY.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This is called for every PLT relocation R in ELF file LTE, that
|
|
Packit |
0021fb |
* ltrace is about to add to a library constructed in process PROC.
|
|
Packit |
0021fb |
* The corresponding PLT entry is for symbol called NAME, and it's
|
|
Packit |
0021fb |
* I-th relocation in the file.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* If this function returns PLT_DEFAULT, PLT address is obtained by
|
|
Packit |
0021fb |
* calling arch_plt_sym_val, and symbol is allocated. If PLT_OK or
|
|
Packit |
0021fb |
* PLT_DEFAULT are returned, the chain of symbols passed back in RET
|
|
Packit |
0021fb |
* is added to library under construction. */
|
|
Packit |
0021fb |
enum plt_status os_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
|
|
Packit |
0021fb |
const char *name, GElf_Rela *rela,
|
|
Packit |
0021fb |
size_t i, struct library_symbol **ret);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Like os_elf_add_plt_entry, but tied to ARCH_HAVE_ADD_PLT_ENTRY in
|
|
Packit |
0021fb |
* arch.h. The arch callback is called first. If it returns
|
|
Packit |
0021fb |
* PLT_DEFAULT, the os callback is called next. */
|
|
Packit |
0021fb |
enum plt_status arch_elf_add_plt_entry(struct process *proc, struct ltelf *lte,
|
|
Packit |
0021fb |
const char *name, GElf_Rela *rela,
|
|
Packit |
0021fb |
size_t i, struct library_symbol **ret);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callback has to be implemented in OS backend if os.h
|
|
Packit |
0021fb |
* defines OS_HAVE_ADD_FUNC_ENTRY.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This is called for every symbol in ltrace is about to add to the
|
|
Packit |
0021fb |
* library constructed for LTE in process PROC.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* If this function returns PLT_DEFAULT, then if there is a
|
|
Packit |
0021fb |
* pre-existing symbol, its name may be updated if the newly-found
|
|
Packit |
0021fb |
* name is shorter. Otherwise a new symbol is created.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* If PLT_OK or PLT_DEFAULT are returned, the chain of symbols passed
|
|
Packit |
0021fb |
* back in RET is added to library under construction. */
|
|
Packit |
0021fb |
enum plt_status os_elf_add_func_entry(struct process *proc, struct ltelf *lte,
|
|
Packit |
0021fb |
const GElf_Sym *sym,
|
|
Packit |
0021fb |
arch_addr_t addr, const char *name,
|
|
Packit |
0021fb |
struct library_symbol **ret);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Like os_elf_add_func_entry, but tied to ARCH_HAVE_ADD_FUNC_ENTRY in
|
|
Packit |
0021fb |
* arch.h. The arch callback is called first. If it returns
|
|
Packit |
0021fb |
* PLT_DEFAULT, the os callback is called next. */
|
|
Packit |
0021fb |
enum plt_status arch_elf_add_func_entry(struct process *proc, struct ltelf *lte,
|
|
Packit |
0021fb |
const GElf_Sym *sym,
|
|
Packit |
0021fb |
arch_addr_t addr, const char *name,
|
|
Packit |
0021fb |
struct library_symbol **ret);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This callback needs to be implemented if arch.h defines
|
|
Packit |
0021fb |
* ARCH_HAVE_DYNLINK_DONE. It is called after the dynamic linker is
|
|
Packit |
0021fb |
* done with the process start-up. */
|
|
Packit |
0021fb |
void arch_dynlink_done(struct process *proc);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This callback needs to be implemented if arch.h defines
|
|
Packit |
0021fb |
* ARCH_HAVE_SYMBOL_RET. It is called after a traced call returns. */
|
|
Packit |
0021fb |
void arch_symbol_ret(struct process *proc, struct library_symbol *libsym);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This callback needs to be implemented if arch.h defines
|
|
Packit |
0021fb |
* ARCH_HAVE_FIND_DL_DEBUG.
|
|
Packit |
0021fb |
* It is called by generic code to find the address of the dynamic
|
|
Packit |
0021fb |
* linkers debug structure.
|
|
Packit |
0021fb |
* DYN_ADDR holds the address of the dynamic section.
|
|
Packit |
0021fb |
* If the debug area is found, return 0 and fill in the address in *RET.
|
|
Packit |
0021fb |
* If the debug area is not found, return a negative value. */
|
|
Packit |
0021fb |
int arch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
|
|
Packit |
0021fb |
arch_addr_t *ret);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This is called to obtain a list of directories to search when
|
|
Packit |
0021fb |
* loading config files. The callback sets *RETP to a pointer to the
|
|
Packit |
0021fb |
* first element of a NULL-terminated array of directory names. It's
|
|
Packit |
0021fb |
* legitimate to set *RETP to NULL to indicate there are no
|
|
Packit |
0021fb |
* directories. The function returns 0 on success or a negative value
|
|
Packit |
0021fb |
* on a failure.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* If PRIVATE is set, the list in *RETP should contain only user's own
|
|
Packit |
0021fb |
* directories (presumably under HOME if there's any such thing on the
|
|
Packit |
0021fb |
* given OS). Otherwise only system directories should be reported.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* The directories don't have to exist. Directories passed in -F are
|
|
Packit |
0021fb |
* handled separately by the caller and this callback shouldn't
|
|
Packit |
0021fb |
* concern itself with it. */
|
|
Packit |
0021fb |
int os_get_config_dirs(int private, const char ***retp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* This is called to obtain list of legacy config files to import, if
|
|
Packit |
0021fb |
* any. A reference to initialized vector of char* is passed in.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This returns 0 on success, in which case strings from *RETP (if
|
|
Packit |
0021fb |
* any) are interpreted as files names. These files belong to the
|
|
Packit |
0021fb |
* caller and will eventually be freed.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* Returns a negative value for failure, in which case *RETP contents
|
|
Packit |
0021fb |
* are not consulted in any way. */
|
|
Packit |
0021fb |
int os_get_ltrace_conf_filenames(struct vect *retp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* If arch.h defines ARCH_HAVE_FETCH_ARG, the following callbacks have
|
|
Packit |
0021fb |
* to be implemented: arch_fetch_arg_init, arch_fetch_arg_clone,
|
|
Packit |
0021fb |
* arch_fetch_arg_done, arch_fetch_arg_next and arch_fetch_retval.
|
|
Packit |
0021fb |
* See fetch.h for details. */
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* If arch.h defines both ARCH_HAVE_FETCH_ARG and
|
|
Packit |
0021fb |
* ARCH_HAVE_FETCH_PACK, the following callbacks have to be
|
|
Packit |
0021fb |
* implemented: arch_fetch_param_pack_start,
|
|
Packit |
0021fb |
* arch_fetch_param_pack_end. See fetch.h for details. */
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
enum sw_singlestep_status {
|
|
Packit |
0021fb |
SWS_FAIL,
|
|
Packit |
0021fb |
SWS_OK,
|
|
Packit |
0021fb |
SWS_HW,
|
|
Packit |
0021fb |
};
|
|
Packit |
0021fb |
struct sw_singlestep_data;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The following callback has to be implemented in backend if arch.h
|
|
Packit |
0021fb |
* defines ARCH_HAVE_SW_SINGLESTEP.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This is called before the OS backend requests hardware singlestep.
|
|
Packit |
0021fb |
* arch_sw_singlestep should consider whether a singlestep needs to be
|
|
Packit |
0021fb |
* done in software. If not, it returns SWS_HW. Otherwise it needs
|
|
Packit |
0021fb |
* to add one or several breakpoints by calling ADD_CB. When it is
|
|
Packit |
0021fb |
* done, it continues the process as appropriate, and answers either
|
|
Packit |
0021fb |
* SWS_OK, or SWS_FAIL, depending on how it went.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* PROC is the process that should perform the singlestep, BP the
|
|
Packit |
0021fb |
* breakpoint that we are singlestepping over. ADD_CB is a callback
|
|
Packit |
0021fb |
* to request adding breakpoints that should trap the process after
|
|
Packit |
0021fb |
* it's continued. The arguments to ADD_CB are the address where the
|
|
Packit |
0021fb |
* breakpoint should be added, and DATA. ADD_CB returns 0 on success
|
|
Packit |
0021fb |
* or a negative value on failure. It is expected that
|
|
Packit |
0021fb |
* arch_sw_singlestep returns SWS_FAIL if ADD_CB returns error. */
|
|
Packit |
0021fb |
enum sw_singlestep_status arch_sw_singlestep(struct process *proc,
|
|
Packit |
0021fb |
struct breakpoint *bp,
|
|
Packit |
0021fb |
int (*add_cb)(arch_addr_t addr,
|
|
Packit |
0021fb |
struct sw_singlestep_data *),
|
|
Packit |
0021fb |
struct sw_singlestep_data *data);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
#endif /* BACKEND_H */
|