10#include "../linker/image.h"
22 virtual char32_t GetChar(uint8_t
const *& input,
size_t& length) = 0;
24 char32_t operator[](uint8_t input)
26 uint8_t
const * input_pointer = &input;
28 return GetChar(input_pointer, length);
35 char32_t (* codepage)[256];
43 assert(this->codepage !=
nullptr);
46 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
57 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
63 ::EndianType endiantype;
66 : endiantype(endiantype)
70 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
77 ::EndianType endiantype;
80 : endiantype(endiantype)
84 char32_t GetChar(uint8_t
const *& input,
size_t& length)
override;
90template <
typename ... Ts>
100 return values == std::tuple<Ts...>();
116 std::map<offset_t, std::string>
names;
199 static std::shared_ptr<ChoiceDisplay>
Make(std::string on_true, std::string on_false)
201 std::map<offset_t, std::string>
names;
208 return std::make_shared<ChoiceDisplay>(
names,
"",
false, 0,
nullptr);
217 static std::shared_ptr<ChoiceDisplay>
Make(std::string on_true)
219 std::map<offset_t, std::string>
names;
226 return std::make_shared<ChoiceDisplay>(
names,
"unknown",
false, 0,
nullptr);
229 bool IsMissing(std::tuple<offset_t>& values)
override;
230 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
251 static std::shared_ptr<HexDisplay>
Make(
unsigned width = 8)
253 return std::make_shared<HexDisplay>(width);
256 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
266 bool enable_signed =
false;
267 DecDisplay(std::string suffix,
bool enable_signed)
268 : suffix(suffix), enable_signed(enable_signed)
278 static std::shared_ptr<DecDisplay>
Make(
bool enable_signed)
280 return std::make_shared<DecDisplay>(
"", enable_signed);
290 static std::shared_ptr<DecDisplay>
Make(std::string suffix =
"",
bool enable_signed =
false)
292 return std::make_shared<DecDisplay>(suffix, enable_signed);
295 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values)
override;
316 static std::shared_ptr<SegmentedDisplay>
Make(
unsigned width = 4)
318 return std::make_shared<SegmentedDisplay>(width);
321 void DisplayValue(
Dumper& dump, std::tuple<offset_t, offset_t> values)
override;
330 std::string separator;
332 : separator(separator)
342 static std::shared_ptr<VersionDisplay>
Make(std::string separator =
".")
344 return std::make_shared<VersionDisplay>(separator);
347 void DisplayValue(
Dumper& dump, std::tuple<offset_t, offset_t> values)
override;
353template <
typename ... Ts>
358 std::shared_ptr<
Display<Ts...>> offset_display;
361 : suffix(suffix), offset_display(offset_display)
373 return Make(
"", offset_display);
383 static std::shared_ptr<SectionedDisplay>
Make(std::string suffix, std::shared_ptr<
Display<Ts...>> offset_display)
385 return std::make_shared<SectionedDisplay>(suffix, offset_display);
388 void DisplayValue(
Dumper& dump, std::tuple<offset_t, Ts...> values)
override;
400 unsigned offset, length;
401 std::shared_ptr<Display<offset_t>> display;
405 BitField(
unsigned offset,
unsigned length, std::shared_ptr<
Display<offset_t>> display,
bool optional_field, std::string label)
406 : offset(offset), length(length), display(display), optional_field(optional_field), label(label)
410 bool ShouldDisplay(std::tuple<offset_t>& values)
412 return !optional_field || !display->IsMissing(values);
416 std::map<unsigned, std::unique_ptr<BitField>> bitfields;
429 static std::shared_ptr<BitFieldDisplay>
Make(
unsigned width = 8)
431 return std::make_shared<BitFieldDisplay>(width);
434 std::shared_ptr<BitFieldDisplay> AddBitField(
unsigned offset,
unsigned length, std::shared_ptr<
Display<offset_t>> display,
bool optional_field)
436 bitfields[offset] = std::make_unique<BitField>(offset, length, display, optional_field,
"");
437 return shared_from_this();
440 std::shared_ptr<BitFieldDisplay> AddBitField(
unsigned offset,
unsigned length, std::string label, std::shared_ptr<Display<offset_t>> display,
bool optional_field =
false)
442 bitfields[offset] = std::make_unique<BitField>(offset, length, display, optional_field, label);
443 return shared_from_this();
446 void DisplayValue(Dumper& dump, std::tuple<offset_t> values)
override;
459 std::string open_quote, close_quote;
462 :
width(
width), open_quote(open_quote), close_quote(close_quote)
474 static std::shared_ptr<StringDisplay>
Make(
size_t width, std::string open_quote, std::string close_quote)
476 return std::make_shared<StringDisplay>(
width, open_quote, close_quote);
486 static std::shared_ptr<StringDisplay>
Make(
size_t width, std::string quote =
"")
488 return std::make_shared<StringDisplay>(
width, quote, quote);
497 static std::shared_ptr<StringDisplay>
Make(std::string quote =
"")
499 return std::make_shared<StringDisplay>(-1, quote, quote);
502 bool IsMissing(std::tuple<std::string>& values)
override;
503 void DisplayValue(
Dumper& dump, std::tuple<std::string> values)
override;
505 using Display<std::string>::IsMissing;
506 bool IsMissing(std::tuple<offset_t>& values);
507 using Display<std::string>::DisplayValue;
508 void DisplayValue(
Dumper& dump, std::tuple<offset_t> values);
531 virtual bool ShouldDisplay() = 0;
532 virtual void DisplayValue(
Dumper& dump) = 0;
538template <
typename ... Ts>
544 std::tuple<Ts...> values;
551 bool ShouldDisplay()
override
556 void DisplayValue(Dumper& dump)
override
558 display->DisplayValue(dump, values);
570 std::map<std::string, std::shared_ptr<Field>> field_names;
571 std::vector<std::shared_ptr<Field>> fields;
580 std::shared_ptr<Field> FindField(std::string name)
582 auto it = field_names.find(name);
583 if(it == field_names.end())
588 template <
typename T>
589 T GetField(std::string name, offset_t default_value = T())
591 auto it = field_names.find(name);
592 if(it == field_names.end())
593 return default_value;
594 if(
auto field = std::dynamic_pointer_cast<
FieldOf<T>>(it->second))
596 return std::get<0>(field->values);
598 return default_value;
602 offset_t GetField(std::string name,
int index, offset_t default_value)
604 auto it = field_names.find(name);
605 if(it == field_names.end())
606 return default_value;
607 return it->second->values[index];
611 void AddField(std::shared_ptr<Field> field)
613 fields.push_back(field);
614 field_names[field->label] = field;
617 void AddField(
size_t index, std::shared_ptr<Field> field)
619 fields.insert(fields.begin() + index, field);
620 field_names[field->label] = field;
623 template <
typename D,
typename ... Ts>
624 void AddField(std::string label, std::shared_ptr<D> display, Ts... values)
626 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
false));
629 template <
typename D,
typename ... Ts>
630 void AddOptionalField(std::string label, std::shared_ptr<D> display, Ts... values)
632 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
true,
false));
635 template <
typename D,
typename ... Ts>
636 void AddHiddenField(std::string label, std::shared_ptr<D> display, Ts... values)
638 AddField(std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
true));
641 template <
typename D,
typename ... Ts>
642 void InsertField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
644 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
false));
647 template <
typename D,
typename ... Ts>
648 void InsertOptionalField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
650 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
true,
false));
653 template <
typename D,
typename ... Ts>
654 void InsertHiddenField(
size_t index, std::string label, std::shared_ptr<D> display, Ts... values)
656 AddField(index, std::make_shared<
FieldOf<Ts...>>(label, display, values...,
false,
true));
668 Region(std::string name, offset_t offset, offset_t length,
unsigned display_width)
675 static std::shared_ptr<Region> Make(std::string name, offset_t offset, offset_t length,
unsigned display_width)
677 return std::make_shared<Region>(name, offset, length, display_width);
691 unsigned display_width;
693 Entry(std::string name, offset_t number, offset_t offset = offset_t(-1),
unsigned display_width = 8)
694 :
Container(name), number(number), offset(offset), display_width(display_width)
726 std::shared_ptr<Linker::Image> image;
728 std::set<offset_t> signal_starts;
729 std::set<offset_t> signal_ends;
739 offset_t end = off + len - 1;
740 signal_starts.insert(off);
741 signal_ends.insert(end);
744 Block(std::string name, offset_t offset, std::shared_ptr<Linker::Image> image, offset_t address,
unsigned display_width,
746 :
Region(name, offset, image ? image->ImageSize() : 0, display_width),
756 static std::shared_ptr<Block> Make(std::string name, offset_t offset, std::shared_ptr<Linker::Image> image, offset_t address,
unsigned display_width,
762 void Display(Dumper& dump)
override;
782 : out(out), use_ansi(
true), encoding(
nullptr), string_encoding(
nullptr)
789 if(this->encoding ==
nullptr || force)
791 this->encoding = &encoding;
798 Encoding * old_encoding = this->string_encoding;
799 this->string_encoding = &encoding;
803 void SetTitle(std::string title)
805 out <<
"=== " << title <<
" ===" << std::endl;
813 void PrintHex(offset_t value,
unsigned width, std::string prefix =
"0x")
815 out << prefix << std::hex << std::setw(width) << std::setfill(
'0') << value;
822 void PrintHex(offset_t value,
unsigned width,
bool prefixed)
824 PrintHex(value, width, prefixed ?
"0x" :
"");
831 void PrintDec(offset_t value, std::string prefix =
"#")
833 out << prefix << std::dec << value;
841 out << prefix << std::dec << value;
848 void PrintDec(offset_t value,
bool prefixed)
850 PrintDec(value, prefixed ?
"#" :
"");
860 const char32_t * input = &c;
861 char * output =
nullptr;
863 UTF32ToUTF8(input, output, 0, size);
864 std::vector<char> buffer(size);
865 output = buffer.data();
866 UTF32ToUTF8(input, output, size, size);
867 out << std::string(buffer.data(), buffer.size());
870 void PutEncodedString(std::string encoded_string,
bool terminate_at_null =
false)
872 uint8_t
const * input =
reinterpret_cast<uint8_t *
>(encoded_string.data());
873 size_t length = encoded_string.size();
875 while((c = (string_encoding ? string_encoding : encoding)->GetChar(input, length)) != char32_t(-1) || (terminate_at_null && c == U
'\0'))
881 void PutEncodedString(offset_t width, std::string encoded_string,
char32_t padding)
883 uint8_t
const * input =
reinterpret_cast<uint8_t *
>(encoded_string.data());
884 size_t length = encoded_string.size();
886 while(width > 0 && (c = (string_encoding ? string_encoding : encoding)->GetChar(input, length)) != char32_t(-1))
917template <
unsigned I,
size_t ... Is,
typename ... Ts>
918 inline auto rest_(std::tuple<Ts...> elements, std::index_sequence<Is...> s)
920 return std::make_tuple(std::get<I + Is>(elements)...);
923template <
unsigned I,
typename ... Ts>
924 inline auto rest(std::tuple<Ts...> elements)
926 return rest_<I>(elements, std::make_index_sequence<
sizeof...(Ts) - I>());
929template <
typename ... Ts>
930 void SectionedDisplay<Ts...>::DisplayValue(Dumper& dump, std::tuple<offset_t, Ts...> values)
932 dump.PrintDec(std::get<0>(values),
"");
933 dump.out << suffix <<
':';
934 offset_display->DisplayValue(dump, rest<1>(values));
A value that is separated into bitfields, typically bit flags.
Definition dumper.h:395
static std::shared_ptr< BitFieldDisplay > Make(unsigned width=8)
Create a bit field display.
Definition dumper.h:429
A region within a file that can be dumped, decompiled, and it may contain fixups.
Definition dumper.h:705
unsigned offset_display_width
Displaying in-file offsets.
Definition dumper.h:708
void AddSignal(offset_t off, offset_t len)
Add a relocation inside the image block.
Definition dumper.h:737
unsigned position_display_width
Displaying in-segment positions.
Definition dumper.h:710
unsigned address_display_width
Displaying in-memory addresses.
Definition dumper.h:712
Represents an enumerated value, with named options.
Definition dumper.h:111
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:162
std::map< offset_t, std::string > names
Maps values to names.
Definition dumper.h:116
std::shared_ptr< Display< offset_t > > secondary_display
Alternative representation, appearing in parentheses after the value.
Definition dumper.h:133
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:217
bool missing_on_value
If false, any value not listed in names is missing, otherwise only missing_value is missing.
Definition dumper.h:125
static std::shared_ptr< ChoiceDisplay > Make(std::string on_true, std::string on_false)
Creates a boolean choice.
Definition dumper.h:199
std::string default_name
Name for values not contained in names.
Definition dumper.h:120
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:187
offset_t missing_value
The single missing value, only used for missing_on_value true.
Definition dumper.h:129
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:148
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:174
A record whose values should be displayed together, as a collection.
Definition dumper.h:566
Represents a field with a decimal display, usually indices into an array or similar,...
Definition dumper.h:263
static std::shared_ptr< DecDisplay > Make(bool enable_signed)
Creates a decimal display.
Definition dumper.h:278
static std::shared_ptr< DecDisplay > Make(std::string suffix="", bool enable_signed=false)
Creates a decimal display.
Definition dumper.h:290
This class represents an entry that can be displayed in a file dump.
Definition dumper.h:92
virtual bool IsMissing(std::tuple< Ts... > &values)
Returns true if the specified value is such that it should not be displayed.
Definition dumper.h:97
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:773
void PrintDecSigned(relative_offset_t value, std::string prefix="#")
Displays a decimal value (default prefix is "#")
Definition dumper.h:839
void PrintHex(offset_t value, unsigned width, std::string prefix="0x")
Displays a hexadecimal value (default prefix is "0x")
Definition dumper.h:813
void EndUnderline()
ANSI escape sequence to remove all formatting.
Definition dumper.h:910
void PrintDec(offset_t value, std::string prefix="#")
Displays a decimal value (default prefix is "#")
Definition dumper.h:831
void BeginUnderline()
ANSI escape sequence to add underline.
Definition dumper.h:901
void PutChar(char32_t c)
Displays a Unicode character as a UTF-8 byte sequence.
Definition dumper.h:857
A brief record, such as a relocation or imported library.
Definition dumper.h:687
A typed representation of a named value within a structure.
Definition dumper.h:540
std::shared_ptr< Display< Ts... > > display
The method to show it in.
Definition dumper.h:543
A representation of a named value within a structure.
Definition dumper.h:515
std::string label
The name to be displayed.
Definition dumper.h:518
bool internal
The field should not be displayed, it is for internal use (alternatively, it can be displayed through...
Definition dumper.h:522
bool optional_field
If the field is optional, it will not be displayed for certain values.
Definition dumper.h:520
Represents a field with a hexadecimal display, typically bitfields, addresses, sizes,...
Definition dumper.h:237
static std::shared_ptr< HexDisplay > Make(unsigned width=8)
Creates a hexadecimal display.
Definition dumper.h:251
A record that represents a region within the file.
Definition dumper.h:666
A display with a prefix for a section.
Definition dumper.h:355
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:383
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:371
A value displayed as a colon-separated pair, typically 8086 segmented addresses.
Definition dumper.h:302
static std::shared_ptr< SegmentedDisplay > Make(unsigned width=4)
Create a segmented display of two hexadecimal values.
Definition dumper.h:316
A display for a fixed or variable length string field.
Definition dumper.h:453
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:458
static std::shared_ptr< StringDisplay > Make(size_t width, std::string quote="")
Create a string display.
Definition dumper.h:486
static std::shared_ptr< StringDisplay > Make(size_t width, std::string open_quote, std::string close_quote)
Create a string display.
Definition dumper.h:474
static std::shared_ptr< StringDisplay > Make(std::string quote="")
Create a string display.
Definition dumper.h:497
A value displayed as a separated pair, such as a version number.
Definition dumper.h:328
static std::shared_ptr< VersionDisplay > Make(std::string separator=".")
Create a version display of two unsigned decimal values.
Definition dumper.h:342