linuxApi

dlsym

https://linux.die.net/man/3/dlsym

void *dlsym(void *handle, const char *symbol);

The function dlsym() takes a “handle” of a dynamic library returned by dlopen() and the null-terminated symbol name, returning the address where that symbol is loaded into memory.

pthread_create

http://man7.org/linux/man-pages/man3/pthread_create.3.html

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);
   The pthread_create() function starts a new thread in the calling
   process.  The new thread starts execution by invoking
   start_routine(); arg is passed as the sole argument of
   start_routine().


sigaction

https://linux.die.net/man/2/sigaction

int sigaction(int signum, const struct sigaction *act,
              struct sigaction *oldact);

The sigaction() system call is used to change the action taken by a process on receipt of a specific signal. (See signal(7) for an overview of signals.)

signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.

If act is non-NULL, the new action for signal signum is installed from act. If oldact is non-NULL, the previous action is saved in oldact.

sigaltstack

http://man7.org/linux/man-pages/man2/sigaltstack.2.html

int sigaltstack(const stack_t *ss, stack_t *old_ss);
sigaltstack() allows a process to define a new alternate signal stack
       and/or retrieve the state of an existing alternate signal stack.  An
       alternate signal stack is used during the execution of a signal
       handler if the establishment of that handler (see sigaction(2))
       requested it.
       
     The normal sequence of events for using an alternate signal stack is
       the following:

       1. Allocate an area of memory to be used for the alternate signal
          stack.

       2. Use sigaltstack() to inform the system of the existence and
          location of the alternate signal stack.

       3. When establishing a signal handler using sigaction(2), inform the
          system that the signal handler should be executed on the alternate
          signal stack by specifying the SA_ONSTACK flag.
          
       The ss argument is used to specify a new alternate signal stack,
       while the old_ss argument is used to retrieve information about the
       currently established signal stack.  If we are interested in
       performing just one of these tasks, then the other argument can be
       specified as NULL.

memcpy

http://man7.org/linux/man-pages/man3/memcpy.3.html

void *memcpy(void *dest, const void *src, size_t n);
The memcpy() function copies n bytes from memory area src to memory
       area dest.  The memory areas must not overlap.  Use memmove(3) if the
       memory areas do overlap.
       
       The memcpy() function returns a pointer to dest.

prctl

http://man7.org/linux/man-pages/man2/prctl.2.html

int prctl(int option, unsigned long arg2, unsigned long arg3,
                 unsigned long arg4, unsigned long arg5);
                 
prctl() is called with a first argument describing what to do (with
       values defined in <linux/prctl.h>), and further arguments with a
       significance depending on the first one.  The first argument can be:
       PR_SET_PTRACER (since Linux 3.4)......

fork

http://man7.org/linux/man-pages/man2/fork.2.html

 pid_t fork(void);
fork() creates a new process by duplicating the calling process.  The
       new process is referred to as the child process.  The calling process
       is referred to as the parent process.

       The child process and the parent process run in separate memory
       spaces.  At the time of fork() both memory spaces have the same
       content.  Memory writes, file mappings (mmap(2)), and unmappings
       (munmap(2)) performed by one of the processes do not affect the
       other.
       
       
       RETURN VALUE         top
       On success, the PID of the child process is returned in the parent,
       and 0 is returned in the child.  On failure, -1 is returned in the
       parent, no child process is created, and errno is set appropriately.

waitpid

https://linux.die.net/man/3/waitpid

wait, waitpid - wait for a child process to stop or terminate

pid_t waitpid(pid_t pid, int *stat_loc, int options);

execl

https://linux.die.net/man/3/execl

execl, execlp, execle, execv, execvp, execvpe - execute a file

int execl(const char *path, const char *arg, ...);

alarm

http://man7.org/linux/man-pages/man2/alarm.2.html

unsigned int alarm(unsigned int seconds);

alarm() arranges for a SIGALRM signal to be delivered to the calling
       process in seconds seconds.

read

http://man7.org/linux/man-pages/man2/read.2.html

ssize_t read(int fd, void *buf, size_t count);

read() attempts to read up to count bytes from file descriptor fd
       into the buffer starting at buf.


write

http://man7.org/linux/man-pages/man2/write.2.html

write - write to a file descriptor

