blob: 70d759ff665f6df292dc9d2e70f0ad48399aeeda [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_PHYS_SYMBOLIZE_H_
#define ZIRCON_KERNEL_PHYS_SYMBOLIZE_H_
#include <stdint.h>
#include <stdio.h>
#include <ktl/string_view.h>
#include "main.h"
class Symbolize {
public:
// Each program contains `const char Symbolize::kProgramName_[] = "myname";`.
//
// Note this can't be a ktl::string_view because that would be a
// static initializer containing a pointer.
static const char kProgramName_[];
Symbolize() = default;
Symbolize(const Symbolize&) = delete;
explicit Symbolize(FILE* f) : output_(f) {}
static Symbolize* GetInstance() {
instance_.EnsureOutput();
return &instance_;
}
void set_output(FILE* f) { output_ = f; }
// Print the contextual markup elements describing this phys executable.
PHYS_SINGLETHREAD void ContextAlways();
// Same, but idempotent: the first call prints and others do nothing.
PHYS_SINGLETHREAD void Context();
// Print the presentation markup element for one frame of a backtrace.
void BackTraceFrame(unsigned int n, uintptr_t pc);
// Print a backtrace, ensuring context has been printed beforehand.
// This takes any container of uintptr_t, so FramePointer works.
template <typename T>
PHYS_SINGLETHREAD void BackTrace(const T& pcs) {
Context();
unsigned int n = 0;
for (uintptr_t pc : pcs) {
BackTraceFrame(n++, pc);
}
}
// Print the trigger markup element for a dumpfile.
// TODO(mcgrathr): corresponds to a ZBI item
PHYS_SINGLETHREAD void DumpFile(ktl::string_view type, ktl::string_view name);
private:
static Symbolize instance_;
FILE* output_ = nullptr;
bool context_done_ = false;
void Printf(const char* fmt, ...);
// Implementation details of ContextAlways().
void PrintModule();
void PrintMmap();
// This is only needed rather than just `instance_{stdout}` because neither
// static constructors nor link-time initializers with non-nullptr pointers
// are available in phys executables.
void EnsureOutput() {
if (!output_) {
output_ = stdout;
}
}
};
#endif // ZIRCON_KERNEL_PHYS_SYMBOLIZE_H_