def fork_exit(name): return Struct(name, SNInt32("pid"), SNInt32("ppid"), SNInt32("tid"), SNInt32("ptid"), UNInt64("time"), sample_id())
def mmap2(): return Struct("mmap2", SNInt32("pid"), SNInt32("tid"), UNInt64("addr"), UNInt64("len"), UNInt64("pgoff"), UNInt32("maj"), UNInt32("min"), UNInt64("ino"), UNInt64("ino_generation"), UNInt32("prot"), UNInt32("flags"), CString("filename"), sample_id())
def sample_id(): return If( lambda ctx: True, # xxx check size Embedded( Struct( "id_all", If(lambda ctx: sample_type(ctx).tid, Embedded(Struct("pid2", SNInt32("pid2"), SNInt32("tid2")))), If(lambda ctx: sample_type(ctx).time, UNInt64("time2")), If(lambda ctx: sample_type(ctx).id, UNInt64("id2")), If(lambda ctx: sample_type(ctx).stream_id, UNInt64("stream_id2")), If(lambda ctx: sample_type(ctx).cpu, Embedded(Struct("cpu", UNInt32("cpu2"), UNInt32("res")))), If(lambda ctx: sample_type(ctx).identifier, UNInt64("identifier2")))))
def mmap(): return Struct("mmap", SNInt32("pid"), SNInt32("tid"), UNInt64("addr"), UNInt64("len"), UNInt64("pgoff"), Anchor("start_of_filename"), CString("filename"), Anchor("end_of_filename"), # hack for now. this shouldn't be needed. If(lambda ctx: True, # XXX Embedded(Pointer(lambda ctx: ctx.size + ctx.start - sample_id_size(ctx), sample_id()))))
def build_id(): return Struct("build_id", Anchor("start"), UNInt32("type"), UNInt16("misc"), UNInt16("size"), SNInt32("pid"), HexDumpAdapter(String("build_id", 24)), CString("filename"), Anchor("offset"), pad("size"))
def perf_event(): return Struct( "perf_event", Anchor("start"), perf_event_header(), Anchor("header_end"), Switch( "data", lambda ctx: ctx.type, { "MMAP": mmap(), # noqa E121 "MMAP2": mmap2(), "LOST": Struct("lost", UNInt64("id"), UNInt64("lost"), sample_id()), "COMM": Struct("comm", SNInt32("pid"), SNInt32("tid"), CString("comm"), sample_id()), "EXIT": fork_exit("exit"), "THROTTLE": throttle("throttle"), "UNTHROTTLE": throttle("unthrottle"), "FINISHED_ROUND": Pass, "FORK": fork_exit("fork"), "READ": Embedded( Struct("read_event", SNInt32("pid"), SNInt32("tid"), read_format(), sample_id())), "SAMPLE": event() }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start)))
def event(): return Embedded( Struct( "event", If(lambda ctx: sample_type(ctx).identifier, UNInt64("identifier")), If(lambda ctx: sample_type(ctx).ip, UNInt64("ip")), If(lambda ctx: sample_type(ctx).tid, Embedded(Struct("tid", SNInt32("pid"), SNInt32("tid")))), If(lambda ctx: sample_type(ctx).time, UNInt64("time")), If(lambda ctx: sample_type(ctx).addr, UNInt64("addr")), If(lambda ctx: sample_type(ctx).id, UNInt64("id")), If(lambda ctx: sample_type(ctx).stream_id, UNInt64("stream_id")), If(lambda ctx: sample_type(ctx).cpu, Embedded(Struct("cpu", UNInt32("cpu"), UNInt32("res")))), If(lambda ctx: sample_type(ctx).period, UNInt64("period")), If(lambda ctx: sample_type(ctx).read, read_format()), If( lambda ctx: sample_type(ctx).callchain, Struct("callchain", UNInt64("nr"), Array(lambda ctx: ctx.nr, UNInt64("caller")))), If( lambda ctx: sample_type(ctx).raw, Struct("raw", UNInt32("size"), Bytes("raw", lambda ctx: ctx.size))), If( lambda ctx: sample_type(ctx).branch_stack, Struct( "branch_stack", UNInt64("nr"), Array( lambda ctx: ctx.nr, Struct( "branch", UNInt64("from"), UNInt64("to"), # Little-Endian! BitStruct("flags", Padding(4), Flag("abort"), Flag("in_tx"), Flag("predicted"), Flag("mispred"), Padding(64 - 1 * 8)))))), If( lambda ctx: sample_type(ctx).regs_user, Struct("regs_user", Enum(UNInt64("abi"), NONE=0, ABI_32=1, ABI_64=2), Array(lambda ctx: hweight64(ctx), UNInt64("reg")))), If( lambda ctx: sample_type(ctx).stack_user, Struct("stack_user", UNInt64("size"), Bytes("data", lambda ctx: ctx.size), UNInt64("dyn_size"))), If(lambda ctx: sample_type(ctx).weight, UNInt64("weight")), If(lambda ctx: sample_type(ctx).data_src, UNInt64("data_src")), If(lambda ctx: sample_type(ctx).transaction, UNInt64("transaction")), If( lambda ctx: sample_type(ctx).regs_intr, Struct("regs_intr", Enum(UNInt64("abi"), NONE=0, ABI_32=1, ABI_64=2), Array(lambda ctx: hweight64(ctx), UNInt64("reg")))), Anchor("end_event"), Padding(lambda ctx: max(0, ctx.size - ctx.end_event))))
def perf_event(): return Struct("perf_event", Anchor("start"), perf_event_header(), Anchor("header_end"), Switch("data", lambda ctx: ctx.type, { "MMAP": mmap(), # noqa E121 "MMAP2": mmap2(), "LOST": Struct("lost", UNInt64("id"), UNInt64("lost"), sample_id()), "COMM": Struct("comm", SNInt32("pid"), SNInt32("tid"), CString("comm"), sample_id()), "EXIT": fork_exit("exit"), "THROTTLE": throttle("throttle"), "UNTHROTTLE": throttle("unthrottle"), "FINISHED_ROUND": Pass, "FORK": fork_exit("fork"), "READ": Embedded(Struct("read_event", SNInt32("pid"), SNInt32("tid"), read_format(), sample_id())), "SAMPLE": event(), "TIME_CONV": time_conv(), "THREAD_MAP": thread_map(), # below are the so far not handled ones. Dump their # raw data only "RECORD_AUX": ignore(), "AUX": ignore(), "ITRACE_START": ignore(), "LOST_SAMPLES": ignore(), "SWITCH": ignore(), "SWITCH_CPU_WIDE": ignore(), "NAMESPACES": ignore(), "KSYMBOL": ignore(), "BPF_EVENT": ignore(), "CGROUP": ignore(), "HEADER_ATTR": ignore(), "HEADER_EVENT_TYPE": ignore(), "TRACING_DATA": ignore(), "HEADER_BUILD_ID": ignore(), "ID_INDEX": ignore(), "AUXTRACE_INFO": ignore(), "AUXTRACE": ignore(), "AUXTRACE_ERROR": ignore(), "CPU_MAP": ignore(), "STAT": ignore(), "STAT_ROUND": ignore(), "EVENT_UPDATE": ignore(), "HEADER_FEATURE": ignore(), "COMPRESSED": ignore(), }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start)))