Skip to content

Commit

Permalink
Add support for SHT_RELA in vkgc
Browse files Browse the repository at this point in the history
Currently LLVM generates relocations in an ELF SHT_REL section. To
allow for changing the compiler to use SHT_RELA instead, this patch
updates vkgcElfReader and vkgcPipelineDumper to support both section
types.
  • Loading branch information
jayfoad committed Nov 29, 2023
1 parent bbef90e commit 631d2e2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 13 deletions.
7 changes: 5 additions & 2 deletions tool/dumper/vkgcPipelineDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2065,7 +2065,7 @@ OStream &operator<<(OStream &out, ElfReader<Elf> &reader) {
offset += noteHeaderSize + noteNameSize + alignTo(node->descSize, sizeof(unsigned));
assert(offset <= section->secHead.sh_size);
}
} else if (strcmp(section->name, RelocName) == 0) {
} else if (strcmp(section->name, RelocName) == 0 || strcmp(section->name, RelocAName) == 0) {
// Output .reloc section
out << section->name << " (size = " << section->secHead.sh_size << " bytes)\n";
const unsigned relocCount = reader.getRelocationCount();
Expand All @@ -2075,7 +2075,10 @@ OStream &operator<<(OStream &out, ElfReader<Elf> &reader) {
ElfSymbol elfSym = {};
reader.getSymbol(reloc.symIdx, &elfSym);
snprintf(formatBuf, sizeof(formatBuf), " %-35s", elfSym.pSymName);
out << "#" << i << " " << formatBuf << " offset = " << reloc.offset << "\n";
out << "#" << i << " " << formatBuf << " offset = " << reloc.offset;
if (reloc.useExplicitAddend)
out << ", addend = " << reloc.addend;
out << "\n";
}
} else if (strncmp(section->name, AmdGpuConfigName, sizeof(AmdGpuConfigName) - 1) == 0) {
// Output .AMDGPU.config section
Expand Down
28 changes: 20 additions & 8 deletions util/vkgcElfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ template <class Elf> Result ElfReader<Elf>::ReadFromBuffer(const void *buffer, s
// Get section index
m_symSecIdx = GetSectionIndex(SymTabName);
m_relocSecIdx = GetSectionIndex(RelocName);
if (m_relocSecIdx < 0)
m_relocSecIdx = GetSectionIndex(RelocAName);
m_strtabSecIdx = GetSectionIndex(StrTabName);
m_textSecIdx = GetSectionIndex(TextName);

Expand Down Expand Up @@ -210,14 +212,24 @@ template <class Elf> unsigned ElfReader<Elf>::getRelocationCount() const {
// @param idx : Relocation index
// @param [out] reloc : Info of the relocation
template <class Elf> void ElfReader<Elf>::getRelocation(unsigned idx, ElfReloc *reloc) const {
auto &section = m_sections[m_relocSecIdx];

auto relocs = reinterpret_cast<const typename Elf::Reloc *>(section->data);
reloc->offset = relocs[idx].r_offset;
reloc->symIdx = relocs[idx].r_symbol;
reloc->type = relocs[idx].r_type;
reloc->addend = 0;
reloc->useExplicitAddend = false;
auto *section = m_sections[m_relocSecIdx];

if (section->secHead.sh_type == SHT_REL) {
auto relocs = reinterpret_cast<const typename Elf::Reloc *>(section->data);
reloc->offset = relocs[idx].r_offset;
reloc->symIdx = relocs[idx].r_symbol;
reloc->type = relocs[idx].r_type;
reloc->addend = 0;
reloc->useExplicitAddend = false;
} else {
assert(section->secHead.sh_type == SHT_RELA);
auto relocs = reinterpret_cast<const typename Elf::RelocA *>(section->data);
reloc->offset = relocs[idx].r_offset;
reloc->symIdx = relocs[idx].r_symbol;
reloc->type = relocs[idx].r_type;
reloc->addend = relocs[idx].r_addend;
reloc->useExplicitAddend = true;
}
}

// =====================================================================================================================
Expand Down
35 changes: 32 additions & 3 deletions util/vkgcElfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ enum ElfSectionHeaderTypes : uint32_t {
SHT_HASH = 5, // Symbol hash table
SHT_DYNAMIC = 6, // Information for dynamic linking
SHT_NOTE = 7, // Information about the file
SHT_NOBITS = 8, // Data occupies no space in the file
SHT_REL = 9, // Relocation entries; no explicit addends
};

// Enumerates ELF Section flags.
Expand All @@ -150,7 +152,8 @@ static const char ShStrTabName[] = ".shstrtab"; // Name of ".shstrtab" section
static const char StrTabName[] = ".strtab"; // Name of ".strtab" section
static const char SymTabName[] = ".symtab"; // Name of ".symtab" section
static const char NoteName[] = ".note"; // Name of ".note" section
static const char RelocName[] = ".rel.text"; // Name of ".reloc" section
static const char RelocName[] = ".rel.text"; // Name of SHT_REL section
static const char RelocAName[] = ".rela.text"; // Name of SHT_RELA section
static const char CommentName[] = ".comment"; // Name of ".comment" section

static const uint32_t NT_AMD_AMDGPU_ISA = 11; // Note type of AMDGPU ISA version
Expand Down Expand Up @@ -221,7 +224,7 @@ struct Elf32 {
uint16_t st_shndx; // Which section (header table index) it's defined in
};

// ELF relocation entry (without explicit append)
// ELF relocation entry (without explicit addend)
struct Reloc {
uint32_t r_offset; // Location (file byte offset, or program virtual address)
union {
Expand All @@ -233,6 +236,19 @@ struct Elf32 {
};
};

// ELF relocation entry with explicit addend
struct RelocA {
uint32_t r_offset; // Location (file byte offset, or program virtual address)
union {
uint32_t r_info; // Symbol table index and type of relocation to apply
struct {
uint32_t r_type : 8; // Type of relocation
uint32_t r_symbol : 24; // Index of the symbol in the symbol table
};
};
uint32_t r_addend; // Compute value for relocatable field by adding this
};

// ELF program header
struct Phdr {
uint32_t p_type; // Type of segment
Expand Down Expand Up @@ -301,7 +317,7 @@ struct Elf64 {
uint64_t st_size; // Size of the symbol
};

// ELF relocation entry
// ELF relocation entry (without explicit addend)
struct Reloc {
uint64_t r_offset; // Location (file byte offset, or program virtual address)
union {
Expand All @@ -313,6 +329,19 @@ struct Elf64 {
};
};

// ELF relocation entry with explicit addend
struct RelocA {
uint64_t r_offset; // Location (file byte offset, or program virtual address)
union {
uint64_t r_info; // Symbol table index and type of relocation to apply
struct {
uint32_t r_type; // Type of relocation
uint32_t r_symbol; // Index of the symbol in the symbol table
};
};
uint64_t r_addend; // Compute value for relocatable field by adding this
};

// ELF program header
struct Phdr {
uint32_t p_type; // Type of segment
Expand Down

0 comments on commit 631d2e2

Please sign in to comment.