1 //===-- ObjectFileMachOTest.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Host/HostInfo.h"
10 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
11 #include "TestingSupport/SubsystemRAII.h"
12 #include "TestingSupport/TestUtilities.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Host/FileSystem.h"
15 #include "lldb/lldb-defines.h"
16 #include "gtest/gtest.h"
22 using namespace lldb_private
;
26 class ObjectFileMachOTest
: public ::testing::Test
{
27 SubsystemRAII
<FileSystem
, HostInfo
, ObjectFileMachO
> subsystems
;
31 #if defined(__APPLE__)
32 TEST_F(ObjectFileMachOTest
, ModuleFromSharedCacheInfo
) {
33 SharedCacheImageInfo image_info
=
34 HostInfo::GetSharedCacheImageInfo("/usr/lib/libobjc.A.dylib");
35 EXPECT_TRUE(image_info
.uuid
);
36 EXPECT_TRUE(image_info
.data_sp
);
38 ModuleSpec
spec(FileSpec(), UUID(), image_info
.data_sp
);
39 lldb::ModuleSP module
= std::make_shared
<Module
>(spec
);
40 ObjectFile
*OF
= module
->GetObjectFile();
41 ASSERT_TRUE(llvm::isa
<ObjectFileMachO
>(OF
));
43 OF
->GetArchitecture().IsCompatibleMatch(HostInfo::GetArchitecture()));
44 Symtab
*symtab
= OF
->GetSymtab();
45 ASSERT_NE(symtab
, nullptr);
46 void *libobjc
= dlopen("/usr/lib/libobjc.A.dylib", RTLD_LAZY
);
47 ASSERT_NE(libobjc
, nullptr);
49 // This function checks that if we read something from the
50 // ObjectFile we get through the shared cache in-mmeory
51 // buffer, it matches what we get by reading directly the
52 // memory of the symbol.
53 auto check_symbol
= [&](const char *sym_name
) {
54 std::vector
<uint32_t> symbol_indices
;
55 symtab
->FindAllSymbolsWithNameAndType(ConstString(sym_name
),
56 lldb::eSymbolTypeAny
, symbol_indices
);
57 EXPECT_EQ(symbol_indices
.size(), 1u);
59 Symbol
*sym
= symtab
->SymbolAtIndex(symbol_indices
[0]);
60 ASSERT_NE(sym
, nullptr);
61 Address base
= sym
->GetAddress();
62 size_t size
= sym
->GetByteSize();
65 EXPECT_EQ(OF
->ReadSectionData(base
.GetSection().get(), base
.GetOffset(),
69 void *sym_addr
= dlsym(libobjc
, sym_name
);
70 ASSERT_NE(sym_addr
, nullptr);
71 EXPECT_EQ(memcmp(buffer
, sym_addr
, size
), 0);
74 // Read a symbol from the __TEXT segment...
75 check_symbol("objc_msgSend");
76 // ... and one from the __DATA segment
77 check_symbol("OBJC_CLASS_$_NSObject");
80 TEST_F(ObjectFileMachOTest
, IndirectSymbolsInTheSharedCache
) {
81 SharedCacheImageInfo image_info
= HostInfo::GetSharedCacheImageInfo(
82 "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit");
83 ModuleSpec
spec(FileSpec(), UUID(), image_info
.data_sp
);
84 lldb::ModuleSP module
= std::make_shared
<Module
>(spec
);
86 ObjectFile
*OF
= module
->GetObjectFile();
87 ASSERT_TRUE(llvm::isa
<ObjectFileMachO
>(OF
));
89 OF
->GetArchitecture().IsCompatibleMatch(HostInfo::GetArchitecture()));
91 // Check that we can parse the symbol table several times over without
94 for (size_t i
= 0; i
< 10; i
++)
95 OF
->ParseSymtab(symtab
);