1 //===----------- StringTableBuilderTest.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/MC/StringTableBuilder.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/Support/Endian.h"
12 #include "gtest/gtest.h"
13 #include <string>
14
15 using namespace llvm;
16
17 namespace {
18
TEST(StringTableBuilderTest,BasicELF)19 TEST(StringTableBuilderTest, BasicELF) {
20 StringTableBuilder B(StringTableBuilder::ELF);
21
22 B.add("foo");
23 B.add("bar");
24 B.add("foobar");
25
26 B.finalize();
27
28 std::string Expected;
29 Expected += '\x00';
30 Expected += "foobar";
31 Expected += '\x00';
32 Expected += "foo";
33 Expected += '\x00';
34
35 SmallString<64> Data;
36 raw_svector_ostream OS(Data);
37 B.write(OS);
38
39 EXPECT_EQ(Expected, Data);
40 EXPECT_EQ(1U, B.getOffset("foobar"));
41 EXPECT_EQ(4U, B.getOffset("bar"));
42 EXPECT_EQ(8U, B.getOffset("foo"));
43 }
44
TEST(StringTableBuilderTest,BasicWinCOFF)45 TEST(StringTableBuilderTest, BasicWinCOFF) {
46 StringTableBuilder B(StringTableBuilder::WinCOFF);
47
48 // Strings must be 9 chars or longer to go in the table.
49 B.add("hippopotamus");
50 B.add("pygmy hippopotamus");
51 B.add("river horse");
52
53 B.finalize();
54
55 // size_field + "pygmy hippopotamus\0" + "river horse\0"
56 uint32_t ExpectedSize = 4 + 19 + 12;
57 EXPECT_EQ(ExpectedSize, B.getSize());
58
59 std::string Expected;
60
61 ExpectedSize =
62 support::endian::byte_swap<uint32_t, support::little>(ExpectedSize);
63 Expected.append((const char*)&ExpectedSize, 4);
64 Expected += "pygmy hippopotamus";
65 Expected += '\x00';
66 Expected += "river horse";
67 Expected += '\x00';
68
69 SmallString<64> Data;
70 raw_svector_ostream OS(Data);
71 B.write(OS);
72
73 EXPECT_EQ(Expected, Data);
74 EXPECT_EQ(4U, B.getOffset("pygmy hippopotamus"));
75 EXPECT_EQ(10U, B.getOffset("hippopotamus"));
76 EXPECT_EQ(23U, B.getOffset("river horse"));
77 }
78
TEST(StringTableBuilderTest,ELFInOrder)79 TEST(StringTableBuilderTest, ELFInOrder) {
80 StringTableBuilder B(StringTableBuilder::ELF);
81 EXPECT_EQ(1U, B.add("foo"));
82 EXPECT_EQ(5U, B.add("bar"));
83 EXPECT_EQ(9U, B.add("foobar"));
84
85 B.finalizeInOrder();
86
87 std::string Expected;
88 Expected += '\x00';
89 Expected += "foo";
90 Expected += '\x00';
91 Expected += "bar";
92 Expected += '\x00';
93 Expected += "foobar";
94 Expected += '\x00';
95
96 SmallString<64> Data;
97 raw_svector_ostream OS(Data);
98 B.write(OS);
99
100 EXPECT_EQ(Expected, Data);
101 EXPECT_EQ(1U, B.getOffset("foo"));
102 EXPECT_EQ(5U, B.getOffset("bar"));
103 EXPECT_EQ(9U, B.getOffset("foobar"));
104 }
105
TEST(StringTableBuilderTest,MachOInOrder)106 TEST(StringTableBuilderTest, MachOInOrder) {
107 StringTableBuilder B(StringTableBuilder::MachO);
108
109 B.add("foo");
110 B.add("bar");
111 B.add("fooba");
112
113 B.finalizeInOrder();
114
115 std::string Expected;
116 Expected += '\x00';
117 Expected += "foo";
118 Expected += '\x00';
119 Expected += "bar";
120 Expected += '\x00';
121 Expected += "fooba";
122 Expected += '\x00';
123
124 // Mach-O pads to 4 bytes
125 Expected += '\x00';
126
127 SmallString<64> Data;
128 raw_svector_ostream OS(Data);
129 B.write(OS);
130
131 EXPECT_EQ(Expected, Data);
132 EXPECT_EQ(1U, B.getOffset("foo"));
133 EXPECT_EQ(5U, B.getOffset("bar"));
134 EXPECT_EQ(9U, B.getOffset("fooba"));
135 }
136
TEST(StringTableBuilderTest,MachO64InOrder)137 TEST(StringTableBuilderTest, MachO64InOrder) {
138 StringTableBuilder B(StringTableBuilder::MachO64);
139
140 B.add("foo");
141 B.add("bar");
142 B.add("f");
143
144 B.finalizeInOrder();
145
146 std::string Expected;
147 Expected += '\x00';
148 Expected += "foo";
149 Expected += '\x00';
150 Expected += "bar";
151 Expected += '\x00';
152 Expected += "f";
153 Expected += '\x00';
154
155 // 64 bit Mach-O pads to 8 bytes
156 Expected += '\x00';
157 Expected += '\x00';
158 Expected += '\x00';
159 Expected += '\x00';
160 Expected += '\x00';
161
162 SmallString<64> Data;
163 raw_svector_ostream OS(Data);
164 B.write(OS);
165
166 EXPECT_EQ(Expected, Data);
167 EXPECT_EQ(1U, B.getOffset("foo"));
168 EXPECT_EQ(5U, B.getOffset("bar"));
169 EXPECT_EQ(9U, B.getOffset("f"));
170 }
171
TEST(StringTableBuilderTest,MachOLinkedInOrder)172 TEST(StringTableBuilderTest, MachOLinkedInOrder) {
173 StringTableBuilder B(StringTableBuilder::MachOLinked);
174
175 B.add("foo");
176 B.add("bar");
177 B.add("foob");
178
179 B.finalizeInOrder();
180
181 std::string Expected;
182 Expected += ' ';
183 Expected += '\x00';
184 Expected += "foo";
185 Expected += '\x00';
186 Expected += "bar";
187 Expected += '\x00';
188 Expected += "foob";
189 Expected += '\x00';
190
191 // Mach-O pads to 4 bytes
192 Expected += '\x00';
193
194 SmallString<64> Data;
195 raw_svector_ostream OS(Data);
196 B.write(OS);
197
198 EXPECT_EQ(Expected, Data);
199 EXPECT_EQ(2U, B.getOffset("foo"));
200 EXPECT_EQ(6U, B.getOffset("bar"));
201 EXPECT_EQ(10U, B.getOffset("foob"));
202 }
203
TEST(StringTableBuilderTest,MachO64LinkedInOrder)204 TEST(StringTableBuilderTest, MachO64LinkedInOrder) {
205 StringTableBuilder B(StringTableBuilder::MachO64Linked);
206
207 B.add("foo");
208 B.add("ba");
209 B.add("f");
210
211 B.finalizeInOrder();
212
213 std::string Expected;
214 Expected += ' ';
215 Expected += '\x00';
216 Expected += "foo";
217 Expected += '\x00';
218 Expected += "ba";
219 Expected += '\x00';
220 Expected += "f";
221 Expected += '\x00';
222
223 // 64 bit Mach-O pads to 8 bytes
224 Expected += '\x00';
225 Expected += '\x00';
226 Expected += '\x00';
227 Expected += '\x00';
228 Expected += '\x00';
229
230 SmallString<64> Data;
231 raw_svector_ostream OS(Data);
232 B.write(OS);
233
234 EXPECT_EQ(Expected, Data);
235 EXPECT_EQ(2U, B.getOffset("foo"));
236 EXPECT_EQ(6U, B.getOffset("ba"));
237 EXPECT_EQ(9U, B.getOffset("f"));
238 }
239 }
240