Skip to content

[Object][COFF][llvm-readobj] Add support for ARM64X dynamic relocations. #97229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions llvm/include/llvm/BinaryFormat/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,21 @@ enum RelocationTypesARM64 : unsigned {
IMAGE_REL_ARM64_REL32 = 0x0011,
};

enum DynamicRelocationType : unsigned {
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE = 1,
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE = 2,
IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER = 3,
IMAGE_DYNAMIC_RELOCATION_GUARD_INDIR_CONTROL_TRANSFER = 4,
IMAGE_DYNAMIC_RELOCATION_GUARD_SWITCHTABLE_BRANCH = 5,
IMAGE_DYNAMIC_RELOCATION_ARM64X = 6,
};

enum Arm64XFixupType : uint8_t {
IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL = 0,
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE = 1,
IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA = 2,
};

enum COMDATType : uint8_t {
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
IMAGE_COMDAT_SELECT_ANY,
Expand Down
99 changes: 99 additions & 0 deletions llvm/include/llvm/Object/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ template <typename T> class ArrayRef;

namespace object {

class Arm64XRelocRef;
class BaseRelocRef;
class DelayImportDirectoryEntryRef;
class DynamicRelocRef;
class ExportDirectoryEntryRef;
class ImportDirectoryEntryRef;
class ImportedSymbolRef;
Expand All @@ -48,6 +50,8 @@ using delay_import_directory_iterator =
using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
using base_reloc_iterator = content_iterator<BaseRelocRef>;
using dynamic_reloc_iterator = content_iterator<DynamicRelocRef>;
using arm64x_reloc_iterator = content_iterator<Arm64XRelocRef>;

/// The DOS compatible header at the front of all PE/COFF executables.
struct dos_header {
Expand Down Expand Up @@ -832,6 +836,37 @@ struct debug_h_header {
support::ulittle16_t HashAlgorithm;
};

struct coff_dynamic_reloc_table {
support::ulittle32_t Version;
support::ulittle32_t Size;
};

struct coff_dynamic_relocation32 {
support::ulittle32_t Symbol;
support::ulittle32_t BaseRelocSize;
};

struct coff_dynamic_relocation64 {
support::ulittle64_t Symbol;
support::ulittle32_t BaseRelocSize;
};

struct coff_dynamic_relocation32_v2 {
support::ulittle32_t HeaderSize;
support::ulittle32_t FixupInfoSize;
support::ulittle32_t Symbol;
support::ulittle32_t SymbolGroup;
support::ulittle32_t Flags;
};

struct coff_dynamic_relocation64_v2 {
support::ulittle32_t HeaderSize;
support::ulittle32_t FixupInfoSize;
support::ulittle64_t Symbol;
support::ulittle32_t SymbolGroup;
support::ulittle32_t Flags;
};

class COFFObjectFile : public ObjectFile {
private:
COFFObjectFile(MemoryBufferRef Object);
Expand Down Expand Up @@ -861,6 +896,7 @@ class COFFObjectFile : public ObjectFile {
// Either coff_load_configuration32 or coff_load_configuration64.
const void *LoadConfig = nullptr;
const chpe_metadata *CHPEMetadata = nullptr;
const coff_dynamic_reloc_table *DynamicRelocTable = nullptr;

Expected<StringRef> getString(uint32_t offset) const;

Expand All @@ -880,6 +916,7 @@ class COFFObjectFile : public ObjectFile {
Error initDebugDirectoryPtr();
Error initTLSDirectoryPtr();
Error initLoadConfigPtr();
Error initDynamicRelocPtr(uint32_t SectionIndex, uint32_t SectionOffset);

public:
static Expected<std::unique_ptr<COFFObjectFile>>
Expand Down Expand Up @@ -986,6 +1023,9 @@ class COFFObjectFile : public ObjectFile {
}

const chpe_metadata *getCHPEMetadata() const { return CHPEMetadata; }
const coff_dynamic_reloc_table *getDynamicRelocTable() const {
return DynamicRelocTable;
}

StringRef getRelocationTypeName(uint16_t Type) const;

Expand Down Expand Up @@ -1054,6 +1094,8 @@ class COFFObjectFile : public ObjectFile {
export_directory_iterator export_directory_end() const;
base_reloc_iterator base_reloc_begin() const;
base_reloc_iterator base_reloc_end() const;
dynamic_reloc_iterator dynamic_reloc_begin() const;
dynamic_reloc_iterator dynamic_reloc_end() const;
const debug_directory *debug_directory_begin() const {
return DebugDirectoryBegin;
}
Expand All @@ -1066,6 +1108,7 @@ class COFFObjectFile : public ObjectFile {
delay_import_directories() const;
iterator_range<export_directory_iterator> export_directories() const;
iterator_range<base_reloc_iterator> base_relocs() const;
iterator_range<dynamic_reloc_iterator> dynamic_relocs() const;
iterator_range<const debug_directory *> debug_directories() const {
return make_range(debug_directory_begin(), debug_directory_end());
}
Expand Down Expand Up @@ -1295,6 +1338,62 @@ class BaseRelocRef {
uint32_t Index;
};

class DynamicRelocRef {
public:
DynamicRelocRef() = default;
DynamicRelocRef(const void *Header, const COFFObjectFile *Owner)
: Obj(Owner), Header(reinterpret_cast<const uint8_t *>(Header)) {}

bool operator==(const DynamicRelocRef &Other) const;
void moveNext();
uint32_t getType() const;
void getContents(ArrayRef<uint8_t> &Ref) const;

arm64x_reloc_iterator arm64x_reloc_begin() const;
arm64x_reloc_iterator arm64x_reloc_end() const;
iterator_range<arm64x_reloc_iterator> arm64x_relocs() const;

private:
Error validate() const;

const COFFObjectFile *Obj;
const uint8_t *Header;

friend class COFFObjectFile;
};

class Arm64XRelocRef {
public:
Arm64XRelocRef() = default;
Arm64XRelocRef(const coff_base_reloc_block_header *Header, uint32_t Index = 0)
: Header(Header), Index(Index) {}

bool operator==(const Arm64XRelocRef &Other) const;
void moveNext();

COFF::Arm64XFixupType getType() const {
return COFF::Arm64XFixupType((getReloc() >> 12) & 3);
}
uint32_t getRVA() const { return Header->PageRVA + (getReloc() & 0xfff); }
uint8_t getSize() const;
uint64_t getValue() const;

private:
const support::ulittle16_t &getReloc(uint32_t Offset = 0) const {
return reinterpret_cast<const support::ulittle16_t *>(Header +
1)[Index + Offset];
}

uint16_t getArg() const { return getReloc() >> 14; }
uint8_t getEntrySize() const;
Error validate(const COFFObjectFile *Obj) const;

const coff_base_reloc_block_header *Header;
uint32_t Index;

friend class DynamicRelocRef;
};

class ResourceSectionRef {
public:
ResourceSectionRef() = default;
Expand Down
Loading
Loading