# Appendix: Glossary and References

> Source: https://www.ymotongpoo.com/books/go-ebpf-primer/99-glossary_references/


## Glossary

This glossary is a quick reference for the terms in this book. The parentheses after each term give the chapter that covers it in the most detail. If you start from a Hurdle chapter and meet a term that you don't know, this list points back to the chapter that explains it.

### Computing basics

- **Bits and bytes**: The smallest unit of information, which is 0 or 1, and a group of 8 of them. One byte represents 0 through 255 (Chapter 2).
- **Memory**: A sequence of bytes, each one with a numbered address. You read and write memory by number, not by name (Chapter 2).
- **Address**: The serial number of one cell of memory. It is a plain number, and most tools print it in hexadecimal (Chapter 2).
- **Hexadecimal**: The notation for numbers that starts with `0x`. Two digits stand for exactly one byte (Chapter 2).
- **Instructions and machine code**: The smallest units of work that a CPU can perform, and the byte sequences that represent them. Instructions also live in memory and have addresses (Chapters 2 and 4).
- **PC (program counter)**: The register that holds the address of the next instruction to execute. Its formal name is RIP (Chapter 2).
- **Register**: A fast storage location inside the CPU. amd64 has 16 general-purpose registers, each 64 bits wide (Chapter 2).
- **SP (stack pointer)**: The register that points to the top of the stack, which is the last location pushed. Its formal name is RSP. At the first instruction of a function, it points at the return address that the preceding `CALL` pushed (Chapters 2 and 5, Hurdle 1).
- **Pointer**: A variable whose value is an address (Chapter 2).
- **Field offset**: The number of bytes from the start of a struct to a field. `unsafe.Offsetof` returns it (Chapter 2, Hurdle 3).
- **Padding**: The unused bytes that the compiler inserts into a struct to align its fields (Chapter 2).

### The OS and the kernel

- **Kernel**: The core of the OS. It operates the hardware, isolates processes from each other, and schedules them (Chapter 3).
- **Process**: One running program's worth of state. The kernel tells processes apart by PID and gives each one its own virtual address space (Chapter 3).
- **Virtual addresses and virtual memory**: A private sequence of addresses that the kernel prepares for each process. The kernel maps those addresses onto physical memory (Chapter 3).
- **Text segment, data segment, heap, stack**: The regions of an address space. They hold machine code, global variables, dynamic allocations, and the working area for function calls, in that order (Chapter 3).
- **User space and kernel space**: The division that follows the CPU's privilege levels. Applications run on the restricted side, which is user space (Chapter 3).
- **System call**: A request from user space to the kernel. The call switches the privilege level (Chapter 3).
- **Thread**: The unit of execution that the kernel manages. Threads in one process share the address space, and each one has its own stack (Chapter 3).
- **ASLR**: A security mechanism that randomizes the placement of the stack and the heap on each launch (Chapter 3). In a Go binary, the runtime separately picks the base of the heap at random.
- **Escape analysis**: The analysis that the Go compiler runs to decide whether a value goes on the stack or the heap (Chapter 3).

### Executables

- **Compiling and linking**: The step that turns source code into machine code, and the step that combines the parts into one executable and fixes the addresses (Chapter 4).
- **Static linking and dynamic linking**: The method that embeds libraries into the executable, and the method that binds to shared libraries at run time (Chapter 4).
- **Disassembly**: Turning machine-code byte sequences back into instruction notation that a person can read. `go tool objdump` does this (Chapter 4).
- **Symbol table**: A table that maps names to addresses. It lives in the ELF `.symtab` section, and `go tool nm` prints it (Chapter 4).
- **ELF and sections**: The Linux executable format, and the divisions inside it such as `.text` and `.rodata` (Chapter 4).
- **`.gopclntab`**: A Go-specific table that maps instruction addresses to function names and line numbers. The runtime uses it for stack traces on panic, and even `-s -w` does not remove it (Chapters 4 and 14).
- **DWARF**: Debug information that records types, field offsets, and line numbers. It lives in the `.debug_*` sections, and `-w` removes it (Chapter 4, Hurdle 3).
- **Build info**: A blob that records the Go version and the list of dependency modules. `go version -m` reads it (Chapter 4, Hurdle 3).
- **Page**: The fixed-size unit, usually 4KB, that the mapping table for virtual memory uses. The kernel loads and replaces physical memory one page at a time (Chapter 4).
- **Copy-on-write**: The kernel mechanism that serves a write to a read-only shared page. The kernel makes a copy private to that process and repoints the mapping table at the copy (Chapters 4 and 7).

