gem5 v23.0.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
symtab.test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Daniel R. Carvalho
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <gmock/gmock.h>
30#include <gtest/gtest-spi.h>
31#include <gtest/gtest.h>
32
33#include <cassert>
34#include <initializer_list>
35#include <sstream>
36
38#include "base/loader/symtab.hh"
39
40using namespace gem5;
41
50std::string
52{
53 std::stringstream ss;
54
55 if (symbol.binding != expected.binding) {
56 ss << " symbols' bindings do not match: seen `" <<
57 (int)symbol.binding << "`, expected `" <<
58 (int)expected.binding << "`.\n";
59 }
60
61 if (symbol.name != expected.name) {
62 ss << " symbols' names do not match: seen `" << symbol.name <<
63 "`, expected `" << expected.name << "`.\n";
64 }
65
66 if (symbol.address != expected.address) {
67 ss << " symbols' addresses do not match: seen `" <<
68 symbol.address << "`, expected `" << expected.address << "`.\n";
69 }
70
71 // No error, symbols match
72 return ss.str();
73}
74
84::testing::AssertionResult
85checkSymbol(const char* m_symbol, const char* m_expected,
86 const loader::Symbol& symbol, const loader::Symbol& expected)
87{
88 const std::string error = getSymbolError(symbol, expected);
89 if (!error.empty()) {
90 return ::testing::AssertionFailure() << "Symbols do not match (" <<
91 m_symbol << " != " << m_expected << ")\n" << error;
92 }
93 return ::testing::AssertionSuccess();
94}
95
103::testing::AssertionResult
105 const std::initializer_list<loader::Symbol>& expected)
106{
107 if (expected.size() != (symtab.end() - symtab.begin())) {
108 return ::testing::AssertionFailure() << "the number of symbols in "
109 "the table does not match expectation (seen " <<
110 (symtab.end() - symtab.begin()) << ", expected " <<
111 expected.size();
112 }
113
114 // @todo We should not assume that the symbols are seen in the given order
115 auto it = symtab.begin();
116 for (const auto& symbol : expected) {
117 const std::string error = getSymbolError(*(it++), symbol);
118 if (!error.empty()) {
119 return ::testing::AssertionFailure() << error;
120 }
121 }
122
123 return ::testing::AssertionSuccess();
124}
125
127TEST(LoaderSymtabTest, EmptyConstruction)
128{
129 loader::SymbolTable symtab;
130 ASSERT_TRUE(symtab.empty());
131 ASSERT_TRUE(checkTable(symtab, {}));
132}
133
135TEST(LoaderSymtabTest, InsertSymbolNoName)
136{
137 loader::SymbolTable symtab;
138
139 loader::Symbol symbol = {loader::Symbol::Binding::Local, "", 0x10};
140 ASSERT_FALSE(symtab.insert(symbol));
141 ASSERT_TRUE(checkTable(symtab, {}));
142}
143
145TEST(LoaderSymtabTest, InsertOneSymbol)
146{
147 loader::SymbolTable symtab;
148
149 loader::Symbol symbol = {loader::Symbol::Binding::Local, "symbol", 0x10};
150 ASSERT_TRUE(symtab.insert(symbol));
151
152 ASSERT_FALSE(symtab.empty());
153 ASSERT_TRUE(checkTable(symtab, {symbol}));
154}
155
157TEST(LoaderSymtabTest, InsertSymbolExistingName)
158{
159 loader::SymbolTable symtab;
160
161 const std::string name = "symbol";
162 loader::Symbol symbols[] = {
163 {loader::Symbol::Binding::Local, name, 0x10},
164 {loader::Symbol::Binding::Local, name, 0x20},
165 };
166 ASSERT_TRUE(symtab.insert(symbols[0]));
167 ASSERT_FALSE(symtab.insert(symbols[1]));
168
169 // Check that the second symbol has not been inserted
170 ASSERT_TRUE(checkTable(symtab, {symbols[0]}));
171}
172
174TEST(LoaderSymtabTest, InsertSymbolExistingAddress)
175{
176 loader::SymbolTable symtab;
177
178 const Addr addr = 0x10;
179 loader::Symbol symbols[] = {
180 {loader::Symbol::Binding::Local, "symbol", addr},
181 {loader::Symbol::Binding::Local, "symbol2", addr},
182 };
183 ASSERT_TRUE(symtab.insert(symbols[0]));
184 ASSERT_TRUE(symtab.insert(symbols[1]));
185
186 // Check that all symbols are present
187 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1]}));
188}
189
191TEST(LoaderSymtabTest, InsertMultipleSymbols)
192{
193 loader::SymbolTable symtab;
194
195 loader::Symbol symbols[] = {
196 {loader::Symbol::Binding::Local, "symbol", 0x10},
197 {loader::Symbol::Binding::Local, "symbol2", 0x20},
198 {loader::Symbol::Binding::Local, "symbol3", 0x30},
199 };
200 EXPECT_TRUE(symtab.insert(symbols[0]));
201 EXPECT_TRUE(symtab.insert(symbols[1]));
202 EXPECT_TRUE(symtab.insert(symbols[2]));
203
204 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2]}));
205}
206
210TEST(LoaderSymtabTest, ClearMultiple)
211{
212 loader::SymbolTable symtab;
213
214 loader::Symbol symbols[] = {
215 {loader::Symbol::Binding::Local, "symbol", 0x10},
216 {loader::Symbol::Binding::Local, "symbol2", 0x20},
217 {loader::Symbol::Binding::Local, "symbol3", 0x30},
218 };
219 EXPECT_TRUE(symtab.insert(symbols[0]));
220 EXPECT_TRUE(symtab.insert(symbols[1]));
221 EXPECT_TRUE(symtab.insert(symbols[2]));
222
223 symtab.clear();
224 ASSERT_TRUE(symtab.empty());
225 ASSERT_TRUE(checkTable(symtab, {}));
226}
227
232TEST(LoaderSymtabTest, Offset)
233{
234 loader::SymbolTable symtab;
235
236 loader::Symbol symbols[] = {
237 {loader::Symbol::Binding::Local, "symbol", 0x10},
238 {loader::Symbol::Binding::Local, "symbol2", 0x20},
239 {loader::Symbol::Binding::Local, "symbol3", 0x30},
240 };
241 EXPECT_TRUE(symtab.insert(symbols[0]));
242 EXPECT_TRUE(symtab.insert(symbols[1]));
243 EXPECT_TRUE(symtab.insert(symbols[2]));
244
245 Addr offset = 0x5;
246 const auto symtab_new = symtab.offset(offset);
247
248 // Check that the original table is not modified
249 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2]}));
250
251 // Check that the new table is offset
252 loader::Symbol expected_symbols[] = {
253 {symbols[0].binding, symbols[0].name, symbols[0].address + offset},
254 {symbols[1].binding, symbols[1].name, symbols[1].address + offset},
255 {symbols[2].binding, symbols[2].name, symbols[2].address + offset},
256 };
257 ASSERT_TRUE(checkTable(*symtab_new, {expected_symbols[0],
258 expected_symbols[1], expected_symbols[2]}));
259}
260
265TEST(LoaderSymtabTest, Mask)
266{
267 loader::SymbolTable symtab;
268
269 loader::Symbol symbols[] = {
270 {loader::Symbol::Binding::Local, "symbol", 0x1310},
271 {loader::Symbol::Binding::Local, "symbol2", 0x2810},
272 {loader::Symbol::Binding::Local, "symbol3", 0x2920},
273 {loader::Symbol::Binding::Local, "symbol4", 0x3C20},
274 };
275 EXPECT_TRUE(symtab.insert(symbols[0]));
276 EXPECT_TRUE(symtab.insert(symbols[1]));
277 EXPECT_TRUE(symtab.insert(symbols[2]));
278 EXPECT_TRUE(symtab.insert(symbols[3]));
279
280 Addr mask = 0x0110;
281 const auto symtab_new = symtab.mask(mask);
282
283 // Check that the original table is not modified
284 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
285 symbols[3]}));
286
287 // Check that the new table is masked
288 loader::Symbol expected_symbols[] = {
289 {symbols[0].binding, symbols[0].name, symbols[0].address & mask},
290 {symbols[1].binding, symbols[1].name, symbols[1].address & mask},
291 {symbols[2].binding, symbols[2].name, symbols[2].address & mask},
292 {symbols[3].binding, symbols[3].name, symbols[3].address & mask},
293 };
294 ASSERT_TRUE(checkTable(*symtab_new, {expected_symbols[0],
295 expected_symbols[1], expected_symbols[2], expected_symbols[3]}));
296}
297
302TEST(LoaderSymtabTest, Rename)
303{
304 loader::SymbolTable symtab;
305
306 loader::Symbol symbols[] = {
307 {loader::Symbol::Binding::Local, "symbol", 0x10},
308 {loader::Symbol::Binding::Local, "symbol2", 0x20},
309 {loader::Symbol::Binding::Local, "symbol3", 0x30},
310 {loader::Symbol::Binding::Local, "symbol4", 0x40},
311 };
312 EXPECT_TRUE(symtab.insert(symbols[0]));
313 EXPECT_TRUE(symtab.insert(symbols[1]));
314 EXPECT_TRUE(symtab.insert(symbols[2]));
315 EXPECT_TRUE(symtab.insert(symbols[3]));
316
317 const auto symtab_new =
318 symtab.rename([](std::string &name) { name = name + "_suffix"; });
319
320 // Check that the original table is not modified
321 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
322 symbols[3]}));
323
324 // Check that the new table's symbols have been renamed
325 loader::Symbol expected_symbols[] = {
326 {symbols[0].binding, symbols[0].name + "_suffix", symbols[0].address},
327 {symbols[1].binding, symbols[1].name + "_suffix", symbols[1].address},
328 {symbols[2].binding, symbols[2].name + "_suffix", symbols[2].address},
329 {symbols[3].binding, symbols[3].name + "_suffix", symbols[3].address},
330 };
331 ASSERT_TRUE(checkTable(*symtab_new, {expected_symbols[0],
332 expected_symbols[1], expected_symbols[2], expected_symbols[3]}));
333}
334
339TEST(LoaderSymtabTest, RenameNonUnique)
340{
341 loader::SymbolTable symtab;
342
343 loader::Symbol symbols[] = {
344 {loader::Symbol::Binding::Local, "symbol", 0x10},
345 {loader::Symbol::Binding::Local, "symbol2", 0x20},
346 {loader::Symbol::Binding::Local, "symbol3", 0x30},
347 {loader::Symbol::Binding::Local, "symbol4", 0x40},
348 };
349 EXPECT_TRUE(symtab.insert(symbols[0]));
350 EXPECT_TRUE(symtab.insert(symbols[1]));
351 EXPECT_TRUE(symtab.insert(symbols[2]));
352 EXPECT_TRUE(symtab.insert(symbols[3]));
353
354 int i = 0;
355 const auto symtab_new = symtab.rename([&i](std::string &name)
356 {
357 if ((i++ % 2) == 0) {
358 name = "NonUniqueName";
359 }
360 });
361
362 // Check that the original table is not modified
363 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
364 symbols[3]}));
365
366 // Check that the new table's symbols have been renamed, yet it does not
367 // contain the symbols with duplicated names
368 loader::Symbol expected_symbols[] = {
369 {symbols[0].binding, "NonUniqueName", symbols[0].address},
370 {symbols[1].binding, symbols[1].name, symbols[1].address},
371 {symbols[3].binding, symbols[3].name, symbols[3].address},
372 };
373 ASSERT_TRUE(checkTable(*symtab_new, {expected_symbols[0],
374 expected_symbols[1], expected_symbols[2]}));
375}
376
381TEST(LoaderSymtabTest, Globals)
382{
383 loader::SymbolTable symtab;
384
385 loader::Symbol symbols[] = {
386 {loader::Symbol::Binding::Local, "symbol", 0x10},
387 {loader::Symbol::Binding::Global, "symbol2", 0x20},
388 {loader::Symbol::Binding::Local, "symbol3", 0x30},
389 {loader::Symbol::Binding::Weak, "symbol4", 0x40},
390 {loader::Symbol::Binding::Weak, "symbol5", 0x50}
391 };
392 EXPECT_TRUE(symtab.insert(symbols[0]));
393 EXPECT_TRUE(symtab.insert(symbols[1]));
394 EXPECT_TRUE(symtab.insert(symbols[2]));
395 EXPECT_TRUE(symtab.insert(symbols[3]));
396 EXPECT_TRUE(symtab.insert(symbols[4]));
397
398 const auto symtab_new = symtab.globals();
399
400 // Check that the original table is not modified
401 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
402 symbols[3], symbols[4]}));
403
404 // Check that the new table only contains globals
405 ASSERT_TRUE(checkTable(*symtab_new, {symbols[1]}));
406}
407
412TEST(LoaderSymtabTest, Locals)
413{
414 loader::SymbolTable symtab;
415
416 loader::Symbol symbols[] = {
417 {loader::Symbol::Binding::Local, "symbol", 0x10},
418 {loader::Symbol::Binding::Global, "symbol2", 0x20},
419 {loader::Symbol::Binding::Local, "symbol3", 0x30},
420 {loader::Symbol::Binding::Weak, "symbol4", 0x40},
421 {loader::Symbol::Binding::Weak, "symbol5", 0x50}
422 };
423 EXPECT_TRUE(symtab.insert(symbols[0]));
424 EXPECT_TRUE(symtab.insert(symbols[1]));
425 EXPECT_TRUE(symtab.insert(symbols[2]));
426 EXPECT_TRUE(symtab.insert(symbols[3]));
427 EXPECT_TRUE(symtab.insert(symbols[4]));
428
429 const auto symtab_new = symtab.locals();
430
431 // Check that the original table is not modified
432 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
433 symbols[3], symbols[4]}));
434
435 // Check that the new table only contains locals
436 ASSERT_TRUE(checkTable(*symtab_new, {symbols[0], symbols[2]}));
437}
438
443TEST(LoaderSymtabTest, Weaks)
444{
445 loader::SymbolTable symtab;
446
447 loader::Symbol symbols[] = {
448 {loader::Symbol::Binding::Local, "symbol", 0x10},
449 {loader::Symbol::Binding::Global, "symbol2", 0x20},
450 {loader::Symbol::Binding::Local, "symbol3", 0x30},
451 {loader::Symbol::Binding::Weak, "symbol4", 0x40},
452 {loader::Symbol::Binding::Weak, "symbol5", 0x50}
453 };
454 EXPECT_TRUE(symtab.insert(symbols[0]));
455 EXPECT_TRUE(symtab.insert(symbols[1]));
456 EXPECT_TRUE(symtab.insert(symbols[2]));
457 EXPECT_TRUE(symtab.insert(symbols[3]));
458 EXPECT_TRUE(symtab.insert(symbols[4]));
459
460 const auto symtab_new = symtab.weaks();
461
462 // Check that the original table is not modified
463 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
464 symbols[3], symbols[4]}));
465
466 // Check that the new table only contains weaks
467 ASSERT_TRUE(checkTable(*symtab_new, {symbols[3], symbols[4]}));
468}
469
471TEST(LoaderSymtabTest, FindNonExistentAddress)
472{
473 loader::SymbolTable symtab;
474
475 loader::Symbol symbol = {loader::Symbol::Binding::Local, "symbol", 0x10};
476 EXPECT_TRUE(symtab.insert(symbol));
477
478 ASSERT_EQ(symtab.find(0x0), symtab.end());
479}
480
482TEST(LoaderSymtabTest, FindUniqueAddress)
483{
484 loader::SymbolTable symtab;
485
486 loader::Symbol symbols[] = {
487 {loader::Symbol::Binding::Local, "symbol", 0x10},
488 {loader::Symbol::Binding::Local, "symbol2", 0x20},
489 {loader::Symbol::Binding::Local, "symbol3", 0x30},
490 };
491 EXPECT_TRUE(symtab.insert(symbols[0]));
492 EXPECT_TRUE(symtab.insert(symbols[1]));
493 EXPECT_TRUE(symtab.insert(symbols[2]));
494
495 const auto it = symtab.find(symbols[2].address);
496 ASSERT_NE(it, symtab.end());
497 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbols[2]);
498}
499
503TEST(LoaderSymtabTest, FindNonUniqueAddress)
504{
505 loader::SymbolTable symtab;
506
507 const Addr addr = 0x20;
508 loader::Symbol symbols[] = {
509 {loader::Symbol::Binding::Local, "symbol", 0x10},
510 {loader::Symbol::Binding::Local, "symbol2", addr},
511 {loader::Symbol::Binding::Local, "symbol3", addr},
512 };
513 EXPECT_TRUE(symtab.insert(symbols[0]));
514 EXPECT_TRUE(symtab.insert(symbols[1]));
515 EXPECT_TRUE(symtab.insert(symbols[2]));
516
517 const auto it = symtab.find(symbols[1].address);
518 ASSERT_NE(it, symtab.end());
519 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbols[1]);
520}
521
523TEST(LoaderSymtabTest, FindNonExistentName)
524{
525 loader::SymbolTable symtab;
526
527 loader::Symbol symbol = {loader::Symbol::Binding::Local, "symbol", 0x10};
528 EXPECT_TRUE(symtab.insert(symbol));
529
530 const auto it = symtab.find("symbol2");
531 ASSERT_EQ(it, symtab.end());
532}
533
535TEST(LoaderSymtabTest, FindExistingName)
536{
537 loader::SymbolTable symtab;
538
539 loader::Symbol symbols[] = {
540 {loader::Symbol::Binding::Local, "symbol", 0x10},
541 {loader::Symbol::Binding::Local, "symbol2", 0x20},
542 {loader::Symbol::Binding::Local, "symbol3", 0x30},
543 };
544 EXPECT_TRUE(symtab.insert(symbols[0]));
545 EXPECT_TRUE(symtab.insert(symbols[1]));
546 EXPECT_TRUE(symtab.insert(symbols[2]));
547
548 const auto it = symtab.find(symbols[1].name);
549 ASSERT_NE(it, symtab.end());
550 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbols[1]);
551}
552
554TEST(LoaderSymtabTest, FindNearestExact)
555{
556 loader::SymbolTable symtab;
557
558 loader::Symbol symbols[] = {
559 {loader::Symbol::Binding::Local, "symbol", 0x10},
560 {loader::Symbol::Binding::Local, "symbol2", 0x20},
561 };
562 EXPECT_TRUE(symtab.insert(symbols[0]));
563 EXPECT_TRUE(symtab.insert(symbols[1]));
564
565 const auto it = symtab.findNearest(symbols[1].address);
566 ASSERT_NE(it, symtab.end());
567 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbols[1]);
568}
569
574TEST(LoaderSymtabTest, FindNearestRound)
575{
576 loader::SymbolTable symtab;
577
578 loader::Symbol symbol = {loader::Symbol::Binding::Local, "symbol", 0x10};
579 EXPECT_TRUE(symtab.insert(symbol));
580
581 const auto it = symtab.findNearest(symbol.address + 0x1);
582 ASSERT_NE(it, symtab.end());
583 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbol);
584}
585
591TEST(LoaderSymtabTest, FindNearestRoundWithNext)
592{
593 loader::SymbolTable symtab;
594
595 loader::Symbol symbols[] = {
596 {loader::Symbol::Binding::Local, "symbol", 0x10},
597 {loader::Symbol::Binding::Local, "symbol2", 0x20},
598 };
599 EXPECT_TRUE(symtab.insert(symbols[0]));
600 EXPECT_TRUE(symtab.insert(symbols[1]));
601
602 Addr next_addr;
603 const auto it = symtab.findNearest(symbols[0].address + 0x1, next_addr);
604 ASSERT_NE(it, symtab.end());
605 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbols[0]);
606 ASSERT_EQ(next_addr, symbols[1].address);
607}
608
614TEST(LoaderSymtabTest, FindNearestRoundWithNextNonExistent)
615{
616 loader::SymbolTable symtab;
617
618 loader::Symbol symbol = {loader::Symbol::Binding::Local, "symbol", 0x10};
619 EXPECT_TRUE(symtab.insert(symbol));
620
621 Addr next_addr;
622 const auto it = symtab.findNearest(symbol.address + 0x1, next_addr);
623 ASSERT_NE(it, symtab.end());
624 ASSERT_PRED_FORMAT2(checkSymbol, *it, symbol);
625 ASSERT_EQ(next_addr, 0);
626}
627
632TEST(LoaderSymtabTest, FindNearestNonExistent)
633{
634 loader::SymbolTable symtab;
635
636 loader::Symbol symbol = {loader::Symbol::Binding::Local, "symbol", 0x10};
637 EXPECT_TRUE(symtab.insert(symbol));
638
639 const auto it = symtab.findNearest(symbol.address - 0x1);
640 ASSERT_EQ(it, symtab.end());
641}
642
647TEST(LoaderSymtabTest, InsertTableConflicting)
648{
649 const std::string name = "symbol";
650 loader::Symbol symbols[] = {
651 {loader::Symbol::Binding::Local, name, 0x10},
652 {loader::Symbol::Binding::Local, "symbol2", 0x20},
653 {loader::Symbol::Binding::Local, "symbol3", 0x30},
654 {loader::Symbol::Binding::Local, "symbol4", 0x40},
655 // Introduce name conflict
656 {loader::Symbol::Binding::Local, name, 0x50},
657 };
658
659 // Populate table 1
660 loader::SymbolTable symtab;
661 EXPECT_TRUE(symtab.insert(symbols[0]));
662 EXPECT_TRUE(symtab.insert(symbols[1]));
663 EXPECT_TRUE(symtab.insert(symbols[2]));
664
665 // Populate table 2
666 loader::SymbolTable symtab2;
667 EXPECT_TRUE(symtab2.insert(symbols[3]));
668 EXPECT_TRUE(symtab2.insert(symbols[4]));
669
670 // Do the insertion
671 ASSERT_FALSE(symtab.insert(symtab2));
672
673 // Check that none of the tables change
674 ASSERT_TRUE(checkTable(symtab2, {symbols[3], symbols[4]}));
675 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2]}));
676}
677
682TEST(LoaderSymtabTest, InsertTable)
683{
684 loader::Symbol symbols[] = {
685 {loader::Symbol::Binding::Local, "symbol", 0x10},
686 {loader::Symbol::Binding::Local, "symbol2", 0x20},
687 {loader::Symbol::Binding::Local, "symbol3", 0x30},
688 {loader::Symbol::Binding::Local, "symbol4", 0x40},
689 {loader::Symbol::Binding::Local, "symbol5", 0x50},
690 };
691
692 // Populate table 1
693 loader::SymbolTable symtab;
694 EXPECT_TRUE(symtab.insert(symbols[0]));
695 EXPECT_TRUE(symtab.insert(symbols[1]));
696 EXPECT_TRUE(symtab.insert(symbols[2]));
697
698 // Populate table 2
699 loader::SymbolTable symtab2;
700 EXPECT_TRUE(symtab2.insert(symbols[3]));
701 EXPECT_TRUE(symtab2.insert(symbols[4]));
702
703 // Do the insertion
704 symtab.insert(symtab2);
705
706 // Check that symtab2 does not change
707 ASSERT_TRUE(checkTable(symtab2, {symbols[3], symbols[4]}));
708
709 // Check that the symbols from symtab2 have been inserted in symtab
710 ASSERT_TRUE(checkTable(symtab, {symbols[0], symbols[1], symbols[2],
711 symbols[3], symbols[4]}));
712}
713
715
718{
719 // Populate the table
720 loader::SymbolTable symtab;
721 loader::Symbol symbols[] = {
722 {loader::Symbol::Binding::Local, "symbol", 0x10},
723 {loader::Symbol::Binding::Local, "symbol2", 0x20},
724 {loader::Symbol::Binding::Local, "symbol3", 0x30},
725 };
726 EXPECT_TRUE(symtab.insert(symbols[0]));
727 EXPECT_TRUE(symtab.insert(symbols[1]));
728 EXPECT_TRUE(symtab.insert(symbols[2]));
729
730 // Serialization
731 std::ostringstream cp;
733 symtab.serialize("test", cp);
734
735 // Verify the output
736 ASSERT_THAT(cp.str(), ::testing::StrEq("\n[Section1]\ntest.size=3\n"
737 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
738 "test.addr_1=32\ntest.symbol_1=symbol2\ntest.binding_1=1\n"
739 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n"));
740}
741
744{
745 loader::Symbol symbols[] = {
746 {loader::Symbol::Binding::Local, "symbol", 0x10},
747 {loader::Symbol::Binding::Local, "symbol2", 0x20},
748 {loader::Symbol::Binding::Local, "symbol3", 0x30},
749 };
750 simulateSerialization("\n[Section1]\ntest.size=3\n"
751 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
752 "test.addr_1=32\ntest.symbol_1=symbol2\ntest.binding_1=1\n"
753 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n");
754
755 loader::SymbolTable unserialized_symtab;
756 CheckpointIn cp(getDirName());
758 unserialized_symtab.unserialize("test", cp);
759
760 // Make sure that the symbols in symtab are present in the
761 // unserialized table
762 ASSERT_TRUE(checkTable(unserialized_symtab, {symbols[0], symbols[1],
763 symbols[2]}));
764}
765
771TEST_F(LoaderSymtabSerializationFixture, UnserializationMissingBinding)
772{
773 loader::Symbol symbols[] = {
774 {loader::Symbol::Binding::Local, "symbol", 0x10},
775 {loader::Symbol::Binding::Global, "symbol2", 0x20},
776 {loader::Symbol::Binding::Local, "symbol3", 0x30},
777 };
778 simulateSerialization("\n[Section1]\ntest.size=3\n"
779 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
780 "test.addr_1=32\ntest.symbol_1=symbol2\n"
781 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n");
782
783 loader::SymbolTable unserialized_symtab;
784 CheckpointIn cp(getDirName());
786
787 unserialized_symtab.unserialize("test", cp);
788
789 // Make sure that the symbols in symtab are present in the
790 // unserialized table
791 ASSERT_TRUE(checkTable(unserialized_symtab, {symbols[0], symbols[1],
792 symbols[2]}));
793}
794
801 UnserializationMissingBindingChangeDefault)
802{
803 loader::Symbol symbols[] = {
804 {loader::Symbol::Binding::Local, "symbol", 0x10},
805 {loader::Symbol::Binding::Weak, "symbol2", 0x20},
806 {loader::Symbol::Binding::Local, "symbol3", 0x30},
807 };
808 simulateSerialization("\n[Section1]\ntest.size=3\n"
809 "test.addr_0=16\ntest.symbol_0=symbol\ntest.binding_0=1\n"
810 "test.addr_1=32\ntest.symbol_1=symbol2\n"
811 "test.addr_2=48\ntest.symbol_2=symbol3\ntest.binding_2=1\n");
812
813 loader::SymbolTable unserialized_symtab;
814 CheckpointIn cp(getDirName());
816
817 unserialized_symtab.unserialize("test", cp,
818 loader::Symbol::Binding::Weak);
819
820 // Make sure that the symbols in symtab are present in the
821 // unserialized table
822 ASSERT_TRUE(checkTable(unserialized_symtab, {symbols[0], symbols[1],
823 symbols[2]}));
824}
std::string error
Container for serializing global variables (not associated with any serialized object).
Definition globals.hh:55
Fixture class that handles temporary directory creation.
SymbolTablePtr locals() const
Generates a new symbol table containing only local symbols.
Definition symtab.hh:277
SymbolTablePtr weaks() const
Generates a new symbol table containing only weak symbols.
Definition symtab.hh:288
bool empty() const
Verifies whether the table is empty.
Definition symtab.hh:203
SymbolTablePtr globals() const
Generates a new symbol table containing only global symbols.
Definition symtab.hh:266
void clear()
Clears the table.
Definition symtab.cc:46
const_iterator end() const
Definition symtab.hh:175
void unserialize(const std::string &base, CheckpointIn &cp, Symbol::Binding default_binding=Symbol::Binding::Global)
Populate the table by unserializing a checkpoint.
Definition symtab.cc:106
const_iterator begin() const
Definition symtab.hh:172
const_iterator findNearest(Addr addr, Addr &next_addr) const
Find the nearest symbol equal to or less than the supplied address (e.g., the label for the enclosing...
Definition symtab.hh:360
SymbolTablePtr mask(Addr m) const
Generate a new table by a mask to the symbols of the current table.
Definition symtab.hh:232
SymbolTablePtr offset(Addr addr_offset) const
Generate a new table by applying an offset to the symbols of the current table.
Definition symtab.hh:213
SymbolTablePtr rename(std::function< void(std::string &)> func) const
Modify the symbols' name with a given transform function.
Definition symtab.hh:250
void serialize(const std::string &base, CheckpointOut &cp) const
Serialize the table's contents.
Definition symtab.cc:92
bool insert(const Symbol &symbol)
Insert a new symbol in the table if it does not already exist.
Definition symtab.cc:54
const_iterator find(Addr address) const
Search for a symbol by its address.
Definition symtab.hh:321
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 21 > ss
Definition misc_types.hh:60
Bitfield< 18 > scs
Bitfield< 3 > addr
Definition types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
std::string name
Definition symtab.hh:60
std::string getSymbolError(const loader::Symbol &symbol, const loader::Symbol &expected)
Checks if a symbol's contents matches the expected contents to generate an error message.
::testing::AssertionResult checkSymbol(const char *m_symbol, const char *m_expected, const loader::Symbol &symbol, const loader::Symbol &expected)
Checks that a symbol's contents matches the expected contents.
TEST_F(LoaderSymtabSerializationFixture, Serialization)
Test serialization.
::testing::AssertionResult checkTable(const loader::SymbolTable &symtab, const std::initializer_list< loader::Symbol > &expected)
Checks that a symbol table contains only the expected symbols.
TEST(LoaderSymtabTest, EmptyConstruction)
Test that the constructor creates an empty table.
const std::string & name()
Definition trace.cc:48

Generated on Mon Jul 10 2023 15:32:00 for gem5 by doxygen 1.9.7