# Vendored libunwind — Maintenance Notes

## Source

- **Upstream**: https://github.com/libunwind/libunwind
- **Version**: 1.8.3 (from the release tarball, *not* from the git repository)
- **Tarball**: https://github.com/libunwind/libunwind/releases/download/v1.8.3/libunwind-1.8.3.tar.gz

## Purpose

libunwind is vendored so the sentry-native SDK can perform stack unwinding on
Linux without requiring users to install any external packages.  Only the
**local** unwinding functionality is needed.

## Supported Architectures (built by CMake)

| Architecture       | `src/` dir     | `include/tdep-*` dir    |
|--------------------|----------------|-------------------------|
| x86_64             | `src/x86_64/`  | `include/tdep-x86_64/`  |
| x86 (i686, 32-bit) | `src/x86/`     | `include/tdep-x86/`     |
| aarch64            | `src/aarch64/` | `include/tdep-aarch64/` |
| arm (32-bit)       | `src/arm/`     | `include/tdep-arm/`     |

Core shared code: `src/mi/`, `src/dwarf/`, `src/os-linux.c`,
`src/dl-iterate-phdr.c`.

> **Note:** `src/unwind/` is present in the tree but is **not compiled**. See
> [Excluded: C++ exception ABI sources](#excluded-c-exception-abi-sources) below.

## What Was Removed from the Release Tarball

The release tarball contains 911 files.  547 were removed (the vendor tree
keeps 368 files, of which 4 are custom additions).  Every removal falls into
one of four categories:

### 1. Documentation & tests

| Directory | Files | Reason                                                 |
|-----------|-------|--------------------------------------------------------|
| `doc/`    | 84    | Man pages and LaTeX sources — not needed to build      |
| `tests/`  | 90    | Test suite — sentry-native has its own unwinding tests |

### 2. Autotools / build scaffolding

| Directory | Files | Reason                                                                                                                                                                                                                  |
|-----------|-------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `m4/`     | 5     | Autotools M4 macros — the vendor uses a custom CMake build                                                                                                                                                              |
| `config/` | 9     | Generic autotools helper scripts (`ltmain.sh`, `config.guess`, `config.sub`, `install-sh`, `compile`, `depcomp`, `ar-lib`, `missing`, `test-driver`) — boilerplate regenerated by `autoreconf`, not useful as reference |

### 3. Unsupported CPU architectures

Source and include directories for architectures sentry-native does not target:

| Architecture          | Removed `src/` dir | Removed `include/tdep-*` dir |
|-----------------------|--------------------|------------------------------|
| HP PA-RISC            | `src/hppa/`        | `include/tdep-hppa/`         |
| Intel Itanium (IA-64) | `src/ia64/`        | `include/tdep-ia64/`         |
| LoongArch 64          | `src/loongarch64/` | `include/tdep-loongarch64/`  |
| MIPS                  | `src/mips/`        | `include/tdep-mips/`         |
| PowerPC (shared)      | `src/ppc/`         | —                            |
| PowerPC 32-bit        | `src/ppc32/`       | `include/tdep-ppc32/`        |
| PowerPC 64-bit        | `src/ppc64/`       | `include/tdep-ppc64/`        |
| IBM System/390        | `src/s390x/`       | `include/tdep-s390x/`        |
| SuperH                | `src/sh/`          | `include/tdep-sh/`           |

### 4. Unused feature modules

These are separate `libunwind` "accessor" libraries for non-local unwinding use
cases.  sentry-native only uses local unwinding (unwinding the current process
in-process), so none of these are needed:

| Directory       | Purpose                             | Why removed                       |
|-----------------|-------------------------------------|-----------------------------------|
| `src/coredump/` | Unwinding from a coredump file      | Not a live-process use case       |
| `src/nto/`      | QNX Neutrino ptrace-based unwinding | QNX is not a sentry-native target |
| `src/ptrace/`   | Remote unwinding via `ptrace()`     | Only local unwinding is needed    |
| `src/setjmp/`   | `setjmp`/`longjmp` wrappers         | Not relevant for crash reporting  |

### What is kept but NOT built

The following are present in the vendor tree but are **not** compiled by the
custom `CMakeLists.txt`:

| Path                                                                                                     | Notes                                                                                                                                      |
|----------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `src/riscv/`, `include/tdep-riscv/`                                                                      | RISC-V — kept for potential future use                                                                                                     |
| `src/unwind/`, `src/mi/_ReadULEB.c`, `src/mi/_ReadSLEB.c`                                                | C++ exception ABI conflicts with `libgcc_eh.a`; see [above](#excluded-c-exception-abi-sources)                                             |
| `include/libunwind-*.h` for removed arches                                                               | Referenced via `#ifdef` in `include/libunwind.h` — harmless dead code                                                                      |
| Autotools artifacts (`configure`, `configure.ac`, `Makefile.am`, `Makefile.in`, `aclocal.m4`, `INSTALL`) | Carried over from the release tarball. Not used by CMake, but `configure.ac` and `Makefile.am` are useful as reference for the build logic |

### Excluded: C++ exception ABI sources

The `src/unwind/` directory and `src/mi/_ReadULEB.c` / `src/mi/_ReadSLEB.c`
are **present in the tree but excluded from the CMake build**.  These files
implement the Itanium C++ exception handling ABI (`_Unwind_Resume`,
`_Unwind_RaiseException`, `_Unwind_ForcedUnwind`, etc.) — the same symbols
that `libgcc_eh.a` provides.

When sentry-native is built as a static library (`SENTRY_BUILD_SHARED_LIBS=OFF`)
and linked into a shared library whose toolchain uses `-static-libgcc`
(e.g. godot-cpp), including these symbols causes **multiple definition** errors
against `libgcc_eh.a`.  Excluding them is safe because sentry-native only uses
the local unwinding API (`_ULx86_64_init_local`, `_ULx86_64_step`, etc.) and
never calls into the C++ exception ABI.

## Custom Additions (not in the upstream tarball)

| File                                | Purpose                                                                                                                                           |
|-------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|
| `CMakeLists.txt`                    | Custom CMake build that replaces the upstream autotools + upstream CMake build. Builds a static `unwind` target for x86, x86_64, and aarch64 only |
| `cmake/config.h.cmake.in`           | CMake template for `config.h` (replaces autotools `configure`-generated header)                                                                   |
| `cmake/libunwind-common.h.cmake.in` | CMake template for `libunwind-common.h`                                                                                                           |
| `VENDORING.md`                      | This file                                                                                                                                         |

## Source Modifications

Only **one** upstream source file was modified:

### `include/libunwind-aarch64.h` — `alignas` → `__attribute__((aligned))`

```c
// UPSTREAM (requires C11 <stdalign.h> / alignas):
alignas(16) uint8_t __reserved[(66 * 8)];

// VENDOR (C99-compatible):
uint8_t __reserved[(66 * 8)] __attribute__((aligned(16)));
```

**Reason**: The SDK targets C99.  `alignas` is a C11 keyword.  The
`__attribute__((aligned(...)))` form is semantically equivalent and supported by
both GCC and Clang.

## How to Update the Vendored Version

1. Download the **release tarball** (not a git checkout) from
   https://github.com/libunwind/libunwind/releases

2. Extract it.  The tarball includes autotools-generated files (`configure`,
   `Makefile.in`, `config/`, etc.) that are not in the git repository.

3. Delete and re-copy these directories from the new tarball, **excluding** the
   removed architecture dirs listed above:
   - `src/` — keep only: `aarch64/`, `arm/`, `dwarf/`, `mi/`, `riscv/`,
     `unwind/`, `x86/`, `x86_64/`, and top-level `.c` / `.h` files
     (`src/unwind/` is kept for reference but **not compiled** — do not add it
     to `CMakeLists.txt`)
   - `include/` — keep only: `tdep/`, `tdep-aarch64/`, `tdep-arm/`,
     `tdep-riscv/`, `tdep-x86/`, `tdep-x86_64/`, and all top-level `.h` /
     `.h.in` files
   - Top-level files (`configure`, `configure.ac`, `Makefile.am`, `Makefile.in`,
     `aclocal.m4`, `NEWS`, `README`, `COPYING`, `AUTHORS`, `ChangeLog`, `TODO`,
     `INSTALL`) — do **not** copy `config/`

4. **Do NOT overwrite** `CMakeLists.txt`, `cmake/`, or `VENDORING.md` — these
   are custom.

5. Review the upstream `src/CMakeLists.txt` (or `src/Makefile.am`) for any
   **new source files** added to the architectures we build, and add them to
   our custom `CMakeLists.txt`.

6. **Re-apply source modifications**:
   - Check `include/libunwind-aarch64.h` for `alignas` — replace with
     `__attribute__((aligned(...)))`.
   - Scan for other C11/C23 constructs incompatible with C99.

7. Build and test on all four architectures: x86_64, x86 (32-bit), aarch64, arm (32-bit).

8. To add a **new architecture**, also:
   - Keep its `src/<arch>/` and `include/tdep-<arch>/` directories from the
     tarball
   - Add its source files to `CMakeLists.txt`
   - Verify `cmake/config.h.cmake.in` covers any new `#define`s
