diff --git a/thorlog/v3/process.go b/thorlog/v3/process.go index 73e1029..19a8c3e 100644 --- a/thorlog/v3/process.go +++ b/thorlog/v3/process.go @@ -46,7 +46,48 @@ type ProcessInfo struct { ProcessConnections `textlog:",expand"` - Memory *SparseData `json:"memory,omitempty" textlog:"memory,expand,omitempty"` + Sections Sections `json:"sections,omitempty" textlog:"-"` +} + +type Sections []Section + +// Section describes a memory range in a process's virtual memory. +// This typically corresponds to a section in an executable file or library, such as .text, .data, etc., +// or a stack, heap, or similar. +// In Linux terms: it corresponds to a line in /proc//maps. +type Section struct { + // Name of the section. For sections from loaded libraries, this is the library's file path. + // For other memory ranges, this is OS specific and may be empty. + Name string `json:"name"` + // Address is the start address of the section in the process's virtual memory. + Address uint64 `json:"address"` + // Size is the size of the section in bytes. + Size uint64 `json:"size" textlog:"size"` + // Offset is the offset within the mapped file or library, if this section + // corresponds to a file section. If this section does not correspond to a file, + // this is empty. + Offset uint64 `json:"offset,omitempty"` + // SparseData contains a sparse representation of the section's data. + // Only the interesting parts of the section are included, typically those that have been matched. + SparseData *SparseData `json:"sparse_data,omitempty"` + // Permissions of the section. + Permissions RwxPermissions `json:"permissions"` +} + +// RelativeTextPointer implements the jsonlog.TextReferenceResolver interface for Sections. +// It resolves a reference to a Section's SparseData field to a human-readable string. +func (s *Sections) RelativeTextPointer(pointee any) (string, bool) { + for i := range *s { + section := &(*s)[i] + if pointee == §ion.SparseData { + if section.Name != "" { + return section.Name, true + } else { + return fmt.Sprintf("0x%x", section.Address), true + } + } + } + return "", false } type ProcessConnections struct { diff --git a/thorlog/v3/sparsedata.go b/thorlog/v3/sparsedata.go index 9dc9f8e..db45404 100644 --- a/thorlog/v3/sparsedata.go +++ b/thorlog/v3/sparsedata.go @@ -9,10 +9,21 @@ import ( "github.com/NextronSystems/jsonlog" ) +// SparseData is a log object that represents a sparse data structure. +// SparseData represents a selection of data from a large data block (e.g.: a file's content) +// that is not fully contained in the log. +// +// Not all parts of the full data structure are necessarily contained in the sparse data, +// typically based on how much data is relevant for the analysis. type SparseData struct { jsonlog.ObjectHeader + // Elements is a list of sparse data elements that contain the actual data. + // Each element has an offset within the block and the data that is present at that offset. + // Elements are ordered by their offset, and are guaranteed to be non-overlapping. Elements []SparseDataElement `json:"elements" jsonschema:"nullable"` - Length int64 `json:"length"` + // Length is the length of the block where the sparse elements reside in. + // In other words, all Elements are within an address range of [0, Length). + Length int64 `json:"length"` } const truncateSequence = "[...]"