1 //===-- ObjectFilePECOFF.h --------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_ObjectFilePECOFF_h_ 11 #define liblldb_ObjectFilePECOFF_h_ 12 13 #include <vector> 14 15 #include "lldb/Symbol/ObjectFile.h" 16 #include "llvm/Object/Binary.h" 17 18 class ObjectFilePECOFF : public lldb_private::ObjectFile { 19 public: 20 typedef enum MachineType { 21 MachineUnknown = 0x0, 22 MachineAm33 = 0x1d3, 23 MachineAmd64 = 0x8664, 24 MachineArm = 0x1c0, 25 MachineArmNt = 0x1c4, 26 MachineArm64 = 0xaa64, 27 MachineEbc = 0xebc, 28 MachineX86 = 0x14c, 29 MachineIA64 = 0x200, 30 MachineM32R = 0x9041, 31 MachineMips16 = 0x266, 32 MachineMipsFpu = 0x366, 33 MachineMipsFpu16 = 0x466, 34 MachinePowerPc = 0x1f0, 35 MachinePowerPcfp = 0x1f1, 36 MachineR4000 = 0x166, 37 MachineSh3 = 0x1a2, 38 MachineSh3dsp = 0x1a3, 39 MachineSh4 = 0x1a6, 40 MachineSh5 = 0x1a8, 41 MachineThumb = 0x1c2, 42 MachineWcemIpsv2 = 0x169 43 } MachineType; 44 45 ObjectFilePECOFF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 46 lldb::offset_t data_offset, 47 const lldb_private::FileSpec *file, 48 lldb::offset_t file_offset, lldb::offset_t length); 49 50 ObjectFilePECOFF(const lldb::ModuleSP &module_sp, 51 lldb::DataBufferSP &header_data_sp, 52 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 53 54 ~ObjectFilePECOFF() override; 55 56 //------------------------------------------------------------------ 57 // Static Functions 58 //------------------------------------------------------------------ 59 static void Initialize(); 60 61 static void Terminate(); 62 63 static lldb_private::ConstString GetPluginNameStatic(); 64 65 static const char *GetPluginDescriptionStatic(); 66 67 static ObjectFile * 68 CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 69 lldb::offset_t data_offset, const lldb_private::FileSpec *file, 70 lldb::offset_t offset, lldb::offset_t length); 71 72 static lldb_private::ObjectFile *CreateMemoryInstance( 73 const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, 74 const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); 75 76 static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, 77 lldb::DataBufferSP &data_sp, 78 lldb::offset_t data_offset, 79 lldb::offset_t file_offset, 80 lldb::offset_t length, 81 lldb_private::ModuleSpecList &specs); 82 83 static bool SaveCore(const lldb::ProcessSP &process_sp, 84 const lldb_private::FileSpec &outfile, 85 lldb_private::Status &error); 86 87 static bool MagicBytesMatch(lldb::DataBufferSP &data_sp); 88 89 static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type); 90 91 bool ParseHeader() override; 92 93 bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, 94 bool value_is_offset) override; 95 96 lldb::ByteOrder GetByteOrder() const override; 97 98 bool IsExecutable() const override; 99 100 uint32_t GetAddressByteSize() const override; 101 102 // virtual lldb_private::AddressClass 103 // GetAddressClass (lldb::addr_t file_addr); 104 105 lldb_private::Symtab *GetSymtab() override; 106 107 bool IsStripped() override; 108 109 void CreateSections(lldb_private::SectionList &unified_section_list) override; 110 111 void Dump(lldb_private::Stream *s) override; 112 113 bool GetArchitecture(lldb_private::ArchSpec &arch) override; 114 115 bool GetUUID(lldb_private::UUID *uuid) override; 116 117 uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; 118 119 virtual lldb_private::Address GetEntryPointAddress() override; 120 121 ObjectFile::Type CalculateType() override; 122 123 ObjectFile::Strata CalculateStrata() override; 124 125 //------------------------------------------------------------------ 126 // PluginInterface protocol 127 //------------------------------------------------------------------ 128 lldb_private::ConstString GetPluginName() override; 129 130 uint32_t GetPluginVersion() override; 131 132 bool IsWindowsSubsystem(); 133 134 lldb_private::DataExtractor ReadImageData(uint32_t offset, size_t size); 135 136 protected: 137 bool NeedsEndianSwap() const; 138 139 typedef struct dos_header { // DOS .EXE header 140 uint16_t e_magic; // Magic number 141 uint16_t e_cblp; // Bytes on last page of file 142 uint16_t e_cp; // Pages in file 143 uint16_t e_crlc; // Relocations 144 uint16_t e_cparhdr; // Size of header in paragraphs 145 uint16_t e_minalloc; // Minimum extra paragraphs needed 146 uint16_t e_maxalloc; // Maximum extra paragraphs needed 147 uint16_t e_ss; // Initial (relative) SS value 148 uint16_t e_sp; // Initial SP value 149 uint16_t e_csum; // Checksum 150 uint16_t e_ip; // Initial IP value 151 uint16_t e_cs; // Initial (relative) CS value 152 uint16_t e_lfarlc; // File address of relocation table 153 uint16_t e_ovno; // Overlay number 154 uint16_t e_res[4]; // Reserved words 155 uint16_t e_oemid; // OEM identifier (for e_oeminfo) 156 uint16_t e_oeminfo; // OEM information; e_oemid specific 157 uint16_t e_res2[10]; // Reserved words 158 uint32_t e_lfanew; // File address of new exe header 159 } dos_header_t; 160 161 typedef struct coff_header { 162 uint16_t machine; 163 uint16_t nsects; 164 uint32_t modtime; 165 uint32_t symoff; 166 uint32_t nsyms; 167 uint16_t hdrsize; 168 uint16_t flags; 169 } coff_header_t; 170 171 typedef struct data_directory { 172 uint32_t vmaddr; 173 uint32_t vmsize; 174 } data_directory_t; 175 176 typedef struct coff_opt_header { 177 uint16_t magic; 178 uint8_t major_linker_version; 179 uint8_t minor_linker_version; 180 uint32_t code_size; 181 uint32_t data_size; 182 uint32_t bss_size; 183 uint32_t entry; 184 uint32_t code_offset; 185 uint32_t data_offset; 186 187 uint64_t image_base; 188 uint32_t sect_alignment; 189 uint32_t file_alignment; 190 uint16_t major_os_system_version; 191 uint16_t minor_os_system_version; 192 uint16_t major_image_version; 193 uint16_t minor_image_version; 194 uint16_t major_subsystem_version; 195 uint16_t minor_subsystem_version; 196 uint32_t reserved1; 197 uint32_t image_size; 198 uint32_t header_size; 199 uint32_t checksum; 200 uint16_t subsystem; 201 uint16_t dll_flags; 202 uint64_t stack_reserve_size; 203 uint64_t stack_commit_size; 204 uint64_t heap_reserve_size; 205 uint64_t heap_commit_size; 206 uint32_t loader_flags; 207 // uint32_t num_data_dir_entries; 208 std::vector<data_directory> 209 data_dirs; // will contain num_data_dir_entries entries 210 } coff_opt_header_t; 211 212 typedef enum coff_data_dir_type { 213 coff_data_dir_export_table = 0, 214 coff_data_dir_import_table = 1, 215 } coff_data_dir_type; 216 217 typedef struct section_header { 218 char name[8]; 219 uint32_t vmsize; // Virtual Size 220 uint32_t vmaddr; // Virtual Addr 221 uint32_t size; // File size 222 uint32_t offset; // File offset 223 uint32_t reloff; // Offset to relocations 224 uint32_t lineoff; // Offset to line table entries 225 uint16_t nreloc; // Number of relocation entries 226 uint16_t nline; // Number of line table entries 227 uint32_t flags; 228 } section_header_t; 229 230 typedef struct coff_symbol { 231 char name[8]; 232 uint32_t value; 233 uint16_t sect; 234 uint16_t type; 235 uint8_t storage; 236 uint8_t naux; 237 } coff_symbol_t; 238 239 typedef struct export_directory_entry { 240 uint32_t characteristics; 241 uint32_t time_date_stamp; 242 uint16_t major_version; 243 uint16_t minor_version; 244 uint32_t name; 245 uint32_t base; 246 uint32_t number_of_functions; 247 uint32_t number_of_names; 248 uint32_t address_of_functions; 249 uint32_t address_of_names; 250 uint32_t address_of_name_ordinals; 251 } export_directory_entry; 252 253 static bool ParseDOSHeader(lldb_private::DataExtractor &data, 254 dos_header_t &dos_header); 255 static bool ParseCOFFHeader(lldb_private::DataExtractor &data, 256 lldb::offset_t *offset_ptr, 257 coff_header_t &coff_header); 258 bool ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr); 259 bool ParseSectionHeaders(uint32_t offset); 260 261 uint32_t ParseDependentModules(); 262 263 static void DumpDOSHeader(lldb_private::Stream *s, 264 const dos_header_t &header); 265 static void DumpCOFFHeader(lldb_private::Stream *s, 266 const coff_header_t &header); 267 static void DumpOptCOFFHeader(lldb_private::Stream *s, 268 const coff_opt_header_t &header); 269 void DumpSectionHeaders(lldb_private::Stream *s); 270 void DumpSectionHeader(lldb_private::Stream *s, const section_header_t &sh); 271 void DumpDependentModules(lldb_private::Stream *s); 272 273 bool GetSectionName(std::string §_name, const section_header_t §); 274 275 typedef std::vector<section_header_t> SectionHeaderColl; 276 typedef SectionHeaderColl::iterator SectionHeaderCollIter; 277 typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter; 278 279 private: 280 bool CreateBinary(); 281 282 private: 283 dos_header_t m_dos_header; 284 coff_header_t m_coff_header; 285 coff_opt_header_t m_coff_header_opt; 286 SectionHeaderColl m_sect_headers; 287 lldb::addr_t m_image_base; 288 lldb_private::Address m_entry_point_address; 289 llvm::Optional<lldb_private::FileSpecList> m_deps_filespec; 290 typedef llvm::object::OwningBinary<llvm::object::Binary> OWNBINType; 291 llvm::Optional<OWNBINType> m_owningbin; 292 }; 293 294 #endif // liblldb_ObjectFilePECOFF_h_ 295