blob: cf02455e6351f90fc75d685a447c440bd0526a4d [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package symbolize
import (
"encoding/json"
)
type jsonVisitor struct {
stack []json.RawMessage
}
func GetLineJson(line []Node) ([]byte, error) {
var j jsonVisitor
for _, token := range line {
token.Accept(&j)
}
return j.getJson()
}
func (j *jsonVisitor) getJson() ([]byte, error) {
return json.MarshalIndent(j.stack, "", "\t")
}
func (j *jsonVisitor) VisitBt(elem *BacktraceElement) {
type loc struct {
File OptStr `json:"file"`
Line int `json:"line"`
Function OptStr `json:"function"`
}
var locs []loc
for _, srcloc := range elem.info.locs {
locs = append(locs, loc{
File: srcloc.file,
Line: srcloc.line,
Function: srcloc.function,
})
}
msg, _ := json.Marshal(struct {
Type string `json:"type"`
Vaddr uint64 `json:"vaddr"`
Num uint64 `json:"num"`
Locs []loc `json:"locs"`
}{
Type: "bt",
Vaddr: elem.vaddr,
Num: elem.num,
Locs: locs,
})
j.stack = append(j.stack, msg)
}
func (j *jsonVisitor) VisitPc(elem *PCElement) {
loc := elem.info.locs[0]
msg, _ := json.Marshal(struct {
Type string `json:"type"`
Vaddr uint64 `json:"vaddr"`
File OptStr `json:"file"`
Line int `json:"line"`
Function OptStr `json:"function"`
}{
Type: "pc",
Vaddr: elem.vaddr,
File: loc.file,
Line: loc.line,
Function: loc.function,
})
j.stack = append(j.stack, msg)
}
func (j *jsonVisitor) VisitColor(elem *ColorCode) {
out := j.stack
msg, _ := json.Marshal(struct {
Type string `json:"type"`
Color uint64 `json:"color"`
}{
Type: "color",
Color: elem.color,
})
j.stack = append(out, msg)
}
func (j *jsonVisitor) VisitText(elem *Text) {
msg, _ := json.Marshal(struct {
Type string `json:"type"`
Text string `json:"text"`
}{
Type: "text",
Text: elem.text,
})
j.stack = append(j.stack, msg)
}
func (j *jsonVisitor) VisitDump(elem *DumpfileElement) {
msg, _ := json.Marshal(struct {
Type string `json:"type"`
SinkType string `json:"sinkType"`
DumpName string `json:"name"`
}{
Type: "dumpfile",
SinkType: elem.sinkType,
DumpName: elem.name,
})
j.stack = append(j.stack, msg)
}
// TODO: update this for generalized modules
func (j *jsonVisitor) VisitModule(elem *ModuleElement) {
msg, _ := json.Marshal(struct {
Type string `json:"type"`
Name string `json:"name"`
Build string `json:"build"`
Id uint64 `json:"id"`
}{
Type: "module",
Name: elem.mod.Name,
Build: elem.mod.Build,
Id: elem.mod.Id,
})
j.stack = append(j.stack, msg)
}
func (j *jsonVisitor) VisitReset(elem *ResetElement) {
msg, _ := json.Marshal(map[string]string{
"type": "reset",
})
j.stack = append(j.stack, msg)
}
// TODO: update this for generalized loads
func (j *jsonVisitor) VisitMapping(elem *MappingElement) {
msg, _ := json.Marshal(struct {
Type string `json:"type"`
Mod uint64 `json:"mod"`
Size uint64 `json:"size"`
Vaddr uint64 `json:"vaddr"`
Flags string `json:"flags"`
ModRelAddr uint64 `json:"modRelAddr"`
}{
Type: "mmap",
Mod: elem.seg.Mod,
Size: elem.seg.Size,
Vaddr: elem.seg.Vaddr,
Flags: elem.seg.Flags,
ModRelAddr: elem.seg.ModRelAddr,
})
j.stack = append(j.stack, msg)
}