Files
RedBear-OS/local/recipes/dev/libclc/source/lldb/unittests/Symbol/SymtabTest.cpp
T
vasilito cb424d7448 build: static patch-sanity linter (shift-left the malformed-patch class)
verify-patch-sanity.py validates every active recipe .patch has internally-
consistent hunk line counts — catching the 'malformed patch at line N' failure
at commit/CI/preflight time instead of hours into a cook. This cycle hit that
class three times (qtwaylandscanner, sddm, xwayland), each only discovered when
cookbook tried to apply the patch.

Running it across the repo found 29 latent malformed patches (validated against
GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22').
They were harmless only because they sit in vendored recipes (baked, not re-
applied) — but would fail on any version-bump re-derivation. --fix recounts the
hunk headers (body untouched) and repaired all 29.

Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test
(test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats
(empty placeholders, bare-@@ git hunks).
2026-08-01 05:13:02 +03:00

838 lines
26 KiB
C++

//===-- SymbolTest.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
#include "Plugins/SymbolFile/Symtab/SymbolFileSymtab.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Core/DataFileCache.h"
#include "lldb/Core/Module.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/DataExtractor.h"
#include <memory>
#include "gtest/gtest.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::plugin::dwarf;
class SymtabTest : public testing::Test {
SubsystemRAII<FileSystem, HostInfo, ObjectFileMachO, SymbolFileDWARF,
ObjectFileELF, SymbolFileSymtab, TypeSystemClang>
subsystem;
};
static void EncodeDecode(const Symtab &object, ByteOrder byte_order) {
const uint8_t addr_size = 8;
DataEncoder file(byte_order, addr_size);
object.Encode(file);
llvm::ArrayRef<uint8_t> bytes = file.GetData();
DataExtractor data(bytes.data(), bytes.size(), byte_order, addr_size);
Symtab decoded_object(object.GetObjectFile());
offset_t data_offset = 0;
bool uuid_mismatch = false;
decoded_object.Decode(data, &data_offset, uuid_mismatch);
ASSERT_EQ(object.GetNumSymbols(), decoded_object.GetNumSymbols());
for (size_t i = 0; i < object.GetNumSymbols(); ++i)
EXPECT_EQ(*object.SymbolAtIndex(i), *decoded_object.SymbolAtIndex(i));
}
static void EncodeDecode(const Symtab &object) {
EncodeDecode(object, eByteOrderLittle);
EncodeDecode(object, eByteOrderBig);
}
TEST_F(SymtabTest, EncodeDecodeSymtab) {
auto ExpectedFile = TestFile::fromYaml(R"(
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x100000C
cpusubtype: 0x0
filetype: 0x2
ncmds: 17
sizeofcmds: 792
flags: 0x200085
reserved: 0x0
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __PAGEZERO
vmaddr: 0
vmsize: 4294967296
fileoff: 0
filesize: 0
maxprot: 0
initprot: 0
nsects: 0
flags: 0
- cmd: LC_SEGMENT_64
cmdsize: 232
segname: __TEXT
vmaddr: 4294967296
vmsize: 16384
fileoff: 0
filesize: 16384
maxprot: 5
initprot: 5
nsects: 2
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x100003F94
size: 36
offset: 0x3F94
align: 2
reloff: 0x0
nreloc: 0
flags: 0x80000400
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: FF8300D1E80300AA00008052FF1F00B9E81B00B9E10B00F9E20700F9FF830091C0035FD6
- sectname: __unwind_info
segname: __TEXT
addr: 0x100003FB8
size: 72
offset: 0x3FB8
align: 2
reloff: 0x0
nreloc: 0
flags: 0x0
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: 010000001C000000000000001C000000000000001C00000002000000943F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000200002
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __LINKEDIT
vmaddr: 4294983680
vmsize: 16384
fileoff: 16384
filesize: 674
maxprot: 1
initprot: 1
nsects: 0
flags: 0
- cmd: LC_DYLD_CHAINED_FIXUPS
cmdsize: 16
dataoff: 16384
datasize: 56
- cmd: LC_DYLD_EXPORTS_TRIE
cmdsize: 16
dataoff: 16440
datasize: 48
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 16496
nsyms: 10
stroff: 16656
strsize: 128
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 8
iextdefsym: 8
nextdefsym: 2
iundefsym: 10
nundefsym: 0
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
- cmd: LC_LOAD_DYLINKER
cmdsize: 32
name: 12
Content: '/usr/lib/dyld'
ZeroPadBytes: 7
- cmd: LC_UUID
cmdsize: 24
uuid: 1EECD2B8-16EA-3FEC-AB3C-F46139DBD0E2
- cmd: LC_BUILD_VERSION
cmdsize: 32
platform: 1
minos: 786432
sdk: 786432
ntools: 1
Tools:
- tool: 3
version: 46596096
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
- cmd: LC_MAIN
cmdsize: 24
entryoff: 16276
stacksize: 0
- cmd: LC_LOAD_DYLIB
cmdsize: 48
dylib:
name: 24
timestamp: 2
current_version: 78643968
compatibility_version: 65536
Content: '/usr/lib/libc++.1.dylib'
ZeroPadBytes: 1
- cmd: LC_LOAD_DYLIB
cmdsize: 56
dylib:
name: 24
timestamp: 2
current_version: 85917696
compatibility_version: 65536
Content: '/usr/lib/libSystem.B.dylib'
ZeroPadBytes: 6
- cmd: LC_FUNCTION_STARTS
cmdsize: 16
dataoff: 16488
datasize: 8
- cmd: LC_DATA_IN_CODE
cmdsize: 16
dataoff: 16496
datasize: 0
- cmd: LC_CODE_SIGNATURE
cmdsize: 16
dataoff: 16784
datasize: 274
LinkEditData:
NameList:
- n_strx: 28
n_type: 0x64
n_sect: 0
n_desc: 0
n_value: 0
- n_strx: 64
n_type: 0x64
n_sect: 0
n_desc: 0
n_value: 0
- n_strx: 73
n_type: 0x66
n_sect: 0
n_desc: 1
n_value: 1639532873
- n_strx: 1
n_type: 0x2E
n_sect: 1
n_desc: 0
n_value: 4294983572
- n_strx: 115
n_type: 0x24
n_sect: 1
n_desc: 0
n_value: 4294983572
- n_strx: 1
n_type: 0x24
n_sect: 0
n_desc: 0
n_value: 36
- n_strx: 1
n_type: 0x4E
n_sect: 1
n_desc: 0
n_value: 36
- n_strx: 1
n_type: 0x64
n_sect: 1
n_desc: 0
n_value: 0
- n_strx: 2
n_type: 0xF
n_sect: 1
n_desc: 16
n_value: 4294967296
- n_strx: 22
n_type: 0xF
n_sect: 1
n_desc: 0
n_value: 4294983572
StringTable:
- ' '
- __mh_execute_header
- _main
- '/Users/gclayton/Documents/src/args/'
- main.cpp
- '/Users/gclayton/Documents/src/args/main.o'
- _main
- ''
- ''
- ''
- ''
- ''
- ''
- ''
...
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
ObjectFile *objfile = module_sp->GetObjectFile();
ASSERT_NE(objfile, nullptr);
// Test encoding and decoding an empty symbol table.
Symtab symtab(objfile);
symtab.PreloadSymbols();
EncodeDecode(symtab);
// Now encode and decode an actual symbol table from our yaml.
Symtab *module_symtab = module_sp->GetSymtab();
ASSERT_NE(module_symtab, nullptr);
module_symtab->PreloadSymbols();
EncodeDecode(*module_symtab);
}
TEST_F(SymtabTest, TestDecodeCStringMaps) {
// Symbol tables save out the symbols, but they also save out the symbol table
// name indexes. These name indexes are a map of sorted ConstString + T pairs
// and when they are decoded from a file, they are no longer sorted since
// ConstString objects can be sorted by "const char *" and the order in which
// these strings are created won't be the same in a new process. We need to
// ensure these name lookups happen correctly when we load the name indexes,
// so this test loads a symbol table from a cache file from
// "lldb/unittests/Symbol/Inputs/indexnames-symtab-cache" and make sure we
// can correctly lookup each of the names in the symbol table.
auto ExpectedFile = TestFile::fromYaml(R"(
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x100000C
cpusubtype: 0x0
filetype: 0x2
ncmds: 16
sizeofcmds: 744
flags: 0x200085
reserved: 0x0
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __PAGEZERO
vmaddr: 0
vmsize: 4294967296
fileoff: 0
filesize: 0
maxprot: 0
initprot: 0
nsects: 0
flags: 0
- cmd: LC_SEGMENT_64
cmdsize: 232
segname: __TEXT
vmaddr: 4294967296
vmsize: 16384
fileoff: 0
filesize: 16384
maxprot: 5
initprot: 5
nsects: 2
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x100003F64
size: 76
offset: 0x3F64
align: 2
reloff: 0x0
nreloc: 0
flags: 0x80000400
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: 80018052C0035FD6E0028052C0035FD640048052C0035FD6FF8300D1FD7B01A9FD43009108008052E80B00B9BFC31FB8F4FFFF97F5FFFF97F6FFFF97E00B40B9FD7B41A9FF830091C0035FD6
- sectname: __unwind_info
segname: __TEXT
addr: 0x100003FB0
size: 80
offset: 0x3FB0
align: 2
reloff: 0x0
nreloc: 0
flags: 0x0
reserved1: 0x0
reserved2: 0x0
reserved3: 0x0
content: 010000001C000000000000001C000000000000001C00000002000000643F00003400000034000000B13F00000000000034000000030000000C0002001400020000000001180000000000000400000002
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __LINKEDIT
vmaddr: 4294983680
vmsize: 16384
fileoff: 16384
filesize: 994
maxprot: 1
initprot: 1
nsects: 0
flags: 0
- cmd: LC_DYLD_CHAINED_FIXUPS
cmdsize: 16
dataoff: 16384
datasize: 56
- cmd: LC_DYLD_EXPORTS_TRIE
cmdsize: 16
dataoff: 16440
datasize: 80
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 16528
nsyms: 25
stroff: 16928
strsize: 176
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 20
iextdefsym: 20
nextdefsym: 5
iundefsym: 25
nundefsym: 0
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
- cmd: LC_LOAD_DYLINKER
cmdsize: 32
name: 12
Content: '/usr/lib/dyld'
ZeroPadBytes: 7
- cmd: LC_UUID
cmdsize: 24
uuid: 3E94866E-0D1A-39BD-975B-64E8F1FDBAAE
- cmd: LC_BUILD_VERSION
cmdsize: 32
platform: 1
minos: 786432
sdk: 787200
ntools: 1
Tools:
- tool: 3
version: 49938432
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
- cmd: LC_MAIN
cmdsize: 24
entryoff: 16252
stacksize: 0
- cmd: LC_LOAD_DYLIB
cmdsize: 56
dylib:
name: 24
timestamp: 2
current_version: 85943299
compatibility_version: 65536
Content: '/usr/lib/libSystem.B.dylib'
ZeroPadBytes: 6
- cmd: LC_FUNCTION_STARTS
cmdsize: 16
dataoff: 16520
datasize: 8
- cmd: LC_DATA_IN_CODE
cmdsize: 16
dataoff: 16528
datasize: 0
- cmd: LC_CODE_SIGNATURE
cmdsize: 16
dataoff: 17104
datasize: 274
LinkEditData:
NameList:
- n_strx: 43
n_type: 0x64
n_sect: 0
n_desc: 0
n_value: 0
- n_strx: 91
n_type: 0x64
n_sect: 0
n_desc: 0
n_value: 0
- n_strx: 98
n_type: 0x66
n_sect: 0
n_desc: 1
n_value: 1651098491
- n_strx: 1
n_type: 0x2E
n_sect: 1
n_desc: 0
n_value: 4294983524
- n_strx: 152
n_type: 0x24
n_sect: 1
n_desc: 0
n_value: 4294983524
- n_strx: 1
n_type: 0x24
n_sect: 0
n_desc: 0
n_value: 8
- n_strx: 1
n_type: 0x4E
n_sect: 1
n_desc: 0
n_value: 8
- n_strx: 1
n_type: 0x2E
n_sect: 1
n_desc: 0
n_value: 4294983532
- n_strx: 157
n_type: 0x24
n_sect: 1
n_desc: 0
n_value: 4294983532
- n_strx: 1
n_type: 0x24
n_sect: 0
n_desc: 0
n_value: 8
- n_strx: 1
n_type: 0x4E
n_sect: 1
n_desc: 0
n_value: 8
- n_strx: 1
n_type: 0x2E
n_sect: 1
n_desc: 0
n_value: 4294983540
- n_strx: 162
n_type: 0x24
n_sect: 1
n_desc: 0
n_value: 4294983540
- n_strx: 1
n_type: 0x24
n_sect: 0
n_desc: 0
n_value: 8
- n_strx: 1
n_type: 0x4E
n_sect: 1
n_desc: 0
n_value: 8
- n_strx: 1
n_type: 0x2E
n_sect: 1
n_desc: 0
n_value: 4294983548
- n_strx: 167
n_type: 0x24
n_sect: 1
n_desc: 0
n_value: 4294983548
- n_strx: 1
n_type: 0x24
n_sect: 0
n_desc: 0
n_value: 52
- n_strx: 1
n_type: 0x4E
n_sect: 1
n_desc: 0
n_value: 52
- n_strx: 1
n_type: 0x64
n_sect: 1
n_desc: 0
n_value: 0
- n_strx: 2
n_type: 0xF
n_sect: 1
n_desc: 16
n_value: 4294967296
- n_strx: 22
n_type: 0xF
n_sect: 1
n_desc: 0
n_value: 4294983532
- n_strx: 27
n_type: 0xF
n_sect: 1
n_desc: 0
n_value: 4294983540
- n_strx: 32
n_type: 0xF
n_sect: 1
n_desc: 0
n_value: 4294983524
- n_strx: 37
n_type: 0xF
n_sect: 1
n_desc: 0
n_value: 4294983548
StringTable:
- ' '
- __mh_execute_header
- _bar
- _baz
- _foo
- _main
- '/Users/gclayton/Documents/objfiles/index-names/'
- main.c
- '/Users/gclayton/Documents/objfiles/index-names/main.o'
- _foo
- _bar
- _baz
- _main
- ''
- ''
- ''
FunctionStarts: [ 0x3F64, 0x3F6C, 0x3F74, 0x3F7C ]
...
)");
// This data was taken from a hex dump of the object file from the above yaml
// and hexdumped so we can load the cache data in this test.
const uint8_t symtab_cache_bytes[] = {
0x01, 0x10, 0x3e, 0x94, 0x86, 0x6e, 0x0d, 0x1a,
0x39, 0xbd, 0x97, 0x5b, 0x64, 0xe8, 0xf1, 0xfd,
0xba, 0xae, 0xff, 0x53, 0x54, 0x41, 0x42, 0x91,
0x00, 0x00, 0x00, 0x00, 0x2f, 0x55, 0x73, 0x65,
0x72, 0x73, 0x2f, 0x67, 0x63, 0x6c, 0x61, 0x79,
0x74, 0x6f, 0x6e, 0x2f, 0x44, 0x6f, 0x63, 0x75,
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x6f, 0x62,
0x6a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x69,
0x6e, 0x64, 0x65, 0x78, 0x2d, 0x6e, 0x61, 0x6d,
0x65, 0x73, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e,
0x63, 0x00, 0x2f, 0x55, 0x73, 0x65, 0x72, 0x73,
0x2f, 0x67, 0x63, 0x6c, 0x61, 0x79, 0x74, 0x6f,
0x6e, 0x2f, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65,
0x6e, 0x74, 0x73, 0x2f, 0x6f, 0x62, 0x6a, 0x66,
0x69, 0x6c, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x6f, 0x00,
0x66, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00,
0x62, 0x61, 0x7a, 0x00, 0x6d, 0x61, 0x69, 0x6e,
0x00, 0x5f, 0x6d, 0x68, 0x5f, 0x65, 0x78, 0x65,
0x63, 0x75, 0x74, 0x65, 0x5f, 0x68, 0x65, 0x61,
0x64, 0x65, 0x72, 0x00, 0x53, 0x59, 0x4d, 0x42,
0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x2a,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x64, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0a, 0x20, 0x01, 0x37, 0x00, 0x00, 0x00, 0x00,
0x7b, 0xc3, 0x69, 0x62, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x66, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x32, 0x01, 0x6d, 0x00, 0x00,
0x00, 0x01, 0x64, 0x3f, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x32, 0x01, 0x71,
0x00, 0x00, 0x00, 0x01, 0x6c, 0x3f, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x32,
0x01, 0x75, 0x00, 0x00, 0x00, 0x01, 0x74, 0x3f,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0f, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x32, 0x01, 0x79, 0x00, 0x00, 0x00, 0x01,
0x7c, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x12, 0x02, 0x7e, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x64, 0x3f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x01, 0x00,
0x43, 0x4d, 0x41, 0x50, 0x07, 0x00, 0x00, 0x00,
0x6d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x75, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x71, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x7e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00
};
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
ObjectFile *objfile = module_sp->GetObjectFile();
ASSERT_NE(objfile, nullptr);
// Test encoding and decoding an empty symbol table.
DataExtractor data(symtab_cache_bytes, sizeof(symtab_cache_bytes),
eByteOrderLittle, 8);
Symtab symtab(objfile);
offset_t data_offset = 0;
bool uuid_mismatch = false; // Gets set to true if signature doesn't match.
const bool success = symtab.Decode(data, &data_offset, uuid_mismatch);
ASSERT_EQ(success, true);
ASSERT_EQ(uuid_mismatch, false);
// Now make sure that name lookup works for all symbols. This indicates that
// the Symtab::NameToIndexMap was decoded correctly and works as expected.
Symbol *symbol = nullptr;
symbol = symtab.FindFirstSymbolWithNameAndType(ConstString("main"),
eSymbolTypeCode,
Symtab::eDebugAny,
Symtab::eVisibilityAny);
ASSERT_NE(symbol, nullptr);
symbol = symtab.FindFirstSymbolWithNameAndType(ConstString("foo"),
eSymbolTypeCode,
Symtab::eDebugAny,
Symtab::eVisibilityAny);
ASSERT_NE(symbol, nullptr);
symbol = symtab.FindFirstSymbolWithNameAndType(ConstString("bar"),
eSymbolTypeCode,
Symtab::eDebugAny,
Symtab::eVisibilityAny);
ASSERT_NE(symbol, nullptr);
symbol = symtab.FindFirstSymbolWithNameAndType(ConstString("baz"),
eSymbolTypeCode,
Symtab::eDebugAny,
Symtab::eVisibilityAny);
ASSERT_NE(symbol, nullptr);
}
TEST_F(SymtabTest, TestSymbolFileCreatedOnDemand) {
auto ExpectedFile = TestFile::fromYaml(R"(
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Entry: 0x0000000000400180
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
Address: 0x0000000000400180
AddressAlign: 0x0000000000000010
Content: 554889E58B042500106000890425041060005DC3
Symbols:
- Name: _start
Type: STT_FUNC
Section: .text
Value: 0x0000000000400180
Size: 0x0000000000000014
Binding: STB_GLOBAL
...
)");
ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded());
auto module_sp = std::make_shared<Module>(ExpectedFile->moduleSpec());
// The symbol file should not be created by default.
Symtab *module_symtab = module_sp->GetSymtab(/*can_create=*/false);
ASSERT_EQ(module_symtab, nullptr);
// But it should be created on demand.
module_symtab = module_sp->GetSymtab(/*can_create=*/true);
ASSERT_NE(module_symtab, nullptr);
// And we should be able to get it again once it has been created.
Symtab *cached_module_symtab = module_sp->GetSymtab(/*can_create=*/false);
ASSERT_EQ(module_symtab, cached_module_symtab);
}
TEST_F(SymtabTest, TestSymbolTableCreatedOnDemand) {
const char *yamldata = R"(
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_386
DWARF:
debug_abbrev:
- Table:
- Code: 0x00000001
Tag: DW_TAG_compile_unit
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_addr_base
Form: DW_FORM_sec_offset
debug_info:
- Version: 5
AddrSize: 4
UnitType: DW_UT_compile
Entries:
- AbbrCode: 0x00000001
Values:
- Value: 0x8 # Offset of the first Address past the header
- AbbrCode: 0x0
debug_addr:
- Version: 5
AddressSize: 4
Entries:
- Address: 0x1234
- Address: 0x5678
debug_line:
- Length: 42
Version: 2
PrologueLength: 36
MinInstLength: 1
DefaultIsStmt: 1
LineBase: 251
LineRange: 14
OpcodeBase: 13
StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ]
IncludeDirs:
- '/tmp'
Files:
- Name: main.cpp
DirIdx: 1
ModTime: 0
Length: 0
)";
llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
EXPECT_THAT_EXPECTED(file, llvm::Succeeded());
auto module_sp = std::make_shared<Module>(file->moduleSpec());
SymbolFile *symbol_file = module_sp->GetSymbolFile();
// At this point, the symbol table is not created. This is because the above
// yaml data contains the necessary sections in order for
// SymbolFileDWARF::CalculateAbilities() to identify all abilities, saving it
// from calling SymbolFileDWARFDebugMap::CalculateAbilities(), which
// eventually loads the symbol table, which we don't want.
// The symbol table should not be created if asked not to.
Symtab *symtab = symbol_file->GetSymtab(/*can_create=*/false);
ASSERT_EQ(symtab, nullptr);
// But it should be created on demand.
symtab = symbol_file->GetSymtab(/*can_create=*/true);
ASSERT_NE(symtab, nullptr);
// And we should be able to get it again once it has been created.
Symtab *cached_symtab = symbol_file->GetSymtab(/*can_create=*/false);
ASSERT_EQ(symtab, cached_symtab);
}