10#include "../linker/image.h"
35 Header = 1 << _Header,
37 Symbol = 1 << _Symbol,
39 Relocation = 1 << _Relocation,
41 Import = 1 << _Import,
43 Export = 1 << _Export,
45 Control = 1 << _Control,
47 String = 1 << _String,
51 Resource = 1 << _Resource,
53 Dynamic = 1 << _Dynamic,
55 Miscellaneous = 1 << _Miscellaneous,
57 Redundant = 1 << _Redundant,
59 Generated = 1 << _Generated,
62 All = Image | Header | Symbol | Relocation | Import | Export | Control | String | Debug | Resource | Dynamic | Miscellaneous | Redundant | Generated,
72 virtual char32_t GetChar(uint8_t
const *& input,
size_t& length) = 0;
74 char32_t operator[](uint8_t input)
76 uint8_t
const * input_pointer = &input;
78 return GetChar(input_pointer, length);
85 char32_t (* codepage)[256];
93 assert(this->codepage !=
nullptr);
96 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
107 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
113 ::EndianType endiantype;
116 : endiantype(endiantype)
120 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
127 ::EndianType endiantype;
130 : endiantype(endiantype)
134 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
148 std::map<size_t, std::map<Formatting, bool>> formatting;
157 template <
typename ... Ts>
158 RichText(std::string text, Formatting format, Ts ... rest)
161 formatting[0][format] =
true;
162 formatting[text.size()][format] =
false;
171 RichText& operator +=(std::string s)
178 void Dump(
Dumper& dump)
const;
180 bool operator ==(
const RichText& other)
const
182 return text == other.text && formatting == other.formatting;
196template <
typename ... Ts>
206 return values == std::tuple<Ts...>();
222 std::map<offset_t, std::string>
names;
305 static std::shared_ptr<ChoiceDisplay>
Make(std::string on_true, std::string on_false)
307 std::map<offset_t, std::string>
names;
314 return std::make_shared<ChoiceDisplay>(
names,
"",
false, 0,
nullptr);
323 static std::shared_ptr<ChoiceDisplay>
Make(std::string on_true)
325 std::map<offset_t, std::string>
names;
332 return std::make_shared<ChoiceDisplay>(
names,
"unknown",
false, 0,
nullptr);
335 bool IsMissing(std::tuple<offset_t>& values)
override;
336 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
357 static std::shared_ptr<HexDisplay>
Make(
unsigned width = 8)
359 return std::make_shared<HexDisplay>(width);
362 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
372 bool enable_signed =
false;
373 DecDisplay(std::string suffix,
bool enable_signed)
374 : suffix(suffix), enable_signed(enable_signed)
384 static std::shared_ptr<DecDisplay>
Make(
bool enable_signed)
386 return std::make_shared<DecDisplay>(
"", enable_signed);
396 static std::shared_ptr<DecDisplay>
Make(std::string suffix =
"",
bool enable_signed =
false)
398 return std::make_shared<DecDisplay>(suffix, enable_signed);
401 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
422 static std::shared_ptr<SegmentedDisplay>
Make(
unsigned width = 4)
424 return std::make_shared<SegmentedDisplay>(width);
427 void DisplayValue(
Dumper& dump, std::tuple<offset_t, offset_t> values)
override;
436 std::string separator;
438 : separator(separator)
448 static std::shared_ptr<VersionDisplay>
Make(std::string separator =
".")
450 return std::make_shared<VersionDisplay>(separator);
453 void DisplayValue(
Dumper& dump, std::tuple<offset_t, offset_t> values)
override;
459template <
typename ... Ts>
464 std::shared_ptr<
Display<Ts...>> offset_display;
467 : suffix(suffix), offset_display(offset_display)
479 return Make(
"", offset_display);
489 static std::shared_ptr<SectionedDisplay>
Make(std::string suffix, std::shared_ptr<
Display<Ts...>> offset_display)
491 return std::make_shared<SectionedDisplay>(suffix, offset_display);
494 void DisplayValue(
Dumper& dump, std::tuple<offset_t, Ts...> values)
override;
506 unsigned offset, length;
507 std::shared_ptr<Display<offset_t>> display;
511 BitField(
unsigned offset,
unsigned length, std::shared_ptr<
Display<offset_t>> display,
bool optional_field, std::string label)
512 : offset(offset), length(length), display(display), optional_field(optional_field), label(label)
516 bool ShouldDisplay(std::tuple<offset_t>& values)
518 return !optional_field || !display->IsMissing(values);
522 std::map<unsigned, std::unique_ptr<BitField>> bitfields;
535 static std::shared_ptr<BitFieldDisplay>
Make(
unsigned width = 8)
537 return std::make_shared<BitFieldDisplay>(width);
540 std::shared_ptr<BitFieldDisplay> AddBitField(
unsigned offset,
unsigned length, std::shared_ptr<
Display<offset_t>> display,
bool optional_field)
542 bitfields[offset] = std::make_unique<BitField>(offset, length, display, optional_field,
"");
543 return shared_from_this();
546 std::shared_ptr<BitFieldDisplay> AddBitField(
unsigned offset,
unsigned length, std::string label, std::shared_ptr<Display<offset_t>> display,
bool optional_field =
false)
548 bitfields[offset] = std::make_unique<BitField>(offset, length, display, optional_field, label);
549 return shared_from_this();
552 void DisplayValue(Dumper& dump, std::tuple<offset_t> values)
override;
560template <
typename Clock>
564 typedef ::Timestamp<Clock> Timestamp;
566 static std::shared_ptr<TimestampDisplay> Make()
568 return std::make_shared<TimestampDisplay>();
571 bool IsMissing(std::tuple<Timestamp>& values)
override
573 return Clock::to_ticks(std::get<0>(values)) == 0;
576 void DisplayValue(
Dumper& dump, std::tuple<Timestamp> values)
override;
578 using Display<Timestamp>::IsMissing;
579 bool IsMissing(std::tuple<offset_t>& values)
581 return std::get<0>(values) == 0;
584 using Display<Timestamp>::DisplayValue;
585 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
588 DisplayValue(dump, std::make_tuple(Clock::to_time_stamp(std::get<0>(values))));
626 bool IsMissing(std::tuple<std::vector<uint8_t>>& values)
override;
627 void DisplayValue(
Dumper& dump, std::tuple<std::vector<uint8_t>> values)
override;
629 using Display<std::vector<uint8_t>>::IsMissing;
630 bool IsMissing(std::tuple<offset_t>& values);
631 using Display<std::vector<uint8_t>>::DisplayValue;
632 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values);
645 std::string open_quote, close_quote;
648 :
width(
width), open_quote(open_quote), close_quote(close_quote)
660 static std::shared_ptr<StringDisplay>
Make(
size_t width, std::string open_quote, std::string close_quote)
662 return std::make_shared<StringDisplay>(
width, open_quote, close_quote);
672 static std::shared_ptr<StringDisplay>
Make(
size_t width, std::string quote =
"")
674 return std::make_shared<StringDisplay>(
width, quote, quote);
683 static std::shared_ptr<StringDisplay>
Make(std::string quote =
"")
685 return std::make_shared<StringDisplay>(-1, quote, quote);
688 bool IsMissing(std::tuple<std::string>& values)
override;
689 void DisplayValue(
Dumper& dump, std::tuple<std::string> values)
override;
691 using Display<std::string>::IsMissing;
692 bool IsMissing(std::tuple<offset_t>& values);
693 using Display<std::string>::DisplayValue;
694 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values);
703 std::string open_quote, close_quote;
706 : open_quote(open_quote), close_quote(close_quote)
717 static std::shared_ptr<RichTextDisplay>
Make(std::string open_quote, std::string close_quote)
719 return std::make_shared<RichTextDisplay>(open_quote, close_quote);
728 static std::shared_ptr<RichTextDisplay>
Make(std::string quote =
"")
730 return std::make_shared<RichTextDisplay>(quote, quote);
733 bool IsMissing(std::tuple<RichText>& values)
override;
734 void DisplayValue(
Dumper& dump, std::tuple<RichText> values)
override;
737 bool IsMissing(std::tuple<offset_t>& values);
739 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values);
762 virtual bool ShouldDisplay() = 0;
763 virtual void DisplayValue(
Dumper& dump) = 0;
769template <
typename ... Ts>
775 std::tuple<Ts...> values;
782 bool ShouldDisplay()
override
787 void DisplayValue(Dumper& dump)
override
789 display->DisplayValue(dump, values);
801 std::map<std::string, std::shared_ptr<Field>> field_names;
802 std::vector<std::shared_ptr<Field>> fields;
811 std::shared_ptr<Field> FindField(std::string name)
813 auto it = field_names.find(name);
814 if(it == field_names.end())
819 template <
typename T>
820 T GetField(std::string name, offset_t default_value = T())
822 auto it = field_names.find(name);
823 if(it == field_names.end())
824 return default_value;
825 if(
auto field = std::dynamic_pointer_cast<
FieldOf<T>>(it->second))
827 return std::get<0>(field->values);
829 return default_value;
833 offset_t GetField(std::string name,
int index, offset_t default_value)
835 auto it = field_names.find(name);
836 if(it == field_names.end())
837 return default_value;
838 return it->second->values[index];
842 void AddField(std::shared_ptr<Field> field)
844 fields.push_back(field);
845 field_names[field->label] = field;
848 void AddField(
size_t index, std::shared_ptr<Field> field)
850 fields.insert(fields.begin() + index, field);
851 field_names[field->label] = field;
854 template <
typename D,
typename ... Ts>
855 void AddField(std::string label, std::shared_ptr<D> display, Ts... values)
857 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
false));
860 template <
typename D,
typename ... Ts>
861 void AddOptionalField(std::string label, std::shared_ptr<D> display, Ts... values)
863 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
true,
false));
866 template <
typename D,
typename ... Ts>
867 void AddHiddenField(std::string label, std::shared_ptr<D> display, Ts... values)
869 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
true));
872 template <
typename D,
typename ... Ts>
873 void InsertField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
875 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
false));
878 template <
typename D,
typename ... Ts>
879 void InsertOptionalField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
881 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
true,
false));
884 template <
typename D,
typename ... Ts>
885 void InsertHiddenField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
887 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
true));
904 Region(std::string name, offset_t offset, offset_t length,
unsigned display_width)
911 static std::shared_ptr<Region> Make(std::string name, offset_t offset, offset_t length,
unsigned display_width)
913 return std::make_shared<Region>(name, offset, length, display_width);
927 unsigned display_width;
929 Entry(std::string name, offset_t number, offset_t offset = offset_t(-1),
unsigned display_width = 8)
930 :
Container(name), number(number), offset(offset), display_width(display_width)
962 std::shared_ptr<Linker::Image> image;
964 std::set<offset_t> signal_starts;
965 std::set<offset_t> signal_ends;
975 offset_t end = off + len - 1;
976 signal_starts.insert(off);
977 signal_ends.insert(end);
980 Block(std::string name, offset_t offset, std::shared_ptr<Linker::Image> image, offset_t address,
unsigned display_width,
982 :
Region(name, offset, image ? image->ImageSize() : 0, display_width),
992 static std::shared_ptr<Block> Make(std::string name, offset_t offset, std::shared_ptr<Linker::Image> image, offset_t address,
unsigned display_width,
998 void Display(Dumper& dump,
int options)
override;
1013 int show_options = All;
1014 int hide_options = None;
1019 Dumper(std::ostream& out)
1020 : out(out), use_ansi(
true), encoding(
nullptr), string_encoding(
nullptr)
1027 if(this->encoding ==
nullptr || force)
1029 this->encoding = &encoding;
1031 return old_encoding;
1036 Encoding * old_encoding = this->string_encoding;
1037 this->string_encoding = &encoding;
1038 return old_encoding;
1041 void SetTitle(std::string title)
1043 out <<
"=== " << title <<
" ===" << std::endl;
1051 void PrintHex(offset_t value,
unsigned width, std::string prefix =
"0x")
1053 out << prefix << std::hex << std::setw(width) << std::setfill(
'0') << value;
1060 void PrintHex(offset_t value,
unsigned width,
bool prefixed)
1062 PrintHex(value, width, prefixed ?
"0x" :
"");
1069 void PrintDec(offset_t value, std::string prefix =
"#")
1071 out << prefix << std::dec << value;
1079 out << prefix << std::dec << value;
1086 void PrintDec(offset_t value,
bool prefixed)
1088 PrintDec(value, prefixed ?
"#" :
"");
1098 const char32_t * input = &c;
1099 char * output =
nullptr;
1101 UTF32ToUTF8(input, output, 0, size);
1102 std::vector<char> buffer(size);
1103 output = buffer.data();
1104 UTF32ToUTF8(input, output, size, size);
1105 out << std::string(buffer.data(), buffer.size());
1108 void PutEncodedString(std::string encoded_string,
bool terminate_at_null =
false)
1110 uint8_t
const * input =
reinterpret_cast<uint8_t *
>(encoded_string.data());
1111 size_t length = encoded_string.size();
1113 while((c = (string_encoding ? string_encoding : encoding)->GetChar(input, length)) != char32_t(-1) || (terminate_at_null && c == U
'\0'))
1119 void PutEncodedString(offset_t width, std::string encoded_string,
char32_t padding)
1121 uint8_t
const * input =
reinterpret_cast<uint8_t *
>(encoded_string.data());
1122 size_t length = encoded_string.size();
1124 while(width > 0 && (c = (string_encoding ? string_encoding : encoding)->GetChar(input, length)) != char32_t(-1))
1173template <
unsigned I,
size_t ... Is,
typename ... Ts>
1174 inline auto rest_(std::tuple<Ts...> elements, std::index_sequence<Is...> s)
1176 return std::make_tuple(std::get<I + Is>(elements)...);
1179template <
unsigned I,
typename ... Ts>
1180 inline auto rest(std::tuple<Ts...> elements)
1182 return rest_<I>(elements, std::make_index_sequence<
sizeof...(Ts) - I>());
1185template <
typename ... Ts>
1186 void SectionedDisplay<Ts...>::DisplayValue(Dumper& dump, std::tuple<offset_t, Ts...> values)
1188 dump.PrintDec(std::get<0>(values),
"");
1189 dump.out << suffix <<
':';
1190 offset_display->DisplayValue(dump, rest<1>(values));
1193template <
typename Clock>
1194 void TimestampDisplay<Clock>::DisplayValue(Dumper& dump, std::tuple<Timestamp> values)
1196 dump.out << Clock::to_iso_time(std::get<0>(values));
A value that is separated into bitfields, typically bit flags.
Definition dumper.h:501
static std::shared_ptr< BitFieldDisplay > Make(unsigned width=8)
Create a bit field display.
Definition dumper.h:535
A display for a fixed length binary data field.
Definition dumper.h:596
std::shared_ptr< Display< std::string > > secondary_display
Alternative representation, appearing after the value.
Definition dumper.h:606
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:601
static std::shared_ptr< BlobDisplay > Make(size_t width, std::shared_ptr< Display< std::string > > secondary_display=nullptr)
Create a binary blob display.
Definition dumper.h:621
A region within a file that can be dumped, decompiled, and it may contain fixups.
Definition dumper.h:941
unsigned offset_display_width
Displaying in-file offsets.
Definition dumper.h:944
void AddSignal(offset_t off, offset_t len)
Add a relocation inside the image block.
Definition dumper.h:973
unsigned position_display_width
Displaying in-segment positions.
Definition dumper.h:946
void Display(Dumper &dump, int options) override
Passes information onto the dumper.
Definition dumper.cc:452
unsigned address_display_width
Displaying in-memory addresses.
Definition dumper.h:948
Represents an enumerated value, with named options.
Definition dumper.h:217
static std::shared_ptr< ChoiceDisplay > Make(std::map< offset_t, std::string > names, offset_t missing_value, std::string default_name="unknown", std::shared_ptr< Display< offset_t > > secondary_display=nullptr)
Create a choice display.
Definition dumper.h:268
std::map< offset_t, std::string > names
Maps values to names.
Definition dumper.h:222
std::shared_ptr< Display< offset_t > > secondary_display
Alternative representation, appearing in parentheses after the value.
Definition dumper.h:239
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:323
bool missing_on_value
If false, any value not listed in names is missing, otherwise only missing_value is missing.
Definition dumper.h:231
static std::shared_ptr< ChoiceDisplay > Make(std::string on_true, std::string on_false)
Creates a boolean choice.
Definition dumper.h:305
std::string default_name
Name for values not contained in names.
Definition dumper.h:226
static std::shared_ptr< ChoiceDisplay > Make(std::map< offset_t, std::string > names, offset_t missing_value, std::shared_ptr< Display< offset_t > > secondary_display)
Create a choice display.
Definition dumper.h:293
offset_t missing_value
The single missing value, only used for missing_on_value true.
Definition dumper.h:235
static std::shared_ptr< ChoiceDisplay > Make(std::map< offset_t, std::string > names, std::string default_name="unknown", std::shared_ptr< Display< offset_t > > secondary_display=nullptr)
Create a choice display.
Definition dumper.h:254
static std::shared_ptr< ChoiceDisplay > Make(std::map< offset_t, std::string > names, std::shared_ptr< Display< offset_t > > secondary_display)
Create a choice display.
Definition dumper.h:280
A record whose values should be displayed together, as a collection.
Definition dumper.h:797
Represents a field with a decimal display, usually indices into an array or similar,...
Definition dumper.h:369
static std::shared_ptr< DecDisplay > Make(bool enable_signed)
Creates a decimal display.
Definition dumper.h:384
static std::shared_ptr< DecDisplay > Make(std::string suffix="", bool enable_signed=false)
Creates a decimal display.
Definition dumper.h:396
This class represents an entry that can be displayed in a file dump.
Definition dumper.h:198
virtual bool IsMissing(std::tuple< Ts... > &values)
Returns true if the specified value is such that it should not be displayed.
Definition dumper.h:203
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.
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:1009
void PrintDecSigned(relative_offset_t value, std::string prefix="#")
Displays a decimal value (default prefix is "#")
Definition dumper.h:1077
void BeginBold()
ANSI escape sequence to begin bold text.
Definition dumper.h:1139
void PrintHex(offset_t value, unsigned width, std::string prefix="0x")
Displays a hexadecimal value (default prefix is "0x")
Definition dumper.h:1051
void EndBold()
ANSI escape sequence to end terminate text.
Definition dumper.h:1148
void EndUnderline()
ANSI escape sequence to remove all formatting.
Definition dumper.h:1166
void PrintDec(offset_t value, std::string prefix="#")
Displays a decimal value (default prefix is "#")
Definition dumper.h:1069
void BeginUnderline()
ANSI escape sequence to add underline.
Definition dumper.h:1157
void PutChar(char32_t c)
Displays a Unicode character as a UTF-8 byte sequence.
Definition dumper.h:1095
A brief record, such as a relocation or imported library.
Definition dumper.h:923
A typed representation of a named value within a structure.
Definition dumper.h:771
std::shared_ptr< Display< Ts... > > display
The method to show it in.
Definition dumper.h:774
A representation of a named value within a structure.
Definition dumper.h:746
std::string label
The name to be displayed.
Definition dumper.h:749
bool internal
The field should not be displayed, it is for internal use (alternatively, it can be displayed through...
Definition dumper.h:753
bool optional_field
If the field is optional, it will not be displayed for certain values.
Definition dumper.h:751
Represents a field with a hexadecimal display, typically bitfields, addresses, sizes,...
Definition dumper.h:343
static std::shared_ptr< HexDisplay > Make(unsigned width=8)
Creates a hexadecimal display.
Definition dumper.h:357
A record that represents a region within the file.
Definition dumper.h:902
A display for a fixed or variable length string field with formatting.
Definition dumper.h:701
static std::shared_ptr< RichTextDisplay > Make(std::string quote="")
Create a string display.
Definition dumper.h:728
static std::shared_ptr< RichTextDisplay > Make(std::string open_quote, std::string close_quote)
Create a string display.
Definition dumper.h:717
A display with a prefix for a section.
Definition dumper.h:461
static std::shared_ptr< SectionedDisplay > Make(std::string suffix, std::shared_ptr< Display< Ts... > > offset_display)
Create a sectioned display of an unsigned decimal and a secondary value.
Definition dumper.h:489
static std::shared_ptr< SectionedDisplay > Make(std::shared_ptr< Display< Ts... > > offset_display)
Create a sectioned display of an unsigned decimal and a secondary value.
Definition dumper.h:477
A value displayed as a colon-separated pair, typically 8086 segmented addresses.
Definition dumper.h:408
static std::shared_ptr< SegmentedDisplay > Make(unsigned width=4)
Create a segmented display of two hexadecimal values.
Definition dumper.h:422
A display for a fixed or variable length string field.
Definition dumper.h:639
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:644
static std::shared_ptr< StringDisplay > Make(size_t width, std::string quote="")
Create a string display.
Definition dumper.h:672
static std::shared_ptr< StringDisplay > Make(size_t width, std::string open_quote, std::string close_quote)
Create a string display.
Definition dumper.h:660
static std::shared_ptr< StringDisplay > Make(std::string quote="")
Create a string display.
Definition dumper.h:683
A value that holds a time point.
Definition dumper.h:562
A value displayed as a separated pair, such as a version number.
Definition dumper.h:434
static std::shared_ptr< VersionDisplay > Make(std::string separator=".")
Create a version display of two unsigned decimal values.
Definition dumper.h:448