Many improvements to MIPS flags handling to make output consistent with GNU binutils...
authorAG <github@mzpqnxow.com>
Sun, 26 Nov 2017 13:57:43 +0000 (08:57 -0500)
committerEli Bendersky <eliben@users.noreply.github.com>
Sun, 26 Nov 2017 13:57:43 +0000 (05:57 -0800)
* Add EF_MIPS_PIC for E_FLAGS for statically linked MIPS-I executable produced by MUSL

pyelftools picked up CPIC but not PIC

binutils readelf says:
  Flags:                             0x1007, noreorder, pic, cpic, o32, mips1

pyelftools said (before this change):
  Flags:                             0x1007, noreorder, cpic, o32, mips1

Reproduce with the binary available at:

https://github.com/mzpqnxow/embedded-toolkit/blob/master/prebuilt_static_bins/gdbserver/gdbserver-6.8-mips-i-rtl819x-lexra

* Fix order of fix, was "cpic, pic" needs to be "pic, cpic", reordered the if statement to address this

* - Improve reporting on MIPS flags, fix many inconsistencies with GNU binutils
- Fix `desrciption` typo that raises fatal exception when encountering an unknown ABI
- Add E_FLAGS_MASKS constants to simplify ABI logic

* Add masks for E_FLAGS to simplify ABI logic

elftools/elf/constants.py
scripts/readelf.py

index 7c898080f0736507d8781117892800e5fa97d644..f9023c9bcdd00c9de69c494631c8b989f4d2e92a 100644 (file)
@@ -34,6 +34,7 @@ class E_FLAGS(object):
     EF_MIPS_64BIT_WHIRL=16
     EF_MIPS_ABI2=32
     EF_MIPS_ABI_ON32=64
+    EF_MIPS_32BITMODE = 256
     EF_MIPS_NAN2008=1024
     EF_MIPS_ARCH=0xf0000000
     EF_MIPS_ARCH_1=0x00000000
@@ -46,6 +47,20 @@ class E_FLAGS(object):
     EF_MIPS_ARCH_32R2=0x70000000
     EF_MIPS_ARCH_64R2=0x80000000
 
+
+class E_FLAGS_MASKS(object):
+    """Masks to be used for convenience when working with E_FLAGS
+
+    This is a simplified approach that is also used by GNU binutils
+    readelf
+    """
+    EFM_MIPS_ABI = 0x0000F000
+    EFM_MIPS_ABI_O32 = 0x00001000
+    EFM_MIPS_ABI_O64 = 0x00002000
+    EFM_MIPS_ABI_EABI32 = 0x00003000
+    EFM_MIPS_ABI_EABI64 = 0x00004000
+
+
 class SHN_INDICES(object):
     """ Special section indices
     """
index a09ba7dd2c504da8af5769d22f8e2e74211acbe6..397dfbdf0cb47b11a0999c4d1b6a9355a9d88bb1 100755 (executable)
@@ -40,6 +40,7 @@ from elftools.elf.descriptions import (
     describe_ver_flags, describe_note, describe_attr_tag_arm
     )
 from elftools.elf.constants import E_FLAGS
+from elftools.elf.constants import E_FLAGS_MASKS
 from elftools.dwarf.dwarfinfo import DWARFInfo
 from elftools.dwarf.descriptions import (
     describe_reg_name, describe_attr_value, set_global_machine_arch,
@@ -134,17 +135,45 @@ class ReadElf(object):
                 if flags:
                     description += ', <unknown>'
             else:
-                desrciption += ', <unrecognized EABI>'
+                description += ', <unrecognized EABI>'
 
         elif self.elffile['e_machine'] == "EM_MIPS":
             if flags & E_FLAGS.EF_MIPS_NOREORDER:
                 description += ", noreorder"
+            if flags & E_FLAGS.EF_MIPS_PIC:
+                description += ", pic"
             if flags & E_FLAGS.EF_MIPS_CPIC:
                 description += ", cpic"
-            if not (flags & E_FLAGS.EF_MIPS_ABI2) and not (flags & E_FLAGS.EF_MIPS_ABI_ON32):
+            if (flags & E_FLAGS.EF_MIPS_ABI2):
+                description += ", abi2"
+            if (flags & E_FLAGS.EF_MIPS_32BITMODE):
+                description += ", 32bitmode"
+            if (flags & E_FLAGS_MASKS.EFM_MIPS_ABI_O32):
                 description += ", o32"
+            elif (flags & E_FLAGS_MASKS.EFM_MIPS_ABI_O64):
+                description += ", o64"
+            elif (flags & E_FLAGS_MASKS.EFM_MIPS_ABI_EABI32):
+                description += ", eabi32"
+            elif (flags & E_FLAGS_MASKS.EFM_MIPS_ABI_EABI64):
+                description += ", eabi64"
             if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_1:
                 description += ", mips1"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_2:
+                description += ", mips2"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_3:
+                description += ", mips3"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_4:
+                description += ", mips4"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_5:
+                description += ", mips5"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_32R2:
+                description += ", mips32r2"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_64R2:
+                description += ", mips64r2"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_32:
+                description += ", mips32"
+            if (flags & E_FLAGS.EF_MIPS_ARCH) == E_FLAGS.EF_MIPS_ARCH_64:
+                description += ", mips64"
 
         return description