No description
  • C++ 84.7%
  • Shell 14.5%
  • Makefile 0.8%
Find a file
2026-06-22 16:27:42 +02:00
include Initial commit 2026-06-22 16:27:42 +02:00
tests Initial commit 2026-06-22 16:27:42 +02:00
.gitignore Initial commit 2026-06-22 16:27:42 +02:00
Makefile Initial commit 2026-06-22 16:27:42 +02:00
README.md Initial commit 2026-06-22 16:27:42 +02:00
ttnop.cpp Initial commit 2026-06-22 16:27:42 +02:00

ttnop

A program meant for surfacing synchronization bugs that injects NOP delays into arbitrary places in a linked kernel without moving any existing code.

It works by detouring. The instruction at each site is overwritten with a jump into a code cave grown onto the end of .text that holds the delay, a faithful copy of the displaced instruction, and a jump back.

Build

make

Use

ttnop <in.elf> -o <out.elf> [SITE ...] [options]

A SITE is LOC=N: inject a delay of N before the instruction at LOC:

# 5 nops before the instruction at VMA 0x6510
ttnop kernel.elf -o slow.elf 0x6510=5

# by symbol, and symbol+offset
ttnop kernel.elf -o slow.elf main=8  main+0x1c=3

# from a file (one LOC=N per line, '#' comments allowed)
ttnop kernel.elf -o slow.elf -f nop-sites

# a delay before every instruction of a class
ttnop kernel.elf -o slow.elf --every store=2 --every call=4
# classes: load store op opimm lui branch jal call jalr system fence amo custom all

Large delays: --loop

By default a delay of N is N NOPs, which can outgrow memory. --loop instead emits a fixed (typically) 8-word loop of N iterations (2N cycles), so arbitrarily large delays stay compact:

ttnop kernel.elf -o slow.elf 0x6510=50000 --loop

The loop saves/restores t0 on the stack, so do not target the first few instructions of a function.

Inspect & verify

ttnop kernel.elf --list                        # classify .text + per-class tally
ttnop kernel.elf -o s.elf --every branch=3 --list   # dry-run plan + cave map
ttnop kernel.elf -o s.elf 0x6510=5 --verify    # re-open output, re-check detours

How a detour looks

bltu a4,a5,0x65ac at 0x6590, asking for 3 nops, becomes a jump into the cave:

0x6590:  j      0x6980            # was bltu; now jumps into the cave

0x6980:  nop; nop; nop            # the delay
0x698c:  bgeu   a4,a5, 0x6994     # inverted condition ...
0x6990:  j      0x65ac            #   ... taken edge -> original target
0x6994:  j      0x6594            #   ... fall-through edge -> site+4