Provide enums for DT_FLAGS and DT_FLAGS_1 (#200)
authorAndreas Ziegler <ziegler@einserver.de>
Thu, 4 Oct 2018 12:15:49 +0000 (14:15 +0200)
committerEli Bendersky <eliben@users.noreply.github.com>
Thu, 4 Oct 2018 12:15:49 +0000 (05:15 -0700)
* Provide enums for DT_FLAGS and DT_FLAGS_1

This change adds two enums with the name to value mappings
for the two flags fields in the dynamic section. The values
and corresponding names are taken from the elf/elf.h file
in the most recent glibc version.

The enums are also used to print the names instead of the
raw hex values for DT_FLAGS and DT_FLAGS_1 in
scripts/readelf.py.

Fixes: #189
* Add test file for DT_FLAGS/DT_FLAGS_1 parsing

The test file has the DF_BIND_NOW and DF_ORIGIN flags set
in DT_FLAGS as well as DF_1_NOW, DF_1_GLOBAL, DF_1_NOOPEN
and DF_1_ORIGIN flags in DF_FLAGS_1.

This is the source code for the dt_flags.elf file:

  #include <stdio.h>

  int function(const char *arg){
      printf("Hello, %s!", arg);
      return 0;
  }

and was compiled using the following command line:

$ gcc -shared -m32 \
  -Wl,-rpath,'$ORIGIN/lib',-z,global,-z,origin,-z,nodlopen,-z,now \
  -o testfiles_for_readelf/dt_flags.elf dt_flags.c

elftools/elf/descriptions.py
elftools/elf/enums.py
scripts/readelf.py
test/testfiles_for_readelf/dt_flags.elf [new file with mode: 0644]

index 022b0745bf43563a5010e661f7d7a0002a74be95..5e8ff6e5788a32ff5a821df4ba3864838e219227 100644 (file)
@@ -10,7 +10,7 @@ from .enums import (
     ENUM_D_TAG, ENUM_E_VERSION, ENUM_P_TYPE_BASE, ENUM_SH_TYPE_BASE,
     ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64,
     ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64, ENUM_RELOC_TYPE_MIPS,
-    ENUM_ATTR_TAG_ARM)
+    ENUM_ATTR_TAG_ARM, ENUM_DT_FLAGS, ENUM_DT_FLAGS_1)
 from .constants import P_FLAGS, SH_FLAGS, SUNW_SYMINFO_FLAGS, VER_FLAGS
 from ..common.py3compat import iteritems
 
@@ -119,6 +119,16 @@ def describe_dyn_tag(x):
     return _DESCR_D_TAG.get(x, _unknown)
 
 
+def describe_dt_flags(x):
+    return ' '.join(key[3:] for key, val in
+        sorted(ENUM_DT_FLAGS.items(), key=lambda t: t[1]) if x & val)
+
+
+def describe_dt_flags_1(x):
+    return ' '.join(key[5:] for key, val in
+        sorted(ENUM_DT_FLAGS_1.items(), key=lambda t: t[1]) if x & val)
+
+
 def describe_syminfo_flags(x):
     return ''.join(_DESCR_SYMINFO_FLAGS[flag] for flag in (
         SUNW_SYMINFO_FLAGS.SYMINFO_FLG_CAP,
index e37effa9a2c4caf24625edc699dac90d1e50babc..1ccbda6f07c177c42d1dbf5bd34f1ff11e615b4b 100644 (file)
@@ -605,6 +605,45 @@ ENUM_D_TAG.update(ENUM_D_TAG_SOLARIS)
 for k in ENUMMAP_EXTRA_D_TAG_MACHINE:
     ENUM_D_TAG.update(ENUMMAP_EXTRA_D_TAG_MACHINE[k])
 
+ENUM_DT_FLAGS = dict(
+    DF_ORIGIN=0x1,
+    DF_SYMBOLIC=0x2,
+    DF_TEXTREL=0x4,
+    DF_BIND_NOW=0x8,
+    DF_STATIC_TLS=0x10,
+)
+
+ENUM_DT_FLAGS_1 = dict(
+    DF_1_NOW=0x1,
+    DF_1_GLOBAL=0x2,
+    DF_1_GROUP=0x4,
+    DF_1_NODELETE=0x8,
+    DF_1_LOADFLTR=0x10,
+    DF_1_INITFIRST=0x20,
+    DF_1_NOOPEN=0x40,
+    DF_1_ORIGIN=0x80,
+    DF_1_DIRECT=0x100,
+    DF_1_TRANS=0x200,
+    DF_1_INTERPOSE=0x400,
+    DF_1_NODEFLIB=0x800,
+    DF_1_NODUMP=0x1000,
+    DF_1_CONFALT=0x2000,
+    DF_1_ENDFILTEE=0x4000,
+    DF_1_DISPRELDNE=0x8000,
+    DF_1_DISPRELPND=0x10000,
+    DF_1_NODIRECT=0x20000,
+    DF_1_IGNMULDEF=0x40000,
+    DF_1_NOKSYMS=0x80000,
+    DF_1_NOHDR=0x100000,
+    DF_1_EDITED=0x200000,
+    DF_1_NORELOC=0x400000,
+    DF_1_SYMINTPOSE=0x800000,
+    DF_1_GLOBAUDIT=0x1000000,
+    DF_1_SINGLETON=0x2000000,
+    DF_1_STUB=0x4000000,
+    DF_1_PIE=0x8000000,
+)
+
 ENUM_RELOC_TYPE_MIPS = dict(
     R_MIPS_NONE=0,
     R_MIPS_16=1,
index 8535119fb597f40afdeb0d55d97291c23e790570..087218a129e9ae0ec0302fbed52782d2e7d5d8bd 100755 (executable)
@@ -37,7 +37,8 @@ from elftools.elf.descriptions import (
     describe_sh_type, describe_sh_flags,
     describe_symbol_type, describe_symbol_bind, describe_symbol_visibility,
     describe_symbol_shndx, describe_reloc_type, describe_dyn_tag,
-    describe_ver_flags, describe_note, describe_attr_tag_arm
+    describe_dt_flags, describe_dt_flags_1, describe_ver_flags, describe_note,
+    describe_attr_tag_arm
     )
 from elftools.elf.constants import E_FLAGS
 from elftools.elf.constants import E_FLAGS_MASKS
@@ -425,6 +426,10 @@ class ReadElf(object):
                     parsed = 'Library soname: [%s]' % tag.soname
                 elif tag.entry.d_tag.endswith(('SZ', 'ENT')):
                     parsed = '%i (bytes)' % tag['d_val']
+                elif tag.entry.d_tag == 'DT_FLAGS':
+                    parsed = describe_dt_flags(tag.entry.d_val)
+                elif tag.entry.d_tag == 'DT_FLAGS_1':
+                    parsed = 'Flags: %s' % describe_dt_flags_1(tag.entry.d_val)
                 elif tag.entry.d_tag.endswith(('NUM', 'COUNT')):
                     parsed = '%i' % tag['d_val']
                 elif tag.entry.d_tag == 'DT_PLTREL':
diff --git a/test/testfiles_for_readelf/dt_flags.elf b/test/testfiles_for_readelf/dt_flags.elf
new file mode 100644 (file)
index 0000000..17574dd
Binary files /dev/null and b/test/testfiles_for_readelf/dt_flags.elf differ