34 unsigned FormatAdditionalSectionFlags(std::string section_name)
const override;
36 ::EndianType endiantype = ::LittleEndian;
47 system_type system = system_type(0);
53 PreProcessInitialization = 0x00000004,
54 NoInternalFixup = 0x00000010,
55 NoExternalFixup = 0x00000020,
56 FullScreen = 0x00000100,
57 GUIAware = 0x00000200,
59 ErrorInImage = 0x00002000,
61 ProtectedMemoryLibrary = 0x00018000,
62 PhysicalDriver = 0x00020000,
63 VirtualDriver = 0x00028000,
64 PerProcessTermination = 0x40000000,
66 uint32_t module_flags = 0;
68 bool IsLibrary()
const;
70 bool IsDriver()
const;
72 bool extended_format =
false;
88 enum compatibility_type
95 compatibility_type compatibility = CompatibleNone;
103 LEFormat(
unsigned system,
unsigned module_flags,
bool extended_format)
104 : system(system_type(system)), module_flags(module_flags), extended_format(extended_format), last_page_size(0)
109 static std::shared_ptr<LEFormat> CreateConsoleApplication(system_type system = OS2);
111 static std::shared_ptr<LEFormat> CreateGUIApplication(system_type system = OS2);
113 static std::shared_ptr<LEFormat> CreateLibraryModule(system_type system = OS2);
115 std::shared_ptr<LEFormat> SimulateLinker(compatibility_type compatibility);
118 std::string program_name, module_name;
120 uint32_t page_count = 0;
121 uint32_t eip_object = 0, eip_value = 0, esp_object = 0, esp_value = 0;
124 uint32_t last_page_size;
125 uint32_t page_offset_shift;
127 uint32_t fixup_section_size = 0, loader_section_size = 0;
128 uint32_t object_table_offset = 0, object_page_table_offset = 0, object_iterated_pages_offset = 0;
129 uint32_t resource_table_offset = 0, resource_table_entry_count = 0, resident_name_table_offset = 0;
130 uint32_t entry_table_offset = 0, fixup_page_table_offset = 0, fixup_record_table_offset = 0;
131 uint32_t imported_module_table_offset = 0, imported_procedure_table_offset = 0;
132 uint32_t data_pages_offset = 0, nonresident_name_table_offset = 0, nonresident_name_table_size = 0;
133 uint32_t automatic_data = 0, stack_size = 0, heap_size = 0;
138 std::shared_ptr<Linker::Segment> image;
145 Discardable = 0x0010,
147 PreloadPages = 0x0040,
148 InvalidPages = 0x0080,
149 ZeroFilledPages = 0x0100,
151 ResidentContiguous = 0x0300,
152 ResidentLongLockable = 0x0400,
156 IOPrivilege = 0x8000,
159 uint32_t page_table_index = 0;
160 uint32_t page_entry_count = 0;
161 uint32_t data_pages_offset = 0;
163 Object(std::shared_ptr<Linker::Segment> segment,
unsigned flags)
164 : image(segment), flags(flag_type(flags))
169 void AddRelocation(
Object&
object,
unsigned type,
unsigned flags,
size_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0);
178 uint32_t fixup_table_index;
203 uint32_t fixup_offset = 0;
218 SourceTypeMask = 0x0F,
223 source_type type = source_type(0);
239 flag_type flags = flag_type(0);
242 uint32_t addition = 0;
245 : Writer(::LittleEndian)
249 Relocation(
unsigned type,
unsigned flags, uint16_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0)
250 : Writer(::LittleEndian), type(source_type(type)), flags(flag_type(flags)), module(module), target(target), addition(addition)
252 sources.push_back(offset);
257 bool IsExternal()
const;
259 bool IsSelectorOrOffset()
const;
261 bool ComesBefore()
const;
263 size_t GetSourceSize()
const;
266 std::vector<uint16_t> sources;
270 void DecrementSingleSourceOffset(
size_t amount);
272 bool IsSelector()
const;
273 bool IsSourceList()
const;
274 bool IsAdditive()
const;
275 size_t GetTargetSize()
const;
276 size_t GetAdditiveSize()
const;
277 size_t GetModuleSize()
const;
278 size_t GetOrdinalSize()
const;
280 void CalculateSizes(compatibility_type compatibility);
282 size_t GetSize()
const;
284 void WriteFile(
Linker::Writer& wr, compatibility_type compatibility)
const;
286 std::map<uint16_t, Relocation> relocations;
294 Page(uint16_t fixup_table_index, uint8_t type)
295 : le{fixup_table_index, type}
299 Page(uint32_t offset, uint16_t size, uint8_t flags)
300 : lx{offset, size, flags}
305 static Page LEPage(uint16_t fixup_table_index, uint8_t type);
307 static Page LXPage(uint32_t offset, uint16_t size, uint8_t flags);
333 entry_type type = Unused;
340 flag_type flags = flag_type(0);
344 : Writer(::LittleEndian)
348 Entry(
unsigned type, uint16_t
object,
unsigned flags, uint32_t offset)
349 : Writer(::LittleEndian), type(entry_type(type)), object(
object), flags(flag_type(flags)), offset(offset)
353 bool SameBundle(
const Entry& other)
const;
355 offset_t GetEntryHeadSize()
const;
357 offset_t GetEntryBodySize()
const;
365 static const uint32_t page_size = 0x1000;
367 std::shared_ptr<Linker::Segment> stack, heap;
368 std::vector<Object> objects;
369 std::map<std::shared_ptr<Linker::Segment>,
size_t> object_index;
370 std::vector<Page> pages;
371 std::vector<Resource> resources;
372 std::vector<Name> resident_names, nonresident_names;
373 std::vector<Entry> entries;
374 std::vector<std::string> imported_modules, imported_procedures;
375 std::map<std::string, uint32_t> imported_procedure_name_offsets;
376 offset_t imported_procedure_names_length = 0;
378 unsigned GetDefaultObjectFlags()
const;
379 void AddObject(
const Object&
object);
380 uint16_t FetchImportedModuleName(std::string name);
381 uint16_t FetchImportedProcedureName(std::string name);
384 uint8_t CountBundles(
size_t entry_index)
const;
386 void SetOptions(std::map<std::string, std::string>& options)
override;
387 void OnNewSegment(std::shared_ptr<Linker::Segment> segment)
override;