Skip to content

Commit ec86064

Browse files
committed
[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).
1 parent 5c19427 commit ec86064

File tree

1 file changed

+50
-13
lines changed

1 file changed

+50
-13
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,25 @@ template <> struct MachOTraits<8> {
5252
using Section = const struct llvm::MachO::section_64;
5353
static constexpr size_t MagicNumber = llvm::MachO::MH_MAGIC_64;
5454
};
55+
56+
template <unsigned char ELFClass> struct ELFTraits;
57+
58+
template <> struct ELFTraits<llvm::ELF::ELFCLASS32> {
59+
using Header = const struct llvm::ELF::Elf32_Ehdr;
60+
using Section = const struct llvm::ELF::Elf32_Shdr;
61+
using Offset = llvm::ELF::Elf32_Off;
62+
using Size = llvm::ELF::Elf32_Word;
63+
static constexpr unsigned char ELFClass = llvm::ELF::ELFCLASS32;
64+
};
65+
66+
template <> struct ELFTraits<llvm::ELF::ELFCLASS64> {
67+
using Header = const struct llvm::ELF::Elf64_Ehdr;
68+
using Section = const struct llvm::ELF::Elf64_Shdr;
69+
using Offset = llvm::ELF::Elf64_Off;
70+
using Size = llvm::ELF::Elf64_Xword;
71+
static constexpr unsigned char ELFClass = llvm::ELF::ELFCLASS64;
72+
};
73+
5574
} // namespace
5675

5776
namespace swift {
@@ -266,15 +285,12 @@ class ReflectionContext
266285
return false;
267286
}
268287
#else // ELF platforms.
269-
bool addImage(RemoteAddress ImageStart) {
288+
template <typename T> bool readELFSections(RemoteAddress ImageStart) {
270289
auto Buf =
271-
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
272-
273-
// Read the header.
274-
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
290+
this->getReader().readBytes(ImageStart, sizeof(typename T::Header));
275291

276-
if (!Hdr->checkMagic())
277-
return false;
292+
auto Hdr = reinterpret_cast<const typename T::Header *>(Buf.get());
293+
assert(Hdr->getFileClass() == T::ELFClass && "invalid ELF file class");
278294

279295
// From the header, grab informations about the section header table.
280296
auto SectionHdrAddress = ImageStart.getAddressData() + Hdr->e_shoff;
@@ -283,13 +299,13 @@ class ReflectionContext
283299

284300
// Collect all the section headers, we need them to look up the
285301
// reflection sections (by name) and the string table.
286-
std::vector<const llvm::ELF::Elf64_Shdr *> SecHdrVec;
302+
std::vector<const typename T::Section *> SecHdrVec;
287303
for (unsigned I = 0; I < SectionHdrNumEntries; ++I) {
288304
auto SecBuf = this->getReader().readBytes(
289305
RemoteAddress(SectionHdrAddress + (I * SectionEntrySize)),
290306
SectionEntrySize);
291307
auto SecHdr =
292-
reinterpret_cast<const llvm::ELF::Elf64_Shdr *>(SecBuf.get());
308+
reinterpret_cast<const typename T::Section *>(SecBuf.get());
293309
SecHdrVec.push_back(SecHdr);
294310
}
295311

@@ -304,9 +320,9 @@ class ReflectionContext
304320

305321
assert(SecIdx < SecHdrVec.size() && "malformed ELF object");
306322

307-
const llvm::ELF::Elf64_Shdr *SecHdrStrTab = SecHdrVec[SecIdx];
308-
llvm::ELF::Elf64_Off StrTabOffset = SecHdrStrTab->sh_offset;
309-
llvm::ELF::Elf64_Xword StrTabSize = SecHdrStrTab->sh_size;
323+
const typename T::Section *SecHdrStrTab = SecHdrVec[SecIdx];
324+
typename T::Offset StrTabOffset = SecHdrStrTab->sh_offset;
325+
typename T::Size StrTabSize = SecHdrStrTab->sh_size;
310326

311327
auto StrTabStart =
312328
RemoteAddress(ImageStart.getAddressData() + StrTabOffset);
@@ -316,7 +332,7 @@ class ReflectionContext
316332
auto findELFSectionByName = [&](std::string Name)
317333
-> std::pair<std::pair<const char *, const char *>, uint32_t> {
318334
// Now for all the sections, find their name.
319-
for (const llvm::ELF::Elf64_Shdr *Hdr : SecHdrVec) {
335+
for (const typename T::Section *Hdr : SecHdrVec) {
320336
uint32_t Offset = Hdr->sh_name;
321337
auto SecName = std::string(StrTab + Offset);
322338
if (SecName != Name)
@@ -371,6 +387,27 @@ class ReflectionContext
371387
savedBuffers.push_back(std::move(Buf));
372388
return true;
373389
}
390+
391+
bool addImage(RemoteAddress ImageStart) {
392+
auto Buf =
393+
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
394+
395+
// Read the header.
396+
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
397+
398+
if (!Hdr->checkMagic())
399+
return false;
400+
401+
// Check if we have a ELFCLASS32 or ELFCLASS64
402+
unsigned char FileClass = Hdr->getFileClass();
403+
if (FileClass == llvm::ELF::ELFCLASS64) {
404+
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS64>>(ImageStart);
405+
} else if (FileClass == llvm::ELF::ELFCLASS32) {
406+
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS32>>(ImageStart);
407+
} else {
408+
return false;
409+
}
410+
}
374411
#endif
375412

376413
void addReflectionInfo(ReflectionInfo I) {

0 commit comments

Comments
 (0)