### Function calls

- **Stack frame**: The working area that one function call pushes onto the stack (Chapter 5).
- **Last in, first out (LIFO)**: The order in which the last thing pushed comes off first. A function returns in the reverse of the order you called it, so the stack only ever works this way (Chapter 5).
- **Return address**: The address of the instruction after the call, which `CALL` pushes onto the stack. `RET` pops it and jumps there. At the first instruction of the function, `SP` points at that slot (Chapter 5, Hurdle 1).
- **Calling convention**: The agreement on where arguments and return values go. One form passes arguments on the stack, and the other passes them in registers (Chapter 5, Hurdle 2).
- **Inlining**: A compiler optimization that replaces a call to a small function with the body of that function. The `CALL` instruction disappears with it (Chapter 5).
- **`//go:noinline`**: A compiler directive that forbids inlining. I use it in this book's experiments to keep the observation target in place (Chapter 5).

### The Go runtime

- **Runtime**: The execution support machinery that ships inside every Go binary. It performs its own scheduling and memory management (Chapter 6).
- **goroutine**: The unit of execution that the Go runtime manages. The kernel cannot see it (Chapter 6).
- **g, m, p**: Runtime-internal structs that represent a goroutine, an OS thread, and the resources needed to run Go code, respectively (Chapter 6).
- **Movable stack**: The property that a goroutine's stack relocates to a different region when it grows (Chapter 6, Hurdle 1).
- **ABIInternal**: The calling convention Go uses internally. The name dates to Go 1.12; on amd64 it passes arguments in registers from Go 1.17 (Hurdle 2).
- **ABI0**: The stable calling convention for calls out of assembly. It passes arguments on the stack, and a wrapper sits between it and ABIInternal (Hurdle 2).
- **R14**: The register that, on amd64, always points at the current goroutine's `g` struct (Hurdle 2).

### eBPF and OBI

- **eBPF**: The Linux mechanism for running small user-written programs safely inside the kernel (Chapter 7).
- **Verifier**: The mechanism that statically analyzes an eBPF program before the kernel loads it, and guarantees termination and memory safety (Chapter 7).
- **Map**: A key-value store that the kernel manages and that eBPF programs and user space share (Chapter 7).
- **uprobe and uretprobe**: A probe that the kernel places at an instruction address, and a mechanism that catches the return of a function. The kernel places a uprobe by replacing one byte with a breakpoint instruction. It places a uretprobe by rewriting the return address on the stack at function entry (Chapter 7, Hurdle 1).
- **Trampoline**: The kernel-side code that a uretprobe writes onto the stack in place of the return address (Hurdle 1).
- **cilium/ebpf**: The de facto Go library for loading and attaching eBPF programs (Chapter 7).
- **Ring buffer**: A shared buffer that passes events from the kernel to user space (Chapter 8).
- **OBI**: OpenTelemetry eBPF Instrumentation. An eBPF auto-instrumentation tool that descends from Beyla (Chapter 8).
- **Zero-code instrumentation**: Adding observation points from the outside, without changing the application's code (Chapter 1).
- **Protocol instrumentation**: A language-independent instrumentation path that interprets the byte sequence flowing through a socket as a protocol (Chapter 8).
- **`offsets.json`**: OBI's table of field offsets for each version of Go and of the libraries (Hurdle 3).
- **`bpf_probe_write_user`**: The eBPF helper that rewrites user-space memory in the target process (Hurdle 4).

