mirror of
https://github.com/golang/go.git
synced 2025-05-30 19:52:53 +00:00
cmd/internal/obj: simplify filename handling
The old Go object file format used linker symbols like "gofile..foo" to record references to the filename "foo". But the current object file format has a dedicated section for file names, so we don't need these useless prefixes anymore. Also, change DWARF generation to pass around the src.Pos directly, rather than the old file symbols, which it just turned back into a file index before writing out anyway. Finally, directly record the FileIndex into src.PosBase, so that we can skip the map lookups. Change-Id: Ia4a5ebfa95da271f2522e45befdb9f137c16d373 Reviewed-on: https://go-review.googlesource.com/c/go/+/523378 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
06f420fc19
commit
c9bb7ce2d7
@ -273,13 +273,11 @@ func insertInlCall(dwcalls *dwarf.InlCalls, inlIdx int, imap map[int]int) int {
|
|||||||
// Create new entry for this inline
|
// Create new entry for this inline
|
||||||
inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
|
inlinedFn := base.Ctxt.InlTree.InlinedFunction(inlIdx)
|
||||||
callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
|
callXPos := base.Ctxt.InlTree.CallPos(inlIdx)
|
||||||
callPos := base.Ctxt.PosTable.Pos(callXPos)
|
callPos := base.Ctxt.InnermostPos(callXPos)
|
||||||
callFileSym := base.Ctxt.Lookup(callPos.Base().SymFilename())
|
|
||||||
absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
|
absFnSym := base.Ctxt.DwFixups.AbsFuncDwarfSym(inlinedFn)
|
||||||
ic := dwarf.InlCall{
|
ic := dwarf.InlCall{
|
||||||
InlIndex: inlIdx,
|
InlIndex: inlIdx,
|
||||||
CallFile: callFileSym,
|
CallPos: callPos,
|
||||||
CallLine: uint32(callPos.RelLine()),
|
|
||||||
AbsFunSym: absFnSym,
|
AbsFunSym: absFnSym,
|
||||||
Root: parCallIdx == -1,
|
Root: parCallIdx == -1,
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ package dwarf
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"cmd/internal/src"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
@ -85,13 +86,12 @@ type Range struct {
|
|||||||
type FnState struct {
|
type FnState struct {
|
||||||
Name string
|
Name string
|
||||||
Info Sym
|
Info Sym
|
||||||
Filesym Sym
|
|
||||||
Loc Sym
|
Loc Sym
|
||||||
Ranges Sym
|
Ranges Sym
|
||||||
Absfn Sym
|
Absfn Sym
|
||||||
StartPC Sym
|
StartPC Sym
|
||||||
|
StartPos src.Pos
|
||||||
Size int64
|
Size int64
|
||||||
StartLine int32
|
|
||||||
External bool
|
External bool
|
||||||
Scopes []Scope
|
Scopes []Scope
|
||||||
InlCalls InlCalls
|
InlCalls InlCalls
|
||||||
@ -166,11 +166,8 @@ type InlCall struct {
|
|||||||
// index into ctx.InlTree describing the call inlined here
|
// index into ctx.InlTree describing the call inlined here
|
||||||
InlIndex int
|
InlIndex int
|
||||||
|
|
||||||
// Symbol of file containing inlined call site (really *obj.LSym).
|
// Position of the inlined call site.
|
||||||
CallFile Sym
|
CallPos src.Pos
|
||||||
|
|
||||||
// Line number of inlined call site.
|
|
||||||
CallLine uint32
|
|
||||||
|
|
||||||
// Dwarf abstract subroutine symbol (really *obj.LSym).
|
// Dwarf abstract subroutine symbol (really *obj.LSym).
|
||||||
AbsFunSym Sym
|
AbsFunSym Sym
|
||||||
@ -202,7 +199,6 @@ type Context interface {
|
|||||||
RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int)
|
RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int)
|
||||||
RecordChildDieOffsets(s Sym, vars []*Var, offsets []int32)
|
RecordChildDieOffsets(s Sym, vars []*Var, offsets []int32)
|
||||||
AddString(s Sym, v string)
|
AddString(s Sym, v string)
|
||||||
AddFileRef(s Sym, f interface{})
|
|
||||||
Logf(format string, args ...interface{})
|
Logf(format string, args ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,7 +1242,8 @@ func PutAbstractFunc(ctxt Context, s *FnState) error {
|
|||||||
// DW_AT_inlined value
|
// DW_AT_inlined value
|
||||||
putattr(ctxt, s.Absfn, abbrev, DW_FORM_data1, DW_CLS_CONSTANT, int64(DW_INL_inlined), nil)
|
putattr(ctxt, s.Absfn, abbrev, DW_FORM_data1, DW_CLS_CONSTANT, int64(DW_INL_inlined), nil)
|
||||||
|
|
||||||
putattr(ctxt, s.Absfn, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartLine), nil)
|
// TODO(mdempsky): Shouldn't we write out StartPos.FileIndex() too?
|
||||||
|
putattr(ctxt, s.Absfn, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartPos.RelLine()), nil)
|
||||||
|
|
||||||
var ev int64
|
var ev int64
|
||||||
if s.External {
|
if s.External {
|
||||||
@ -1335,9 +1332,9 @@ func putInlinedFunc(ctxt Context, s *FnState, callIdx int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit call file, line attrs.
|
// Emit call file, line attrs.
|
||||||
ctxt.AddFileRef(s.Info, ic.CallFile)
|
putattr(ctxt, s.Info, abbrev, DW_FORM_data4, DW_CLS_CONSTANT, int64(1+ic.CallPos.FileIndex()), nil) // 1-based file table
|
||||||
form := int(expandPseudoForm(DW_FORM_udata_pseudo))
|
form := int(expandPseudoForm(DW_FORM_udata_pseudo))
|
||||||
putattr(ctxt, s.Info, abbrev, form, DW_CLS_CONSTANT, int64(ic.CallLine), nil)
|
putattr(ctxt, s.Info, abbrev, form, DW_CLS_CONSTANT, int64(ic.CallPos.RelLine()), nil)
|
||||||
|
|
||||||
// Variables associated with this inlined routine instance.
|
// Variables associated with this inlined routine instance.
|
||||||
vars := ic.InlVars
|
vars := ic.InlVars
|
||||||
@ -1438,8 +1435,8 @@ func PutDefaultFunc(ctxt Context, s *FnState, isWrapper bool) error {
|
|||||||
if isWrapper {
|
if isWrapper {
|
||||||
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
|
putattr(ctxt, s.Info, abbrev, DW_FORM_flag, DW_CLS_FLAG, int64(1), 0)
|
||||||
} else {
|
} else {
|
||||||
ctxt.AddFileRef(s.Info, s.Filesym)
|
putattr(ctxt, s.Info, abbrev, DW_FORM_data4, DW_CLS_CONSTANT, int64(1+s.StartPos.FileIndex()), nil) // 1-based file index
|
||||||
putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartLine), nil)
|
putattr(ctxt, s.Info, abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(s.StartPos.RelLine()), nil)
|
||||||
|
|
||||||
var ev int64
|
var ev int64
|
||||||
if s.External {
|
if s.External {
|
||||||
|
@ -48,7 +48,7 @@ func (ctxt *Link) generateDebugLinesSymbol(s, lines *LSym) {
|
|||||||
line := int64(1)
|
line := int64(1)
|
||||||
pc := s.Func().Text.Pc
|
pc := s.Func().Text.Pc
|
||||||
var lastpc int64 // last PC written to line table, not last PC in func
|
var lastpc int64 // last PC written to line table, not last PC in func
|
||||||
name := ""
|
fileIndex := 1
|
||||||
prologue, wrotePrologue := false, false
|
prologue, wrotePrologue := false, false
|
||||||
// Walk the progs, generating the DWARF table.
|
// Walk the progs, generating the DWARF table.
|
||||||
for p := s.Func().Text; p != nil; p = p.Link {
|
for p := s.Func().Text; p != nil; p = p.Link {
|
||||||
@ -58,15 +58,15 @@ func (ctxt *Link) generateDebugLinesSymbol(s, lines *LSym) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newStmt := p.Pos.IsStmt() != src.PosNotStmt
|
newStmt := p.Pos.IsStmt() != src.PosNotStmt
|
||||||
newName, newLine := ctxt.getFileSymbolAndLine(p.Pos)
|
newFileIndex, newLine := ctxt.getFileIndexAndLine(p.Pos)
|
||||||
|
newFileIndex++ // 1 indexing for the table
|
||||||
|
|
||||||
// Output debug info.
|
// Output debug info.
|
||||||
wrote := false
|
wrote := false
|
||||||
if name != newName {
|
if newFileIndex != fileIndex {
|
||||||
newFile := ctxt.PosTable.FileIndex(newName) + 1 // 1 indexing for the table.
|
|
||||||
dctxt.AddUint8(lines, dwarf.DW_LNS_set_file)
|
dctxt.AddUint8(lines, dwarf.DW_LNS_set_file)
|
||||||
dwarf.Uleb128put(dctxt, lines, int64(newFile))
|
dwarf.Uleb128put(dctxt, lines, int64(newFileIndex))
|
||||||
name = newName
|
fileIndex = newFileIndex
|
||||||
wrote = true
|
wrote = true
|
||||||
}
|
}
|
||||||
if prologue && !wrotePrologue {
|
if prologue && !wrotePrologue {
|
||||||
@ -258,16 +258,6 @@ func (c dwCtxt) AddDWARFAddrSectionOffset(s dwarf.Sym, t interface{}, ofs int64)
|
|||||||
r.Type = objabi.R_DWARFSECREF
|
r.Type = objabi.R_DWARFSECREF
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c dwCtxt) AddFileRef(s dwarf.Sym, f interface{}) {
|
|
||||||
ls := s.(*LSym)
|
|
||||||
rsym := f.(*LSym)
|
|
||||||
fidx := c.Link.PosTable.FileIndex(rsym.Name)
|
|
||||||
// Note the +1 here -- the value we're writing is going to be an
|
|
||||||
// index into the DWARF line table file section, whose entries
|
|
||||||
// are numbered starting at 1, not 0.
|
|
||||||
ls.WriteInt(c.Link, ls.Size, 4, int64(fidx+1))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 {
|
func (c dwCtxt) CurrentOffset(s dwarf.Sym) int64 {
|
||||||
ls := s.(*LSym)
|
ls := s.(*LSym)
|
||||||
return ls.Size
|
return ls.Size
|
||||||
@ -329,17 +319,13 @@ func (s *LSym) Length(dwarfContext interface{}) int64 {
|
|||||||
return s.Size
|
return s.Size
|
||||||
}
|
}
|
||||||
|
|
||||||
// fileSymbol returns a symbol corresponding to the source file of the
|
// textPos returns the source position of the first instruction (prog)
|
||||||
// first instruction (prog) of the specified function. This will
|
// of the specified function.
|
||||||
// presumably be the file in which the function is defined.
|
func textPos(fn *LSym) src.XPos {
|
||||||
func (ctxt *Link) fileSymbol(fn *LSym) *LSym {
|
if p := fn.Func().Text; p != nil {
|
||||||
p := fn.Func().Text
|
return p.Pos
|
||||||
if p != nil {
|
|
||||||
f, _ := ctxt.getFileSymbolAndLine(p.Pos)
|
|
||||||
fsym := ctxt.Lookup(f)
|
|
||||||
return fsym
|
|
||||||
}
|
}
|
||||||
return nil
|
return src.NoXPos
|
||||||
}
|
}
|
||||||
|
|
||||||
// populateDWARF fills in the DWARF Debugging Information Entries for
|
// populateDWARF fills in the DWARF Debugging Information Entries for
|
||||||
@ -362,17 +348,19 @@ func (ctxt *Link) populateDWARF(curfn Func, s *LSym) {
|
|||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
dwctxt := dwCtxt{ctxt}
|
dwctxt := dwCtxt{ctxt}
|
||||||
filesym := ctxt.fileSymbol(s)
|
startPos := ctxt.InnermostPos(textPos(s))
|
||||||
|
if !startPos.IsKnown() || startPos.RelLine() != uint(s.Func().StartLine) {
|
||||||
|
panic("bad startPos")
|
||||||
|
}
|
||||||
fnstate := &dwarf.FnState{
|
fnstate := &dwarf.FnState{
|
||||||
Name: s.Name,
|
Name: s.Name,
|
||||||
Info: info,
|
Info: info,
|
||||||
Filesym: filesym,
|
|
||||||
Loc: loc,
|
Loc: loc,
|
||||||
Ranges: ranges,
|
Ranges: ranges,
|
||||||
Absfn: absfunc,
|
Absfn: absfunc,
|
||||||
StartPC: s,
|
StartPC: s,
|
||||||
Size: s.Size,
|
Size: s.Size,
|
||||||
StartLine: s.Func().StartLine,
|
StartPos: startPos,
|
||||||
External: !s.Static(),
|
External: !s.Static(),
|
||||||
Scopes: scopes,
|
Scopes: scopes,
|
||||||
InlCalls: inlcalls,
|
InlCalls: inlcalls,
|
||||||
@ -434,13 +422,12 @@ func (ctxt *Link) DwarfAbstractFunc(curfn Func, s *LSym) {
|
|||||||
s.NewFuncInfo()
|
s.NewFuncInfo()
|
||||||
}
|
}
|
||||||
scopes, _ := ctxt.DebugInfo(s, absfn, curfn)
|
scopes, _ := ctxt.DebugInfo(s, absfn, curfn)
|
||||||
_, startLine := ctxt.getFileSymbolAndLine(curfn.Pos())
|
|
||||||
dwctxt := dwCtxt{ctxt}
|
dwctxt := dwCtxt{ctxt}
|
||||||
fnstate := dwarf.FnState{
|
fnstate := dwarf.FnState{
|
||||||
Name: s.Name,
|
Name: s.Name,
|
||||||
Info: absfn,
|
Info: absfn,
|
||||||
Absfn: absfn,
|
Absfn: absfn,
|
||||||
StartLine: startLine,
|
StartPos: ctxt.InnermostPos(curfn.Pos()),
|
||||||
External: !s.Static(),
|
External: !s.Static(),
|
||||||
Scopes: scopes,
|
Scopes: scopes,
|
||||||
UseBASEntries: ctxt.UseBASEntries,
|
UseBASEntries: ctxt.UseBASEntries,
|
||||||
|
@ -14,22 +14,14 @@ func (ctxt *Link) AddImport(pkg string, fingerprint goobj.FingerprintType) {
|
|||||||
ctxt.Imports = append(ctxt.Imports, goobj.ImportedPkg{Pkg: pkg, Fingerprint: fingerprint})
|
ctxt.Imports = append(ctxt.Imports, goobj.ImportedPkg{Pkg: pkg, Fingerprint: fingerprint})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFileSymbolAndLine returns the relative file symbol and relative line
|
|
||||||
// number for a position (i.e., as adjusted by a //line directive). This is the
|
|
||||||
// file/line visible in the final binary (pcfile, pcln, etc).
|
|
||||||
func (ctxt *Link) getFileSymbolAndLine(xpos src.XPos) (f string, l int32) {
|
|
||||||
pos := ctxt.InnermostPos(xpos)
|
|
||||||
if !pos.IsKnown() {
|
|
||||||
pos = src.Pos{}
|
|
||||||
}
|
|
||||||
return pos.SymFilename(), int32(pos.RelLine())
|
|
||||||
}
|
|
||||||
|
|
||||||
// getFileIndexAndLine returns the relative file index (local to the CU), and
|
// getFileIndexAndLine returns the relative file index (local to the CU), and
|
||||||
// the relative line number for a position (i.e., as adjusted by a //line
|
// the relative line number for a position (i.e., as adjusted by a //line
|
||||||
// directive). This is the file/line visible in the final binary (pcfile, pcln,
|
// directive). This is the file/line visible in the final binary (pcfile, pcln,
|
||||||
// etc).
|
// etc).
|
||||||
func (ctxt *Link) getFileIndexAndLine(xpos src.XPos) (int, int32) {
|
func (ctxt *Link) getFileIndexAndLine(xpos src.XPos) (int, int32) {
|
||||||
f, l := ctxt.getFileSymbolAndLine(xpos)
|
pos := ctxt.InnermostPos(xpos)
|
||||||
return ctxt.PosTable.FileIndex(f), l
|
if !pos.IsKnown() {
|
||||||
|
pos = src.Pos{}
|
||||||
|
}
|
||||||
|
return pos.FileIndex(), int32(pos.RelLine())
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,15 @@ func TestGetFileSymbolAndLine(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
f, l := ctxt.getFileSymbolAndLine(ctxt.PosTable.XPos(test.pos))
|
fileIndex, line := ctxt.getFileIndexAndLine(ctxt.PosTable.XPos(test.pos))
|
||||||
got := fmt.Sprintf("%s:%d", f, l)
|
|
||||||
if got != src.FileSymPrefix+test.want {
|
file := "??"
|
||||||
|
if fileIndex >= 0 {
|
||||||
|
file = ctxt.PosTable.FileTable()[fileIndex]
|
||||||
|
}
|
||||||
|
got := fmt.Sprintf("%s:%d", file, line)
|
||||||
|
|
||||||
|
if got != test.want {
|
||||||
t.Errorf("ctxt.getFileSymbolAndLine(%v) = %q, want %q", test.pos, got, test.want)
|
t.Errorf("ctxt.getFileSymbolAndLine(%v) = %q, want %q", test.pos, got, test.want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func (ctxt *Link) InitTextSym(s *LSym, flag int, start src.XPos) {
|
|||||||
// startLine should be the same line number that would be displayed via
|
// startLine should be the same line number that would be displayed via
|
||||||
// pcln, etc for the declaration (i.e., relative line number, as
|
// pcln, etc for the declaration (i.e., relative line number, as
|
||||||
// adjusted by //line).
|
// adjusted by //line).
|
||||||
_, startLine := ctxt.getFileSymbolAndLine(start)
|
_, startLine := ctxt.getFileIndexAndLine(start)
|
||||||
|
|
||||||
s.Func().FuncID = objabi.GetFuncID(s.Name, flag&WRAPPER != 0 || flag&ABIWRAPPER != 0)
|
s.Func().FuncID = objabi.GetFuncID(s.Name, flag&WRAPPER != 0 || flag&ABIWRAPPER != 0)
|
||||||
s.Func().FuncFlag = ctxt.toFuncFlag(flag)
|
s.Func().FuncFlag = ctxt.toFuncFlag(flag)
|
||||||
|
@ -449,10 +449,6 @@ func (ctxt *Link) traverseFuncAux(flag traverseFlag, fsym *LSym, fn func(parent
|
|||||||
if call.Func != nil {
|
if call.Func != nil {
|
||||||
fn(fsym, call.Func)
|
fn(fsym, call.Func)
|
||||||
}
|
}
|
||||||
f, _ := ctxt.getFileSymbolAndLine(call.Pos)
|
|
||||||
if filesym := ctxt.Lookup(f); filesym != nil {
|
|
||||||
fn(fsym, filesym)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auxsyms := []*LSym{fninfo.dwarfRangesSym, fninfo.dwarfLocSym, fninfo.dwarfDebugLinesSym, fninfo.dwarfInfoSym, fninfo.WasmImportSym, fninfo.sehUnwindInfoSym}
|
auxsyms := []*LSym{fninfo.dwarfRangesSym, fninfo.dwarfLocSym, fninfo.dwarfDebugLinesSym, fninfo.dwarfInfoSym, fninfo.WasmImportSym, fninfo.sehUnwindInfoSym}
|
||||||
|
@ -116,9 +116,9 @@ func (p Pos) RelCol() uint {
|
|||||||
// AbsFilename() returns the absolute filename recorded with the position's base.
|
// AbsFilename() returns the absolute filename recorded with the position's base.
|
||||||
func (p Pos) AbsFilename() string { return p.base.AbsFilename() }
|
func (p Pos) AbsFilename() string { return p.base.AbsFilename() }
|
||||||
|
|
||||||
// SymFilename() returns the absolute filename recorded with the position's base,
|
// FileIndex returns the file index of the position's base's absolute
|
||||||
// prefixed by FileSymPrefix to make it appropriate for use as a linker symbol.
|
// filename within the PosTable that it was registered.
|
||||||
func (p Pos) SymFilename() string { return p.base.SymFilename() }
|
func (p Pos) FileIndex() int { return p.base.FileIndex() }
|
||||||
|
|
||||||
func (p Pos) String() string {
|
func (p Pos) String() string {
|
||||||
return p.Format(true, true)
|
return p.Format(true, true)
|
||||||
@ -193,9 +193,9 @@ type PosBase struct {
|
|||||||
pos Pos // position at which the relative position is (line, col)
|
pos Pos // position at which the relative position is (line, col)
|
||||||
filename string // file name used to open source file, for error messages
|
filename string // file name used to open source file, for error messages
|
||||||
absFilename string // absolute file name, for PC-Line tables
|
absFilename string // absolute file name, for PC-Line tables
|
||||||
symFilename string // cached symbol file name, to avoid repeated string concatenation
|
|
||||||
line, col uint // relative line, column number at pos
|
line, col uint // relative line, column number at pos
|
||||||
inl int // inlining index (see cmd/internal/obj/inl.go)
|
inl int // inlining index (see cmd/internal/obj/inl.go)
|
||||||
|
fileIndex int // index of absFilename within PosTable.FileTable
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFileBase returns a new *PosBase for a file with the given (relative and
|
// NewFileBase returns a new *PosBase for a file with the given (relative and
|
||||||
@ -204,10 +204,10 @@ func NewFileBase(filename, absFilename string) *PosBase {
|
|||||||
base := &PosBase{
|
base := &PosBase{
|
||||||
filename: filename,
|
filename: filename,
|
||||||
absFilename: absFilename,
|
absFilename: absFilename,
|
||||||
symFilename: FileSymPrefix + absFilename,
|
|
||||||
line: 1,
|
line: 1,
|
||||||
col: 1,
|
col: 1,
|
||||||
inl: -1,
|
inl: -1,
|
||||||
|
fileIndex: -1,
|
||||||
}
|
}
|
||||||
base.pos = MakePos(base, 1, 1)
|
base.pos = MakePos(base, 1, 1)
|
||||||
return base
|
return base
|
||||||
@ -220,24 +220,22 @@ func NewFileBase(filename, absFilename string) *PosBase {
|
|||||||
//
|
//
|
||||||
// at position pos.
|
// at position pos.
|
||||||
func NewLinePragmaBase(pos Pos, filename, absFilename string, line, col uint) *PosBase {
|
func NewLinePragmaBase(pos Pos, filename, absFilename string, line, col uint) *PosBase {
|
||||||
return &PosBase{pos, filename, absFilename, FileSymPrefix + absFilename, line, col, -1}
|
return &PosBase{pos, filename, absFilename, line, col, -1, -1}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInliningBase returns a copy of the old PosBase with the given inlining
|
// NewInliningBase returns a copy of the orig PosBase with the given inlining
|
||||||
// index. If old == nil, the resulting PosBase has no filename.
|
// index. If orig == nil, NewInliningBase panics.
|
||||||
func NewInliningBase(old *PosBase, inlTreeIndex int) *PosBase {
|
func NewInliningBase(orig *PosBase, inlTreeIndex int) *PosBase {
|
||||||
if old == nil {
|
if orig == nil {
|
||||||
base := &PosBase{line: 1, col: 1, inl: inlTreeIndex}
|
panic("no old PosBase")
|
||||||
base.pos = MakePos(base, 1, 1)
|
|
||||||
return base
|
|
||||||
}
|
}
|
||||||
copy := *old
|
base := *orig
|
||||||
base := ©
|
|
||||||
base.inl = inlTreeIndex
|
base.inl = inlTreeIndex
|
||||||
if old == old.pos.base {
|
base.fileIndex = -1
|
||||||
base.pos.base = base
|
if orig == orig.pos.base {
|
||||||
|
base.pos.base = &base
|
||||||
}
|
}
|
||||||
return base
|
return &base
|
||||||
}
|
}
|
||||||
|
|
||||||
var noPos Pos
|
var noPos Pos
|
||||||
@ -269,16 +267,21 @@ func (b *PosBase) AbsFilename() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSymPrefix is the linker symbol prefix that used to be used for
|
||||||
|
// linker pseudo-symbols representing file names.
|
||||||
const FileSymPrefix = "gofile.."
|
const FileSymPrefix = "gofile.."
|
||||||
|
|
||||||
// SymFilename returns the absolute filename recorded with the base,
|
// FileIndex returns the index of the base's absolute filename within
|
||||||
// prefixed by FileSymPrefix to make it appropriate for use as a linker symbol.
|
// its PosTable's FileTable. It panics if it hasn't been registered
|
||||||
// If b is nil, SymFilename returns FileSymPrefix + "??".
|
// with a PosTable. If b == nil, the result is -1.
|
||||||
func (b *PosBase) SymFilename() string {
|
func (b *PosBase) FileIndex() int {
|
||||||
if b != nil {
|
if b != nil {
|
||||||
return b.symFilename
|
if b.fileIndex < 0 {
|
||||||
|
panic("PosBase has no file index")
|
||||||
|
}
|
||||||
|
return b.fileIndex
|
||||||
}
|
}
|
||||||
return FileSymPrefix + "??"
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line returns the line number recorded with the base.
|
// Line returns the line number recorded with the base.
|
||||||
|
@ -124,25 +124,40 @@ type PosTable struct {
|
|||||||
// XPos returns the corresponding XPos for the given pos,
|
// XPos returns the corresponding XPos for the given pos,
|
||||||
// adding pos to t if necessary.
|
// adding pos to t if necessary.
|
||||||
func (t *PosTable) XPos(pos Pos) XPos {
|
func (t *PosTable) XPos(pos Pos) XPos {
|
||||||
m := t.indexMap
|
return XPos{t.baseIndex(pos.base), pos.lico}
|
||||||
if m == nil {
|
}
|
||||||
// Create new list and map and populate with nil
|
|
||||||
// base so that NoPos always gets index 0.
|
func (t *PosTable) baseIndex(base *PosBase) int32 {
|
||||||
|
if base == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if i, ok := t.indexMap[base]; ok {
|
||||||
|
return int32(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if base.fileIndex >= 0 {
|
||||||
|
panic("PosBase already registered with a PosTable")
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.indexMap == nil {
|
||||||
t.baseList = append(t.baseList, nil)
|
t.baseList = append(t.baseList, nil)
|
||||||
m = map[*PosBase]int{nil: 0}
|
t.indexMap = make(map[*PosBase]int)
|
||||||
t.indexMap = m
|
|
||||||
t.nameMap = make(map[string]int)
|
t.nameMap = make(map[string]int)
|
||||||
}
|
}
|
||||||
i, ok := m[pos.base]
|
|
||||||
|
i := len(t.baseList)
|
||||||
|
t.indexMap[base] = i
|
||||||
|
t.baseList = append(t.baseList, base)
|
||||||
|
|
||||||
|
fileIndex, ok := t.nameMap[base.absFilename]
|
||||||
if !ok {
|
if !ok {
|
||||||
i = len(t.baseList)
|
fileIndex = len(t.nameMap)
|
||||||
t.baseList = append(t.baseList, pos.base)
|
t.nameMap[base.absFilename] = fileIndex
|
||||||
t.indexMap[pos.base] = i
|
|
||||||
if _, ok := t.nameMap[pos.base.symFilename]; !ok {
|
|
||||||
t.nameMap[pos.base.symFilename] = len(t.nameMap)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return XPos{int32(i), pos.lico}
|
base.fileIndex = fileIndex
|
||||||
|
|
||||||
|
return int32(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pos returns the corresponding Pos for the given p.
|
// Pos returns the corresponding Pos for the given p.
|
||||||
@ -155,14 +170,6 @@ func (t *PosTable) Pos(p XPos) Pos {
|
|||||||
return Pos{base, p.lico}
|
return Pos{base, p.lico}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileIndex returns the index of the given filename(symbol) in the PosTable, or -1 if not found.
|
|
||||||
func (t *PosTable) FileIndex(filename string) int {
|
|
||||||
if v, ok := t.nameMap[filename]; ok {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileTable returns a slice of all files used to build this package.
|
// FileTable returns a slice of all files used to build this package.
|
||||||
func (t *PosTable) FileTable() []string {
|
func (t *PosTable) FileTable() []string {
|
||||||
// Create a LUT of the global package level file indices. This table is what
|
// Create a LUT of the global package level file indices. This table is what
|
||||||
|
@ -62,8 +62,8 @@ func TestConversion(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tab.baseList) != len(tab.indexMap) {
|
if len(tab.baseList) != 1+len(tab.indexMap) { // indexMap omits nil
|
||||||
t.Errorf("table length discrepancy: %d != %d", len(tab.baseList), len(tab.indexMap))
|
t.Errorf("table length discrepancy: %d != 1+%d", len(tab.baseList), len(tab.indexMap))
|
||||||
}
|
}
|
||||||
|
|
||||||
const wantLen = 4
|
const wantLen = 4
|
||||||
|
@ -154,10 +154,6 @@ func (c dwctxt) Logf(format string, args ...interface{}) {
|
|||||||
|
|
||||||
// At the moment these interfaces are only used in the compiler.
|
// At the moment these interfaces are only used in the compiler.
|
||||||
|
|
||||||
func (c dwctxt) AddFileRef(s dwarf.Sym, f interface{}) {
|
|
||||||
panic("should be used only in the compiler")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
|
func (c dwctxt) CurrentOffset(s dwarf.Sym) int64 {
|
||||||
panic("should be used only in the compiler")
|
panic("should be used only in the compiler")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user