[RFC] ArchSpec

ArchSpec.h (16 KB)

ArchSpec.cpp (19.6 KB)

Committed revision 126278.

I took the changes you made Stephen and modified them to work slightly differently. Everyone please check out the changes and let me know what you think. See the commit message for revision 126278 for all the details.

More comments below on what this revision does.

*,

The ArchSpec class has been giving me a few problems on linux lately.
There were two main issues:

   1) The default "personality" for an ArchSpec is MachO. This
      assumption was causing a few issues when the linux plugins were
      being handed an ArchSpec they could not deal with.

This has been resolved with the fixes. No more mach-o by default.

   2) We have an llvm::Triple embedded in an ArchSpec. For MachO
      ArchSpec's it makes sense to have a vendor-os component of
      "apple-darwin" as default, but for ELF there is no way to guess
      what the operating system might be. Since we do not have the
      logic in LLDB yet to create an ArchSpec's with the appropriate OS
      bits resolved we were failing during plugin lookup on linux.

ArchSpec can now be set directly from a llvm::Triple, or from a const char * that contains the triple:

ArchSpec (const llvm::Triple &triple);
ArchSpec (const char *triple_cstr);

The above constructors just call through to:

void
SetTriple (const llvm::Triple &triple);

void
SetTriple (const char *triple_cstr);

If the "triple_cstr" is just an arch ("i386" or "x86_64"), the triple will now default to the host OS and the host vendor (make sure your host layer is returning correct values for the host architecture and the host vendor and host os!)

This should solve the failing lookups for the linux plug-ins.

Also, if you really want to specify a triple more completely, any of the commands or options that specify the arch ("--arch ARCH" or "-a ARCH") are really taking target triples so you can actually target a different type:

(lldb) file --arch i386-pc-linux /path/to/baz.elf

So basically what I think we need is:

   A) An ArchSpec which does not assume much.

It is purely agnostic right now, so this should be solved.

   B) An ArchSpec that is free of "magic" cpu type and subtype numbers,
      feature flags, etc. Use generic values like ArchSpec::CPU,
      llvm::Triples, or plain strings instead.

Done!

   C) A bit more logic at the points where ArchSpecs are instantiated
      to figure out what the ArchSpec should be.

This should be taken care of by the constructors and SetTriple functions above, and there is still a SetArchitecture that takes an architecture type + cpu type/machine + subtype/flags so the ELF and MachO object file parsers can still directly set their architectures and have it translated into the internal format:

ArchSpec (lldb::ArchitectureType arch_type,
          uint32_t cpu_type, // mach-o cputype or ELF e_machine
          uint32_t cpu_subtype); // mach-o subtype or ELF e_flags

Which just calls through to:

bool
ArchSpec::SetArchitecture (lldb::ArchitectureType arch_type,
                           uint32_t cpu,
                           uint32_t sub);