| 1 | //===-- SymbolTest.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 "lldb/Symbol/Symbol.h" |
| 10 | #include "lldb/Core/DataFileCache.h" |
| 11 | #include "lldb/Core/Section.h" |
| 12 | #include "lldb/Utility/DataEncoder.h" |
| 13 | #include "lldb/Utility/DataExtractor.h" |
| 14 | |
| 15 | #include "gtest/gtest.h" |
| 16 | |
| 17 | using namespace lldb; |
| 18 | using namespace lldb_private; |
| 19 | |
| 20 | static void EncodeDecode(const Symbol &object, const SectionList *sect_list, |
| 21 | ByteOrder byte_order) { |
| 22 | const uint8_t addr_size = 8; |
| 23 | DataEncoder file(byte_order, addr_size); |
| 24 | DataEncoder strtab_encoder(byte_order, addr_size); |
| 25 | ConstStringTable const_strtab; |
| 26 | object.Encode(encoder&: file, strtab&: const_strtab); |
| 27 | llvm::ArrayRef<uint8_t> bytes = file.GetData(); |
| 28 | DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size); |
| 29 | |
| 30 | const_strtab.Encode(encoder&: strtab_encoder); |
| 31 | llvm::ArrayRef<uint8_t> strtab_bytes = strtab_encoder.GetData(); |
| 32 | DataExtractor strtab_data(strtab_bytes.data(), strtab_bytes.size(), |
| 33 | byte_order, addr_size); |
| 34 | StringTableReader strtab_reader; |
| 35 | offset_t strtab_data_offset = 0; |
| 36 | ASSERT_EQ(strtab_reader.Decode(strtab_data, &strtab_data_offset), true); |
| 37 | |
| 38 | Symbol decoded_object; |
| 39 | offset_t data_offset = 0; |
| 40 | decoded_object.Decode(data, offset_ptr: &data_offset, section_list: sect_list, strtab: strtab_reader); |
| 41 | EXPECT_EQ(object, decoded_object); |
| 42 | } |
| 43 | |
| 44 | static void EncodeDecode(const Symbol &object, const SectionList *sect_list) { |
| 45 | EncodeDecode(object, sect_list, byte_order: eByteOrderLittle); |
| 46 | EncodeDecode(object, sect_list, byte_order: eByteOrderBig); |
| 47 | } |
| 48 | |
| 49 | TEST(SymbolTest, EncodeDecodeSymbol) { |
| 50 | |
| 51 | SectionSP sect_sp(new Section( |
| 52 | /*module_sp=*/ModuleSP(), |
| 53 | /*obj_file=*/nullptr, |
| 54 | /*sect_id=*/1, |
| 55 | /*name=*/ConstString(".text" ), |
| 56 | /*sect_type=*/eSectionTypeCode, |
| 57 | /*file_vm_addr=*/0x1000, |
| 58 | /*vm_size=*/0x1000, |
| 59 | /*file_offset=*/0, |
| 60 | /*file_size=*/0, |
| 61 | /*log2align=*/5, |
| 62 | /*flags=*/0x10203040)); |
| 63 | |
| 64 | SectionList sect_list; |
| 65 | sect_list.AddSection(section_sp: sect_sp); |
| 66 | |
| 67 | Symbol symbol( |
| 68 | /*symID=*/0x10203040, |
| 69 | /*name=*/"main" , |
| 70 | /*type=*/eSymbolTypeCode, |
| 71 | /*bool external=*/false, |
| 72 | /*bool is_debug=*/false, |
| 73 | /*bool is_trampoline=*/false, |
| 74 | /*bool is_artificial=*/false, |
| 75 | /*section_sp=*/sect_sp, |
| 76 | /*offset=*/0x0, |
| 77 | /*size=*/0x100, |
| 78 | /*size_is_valid=*/true, |
| 79 | /*contains_linker_annotations=*/false, |
| 80 | /*flags=*/0x11223344); |
| 81 | |
| 82 | // Test encoding a symbol with an address. |
| 83 | EncodeDecode(object: symbol, sect_list: §_list); |
| 84 | |
| 85 | // Test that encoding the bits in the bitfield works for all endianness |
| 86 | // combos. |
| 87 | |
| 88 | // Test Symbol.m_is_synthetic |
| 89 | symbol.SetIsSynthetic(true); |
| 90 | EncodeDecode(object: symbol, sect_list: §_list); |
| 91 | symbol.SetIsSynthetic(false); |
| 92 | |
| 93 | // Test Symbol.m_is_debug |
| 94 | symbol.SetDebug(true); |
| 95 | EncodeDecode(object: symbol, sect_list: §_list); |
| 96 | symbol.SetDebug(false); |
| 97 | |
| 98 | // Test Symbol.m_is_external |
| 99 | symbol.SetExternal(true); |
| 100 | EncodeDecode(object: symbol, sect_list: §_list); |
| 101 | symbol.SetExternal(false); |
| 102 | |
| 103 | // Test Symbol.m_size_is_sibling |
| 104 | symbol.SetSizeIsSibling(true); |
| 105 | EncodeDecode(object: symbol, sect_list: §_list); |
| 106 | symbol.SetSizeIsSibling(false); |
| 107 | |
| 108 | // Test Symbol.m_size_is_synthesized |
| 109 | symbol.SetSizeIsSynthesized(true); |
| 110 | EncodeDecode(object: symbol, sect_list: §_list); |
| 111 | symbol.SetSizeIsSynthesized(false); |
| 112 | |
| 113 | // Test Symbol.m_size_is_synthesized |
| 114 | symbol.SetByteSize(0); |
| 115 | EncodeDecode(object: symbol, sect_list: §_list); |
| 116 | symbol.SetByteSize(0x100); |
| 117 | |
| 118 | // Test Symbol.m_demangled_is_synthesized |
| 119 | symbol.SetDemangledNameIsSynthesized(true); |
| 120 | EncodeDecode(object: symbol, sect_list: §_list); |
| 121 | symbol.SetDemangledNameIsSynthesized(false); |
| 122 | |
| 123 | // Test Symbol.m_contains_linker_annotations |
| 124 | symbol.SetContainsLinkerAnnotations(true); |
| 125 | EncodeDecode(object: symbol, sect_list: §_list); |
| 126 | symbol.SetContainsLinkerAnnotations(false); |
| 127 | |
| 128 | // Test Symbol.m_is_weak |
| 129 | symbol.SetIsWeak(true); |
| 130 | EncodeDecode(object: symbol, sect_list: §_list); |
| 131 | symbol.SetIsWeak(false); |
| 132 | |
| 133 | // Test encoding a symbol with no address. |
| 134 | symbol.GetAddressRef().SetSection(SectionSP()); |
| 135 | EncodeDecode(object: symbol, sect_list: §_list); |
| 136 | } |
| 137 | |