ssize_t write(int fd, const void *buf, size_t count);

       write() writes up to count bytes from the buffer starting at buf to
       the file referred to by the file descriptor fd.

open

http://man7.org/linux/man-pages/man2/open.2.html

int open(const char *pathname, int flags);

The open() system call opens the file specified by pathname.  If the
       specified file does not exist, it may optionally (if O_CREAT is
       specified in flags) be created by open().

ptrace

http://man7.org/linux/man-pages/man2/ptrace.2.html

NAME         top
       ptrace - process trace
       
SYNOPSIS         top
       #include <sys/ptrace.h>

       long ptrace(enum __ptrace_request request, pid_t pid,
                   void *addr, void *data);
                   
     PTRACE_ATTACH
              Attach to the process specified in pid, making it a tracee of
              the calling process.  The tracee is sent a SIGSTOP, but will
              not necessarily have stopped by the completion of this call;
              use waitpid(2) to wait for the tracee to stop.  See the
              "Attaching and detaching" subsection for additional informa‐
              tion.  (addr and data are ignored.)

              Permission to perform a PTRACE_ATTACH is governed by a ptrace
              access mode PTRACE_MODE_ATTACH_REALCREDS check; see below.
              
              
     Attaching and detaching
       A thread can be attached to the tracer using the call

           ptrace(PTRACE_ATTACH, tid, 0, 0);
       or
           ptrace(PTRACE_SEIZE, tid, 0, PTRACE_O_flags);

       PTRACE_ATTACH sends SIGSTOP to this thread.  If the tracer wants this
       SIGSTOP to have no effect, it needs to suppress it.
       
       
       
       PTRACE_GETREGSET (since Linux 2.6.34)
              Read the tracee's registers.  addr specifies, in an
              architecture-dependent way, the type of registers to be read.
              NT_PRSTATUS (with numerical value 1) usually results in
              reading of general-purpose registers.  If the CPU has, for
              example, floating-point and/or vector registers, they can be
              retrieved by setting addr to the corresponding NT_foo
              constant.  data points to a struct iovec, which describes the
              destination buffer's location and length.  On return, the
              kernel modifies iov.len to indicate the actual number of bytes
              returned.
              
        PTRACE_PEEKTEXT, PTRACE_PEEKDATA
              Read a word at the address addr in the tracee's memory,
              returning the word as the result of the ptrace() call.  Linux
              does not have separate text and data address spaces, so these
              two requests are currently equivalent.  (data is ignored; but
              see NOTES.)
              
RETURN VALUE         top
       On success, the PTRACE_PEEK* requests return the requested data (but
       see NOTES), the PTRACE_SECCOMP_GET_FILTER request returns the number
       of instructions in the BPF program, and other requests return zero.

       On error, all requests return -1, and errno is set appropriately.
       Since the value returned by a successful PTRACE_PEEK* request may be
       -1, the caller must clear errno before the call, and then check it
       afterward to determine whether or not an error occurred.

SIGSTOP

作用是suspend,可以通过SIGCONT恢复

eventfd

http://man7.org/linux/man-pages/man2/eventfd.2.html

eventfd - create a file descriptor for event notification

#include <sys/eventfd.h>

       int eventfd(unsigned int initval, int flags);
       
       eventfd() creates an "eventfd object" that can be used as an event
       wait/notify mechanism by user-space applications, and by the kernel
       to notify user-space applications of events. 
       
       As its return value, eventfd() returns a new file descriptor that can
       be used to refer to the eventfd object.
       
              EFD_CLOEXEC (since Linux 2.6.27)
              Set the close-on-exec (FD_CLOEXEC) flag on the new file
              descriptor.  See the description of the O_CLOEXEC flag in
              open(2) for reasons why this may be useful.

dup2

http://man7.org/linux/man-pages/man2/dup.2.html

dup, dup2, dup3 - duplicate a file descriptor

int dup(int oldfd);
       int dup2(int oldfd, int newfd);
       int dup3(int oldfd, int newfd, int flags);
       
       
       The dup() system call creates a copy of the file descriptor oldfd,
       using the lowest-numbered unused file descriptor for the new
       descriptor.
       
       The dup2() system call performs the same task as dup(), but instead
       of using the lowest-numbered unused file descriptor, it uses the file
       descriptor number specified in newfd.  If the file descriptor newfd
       was previously open, it is silently closed before being reused.

syscall

