Skip to content

Commit

Permalink
Refactor ObjectFile::GetSDKVersion
Browse files Browse the repository at this point in the history
Summary: This patch modernizes the GetSDKVersion API and hopefully prevents problems such as the ones discovered in D61218.

Reviewers: aprantl, jasonmolenda, clayborg

Reviewed By: aprantl, clayborg

Subscribers: clayborg, labath, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D61233

llvm-svn: 365090
  • Loading branch information
Teemperor committed Jul 3, 2019
1 parent 8bb1e15 commit e0afcd8
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 53 deletions.
14 changes: 5 additions & 9 deletions lldb/include/lldb/Symbol/ObjectFile.h
Expand Up @@ -578,15 +578,11 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,

/// Get the SDK OS version this object file was built with.
///
/// The versions arguments and returns values are the same as the
/// GetMinimumOSVersion()
virtual uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) {
if (versions && num_versions) {
for (uint32_t i = 0; i < num_versions; ++i)
versions[i] = UINT32_MAX;
}
return 0;
}
/// \return
/// This function returns extracted version numbers as a
/// llvm::VersionTuple. In case of error an empty VersionTuple is
/// returned.
virtual llvm::VersionTuple GetSDKVersion() { return llvm::VersionTuple(); }

/// Return true if this file is a dynamic link editor (dyld)
///
Expand Down
50 changes: 12 additions & 38 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Expand Up @@ -5849,12 +5849,10 @@ llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
return *m_min_os_version;
}

uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
uint32_t num_versions) {
if (m_sdk_versions.empty()) {
llvm::VersionTuple ObjectFileMachO::GetSDKVersion() {
if (!m_sdk_versions.hasValue()) {
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
bool success = false;
for (uint32_t i = 0; !success && i < m_header.ncmds; ++i) {
for (uint32_t i = 0; i < m_header.ncmds; ++i) {
const lldb::offset_t load_cmd_offset = offset;

version_min_command lc;
Expand All @@ -5870,10 +5868,8 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
const uint32_t yy = (lc.sdk >> 8) & 0xffu;
const uint32_t zz = lc.sdk & 0xffu;
if (xxxx) {
m_sdk_versions.push_back(xxxx);
m_sdk_versions.push_back(yy);
m_sdk_versions.push_back(zz);
success = true;
m_sdk_versions = llvm::VersionTuple(xxxx, yy, zz);
break;
} else {
GetModule()->ReportWarning(
"minimum OS version load command with invalid (0) version found.");
Expand All @@ -5883,9 +5879,9 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
offset = load_cmd_offset + lc.cmdsize;
}

if (!success) {
if (!m_sdk_versions.hasValue()) {
offset = MachHeaderSizeFromMagic(m_header.magic);
for (uint32_t i = 0; !success && i < m_header.ncmds; ++i) {
for (uint32_t i = 0; i < m_header.ncmds; ++i) {
const lldb::offset_t load_cmd_offset = offset;

version_min_command lc;
Expand All @@ -5912,41 +5908,19 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
const uint32_t yy = (minos >> 8) & 0xffu;
const uint32_t zz = minos & 0xffu;
if (xxxx) {
m_sdk_versions.push_back(xxxx);
m_sdk_versions.push_back(yy);
m_sdk_versions.push_back(zz);
success = true;
m_sdk_versions = llvm::VersionTuple(xxxx, yy, zz);
break;
}
}
offset = load_cmd_offset + lc.cmdsize;
}
}

if (!success) {
// Push an invalid value so we don't try to find
// the version # again on the next call to this
// method.
m_sdk_versions.push_back(UINT32_MAX);
}
if (!m_sdk_versions.hasValue())
m_sdk_versions = llvm::VersionTuple();
}

// Legitimate version numbers will have 3 entries pushed
// on to m_sdk_versions. If we only have one value, it's
// the sentinel value indicating that this object file
// does not have a valid minimum os version #.
if (m_sdk_versions.size() > 1) {
if (versions != nullptr && num_versions > 0) {
for (size_t i = 0; i < num_versions; ++i) {
if (i < m_sdk_versions.size())
versions[i] = m_sdk_versions[i];
else
versions[i] = 0;
}
}
return m_sdk_versions.size();
}
// Call the superclasses version that will empty out the data
return ObjectFile::GetSDKVersion(versions, num_versions);
return m_sdk_versions.getValue();
}

bool ObjectFileMachO::GetIsDynamicLinkEditor() {
Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
Expand Up @@ -116,7 +116,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {

llvm::VersionTuple GetMinimumOSVersion() override;

uint32_t GetSDKVersion(uint32_t *versions, uint32_t num_versions) override;
llvm::VersionTuple GetSDKVersion() override;

bool GetIsDynamicLinkEditor() override;

Expand Down Expand Up @@ -198,7 +198,7 @@ class ObjectFileMachO : public lldb_private::ObjectFile {
std::vector<llvm::MachO::segment_command_64> m_mach_segments;
std::vector<llvm::MachO::section_64> m_mach_sections;
llvm::Optional<llvm::VersionTuple> m_min_os_version;
std::vector<uint32_t> m_sdk_versions;
llvm::Optional<llvm::VersionTuple> m_sdk_versions;
typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
lldb_private::Address m_entry_point_address;
FileRangeArray m_thread_context_offsets;
Expand Down
8 changes: 4 additions & 4 deletions lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
Expand Up @@ -163,8 +163,8 @@ ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
std::string xcode_contents_path;
std::string default_xcode_sdk;
FileSpec fspec;
uint32_t versions[2];
if (objfile->GetSDKVersion(versions, 2)) {
llvm::VersionTuple version = objfile->GetSDKVersion();
if (!version.empty()) {
fspec = HostInfo::GetShlibDir();
if (fspec) {
std::string path;
Expand Down Expand Up @@ -208,8 +208,8 @@ ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
StreamString sdk_path;
sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/"
"SDKs/MacOSX%u.%u.sdk",
xcode_contents_path.c_str(), versions[0],
versions[1]);
xcode_contents_path.c_str(), version.getMajor(),
version.getMinor().getValue());
fspec.SetFile(sdk_path.GetString(), FileSpec::Style::native);
if (FileSystem::Instance().Exists(fspec))
return ConstString(sdk_path.GetString());
Expand Down

0 comments on commit e0afcd8

Please sign in to comment.