5#include "../dumper/dumper.h"
6#include "../linker/buffer.h"
7#include "../linker/reader.h"
8#include "../linker/segment_manager.h"
9#include "../linker/writer.h"
37 InterleaveRepeatBlockWithBlockCopy = 3,
38 InterleaveRepeatBlockWithZero = 4,
54 static size_t GetValueSize(uint32_t value,
size_t size_hint = 0);
92 std::weak_ptr<PEFFormat::Section> section;
94 std::weak_ptr<ImportedSymbol> symbol;
96 static inline Relocation ToSection(uint32_t section_number)
100 relocation.number = section_number;
104 static inline Relocation ToSection(std::weak_ptr<PEFFormat::Section> section)
108 relocation.compiled =
false;
109 relocation.section = section;
113 static inline Relocation ToSymbol(uint32_t symbol_number)
116 relocation.type = Symbol;
117 relocation.number = symbol_number;
121 static inline Relocation ToSymbol(std::weak_ptr<ImportedSymbol> symbol)
124 relocation.type = Symbol;
125 relocation.compiled =
false;
126 relocation.symbol = symbol;
145 size_t reloc_instr_ptr = 0;
146 uint32_t reloc_address = 0;
147 uint32_t import_index = 0;
148 uint32_t section_c = 0;
149 uint32_t section_d = 0;
150 uint32_t current_repeat_count = 0;
152 std::vector<RelocOpcode>& reloc_opcodes;
153 std::map<uint32_t, Relocation>& relocations;
158 : pef_format(pef_format), reloc_opcodes(reloc_opcodes), relocations(relocations)
163 void Advance(uint32_t offset)
165 reloc_address += offset;
170 relocations[reloc_address] = relocation;
174 void AddSection(uint32_t section_number)
176 AddRelocation(Relocation::ToSection(section_number));
181 AddSection(section_c);
186 AddSection(section_d);
191 AddRelocation(Relocation::ToSymbol(import_index));
196 void Regress(uint32_t block_count);
208 void Repeat(uint32_t block_count, uint32_t repeat_count)
211 if(current_repeat_count != 1)
218 if(current_repeat_count == 0)
221 current_repeat_count = repeat_count;
225 current_repeat_count --;
229 void GenerateRelocations();
241 BySectDWithSkip = 0x0000,
251 SmBySection = 0x6600,
252 IncrPosition = 0x8000,
254 SetPosition = 0xA000,
257 LgBySection = 0xB400,
311 void Dump(
Dumper::Dumper& dump,
const PEFFormat& pef_format, uint32_t opcode_index,
int display_options = 0)
const;
321 PatternInitializedData = 2,
335 static constexpr uint32_t NoNameOffset = uint32_t(-1);
336 uint32_t name_offset = NoNameOffset;
337 std::string name =
"";
338 uint32_t default_address = 0;
339 uint32_t total_size = 0;
340 uint32_t unpacked_size = 0;
341 uint32_t packed_size = 0;
342 uint32_t container_offset = 0;
343 section_type section_kind = Code;
344 share_type share_kind = ProcessShare;
345 uint8_t alignment = 0;
346 uint8_t reserved = 0;
348 uint32_t section_number = uint32_t(-1);
350 std::shared_ptr<Linker::Contents> image;
351 std::vector<PatternInitialization> patterns;
353 std::map<uint32_t, Relocation> relocations;
354 std::vector<RelocOpcode> reloc_opcodes;
355 bool contains_relocations =
false;
356 uint16_t reserved_a = 0;
357 uint32_t reloc_instr_size = 0;
358 uint32_t first_reloc_offset = 0;
361 Section(section_type section_kind, share_type share_kind, std::shared_ptr<Linker::Contents> image)
362 : section_kind(section_kind), share_kind(share_kind), image(image)
364 alignment = ExpectedAlignment();
367 bool IsInstantiated()
const
373 case PatternInitializedData:
382 offset_t ExpectedAlignment()
const
391 case PatternInitializedData:
401 size_t GetImageSize(
PEFFormat& pef_format);
415 cpu_type architecture = PPC;
416 uint32_t format_version = 1;
417 uint32_t date_time_stamp = 0;
418 uint32_t old_def_version = 0;
419 uint32_t old_imp_version = 0;
420 uint32_t current_version = 0;
421 uint32_t reserved = 0;
422 uint16_t inst_section_count = 0;
423 std::vector<std::shared_ptr<Section>> sections;
424 std::vector<std::string> section_name_table;
425 uint32_t section_name_table_end = 0;
427 static constexpr uint32_t ContainerHeaderSize = 40;
428 static constexpr uint32_t SectionHeaderSize = 28;
430 uint32_t GetSectionNameTableOffset()
const
432 return ContainerHeaderSize + SectionHeaderSize * sections.size();
436 uint32_t loader_section_offset = 0;
438 static constexpr uint32_t NoSection = uint32_t(-1);
439 static constexpr uint32_t Absolute = uint32_t(-2);
440 static constexpr uint32_t Reexported = uint32_t(-3);
445 std::weak_ptr<Section> section_pointer;
446 uint32_t section = NoSection;
451 bool IsPresent()
const {
return section != NoSection; }
452 void StoreSectionIndex()
454 auto actual_section = section_pointer.lock();
455 section = actual_section ? actual_section->section_number : NoSection;
458 Reference main_symbol, init_symbol, term_symbol;
464 uint32_t name_offset = 0;
465 std::string name =
"";
468 void StoreNameString(
PEFFormat& pef_format);
469 void StoreNameStringNoNull(
PEFFormat& pef_format);
473 Name(std::string name)
481 enum symbol_class_type
489 static inline constexpr bool IsValidSymbolClass(
int value)
507 symbol_class_type symbol_class = TVect;
510 uint32_t symbol_number = uint32_t(-1);
515 std::weak_ptr<ImportedLibrary> library;
521 uint32_t old_imp_version = 0;
522 uint32_t current_version = 0;
523 uint32_t imported_symbol_count = 0;
524 uint32_t first_imported_symbol = 0;
525 std::vector<std::shared_ptr<ImportedSymbol>> imported_symbols;
527 std::map<std::string, std::shared_ptr<ImportedSymbol>> named_imported_symbols;
529 uint8_t reserved_a = 0;
530 uint16_t reserved_b = 0;
535 std::shared_ptr<ImportedSymbol> GetImportByName(std::string name)
537 auto symbol_iter = named_imported_symbols.find(name);
538 if(symbol_iter == named_imported_symbols.end())
540 auto symbol = std::make_shared<ImportedSymbol>(name);
541 imported_symbols.push_back(symbol);
542 named_imported_symbols[name] = symbol;
547 return symbol_iter->second;
551 std::vector<std::shared_ptr<ImportedLibrary>> imported_libraries;
553 std::map<std::string, std::shared_ptr<ImportedLibrary>> named_imported_libraries;
554 std::vector<std::shared_ptr<ImportedSymbol>> imported_symbols;
555 std::vector<uint32_t> reloc_section_indexes;
556 uint32_t reloc_instr_offset = 0;
557 uint32_t loader_strings_offset = 0;
558 uint32_t export_hash_offset = 0;
559 std::vector<RelocOpcode> relocs_area;
560 uint32_t relocs_area_size = 0;
561 std::vector<std::string> loader_string_table;
562 uint32_t loader_string_table_size = 0;
568 uint16_t chain_count = 0;
569 uint32_t first_index = 0;
572 std::vector<std::shared_ptr<ExportedSymbol>> chain;
574 std::vector<HashTableEntry> hash_table;
578 uint16_t symbol_length = 0;
579 uint16_t hash_value = 0;
580 symbol_class_type symbol_class = Data;
590 :
Name(name), symbol_class(symbol_class)
594 using Name::LoadNameString;
597 std::vector<std::shared_ptr<ExportedSymbol>> exported_symbols;
599 static uint32_t ComputeHashWord(std::string name);
600 static uint32_t HashTableIndex(uint32_t hash_word, uint32_t export_hash_table_power);
601 static uint8_t ComputeHashTableExponent(uint32_t hash_table_size);
603 std::shared_ptr<ImportedLibrary> FetchImportLibrary(std::string name)
605 auto library_iter = named_imported_libraries.find(name);
606 if(library_iter == named_imported_libraries.end())
608 auto library = std::make_shared<ImportedLibrary>(name);
609 imported_libraries.push_back(library);
610 named_imported_libraries[name] = library;
615 return library_iter->second;
619 static constexpr uint32_t LoaderHeaderSize = 56;
620 static constexpr uint32_t LibraryDescriptionSize = 28;
621 uint32_t GetLibraryDescriptionsSize()
const
623 return LibraryDescriptionSize * imported_libraries.size();
625 uint32_t GetSymbolTablesSize()
const
628 for(
auto library : imported_libraries)
630 size += 4 * library->imported_symbols.size();
634 uint32_t GetRelocationHeadersSize()
const
636 return 12 * reloc_section_indexes.size();
638 uint32_t GetRelocationAreaSize()
const
640 return relocs_area_size;
642 uint32_t GetLoaderStringAreaSize()
const
644 return loader_string_table_size;
646 uint32_t GetExportHashTableSize()
const
648 return 4 * hash_table.size();
650 uint32_t GetExportKeyTableSize()
const
652 return 4 * exported_symbols.size();
654 uint32_t GetExportSymbolTableSize()
const
656 return 10 * exported_symbols.size();
659 uint32_t GetMinimumRelocInstrOffset()
const
661 return LoaderHeaderSize
662 + GetLibraryDescriptionsSize()
663 + GetSymbolTablesSize()
664 + GetRelocationHeadersSize();
667 uint32_t GetLoaderSectionSize()
const
670 std::max({LoaderHeaderSize
671 + GetLibraryDescriptionsSize()
672 + GetSymbolTablesSize()
673 + GetRelocationHeadersSize(),
674 reloc_instr_offset + GetRelocationAreaSize(),
675 loader_strings_offset + GetLoaderStringAreaSize(),
677 + GetExportHashTableSize()
678 + GetExportKeyTableSize()
679 + GetExportSymbolTableSize()});
683 std::map<std::shared_ptr<Linker::Segment>, std::shared_ptr<Section>> segment_to_section_map;
697 void OnNewSegment(std::shared_ptr<Linker::Segment> segment)
override;
An abstract interface that separates structure and presentation of the data inside a file.
Definition dumper.h:828
A buffer that can be used to read and store data from a file.
Definition buffer.h:22
Encodes an object module file as a collection of sections, symbols and relocations.
Definition module.h:24
Stores an absolute address along with the containing segment or address space.
Definition position.h:17
A helper class, encapsulating functionality needed to import binary data.
Definition reader.h:20
A helper class to collect sections into segments.
Definition segment_manager.h:32
A helper class, encapsulating functionality needed to export binary data.
Definition writer.h:15
void WriteWord(size_t bytes, uint64_t value, EndianType endiantype)
Read a word.
Definition writer.cc:67