### Distributed tracing

- **Instrumentation**: Adding observation points that record processing times and call relationships (Chapter 1).
- **Distributed trace, trace ID, span**: The record of one operation that spans several services, the identifier of that record, and one segment of it (Chapter 1).
- **traceparent**: The W3C standard header that carries the trace ID and the span ID over HTTP (Chapter 1, Hurdle 4).
- **Backend**: The server that collects telemetry records and displays them (Chapter 1).
- **Context propagation**: Carrying a trace's identifying information across process and service boundaries (Hurdle 4).
- **OTLP**: OpenTelemetry's standard protocol for transporting telemetry (Chapter 8).

## References

### OBI

- OpenTelemetry eBPF Instrumentation (OBI): <https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation>
- Official OBI documentation: <https://opentelemetry.io/docs/zero-code/obi/>
- OBI distributed traces documentation: <https://opentelemetry.io/docs/zero-code/obi/distributed-traces/>
- Support status overview (`SUPPORT_MATRIX.md`): <https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/blob/main/SUPPORT_MATRIX.md>
- Context propagation design notes (`devdocs/context-propagation.md`): <https://github.com/open-telemetry/opentelemetry-ebpf-instrumentation/blob/main/devdocs/context-propagation.md>

This book cites the following locations in the OBI source.

| Topic | File |
|---|---|
| Searching for `RET` instructions | `pkg/internal/goexec/instructions_amd64.go` |
| ELF parsing and locating moduledata | `pkg/internal/goexec/instructions.go` |
| Attaching uprobes | `pkg/ebpf/instrumenter.go` |
| Macros for argument registers and the `g` pointer | `bpf/bpfcore/utils.h` |
| goroutine identifiers | `bpf/common/go_addr_key.h` |
| Parent-child tracking of goroutines | `bpf/gotracer/go_runtime.c`, `bpf/gotracer/go_common.h` |
| Header injection | `bpf/gotracer/go_nethttp.c` |
| Offset resolution and reading build info | `pkg/internal/goexec/structmembers.go`, `pkg/internal/goexec/gofile.go` |
| Offset table | `pkg/internal/goexec/offsets.json` |
| List of instrumented symbols | `pkg/internal/ebpf/gotracer/gotracer.go` |

### Upstream Go

- golang/go#22008 (runtime: ebpf uretprobe support): <https://github.com/golang/go/issues/22008>
- golang/go#27077 (report of `fatal error: unknown caller pc` when attaching a uprobe, closed): <https://github.com/golang/go/issues/27077>
- golang/go#73798 (proposal for a goroutine start hook, not planned): <https://github.com/golang/go/issues/73798>
- golang/go#63185 (runtime/trace flight recorder, Go 1.25): <https://github.com/golang/go/issues/63185>
- Go 1.17 Release Notes (register-based calling convention): <https://go.dev/doc/go1.17>
- Go internal ABI specification: <https://github.com/golang/go/blob/master/src/cmd/compile/abi-internal.md>
- open-telemetry/opentelemetry-go-compile-instrumentation (the Compile-Time Instrumentation SIG, `otelc`): <https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation>
- Announcing v1 of OpenTelemetry Go Compile-Time Instrumentation: <https://opentelemetry.io/blog/2026/go-compile-time-instrumentation-v1/>

### eBPF

- cilium/ebpf (the Go loader library): <https://github.com/cilium/ebpf>

### Talk

- Go Conference 2026, "Behind the Scenes of OpenTelemetry eBPF Instrumentation" (in Japanese): <https://gocon.jp/2026/timetable/1263399/>

> The program output in this book includes values, such as addresses, that change from run to run. The start of Chapter 1 lists the versions of Go, OBI, and the kernel that I used to check the results.

