purego_dibuilder.go raw

   1  //go:build purego
   2  
   3  package llvm
   4  
   5  import (
   6  	"debug/dwarf"
   7  	"runtime"
   8  	"unsafe"
   9  
  10  	"github.com/ebitengine/purego"
  11  )
  12  
  13  type DwarfTag uint32
  14  
  15  const (
  16  	DW_TAG_lexical_block   DwarfTag = 0x0b
  17  	DW_TAG_compile_unit    DwarfTag = 0x11
  18  	DW_TAG_variable        DwarfTag = 0x34
  19  	DW_TAG_base_type       DwarfTag = 0x24
  20  	DW_TAG_pointer_type    DwarfTag = 0x0F
  21  	DW_TAG_structure_type  DwarfTag = 0x13
  22  	DW_TAG_subroutine_type DwarfTag = 0x15
  23  	DW_TAG_file_type       DwarfTag = 0x29
  24  	DW_TAG_subprogram      DwarfTag = 0x2E
  25  	DW_TAG_auto_variable   DwarfTag = 0x100
  26  	DW_TAG_arg_variable    DwarfTag = 0x101
  27  )
  28  
  29  const (
  30  	FlagPrivate = 1 << iota
  31  	FlagProtected
  32  	FlagFwdDecl
  33  	FlagAppleBlock
  34  	FlagReserved
  35  	FlagVirtual
  36  	FlagArtificial
  37  	FlagExplicit
  38  	FlagPrototyped
  39  	FlagObjcClassComplete
  40  	FlagObjectPointer
  41  	FlagVector
  42  	FlagStaticMember
  43  	FlagIndirectVariable
  44  )
  45  
  46  type DwarfLang uint32
  47  
  48  const DW_LANG_Go DwarfLang = 0x0016
  49  
  50  type DwarfTypeEncoding uint32
  51  
  52  const (
  53  	DW_ATE_address         DwarfTypeEncoding = 0x01
  54  	DW_ATE_boolean         DwarfTypeEncoding = 0x02
  55  	DW_ATE_complex_float   DwarfTypeEncoding = 0x03
  56  	DW_ATE_float           DwarfTypeEncoding = 0x04
  57  	DW_ATE_signed          DwarfTypeEncoding = 0x05
  58  	DW_ATE_signed_char     DwarfTypeEncoding = 0x06
  59  	DW_ATE_unsigned        DwarfTypeEncoding = 0x07
  60  	DW_ATE_unsigned_char   DwarfTypeEncoding = 0x08
  61  	DW_ATE_imaginary_float DwarfTypeEncoding = 0x09
  62  )
  63  
  64  type MetadataKind int
  65  
  66  type DIBuilder struct {
  67  	C uintptr
  68  	m Module
  69  }
  70  
  71  var (
  72  	symCreateDIBuilder      uintptr
  73  	symDisposeDIBuilder     uintptr
  74  	symDIBuilderFinalize    uintptr
  75  	symDIBCreateFile        uintptr
  76  
  77  	// Shims for >15 arg functions (in libmoxie-llvm-glue.so)
  78  	symMoxieCreateCompileUnit uintptr
  79  	symMoxieCreateStructType  uintptr
  80  	symDIBCreateLexBlock    uintptr
  81  	symDIBCreateLexBlockFile uintptr
  82  	symDIBCreateFunction    uintptr
  83  	symDIBCreateAutoVar     uintptr
  84  	symDIBCreateParamVar    uintptr
  85  	symDIBCreateBasicType   uintptr
  86  	symDIBCreatePointerType uintptr
  87  	symDIBCreateSubrtnType  uintptr
  88  	symDIBCreateMemberType  uintptr
  89  	symDIBCreateArrayType   uintptr
  90  	symDIBCreateTypedef     uintptr
  91  	symDIBCreateReplaceableType uintptr
  92  	symDIBCreateGlobalVarExpr   uintptr
  93  	symDIBGetOrCreateSubrange   uintptr
  94  	symDIBGetOrCreateArray      uintptr
  95  	symDIBGetOrCreateTypeArray  uintptr
  96  	symDIBCreateExpression      uintptr
  97  	symDIBCreateDebugLocation   uintptr
  98  
  99  	// Metadata operations
 100  	symSetSubprogram     uintptr
 101  	symGetSubprogram     uintptr
 102  	symTemporaryMDNode   uintptr
 103  	symMDReplaceAllUses  uintptr
 104  	symGetMetadataKind   uintptr
 105  
 106  	// DIFile/DILocation accessors
 107  	symDIFileGetDir      uintptr
 108  	symDIFileGetFilename uintptr
 109  	symDIFileGetSource   uintptr
 110  	symDILocGetLine      uintptr
 111  	symDILocGetColumn    uintptr
 112  	symDILocGetScope     uintptr
 113  	symDILocGetInlinedAt uintptr
 114  	symDIScopeGetFile    uintptr
 115  	symDISubprogramGetLine uintptr
 116  
 117  	// Glue: insert dbg value record
 118  	symGoInsertDbgValueRecord uintptr
 119  )
 120  
 121  func registerDIBuilder() {
 122  	symCreateDIBuilder = mustSym(libLLVM, "LLVMCreateDIBuilder")
 123  	symDisposeDIBuilder = mustSym(libLLVM, "LLVMDisposeDIBuilder")
 124  	symDIBuilderFinalize = mustSym(libLLVM, "LLVMDIBuilderFinalize")
 125  	symMoxieCreateCompileUnit = mustSym(libGlue, "MoxieCreateCompileUnit")
 126  	symDIBCreateFile = mustSym(libLLVM, "LLVMDIBuilderCreateFile")
 127  	symDIBCreateLexBlock = mustSym(libLLVM, "LLVMDIBuilderCreateLexicalBlock")
 128  	symDIBCreateLexBlockFile = mustSym(libLLVM, "LLVMDIBuilderCreateLexicalBlockFile")
 129  	symDIBCreateFunction = mustSym(libLLVM, "LLVMDIBuilderCreateFunction")
 130  	symDIBCreateAutoVar = mustSym(libLLVM, "LLVMDIBuilderCreateAutoVariable")
 131  	symDIBCreateParamVar = mustSym(libLLVM, "LLVMDIBuilderCreateParameterVariable")
 132  	symDIBCreateBasicType = mustSym(libLLVM, "LLVMDIBuilderCreateBasicType")
 133  	symDIBCreatePointerType = mustSym(libLLVM, "LLVMDIBuilderCreatePointerType")
 134  	symDIBCreateSubrtnType = mustSym(libLLVM, "LLVMDIBuilderCreateSubroutineType")
 135  	symMoxieCreateStructType = mustSym(libGlue, "MoxieCreateStructType")
 136  	symDIBCreateMemberType = mustSym(libLLVM, "LLVMDIBuilderCreateMemberType")
 137  	symDIBCreateArrayType = mustSym(libLLVM, "LLVMDIBuilderCreateArrayType")
 138  	symDIBCreateTypedef = mustSym(libLLVM, "LLVMDIBuilderCreateTypedef")
 139  	symDIBCreateReplaceableType = mustSym(libLLVM, "LLVMDIBuilderCreateReplaceableCompositeType")
 140  	symDIBCreateGlobalVarExpr = mustSym(libLLVM, "LLVMDIBuilderCreateGlobalVariableExpression")
 141  	symDIBGetOrCreateSubrange = mustSym(libLLVM, "LLVMDIBuilderGetOrCreateSubrange")
 142  	symDIBGetOrCreateArray = mustSym(libLLVM, "LLVMDIBuilderGetOrCreateArray")
 143  	symDIBGetOrCreateTypeArray = mustSym(libLLVM, "LLVMDIBuilderGetOrCreateTypeArray")
 144  	symDIBCreateExpression = mustSym(libLLVM, "LLVMDIBuilderCreateExpression")
 145  	symDIBCreateDebugLocation = mustSym(libLLVM, "LLVMDIBuilderCreateDebugLocation")
 146  
 147  	symSetSubprogram = mustSym(libLLVM, "LLVMSetSubprogram")
 148  	symGetSubprogram = mustSym(libLLVM, "LLVMGetSubprogram")
 149  	symTemporaryMDNode = mustSym(libLLVM, "LLVMTemporaryMDNode")
 150  	symMDReplaceAllUses = mustSym(libLLVM, "LLVMMetadataReplaceAllUsesWith")
 151  	symGetMetadataKind = mustSym(libLLVM, "LLVMGetMetadataKind")
 152  
 153  	symDIFileGetDir = mustSym(libLLVM, "LLVMDIFileGetDirectory")
 154  	symDIFileGetFilename = mustSym(libLLVM, "LLVMDIFileGetFilename")
 155  	symDIFileGetSource = mustSym(libLLVM, "LLVMDIFileGetSource")
 156  	symDILocGetLine = mustSym(libLLVM, "LLVMDILocationGetLine")
 157  	symDILocGetColumn = mustSym(libLLVM, "LLVMDILocationGetColumn")
 158  	symDILocGetScope = mustSym(libLLVM, "LLVMDILocationGetScope")
 159  	symDILocGetInlinedAt = mustSym(libLLVM, "LLVMDILocationGetInlinedAt")
 160  	symDIScopeGetFile = mustSym(libLLVM, "LLVMDIScopeGetFile")
 161  	symDISubprogramGetLine = mustSym(libLLVM, "LLVMDISubprogramGetLine")
 162  
 163  	if libGlue != 0 {
 164  		symGoInsertDbgValueRecord = trySym(libGlue, "LLVMGoDIBuilderInsertDbgValueRecordAtEnd")
 165  	}
 166  }
 167  
 168  func NewDIBuilder(m Module) *DIBuilder {
 169  	r, _, _ := purego.SyscallN(symCreateDIBuilder, m.C)
 170  	return &DIBuilder{C: r, m: m}
 171  }
 172  
 173  func (d *DIBuilder) Destroy() {
 174  	purego.SyscallN(symDisposeDIBuilder, d.C)
 175  }
 176  
 177  func (d *DIBuilder) Finalize() {
 178  	purego.SyscallN(symDIBuilderFinalize, d.C)
 179  }
 180  
 181  type DICompileUnit struct {
 182  	Language       DwarfLang
 183  	File           string
 184  	Dir            string
 185  	Producer       string
 186  	Optimized      bool
 187  	Flags          string
 188  	RuntimeVersion int
 189  	SysRoot        string
 190  	SDK            string
 191  }
 192  
 193  func (d *DIBuilder) CreateCompileUnit(cu DICompileUnit) Metadata {
 194  	cfile := cString(cu.File)
 195  	cdir := cString(cu.Dir)
 196  	fileMD, _, _ := purego.SyscallN(symDIBCreateFile, d.C, cfile, uintptr(len(cu.File)), cdir, uintptr(len(cu.Dir)))
 197  	cprod := cString(cu.Producer)
 198  	csysroot := cString(cu.SysRoot)
 199  	csdk := cString(cu.SDK)
 200  	r, _, _ := purego.SyscallN(symMoxieCreateCompileUnit, d.C,
 201  		uintptr(cu.Language), fileMD,
 202  		cprod, uintptr(len(cu.Producer)),
 203  		boolToInt(cu.Optimized),
 204  		uintptr(cu.RuntimeVersion),
 205  		csysroot, uintptr(len(cu.SysRoot)),
 206  		csdk, uintptr(len(cu.SDK)))
 207  	runtime.KeepAlive(cu)
 208  	return Metadata{r}
 209  }
 210  
 211  func (d *DIBuilder) CreateFile(filename, dir string) Metadata {
 212  	cfile := cString(filename)
 213  	cdir := cString(dir)
 214  	r, _, _ := purego.SyscallN(symDIBCreateFile, d.C, cfile, uintptr(len(filename)), cdir, uintptr(len(dir)))
 215  	runtime.KeepAlive(filename)
 216  	runtime.KeepAlive(dir)
 217  	return Metadata{r}
 218  }
 219  
 220  type DILexicalBlock struct {
 221  	File   Metadata
 222  	Line   int
 223  	Column int
 224  }
 225  
 226  func (d *DIBuilder) CreateLexicalBlock(scope Metadata, b DILexicalBlock) Metadata {
 227  	r, _, _ := purego.SyscallN(symDIBCreateLexBlock, d.C, scope.C, b.File.C, uintptr(b.Line), uintptr(b.Column))
 228  	return Metadata{r}
 229  }
 230  
 231  func (d *DIBuilder) CreateLexicalBlockFile(scope, file Metadata, discriminator int) Metadata {
 232  	r, _, _ := purego.SyscallN(symDIBCreateLexBlockFile, d.C, scope.C, file.C, uintptr(discriminator))
 233  	return Metadata{r}
 234  }
 235  
 236  type DIFunction struct {
 237  	Name         string
 238  	LinkageName  string
 239  	File         Metadata
 240  	Line         int
 241  	Type         Metadata
 242  	LocalToUnit  bool
 243  	IsDefinition bool
 244  	ScopeLine    int
 245  	Flags        int
 246  	Optimized    bool
 247  }
 248  
 249  func (d *DIBuilder) CreateFunction(scope Metadata, f DIFunction) Metadata {
 250  	cname := cString(f.Name)
 251  	clinkage := cString(f.LinkageName)
 252  	r, _, _ := purego.SyscallN(symDIBCreateFunction, d.C, scope.C,
 253  		cname, uintptr(len(f.Name)),
 254  		clinkage, uintptr(len(f.LinkageName)),
 255  		f.File.C, uintptr(f.Line), f.Type.C,
 256  		boolToInt(f.LocalToUnit), boolToInt(f.IsDefinition),
 257  		uintptr(f.ScopeLine), uintptr(f.Flags), boolToInt(f.Optimized))
 258  	runtime.KeepAlive(f.Name)
 259  	runtime.KeepAlive(f.LinkageName)
 260  	return Metadata{r}
 261  }
 262  
 263  type DIAutoVariable struct {
 264  	Name           string
 265  	File           Metadata
 266  	Line           int
 267  	Type           Metadata
 268  	AlwaysPreserve bool
 269  	Flags          int
 270  	AlignInBits    uint32
 271  }
 272  
 273  func (d *DIBuilder) CreateAutoVariable(scope Metadata, v DIAutoVariable) Metadata {
 274  	cname := cString(v.Name)
 275  	r, _, _ := purego.SyscallN(symDIBCreateAutoVar, d.C, scope.C,
 276  		cname, uintptr(len(v.Name)),
 277  		v.File.C, uintptr(v.Line), v.Type.C,
 278  		boolToInt(v.AlwaysPreserve), uintptr(v.Flags), uintptr(v.AlignInBits))
 279  	runtime.KeepAlive(v.Name)
 280  	return Metadata{r}
 281  }
 282  
 283  type DIParameterVariable struct {
 284  	Name           string
 285  	File           Metadata
 286  	Line           int
 287  	Type           Metadata
 288  	AlwaysPreserve bool
 289  	Flags          int
 290  	ArgNo          int
 291  }
 292  
 293  func (d *DIBuilder) CreateParameterVariable(scope Metadata, v DIParameterVariable) Metadata {
 294  	cname := cString(v.Name)
 295  	r, _, _ := purego.SyscallN(symDIBCreateParamVar, d.C, scope.C,
 296  		cname, uintptr(len(v.Name)),
 297  		uintptr(v.ArgNo),
 298  		v.File.C, uintptr(v.Line), v.Type.C,
 299  		boolToInt(v.AlwaysPreserve), uintptr(v.Flags))
 300  	runtime.KeepAlive(v.Name)
 301  	return Metadata{r}
 302  }
 303  
 304  type DIBasicType struct {
 305  	Name       string
 306  	SizeInBits uint64
 307  	Encoding   DwarfTypeEncoding
 308  }
 309  
 310  func (d *DIBuilder) CreateBasicType(t DIBasicType) Metadata {
 311  	cname := cString(t.Name)
 312  	r, _, _ := purego.SyscallN(symDIBCreateBasicType, d.C,
 313  		cname, uintptr(len(t.Name)),
 314  		uintptr(t.SizeInBits), uintptr(t.Encoding), 0)
 315  	runtime.KeepAlive(t.Name)
 316  	return Metadata{r}
 317  }
 318  
 319  type DIPointerType struct {
 320  	Pointee     Metadata
 321  	SizeInBits  uint64
 322  	AlignInBits uint32
 323  	AddressSpace uint32
 324  	Name        string
 325  }
 326  
 327  func (d *DIBuilder) CreatePointerType(t DIPointerType) Metadata {
 328  	cname := cString(t.Name)
 329  	r, _, _ := purego.SyscallN(symDIBCreatePointerType, d.C,
 330  		t.Pointee.C, uintptr(t.SizeInBits), uintptr(t.AlignInBits), uintptr(t.AddressSpace),
 331  		cname, uintptr(len(t.Name)))
 332  	runtime.KeepAlive(t.Name)
 333  	return Metadata{r}
 334  }
 335  
 336  type DISubroutineType struct {
 337  	File       Metadata
 338  	Parameters []Metadata
 339  	Flags      int
 340  }
 341  
 342  func (d *DIBuilder) CreateSubroutineType(t DISubroutineType) Metadata {
 343  	r, _, _ := purego.SyscallN(symDIBCreateSubrtnType, d.C,
 344  		t.File.C, metadataRefPtr(t.Parameters), uintptr(len(t.Parameters)), uintptr(t.Flags))
 345  	return Metadata{r}
 346  }
 347  
 348  type DIStructType struct {
 349  	Name        string
 350  	File        Metadata
 351  	Line        int
 352  	SizeInBits  uint64
 353  	AlignInBits uint32
 354  	Flags       int
 355  	DerivedFrom Metadata
 356  	Elements    []Metadata
 357  	VTableHolder Metadata
 358  	UniqueID    string
 359  }
 360  
 361  func (d *DIBuilder) CreateStructType(scope Metadata, t DIStructType) Metadata {
 362  	cname := cString(t.Name)
 363  	cunique := cString(t.UniqueID)
 364  	var elemsPtr uintptr
 365  	if len(t.Elements) > 0 {
 366  		elemsPtr = metadataRefPtr(t.Elements)
 367  	}
 368  	r, _, _ := purego.SyscallN(symMoxieCreateStructType, d.C, scope.C,
 369  		cname, uintptr(len(t.Name)),
 370  		t.File.C, uintptr(t.Line),
 371  		uintptr(t.SizeInBits), uintptr(t.AlignInBits), uintptr(t.Flags),
 372  		t.DerivedFrom.C, elemsPtr, uintptr(len(t.Elements)),
 373  		t.VTableHolder.C,
 374  		cunique, uintptr(len(t.UniqueID)))
 375  	runtime.KeepAlive(t.Name)
 376  	runtime.KeepAlive(t.UniqueID)
 377  	return Metadata{r}
 378  }
 379  
 380  type DIMemberType struct {
 381  	Name         string
 382  	File         Metadata
 383  	Line         int
 384  	SizeInBits   uint64
 385  	AlignInBits  uint32
 386  	OffsetInBits uint64
 387  	Flags        int
 388  	Type         Metadata
 389  }
 390  
 391  func (d *DIBuilder) CreateMemberType(scope Metadata, t DIMemberType) Metadata {
 392  	cname := cString(t.Name)
 393  	r, _, _ := purego.SyscallN(symDIBCreateMemberType, d.C, scope.C,
 394  		cname, uintptr(len(t.Name)),
 395  		t.File.C, uintptr(t.Line),
 396  		uintptr(t.SizeInBits), uintptr(t.AlignInBits), uintptr(t.OffsetInBits),
 397  		uintptr(t.Flags), t.Type.C)
 398  	runtime.KeepAlive(t.Name)
 399  	return Metadata{r}
 400  }
 401  
 402  type DISubrange struct {
 403  	Lo    int64
 404  	Count int64
 405  }
 406  
 407  type DIArrayType struct {
 408  	SizeInBits  uint64
 409  	AlignInBits uint32
 410  	ElementType Metadata
 411  	Subscripts  []DISubrange
 412  }
 413  
 414  func (d *DIBuilder) CreateArrayType(t DIArrayType) Metadata {
 415  	subscriptsSlice := make([]Metadata, len(t.Subscripts))
 416  	for i, s := range t.Subscripts {
 417  		subscriptsSlice[i] = d.getOrCreateSubrange(s.Lo, s.Count)
 418  	}
 419  	r, _, _ := purego.SyscallN(symDIBCreateArrayType, d.C,
 420  		uintptr(t.SizeInBits), uintptr(t.AlignInBits), t.ElementType.C,
 421  		metadataRefPtr(subscriptsSlice), uintptr(len(subscriptsSlice)))
 422  	return Metadata{r}
 423  }
 424  
 425  type DITypedef struct {
 426  	Type        Metadata
 427  	Name        string
 428  	File        Metadata
 429  	Line        int
 430  	Context     Metadata
 431  	AlignInBits uint32
 432  }
 433  
 434  func (d *DIBuilder) CreateTypedef(t DITypedef) Metadata {
 435  	cname := cString(t.Name)
 436  	r, _, _ := purego.SyscallN(symDIBCreateTypedef, d.C,
 437  		t.Type.C, cname, uintptr(len(t.Name)),
 438  		t.File.C, uintptr(t.Line), t.Context.C, uintptr(t.AlignInBits))
 439  	runtime.KeepAlive(t.Name)
 440  	return Metadata{r}
 441  }
 442  
 443  type DIReplaceableCompositeType struct {
 444  	Tag         dwarf.Tag
 445  	Name        string
 446  	File        Metadata
 447  	Line        int
 448  	RuntimeLang int
 449  	SizeInBits  uint64
 450  	AlignInBits uint32
 451  	Flags       int
 452  	UniqueID    string
 453  }
 454  
 455  func (d *DIBuilder) CreateReplaceableCompositeType(scope Metadata, t DIReplaceableCompositeType) Metadata {
 456  	cname := cString(t.Name)
 457  	cunique := cString(t.UniqueID)
 458  	r, _, _ := purego.SyscallN(symDIBCreateReplaceableType, d.C,
 459  		uintptr(t.Tag), cname, uintptr(len(t.Name)),
 460  		scope.C, t.File.C, uintptr(t.Line),
 461  		uintptr(t.RuntimeLang), uintptr(t.SizeInBits), uintptr(t.AlignInBits),
 462  		uintptr(t.Flags), cunique, uintptr(len(t.UniqueID)))
 463  	runtime.KeepAlive(t.Name)
 464  	runtime.KeepAlive(t.UniqueID)
 465  	return Metadata{r}
 466  }
 467  
 468  type DIGlobalVariableExpression struct {
 469  	Name        string
 470  	LinkageName string
 471  	File        Metadata
 472  	Line        int
 473  	Type        Metadata
 474  	LocalToUnit bool
 475  	Expr        Metadata
 476  	Decl        Metadata
 477  	AlignInBits uint32
 478  }
 479  
 480  func (d *DIBuilder) CreateGlobalVariableExpression(scope Metadata, g DIGlobalVariableExpression) Metadata {
 481  	cname := cString(g.Name)
 482  	clinkage := cString(g.LinkageName)
 483  	r, _, _ := purego.SyscallN(symDIBCreateGlobalVarExpr, d.C, scope.C,
 484  		cname, uintptr(len(g.Name)),
 485  		clinkage, uintptr(len(g.LinkageName)),
 486  		g.File.C, uintptr(g.Line), g.Type.C,
 487  		boolToInt(g.LocalToUnit), g.Expr.C, g.Decl.C, uintptr(g.AlignInBits))
 488  	runtime.KeepAlive(g.Name)
 489  	runtime.KeepAlive(g.LinkageName)
 490  	return Metadata{r}
 491  }
 492  
 493  func (d *DIBuilder) CreateExpression(addr []uint64) Metadata {
 494  	var ptr uintptr
 495  	if len(addr) > 0 {
 496  		ptr = uintptr(unsafe.Pointer(&addr[0]))
 497  	}
 498  	r, _, _ := purego.SyscallN(symDIBCreateExpression, d.C, ptr, uintptr(len(addr)))
 499  	return Metadata{r}
 500  }
 501  
 502  func (d *DIBuilder) getOrCreateSubrange(lo, count int64) Metadata {
 503  	r, _, _ := purego.SyscallN(symDIBGetOrCreateSubrange, d.C, uintptr(lo), uintptr(count))
 504  	return Metadata{r}
 505  }
 506  
 507  func (d *DIBuilder) getOrCreateArray(values []Metadata) Metadata {
 508  	r, _, _ := purego.SyscallN(symDIBGetOrCreateArray, d.C, metadataRefPtr(values), uintptr(len(values)))
 509  	return Metadata{r}
 510  }
 511  
 512  func (d *DIBuilder) getOrCreateTypeArray(values []Metadata) Metadata {
 513  	r, _, _ := purego.SyscallN(symDIBGetOrCreateTypeArray, d.C, metadataRefPtr(values), uintptr(len(values)))
 514  	return Metadata{r}
 515  }
 516  
 517  func (d *DIBuilder) CreateDebugLocation(ctx Context, line, col uint, scope, inlinedAt Metadata) Metadata {
 518  	r, _, _ := purego.SyscallN(symDIBCreateDebugLocation, ctx.C, uintptr(line), uintptr(col), scope.C, inlinedAt.C)
 519  	return Metadata{r}
 520  }
 521  
 522  func (d *DIBuilder) InsertValueAtEnd(v Value, diVarInfo, expr Metadata, l DebugLoc, bb BasicBlock) {
 523  	if symGoInsertDbgValueRecord == 0 {
 524  		return
 525  	}
 526  	loc, _, _ := purego.SyscallN(symDIBCreateDebugLocation, d.m.Context().C,
 527  		uintptr(l.Line), uintptr(l.Col), l.Scope.C, l.InlinedAt.C)
 528  	purego.SyscallN(symGoInsertDbgValueRecord, d.C, v.C, diVarInfo.C, expr.C, loc, bb.C)
 529  }
 530  
 531  // Metadata operations
 532  
 533  func (v Value) SetSubprogram(sp Metadata) {
 534  	purego.SyscallN(symSetSubprogram, v.C, sp.C)
 535  }
 536  
 537  func (v Value) Subprogram() Metadata {
 538  	r, _, _ := purego.SyscallN(symGetSubprogram, v.C)
 539  	return Metadata{r}
 540  }
 541  
 542  func (c Context) TemporaryMDNode(mds []Metadata) Metadata {
 543  	r, _, _ := purego.SyscallN(symTemporaryMDNode, c.C, metadataRefPtr(mds), uintptr(len(mds)))
 544  	return Metadata{r}
 545  }
 546  
 547  func (md Metadata) ReplaceAllUsesWith(new Metadata) {
 548  	purego.SyscallN(symMDReplaceAllUses, md.C, new.C)
 549  }
 550  
 551  func (md Metadata) Kind() MetadataKind {
 552  	r, _, _ := purego.SyscallN(symGetMetadataKind, md.C)
 553  	return MetadataKind(r)
 554  }
 555  
 556  // DIFile accessors
 557  
 558  func (md Metadata) FileDirectory() string {
 559  	var length uintptr
 560  	r, _, _ := purego.SyscallN(symDIFileGetDir, md.C, uintptr(unsafe.Pointer(&length)))
 561  	return goStringN(r, int(length))
 562  }
 563  
 564  func (md Metadata) FileFilename() string {
 565  	var length uintptr
 566  	r, _, _ := purego.SyscallN(symDIFileGetFilename, md.C, uintptr(unsafe.Pointer(&length)))
 567  	return goStringN(r, int(length))
 568  }
 569  
 570  func (md Metadata) FileSource() string {
 571  	var length uintptr
 572  	r, _, _ := purego.SyscallN(symDIFileGetSource, md.C, uintptr(unsafe.Pointer(&length)))
 573  	return goStringN(r, int(length))
 574  }
 575  
 576  // DILocation accessors
 577  
 578  func (md Metadata) LocationLine() uint {
 579  	r, _, _ := purego.SyscallN(symDILocGetLine, md.C)
 580  	return uint(r)
 581  }
 582  
 583  func (md Metadata) LocationColumn() uint {
 584  	r, _, _ := purego.SyscallN(symDILocGetColumn, md.C)
 585  	return uint(r)
 586  }
 587  
 588  func (md Metadata) LocationScope() Metadata {
 589  	r, _, _ := purego.SyscallN(symDILocGetScope, md.C)
 590  	return Metadata{r}
 591  }
 592  
 593  func (md Metadata) LocationInlinedAt() Metadata {
 594  	r, _, _ := purego.SyscallN(symDILocGetInlinedAt, md.C)
 595  	return Metadata{r}
 596  }
 597  
 598  func (md Metadata) ScopeFile() Metadata {
 599  	r, _, _ := purego.SyscallN(symDIScopeGetFile, md.C)
 600  	return Metadata{r}
 601  }
 602  
 603  func (md Metadata) SubprogramLine() uint {
 604  	r, _, _ := purego.SyscallN(symDISubprogramGetLine, md.C)
 605  	return uint(r)
 606  }
 607  
 608  // Encoding helpers for DWARF
 609  
 610  func DwarfTypeEncodingForType(tag dwarf.Tag) DwarfTypeEncoding {
 611  	switch tag {
 612  	case dwarf.TagBaseType:
 613  		return DW_ATE_signed
 614  	default:
 615  		return DW_ATE_signed
 616  	}
 617  }
 618