| # Copyright 2015 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| # |
| # Compute a multilib category, as discussed here: |
| # |
| # https://bugs.gentoo.org/show_bug.cgi?id=534206 |
| # |
| # Supported categories: |
| # |
| # alpha_{32,64} |
| # arm_{32,64} |
| # hppa_{32,64} |
| # ia_{32,64} |
| # m68k_{32,64} |
| # mips_{eabi32,eabi64,n32,n64,o32,o64} |
| # ppc_{32,64} |
| # s390_{32,64} |
| # sh_{32,64} |
| # sparc_{32,64} |
| # x86_{32,64,x32} |
| # |
| # NOTES: |
| # |
| # * The ABIs referenced by some of the above *_32 and *_64 categories |
| # may be imaginary, but they are listed anyway, since the goal is to |
| # establish a naming convention that is as consistent and uniform as |
| # possible. |
| # |
| # * The Elf header's e_ident[EI_OSABI] byte is completely ignored, |
| # since OS-independence is one of the goals. The assumption is that, |
| # for given installation, we are only interested in tracking multilib |
| # ABIs for a single OS. |
| |
| from __future__ import unicode_literals |
| |
| from portage.util.elf.constants import ( |
| EF_MIPS_ABI, EF_MIPS_ABI2, ELFCLASS32, ELFCLASS64, |
| EM_386, EM_68K, EM_AARCH64, EM_ALPHA, EM_ARM, EM_IA_64, EM_MIPS, |
| EM_PARISC, EM_PPC, EM_PPC64, EM_S390, EM_SH, EM_SPARC, |
| EM_SPARC32PLUS, EM_SPARCV9, EM_X86_64, E_MIPS_ABI_EABI32, |
| E_MIPS_ABI_EABI64, E_MIPS_ABI_O32, E_MIPS_ABI_O64) |
| |
| _machine_prefix_map = { |
| EM_386: "x86", |
| EM_68K: "m68k", |
| EM_AARCH64: "arm", |
| EM_ALPHA: "alpha", |
| EM_ARM: "arm", |
| EM_IA_64: "ia64", |
| EM_MIPS: "mips", |
| EM_PARISC: "hppa", |
| EM_PPC: "ppc", |
| EM_PPC64: "ppc", |
| EM_S390: "s390", |
| EM_SH: "sh", |
| EM_SPARC: "sparc", |
| EM_SPARC32PLUS: "sparc", |
| EM_SPARCV9: "sparc", |
| EM_X86_64: "x86", |
| } |
| |
| _mips_abi_map = { |
| E_MIPS_ABI_EABI32: "eabi32", |
| E_MIPS_ABI_EABI64: "eabi64", |
| E_MIPS_ABI_O32: "o32", |
| E_MIPS_ABI_O64: "o64", |
| } |
| |
| def _compute_suffix_mips(elf_header): |
| |
| name = None |
| mips_abi = elf_header.e_flags & EF_MIPS_ABI |
| |
| if mips_abi: |
| name = _mips_abi_map.get(mips_abi) |
| elif elf_header.e_flags & EF_MIPS_ABI2: |
| name = "n32" |
| elif elf_header.ei_class == ELFCLASS64: |
| name = "n64" |
| |
| return name |
| |
| def compute_multilib_category(elf_header): |
| """ |
| Compute a multilib category from an ELF header. |
| |
| @param elf_header: an ELFHeader instance |
| @type elf_header: ELFHeader |
| @rtype: str |
| @return: A multilib category, or None if elf_header does not fit |
| into a recognized category |
| """ |
| category = None |
| if elf_header.e_machine is not None: |
| |
| prefix = _machine_prefix_map.get(elf_header.e_machine) |
| suffix = None |
| |
| if prefix == "mips": |
| suffix = _compute_suffix_mips(elf_header) |
| elif elf_header.ei_class == ELFCLASS64: |
| suffix = "64" |
| elif elf_header.ei_class == ELFCLASS32: |
| if elf_header.e_machine == EM_X86_64: |
| suffix = "x32" |
| else: |
| suffix = "32" |
| |
| if prefix is None or suffix is None: |
| category = None |
| else: |
| category = "%s_%s" % (prefix, suffix) |
| |
| return category |