1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "repr/symbol/version_script_parser.h"
16
17 #include <gtest/gtest.h>
18
19 #include <map>
20 #include <sstream>
21 #include <string>
22
23
24 namespace header_checker {
25 namespace repr {
26
27
TEST(VersionScriptParserTest,SmokeTest)28 TEST(VersionScriptParserTest, SmokeTest) {
29 static const char testdata[] = R"TESTDATA(
30 LIBEX_1.0 {
31 global:
32 foo1;
33 bar1; # var
34 local:
35 *;
36 };
37
38 LIBEX_2.0 {
39 global:
40 foo2;
41 bar2; # var
42 } LIBEX_1.0;
43 )TESTDATA";
44
45 VersionScriptParser parser;
46
47 std::istringstream stream(testdata);
48 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
49 ASSERT_TRUE(result);
50
51 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
52 EXPECT_NE(funcs.end(), funcs.find("foo1"));
53 EXPECT_NE(funcs.end(), funcs.find("foo2"));
54 EXPECT_EQ(funcs.end(), funcs.find("bar1"));
55 EXPECT_EQ(funcs.end(), funcs.find("bar2"));
56
57 const ExportedSymbolSet::VarMap &vars = result->GetVars();
58 EXPECT_NE(vars.end(), vars.find("bar1"));
59 EXPECT_NE(vars.end(), vars.find("bar2"));
60 EXPECT_EQ(vars.end(), vars.find("foo1"));
61 EXPECT_EQ(vars.end(), vars.find("foo2"));
62 }
63
64
TEST(VersionScriptParserTest,ExcludeSymbolVersions)65 TEST(VersionScriptParserTest, ExcludeSymbolVersions) {
66 static const char testdata[] = R"TESTDATA(
67 LIBEX_1.0 {
68 global:
69 foo1;
70 bar1; # var
71 local:
72 *;
73 };
74
75 LIBEX_PRIVATE {
76 global:
77 foo2;
78 bar2; # var
79 } LIBEX_1.0;
80 )TESTDATA";
81
82 // excluded_symbol_versions = {}
83 {
84 VersionScriptParser parser;
85
86 std::istringstream stream(testdata);
87 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
88 ASSERT_TRUE(result);
89
90 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
91 EXPECT_NE(funcs.end(), funcs.find("foo2"));
92
93 const ExportedSymbolSet::VarMap &vars = result->GetVars();
94 EXPECT_NE(vars.end(), vars.find("bar2"));
95 }
96
97 // excluded_symbol_versions = {"LIBEX_PRIVATE"}
98 {
99 VersionScriptParser parser;
100 parser.AddExcludedSymbolVersion("LIBEX_PRIVATE");
101
102 std::istringstream stream(testdata);
103 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
104 ASSERT_TRUE(result);
105
106 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
107 EXPECT_EQ(funcs.end(), funcs.find("foo2"));
108
109 const ExportedSymbolSet::VarMap &vars = result->GetVars();
110 EXPECT_EQ(vars.end(), vars.find("bar2"));
111 }
112 }
113
114
TEST(VersionScriptParserTest,VisibilityLabels)115 TEST(VersionScriptParserTest, VisibilityLabels) {
116 static const char testdata[] = R"TESTDATA(
117 LIBEX_1.0 {
118 global:
119 global_f1;
120 global_v1; # var
121 local:
122 local_f2;
123 local_v2; # var
124 global:
125 global_f3;
126 global_v3; # var
127 global:
128 global_f4;
129 global_v4; # var
130 local:
131 local_f5;
132 local_v5; # var
133 local:
134 local_f6;
135 local_v6; # var
136 };
137 )TESTDATA";
138
139 VersionScriptParser parser;
140
141 std::istringstream stream(testdata);
142 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
143 ASSERT_TRUE(result);
144
145 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
146
147 EXPECT_NE(funcs.end(), funcs.find("global_f1"));
148 EXPECT_NE(funcs.end(), funcs.find("global_f3"));
149 EXPECT_NE(funcs.end(), funcs.find("global_f4"));
150
151 EXPECT_EQ(funcs.end(), funcs.find("local_f2"));
152 EXPECT_EQ(funcs.end(), funcs.find("local_f5"));
153 EXPECT_EQ(funcs.end(), funcs.find("local_f6"));
154
155 const ExportedSymbolSet::VarMap &vars = result->GetVars();
156
157 EXPECT_NE(vars.end(), vars.find("global_v1"));
158 EXPECT_NE(vars.end(), vars.find("global_v3"));
159 EXPECT_NE(vars.end(), vars.find("global_v4"));
160
161 EXPECT_EQ(vars.end(), vars.find("local_v2"));
162 EXPECT_EQ(vars.end(), vars.find("local_v5"));
163 EXPECT_EQ(vars.end(), vars.find("local_v6"));
164 }
165
166
TEST(VersionScriptParserTest,ParseSymbolTagsIntroduced)167 TEST(VersionScriptParserTest, ParseSymbolTagsIntroduced) {
168 static const char testdata[] = R"TESTDATA(
169 LIBEX_1.0 {
170 global:
171 test1; # introduced=19
172 test2; # introduced=19 introduced-arm64=20
173 test3; # introduced-arm64=20 introduced=19
174 test4; # future
175 };
176 )TESTDATA";
177
178 {
179 VersionScriptParser parser;
180 parser.SetArch("arm64");
181 parser.SetApiLevel(18);
182
183 std::istringstream stream(testdata);
184 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
185 ASSERT_TRUE(result);
186
187 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
188
189 EXPECT_EQ(funcs.end(), funcs.find("test1"));
190 EXPECT_EQ(funcs.end(), funcs.find("test2"));
191 EXPECT_EQ(funcs.end(), funcs.find("test3"));
192 EXPECT_EQ(funcs.end(), funcs.find("test4"));
193 }
194
195 {
196 VersionScriptParser parser;
197 parser.SetArch("arm64");
198 parser.SetApiLevel(19);
199
200 std::istringstream stream(testdata);
201 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
202 ASSERT_TRUE(result);
203
204 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
205
206 EXPECT_NE(funcs.end(), funcs.find("test1"));
207 EXPECT_EQ(funcs.end(), funcs.find("test2"));
208 EXPECT_EQ(funcs.end(), funcs.find("test3"));
209 EXPECT_EQ(funcs.end(), funcs.find("test4"));
210 }
211
212 {
213 VersionScriptParser parser;
214 parser.SetArch("arm");
215 parser.SetApiLevel(19);
216
217 std::istringstream stream(testdata);
218 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
219 ASSERT_TRUE(result);
220
221 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
222
223 EXPECT_NE(funcs.end(), funcs.find("test1"));
224 EXPECT_NE(funcs.end(), funcs.find("test2"));
225 EXPECT_NE(funcs.end(), funcs.find("test3"));
226 EXPECT_EQ(funcs.end(), funcs.find("test4"));
227 }
228
229 {
230 VersionScriptParser parser;
231 parser.SetArch("arm64");
232 parser.SetApiLevel(20);
233
234 std::istringstream stream(testdata);
235 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
236 ASSERT_TRUE(result);
237
238 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
239
240 EXPECT_NE(funcs.end(), funcs.find("test1"));
241 EXPECT_NE(funcs.end(), funcs.find("test2"));
242 EXPECT_NE(funcs.end(), funcs.find("test3"));
243 EXPECT_EQ(funcs.end(), funcs.find("test4"));
244 }
245
246 {
247 VersionScriptParser parser;
248 parser.SetArch("arm64");
249 parser.SetApiLevel(utils::FUTURE_API_LEVEL);
250
251 std::istringstream stream(testdata);
252 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
253 ASSERT_TRUE(result);
254
255 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
256
257 EXPECT_NE(funcs.end(), funcs.find("test1"));
258 EXPECT_NE(funcs.end(), funcs.find("test2"));
259 EXPECT_NE(funcs.end(), funcs.find("test3"));
260 EXPECT_NE(funcs.end(), funcs.find("test4"));
261 }
262 }
263
264
TEST(VersionScriptParserTest,ParseSymbolTagsArch)265 TEST(VersionScriptParserTest, ParseSymbolTagsArch) {
266 static const char testdata[] = R"TESTDATA(
267 LIBEX_1.0 {
268 global:
269 test1;
270 test2; # arm arm64
271 test3; # arm64
272 test4; # mips
273 };
274 )TESTDATA";
275
276 {
277 VersionScriptParser parser;
278 parser.SetArch("arm");
279
280 std::istringstream stream(testdata);
281 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
282 ASSERT_TRUE(result);
283
284 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
285
286 EXPECT_NE(funcs.end(), funcs.find("test1"));
287 EXPECT_NE(funcs.end(), funcs.find("test2"));
288 EXPECT_EQ(funcs.end(), funcs.find("test3"));
289 EXPECT_EQ(funcs.end(), funcs.find("test4"));
290 }
291
292 {
293 VersionScriptParser parser;
294 parser.SetArch("arm64");
295
296 std::istringstream stream(testdata);
297 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
298 ASSERT_TRUE(result);
299
300 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
301
302 EXPECT_NE(funcs.end(), funcs.find("test1"));
303 EXPECT_NE(funcs.end(), funcs.find("test2"));
304 EXPECT_NE(funcs.end(), funcs.find("test3"));
305 EXPECT_EQ(funcs.end(), funcs.find("test4"));
306 }
307
308 {
309 VersionScriptParser parser;
310 parser.SetArch("mips");
311
312 std::istringstream stream(testdata);
313 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
314 ASSERT_TRUE(result);
315
316 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
317
318 EXPECT_NE(funcs.end(), funcs.find("test1"));
319 EXPECT_EQ(funcs.end(), funcs.find("test2"));
320 EXPECT_EQ(funcs.end(), funcs.find("test3"));
321 EXPECT_NE(funcs.end(), funcs.find("test4"));
322 }
323 }
324
325
TEST(VersionScriptParserTest,ExcludeSymbolTags)326 TEST(VersionScriptParserTest, ExcludeSymbolTags) {
327 static const char testdata[] = R"TESTDATA(
328 LIBEX_1.0 {
329 global:
330 test1;
331 test2; # exclude-tag
332 };
333 )TESTDATA";
334
335 // exclude_symbol_tags = {}
336 {
337 VersionScriptParser parser;
338
339 std::istringstream stream(testdata);
340 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
341 ASSERT_TRUE(result);
342
343 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
344
345 EXPECT_NE(funcs.end(), funcs.find("test1"));
346 EXPECT_NE(funcs.end(), funcs.find("test2"));
347 }
348
349 // exclude_symbol_tags = {"exclude-tag"}
350 {
351 VersionScriptParser parser;
352 parser.AddExcludedSymbolTag("exclude-tag");
353
354 std::istringstream stream(testdata);
355 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
356 ASSERT_TRUE(result);
357
358 const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions();
359
360 EXPECT_NE(funcs.end(), funcs.find("test1"));
361 EXPECT_EQ(funcs.end(), funcs.find("test2"));
362 }
363 }
364
365
TEST(VersionScriptParserTest,ParseExternCpp)366 TEST(VersionScriptParserTest, ParseExternCpp) {
367 static const char testdata[] = R"TESTDATA(
368 LIBEX_1.0 {
369 global:
370 test1;
371 extern "C++" {
372 Test2::test();
373 Test3::test();
374 Test4::*;
375 };
376 test5;
377 };
378 )TESTDATA";
379
380 VersionScriptParser parser;
381
382 std::istringstream stream(testdata);
383 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
384 ASSERT_TRUE(result);
385
386 const ExportedSymbolSet::NameSet &cpp_symbols =
387 result->GetDemangledCppSymbols();
388
389 EXPECT_NE(cpp_symbols.end(), cpp_symbols.find("Test2::test()"));
390 EXPECT_NE(cpp_symbols.end(), cpp_symbols.find("Test3::test()"));
391
392 EXPECT_EQ(cpp_symbols.end(), cpp_symbols.find("test1"));
393 EXPECT_EQ(cpp_symbols.end(), cpp_symbols.find("test4"));
394
395 const ExportedSymbolSet::GlobPatternSet &cpp_glob_patterns =
396 result->GetDemangledCppGlobPatterns();
397
398 EXPECT_NE(cpp_glob_patterns.end(), cpp_glob_patterns.find("Test4::*"));
399 }
400
401
TEST(VersionScriptParserTest,ParseGlobPattern)402 TEST(VersionScriptParserTest, ParseGlobPattern) {
403 static const char testdata[] = R"TESTDATA(
404 LIBEX_1.0 {
405 global:
406 test1*;
407 test2[Aa];
408 test3?;
409 test4;
410 };
411 )TESTDATA";
412
413
414 VersionScriptParser parser;
415
416 std::istringstream stream(testdata);
417 std::unique_ptr<ExportedSymbolSet> result(parser.Parse(stream));
418 ASSERT_TRUE(result);
419
420 const ExportedSymbolSet::GlobPatternSet &glob_patterns =
421 result->GetGlobPatterns();
422
423 EXPECT_NE(glob_patterns.end(), glob_patterns.find("test1*"));
424 EXPECT_NE(glob_patterns.end(), glob_patterns.find("test2[Aa]"));
425 EXPECT_NE(glob_patterns.end(), glob_patterns.find("test3?"));
426
427 EXPECT_EQ(glob_patterns.end(), glob_patterns.find("test4"));
428 }
429
430
431 } // namespace repr
432 } // namespace header_checker
433