summaryrefslogtreecommitdiff
path: root/include/llvm/Object/COFF.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Object/COFF.h')
-rw-r--r--include/llvm/Object/COFF.h142
1 files changed, 134 insertions, 8 deletions
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
index 3e69c3e6e5d4f..dcc58b06e228d 100644
--- a/include/llvm/Object/COFF.h
+++ b/include/llvm/Object/COFF.h
@@ -169,6 +169,26 @@ struct import_directory_table_entry {
support::ulittle32_t ImportAddressTableRVA;
};
+struct debug_directory {
+ support::ulittle32_t Characteristics;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle16_t MajorVersion;
+ support::ulittle16_t MinorVersion;
+ support::ulittle32_t Type;
+ support::ulittle32_t SizeOfData;
+ support::ulittle32_t AddressOfRawData;
+ support::ulittle32_t PointerToRawData;
+};
+
+/// Information that is resent in debug_directory::AddressOfRawData if Type is
+/// IMAGE_DEBUG_TYPE_CODEVIEW.
+struct debug_pdb_info {
+ support::ulittle32_t Signature;
+ uint8_t Guid[16];
+ support::ulittle32_t Age;
+ // PDBFileName: The null-terminated PDB file name follows.
+};
+
template <typename IntTy>
struct import_lookup_table_entry {
IntTy Data;
@@ -414,6 +434,18 @@ struct coff_section {
return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
NumberOfRelocations == UINT16_MAX;
}
+ uint32_t getAlignment() const {
+ // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
+ // IMAGE_SCN_ALIGN_1BYTES.
+ if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
+ return 1;
+
+ // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1.
+ uint32_t Shift = (Characteristics >> 20) & 0xF;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 1;
+ }
};
struct coff_relocation {
@@ -427,20 +459,32 @@ struct coff_aux_function_definition {
support::ulittle32_t TotalSize;
support::ulittle32_t PointerToLinenumber;
support::ulittle32_t PointerToNextFunction;
+ char Unused1[2];
};
+static_assert(sizeof(coff_aux_function_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_bf_and_ef_symbol {
char Unused1[4];
support::ulittle16_t Linenumber;
char Unused2[6];
support::ulittle32_t PointerToNextFunction;
+ char Unused3[2];
};
+static_assert(sizeof(coff_aux_bf_and_ef_symbol) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_weak_external {
support::ulittle32_t TagIndex;
support::ulittle32_t Characteristics;
+ char Unused1[10];
};
+static_assert(sizeof(coff_aux_weak_external) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_section_definition {
support::ulittle32_t Length;
support::ulittle16_t NumberOfRelocations;
@@ -458,12 +502,19 @@ struct coff_aux_section_definition {
}
};
+static_assert(sizeof(coff_aux_section_definition) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_aux_clr_token {
uint8_t AuxType;
uint8_t Reserved;
support::ulittle32_t SymbolTableIndex;
+ char MBZ[12];
};
+static_assert(sizeof(coff_aux_clr_token) == 18,
+ "auxiliary entry must be 18 bytes");
+
struct coff_import_header {
support::ulittle16_t Sig1;
support::ulittle16_t Sig2;
@@ -485,6 +536,26 @@ struct coff_import_directory_table_entry {
support::ulittle32_t ImportAddressTableRVA;
};
+template <typename IntTy>
+struct coff_tls_directory {
+ IntTy StartAddressOfRawData;
+ IntTy EndAddressOfRawData;
+ IntTy AddressOfIndex;
+ IntTy AddressOfCallBacks;
+ support::ulittle32_t SizeOfZeroFill;
+ support::ulittle32_t Characteristics;
+ uint32_t getAlignment() const {
+ // Bit [20:24] contains section alignment.
+ uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
+ if (Shift > 0)
+ return 1U << (Shift - 1);
+ return 0;
+ }
+};
+
+typedef coff_tls_directory<support::little32_t> coff_tls_directory32;
+typedef coff_tls_directory<support::little64_t> coff_tls_directory64;
+
struct coff_load_configuration32 {
support::ulittle32_t Characteristics;
support::ulittle32_t TimeDateStamp;
@@ -563,12 +634,13 @@ private:
const char *StringTable;
uint32_t StringTableSize;
const import_directory_table_entry *ImportDirectory;
- uint32_t NumberOfImportDirectory;
const delay_import_directory_table_entry *DelayImportDirectory;
uint32_t NumberOfDelayImportDirectory;
const export_directory_table_entry *ExportDirectory;
const coff_base_reloc_block_header *BaseRelocHeader;
const coff_base_reloc_block_header *BaseRelocEnd;
+ const debug_directory *DebugDirectoryBegin;
+ const debug_directory *DebugDirectoryEnd;
std::error_code getString(uint32_t offset, StringRef &Res) const;
@@ -582,6 +654,7 @@ private:
std::error_code initDelayImportTablePtr();
std::error_code initExportTablePtr();
std::error_code initBaseRelocPtr();
+ std::error_code initDebugDirectoryPtr();
public:
uintptr_t getSymbolTable() const {
@@ -647,13 +720,13 @@ public:
}
protected:
void moveSymbolNext(DataRefImpl &Symb) const override;
- ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override;
- ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
+ Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
+ Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
- SymbolRef::Type getSymbolType(DataRefImpl Symb) const override;
- ErrorOr<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
+ Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
std::error_code getSectionName(DataRefImpl Sec,
StringRef &Res) const override;
@@ -662,6 +735,7 @@ protected:
std::error_code getSectionContents(DataRefImpl Sec,
StringRef &Res) const override;
uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+ bool isSectionCompressed(DataRefImpl Sec) const override;
bool isSectionText(DataRefImpl Sec) const override;
bool isSectionData(DataRefImpl Sec) const override;
bool isSectionBSS(DataRefImpl Sec) const override;
@@ -693,6 +767,7 @@ public:
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
unsigned getArch() const override;
+ SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
import_directory_iterator import_directory_begin() const;
import_directory_iterator import_directory_end() const;
@@ -702,12 +777,21 @@ public:
export_directory_iterator export_directory_end() const;
base_reloc_iterator base_reloc_begin() const;
base_reloc_iterator base_reloc_end() const;
+ const debug_directory *debug_directory_begin() const {
+ return DebugDirectoryBegin;
+ }
+ const debug_directory *debug_directory_end() const {
+ return DebugDirectoryEnd;
+ }
iterator_range<import_directory_iterator> import_directories() const;
iterator_range<delay_import_directory_iterator>
delay_import_directories() const;
iterator_range<export_directory_iterator> export_directories() const;
iterator_range<base_reloc_iterator> base_relocs() const;
+ iterator_range<const debug_directory *> debug_directories() const {
+ return make_range(debug_directory_begin(), debug_directory_end());
+ }
const dos_header *getDOSHeader() const {
if (!PE32Header && !PE32PlusHeader)
@@ -776,9 +860,28 @@ public:
uint64_t getImageBase() const;
std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+
+ /// Given an RVA base and size, returns a valid array of bytes or an error
+ /// code if the RVA and size is not contained completely within a valid
+ /// section.
+ std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const;
+
std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
StringRef &Name) const;
+ /// Get PDB information out of a codeview debug directory entry.
+ std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
+ const debug_pdb_info *&Info,
+ StringRef &PDBFileName) const;
+
+ /// Get PDB information from an executable. If the information is not present,
+ /// Info will be set to nullptr and PDBFileName will be empty. An error is
+ /// returned only on corrupt object files. Convenience accessor that can be
+ /// used if the debug directory is not already handy.
+ std::error_code getDebugPDBInfo(const debug_pdb_info *&Info,
+ StringRef &PDBFileName) const;
+
bool isRelocatableObject() const override;
bool is64() const { return PE32PlusHeader; }
@@ -807,9 +910,6 @@ public:
std::error_code
getImportTableEntry(const import_directory_table_entry *&Result) const;
- std::error_code
- getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
-
private:
const import_directory_table_entry *ImportTable;
uint32_t Index;
@@ -881,7 +981,9 @@ public:
void moveNext();
std::error_code getSymbolName(StringRef &Result) const;
+ std::error_code isOrdinal(bool &Result) const;
std::error_code getOrdinal(uint16_t &Result) const;
+ std::error_code getHintNameRVA(uint32_t &Result) const;
private:
const import_lookup_table_entry32 *Entry32;
@@ -909,6 +1011,30 @@ private:
const COFFObjectFile *OwningObject;
};
+// Corresponds to `_FPO_DATA` structure in the PE/COFF spec.
+struct FpoData {
+ support::ulittle32_t Offset; // ulOffStart: Offset 1st byte of function code
+ support::ulittle32_t Size; // cbProcSize: # bytes in function
+ support::ulittle32_t NumLocals; // cdwLocals: # bytes in locals/4
+ support::ulittle16_t NumParams; // cdwParams: # bytes in params/4
+ support::ulittle16_t Attributes;
+
+ // cbProlog: # bytes in prolog
+ int getPrologSize() const { return Attributes & 0xF; }
+
+ // cbRegs: # regs saved
+ int getNumSavedRegs() const { return (Attributes >> 8) & 0x7; }
+
+ // fHasSEH: true if seh is func
+ bool hasSEH() const { return (Attributes >> 9) & 1; }
+
+ // fUseBP: true if EBP has been allocated
+ bool useBP() const { return (Attributes >> 10) & 1; }
+
+ // cbFrame: frame pointer
+ int getFP() const { return Attributes >> 14; }
+};
+
} // end namespace object
} // end namespace llvm