ArchSpec IsCompatibleMatch()

I’m trying to understand what the semantics of this function are. When it refers to compatibility, how much compatibility is required?

To use a concrete example, consider the following architectures:

eCore_x86_32_i386,
eCore_x86_32_i486,
eCore_x86_32_i486sx,
eCore_x86_32_i686,

These all fall under the category of “x86 architectures”. So if someone were to call IsCompatibleMatch(arch1.core = eCore_x86_32_i386, arch2.core = eCore_x86_32_i686) would these cores be considered matching or non-matching?

The reason I ask is that when we load a PE / Coff executable, we can get from the PE file the x86_32 file part, but we can’t get whether it was built specifically for a 386, 486, etc. Currently we are just using the value eCore_x86_32_i386 since we don’t know how to be more specific, but this fails to find an architecture match later on in the process. One possible fix is to use kCore_x86_32_any, which would cause the match to succeed. Another possible fix is to make the match function always use wildcard matching for this set of architectures. But then later if someone needs a more specific definition of compatibility, this might not work.

Anyone have suggestions as to what is the correct fix?

I'm trying to understand what the semantics of this function are. When it refers to compatibility, how much compatibility is required?

To use a concrete example, consider the following architectures:

        eCore_x86_32_i386,
        eCore_x86_32_i486,
        eCore_x86_32_i486sx,
        eCore_x86_32_i686,

These all fall under the category of "x86 architectures". So if someone were to call IsCompatibleMatch(arch1.core = eCore_x86_32_i386, arch2.core = eCore_x86_32_i686) would these cores be considered matching or non-matching?

It really depends on what machine you are running on. It is ok to have all of these not be compatible, but have your

virtual bool
PlatformWindows32::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch);

Return the following in order:

eCore_x86_32_i686 for idx == 0
eCore_x86_32_i486sx for idx == 1
eCore_x86_32_i486 for idx == 2
eCore_x86_32_i386 for idx == 3

You would only want to return these architectures if the binaries that you load for windows32 could be PECOFF files that have different triples. For example on MacOSX, we can load "x86_64h" or "x86_64" (our shared libraries have a Haswell slice for more performance). When our dynamic linker loads a binary for "/bin/ls" it checks "liba.dylib" to see if it has a x86_64h slice, and if it doesn't then it falls back to x86_64. Likewise on our iOS platform, the main executable can be armv7s, but the shared libraries can be anything that is less than or equal to armv7s: armv7 armv6, armv5, armv4, etc...

So I would venture to say they shouldn't be compatible. They only should be compatible if your system supports this sort of architecture fall back methodology.

The reason I ask is that when we load a PE / Coff executable, we can get from the PE file the x86_32 file part, but we can't get whether it was built specifically for a 386, 486, etc. Currently we are just using the value eCore_x86_32_i386 since we don't know how to be more specific, but this fails to find an architecture match later on in the process. One possible fix is to use kCore_x86_32_any, which would cause the match to succeed.

This might be what you wan't your lldb_private::Target's architecture to be set to (kCore_x86_32_any) so that it can match any eCore_x86_32_i386, eCore_x86_32_i486, eCore_x86_32_i486sx or eCore_x86_32_i686.

But I would recommend just making the PECOFF just stick to one core type for 32 and 64 bit so you never have to worry about this.

Another possible fix is to make the match function always use wildcard matching for this set of architectures. But then later if someone needs a more specific definition of compatibility, this might not work.

Anyone have suggestions as to what is the correct fix?

So for now I would stick to having to have exact core matches for x86 and x86_64 and make sure PECOFF's GetArchitecture() only hands out one value for 32 bit and one for 64 bit. The rest should just work.

Out of curiosity, why is the ArchSpec even needed? What does it provide that you can’t already do with llvm::Triple?