From 5e6f45201f0b62c1e7a24fc396f3ea6e10dc880d Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 22 Jan 2015 18:59:05 +0000 Subject: [PATCH] Don't stomp the triple when loading a PECOFF target. When you create a target, it tries to look for the platform's list of supported architectures for a match. The match it finds can contain specific triples, like i386-pc-windows-msvc. Later, we overwrite this value with the most generic triple that can apply to any platform with COFF support, causing some of the fields of the triple to get overwritten. This patch changes the behavior to only merge in values from the COFF triple if the fields of the matching triple were unknown/unspecified to begin with. This fixes load address resolution on Windows, since it enables the DynamicLoaderWindows to be used instead of DynamicLoaderStatic. Reviewed by: Greg Clayton Differential Revision: http://reviews.llvm.org/D7120 llvm-svn: 226849 --- lldb/include/lldb/Core/ArchSpec.h | 15 +++++++++++++++ lldb/source/Core/ArchSpec.cpp | 13 +++++++++++++ lldb/source/Core/Module.cpp | 10 +++++++--- .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 9 ++++++++- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lldb/include/lldb/Core/ArchSpec.h b/lldb/include/lldb/Core/ArchSpec.h index 694e204cdc0d..93630f043822 100644 --- a/lldb/include/lldb/Core/ArchSpec.h +++ b/lldb/include/lldb/Core/ArchSpec.h @@ -276,6 +276,21 @@ public: return !m_triple.getOSName().empty(); } + //------------------------------------------------------------------ + /// Merges fields from another ArchSpec into this ArchSpec. + /// + /// This will use the supplied ArchSpec to fill in any fields of + /// the triple in this ArchSpec which were unspecified. This can + /// be used to refine a generic ArchSpec with a more specific one. + /// For example, if this ArchSpec's triple is something like + /// i386-unknown-unknown-unknown, and we have a triple which is + /// x64-pc-windows-msvc, then merging that triple into this one + /// will result in the triple i386-pc-windows-msvc. + /// + //------------------------------------------------------------------ + void + MergeFrom(const ArchSpec &other); + //------------------------------------------------------------------ /// Sets this ArchSpec according to the given architecture name. /// diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index e7a5e489af19..015f76bffbb5 100644 --- a/lldb/source/Core/ArchSpec.cpp +++ b/lldb/source/Core/ArchSpec.cpp @@ -765,6 +765,19 @@ ArchSpec::SetTriple (const char *triple_cstr, Platform *platform) return IsValid(); } +void +ArchSpec::MergeFrom(const ArchSpec &other) +{ + if (GetTriple().getVendor() == llvm::Triple::UnknownVendor && !TripleVendorWasSpecified()) + GetTriple().setVendor(other.GetTriple().getVendor()); + if (GetTriple().getOS() == llvm::Triple::UnknownOS && !TripleOSWasSpecified()) + GetTriple().setOS(other.GetTriple().getOS()); + if (GetTriple().getArch() == llvm::Triple::UnknownArch) + GetTriple().setArch(other.GetTriple().getArch()); + if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) + GetTriple().setEnvironment(other.GetTriple().getEnvironment()); +} + bool ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t sub) { diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 900eea2e0419..d38d403bd313 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1304,10 +1304,14 @@ Module::GetObjectFile() data_offset); if (m_objfile_sp) { - // Once we get the object file, update our module with the object file's + // Once we get the object file, update our module with the object file's // architecture since it might differ in vendor/os if some parts were - // unknown. - m_objfile_sp->GetArchitecture (m_arch); + // unknown. But since the matching arch might already be more specific + // than the generic COFF architecture, only merge in those values that + // overwrite unspecified unknown values. + ArchSpec new_arch; + m_objfile_sp->GetArchitecture(new_arch); + m_arch.MergeFrom(new_arch); } else { diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 4f9ed2e81586..6defd643a43b 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -130,10 +130,17 @@ ObjectFilePECOFF::GetModuleSpecifications (const lldb_private::FileSpec& file, { ArchSpec spec; if (coff_header.machine == MachineAmd64) + { spec.SetTriple("x86_64-pc-windows"); + specs.Append(ModuleSpec(file, spec)); + } else if (coff_header.machine == MachineX86) + { spec.SetTriple("i386-pc-windows"); - specs.Append(ModuleSpec(file, spec)); + specs.Append(ModuleSpec(file, spec)); + spec.SetTriple("i686-pc-windows"); + specs.Append(ModuleSpec(file, spec)); + } } } }