[lldb] Add setting to override PE/COFF ABI by module name

The setting `plugin.object-file.pe-coff.module-abi` is a string-to-enum
map that allows specifying an ABI to a module name. For example:

    ucrtbase.dll=msvc
    libstdc++-6.dll=gnu

This allows for debugging a process which mixes both modules built using
the MSVC ABI and modules built using the MinGW ABI.

Depends on D127048

Reviewed By: DavidSpickett

Differential Revision: https://reviews.llvm.org/D127234
This commit is contained in:
Alvin Wong
2022-06-22 16:16:04 +03:00
committed by Martin Storsjö
parent 4d12378395
commit 3c867898c7
6 changed files with 128 additions and 12 deletions

View File

@@ -16,6 +16,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
@@ -91,6 +92,11 @@ public:
m_collection_sp->GetPropertyAtIndexAsEnumeration(
nullptr, ePropertyABI, llvm::Triple::UnknownEnvironment);
}
OptionValueDictionary *ModuleABIMap() const {
return m_collection_sp->GetPropertyAtIndexAsOptionValueDictionary(
nullptr, ePropertyModuleABIMap);
}
};
static PluginProperties &GetGlobalPluginProperties() {
@@ -283,7 +289,41 @@ size_t ObjectFilePECOFF::GetModuleSpecifications(
return llvm::Triple::MSVC;
}();
llvm::Triple::EnvironmentType env = GetGlobalPluginProperties().ABI();
// Check for a module-specific override.
OptionValueSP module_env_option;
const auto *map = GetGlobalPluginProperties().ModuleABIMap();
if (map->GetNumValues() > 0) {
// Step 1: Try with the exact file name.
auto name = file.GetLastPathComponent();
module_env_option = map->GetValueForKey(name);
if (!module_env_option) {
// Step 2: Try with the file name in lowercase.
auto name_lower = name.GetStringRef().lower();
module_env_option =
map->GetValueForKey(ConstString(llvm::StringRef(name_lower)));
}
if (!module_env_option) {
// Step 3: Try with the file name with ".debug" suffix stripped.
auto name_stripped = name.GetStringRef();
if (name_stripped.consume_back_insensitive(".debug")) {
module_env_option = map->GetValueForKey(ConstString(name_stripped));
if (!module_env_option) {
// Step 4: Try with the file name in lowercase with ".debug" suffix
// stripped.
auto name_lower = name_stripped.lower();
module_env_option =
map->GetValueForKey(ConstString(llvm::StringRef(name_lower)));
}
}
}
}
llvm::Triple::EnvironmentType env;
if (module_env_option)
env =
(llvm::Triple::EnvironmentType)module_env_option->GetEnumerationValue();
else
env = GetGlobalPluginProperties().ABI();
if (env == llvm::Triple::UnknownEnvironment)
env = default_env;