Skip to content

Inline-asm LVO calls omit scratch-register clobbers: 77 sites, 2 REAL in shipped binaries (#68 class) #70

Description

@tinic

Inline-asm AmigaOS library calls whose output + clobber lists omit a scratch register (d0/d1/a0/a1). The library ABI lets any LVO destroy those four, but GCC is told the unlisted input register survives. This is the class of the #68 sockopt bug: bsd_recvfrom omitted a1, and the next inlined call passed a stale from, which returned EFAULT.

Scan (main 58c5c4f): 415 asm LVO statements in src/ and tests/, 77 flagged. The scanner is validated both ways: it flags tests/sockopt/sockopt_test.c:332 (the #68 site) and passes src/tools/toolsock.c.

Shipped sites (16): 2 REAL, 14 LATENT. 43 call-site copies checked by disassembly in a keep-symbols build; its instruction bytes are identical to the release build.

site image verdict evidence
src/tools/installnetprobe.c:59 probe_own_card (a1) InstallNetProbe REAL 968 lea 0x18,a1; 96e jsr -6(a6) OwnCard; owned path 98e jsr -72(a6) CopyTuple(0x20) with a1 not reloaded
src/netdev/netdev_pcmcia.c:79 pc_misc_control (d1) anxnet.device REAL (diag only) 68a8 moveq #10,d1; 68aa jsr -48(a6); 68b0 move.l d1,-(sp) becomes the IOMODE value of netdev_diag_note(0x29)
src/netdev/netdev_dtree.c :50 :61 :73 :86 :98 :110 :122 :134 anxgenet.device, InstallNetProbe LATENT out of line + rts, or the register is rewritten or a call comes first
src/netdev/netdev_pcmcia.c :38 :52 :64 :97 anxnet.device LATENT rewritten or not read
src/tools/installnetprobe.c :72 :88 InstallNetProbe LATENT rewritten on every path

LATENT means the source is wrong but today's codegen doesn't depend on it. The a5 bug (#58) showed that this turns real on the next codegen change.

Test sites (59): ipv6_socket_test 28, sockopt_test 10 (:332 is fixed by #68), udpdrill 9, ifprobe 2, cardgrab 2, tcpdrill 2, and 1 each in apidrill, tls_loop, refused_leak_test, endurance, tickprobe, atf_main.

Not this class: cmake/check-lvo-stub-registers.cmake does not generalise beyond toolsock.c. At -O0 it reports string data decoded as code, and it counts all four registers as inputs to every vector. At -Os and on linked LTO images it flags toolsock.c itself.

Plan (proposed, subject to codex GO):

  1. Fix all 16 shipped sites by adding outputs/clobbers only, one PR per binary, with before/after disassembly.
  2. Make the scanner a build/CI gate over src/ and tests/.
  3. Fix the 59 test sites.

Full list:

src/netdev/genet.c:542 missing a0,a1,d0,d1
src/netdev/netdev_cache.c:85 missing a0,a1,d0,d1
src/netdev/netdev_dtree.c:110 missing a0
src/netdev/netdev_dtree.c:122 missing a0
src/netdev/netdev_dtree.c:134 missing a0
src/netdev/netdev_dtree.c:50 missing a0
src/netdev/netdev_dtree.c:61 missing a0
src/netdev/netdev_dtree.c:73 missing a0,a1
src/netdev/netdev_dtree.c:86 missing a0,a1
src/netdev/netdev_dtree.c:98 missing a0
src/netdev/netdev_pcmcia.c:38 missing a1
src/netdev/netdev_pcmcia.c:52 missing a1
src/netdev/netdev_pcmcia.c:64 missing a1
src/netdev/netdev_pcmcia.c:79 missing a1,d1
src/netdev/netdev_pcmcia.c:97 missing a0,a1,d1
src/tools/installnetprobe.c:59 missing a1
src/tools/installnetprobe.c:72 missing a1
src/tools/installnetprobe.c:88 missing a0,a1,d1
tests/atf/atf_main.c:64 missing a0,d0
tests/compare/tickprobe.c:120 missing d1
tests/endurance/endurance.c:118 missing d1
tests/ipv6/ipv6_socket_test.c:201 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:216 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:230 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:245 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:260 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:276 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:293 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:308 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:327 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:347 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:364 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:380 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:398 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:416 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:432 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:447 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:460 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:475 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:491 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:505 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:517 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:606 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:622 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:638 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:654 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:667 missing a0,a1,d0,d1
tests/ipv6/ipv6_socket_test.c:681 missing a0,a1,d1
tests/ipv6/ipv6_socket_test.c:701 missing a0,a1,d1
tests/leak/refused_leak_test.c:98 missing d1
tests/sockopt/sockopt_test.c:159 missing a0,a1,d1
tests/sockopt/sockopt_test.c:175 missing a0,a1,d1
tests/sockopt/sockopt_test.c:190 missing a0,a1,d1
tests/sockopt/sockopt_test.c:206 missing a0,a1,d1
tests/sockopt/sockopt_test.c:224 missing a0,a1,d1
tests/sockopt/sockopt_test.c:243 missing a0,a1,d1
tests/sockopt/sockopt_test.c:260 missing a0,a1,d1
tests/sockopt/sockopt_test.c:274 missing a0,a1,d1
tests/sockopt/sockopt_test.c:287 missing a0,a1,d1
tests/sockopt/sockopt_test.c:332 missing a1
tests/tcpdrill/tcpdrill.c:156 missing d1
tests/tcpdrill/tcpdrill.c:266 missing d1
tests/tls/tls_loop.c:270 missing d1
tests/tools/apidrill.c:159 missing a0,a1,d0,d1
tests/tools/cardgrab.c:66 missing a1
tests/tools/cardgrab.c:80 missing a1
tests/tools/ifprobe.c:829 missing a0
tests/tools/ifprobe.c:844 missing a0
tests/udpdrill/udpdrill.c:142 missing a0,a1,d1
tests/udpdrill/udpdrill.c:158 missing a0,a1,d1
tests/udpdrill/udpdrill.c:174 missing a0,a1,d1
tests/udpdrill/udpdrill.c:195 missing a1
tests/udpdrill/udpdrill.c:216 missing a0,a1,d1
tests/udpdrill/udpdrill.c:277 missing a1
tests/udpdrill/udpdrill.c:315 missing a0,a1,d1
tests/udpdrill/udpdrill.c:329 missing a0,a1,d1
tests/udpdrill/udpdrill.c:342 missing a0,a1,d1

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions