Better ARM support (with AArch64). Contributed by Dobromir Stefanov
authorEli Bendersky <eliben@gmail.com>
Sat, 8 Jun 2013 16:40:41 +0000 (09:40 -0700)
committerEli Bendersky <eliben@gmail.com>
Sat, 8 Jun 2013 16:40:41 +0000 (09:40 -0700)
CHANGES
elftools/elf/constants.py
elftools/elf/descriptions.py
elftools/elf/elffile.py
elftools/elf/enums.py
scripts/readelf.py
test/run_all_unittests.py
test/test_utils.py
test/testfiles_for_readelf/reloc_aarch64_gcc.o.elf [new file with mode: 0644]
test/testfiles_for_readelf/simple_aarch64_gcc.o.elf [new file with mode: 0644]
test/testfiles_for_readelf/simple_arm_gcc.o.elf [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 8a8bd2aa4e459526606e738beb76a790a1dfe574..26138ffd8344cb6ac0a9645e385c88299c07fe7a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,7 @@ Changelog
 
 + Version 0.22 (??)
 
+  - Better ARM support (including AArch64) - contributed by Dobromir Stefanov.
   - Added some initial support for parsing Solaris OpenCSW ELF files
     (contributed by Yann Rouillard).
   - Added some initial support for DWARF4 (as generated by gcc 4.8)
index 8387c0fbefd373f2c259222785d360cb6fdfd052..7eee4a71ea050d2e09be9e3c6275b7e8736756f4 100644 (file)
@@ -6,6 +6,26 @@
 # Eli Bendersky (eliben@gmail.com)
 # This code is in the public domain
 #-------------------------------------------------------------------------------
+
+class E_FLAGS(object):
+    """ Flag values for the e_flags field of the ELF header
+    """
+    EF_ARM_EABIMASK=0xFF000000
+    EF_ARM_EABI_VER1=0x01000000
+    EF_ARM_EABI_VER2=0x02000000
+    EF_ARM_EABI_VER3=0x03000000
+    EF_ARM_EABI_VER4=0x04000000
+    EF_ARM_EABI_VER5=0x05000000
+    EF_ARM_GCCMASK=0x00400FFF
+    EF_ARM_HASENTRY=0x02
+    EF_ARM_SYMSARESORTED=0x04
+    EF_ARM_DYNSYMSUSESEGIDX=0x8
+    EF_ARM_MAPSYMSFIRST=0x10
+    EF_ARM_LE8=0x00400000
+    EF_ARM_BE8=0x00800000
+    EF_ARM_ABI_FLOAT_SOFT=0x00000200
+    EF_ARM_ABI_FLOAT_HARD=0x00000400
+
 class SHN_INDICES(object):
     """ Special section indices
     """
index c1cda6a0dd6faf60f6e9098115d81910c6da8339..81ba7aea98648b243ec08853a717a63994fe7093 100644 (file)
@@ -7,8 +7,8 @@
 # This code is in the public domain
 #-------------------------------------------------------------------------------
 from .enums import (
-    ENUM_D_TAG, ENUM_E_VERSION, ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64
-    )
+    ENUM_D_TAG, ENUM_E_VERSION, ENUM_RELOC_TYPE_i386, ENUM_RELOC_TYPE_x64,
+        ENUM_RELOC_TYPE_ARM, ENUM_RELOC_TYPE_AARCH64)
 from .constants import P_FLAGS, SH_FLAGS, SUNW_SYMINFO_FLAGS
 from ..common.py3compat import iteritems
 
@@ -77,6 +77,10 @@ def describe_reloc_type(x, elffile):
         return _DESCR_RELOC_TYPE_i386.get(x, _unknown)
     elif arch == 'x64':
         return _DESCR_RELOC_TYPE_x64.get(x, _unknown)
+    elif arch == 'ARM':
+        return _DESCR_RELOC_TYPE_ARM.get(x, _unknown)
+    elif arch == 'AArch64':
+        return _DESCR_RELOC_TYPE_AARCH64.get(x, _unknown)
     else:
         return 'unrecognized: %-7x' % (x & 0xFFFFFFFF)
 
