Skip to content

Commit 94d5398

Browse files
authored
[Object][COFF][llvm-readobj] Add support for ARM64X dynamic relocations. (#97229)
1 parent 0371dff commit 94d5398

File tree

7 files changed

+2443
-4
lines changed

7 files changed

+2443
-4
lines changed

llvm/include/llvm/BinaryFormat/COFF.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,21 @@ enum RelocationTypesARM64 : unsigned {
417417
IMAGE_REL_ARM64_REL32 = 0x0011,
418418
};
419419

420+
enum DynamicRelocationType : unsigned {
421+
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE = 1,
422+
IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE = 2,
423+
IMAGE_DYNAMIC_RELOCATION_GUARD_IMPORT_CONTROL_TRANSFER = 3,
424+
IMAGE_DYNAMIC_RELOCATION_GUARD_INDIR_CONTROL_TRANSFER = 4,
425+
IMAGE_DYNAMIC_RELOCATION_GUARD_SWITCHTABLE_BRANCH = 5,
426+
IMAGE_DYNAMIC_RELOCATION_ARM64X = 6,
427+
};
428+
429+
enum Arm64XFixupType : uint8_t {
430+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL = 0,
431+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE = 1,
432+
IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA = 2,
433+
};
434+
420435
enum COMDATType : uint8_t {
421436
IMAGE_COMDAT_SELECT_NODUPLICATES = 1,
422437
IMAGE_COMDAT_SELECT_ANY,

llvm/include/llvm/Object/COFF.h

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ template <typename T> class ArrayRef;
3535

3636
namespace object {
3737

38+
class Arm64XRelocRef;
3839
class BaseRelocRef;
3940
class DelayImportDirectoryEntryRef;
41+
class DynamicRelocRef;
4042
class ExportDirectoryEntryRef;
4143
class ImportDirectoryEntryRef;
4244
class ImportedSymbolRef;
@@ -48,6 +50,8 @@ using delay_import_directory_iterator =
4850
using export_directory_iterator = content_iterator<ExportDirectoryEntryRef>;
4951
using imported_symbol_iterator = content_iterator<ImportedSymbolRef>;
5052
using base_reloc_iterator = content_iterator<BaseRelocRef>;
53+
using dynamic_reloc_iterator = content_iterator<DynamicRelocRef>;
54+
using arm64x_reloc_iterator = content_iterator<Arm64XRelocRef>;
5155

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

839+
struct coff_dynamic_reloc_table {
840+
support::ulittle32_t Version;
841+
support::ulittle32_t Size;
842+
};
843+
844+
struct coff_dynamic_relocation32 {
845+
support::ulittle32_t Symbol;
846+
support::ulittle32_t BaseRelocSize;
847+
};
848+
849+
struct coff_dynamic_relocation64 {
850+
support::ulittle64_t Symbol;
851+
support::ulittle32_t BaseRelocSize;
852+
};
853+
854+
struct coff_dynamic_relocation32_v2 {
855+
support::ulittle32_t HeaderSize;
856+
support::ulittle32_t FixupInfoSize;
857+
support::ulittle32_t Symbol;
858+
support::ulittle32_t SymbolGroup;
859+
support::ulittle32_t Flags;
860+
};
861+
862+
struct coff_dynamic_relocation64_v2 {
863+
support::ulittle32_t HeaderSize;
864+
support::ulittle32_t FixupInfoSize;
865+
support::ulittle64_t Symbol;
866+
support::ulittle32_t SymbolGroup;
867+
support::ulittle32_t Flags;
868+
};
869+
835870
class COFFObjectFile : public ObjectFile {
836871
private:
837872
COFFObjectFile(MemoryBufferRef Object);
@@ -861,6 +896,7 @@ class COFFObjectFile : public ObjectFile {
861896
// Either coff_load_configuration32 or coff_load_configuration64.
862897
const void *LoadConfig = nullptr;
863898
const chpe_metadata *CHPEMetadata = nullptr;
899+
const coff_dynamic_reloc_table *DynamicRelocTable = nullptr;
864900

865901
Expected<StringRef> getString(uint32_t offset) const;
866902

@@ -880,6 +916,7 @@ class COFFObjectFile : public ObjectFile {
880916
Error initDebugDirectoryPtr();
881917
Error initTLSDirectoryPtr();
882918
Error initLoadConfigPtr();
919+
Error initDynamicRelocPtr(uint32_t SectionIndex, uint32_t SectionOffset);
883920

884921
public:
885922
static Expected<std::unique_ptr<COFFObjectFile>>
@@ -986,6 +1023,9 @@ class COFFObjectFile : public ObjectFile {
9861023
}
9871024

9881025
const chpe_metadata *getCHPEMetadata() const { return CHPEMetadata; }
1026+
const coff_dynamic_reloc_table *getDynamicRelocTable() const {
1027+
return DynamicRelocTable;
1028+
}
9891029

9901030
StringRef getRelocationTypeName(uint16_t Type) const;
9911031

@@ -1054,6 +1094,8 @@ class COFFObjectFile : public ObjectFile {
10541094
export_directory_iterator export_directory_end() const;
10551095
base_reloc_iterator base_reloc_begin() const;
10561096
base_reloc_iterator base_reloc_end() const;
1097+
dynamic_reloc_iterator dynamic_reloc_begin() const;
1098+
dynamic_reloc_iterator dynamic_reloc_end() const;
10571099
const debug_directory *debug_directory_begin() const {
10581100
return DebugDirectoryBegin;
10591101
}
@@ -1066,6 +1108,7 @@ class COFFObjectFile : public ObjectFile {
10661108
delay_import_directories() const;
10671109
iterator_range<export_directory_iterator> export_directories() const;
10681110
iterator_range<base_reloc_iterator> base_relocs() const;
1111+
iterator_range<dynamic_reloc_iterator> dynamic_relocs() const;
10691112
iterator_range<const debug_directory *> debug_directories() const {
10701113
return make_range(debug_directory_begin(), debug_directory_end());
10711114
}
@@ -1295,6 +1338,62 @@ class BaseRelocRef {
12951338
uint32_t Index;
12961339
};
12971340

1341+
class DynamicRelocRef {
1342+
public:
1343+
DynamicRelocRef() = default;
1344+
DynamicRelocRef(const void *Header, const COFFObjectFile *Owner)
1345+
: Obj(Owner), Header(reinterpret_cast<const uint8_t *>(Header)) {}
1346+
1347+
bool operator==(const DynamicRelocRef &Other) const;
1348+
void moveNext();
1349+
uint32_t getType() const;
1350+
void getContents(ArrayRef<uint8_t> &Ref) const;
1351+
1352+
arm64x_reloc_iterator arm64x_reloc_begin() const;
1353+
arm64x_reloc_iterator arm64x_reloc_end() const;
1354+
iterator_range<arm64x_reloc_iterator> arm64x_relocs() const;
1355+
1356+
private:
1357+
Error validate() const;
1358+
1359+
const COFFObjectFile *Obj;
1360+
const uint8_t *Header;
1361+
1362+
friend class COFFObjectFile;
1363+
};
1364+
1365+
class Arm64XRelocRef {
1366+
public:
1367+
Arm64XRelocRef() = default;
1368+
Arm64XRelocRef(const coff_base_reloc_block_header *Header, uint32_t Index = 0)
1369+
: Header(Header), Index(Index) {}
1370+
1371+
bool operator==(const Arm64XRelocRef &Other) const;
1372+
void moveNext();
1373+
1374+
COFF::Arm64XFixupType getType() const {
1375+
return COFF::Arm64XFixupType((getReloc() >> 12) & 3);
1376+
}
1377+
uint32_t getRVA() const { return Header->PageRVA + (getReloc() & 0xfff); }
1378+
uint8_t getSize() const;
1379+
uint64_t getValue() const;
1380+
1381+
private:
1382+
const support::ulittle16_t &getReloc(uint32_t Offset = 0) const {
1383+
return reinterpret_cast<const support::ulittle16_t *>(Header +
1384+
1)[Index + Offset];
1385+
}
1386+
1387+
uint16_t getArg() const { return getReloc() >> 14; }
1388+
uint8_t getEntrySize() const;
1389+
Error validate(const COFFObjectFile *Obj) const;
1390+
1391+
const coff_base_reloc_block_header *Header;
1392+
uint32_t Index;
1393+
1394+
friend class DynamicRelocRef;
1395+
};
1396+
12981397
class ResourceSectionRef {
12991398
public:
13001399
ResourceSectionRef() = default;

0 commit comments

Comments
 (0)