IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Toolchain notes on MIPS

    MaskRay发表于 2023-09-05 02:08:38
    love 0

    UNDER CONSTRUCTION

    This article describes some notes about MIPS with a focus on GCC,binutils, and LLVM/Clang.

    ISAs

    Earlier ISAs, such as MIPS I, MIPS II, MIPS III, and MIPS IV, can beselected by gcc -march=mips[1-4]. MIPS V has noimplementation and GCC doesn't support -march=mips5.

    Successive versions are split into MIPS32 and MIPS64, which can beselected by -march=mips{32,64} and-march=mips{32,64}r{2,3,5,6}.-march=mips{32,64}r4 is not supported.

    Release 6 is very different from prior releases.

    • -march=mips{32,64}r2 define __mips_isa_revto 2.
    • -march=mips{32,64}r3 define __mips_isa_revto 3.
    • -march=mips{32,64}r5 define __mips_isa_revto 5.
    • -march=mips{32,64}r6 define __mips_isa_revto 6.
    • Older processors don't define __mips_isa_rev.

    The ISA revisions of GCC supported -march= values can befound at gcc/config/mips/mips-cpus.def.

    The EF_MIPS_ARCH (0xf0000000) part ofe_flags indicates the ISA.

    When a 64-bit capable CPU is used with o32, assemblers set theEF_MIPS_32BITMODE flag in e_flags.

    ABIs

    o32

    https://refspecs.linuxfoundation.org/elf/mipsabi.pdf

    This is an ILP32 ABI designed for the 32-bit CPU MIPS R3000 thatimplements the MIPS I ISA. It is the original System V ProcessorSupplement ABI for MIPS.

    In GCC, -mabi=32 selects this ABI, which is identifiedas ABI_32.

    Assemblers set the EF_MIPS_ABI_O32 flag ine_flags.

    There are some major flaws:

    • The calling convention provides just 4 integer registers forarguments (inadequate).
    • The ABI is committed to MIPS I and makes odd-numbered floating-pointregisters inaccessible.
    • Only two floating-point registers $12 and $14 hold arguments. Therest use integer registers, which are severely limited.

    MIPS I has 32 floating-point registers. Two registers are paired forholding a double precision number.

    • For single-precision values, the even-numbered floating-pointregister holds the value.
    • For double-precision values, the even-numbered floating-pointregister holds the least significant 32 bits of the value and theodd-numbered floating-point register holds the most significant 32 bitsof the value.

    For o32, -mfp64 selects a variant that enables 64-bitfloating-point registers. This requires at least-march=mips32r2 and GCC will emit.module fp=64; .module oddspreg.

    n64

    This is an LP64 ABI designed for 64-bit CPUs (MIPS III andnewer).

    In GCC, -mabi=64 selects this ABI, which is identifiedas ABI_64.

    Assemblers don't set a particular bit in e_flags.

    n32

    This is an ILP32 ABI for 64-bit CPUs (MIPS III and newer), oftennamed n32.

    In GCC, -mabi=n32 selects this ABI, which is identifiedas ABI_N32. -march= values such asmips3, mips64 are compatible.

    Assemblers set the EF_MIPS_ABI2 bit ine_flags.

    o64

    This is o32 extended for 64-bit CPUs. https://gcc.gnu.org/projects/mipso64-abi.html

    In GCC, -mabi=o64 selects this ABI, which is identifiedas ABI_O64.

    Assemblers set the EF_MIPS_ABI_O64 flag ine_flags.

    EABI

    Assemblers set the EF_MIPS_ABI_EABI32 flag ine_flags.


    o32 and o64 are called TARGET_OLDABI in GCC. n32 and n64are called TARGET_NEWABI in GCC.

    In the old ABIs, the local label prefix for assembly is$, which is strange.


    GCC emits a special section to indicate the ABI for GDB.

    • o32: .mdebug.abi32
    • n32: .mdebug.abiN32
    • n64: .mdebug.abi64
    • o64: mdebug.abiO64
    • 32-bit EABI: .mdebug.eabi32
    • 64-bit EABI: .mdebug.eabi32

    gp register

    Floating-point numbers

    See NaNencodings.

    IEEE 754-2008 says

    A quiet NaN bit string should be encoded with the first bit (d1) ofthe trailing significand field T being 1.

    -mnan=2008 instructs GCC to emit a.nan 2008 directive, which causes GNU assembler to set theEF_MIPS_NAN2008 bit in e_flags.

    MIPS32/MIPS64 Release 6 defaults to -mnan=2008 whileprior ISAs default to -mnan=legacy.

    -modd-spreg

    When 64-bit floating-point registers are available (implied byELFCLASS64) or MIPS32/MIPS64 Release 1 or above, odd-numberedsingle-precision floating-point registers can be used.

    1
    2
    3
    4
    5
    /* ISA has 32 single-precision registers.  */
    #define ISA_HAS_ODD_SPREG ((mips_isa_rev >= 1 \
    && !TARGET_GS464) \
    || TARGET_FLOAT64 \
    || TARGET_MIPS5900)

    However, these registers are disabled for the o32 ABI by default.Specifying -mabi=32 -mfp64uses a variant where floating-point registers are 64 rather than 32 bitswide.

    Dynamic tags

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    % grep DT_MIPS_ include/elf/mips.h
    #define DT_MIPS_RLD_VERSION 0x70000001
    #define DT_MIPS_TIME_STAMP 0x70000002
    #define DT_MIPS_ICHECKSUM 0x70000003
    #define DT_MIPS_IVERSION 0x70000004
    #define DT_MIPS_FLAGS 0x70000005
    #define DT_MIPS_BASE_ADDRESS 0x70000006
    #define DT_MIPS_MSYM 0x70000007
    #define DT_MIPS_CONFLICT 0x70000008
    #define DT_MIPS_LIBLIST 0x70000009
    #define DT_MIPS_LOCAL_GOTNO 0x7000000a
    #define DT_MIPS_CONFLICTNO 0x7000000b
    #define DT_MIPS_LIBLISTNO 0x70000010
    #define DT_MIPS_SYMTABNO 0x70000011
    #define DT_MIPS_UNREFEXTNO 0x70000012
    #define DT_MIPS_GOTSYM 0x70000013
    #define DT_MIPS_HIPAGENO 0x70000014
    #define DT_MIPS_RLD_MAP 0x70000016
    #define DT_MIPS_DELTA_CLASS 0x70000017
    /* Number of entries in DT_MIPS_DELTA_CLASS. */
    #define DT_MIPS_DELTA_CLASS_NO 0x70000018
    #define DT_MIPS_DELTA_INSTANCE 0x70000019
    /* Number of entries in DT_MIPS_DELTA_INSTANCE. */
    #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
    #define DT_MIPS_DELTA_RELOC 0x7000001b
    /* Number of entries in DT_MIPS_DELTA_RELOC. */
    #define DT_MIPS_DELTA_RELOC_NO 0x7000001c
    #define DT_MIPS_DELTA_SYM 0x7000001d
    /* Number of entries in DT_MIPS_DELTA_SYM. */
    #define DT_MIPS_DELTA_SYM_NO 0x7000001e
    #define DT_MIPS_DELTA_CLASSSYM 0x70000020
    /* Number of entries in DT_MIPS_DELTA_CLASSSYM. */
    #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
    #define DT_MIPS_CXX_FLAGS 0x70000022
    #define DT_MIPS_PIXIE_INIT 0x70000023
    #define DT_MIPS_SYMBOL_LIB 0x70000024
    #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
    #define DT_MIPS_LOCAL_GOTIDX 0x70000026
    #define DT_MIPS_HIDDEN_GOTIDX 0x70000027
    #define DT_MIPS_PROTECTED_GOTIDX 0x70000028
    #define DT_MIPS_OPTIONS 0x70000029
    #define DT_MIPS_INTERFACE 0x7000002a
    #define DT_MIPS_DYNSTR_ALIGN 0x7000002b
    #define DT_MIPS_INTERFACE_SIZE 0x7000002c
    #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
    #define DT_MIPS_PERF_SUFFIX 0x7000002e
    #define DT_MIPS_COMPACT_SIZE 0x7000002f
    #define DT_MIPS_GP_VALUE 0x70000030
    #define DT_MIPS_AUX_DYNAMIC 0x70000031
    #define DT_MIPS_PLTGOT 0x70000032
    #define DT_MIPS_RWPLT 0x70000034
    #define DT_MIPS_RLD_MAP_REL 0x70000035
    #define DT_MIPS_XHASH 0x70000036
    /* Flags which may appear in a DT_MIPS_FLAGS entry. */

    Among these dynamic tags, DT_MIPS_LOCAL_GOTNO,DT_MIPS_GOTSYM, DT_MIPS_SYMTABNO, andDT_MIPS_PLTGOT have significant uses in glibc rtld.

    For executable output, DT_MIPS_RLD_MAP_REL holds theoffset to the linker synthesized .rld_map. IfDT_MIPS_RLD_MAP_REL is unavailable, glibc rtld looks forDT_MIPS_RLD_MAP, which is emitted for ET_EXECexecutables.

    Special sections

    There are many special sections. Let me just quote a comment frombinutils/readelf.c:process_mips_specific:

    1
    /* We have a lot of special sections.  Thanks SGI!  */

    There are many sections from other vendors. Anyway, this remark setsup the mood.

    .MIPS.options section

    Mips N32 and N64 ABIs use .MIPS.options.

    .MIPS.abiflags section

    In 2014, [MIPS]Implement O32 FPXX, FP64 and FP64A ABI extensions introduced.MIPS.abiflags (type SHT_MIPS_ABIFLAGS) andPT_MIPS_ABIFLAGS.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    A new implicitly generated section will be present on all new modules. The section contains a versioned data structure which represents essential information to allow a program loader to determine the requirements of the application. ELF e_flags currently contain some of this information but space is limited and e_flags are not available after loading an application.

    The structure is versioned to allow for future extensions. The initial version is 0.

    Register size fields record the maximum size register required for each class of registers
    The floating point ABI is recorded using the same attribute values used for gnu_attribute 4. These are listed in Appendix B.
    ASEs are represented by a bitmask of ASEs that have been used.
    ISA extensions are represented as a single enumeration value.
    The flags1 field includes a flag to record whether odd-numbered single-precision registers were enabled.

    GNU ld has quite involved merging strategy for this section.

    Relocations

    The little-endian n64 ABI messed up the r_info field inrelocations.

    The n64 ABI can pack up to 3 relocations with the same offset intoone record.

    R_MIPS_PC64

    This relocation type does not exist, but we can emulate a 64-bitPC-relative relocation withR_MIPS_PC32 + R_MIPS_64 + R_MIPS_NONE. LLVM implementedthis relocation in https://reviews.llvm.org/D80390 while binutils doesn'tsupport it yet.

    1
    2
    3
    4
    5
    .globl foo
    foo:
    .data
    .quad foo-.
    // R_MIPS_PC32 + R_MIPS_64 + R_MIPS_NONE

    Paired relocations

    TODO

    Distributions

    Here is an incomplete list.

    • https://www.debian.org/ports/mips/
    • https://fedoraproject.org/wiki/Architectures
    • https://wiki.gentoo.org/wiki/Project:MIPS
    • https://wiki.netbsd.org/ports/
    • https://www.openbsd.org/plat.html
    • https://openwrt.org/docs/techref/targets/start

    FreeBSD 14 discontinued MIPS. MIPS code was removed startingsince 2021-12.

    Misc

    E_MIPS_* macros are considereddeprecated.



沪ICP备19023445号-2号
友情链接