http://man7.org/linux/man-pages/man2/syscall.2.html

syscall - indirect system call

long syscall(long number, ...);

mmap

http://man7.org/linux/man-pages/man2/mmap.2.html

mmap, munmap - map or unmap files or devices into memory

       void *mmap(void *addr, size_t length, int prot, int flags,
                  int fd, off_t offset);
       int munmap(void *addr, size_t length);
       
       mmap() creates a new mapping in the virtual address space of the
       calling process.  The starting address for the new mapping is
       specified in addr.  The length argument specifies the length of the
       mapping (which must be greater than 0).

       If addr is NULL, then the kernel chooses the (page-aligned) address
       at which to create the mapping; this is the most portable method of
       creating a new mapping.  If addr is not NULL, then the kernel takes
       it as a hint about where to place the mapping; on Linux, the kernel
       will pick a nearby page boundary (but always above or equal to the
       value specified by /proc/sys/vm/mmap_min_addr) and attempt to create
       the mapping there.  If another mapping already exists there, the
       kernel picks a new address that may or may not depend on the hint.
       The address of the new mapping is returned as the result of the call.
       
              MAP_PRIVATE
              Create a private copy-on-write mapping.  Updates to the
              mapping are not visible to other processes mapping the same
              file, and are not carried through to the underlying file.  It
              is unspecified whether changes made to the file after the
              mmap() call are visible in the mapped region.
              
       RETURN VALUE         top
       On success, mmap() returns a pointer to the mapped area.  On error,
       the value MAP_FAILED (that is, (void *) -1) is returned, and errno is
       set to indicate the cause of the error.

       On success, munmap() returns 0.  On failure, it returns -1, and errno
       is set to indicate the cause of the error (probably to EINVAL).
       

ElfW

https://code.woboq.org/userspace/glibc/elf/link.h.html

/* We use this macro to refer to ELF types independent of the native wordsize.
   `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'.  */
#define ElfW(type)        _ElfW (Elf, __ELF_NATIVE_CLASS, type)
#define _ElfW(e,w,t)        _ElfW_1 (e, w, _##t)
#define _ElfW_1(e,w,t)        e##w##t

Ehdr和Phdr

http://man7.org/linux/man-pages/man5/elf.5.html

Ehdr

ELF header (Ehdr)
       The ELF header is described by the type Elf32_Ehdr or Elf64_Ehdr:
       
           The ELF header is described by the type Elf32_Ehdr or Elf64_Ehdr:

           #define EI_NIDENT 16

           typedef struct {
               unsigned char e_ident[EI_NIDENT];
               uint16_t      e_type;
               uint16_t      e_machine;
               uint32_t      e_version;
               ElfN_Addr     e_entry;
               ElfN_Off      e_phoff;
               ElfN_Off      e_shoff;
               uint32_t      e_flags;
               uint16_t      e_ehsize;
               uint16_t      e_phentsize;
               uint16_t      e_phnum;
               uint16_t      e_shentsize;
               uint16_t      e_shnum;
               uint16_t      e_shstrndx;
           } ElfN_Ehdr;
    

Phdr

Program header (Phdr)
       Program header (Phdr)
       An executable or shared object file's program header table is an
       array of structures, each describing a segment or other information
       the system needs to prepare the program for execution.  An object
       file segment contains one or more sections.  Program headers are
       meaningful only for executable and shared object files.  A file spec‐
       ifies its own program header size with the ELF header's e_phentsize
       and e_phnum members.  The ELF program header is described by the type
       Elf32_Phdr or Elf64_Phdr depending on the architecture:

           typedef struct {
               uint32_t   p_type;
               Elf32_Off  p_offset;
               Elf32_Addr p_vaddr;
               Elf32_Addr p_paddr;
               uint32_t   p_filesz;
               uint32_t   p_memsz;
               uint32_t   p_flags;
               uint32_t   p_align;
           } Elf32_Phdr;

           typedef struct {
               uint32_t   p_type;
               uint32_t   p_flags;
               Elf64_Off  p_offset;
               Elf64_Addr p_vaddr;
               Elf64_Addr p_paddr;
               uint64_t   p_filesz;
               uint64_t   p_memsz;
               uint64_t   p_align;
           }
           
           The main difference between the 32-bit and the 64-bit program header
       lies in the location of the p_flags member in the total struct.