blob: 49a44f0bb99d04ba6db45bd28fa38500127bb73b [file] [log] [blame]
// Copyright 2023 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.
#include "symbolizer_markup.h"
#include <elf.h>
#include <lib/symbolizer-markup/writer.h>
#include "sampler.h"
#include "symbolization_context.h"
struct Sink {
void operator()(std::string_view s) { value.append(s); }
std::string& value;
};
std::string profiler::symbolizer_markup::FormatModule(const profiler::Module& mod) {
const size_t kPageSize = zx_system_get_page_size();
std::string markup;
::symbolizer_markup::Writer writer(Sink{markup});
writer.ElfModule(mod.module_id, mod.module_name, mod.build_id).Newline();
for (const profiler::Segment& segment : mod.loads) {
uintptr_t start = segment.p_vaddr & -kPageSize;
uintptr_t end = (segment.p_vaddr + segment.p_memsz + kPageSize - 1) & -kPageSize;
::symbolizer_markup::MemoryPermissions perms{
.read = (segment.p_flags & PF_R) != 0,
.write = (segment.p_flags & PF_W) != 0,
.execute = (segment.p_flags & PF_X) != 0,
};
writer.LoadImageMmap(mod.vaddr + start, end - start, mod.module_id, perms, start).Newline();
}
return markup;
}
std::string profiler::symbolizer_markup::FormatSample(const profiler::Sample& sample) {
std::string markup;
::symbolizer_markup::Writer writer(Sink{markup});
writer.DecimalDigits(sample.pid).Newline().DecimalDigits(sample.tid).Newline();
for (unsigned n = 0; n < sample.stack.size(); n++) {
if (n == 0) {
writer.ExactPcFrame(n, sample.stack[n]).Newline();
} else {
writer.ReturnAddressFrame(n, sample.stack[n]).Newline();
}
}
return markup;
}