dibuilder.go raw

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