// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause package asm import ( "testing" "sourcedock.dev/petrbalvin/gasm-devkit/parser" ) func TestEmitDWARF(t *testing.T) { src := `#include "textflag.h" TEXT ·add(SB), NOSPLIT, $0-24 MOVQ a+0(FP), AX MOVQ b+8(FP), BX ADDQ BX, AX MOVQ AX, ret+16(FP) RET ` f, errs := parser.Parse("test_amd64.s", src) if len(errs) > 0 { t.Fatalf("parse: %v", errs) } img, err := AssembleFile(f) if err != nil { t.Fatalf("assemble: %v", err) } ds := emitDWARF(img, "test_amd64.s") // .debug_abbrev must not be empty and must start with abbrev code 1. if len(ds.debugAbbrev) == 0 { t.Fatal("empty .debug_abbrev") } if ds.debugAbbrev[0] != 1 { t.Fatalf(".debug_abbrev first byte = %d, want 1", ds.debugAbbrev[0]) } // .debug_info must have a compile unit header (DWARF5 version 5). if len(ds.debugInfo) < 12 { t.Fatalf(".debug_info too short: %d bytes", len(ds.debugInfo)) } // Version field at offset 4 (after unit_length). if ds.debugInfo[4] != 5 || ds.debugInfo[5] != 0 { t.Fatalf(".debug_info version = %d, want 5", uint16(ds.debugInfo[4])|uint16(ds.debugInfo[5])<<8) } // .debug_line must have a header. if len(ds.debugLine) < 20 { t.Fatalf(".debug_line too short: %d bytes", len(ds.debugLine)) } // Version at offset 4. if ds.debugLine[4] != 5 || ds.debugLine[5] != 0 { t.Fatalf(".debug_line version = %d, want 5", uint16(ds.debugLine[4])|uint16(ds.debugLine[5])<<8) } // .debug_line_str must contain the source file name. if len(ds.debugLineStr) == 0 { t.Fatal("empty .debug_line_str") } // Relocations must reference the function. if len(ds.lineRelocs) == 0 { t.Fatal("no .debug_line relocations") } if len(ds.infoRelocs) == 0 { t.Fatal("no .debug_info relocations") } } func TestDwarfAbbrevTable(t *testing.T) { abbrev := dwarfAbbrevTable() if len(abbrev) == 0 { t.Fatal("empty abbrev table") } // Must end with a zero byte (end of table). if abbrev[len(abbrev)-1] != 0 { t.Fatalf("abbrev table last byte = %d, want 0", abbrev[len(abbrev)-1]) } }