9#include "../linker/writable.h"
19template <
typename ... Ts>
29 return values == std::tuple<Ts...>();
45 std::map<offset_t, std::string>
names;
65 static std::shared_ptr<ChoiceDisplay> Make(std::map<offset_t, std::string>
names, std::string
default_name =
"unknown")
78 static std::shared_ptr<ChoiceDisplay>
Make(std::string on_true, std::string on_false)
80 std::map<offset_t, std::string>
names;
87 return std::make_shared<ChoiceDisplay>(
names,
"",
false, 0);
93 static std::shared_ptr<ChoiceDisplay>
Make(std::string on_true)
95 std::map<offset_t, std::string>
names;
102 return std::make_shared<ChoiceDisplay>(
names,
"unknown",
false, 0);
105 bool IsMissing(std::tuple<offset_t>& values)
override;
106 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
121 static std::shared_ptr<HexDisplay> Make(
unsigned width = 8)
123 return std::make_shared<HexDisplay>(width);
126 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
141 static std::shared_ptr<DecDisplay> Make(std::string suffix =
"")
143 return std::make_shared<DecDisplay>(suffix);
146 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
161 static std::shared_ptr<SegmentedDisplay> Make(
unsigned width = 4)
163 return std::make_shared<SegmentedDisplay>(width);
166 void DisplayValue(
Dumper& dump, std::tuple<offset_t, offset_t> values)
override;
175 std::string separator;
177 : separator(separator)
181 static std::shared_ptr<VersionDisplay> Make(std::string separator =
".")
183 return std::make_shared<VersionDisplay>(separator);
186 void DisplayValue(
Dumper& dump, std::tuple<offset_t, offset_t> values)
override;
192template <
typename ... Ts>
197 std::shared_ptr<
Display<Ts...>> offset_display;
200 : suffix(suffix), offset_display(offset_display)
204 static std::shared_ptr<SectionedDisplay> Make(std::shared_ptr<
Display<Ts...>> offset_display)
206 return Make(
"", offset_display);
209 static std::shared_ptr<SectionedDisplay> Make(std::string suffix, std::shared_ptr<
Display<Ts...>> offset_display)
211 return std::make_shared<SectionedDisplay>(suffix, offset_display);
214 void DisplayValue(
Dumper& dump, std::tuple<offset_t, Ts...> values)
override;
226 unsigned offset, length;
227 std::shared_ptr<Display<offset_t>> display;
230 : offset(offset), length(length), display(display), optional_field(optional_field)
234 bool ShouldDisplay(std::tuple<offset_t>& values)
236 return !optional_field || !display->IsMissing(values);
240 std::map<unsigned, std::unique_ptr<BitField>> bitfields;
247 static std::shared_ptr<BitFieldDisplay> Make(
unsigned width = 8)
249 return std::make_shared<BitFieldDisplay>(width);
252 std::shared_ptr<BitFieldDisplay> AddBitField(
unsigned offset,
unsigned length, std::shared_ptr<Display<offset_t>> display,
bool optional_field)
254 bitfields[offset] = std::make_unique<BitField>(offset, length, display, optional_field);
255 return shared_from_this();
258 void DisplayValue(Dumper& dump, std::tuple<offset_t> values)
override;
271 std::string open_quote, close_quote;
274 :
width(
width), open_quote(open_quote), close_quote(close_quote)
278 static std::shared_ptr<StringDisplay> Make(
size_t width, std::string open_quote, std::string close_quote)
280 return std::make_shared<StringDisplay>(
width, open_quote, close_quote);
283 static std::shared_ptr<StringDisplay> Make(
size_t width, std::string quote =
"")
285 return std::make_shared<StringDisplay>(
width, quote, quote);
288 static std::shared_ptr<StringDisplay> Make(std::string quote =
"")
290 return std::make_shared<StringDisplay>(-1, quote, quote);
293 bool IsMissing(std::tuple<std::string>& values)
override;
294 void DisplayValue(Dumper& dump, std::tuple<std::string> values)
override;
296 using Display<std::string>::IsMissing;
297 bool IsMissing(std::tuple<offset_t>& values);
298 using Display<std::string>::DisplayValue;
299 void DisplayValue(Dumper& dump, std::tuple<offset_t> values);
322 virtual bool ShouldDisplay() = 0;
323 virtual void DisplayValue(
Dumper& dump) = 0;
329template <
typename ... Ts>
335 std::tuple<Ts...> values;
342 bool ShouldDisplay()
override
347 void DisplayValue(Dumper& dump)
override
349 display->DisplayValue(dump, values);
361 std::map<std::string, std::shared_ptr<Field>> field_names;
362 std::vector<std::shared_ptr<Field>> fields;
369 std::shared_ptr<Field> FindField(std::string name)
371 auto it = field_names.find(name);
372 if(it == field_names.end())
377 template <
typename T>
378 T GetField(std::string name, offset_t default_value = T())
380 auto it = field_names.find(name);
381 if(it == field_names.end())
382 return default_value;
383 if(
auto field = std::dynamic_pointer_cast<
FieldOf<T>>(it->second))
385 return std::get<0>(field->values);
387 return default_value;
391 offset_t GetField(std::string name,
int index, offset_t default_value)
393 auto it = field_names.find(name);
394 if(it == field_names.end())
395 return default_value;
396 return it->second->values[index];
400 void AddField(std::shared_ptr<Field> field)
402 fields.push_back(field);
403 field_names[field->label] = field;
406 void AddField(
size_t index, std::shared_ptr<Field> field)
408 fields.insert(fields.begin() + index, field);
409 field_names[field->label] = field;
412 template <
typename D,
typename ... Ts>
413 void AddField(std::string label, std::shared_ptr<D> display, Ts... values)
415 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
false));
418 template <
typename D,
typename ... Ts>
419 void AddOptionalField(std::string label, std::shared_ptr<D> display, Ts... values)
421 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
true,
false));
424 template <
typename D,
typename ... Ts>
425 void AddHiddenField(std::string label, std::shared_ptr<D> display, Ts... values)
427 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
true));
430 template <
typename D,
typename ... Ts>
431 void InsertField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
433 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
false));
436 template <
typename D,
typename ... Ts>
437 void InsertOptionalField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
439 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
true,
false));
442 template <
typename D,
typename ... Ts>
443 void InsertHiddenField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
445 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
true));
457 Region(std::string name, offset_t offset, offset_t length,
unsigned display_width)
460 AddField(
"Offset", HexDisplay::Make(display_width), offset);
461 AddField(
"Length", HexDisplay::Make(display_width), length);
464 static std::shared_ptr<Region> Make(std::string name, offset_t offset, offset_t length,
unsigned display_width)
466 return std::make_shared<Region>(name, offset, length, display_width);
480 unsigned display_width;
482 Entry(std::string name, offset_t number, offset_t offset = offset_t(-1),
unsigned display_width = 8)
483 :
Container(name), number(number), offset(offset), display_width(display_width)
503 static char32_t encoding_default[256];
504 static char32_t encoding_cp437[256];
505 static char32_t encoding_st[256];
507 std::shared_ptr<Linker::Writable> image;
509 std::set<offset_t> signal_starts;
510 std::set<offset_t> signal_ends;
520 offset_t end = off + len - 1;
521 signal_starts.insert(off);
522 signal_ends.insert(end);
525 Block(std::string name, offset_t offset, std::shared_ptr<Linker::Writable> image, offset_t address,
unsigned display_width,
527 :
Region(name, offset, image ? image->ActualDataSize() : 0, display_width),
534 AddField(
"Address", HexDisplay::Make(display_width), address);
537 static std::shared_ptr<Block> Make(std::string name, offset_t offset, std::shared_ptr<Linker::Writable> image, offset_t address,
unsigned display_width,
543 void Display(Dumper& dump)
override;
555 char32_t (* encoding)[256];
558 : out(out), use_ansi(
true), encoding(
nullptr)
562 void SetEncoding(
char32_t (& encoding)[256],
bool force =
false)
564 if(this->encoding ==
nullptr || force)
566 this->encoding = &encoding;
570 void SetTitle(std::string title)
572 out <<
"=== " << title <<
" ===" << std::endl;
580 void PrintHex(offset_t value,
unsigned width, std::string prefix =
"0x")
582 out << prefix << std::hex << std::setw(width) << std::setfill(
'0') << value;
589 void PrintHex(offset_t value,
unsigned width,
bool prefixed)
591 PrintHex(value, width, prefixed ?
"0x" :
"");
598 void PrintDec(offset_t value, std::string prefix =
"#")
600 out << prefix << std::dec << value;
607 void PrintDec(offset_t value,
bool prefixed)
609 PrintDec(value, prefixed ?
"#" :
"");
625 out.put((c >> 6) | 0xC0);
626 out.put((c & 0x3F) | 0x80);
630 out.put((c >> 12) | 0xE0);
631 out.put(((c >> 6) & 0x3F) | 0x80);
632 out.put((c & 0x3F) | 0x80);
636 out.put(((c >> 18) & 0x07) | 0xF0);
637 out.put(((c >> 12) & 0x3F) | 0x80);
638 out.put(((c >> 6) & 0x3F) | 0x80);
639 out.put((c & 0x3F) | 0x80);
662template <
unsigned I,
size_t ... Is,
typename ... Ts>
663 inline auto rest_(std::tuple<Ts...> elements, std::index_sequence<Is...> s)
665 return std::make_tuple(std::get<I + Is>(elements)...);
668template <
unsigned I,
typename ... Ts>
669 inline auto rest(std::tuple<Ts...> elements)
671 return rest_<I>(elements, std::make_index_sequence<
sizeof...(Ts) - I>());
674template <
typename ... Ts>
675 void SectionedDisplay<Ts...>::DisplayValue(Dumper& dump, std::tuple<offset_t, Ts...> values)
677 dump.PrintDec(std::get<0>(values),
"");
678 dump.out << suffix <<
':';
679 offset_display->DisplayValue(dump, rest<1>(values));
A value that is separated into bitfields, typically bit flags.
Definition dumper.h:221
A region within a file that can be dumped, decompiled, and it may contain fixups.
Definition dumper.h:494
unsigned offset_display_width
Displaying in-file offsets.
Definition dumper.h:497
void AddSignal(offset_t off, offset_t len)
Add a relocation inside the image block.
Definition dumper.h:518
unsigned position_display_width
Displaying in-segment positions.
Definition dumper.h:499
unsigned address_display_width
Displaying in-memory addresses.
Definition dumper.h:501
Represents an enumerated value, with named options.
Definition dumper.h:40
std::map< offset_t, std::string > names
Maps values to names.
Definition dumper.h:45
static std::shared_ptr< ChoiceDisplay > Make(std::string on_true)
Creates a boolean choice that is either present with name or not present at all.
Definition dumper.h:93
bool missing_on_value
If false, any value not listed in names is missing, otherwise only missing_value is missing.
Definition dumper.h:54
static std::shared_ptr< ChoiceDisplay > Make(std::string on_true, std::string on_false)
Creates a boolean choice.
Definition dumper.h:78
std::string default_name
Name for values not contained in names.
Definition dumper.h:49
offset_t missing_value
The single missing value, only used for missing_on_value true.
Definition dumper.h:58
A record whose values should be displayed together, as a collection.
Definition dumper.h:357
Represents a field with a decimal display, usually indices into an array or similar,...
Definition dumper.h:133
This class represents an entry that can be displayed in a file dump.
Definition dumper.h:21
virtual bool IsMissing(std::tuple< Ts... > &values)
Returns true if the specified value is such that it should not be displayed.
Definition dumper.h:26
virtual void DisplayValue(Dumper &dump, std::tuple< Ts... > values)=0
Prints the value through the Dumper, different types of fields can be displayed in different ways.
A class to control the output of a file analysis.
Definition dumper.h:550
void PrintHex(offset_t value, unsigned width, std::string prefix="0x")
Displays a hexadecimal value (default prefix is "0x")
Definition dumper.h:580
void EndUnderline()
ANSI escape sequence to remove all formatting.
Definition dumper.h:655
void PrintDec(offset_t value, std::string prefix="#")
Displays a decimal value (default prefix is "#")
Definition dumper.h:598
void BeginUnderline()
ANSI escape sequence to add underline.
Definition dumper.h:646
void PutChar(char32_t c)
Displays a Unicode character as a UTF-8 byte sequence.
Definition dumper.h:616
A brief record, such as a relocation or imported library.
Definition dumper.h:476
A typed representation of a named value within a structure.
Definition dumper.h:331
std::shared_ptr< Display< Ts... > > display
The method to show it in.
Definition dumper.h:334
A representation of a named value within a structure.
Definition dumper.h:306
std::string label
The name to be displayed.
Definition dumper.h:309
bool internal
The field should not be displayed, it is for internal use (alternatively, it can be displayed through...
Definition dumper.h:313
bool optional_field
If the field is optional, it will not be displayed for certain values.
Definition dumper.h:311
Represents a field with a hexadecimal display, typically bitfields, addresses, sizes,...
Definition dumper.h:113
A record that represents a region within the file.
Definition dumper.h:455
A display with a prefix for a section.
Definition dumper.h:194
A value displayed as a colon-separated pair, typically 8086 segmented addresses.
Definition dumper.h:153
A display for a fixed or variable length string field.
Definition dumper.h:265
offset_t width
The width of the string field, exactly this many characters will be shown, unless it is offset_t(-1),...
Definition dumper.h:270
A value displayed as a separated pair, such as a version number.
Definition dumper.h:173