diff options
-rw-r--r-- | lldb/include/lldb/Core/ArchSpec.h | 15 | ||||
-rw-r--r-- | lldb/source/Core/ArchSpec.cpp | 13 | ||||
-rw-r--r-- | lldb/source/Core/Module.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Plugins/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 694e204cdc0..93630f04382 100644 --- a/lldb/include/lldb/Core/ArchSpec.h +++ b/lldb/include/lldb/Core/ArchSpec.h @@ -277,6 +277,21 @@ public: } //------------------------------------------------------------------ + /// 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. /// /// The architecture name can be one of the generic system default diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp index e7a5e489af1..015f76bffbb 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 900eea2e041..d38d403bd31 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 4f9ed2e8158..6defd643a43 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)); + } } } } |