@@ -36,18 +36,10 @@ bool utils::elf::isELF(StringRef Buffer) {
36
36
}
37
37
}
38
38
39
- Expected<bool > utils::elf::checkMachine (StringRef Object, uint16_t EMachine) {
40
- assert (isELF (Object) && " Input is not an ELF!" );
41
-
42
- Expected<ELF64LEObjectFile> ElfOrErr =
43
- ELF64LEObjectFile::create (MemoryBufferRef (Object, /* Identifier=*/ " " ),
44
- /* InitContent=*/ false );
45
- if (!ElfOrErr)
46
- return ElfOrErr.takeError ();
47
-
48
- const auto Header = ElfOrErr->getELFFile ().getHeader ();
49
- if (Header.e_ident [EI_CLASS] != ELFCLASS64)
50
- return createError (" Only 64-bit ELF files are supported" );
39
+ template <class ELFT >
40
+ static Expected<bool >
41
+ checkMachineImpl (const object::ELFObjectFile<ELFT> &ELFObj, uint16_t EMachine) {
42
+ const auto Header = ELFObj.getELFFile ().getHeader ();
51
43
if (Header.e_type != ET_EXEC && Header.e_type != ET_DYN)
52
44
return createError (" Only executable ELF files are supported" );
53
45
@@ -71,6 +63,25 @@ Expected<bool> utils::elf::checkMachine(StringRef Object, uint16_t EMachine) {
71
63
return Header.e_machine == EMachine;
72
64
}
73
65
66
+ Expected<bool > utils::elf::checkMachine (StringRef Object, uint16_t EMachine) {
67
+ assert (isELF (Object) && " Input is not an ELF!" );
68
+
69
+ Expected<std::unique_ptr<ObjectFile>> ElfOrErr =
70
+ ObjectFile::createELFObjectFile (
71
+ MemoryBufferRef (Object, /* Identifier=*/ " " ),
72
+ /* InitContent=*/ false );
73
+ if (!ElfOrErr)
74
+ return ElfOrErr.takeError ();
75
+
76
+ if (const ELF64LEObjectFile *ELFObj =
77
+ dyn_cast<ELF64LEObjectFile>(&**ElfOrErr))
78
+ return checkMachineImpl (*ELFObj, EMachine);
79
+ if (const ELF64BEObjectFile *ELFObj =
80
+ dyn_cast<ELF64BEObjectFile>(&**ElfOrErr))
81
+ return checkMachineImpl (*ELFObj, EMachine);
82
+ return createError (" Only 64-bit ELF files are supported" );
83
+ }
84
+
74
85
template <class ELFT >
75
86
static Expected<const typename ELFT::Sym *>
76
87
getSymbolFromGnuHashTable (StringRef Name, const typename ELFT::GnuHash &HashTab,
@@ -231,8 +242,9 @@ getSymTableSymbol(const ELFFile<ELFT> &Elf, const typename ELFT::Shdr &Sec,
231
242
return nullptr ;
232
243
}
233
244
234
- Expected<const typename ELF64LE::Sym *>
235
- utils::elf::getSymbol (const ELFObjectFile<ELF64LE> &ELFObj, StringRef Name) {
245
+ template <class ELFT >
246
+ static Expected<const typename ELFT::Sym *>
247
+ getSymbol (const ELFObjectFile<ELFT> &ELFObj, StringRef Name) {
236
248
// First try to look up the symbol via the hash table.
237
249
for (ELFSectionRef Sec : ELFObj.sections ()) {
238
250
if (Sec.getType () != SHT_HASH && Sec.getType () != SHT_GNU_HASH)
@@ -241,8 +253,7 @@ utils::elf::getSymbol(const ELFObjectFile<ELF64LE> &ELFObj, StringRef Name) {
241
253
auto HashTabOrErr = ELFObj.getELFFile ().getSection (Sec.getIndex ());
242
254
if (!HashTabOrErr)
243
255
return HashTabOrErr.takeError ();
244
- return getHashTableSymbol<ELF64LE>(ELFObj.getELFFile (), **HashTabOrErr,
245
- Name);
256
+ return getHashTableSymbol<ELFT>(ELFObj.getELFFile (), **HashTabOrErr, Name);
246
257
}
247
258
248
259
// If this is an executable file check the entire standard symbol table.
@@ -253,16 +264,17 @@ utils::elf::getSymbol(const ELFObjectFile<ELF64LE> &ELFObj, StringRef Name) {
253
264
auto SymTabOrErr = ELFObj.getELFFile ().getSection (Sec.getIndex ());
254
265
if (!SymTabOrErr)
255
266
return SymTabOrErr.takeError ();
256
- return getSymTableSymbol<ELF64LE >(ELFObj.getELFFile (), **SymTabOrErr, Name);
267
+ return getSymTableSymbol<ELFT >(ELFObj.getELFFile (), **SymTabOrErr, Name);
257
268
}
258
269
259
270
return nullptr ;
260
271
}
261
272
262
- Expected<const void *> utils::elf::getSymbolAddress (
263
- const object::ELFObjectFile<object::ELF64LE> &ELFObj,
264
- const object::ELF64LE::Sym &Symbol) {
265
- const ELFFile<ELF64LE> &ELFFile = ELFObj.getELFFile ();
273
+ template <class ELFT >
274
+ static Expected<const void *>
275
+ getSymbolAddress (const object::ELFObjectFile<ELFT> &ELFObj,
276
+ const typename ELFT::Sym &Symbol) {
277
+ const ELFFile<ELFT> &ELFFile = ELFObj.getELFFile ();
266
278
267
279
auto SecOrErr = ELFFile.getSection (Symbol.st_shndx );
268
280
if (!SecOrErr)
@@ -283,3 +295,40 @@ Expected<const void *> utils::elf::getSymbolAddress(
283
295
284
296
return ELFFile.base () + Offset;
285
297
}
298
+
299
+ template <class ELFT >
300
+ static Expected<std::optional<StringRef>>
301
+ findSymbolInImageImpl (const object::ELFObjectFile<ELFT> &ELFObj,
302
+ StringRef Name) {
303
+ auto SymOrErr = getSymbol (ELFObj, Name);
304
+ if (!SymOrErr)
305
+ return SymOrErr.takeError ();
306
+ if (!*SymOrErr)
307
+ return std::nullopt;
308
+
309
+ // If the symbol was found, return a StringRef covering the associated data,
310
+ // based on the symbol's address and size.
311
+ auto AddrOrErr = getSymbolAddress (ELFObj, **SymOrErr);
312
+ if (!AddrOrErr)
313
+ return AddrOrErr.takeError ();
314
+ return StringRef (static_cast <const char *>(*AddrOrErr), (*SymOrErr)->st_size );
315
+ }
316
+
317
+ Expected<std::optional<StringRef>>
318
+ utils::elf::findSymbolInImage (StringRef Obj, StringRef Name) {
319
+ assert (isELF (Obj) && " Input is not an ELF!" );
320
+
321
+ Expected<std::unique_ptr<ObjectFile>> ElfOrErr =
322
+ ObjectFile::createELFObjectFile (MemoryBufferRef (Obj, /* Identifier=*/ " " ),
323
+ /* InitContent=*/ false );
324
+ if (!ElfOrErr)
325
+ return ElfOrErr.takeError ();
326
+
327
+ if (const ELF64LEObjectFile *ELFObj =
328
+ dyn_cast<ELF64LEObjectFile>(&**ElfOrErr))
329
+ return findSymbolInImageImpl (*ELFObj, Name);
330
+ if (const ELF64BEObjectFile *ELFObj =
331
+ dyn_cast<ELF64BEObjectFile>(&**ElfOrErr))
332
+ return findSymbolInImageImpl (*ELFObj, Name);
333
+ return createError (" Only 64-bit ELF files are supported" );
334
+ }
0 commit comments