@@ -52,6 +52,25 @@ template <> struct MachOTraits<8> {
52
52
using Section = const struct llvm ::MachO::section_64;
53
53
static constexpr size_t MagicNumber = llvm::MachO::MH_MAGIC_64;
54
54
};
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
+
55
74
} // namespace
56
75
57
76
namespace swift {
@@ -266,15 +285,12 @@ class ReflectionContext
266
285
return false ;
267
286
}
268
287
#else // ELF platforms.
269
- bool addImage (RemoteAddress ImageStart) {
288
+ template < typename T> bool readELFSections (RemoteAddress ImageStart) {
270
289
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));
275
291
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 " ) ;
278
294
279
295
// From the header, grab informations about the section header table.
280
296
auto SectionHdrAddress = ImageStart.getAddressData () + Hdr->e_shoff ;
@@ -283,13 +299,13 @@ class ReflectionContext
283
299
284
300
// Collect all the section headers, we need them to look up the
285
301
// 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;
287
303
for (unsigned I = 0 ; I < SectionHdrNumEntries; ++I) {
288
304
auto SecBuf = this ->getReader ().readBytes (
289
305
RemoteAddress (SectionHdrAddress + (I * SectionEntrySize)),
290
306
SectionEntrySize);
291
307
auto SecHdr =
292
- reinterpret_cast <const llvm::ELF::Elf64_Shdr *>(SecBuf.get ());
308
+ reinterpret_cast <const typename T::Section *>(SecBuf.get ());
293
309
SecHdrVec.push_back (SecHdr);
294
310
}
295
311
@@ -304,9 +320,9 @@ class ReflectionContext
304
320
305
321
assert (SecIdx < SecHdrVec.size () && " malformed ELF object" );
306
322
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 ;
310
326
311
327
auto StrTabStart =
312
328
RemoteAddress (ImageStart.getAddressData () + StrTabOffset);
@@ -316,7 +332,7 @@ class ReflectionContext
316
332
auto findELFSectionByName = [&](std::string Name)
317
333
-> std::pair<std::pair<const char *, const char *>, uint32_t > {
318
334
// 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) {
320
336
uint32_t Offset = Hdr->sh_name ;
321
337
auto SecName = std::string (StrTab + Offset);
322
338
if (SecName != Name)
@@ -371,6 +387,27 @@ class ReflectionContext
371
387
savedBuffers.push_back (std::move (Buf));
372
388
return true ;
373
389
}
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
+ }
374
411
#endif
375
412
376
413
void addReflectionInfo (ReflectionInfo I) {
0 commit comments