1 //===-- elf_common.cpp - Common ELF functionality -------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Common ELF functionality for target plugins.
11 //===----------------------------------------------------------------------===//
12 #include "elf_common.h"
15 #include "llvm/BinaryFormat/Magic.h"
16 #include "llvm/Object/Binary.h"
17 #include "llvm/Object/ELFObjectFile.h"
18 #include "llvm/Object/ELFTypes.h"
19 #include "llvm/Object/ObjectFile.h"
20 #include "llvm/Support/MemoryBuffer.h"
23 #define TARGET_NAME ELF Common
25 #define DEBUG_PREFIX "TARGET " GETNAME(TARGET_NAME)
28 using namespace llvm::ELF
;
29 using namespace llvm::object
;
31 /// If the given range of bytes [\p BytesBegin, \p BytesEnd) represents
32 /// a valid ELF, then invoke \p Callback on the ELFObjectFileBase
33 /// created from this range, otherwise, return 0.
34 /// If \p Callback is invoked, then return whatever value \p Callback returns.
36 static int32_t withBytesAsElf(char *BytesBegin
, char *BytesEnd
, F Callback
) {
37 size_t Size
= BytesEnd
- BytesBegin
;
38 StringRef
StrBuf(BytesBegin
, Size
);
40 auto Magic
= identify_magic(StrBuf
);
41 if (Magic
!= file_magic::elf
&& Magic
!= file_magic::elf_relocatable
&&
42 Magic
!= file_magic::elf_executable
&&
43 Magic
!= file_magic::elf_shared_object
&& Magic
!= file_magic::elf_core
) {
44 DP("Not an ELF image!\n");
48 std::unique_ptr
<MemoryBuffer
> MemBuf
=
49 MemoryBuffer::getMemBuffer(StrBuf
, "", false);
50 Expected
<std::unique_ptr
<ObjectFile
>> BinOrErr
=
51 ObjectFile::createELFObjectFile(MemBuf
->getMemBufferRef(),
52 /*InitContent=*/false);
54 DP("Unable to get ELF handle: %s!\n",
55 toString(BinOrErr
.takeError()).c_str());
59 auto *Object
= dyn_cast
<const ELFObjectFileBase
>(BinOrErr
->get());
62 DP("Unknown ELF format!\n");
66 return Callback(Object
);
69 // Check whether an image is valid for execution on target_id
70 int32_t elf_check_machine(__tgt_device_image
*Image
, uint16_t TargetId
) {
71 auto CheckMachine
= [TargetId
](const ELFObjectFileBase
*Object
) {
72 return TargetId
== Object
->getEMachine();
74 return withBytesAsElf(reinterpret_cast<char *>(Image
->ImageStart
),
75 reinterpret_cast<char *>(Image
->ImageEnd
),
79 int32_t elf_is_dynamic(__tgt_device_image
*Image
) {
80 auto CheckDynType
= [](const ELFObjectFileBase
*Object
) {
81 uint16_t Type
= Object
->getEType();
82 DP("ELF Type: %d\n", Type
);
83 return Type
== ET_DYN
;
85 return withBytesAsElf(reinterpret_cast<char *>(Image
->ImageStart
),
86 reinterpret_cast<char *>(Image
->ImageEnd
),