|  | // 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_ |