mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[swift-reflection-dump] Support for ELF32.
Split the addImage method for ELF into two branches for ELF32 and for ELF64 depending on the value stored in the identifier of the image. Most of the code of the previous function moves into readELFSections, which is build similar to the already existing readMachOSections. The code is only modified to use the types from the template parameter. This fixes a couple of reflection tests in Android armv7 (and I suppose it should also fix the same problem in other 32 bits platforms which use ELF).
This commit is contained in:
@@ -52,6 +52,25 @@ template <> struct MachOTraits<8> {
|
|||||||
using Section = const struct llvm::MachO::section_64;
|
using Section = const struct llvm::MachO::section_64;
|
||||||
static constexpr size_t MagicNumber = llvm::MachO::MH_MAGIC_64;
|
static constexpr size_t MagicNumber = llvm::MachO::MH_MAGIC_64;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <unsigned char ELFClass> struct ELFTraits;
|
||||||
|
|
||||||
|
template <> struct ELFTraits<llvm::ELF::ELFCLASS32> {
|
||||||
|
using Header = const struct llvm::ELF::Elf32_Ehdr;
|
||||||
|
using Section = const struct llvm::ELF::Elf32_Shdr;
|
||||||
|
using Offset = llvm::ELF::Elf32_Off;
|
||||||
|
using Size = llvm::ELF::Elf32_Word;
|
||||||
|
static constexpr unsigned char ELFClass = llvm::ELF::ELFCLASS32;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct ELFTraits<llvm::ELF::ELFCLASS64> {
|
||||||
|
using Header = const struct llvm::ELF::Elf64_Ehdr;
|
||||||
|
using Section = const struct llvm::ELF::Elf64_Shdr;
|
||||||
|
using Offset = llvm::ELF::Elf64_Off;
|
||||||
|
using Size = llvm::ELF::Elf64_Xword;
|
||||||
|
static constexpr unsigned char ELFClass = llvm::ELF::ELFCLASS64;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
@@ -266,15 +285,12 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#else // ELF platforms.
|
#else // ELF platforms.
|
||||||
bool addImage(RemoteAddress ImageStart) {
|
template <typename T> bool readELFSections(RemoteAddress ImageStart) {
|
||||||
auto Buf =
|
auto Buf =
|
||||||
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
|
this->getReader().readBytes(ImageStart, sizeof(typename T::Header));
|
||||||
|
|
||||||
// Read the header.
|
auto Hdr = reinterpret_cast<const typename T::Header *>(Buf.get());
|
||||||
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
|
assert(Hdr->getFileClass() == T::ELFClass && "invalid ELF file class");
|
||||||
|
|
||||||
if (!Hdr->checkMagic())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// From the header, grab informations about the section header table.
|
// From the header, grab informations about the section header table.
|
||||||
auto SectionHdrAddress = ImageStart.getAddressData() + Hdr->e_shoff;
|
auto SectionHdrAddress = ImageStart.getAddressData() + Hdr->e_shoff;
|
||||||
@@ -283,13 +299,13 @@ public:
|
|||||||
|
|
||||||
// Collect all the section headers, we need them to look up the
|
// Collect all the section headers, we need them to look up the
|
||||||
// reflection sections (by name) and the string table.
|
// reflection sections (by name) and the string table.
|
||||||
std::vector<const llvm::ELF::Elf64_Shdr *> SecHdrVec;
|
std::vector<const typename T::Section *> SecHdrVec;
|
||||||
for (unsigned I = 0; I < SectionHdrNumEntries; ++I) {
|
for (unsigned I = 0; I < SectionHdrNumEntries; ++I) {
|
||||||
auto SecBuf = this->getReader().readBytes(
|
auto SecBuf = this->getReader().readBytes(
|
||||||
RemoteAddress(SectionHdrAddress + (I * SectionEntrySize)),
|
RemoteAddress(SectionHdrAddress + (I * SectionEntrySize)),
|
||||||
SectionEntrySize);
|
SectionEntrySize);
|
||||||
auto SecHdr =
|
auto SecHdr =
|
||||||
reinterpret_cast<const llvm::ELF::Elf64_Shdr *>(SecBuf.get());
|
reinterpret_cast<const typename T::Section *>(SecBuf.get());
|
||||||
SecHdrVec.push_back(SecHdr);
|
SecHdrVec.push_back(SecHdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,9 +320,9 @@ public:
|
|||||||
|
|
||||||
assert(SecIdx < SecHdrVec.size() && "malformed ELF object");
|
assert(SecIdx < SecHdrVec.size() && "malformed ELF object");
|
||||||
|
|
||||||
const llvm::ELF::Elf64_Shdr *SecHdrStrTab = SecHdrVec[SecIdx];
|
const typename T::Section *SecHdrStrTab = SecHdrVec[SecIdx];
|
||||||
llvm::ELF::Elf64_Off StrTabOffset = SecHdrStrTab->sh_offset;
|
typename T::Offset StrTabOffset = SecHdrStrTab->sh_offset;
|
||||||
llvm::ELF::Elf64_Xword StrTabSize = SecHdrStrTab->sh_size;
|
typename T::Size StrTabSize = SecHdrStrTab->sh_size;
|
||||||
|
|
||||||
auto StrTabStart =
|
auto StrTabStart =
|
||||||
RemoteAddress(ImageStart.getAddressData() + StrTabOffset);
|
RemoteAddress(ImageStart.getAddressData() + StrTabOffset);
|
||||||
@@ -316,7 +332,7 @@ public:
|
|||||||
auto findELFSectionByName = [&](std::string Name)
|
auto findELFSectionByName = [&](std::string Name)
|
||||||
-> std::pair<std::pair<const char *, const char *>, uint32_t> {
|
-> std::pair<std::pair<const char *, const char *>, uint32_t> {
|
||||||
// Now for all the sections, find their name.
|
// Now for all the sections, find their name.
|
||||||
for (const llvm::ELF::Elf64_Shdr *Hdr : SecHdrVec) {
|
for (const typename T::Section *Hdr : SecHdrVec) {
|
||||||
uint32_t Offset = Hdr->sh_name;
|
uint32_t Offset = Hdr->sh_name;
|
||||||
auto SecName = std::string(StrTab + Offset);
|
auto SecName = std::string(StrTab + Offset);
|
||||||
if (SecName != Name)
|
if (SecName != Name)
|
||||||
@@ -371,6 +387,27 @@ public:
|
|||||||
savedBuffers.push_back(std::move(Buf));
|
savedBuffers.push_back(std::move(Buf));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool addImage(RemoteAddress ImageStart) {
|
||||||
|
auto Buf =
|
||||||
|
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
|
||||||
|
|
||||||
|
// Read the header.
|
||||||
|
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
|
||||||
|
|
||||||
|
if (!Hdr->checkMagic())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check if we have a ELFCLASS32 or ELFCLASS64
|
||||||
|
unsigned char FileClass = Hdr->getFileClass();
|
||||||
|
if (FileClass == llvm::ELF::ELFCLASS64) {
|
||||||
|
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS64>>(ImageStart);
|
||||||
|
} else if (FileClass == llvm::ELF::ELFCLASS32) {
|
||||||
|
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS32>>(ImageStart);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void addReflectionInfo(ReflectionInfo I) {
|
void addReflectionInfo(ReflectionInfo I) {
|
||||||
|
|||||||
Reference in New Issue
Block a user