type LineReader … type LineEntry … type LineFile … // LineReader returns a new reader for the line table of compilation // unit cu, which must be an [Entry] with tag [TagCompileUnit]. // // If this compilation unit has no line table, it returns nil, nil. func (d *Data) LineReader(cu *Entry) (*LineReader, error) { … } // readHeader reads the line number program header from r.buf and sets // all of the header fields in r. func (r *LineReader) readHeader(compDir string) error { … } type lnctForm … // readLNCTFormat reads an LNCT format description. func (r *LineReader) readLNCTFormat() []lnctForm { … } // readLNCT reads a sequence of LNCT entries and returns path information. func (r *LineReader) readLNCT(s []lnctForm, dwarf64 bool) (path string, mtime uint64, size uint64, err error) { … } // readFileEntry reads a file entry from either the header or a // DW_LNE_define_file extended opcode and adds it to r.fileEntries. A // true return value indicates that there are no more entries to read. func (r *LineReader) readFileEntry() (bool, error) { … } // updateFile updates r.state.File after r.fileIndex has // changed or r.fileEntries has changed. func (r *LineReader) updateFile() { … } // Next sets *entry to the next row in this line table and moves to // the next row. If there are no more entries and the line table is // properly terminated, it returns [io.EOF]. // // Rows are always in order of increasing entry.Address, but // entry.Line may go forward or backward. func (r *LineReader) Next(entry *LineEntry) error { … } var knownOpcodeLengths … // step processes the next opcode and updates r.state. If the opcode // emits a row in the line table, this updates *entry and returns // true. func (r *LineReader) step(entry *LineEntry) bool { … } // advancePC advances "operation pointer" (the combination of Address // and OpIndex) in r.state by opAdvance steps. func (r *LineReader) advancePC(opAdvance int) { … } type LineReaderPos … // Tell returns the current position in the line table. func (r *LineReader) Tell() LineReaderPos { … } // Seek restores the line table reader to a position returned by [LineReader.Tell]. // // The argument pos must have been returned by a call to [LineReader.Tell] on this // line table. func (r *LineReader) Seek(pos LineReaderPos) { … } // Reset repositions the line table reader at the beginning of the // line table. func (r *LineReader) Reset() { … } // resetState resets r.state to its default values func (r *LineReader) resetState() { … } // Files returns the file name table of this compilation unit as of // the current position in the line table. The file name table may be // referenced from attributes in this compilation unit such as // [AttrDeclFile]. // // Entry 0 is always nil, since file index 0 represents "no file". // // The file name table of a compilation unit is not fixed. Files // returns the file table as of the current position in the line // table. This may contain more entries than the file table at an // earlier position in the line table, though existing entries never // change. func (r *LineReader) Files() []*LineFile { … } var ErrUnknownPC … // SeekPC sets *entry to the [LineEntry] that includes pc and positions // the reader on the next entry in the line table. If necessary, this // will seek backwards to find pc. // // If pc is not covered by any entry in this line table, SeekPC // returns [ErrUnknownPC]. In this case, *entry and the final seek // position are unspecified. // // Note that DWARF line tables only permit sequential, forward scans. // Hence, in the worst case, this takes time linear in the size of the // line table. If the caller wishes to do repeated fast PC lookups, it // should build an appropriate index of the line table. func (r *LineReader) SeekPC(pc uint64, entry *LineEntry) error { … } // pathIsAbs reports whether path is an absolute path (or "full path // name" in DWARF parlance). This is in "whatever form makes sense for // the host system", so this accepts both UNIX-style and DOS-style // absolute paths. We avoid the filepath package because we want this // to behave the same regardless of our host system and because we // don't know what system the paths came from. func pathIsAbs(path string) bool { … } // pathJoin joins dirname and filename. filename must be relative. // DWARF paths can be UNIX-style or DOS-style, so this handles both. func pathJoin(dirname, filename string) string { … } // splitDrive splits the DOS drive letter or UNC share point from // path, if any. path == drive + rest func splitDrive(path string) (drive, rest string) { … }