1 | //===- ELFYAMLTest.cpp - Tests for ELFYAML.cpp ----------------------------===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Object/ELF.h" |
10 | #include "llvm/Object/ELFObjectFile.h" |
11 | #include "llvm/Object/ELFTypes.h" |
12 | #include "llvm/ObjectYAML/yaml2obj.h" |
13 | #include "llvm/Support/YAMLTraits.h" |
14 | #include "llvm/Testing/Support/Error.h" |
15 | #include "gtest/gtest.h" |
16 | |
17 | using namespace llvm; |
18 | using namespace llvm::object; |
19 | |
20 | template <class ELFT> |
21 | static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage, |
22 | StringRef Yaml) { |
23 | Storage.clear(); |
24 | raw_svector_ostream OS(Storage); |
25 | yaml::Input YIn(Yaml); |
26 | if (!yaml::convertYAML(YIn, Out&: OS, ErrHandler: [](const Twine &Msg) {})) |
27 | return createStringError(EC: std::errc::invalid_argument, |
28 | Fmt: "unable to convert YAML" ); |
29 | |
30 | return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "Binary" )); |
31 | } |
32 | |
33 | TEST(ELFRelocationTypeTest, RelocationTestForVE) { |
34 | SmallString<0> Storage; |
35 | Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, Yaml: R"( |
36 | --- !ELF |
37 | FileHeader: |
38 | Class: ELFCLASS64 |
39 | Data: ELFDATA2LSB |
40 | Type: ET_REL |
41 | Machine: EM_VE |
42 | Sections: |
43 | - Name: .rela.text |
44 | Type: SHT_RELA |
45 | Relocations: |
46 | - Type: R_VE_NONE |
47 | - Type: R_VE_REFLONG |
48 | - Type: R_VE_REFQUAD |
49 | - Type: R_VE_SREL32 |
50 | - Type: R_VE_HI32 |
51 | - Type: R_VE_LO32 |
52 | - Type: R_VE_PC_HI32 |
53 | - Type: R_VE_PC_LO32 |
54 | - Type: R_VE_GOT32 |
55 | - Type: R_VE_GOT_HI32 |
56 | - Type: R_VE_GOT_LO32 |
57 | - Type: R_VE_GOTOFF32 |
58 | - Type: R_VE_GOTOFF_HI32 |
59 | - Type: R_VE_GOTOFF_LO32 |
60 | - Type: R_VE_PLT32 |
61 | - Type: R_VE_PLT_HI32 |
62 | - Type: R_VE_PLT_LO32 |
63 | - Type: R_VE_RELATIVE |
64 | - Type: R_VE_GLOB_DAT |
65 | - Type: R_VE_JUMP_SLOT |
66 | - Type: R_VE_COPY |
67 | - Type: R_VE_DTPMOD64 |
68 | - Type: R_VE_DTPOFF64 |
69 | - Type: R_VE_TLS_GD_HI32 |
70 | - Type: R_VE_TLS_GD_LO32 |
71 | - Type: R_VE_TPOFF_HI32 |
72 | - Type: R_VE_TPOFF_LO32 |
73 | - Type: R_VE_CALL_HI32 |
74 | - Type: R_VE_CALL_LO32)" ); |
75 | ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded()); |
76 | const ELFObjectFile<ELF64LE> &File = *ExpectedFile; |
77 | EXPECT_EQ("elf64-ve" , File.getFileFormatName()); |
78 | EXPECT_EQ(Triple::ve, File.getArch()); |
79 | |
80 | // Test relocation types. |
81 | for (SectionRef Sec : File.sections()) { |
82 | Expected<StringRef> NameOrErr = Sec.getName(); |
83 | ASSERT_THAT_EXPECTED(NameOrErr, Succeeded()); |
84 | StringRef SectionName = *NameOrErr; |
85 | if (SectionName != ".rela.text" ) |
86 | continue; |
87 | |
88 | for (RelocationRef R : Sec.relocations()) { |
89 | SmallString<32> RelTypeName; |
90 | using namespace llvm::ELF; |
91 | |
92 | #define NAME_CHECK(ID) \ |
93 | case ID: \ |
94 | R.getTypeName(RelTypeName); \ |
95 | EXPECT_EQ(#ID, RelTypeName); \ |
96 | break |
97 | |
98 | switch (R.getType()) { |
99 | NAME_CHECK(R_VE_NONE); |
100 | NAME_CHECK(R_VE_REFLONG); |
101 | NAME_CHECK(R_VE_REFQUAD); |
102 | NAME_CHECK(R_VE_SREL32); |
103 | NAME_CHECK(R_VE_HI32); |
104 | NAME_CHECK(R_VE_LO32); |
105 | NAME_CHECK(R_VE_PC_HI32); |
106 | NAME_CHECK(R_VE_PC_LO32); |
107 | NAME_CHECK(R_VE_GOT32); |
108 | NAME_CHECK(R_VE_GOT_HI32); |
109 | NAME_CHECK(R_VE_GOT_LO32); |
110 | NAME_CHECK(R_VE_GOTOFF32); |
111 | NAME_CHECK(R_VE_GOTOFF_HI32); |
112 | NAME_CHECK(R_VE_GOTOFF_LO32); |
113 | NAME_CHECK(R_VE_PLT32); |
114 | NAME_CHECK(R_VE_PLT_HI32); |
115 | NAME_CHECK(R_VE_PLT_LO32); |
116 | NAME_CHECK(R_VE_RELATIVE); |
117 | NAME_CHECK(R_VE_GLOB_DAT); |
118 | NAME_CHECK(R_VE_JUMP_SLOT); |
119 | NAME_CHECK(R_VE_COPY); |
120 | NAME_CHECK(R_VE_DTPMOD64); |
121 | NAME_CHECK(R_VE_DTPOFF64); |
122 | NAME_CHECK(R_VE_TLS_GD_HI32); |
123 | NAME_CHECK(R_VE_TLS_GD_LO32); |
124 | NAME_CHECK(R_VE_TPOFF_HI32); |
125 | NAME_CHECK(R_VE_TPOFF_LO32); |
126 | NAME_CHECK(R_VE_CALL_HI32); |
127 | NAME_CHECK(R_VE_CALL_LO32); |
128 | default: |
129 | FAIL() << "Found unexpected relocation type: " + Twine(R.getType()); |
130 | break; |
131 | } |
132 | } |
133 | } |
134 | } |
135 | |