@@ -162,6 +166,8 @@ _DESCR_E_MACHINE = dict(
     EM_IA_64='Intel IA-64',
     EM_X86_64='Advanced Micro Devices X86-64',
     EM_AVR='Atmel AVR 8-bit microcontroller',
+    EM_ARM='ARM',
+    EM_AARCH64='AArch64',
     RESERVED='RESERVED',
 )
 
@@ -176,6 +182,11 @@ _DESCR_P_TYPE = dict(
     PT_GNU_EH_FRAME='GNU_EH_FRAME',
     PT_GNU_STACK='GNU_STACK',
     PT_GNU_RELRO='GNU_RELRO',
+    PT_ARM_ARCHEXT='ARM_ARCHEXT',
+    PT_ARM_EXIDX='ARM_EXIDX',
+    PT_ARM_UNWIND='ARM_UNWIND',
+    PT_AARCH64_ARCHEXT='AARCH64_ARCHEXT',
+    PT_AARCH64_UNWIND='AARCH64_UNWIND',
 )
 
 _DESCR_P_FLAGS = {
@@ -207,6 +218,10 @@ _DESCR_SH_TYPE = dict(
     SHT_GNU_verneed='VERNEED',
     SHT_GNU_versym='VERSYM',
     SHT_GNU_LIBLIST='GNU_LIBLIST',
+    SHT_ARM_EXIDX='ARM_EXIDX',
+    SHT_ARM_PREEMPTMAP='ARM_PREEMPTMAP',
+    SHT_ARM_ATTRIBUTES='ARM_ATTRIBUTES',
+    SHT_ARM_DEBUGOVERLAY='ARM_DEBUGOVERLAY',
 )
 
 _DESCR_SH_FLAGS = {
@@ -281,5 +296,11 @@ _DESCR_RELOC_TYPE_i386 = dict(
 _DESCR_RELOC_TYPE_x64 = dict(
         (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_x64))
 
+_DESCR_RELOC_TYPE_ARM = dict(
+        (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_ARM))
+
+_DESCR_RELOC_TYPE_AARCH64 = dict(
+        (v, k) for k, v in iteritems(ENUM_RELOC_TYPE_AARCH64))
+
 _DESCR_D_TAG = dict(
         (v, k) for k, v in iteritems(ENUM_D_TAG))
index ccb7e562a220009357cbb0c58d849726739a3fbc..ea3bf8a884cc390a9a75a27a29fdb951c03de3f1 100644 (file)
@@ -161,6 +161,8 @@ class ELFFile(object):
             return 'x86'
         elif self['e_machine'] == 'EM_ARM':
             return 'ARM'
+        elif self['e_machine'] == 'EM_AARCH64':
+            return 'AArch64'
         else:
             return '<unknown>'
 
index 121c287be2154cd67ee394f61c429a0173da1018..7989f495a26c99211b9f5f14ed416d8bc6dbe940 100644 (file)
@@ -47,6 +47,7 @@ ENUM_EI_OSABI = dict(
     ELFOSABI_OPENVMS=13,
     ELFOSABI_NSK=14,
     ELFOSABI_AROS=15,
+    ELFOSABI_ARM_AEABI=64,
     ELFOSABI_ARM=97,
     ELFOSABI_STANDALONE=255,
     _default_=Pass,
@@ -159,6 +160,7 @@ ENUM_E_MACHINE = dict(
     EM_ARCA=109,
     EM_UNICORE=110,
     EM_L10M=180,
+    EM_AARCH64=183,
     _default_=Pass,
 )
 
@@ -193,6 +195,10 @@ ENUM_SH_TYPE = dict(
     SHT_HIUSER=0xffffffff,
     SHT_AMD64_UNWIND=0x70000001,
     SHT_SUNW_syminfo=0x6ffffffc,
+    SHT_ARM_EXIDX=0x70000001,
+    SHT_ARM_PREEMPTMAP=0x70000002,
+    SHT_ARM_ATTRIBUTES=0x70000003,
+    SHT_ARM_DEBUGOVERLAY=0x70000004,
     _default_=Pass,
 )
 
@@ -212,6 +218,11 @@ ENUM_P_TYPE = dict(
     PT_GNU_EH_FRAME=0x6474e550,
     PT_GNU_STACK=0x6474e551,
     PT_GNU_RELRO=0x6474e552,
+    PT_ARM_ARCHEXT=0x70000000,
+    PT_ARM_EXIDX=0x70000001,
+    PT_ARM_UNWIND=0x70000001,
+    PT_AARCH64_ARCHEXT=0x70000000,
+    PT_AARCH64_UNWIND=0x70000001,
     _default_=Pass,
 )
 
@@ -456,3 +467,245 @@ ENUM_SUNW_SYMINFO_BOUNDTO = dict(
     _default_=Pass,
 )
 
+ENUM_RELOC_TYPE_ARM = dict(
+    R_ARM_NONE=0,
+    R_ARM_PC24=1,
+    R_ARM_ABS32=2,
+    R_ARM_REL32=3,
+    R_ARM_LDR_PC_G0=4,
+    R_ARM_ABS16=5,
+    R_ARM_ABS12=6,
+    R_ARM_THM_ABS5=7,
+    R_ARM_ABS8=8,
+    R_ARM_SBREL32=9,
+    R_ARM_THM_CALL=10,
+    R_ARM_THM_PC8=11,
+    R_ARM_BREL_ADJ=12,
+    R_ARM_SWI24=13,
+    R_ARM_THM_SWI8=14,
+    R_ARM_XPC25=15,
+    R_ARM_THM_XPC22=16,
+    R_ARM_TLS_DTPMOD32=17,
+    R_ARM_TLS_DTPOFF32=18,
+    R_ARM_TLS_TPOFF32=19,
+    R_ARM_COPY=20,
+    R_ARM_GLOB_DAT=21,
+    R_ARM_JUMP_SLOT=22,
+    R_ARM_RELATIVE=23,
+    R_ARM_GOTOFF32=24,
+    R_ARM_BASE_PREL=25,
+    R_ARM_GOT_BREL=26,
+    R_ARM_PLT32=27,
+    R_ARM_CALL=28,
+    R_ARM_JUMP24=29,
+    R_ARM_THM_JUMP24=30,
+    R_ARM_BASE_ABS=31,
+    R_ARM_ALU_PCREL_7_0=32,
+    R_ARM_ALU_PCREL_15_8=33,
+    R_ARM_ALU_PCREL_23_15=34,
+    R_ARM_LDR_SBREL_11_0_NC=35,
+    R_ARM_ALU_SBREL_19_12_NC=36,
+    R_ARM_ALU_SBREL_27_20_CK=37,
+    R_ARM_TARGET1=38,
+    R_ARM_SBREL31=39,
+    R_ARM_V4BX=40,
+    R_ARM_TARGET2=41,
+    R_ARM_PREL31=42,
+    R_ARM_MOVW_ABS_NC=43,
+    R_ARM_MOVT_ABS=44,
+    R_ARM_MOVW_PREL_NC=45,
+    R_ARM_MOVT_PREL=46,
+    R_ARM_THM_MOVW_ABS_NC=47,
+    R_ARM_THM_MOVT_ABS=48,
+    R_ARM_THM_MOVW_PREL_NC=49,
+    R_ARM_THM_MOVT_PREL=50,
+    R_ARM_THM_JUMP19=51,
+    R_ARM_THM_JUMP6=52,
+    R_ARM_THM_ALU_PREL_11_0=53,
+    R_ARM_THM_PC12=54,
+    R_ARM_ABS32_NOI=55,
+    R_ARM_REL32_NOI=56,
+    R_ARM_ALU_PC_G0_NC=57,
+    R_ARM_ALU_PC_G0=58,
+    R_ARM_ALU_PC_G1_NC=59,
+    R_ARM_ALU_PC_G1=60,
+    R_ARM_ALU_PC_G2=61,
+    R_ARM_LDR_PC_G1=62,
+    R_ARM_LDR_PC_G2=63,
+    R_ARM_LDRS_PC_G0=64,
+    R_ARM_LDRS_PC_G1=65,
+    R_ARM_LDRS_PC_G2=66,
+    R_ARM_LDC_PC_G0=67,
+    R_ARM_LDC_PC_G1=68,
+    R_ARM_LDC_PC_G2=69,
+    R_ARM_ALU_SB_G0_NC=70,
+    R_ARM_ALU_SB_G0=71,
+    R_ARM_ALU_SB_G1_NC=72,
+    R_ARM_ALU_SB_G1=73,
+    R_ARM_ALU_SB_G2=74,
+    R_ARM_LDR_SB_G0=75,
+    R_ARM_LDR_SB_G1=76,
+    R_ARM_LDR_SB_G2=77,
+    R_ARM_LDRS_SB_G0=78,
+    R_ARM_LDRS_SB_G1=79,
+    R_ARM_LDRS_SB_G2=80,
+    R_ARM_LDC_SB_G0=81,
+    R_ARM_LDC_SB_G1=82,
+    R_ARM_LDC_SB_G2=83,
+    R_ARM_MOVW_BREL_NC=84,
+    R_ARM_MOVT_BREL=85,
+    R_ARM_MOVW_BREL=86,
+    R_ARM_THM_MOVW_BREL_NC=87,
+    R_ARM_THM_MOVT_BREL=88,
+    R_ARM_THM_MOVW_BREL=89,
+    R_ARM_PLT32_ABS=94,
+    R_ARM_GOT_ABS=95,
+    R_ARM_GOT_PREL=96,
+    R_ARM_GOT_BREL12=97,
+    R_ARM_GOTOFF12=98,
+    R_ARM_GOTRELAX=99,
+    R_ARM_GNU_VTENTRY=100,
+    R_ARM_GNU_VTINHERIT=101,
+    R_ARM_THM_JUMP11=102,
+    R_ARM_THM_JUMP8=103,
+    R_ARM_TLS_GD32=104,
+    R_ARM_TLS_LDM32=105,
+    R_ARM_TLS_LDO32=106,
+    R_ARM_TLS_IE32=107,
+    R_ARM_TLS_LE32=108,
+    R_ARM_TLS_LDO12=109,
+    R_ARM_TLS_LE12=110,
+    R_ARM_TLS_IE12GP=111,
+    R_ARM_PRIVATE_0=112,
+    R_ARM_PRIVATE_1=113,
+    R_ARM_PRIVATE_2=114,
+    R_ARM_PRIVATE_3=115,
+    R_ARM_PRIVATE_4=116,
+    R_ARM_PRIVATE_5=117,
+    R_ARM_PRIVATE_6=118,
+    R_ARM_PRIVATE_7=119,
+    R_ARM_PRIVATE_8=120,
+    R_ARM_PRIVATE_9=121,
+    R_ARM_PRIVATE_10=122,
+    R_ARM_PRIVATE_11=123,
+    R_ARM_PRIVATE_12=124,
+    R_ARM_PRIVATE_13=125,
+    R_ARM_PRIVATE_14=126,
+    R_ARM_PRIVATE_15=127,
+    R_ARM_ME_TOO=128,
+    R_ARM_THM_TLS_DESCSEQ16=129,
+    R_ARM_THM_TLS_DESCSEQ32=130,
+    R_ARM_THM_GOT_BREL12=131,
+    R_ARM_IRELATIVE=140,
+)
+
+ENUM_RELOC_TYPE_AARCH64 = dict(
+    R_AARCH64_NONE=256,
+    R_AARCH64_ABS64=257,
+    R_AARCH64_ABS32=258,
+    R_AARCH64_ABS16=259,
+    R_AARCH64_PREL64=260,
+    R_AARCH64_PREL32=261,
+    R_AARCH64_PREL16=262,
+    R_AARCH64_MOVW_UABS_G0=263,
+    R_AARCH64_MOVW_UABS_G0_NC=264,
+    R_AARCH64_MOVW_UABS_G1=265,
+    R_AARCH64_MOVW_UABS_G1_NC=266,
+    R_AARCH64_MOVW_UABS_G2=267,
+    R_AARCH64_MOVW_UABS_G2_NC=268,
+    R_AARCH64_MOVW_UABS_G3=269,
+    R_AARCH64_MOVW_SABS_G0=270,
+    R_AARCH64_MOVW_SABS_G1=271,
+    R_AARCH64_MOVW_SABS_G2=272,
+    R_AARCH64_LD_PREL_LO19=273,
+    R_AARCH64_ADR_PREL_LO21=274,
+    R_AARCH64_ADR_PREL_PG_HI21=275,
+    R_AARCH64_ADR_PREL_PG_HI21_NC=276,
+    R_AARCH64_ADD_ABS_LO12_NC=277,
+    R_AARCH64_LDST8_ABS_LO12_NC=278,
+    R_AARCH64_TSTBR14=279,
+    R_AARCH64_CONDBR19=280,
+    R_AARCH64_JUMP26=282,
+    R_AARCH64_CALL26=283,
+    R_AARCH64_LDST16_ABS_LO12_NC=284,
+    R_AARCH64_LDST32_ABS_LO12_NC=285,
+    R_AARCH64_LDST64_ABS_LO12_NC=286,
+    R_AARCH64_MOVW_PREL_G0=287,
+    R_AARCH64_MOVW_PREL_G0_NC=288,
+    R_AARCH64_MOVW_PREL_G1=289,
+    R_AARCH64_MOVW_PREL_G1_NC=290,
+    R_AARCH64_MOVW_PREL_G2=291,
+    R_AARCH64_MOVW_PREL_G2_NC=292,
+    R_AARCH64_MOVW_PREL_G3=293,
+    R_AARCH64_MOVW_GOTOFF_G0=300,
+    R_AARCH64_MOVW_GOTOFF_G0_NC=301,
+    R_AARCH64_MOVW_GOTOFF_G1=302,
+    R_AARCH64_MOVW_GOTOFF_G1_NC=303,
+    R_AARCH64_MOVW_GOTOFF_G2=304,
+    R_AARCH64_MOVW_GOTOFF_G2_NC=305,
+    R_AARCH64_MOVW_GOTOFF_G3=306,
+    R_AARCH64_GOTREL64=307,
+    R_AARCH64_GOTREL32=308,
+    R_AARCH64_GOT_LD_PREL19=309,
+    R_AARCH64_LD64_GOTOFF_LO15=310,
+    R_AARCH64_ADR_GOT_PAGE=311,
+    R_AARCH64_LD64_GOT_LO12_NC=312,
+    R_AARCH64_TLSGD_ADR_PREL21=512,
+    R_AARCH64_TLSGD_ADR_PAGE21=513,
+    R_AARCH64_TLSGD_ADD_LO12_NC=514,
+    R_AARCH64_TLSGD_MOVW_G1=515,
+    R_AARCH64_TLSGD_MOVW_G0_NC=516,
+    R_AARCH64_TLSLD_ADR_PREL21=517,
+    R_AARCH64_TLSLD_ADR_PAGE21=518,
+    R_AARCH64_TLSLD_ADD_LO12_NC=519,
+    R_AARCH64_TLSLD_MOVW_G1=520,
+    R_AARCH64_TLSLD_MOVW_G0_NC=521,
+    R_AARCH64_TLSLD_LD_PREL19=522,
+    R_AARCH64_TLSLD_MOVW_DTPREL_G2=523,
+    R_AARCH64_TLSLD_MOVW_DTPREL_G1=524,
+    R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC=525,
+    R_AARCH64_TLSLD_MOVW_DTPREL_G0=526,
+    R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC=527,
+    R_AARCH64_TLSLD_ADD_DTPREL_HI12=528,
+    R_AARCH64_TLSLD_ADD_DTPREL_LO12=529,
+    R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC=530,
+    R_AARCH64_TLSLD_LDST8_DTPREL_LO12=531,
+    R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC=532,
+    R_AARCH64_TLSLD_LDST16_DTPREL_LO12=533,
+    R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC=534,
+    R_AARCH64_TLSLD_LDST32_DTPREL_LO12=535,
+    R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC=536,
+    R_AARCH64_TLSLD_LDST64_DTPREL_LO12=537,
+    R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC=538,
+    R_AARCH64_TLSIE_MOVW_GOTTPREL_G1=539,
+    R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC=540,
+    R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21=541,
+    R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC=542,
+    R_AARCH64_TLSIE_LD_GOTTPREL_PREL19=543,
+    R_AARCH64_TLSLE_MOVW_TPREL_G2=544,
+    R_AARCH64_TLSLE_MOVW_TPREL_G1=545,
+    R_AARCH64_TLSLE_MOVW_TPREL_G1_NC=546,
+    R_AARCH64_TLSLE_MOVW_TPREL_G0=547,
+    R_AARCH64_TLSLE_MOVW_TPREL_G0_NC=548,
+    R_AARCH64_TLSLE_ADD_TPREL_HI12=549,
+    R_AARCH64_TLSLE_ADD_TPREL_LO12=550,
+    R_AARCH64_TLSLE_ADD_TPREL_LO12_NC=551,
+    R_AARCH64_TLSLE_LDST8_TPREL_LO12=552,
+    R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC=553,
+    R_AARCH64_TLSLE_LDST16_TPREL_LO12=554,
+    R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC=555,
+    R_AARCH64_TLSLE_LDST32_TPREL_LO12=556,
+    R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC=557,
+    R_AARCH64_TLSLE_LDST64_TPREL_LO12=558,
+    R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC=559,
+    R_AARCH64_COPY=1024,
+    R_AARCH64_GLOB_DAT=1025,
+    R_AARCH64_JUMP_SLOT=1026,
+    R_AARCH64_RELATIVE=1027,
+    R_AARCH64_TLS_DTPREL64=1028,
+    R_AARCH64_TLS_DTPMOD64=1029,
+    R_AARCH64_TLS_TPREL64=1030,
+    R_AARCH64_TLS_DTPREL32=1031,
+    R_AARCH64_TLS_DTPMOD32=1032,
+    R_AARCH64_TLS_TPREL32=1033,
+)
index 720106d5d5532381b1b6a701e22a0d35618fb4d4..e45de22e8bdfabe07348bc99d6b66afa870d2da6 100755 (executable)
@@ -34,6 +34,7 @@ from elftools.elf.descriptions import (
     describe_symbol_type, describe_symbol_bind, describe_symbol_visibility,
     describe_symbol_shndx, describe_reloc_type, describe_dyn_tag,
     )
+from elftools.elf.constants import E_FLAGS
 from elftools.dwarf.dwarfinfo import DWARFInfo
 from elftools.dwarf.descriptions import (
     describe_reg_name, describe_attr_value, set_global_machine_arch,
@@ -94,8 +95,9 @@ class ReadElf(object):
         self._emit('  Start of section headers:          %s' %
                 header['e_shoff'])
         self._emitline(' (bytes into file)')
-        self._emitline('  Flags:                             %s' %
-                self._format_hex(header['e_flags']))
+        self._emitline('  Flags:                             %s%s' %
+                (self._format_hex(header['e_flags']),
+                self.decode_flags(header['e_flags'])))
         self._emitline('  Size of this header:               %s (bytes)' %
                 header['e_ehsize'])
         self._emitline('  Size of program headers:           %s (bytes)' %
@@ -109,6 +111,17 @@ class ReadElf(object):
         self._emitline('  Section header string table index: %s' %
                 header['e_shstrndx'])
 
+    def decode_flags(self, flags):
+        description = ""
+        if self.elffile['e_machine'] == "EM_ARM":
+            if flags & E_FLAGS.EF_ARM_HASENTRY:
+                description += ", has entry point"
+
+            version = flags & E_FLAGS.EF_ARM_EABIMASK
+            if version == E_FLAGS.EF_ARM_EABI_VER5:
+                description += ", Version5 EABI"
+        return description
+
     def display_program_headers(self, show_heading=True):
         """ Display the ELF program headers.
             If show_heading is True, displays the heading for this information
@@ -286,10 +299,12 @@ class ReadElf(object):
     def display_dynamic_tags(self):
         """ Display the dynamic tags contained in the file
         """
+        has_dynamic_sections = False
         for section in self.elffile.iter_sections():
             if not isinstance(section, DynamicSection):
                 continue
 
+            has_dynamic_sections = True
             self._emitline("\nDynamic section at offset %s contains %s entries:" % (
                 self._format_hex(section['sh_offset']),
                 section.num_tags()))
@@ -325,6 +340,10 @@ class ReadElf(object):
                     padding,
                     '(%s)' % (tag.entry.d_tag[3:],),
                     parsed))
+        if not has_dynamic_sections:
+            # readelf only prints this if there is at least one segment
+            if self.elffile.num_segments():
+                self._emitline("\nThere is no dynamic section in this file.")
 
     def display_relocations(self):
         """ Display the relocations contained in the file
index f7291bc4dfdc5dec092949911a3b1349e52c3a56..70a57d66f780f0937b193897b60237e6d4bbbaf0 100755 (executable)
@@ -9,16 +9,25 @@
 #-------------------------------------------------------------------------------
 from __future__ import print_function
 
+import os, sys
+
 try:
     import unittest2 as unittest
 except ImportError:
     import unittest
 
 
-if __name__ == '__main__':
-    import os
+def main():
     if not os.path.isdir('test'):
         print('!! Please execute from the root directory of pyelftools')
+        return 1
     else:
         tests = unittest.TestLoader().discover('test', 'test*.py', 'test')
-        unittest.TextTestRunner().run(tests)
+        result = unittest.TextTestRunner().run(tests)
+        if result.wasSuccessful():
+            return 0
+        else:
+            return 1
+
+if __name__ == '__main__':
+    sys.exit(main())
index 314b6b53a877cc660aad53d30ea658ecb9ce9a03..b74f2e51f83fff4728adcb546b06e4c24b9a83cc 100644 (file)
@@ -45,17 +45,17 @@ class Test_parse_cstring_from_stream(unittest.TestCase):
         self.assertEqual(parse_cstring_from_stream(sio, 2348), text[2348:5000])
 
 
-class Test_preserve_stream_pos(object):
+class Test_preserve_stream_pos(unittest.TestCase):
     def test_basic(self):
-        sio = BytesIO('abcdef')
+        sio = BytesIO(b'abcdef')
         with preserve_stream_pos(sio):
             sio.seek(4)
-        self.assertEqual(stream.tell(), 0)
+        self.assertEqual(sio.tell(), 0)
 
         sio.seek(5)
         with preserve_stream_pos(sio):
             sio.seek(0)
-        self.assertEqual(stream.tell(), 5)
+        self.assertEqual(sio.tell(), 5)
 
 
 if __name__ == '__main__':
diff --git a/test/testfiles_for_readelf/reloc_aarch64_gcc.o.elf b/test/testfiles_for_readelf/reloc_aarch64_gcc.o.elf
new file mode 100644 (file)
index 0000000..25eb90c
Binary files /dev/null and b/test/testfiles_for_readelf/reloc_aarch64_gcc.o.elf differ
diff --git a/test/testfiles_for_readelf/simple_aarch64_gcc.o.elf b/test/testfiles_for_readelf/simple_aarch64_gcc.o.elf
new file mode 100644 (file)
index 0000000..9a60f83
Binary files /dev/null and b/test/testfiles_for_readelf/simple_aarch64_gcc.o.elf differ
diff --git a/test/testfiles_for_readelf/simple_arm_gcc.o.elf b/test/testfiles_for_readelf/simple_arm_gcc.o.elf
new file mode 100644 (file)
index 0000000..b678393
Binary files /dev/null and b/test/testfiles_for_readelf/simple_arm_gcc.o.elf differ