33 unsigned FormatAdditionalSectionFlags(std::string section_name)
const override;
35 ::EndianType endiantype = ::LittleEndian;
51 PreProcessInitialization = 0x00000004,
52 NoInternalFixup = 0x00000010,
53 NoExternalFixup = 0x00000020,
54 FullScreen = 0x00000100,
55 GUIAware = 0x00000200,
57 ErrorInImage = 0x00002000,
59 ProtectedMemoryLibrary = 0x00018000,
60 PhysicalDriver = 0x00020000,
61 VirtualDriver = 0x00028000,
62 PerProcessTermination = 0x40000000,
64 uint32_t module_flags;
66 bool IsLibrary()
const;
68 bool IsDriver()
const;
86 enum compatibility_type
93 compatibility_type compatibility = CompatibleNone;
96 LEFormat(
unsigned system,
unsigned module_flags,
bool extended_format)
97 : system((system_type)system), module_flags(module_flags), extended_format(extended_format), last_page_size(0)
102 static std::shared_ptr<LEFormat> CreateConsoleApplication(system_type system = OS2);
104 static std::shared_ptr<LEFormat> CreateGUIApplication(system_type system = OS2);
106 static std::shared_ptr<LEFormat> CreateLibraryModule(system_type system = OS2);
108 std::shared_ptr<LEFormat> SimulateLinker(compatibility_type compatibility);
111 std::string program_name, module_name;
113 uint32_t page_count = 0;
114 uint32_t eip_object = 0, eip_value = 0, esp_object = 0, esp_value = 0;
117 uint32_t last_page_size;
118 uint32_t page_offset_shift;
120 uint32_t fixup_section_size = 0, loader_section_size = 0;
121 uint32_t object_table_offset = 0, object_page_table_offset = 0, object_iterated_pages_offset = 0;
122 uint32_t resource_table_offset = 0, resource_table_entry_count = 0, resident_name_table_offset = 0;
123 uint32_t entry_table_offset = 0, fixup_page_table_offset = 0, fixup_record_table_offset = 0;
124 uint32_t imported_module_table_offset = 0, imported_procedure_table_offset = 0;
125 uint32_t data_pages_offset = 0, nonresident_name_table_offset = 0, nonresident_name_table_size = 0;
126 uint32_t automatic_data = 0, stack_size = 0, heap_size = 0;
131 std::shared_ptr<Linker::Segment> image;
138 Discardable = 0x0010,
140 PreloadPages = 0x0040,
141 InvalidPages = 0x0080,
142 ZeroFilledPages = 0x0100,
144 ResidentContiguous = 0x0300,
145 ResidentLongLockable = 0x0400,
149 IOPrivilege = 0x8000,
152 uint32_t page_table_index = 0;
153 uint32_t page_entry_count = 0;
154 uint32_t data_pages_offset = 0;
156 Object(std::shared_ptr<Linker::Segment> segment,
unsigned flags)
157 : image(segment), flags((flag_type)flags)
162 void AddRelocation(
Object&
object,
unsigned type,
unsigned flags,
size_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0);
171 uint32_t fixup_table_index;
196 uint32_t fixup_offset = 0;
211 SourceTypeMask = 0x0F,
216 source_type type = source_type(0);
232 flag_type flags = flag_type(0);
235 uint32_t addition = 0;
238 : Writer(::LittleEndian)
242 Relocation(
unsigned type,
unsigned flags, uint16_t offset, uint16_t module, uint32_t target = 0, uint32_t addition = 0)
243 : Writer(::LittleEndian), type((source_type)type), flags((flag_type)flags), module(module), target(target), addition(addition)
245 sources.push_back(offset);
250 bool IsExternal()
const;
252 bool IsSelectorOrOffset()
const;
254 bool ComesBefore()
const;
256 size_t GetSourceSize()
const;
259 std::vector<uint16_t> sources;
263 void DecrementSingleSourceOffset(
size_t amount);
265 bool IsSelector()
const;
266 bool IsSourceList()
const;
267 bool IsAdditive()
const;
268 size_t GetTargetSize()
const;
269 size_t GetAdditiveSize()
const;
270 size_t GetModuleSize()
const;
271 size_t GetOrdinalSize()
const;
273 void CalculateSizes(compatibility_type compatibility);
275 size_t GetSize()
const;
277 void WriteFile(
Linker::Writer& wr, compatibility_type compatibility);
279 std::map<uint16_t, Relocation> relocations;
287 Page(uint16_t fixup_table_index, uint8_t type)
288 : le{fixup_table_index, type}
292 Page(uint32_t offset, uint16_t size, uint8_t flags)
293 : lx{offset, size, flags}
298 static Page LEPage(uint16_t fixup_table_index, uint8_t type);
300 static Page LXPage(uint32_t offset, uint16_t size, uint8_t flags);
326 entry_type type = Unused;
333 flag_type flags = flag_type(0);
337 : Writer(::LittleEndian)
341 Entry(
unsigned type, uint16_t
object,
unsigned flags, uint32_t offset)
342 : Writer(::LittleEndian), type((entry_type)type), object(
object), flags((flag_type)flags), offset(offset)
346 bool SameBundle(
const Entry& other)
const;
348 offset_t GetEntryHeadSize()
const;
350 offset_t GetEntryBodySize()
const;
357 static const uint32_t page_size = 0x1000;
359 std::shared_ptr<Linker::Segment> stack, heap;
360 std::vector<Object> objects;
361 std::map<std::shared_ptr<Linker::Segment>,
size_t> object_index;
362 std::vector<Page> pages;
363 std::vector<Resource> resources;
364 std::vector<Name> resident_names, nonresident_names;
365 std::vector<Entry> entries;
366 std::vector<std::string> imported_modules, imported_procedures;
367 std::map<std::string, uint32_t> imported_procedure_name_offsets;
368 offset_t imported_procedure_names_length = 0;
370 unsigned GetDefaultObjectFlags()
const;
371 void AddObject(
const Object&
object);
372 uint16_t FetchImportedModuleName(std::string name);
373 uint16_t FetchImportedProcedureName(std::string name);
376 uint8_t CountBundles(
size_t entry_index);
378 using LinkerManager::SetLinkScript;
379 void SetOptions(std::map<std::string, std::string>& options)
override;
380 void OnNewSegment(std::shared_ptr<Linker::Segment> segment)
override;