This is an archive of the discontinued LLVM Phabricator instance.

Pass Process* along with ObjectFile::GetModuleSpecifications to allow fall back to process's architecture if OS is unknown.
AbandonedPublic

Authored by ovyalov on Apr 16 2015, 7:44 AM.

Details

Summary

ELF shared object may contain System V OS ABI - i.e., OS part of its architecture triple ends up as unknown.
In this case we cannot fall back to host architecture for remote downloaded modules (e.g. setting i386-apple-macosx for Android modules) .
This CL allows to pass Process pointer along with ObjectFile::GetModuleSpecifications so we can take Vendor and OS information from process architecture if it's not null. Additionally, need to store process as part of Module instance so it can be used to properly deduce architecture upon loading an object file.

Diff Detail

Event Timeline

ovyalov updated this revision to Diff 23857.Apr 16 2015, 7:44 AM
ovyalov retitled this revision from to Pass Process* along with ObjectFile::GetModuleSpecifications to allow fall back to process's architecture if OS is unknown. .
ovyalov updated this object.
ovyalov edited the test plan for this revision. (Show Details)
ovyalov added reviewers: clayborg, tberghammer, flackr.
ovyalov added a subscriber: Unknown Object (MLST).
flackr accepted this revision.Apr 16 2015, 10:18 AM
flackr edited edge metadata.

LGTM, this gets at least 3 more tests passing when running maxosx -> linux, woohoo!
TestCPPExceptionBreakpoint.py
TestCPPExceptionBreakpoints.py
TestGlobalVariables.py

This revision is now accepted and ready to land.Apr 16 2015, 10:18 AM
clayborg requested changes to this revision.Apr 16 2015, 1:32 PM
clayborg edited edge metadata.

We shouldn't pass a process along to any Module, ObjectFile or SymbolFile to determine anything. So this is the wrong fix. Why? Modules can be shared between multiple processes and modules should contain no information that comes from a process.

So the real fix is to:

  • Revert this patch
  • Fix ObjectFileELF to never use host anything to fill the OS or vendor it, and just not specify anything that it doesn't know for the OS or vendor. If it can't determine the vendor or OS, then leave them as "unspecified unknown".

What is an "unspecified unknown"? This means if you ask the LLVM triple what its OS is:

llvm::Triple::OSType os = llvm_triple.getOS();

it will return an enumeration llvm::Triple::UnknownOS and if you ask the triple for its OS name:

llvm::StringRef os_name = llvm_triple.getOSName();

And unspecified unknown is when the string is empty. A specified unknown is when the user specified "unknown" in the triple or ArchSpec.

It should return an empty string. This is an "unspecified unknown". If you ask a lldb_private::ArchSpec if it is compatible with another, it will answer yes for the following:

ArchSpec arch1("x86_64-apple-ios"); // This will have
ArchSpec arch2("x86_64"); // This will have unspecified unknown values for both the OS and Vendor
ArchSpec arch3("x86_64-unknown-unknown"); // This will have specified unknown values for both the OS and Vendor

// This will be true for the above arch definitions
if (arch1.IsCompatibleMatch(arch2))


// This will be false for the above arch definitions
if (arch1. IsCompatibleMatch(arch3))

So in ObjectFileELF, don't ever use the host to fill anything in, and only specify the vendor and OS if you can figure it out from the contents of the ELF file on its own.

include/lldb/Core/Module.h
1115

Shared libraries can be shared by multiple processes so you can't store any process info in a module. We have gone to great lengths to avoid associating modules with and process or target and I want to keep it that way.

This revision now requires changes to proceed.Apr 16 2015, 1:32 PM

To further clarify some things: Your target will have an architecture:

ArchSpec target_arch = target.GetArchitecture();

And you will eventually try and load modules for your target and your ELF module might have an architecture that is equivalent to:

ArchSpec module_arch = module->GetArchitecture(); // This will come from the ObjectFileELF

Your module_arch will contain a triple like "x86_64" and will have an unspecified unknown for the OS and vendor. This will be compatible with your target arch so it will allow you to match that module and use it within your target.

If there is any code that is requiring that a Module's OS and vendor to be correctly set, that code will need to be changed to merge the object file arch with the target arch:

void
ModuleFunctionThatMustBeSpecificToATarget (Target *target, ModuleSP module_sp)
{
    ArchSpec arch = module_sp->GetArchitecture();
    arch.MergeFrom(target->GetArchitecture()); // Fill in any gaps in the Module's architecture so that it matches the current process
    ... // Now "arch" is set to have a OS and vendor if it didn't already have one
}

The ArchSpec::MergeFrom will complete the "this" object using info from the argument architecture if anything is an unspecified unknown.

ovyalov abandoned this revision.Apr 17 2015, 6:31 AM

Thanks for suggestions and detailed explanation.
Abandoning this CL in favor of http://reviews.llvm.org/D9078