Upstreaming the BridgeOS device support and the

LC_BUILD_VERSION load command handling - this
commit is a combination of patches by Adrian
Prantl and myself.  llvm::Triple::BridgeOS 
isn't defined yet, so all references to that
are currently commented out.  

Also update Xcode project file to build the 
NativePDB etc plugins.

<rdar://problem/43353615> 

llvm-svn: 344209
This commit is contained in:
Jason Molenda
2018-10-11 00:28:35 +00:00
parent 51fbb2e70a
commit 32762fd29d
19 changed files with 714 additions and 35 deletions

View File

@@ -4880,21 +4880,78 @@ bool ObjectFileMachO::GetUUID(const llvm::MachO::mach_header &header,
return false;
}
static const char *GetOSName(uint32_t cmd) {
static llvm::StringRef GetOSName(uint32_t cmd) {
switch (cmd) {
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
return "ios";
return llvm::Triple::getOSTypeName(llvm::Triple::IOS);
case llvm::MachO::LC_VERSION_MIN_MACOSX:
return "macosx";
return llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
case llvm::MachO::LC_VERSION_MIN_TVOS:
return "tvos";
return llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
case llvm::MachO::LC_VERSION_MIN_WATCHOS:
return "watchos";
return llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
default:
llvm_unreachable("unexpected LC_VERSION load command");
}
}
namespace {
struct OSEnv {
llvm::StringRef os_type;
llvm::StringRef environment;
OSEnv(uint32_t cmd) {
switch (cmd) {
case PLATFORM_MACOS:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::MacOSX);
return;
case PLATFORM_IOS:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
return;
case PLATFORM_TVOS:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
return;
case PLATFORM_WATCHOS:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
return;
// NEED_BRIDGEOS_TRIPLE case PLATFORM_BRIDGEOS:
// NEED_BRIDGEOS_TRIPLE os_type = llvm::Triple::getOSTypeName(llvm::Triple::BridgeOS);
// NEED_BRIDGEOS_TRIPLE return;
#if defined (PLATFORM_IOSSIMULATOR) && defined (PLATFORM_TVOSSIMULATOR) && defined (PLATFORM_WATCHOSSIMULATOR)
case PLATFORM_IOSSIMULATOR:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::IOS);
environment =
llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
return;
case PLATFORM_TVOSSIMULATOR:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::TvOS);
environment =
llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
return;
case PLATFORM_WATCHOSSIMULATOR:
os_type = llvm::Triple::getOSTypeName(llvm::Triple::WatchOS);
environment =
llvm::Triple::getEnvironmentTypeName(llvm::Triple::Simulator);
return;
#endif
default: {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS |
LIBLLDB_LOG_PROCESS));
if (log)
log->Printf("unsupported platform in LC_BUILD_VERSION");
}
}
}
};
struct MinOS {
uint32_t major, minor, patch;
MinOS(uint32_t version)
: major(version >> 16),
minor((version >> 8) & 0xffu),
patch(version & 0xffu) {}
};
} // namespace
bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
const lldb_private::DataExtractor &data,
lldb::offset_t lc_offset,
@@ -4926,36 +4983,34 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
return true;
} else {
struct load_command load_cmd;
llvm::SmallString<16> os_name;
llvm::raw_svector_ostream os(os_name);
// See if there is an LC_VERSION_MIN_* load command that can give
// us the OS type.
lldb::offset_t offset = lc_offset;
for (uint32_t i = 0; i < header.ncmds; ++i) {
const lldb::offset_t cmd_offset = offset;
if (data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
uint32_t major, minor, patch;
struct version_min_command version_min;
llvm::SmallString<16> os_name;
llvm::raw_svector_ostream os(os_name);
switch (load_cmd.cmd) {
case llvm::MachO::LC_VERSION_MIN_IPHONEOS:
case llvm::MachO::LC_VERSION_MIN_MACOSX:
case llvm::MachO::LC_VERSION_MIN_TVOS:
case llvm::MachO::LC_VERSION_MIN_WATCHOS:
case llvm::MachO::LC_VERSION_MIN_WATCHOS: {
if (load_cmd.cmdsize != sizeof(version_min))
break;
data.ExtractBytes(cmd_offset,
sizeof(version_min), data.GetByteOrder(),
&version_min);
major = version_min.version >> 16;
minor = (version_min.version >> 8) & 0xffu;
patch = version_min.version & 0xffu;
os << GetOSName(load_cmd.cmd) << major << '.' << minor << '.'
<< patch;
if (data.ExtractBytes(cmd_offset, sizeof(version_min),
data.GetByteOrder(), &version_min) == 0)
break;
MinOS min_os(version_min.version);
os << GetOSName(load_cmd.cmd) << min_os.major << '.' << min_os.minor
<< '.' << min_os.patch;
triple.setOSName(os.str());
return true;
}
default:
break;
}
@@ -4963,6 +5018,35 @@ bool ObjectFileMachO::GetArchitecture(const llvm::MachO::mach_header &header,
offset = cmd_offset + load_cmd.cmdsize;
}
// See if there is an LC_BUILD_VERSION load command that can give
// us the OS type.
offset = lc_offset;
for (uint32_t i = 0; i < header.ncmds; ++i) {
const lldb::offset_t cmd_offset = offset;
if (data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
if (load_cmd.cmd == llvm::MachO::LC_BUILD_VERSION) {
struct build_version_command build_version;
if (load_cmd.cmdsize != sizeof(build_version))
if (data.ExtractBytes(cmd_offset, sizeof(build_version),
data.GetByteOrder(), &build_version) == 0)
continue;
MinOS min_os(build_version.minos);
OSEnv os_env(build_version.platform);
if (os_env.os_type.empty())
continue;
os << os_env.os_type << min_os.major << '.' << min_os.minor << '.'
<< min_os.patch;
triple.setOSName(os.str());
if (!os_env.environment.empty())
triple.setEnvironmentName(os_env.environment);
return true;
}
offset = cmd_offset + load_cmd.cmdsize;
}
if (header.filetype != MH_KEXT_BUNDLE) {
// We didn't find a LC_VERSION_MIN load command and this isn't a KEXT
// so lets not say our Vendor is Apple, leave it as an unspecified
@@ -5727,8 +5811,30 @@ llvm::VersionTuple ObjectFileMachO::GetMinimumOSVersion() {
m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
break;
}
}
} else if (lc.cmd == llvm::MachO::LC_BUILD_VERSION) {
// struct build_version_command {
// uint32_t cmd; /* LC_BUILD_VERSION */
// uint32_t cmdsize; /* sizeof(struct build_version_command) plus */
// /* ntools * sizeof(struct build_tool_version) */
// uint32_t platform; /* platform */
// uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
// uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
// uint32_t ntools; /* number of tool entries following this */
// };
offset += 4; // skip platform
uint32_t minos = m_data.GetU32(&offset);
const uint32_t xxxx = minos >> 16;
const uint32_t yy = (minos >> 8) & 0xffu;
const uint32_t zz = minos & 0xffu;
if (xxxx) {
m_min_os_version = llvm::VersionTuple(xxxx, yy, zz);
break;
}
}
offset = load_cmd_offset + lc.cmdsize;
}
@@ -5775,6 +5881,46 @@ uint32_t ObjectFileMachO::GetSDKVersion(uint32_t *versions,
offset = load_cmd_offset + lc.cmdsize;
}
if (success == false)
{
offset = MachHeaderSizeFromMagic(m_header.magic);
for (uint32_t i = 0; success == false && i < m_header.ncmds; ++i)
{
const lldb::offset_t load_cmd_offset = offset;
version_min_command lc;
if (m_data.GetU32(&offset, &lc.cmd, 2) == NULL)
break;
if (lc.cmd == llvm::MachO::LC_BUILD_VERSION)
{
// struct build_version_command {
// uint32_t cmd; /* LC_BUILD_VERSION */
// uint32_t cmdsize; /* sizeof(struct build_version_command) plus */
// /* ntools * sizeof(struct build_tool_version) */
// uint32_t platform; /* platform */
// uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
// uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
// uint32_t ntools; /* number of tool entries following this */
// };
offset += 4; // skip platform
uint32_t minos = m_data.GetU32(&offset);
const uint32_t xxxx = minos >> 16;
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;
}
offset = load_cmd_offset + lc.cmdsize;
}
}
if (success == false) {
// Push an invalid value so we don't try to find
// the version # again on the next call to this
@@ -5944,6 +6090,7 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
target_triple.getOS() == llvm::Triple::IOS ||
target_triple.getOS() == llvm::Triple::WatchOS ||
target_triple.getOS() == llvm::Triple::TvOS)) {
// NEED_BRIDGEOS_TRIPLE target_triple.getOS() == llvm::Triple::BridgeOS)) {
bool make_core = false;
switch (target_arch.GetMachine()) {
case llvm::Triple::aarch64: