diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 7594734e4946a..20e2d87ad252c 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -387,6 +387,15 @@ class SymbolFile : public PluginInterface { /// for this module have been changed. virtual void SectionFileAddressesChanged() = 0; + /// Looks for the compile option specified by \p option, and sets \p value to + /// it's value. For example, for a flag such as -foo=bar, looking up \p option + /// "-foo" will set \p value to "bar". For a standalone flag such as -baz, \p + /// value will be empty. + /// + /// If \p cu is set, only that compile unit is searched. Otherwise, every + /// compile unit is searched until the option is found or failure. + /// + /// Returns true if the option is found. virtual bool GetCompileOption(const char *option, std::string &value, CompileUnit *cu = nullptr) { value.clear(); diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index e0d30c2027b7c..dadd6d267bcf6 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -1204,11 +1204,14 @@ class Target : public std::enable_shared_from_this, // 2 - if there is a process, then read from memory // 3 - if there is no process, then read from the file cache // + // The optional did_read_live_memory parameter will be set true if live memory + // was read successfully. + // // The method is virtual for mocking in the unit tests. virtual size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory = false, - lldb::addr_t *load_addr_ptr = nullptr); - + lldb::addr_t *load_addr_ptr = nullptr, + bool *did_read_live_memory = nullptr); size_t ReadCStringFromMemory(const Address &addr, std::string &out_str, Status &error, bool force_live_memory = false); diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index 7914dbd565463..02e366c789f93 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -358,12 +358,12 @@ class LLDBExprNameLookup : public LLDBNameLookup { swift::Identifier getPreferredPrivateDiscriminator() override { if (m_sc.comp_unit) { if (lldb_private::Module *module = m_sc.module_sp.get()) { - if (lldb_private::SymbolFile *symbol_file = - module->GetSymbolFile()) { + if (lldb_private::SymbolFile *symbol_file = module->GetSymbolFile()) { std::string private_discriminator_string; if (symbol_file->GetCompileOption("-private-discriminator", - private_discriminator_string, - m_sc.comp_unit)) { + private_discriminator_string, + m_sc.comp_unit) && + !private_discriminator_string.empty()) { return m_source_file.getASTContext().getIdentifier( private_discriminator_string); } diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp index 5ad007bb22b70..ecf7f3a4caf9f 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp @@ -32,11 +32,6 @@ bool LLDBMemoryReader::queryDataLayout(DataLayoutQueryType type, void *inBuffer, return false; // The mask returned by the process masks out the non-addressable bits. uint64_t mask_pattern = ~ptrauth_mask; - // LLDBMemoryReader sets LLDB_FILE_ADDRESS_BIT to distinguish process - // addresses and file addresses that point into a reflection section on - // disk. Setting the bit in the mask ensures it isn't accidentally cleared - // by ptrauth stripping. - mask_pattern |= LLDB_FILE_ADDRESS_BIT; memcpy(outBuffer, &mask_pattern, m_process.GetAddressByteSize()); return true; } @@ -181,8 +176,7 @@ LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) { if (!target.GetSwiftUseReflectionSymbols()) return {}; - std::optional
maybeAddr = - resolveRemoteAddress(address.getRawAddress()); + std::optional
maybeAddr = remoteAddressToLLDBAddress(address); // This is not an assert, but should never happen. if (!maybeAddr) return {}; @@ -234,8 +228,12 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address, swift::remote::RemoteAddress{ readValue, swift::remote::RemoteAddress::DefaultAddressSpace}}; - if (!readMetadataFromFileCacheEnabled()) + if (!readMetadataFromFileCacheEnabled()) { + assert(address.getAddressSpace() == + swift::remote::RemoteAddress::DefaultAddressSpace && + "Unexpected address space!"); return process_pointer; + } // Try to strip the pointer before checking if we have it mapped. auto strippedPointer = signedPointerStripper(process_pointer); @@ -271,10 +269,10 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address, } // If the containing image is the first registered one, the image's tagged - // start address for it is the first tagged address. Otherwise, the previous - // pair's address is the start tagged address. + // start address for it is zero. Otherwise, the previous pair's address is the + // start of the new address. uint64_t start_tagged_address = pair_iterator == m_range_module_map.begin() - ? LLDB_FILE_ADDRESS_BIT + ? 0 : std::prev(pair_iterator)->first; auto *section_list = module_containing_pointer->GetSectionList(); @@ -298,8 +296,7 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address, } swift::remote::RemoteAbsolutePointer tagged_pointer{ - swift::remote::RemoteAddress{ - tagged_address, swift::remote::RemoteAddress::DefaultAddressSpace}}; + swift::remote::RemoteAddress{tagged_address, LLDBAddressSpace}}; if (tagged_address != (uint64_t)signedPointerStripper(tagged_pointer) .getResolvedAddress() @@ -318,6 +315,13 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address, bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address, uint8_t *dest, uint64_t size) { + auto read_bytes_result = readBytesImpl(address, dest, size); + return read_bytes_result != ReadBytesResult::fail; +} + +LLDBMemoryReader::ReadBytesResult +LLDBMemoryReader::readBytesImpl(swift::remote::RemoteAddress address, + uint8_t *dest, uint64_t size) { Log *log = GetLog(LLDBLog::Types); if (m_local_buffer) { bool overflow = false; @@ -326,7 +330,7 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address, if (overflow) { LLDB_LOGV(log, "[MemoryReader] address {0:x} + size {1} overflows", addr, size); - return false; + return ReadBytesResult::fail; } if (addr >= *m_local_buffer && end <= *m_local_buffer + m_local_buffer_size) { @@ -334,22 +338,22 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address, // GetDynamicTypeAndAddress_Protocol() most likely no longer // hold. memcpy(dest, (void *)addr, size); - return true; + return ReadBytesResult::success_from_file; } } LLDB_LOGV(log, "[MemoryReader] asked to read {0} bytes at address {1:x}", size, address.getRawAddress()); std::optional
maybeAddr = - resolveRemoteAddressFromSymbolObjectFile(address.getRawAddress()); + resolveRemoteAddressFromSymbolObjectFile(address); if (!maybeAddr) - maybeAddr = resolveRemoteAddress(address.getRawAddress()); + maybeAddr = remoteAddressToLLDBAddress(address); if (!maybeAddr) { LLDB_LOGV(log, "[MemoryReader] could not resolve address {0:x}", address.getRawAddress()); - return false; + return ReadBytesResult::fail; } auto addr = *maybeAddr; if (addr.IsSectionOffset()) { @@ -358,14 +362,16 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address, if (object_file->GetType() == ObjectFile::Type::eTypeDebugInfo) { LLDB_LOGV(log, "[MemoryReader] Reading memory from symbol rich binary"); - return object_file->ReadSectionData(section.get(), addr.GetOffset(), dest, - size); + if (object_file->ReadSectionData(section.get(), addr.GetOffset(), dest, + size)) + return ReadBytesResult::success_from_file; + return ReadBytesResult::fail; } } if (size > m_max_read_amount) { LLDB_LOGV(log, "[MemoryReader] memory read exceeds maximum allowed size"); - return false; + return ReadBytesResult::fail; } Target &target(m_process.GetTarget()); Status error; @@ -373,15 +379,18 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address, // address to section + offset. const bool force_live_memory = !readMetadataFromFileCacheEnabled() || !addr.IsSectionOffset(); - if (size > target.ReadMemory(addr, dest, size, error, force_live_memory)) { + bool did_read_live_memory = false; + if (size > target.ReadMemory(addr, dest, size, error, force_live_memory, + /*load_addr_ptr=*/nullptr, + &did_read_live_memory)) { LLDB_LOGV(log, "[MemoryReader] memory read returned fewer bytes than asked for"); - return false; + return ReadBytesResult::fail; } if (error.Fail()) { LLDB_LOGV(log, "[MemoryReader] memory read returned error: {0}", error.AsCString()); - return false; + return ReadBytesResult::fail; } auto format_data = [](auto dest, auto size) { @@ -395,7 +404,8 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address, LLDB_LOGV(log, "[MemoryReader] memory read returned data: {0}", format_data(dest, size)); - return true; + return did_read_live_memory ? ReadBytesResult::success_from_memory + : ReadBytesResult::success_from_file; } bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address, @@ -418,10 +428,10 @@ bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address, address.getRawAddress()); std::optional
maybeAddr = - resolveRemoteAddressFromSymbolObjectFile(address.getRawAddress()); + resolveRemoteAddressFromSymbolObjectFile(address); if (!maybeAddr) - maybeAddr = resolveRemoteAddress(address.getRawAddress()); + maybeAddr = remoteAddressToLLDBAddress(address); if (!maybeAddr) { LLDB_LOGV(log, "[MemoryReader] could not resolve address {0:x}", @@ -461,7 +471,7 @@ bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address, MemoryReaderLocalBufferHolder::~MemoryReaderLocalBufferHolder() { if (m_memory_reader) - m_memory_reader->popLocalBuffer(); + m_memory_reader->popLocalBuffer(); } MemoryReaderLocalBufferHolder @@ -490,12 +500,9 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module, "Trying to register symbol object file, but reading from it is " "disabled!"); - // The first available address is the mask, since subsequent images are mapped - // in ascending order, all of them will contain this mask. - uint64_t module_start_address = LLDB_FILE_ADDRESS_BIT; + uint64_t module_start_address = 0; if (!m_range_module_map.empty()) - // We map the images contiguously one after the other, all with the tag bit - // set. + // We map the images contiguously one after the other. // The address that maps the last module is exactly the address the new // module should start at. module_start_address = m_range_module_map.back().first; @@ -541,18 +548,6 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module, auto size = end_file_address - start_file_address; auto module_end_address = module_start_address + size; - if (module_end_address != - signedPointerStripper( - swift::remote::RemoteAbsolutePointer{swift::remote::RemoteAddress{ - module_end_address, - swift::reflection::RemoteAddress::DefaultAddressSpace}}) - .getResolvedAddress() - .getRawAddress()) { - LLDB_LOG(GetLog(LLDBLog::Types), - "[MemoryReader] module to address map ran into pointer " - "authentication mask!"); - return {}; - } // The address for the next image is the next pointer aligned address // available after the end of the current image. uint64_t next_module_start_address = llvm::alignTo(module_end_address, 8); @@ -566,18 +561,18 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module, std::optional> LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress( - uint64_t tagged_address) const { + swift::remote::RemoteAddress tagged_address) const { Log *log(GetLog(LLDBLog::Types)); if (!readMetadataFromFileCacheEnabled()) return {}; - // If the address contains our mask, this is an image we registered. - if (!(tagged_address & LLDB_FILE_ADDRESS_BIT)) + if (tagged_address.getAddressSpace() != LLDBAddressSpace) return {}; // Dummy pair with the address we're looking for. - auto comparison_pair = std::make_pair(tagged_address, ModuleSP()); + auto comparison_pair = + std::make_pair(tagged_address.getRawAddress(), ModuleSP()); // Explicitly compare only the addresses, never the modules in the pairs. auto pair_iterator = std::lower_bound( @@ -589,7 +584,7 @@ LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress( LLDB_LOG(log, "[MemoryReader] Address {0:x} is larger than the upper bound " "address of the mapped in modules", - tagged_address); + tagged_address.getRawAddress()); return {}; } @@ -601,14 +596,13 @@ LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress( } uint64_t file_address; if (pair_iterator == m_range_module_map.begin()) - // Since this is the first registered module, - // clearing the tag bit will give the virtual file address. - file_address = tagged_address & ~LLDB_FILE_ADDRESS_BIT; + file_address = tagged_address.getRawAddress(); else // The end of the previous section is the start of the current one. // We also need to add the first section's file address since we remove it // when constructing the range to module map. - file_address = tagged_address - std::prev(pair_iterator)->first; + file_address = + (tagged_address - std::prev(pair_iterator)->first).getRawAddress(); // We also need to add the module's file address, since we subtract it when // building the range to module map. @@ -616,31 +610,65 @@ LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress( return {{file_address, module}}; } +bool LLDBMemoryReader::readRemoteAddressImpl( + swift::remote::RemoteAddress address, swift::remote::RemoteAddress &out, + std::size_t size) { + assert((size == 4 || size == 8) && + "Only 32 or 64 bit architectures are supported!"); + if (size != 4 && size != 8) + return false; + + uint64_t buf; + auto read_bytes_result = + readBytesImpl(address, reinterpret_cast(&buf), size); + + uint8_t addressSpace; + switch (read_bytes_result) { + case ReadBytesResult::success_from_file: + addressSpace = LLDBAddressSpace; + break; + case ReadBytesResult::success_from_memory: + addressSpace = swift::remote::RemoteAddress::DefaultAddressSpace; + break; + case ReadBytesResult::fail: + return false; + } + ByteOrder byte_order = m_process.GetTarget().GetArchitecture().GetByteOrder(); + uint32_t byte_size = + m_process.GetTarget().GetArchitecture().GetAddressByteSize(); + DataExtractor extractor((const void *)&buf, size, byte_order, byte_size); + lldb::offset_t offset = 0; + auto data = extractor.GetMaxU64(&offset, size); + out = swift::remote::RemoteAddress(data, addressSpace); + return true; +} + std::optional LLDBMemoryReader::resolveRemoteAddress( swift::reflection::RemoteAddress address) const { std::optional
lldb_address = - LLDBMemoryReader::resolveRemoteAddress(address.getRawAddress()); + LLDBMemoryReader::remoteAddressToLLDBAddress(address); if (!lldb_address) return {}; lldb::addr_t addr = lldb_address->GetLoadAddress(&m_process.GetTarget()); if (addr != LLDB_INVALID_ADDRESS) - return swift::reflection::RemoteAddress(addr, swift::reflection::RemoteAddress::DefaultAddressSpace); + return swift::reflection::RemoteAddress( + addr, swift::reflection::RemoteAddress::DefaultAddressSpace); return {}; } -std::optional
-LLDBMemoryReader::resolveRemoteAddress(uint64_t address) const { +std::optional
LLDBMemoryReader::remoteAddressToLLDBAddress( + swift::remote::RemoteAddress address) const { Log *log(GetLog(LLDBLog::Types)); auto maybe_pair = getFileAddressAndModuleForTaggedAddress(address); if (!maybe_pair) - return Address(address); + return Address(address.getRawAddress()); uint64_t file_address = maybe_pair->first; ModuleSP module = maybe_pair->second; if (m_modules_with_metadata_in_symbol_obj_file.count(module)) - return Address(address); + return Address(address.getRawAddress()); auto *object_file = module->GetObjectFile(); if (!object_file) @@ -656,7 +684,7 @@ LLDBMemoryReader::resolveRemoteAddress(uint64_t address) const { LLDB_LOGV(log, "[MemoryReader] Successfully resolved mapped address {0:x} into " "file address {1:x}", - address, resolved.GetFileAddress()); + address.getRawAddress(), resolved.GetFileAddress()); return resolved; } auto *sec_list = module->GetSectionList(); @@ -700,7 +728,7 @@ LLDBMemoryReader::resolveRemoteAddress(uint64_t address) const { std::optional
LLDBMemoryReader::resolveRemoteAddressFromSymbolObjectFile( - uint64_t address) const { + swift::remote::RemoteAddress address) const { Log *log(GetLog(LLDBLog::Types)); if (!m_process.GetTarget().GetSwiftReadMetadataFromDSYM()) @@ -744,16 +772,11 @@ LLDBMemoryReader::resolveRemoteAddressFromSymbolObjectFile( LLDB_LOGV(log, "[MemoryReader] Successfully resolved mapped address {0:x} into " "file address {1:x} from symbol object file.", - address, file_address); + address.getRawAddress(), file_address); return resolved; } bool LLDBMemoryReader::readMetadataFromFileCacheEnabled() const { - auto &triple = m_process.GetTarget().GetArchitecture().GetTriple(); - - // 32 doesn't have a flag bit we can reliably use, so reading from filecache - // is disabled on it. - return m_process.GetTarget().GetSwiftReadMetadataFromFileCache() && - triple.isArch64Bit(); + return m_process.GetTarget().GetSwiftReadMetadataFromFileCache(); } } // namespace lldb_private diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h index cd6d8a9bb3589..2eef7c3bcec62 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h +++ b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.h @@ -51,6 +51,10 @@ class MemoryReaderLocalBufferHolder { class LLDBMemoryReader : public swift::remote::MemoryReader { public: + /// Besides address space 0 (the DefaultAddressSpace), subclasses are free to + /// use any address space for their own implementation purposes. LLDB uses + /// this address space to track file addresses it sends to RemoteInspection. + static constexpr uint8_t LLDBAddressSpace = 1; LLDBMemoryReader(Process &p, std::function> - getFileAddressAndModuleForTaggedAddress(uint64_t tagged_address) const; + getFileAddressAndModuleForTaggedAddress( + swift::remote::RemoteAddress tagged_address) const; /// Resolves the address by either mapping a tagged address back to an LLDB /// Address with section + offset, or, in case the address is not tagged, @@ -114,12 +124,20 @@ class LLDBMemoryReader : public swift::remote::MemoryReader { /// tagged address back, an Address with just an offset if the address was not /// tagged, and None if the address was tagged but we couldn't convert it back /// to an Address. - std::optional
resolveRemoteAddress(uint64_t address) const; + std::optional
+ remoteAddressToLLDBAddress(swift::remote::RemoteAddress address) const; + + enum class ReadBytesResult { fail, success_from_file, success_from_memory }; + /// Implementation detail of readBytes. Returns a pair where the first element + /// indicates whether the memory was read successfully, the second element + /// indicates whether live memory was read. + ReadBytesResult readBytesImpl(swift::remote::RemoteAddress address, + uint8_t *dest, uint64_t size); /// Reads memory from the symbol rich binary from the address into dest. /// \return true if it was able to successfully read memory. - std::optional
- resolveRemoteAddressFromSymbolObjectFile(uint64_t address) const; + std::optional
resolveRemoteAddressFromSymbolObjectFile( + swift::remote::RemoteAddress address) const; Process &m_process; size_t m_max_read_amount; @@ -144,14 +162,6 @@ class LLDBMemoryReader : public swift::remote::MemoryReader { /// The set of modules where we should read memory from the symbol file's /// object file instead of the main object file. llvm::SmallSet m_modules_with_metadata_in_symbol_obj_file; - - /// The bit used to tag LLDB's virtual addresses as such. See \c - /// m_range_module_map. - const static uint64_t LLDB_FILE_ADDRESS_BIT = 0x2000000000000000; - static_assert(LLDB_FILE_ADDRESS_BIT & SWIFT_ABI_X86_64_SWIFT_SPARE_BITS_MASK, - "LLDB file address bit not in spare bits mask!"); - static_assert(LLDB_FILE_ADDRESS_BIT & SWIFT_ABI_ARM64_SWIFT_SPARE_BITS_MASK, - "LLDB file address bit not in spare bits mask!"); }; } // namespace lldb_private #endif diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 691519f984e25..778e89a382c36 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -727,8 +727,8 @@ std::optional SwiftLanguageRuntime::AddObjectFileToReflectionContext( assert(address <= end_address && "Address outside of range!"); swift::remote::RemoteRef remote_ref( - swift::remote::RemoteAddress( - address, swift::remote::RemoteAddress::DefaultAddressSpace), + swift::remote::RemoteAddress(address, + LLDBMemoryReader::LLDBAddressSpace), Buf); return {remote_ref, size}; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 5cb220bd4f42e..4c85e5481c7e0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -3109,6 +3109,36 @@ SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) { return result; } +namespace { +const char *GetFlags(const char *option, DWARFUnit *dwarf_cu) { + if (!dwarf_cu) + return nullptr; + + const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); + if (!die) + return nullptr; + + const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL); + if (!flags) + return nullptr; + + if (strstr(flags, option)) + return flags; + + return nullptr; +} +bool FindOptionInDWARFCU(const char *option, DWARFUnit *dwarf_cu, + std::string &value) { + const char *flags = GetFlags(option, dwarf_cu); + if (!flags) + return false; + + Args compiler_args(flags); + OptionParsing::GetOptionValueAsString(compiler_args, option, value); + return true; +} +} // namespace + bool SymbolFileDWARF::GetCompileOption(const char *option, std::string &value, CompileUnit *cu) { value.clear(); @@ -3118,52 +3148,19 @@ bool SymbolFileDWARF::GetCompileOption(const char *option, std::string &value, const uint32_t num_compile_units = GetNumCompileUnits(); if (cu) { - auto *dwarf_cu = - llvm::dyn_cast_or_null(GetDWARFCompileUnit(cu)); - - if (dwarf_cu) { + if (auto *dwarf_cu = + llvm::dyn_cast_or_null(GetDWARFCompileUnit(cu))) { // GetDWARFCompileUnit() only looks up by CU#. Make sure that // this is actually the correct SymbolFile by converting it // back to a CompileUnit. if (GetCompUnitForDWARFCompUnit(*dwarf_cu) != cu) return false; - - const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); - if (die) { - const char *flags = - die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL); - - if (flags) { - if (strstr(flags, option)) { - Args compiler_args(flags); - - return OptionParsing::GetOptionValueAsString(compiler_args, - option, value); - } - } - } + return FindOptionInDWARFCU(option, dwarf_cu, value); } } else { - for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { - DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx); - - if (dwarf_cu) { - const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); - if (die) { - const char *flags = - die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL); - - if (flags) { - if (strstr(flags, option)) { - Args compiler_args(flags); - - return OptionParsing::GetOptionValueAsString(compiler_args, - option, value); - } - } - } - } - } + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) + if (DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx)) + return FindOptionInDWARFCU(option, dwarf_cu, value); } return false; diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp index 916b75bd8ca44..b33c8f8e7b9e4 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/CompileUnit.h" #include "llvm/Support/Error.h" +#include "lldb/Utility/LLDBLog.h" #include #include @@ -75,7 +76,7 @@ void TypeSystemSwift::Terminate() { bool TypeSystemSwift::CheckFlagInCU(CompileUnit *cu, const char *flag) { AutoBool interop_enabled = - ModuleList::GetGlobalModuleListProperties().GetSwiftEnableCxxInterop(); + ModuleList::GetGlobalModuleListProperties().GetSwiftEnableCxxInterop(); switch (interop_enabled) { case AutoBool::True: return true; @@ -90,18 +91,18 @@ bool TypeSystemSwift::CheckFlagInCU(CompileUnit *cu, const char *flag) { auto *sym_file = module->GetSymbolFile(); if (!sym_file) return false; - auto options = sym_file->GetCompileOptions(); - for (auto &[unit, args] : options) { - if (unit.get() == cu) { - if (cu->GetLanguage() == eLanguageTypeSwift) - for (const char *arg : args.GetArgumentArrayRef()) - if (strcmp(arg, flag) == 0) - return true; - return false; - } + std::string value; + if (sym_file->GetCompileOption(flag, value, cu)) { + LLDB_LOGV(GetLog(LLDBLog::Types), + "[CheckFlagInCU] Found flag {0} in CU: {1}", flag, + cu->GetPrimaryFile().GetFilename().AsCString()); + return true; } } } + LLDB_LOGV(GetLog(LLDBLog::Types), + "[CheckFlagInCU] Did not find flag {0} in CU: {1}", flag, + cu->GetPrimaryFile().GetFilename().AsCString()); return false; } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index b2a2896352e73..bf486d0faaffa 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -2025,7 +2025,8 @@ size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst, size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory, - lldb::addr_t *load_addr_ptr) { + lldb::addr_t *load_addr_ptr, + bool *did_read_live_memory) { error.Clear(); Address fixed_addr = addr; @@ -2124,6 +2125,8 @@ size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len, if (bytes_read) { if (load_addr_ptr) *load_addr_ptr = load_addr; + if (did_read_live_memory) + *did_read_live_memory = true; return bytes_read; } } diff --git a/lldb/test/API/lang/swift/cxx_interop/forward/expressions/TestSwiftForwardInteropExpressions.py b/lldb/test/API/lang/swift/cxx_interop/forward/expressions/TestSwiftForwardInteropExpressions.py index c76b52a59ecd3..f278858085d74 100644 --- a/lldb/test/API/lang/swift/cxx_interop/forward/expressions/TestSwiftForwardInteropExpressions.py +++ b/lldb/test/API/lang/swift/cxx_interop/forward/expressions/TestSwiftForwardInteropExpressions.py @@ -15,13 +15,14 @@ def setup(self, bkpt_str): self, bkpt_str, lldb.SBFileSpec('main.swift')) return thread - @skipIf(bugnumber='rdar://152745034') @skipIfLinux # rdar://106871422" @skipIf(setting=('symbols.use-swift-clangimporter', 'false')) # rdar://106871275 @swiftTest def test(self): self.setup('Break here') + types_log = self.getBuildArtifact('types.log') + self.expect("log enable lldb types -v -f "+ types_log) # Check that we can call free functions. self.expect('expr returnsInt()', substrs=['Int32', '42']) @@ -54,6 +55,9 @@ def test(self): # Check that po prints the fields of a base class self.expect('po cxxClass', substrs=['CxxClass', 'a : 100', 'b : 101']) + self.filecheck('platform shell cat "%s"' % types_log, __file__) + # CHECK: [CheckFlagInCU] Found flag -enable-experimental-cxx-interop in CU: + @expectedFailureAll(bugnumber="rdar://106216567") @swiftTest def test_po_subclass(self): diff --git a/lldb/test/API/lang/swift/embedded/expr/TestSwiftEmbeddedExpression.py b/lldb/test/API/lang/swift/embedded/expr/TestSwiftEmbeddedExpression.py index a1d04ba6ee86f..a129d3c3d9e1f 100644 --- a/lldb/test/API/lang/swift/embedded/expr/TestSwiftEmbeddedExpression.py +++ b/lldb/test/API/lang/swift/embedded/expr/TestSwiftEmbeddedExpression.py @@ -14,4 +14,10 @@ def test(self): self, "break here", lldb.SBFileSpec("main.swift") ) + types_log = self.getBuildArtifact('types.log') + self.expect("log enable lldb types -v -f "+ types_log) + self.expect("expr a.foo()", substrs=["(Int)", " = 16"]) + + self.filecheck('platform shell cat "%s"' % types_log, __file__) + # CHECK: [CheckFlagInCU] Found flag -enable-embedded-swift in CU: diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp index fdc9bfae1876c..3c4c496889fca 100644 --- a/lldb/unittests/Expression/DWARFExpressionTest.cpp +++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp @@ -111,7 +111,8 @@ class MockTarget : public Target { size_t ReadMemory(const Address &addr, void *dst, size_t dst_len, Status &error, bool force_live_memory = false, - lldb::addr_t *load_addr_ptr = nullptr) /*override*/ { + lldb::addr_t *load_addr_ptr = nullptr, + bool *did_read_live_memory = nullptr) /*override*/ { auto expected_memory = this->ReadMemory(addr.GetOffset(), dst_len); if (!expected_memory) { llvm::consumeError(expected_memory.takeError());