gem5  v22.0.0.1
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 
40 using namespace gem5;
41 
50 std::string
51 getSymbolError(const Loader::Symbol& symbol, const Loader::Symbol& expected)
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
85 checkSymbol(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
104 checkTable(const Loader::SymbolTable& symtab,
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 
127 TEST(LoaderSymtabTest, EmptyConstruction)
128 {
129  Loader::SymbolTable symtab;
130  ASSERT_TRUE(symtab.empty());
131  ASSERT_TRUE(checkTable(symtab, {}));
132 }
133 
135 TEST(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 
145 TEST(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 
157 TEST(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 
174 TEST(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 
191 TEST(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 
210 TEST(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 
232 TEST(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 
265 TEST(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 
302 TEST(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 
339 TEST(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 
381 TEST(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 
412 TEST(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 
443 TEST(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 
471 TEST(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 
482 TEST(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 
503 TEST(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 
523 TEST(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 
535 TEST(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 
554 TEST(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 
574 TEST(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 
591 TEST(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 
614 TEST(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 
632 TEST(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 
647 TEST(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 
682 TEST(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 
771 TEST_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 }
gem5::Globals
Container for serializing global variables (not associated with any serialized object).
Definition: globals.hh:54
TEST
TEST(LoaderSymtabTest, EmptyConstruction)
Test that the constructor creates an empty table.
Definition: symtab.test.cc:127
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
TEST_F
TEST_F(LoaderSymtabSerializationFixture, Serialization)
Test serialization.
Definition: symtab.test.cc:717
gem5::mask
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Definition: bitfield.hh:63
checkTable
::testing::AssertionResult checkTable(const Loader::SymbolTable &symtab, const std::initializer_list< Loader::Symbol > &expected)
Checks that a symbol table contains only the expected symbols.
Definition: symtab.test.cc:104
gem5::MipsISA::scs
Bitfield< 18 > scs
Definition: mt_constants.hh:70
checkSymbol
::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.
Definition: symtab.test.cc:85
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
ss
std::stringstream ss
Definition: trace.test.cc:45
gem5::SerializationFixture
Fixture class that handles temporary directory creation.
Definition: serialization_fixture.hh:52
serialization_fixture.hh
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
name
const std::string & name()
Definition: trace.cc:49
getSymbolError
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.
Definition: symtab.test.cc:51
symtab.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::Serializable::ScopedCheckpointSection
Definition: serialize.hh:172
expected
std::vector< SwitchingFiber * > expected({ &a, &b, &a, &a, &a, &b, &c, &a, &c, &c, &c })
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
error
std::string error
Definition: remote_gdb.cc:210

Generated on Sat Jun 18 2022 08:12:19 for gem5 by doxygen 1.8.17