[01/57] Import elfio lib to easy our elf file generating.

Submitted by junyan.he@inbox.com on June 11, 2017, 5:49 a.m.

Details

Message ID 1497160243-6286-1-git-send-email-junyan.he@inbox.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Beignet

Not browsing as part of any series.

Commit Message

junyan.he@inbox.com June 11, 2017, 5:49 a.m.
From: Junyan He <junyan.he@intel.com>

Import this MIT license elf read/write lib. It just
has c++ header files and is easy to use, which can help
us  generate ELF format binary a lot.

Signed-off-by: Junyan He <junyan.he@intel.com>
Reviewed-by: Yang Rong <rong.r.yang@intel.com>
---
 backend/src/elfio/elf_types.hpp        | 749 +++++++++++++++++++++++++
 backend/src/elfio/elfio.hpp            | 848 ++++++++++++++++++++++++++++
 backend/src/elfio/elfio_dump.hpp       | 972 +++++++++++++++++++++++++++++++++
 backend/src/elfio/elfio_dynamic.hpp    | 253 +++++++++
 backend/src/elfio/elfio_header.hpp     | 146 +++++
 backend/src/elfio/elfio_note.hpp       | 166 ++++++
 backend/src/elfio/elfio_relocation.hpp | 369 +++++++++++++
 backend/src/elfio/elfio_section.hpp    | 296 ++++++++++
 backend/src/elfio/elfio_segment.hpp    | 220 ++++++++
 backend/src/elfio/elfio_strings.hpp    |  96 ++++
 backend/src/elfio/elfio_symbols.hpp    | 278 ++++++++++
 backend/src/elfio/elfio_utils.hpp      | 209 +++++++
 12 files changed, 4602 insertions(+)
 create mode 100644 backend/src/elfio/elf_types.hpp
 create mode 100644 backend/src/elfio/elfio.hpp
 create mode 100644 backend/src/elfio/elfio_dump.hpp
 create mode 100644 backend/src/elfio/elfio_dynamic.hpp
 create mode 100644 backend/src/elfio/elfio_header.hpp
 create mode 100644 backend/src/elfio/elfio_note.hpp
 create mode 100644 backend/src/elfio/elfio_relocation.hpp
 create mode 100644 backend/src/elfio/elfio_section.hpp
 create mode 100644 backend/src/elfio/elfio_segment.hpp
 create mode 100644 backend/src/elfio/elfio_strings.hpp
 create mode 100644 backend/src/elfio/elfio_symbols.hpp
 create mode 100644 backend/src/elfio/elfio_utils.hpp

Patch hide | download patch | download mbox

diff --git a/backend/src/elfio/elf_types.hpp b/backend/src/elfio/elf_types.hpp
new file mode 100644
index 0000000..1b90c4c
--- /dev/null
+++ b/backend/src/elfio/elf_types.hpp
@@ -0,0 +1,749 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFTYPES_H
+#define ELFTYPES_H
+
+#ifndef ELFIO_NO_OWN_TYPES
+    #if !defined(ELFIO_NO_CSTDINT) && !defined(ELFIO_NO_INTTYPES)
+        #include <stdint.h>
+    #else
+        typedef unsigned char  uint8_t;
+        typedef signed char    int8_t;
+        typedef unsigned short uint16_t;
+        typedef signed short   int16_t;
+        #ifdef _MSC_VER
+            typedef unsigned __int32 uint32_t;
+            typedef signed   __int32 int32_t;
+            typedef unsigned __int64 uint64_t;
+            typedef signed   __int64 int64_t;
+        #else
+            typedef unsigned int       uint32_t;
+            typedef signed   int       int32_t;
+            typedef unsigned long long uint64_t;
+            typedef signed   long long int64_t;
+        #endif // _MSC_VER
+    #endif // ELFIO_NO_CSTDINT
+#endif // ELFIO_NO_OWN_TYPES
+
+namespace ELFIO {
+
+// Attention! Platform depended definitions.
+typedef uint16_t Elf_Half;
+typedef uint32_t Elf_Word;
+typedef int32_t  Elf_Sword;
+typedef uint64_t Elf_Xword;
+typedef int64_t  Elf_Sxword;
+
+typedef uint32_t Elf32_Addr;
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+
+#define Elf32_Half Elf_Half
+#define Elf64_Half Elf_Half
+#define Elf32_Word Elf_Word
+#define Elf64_Word Elf_Word
+#define Elf32_Sword Elf_Sword
+#define Elf64_Sword Elf_Sword
+
+///////////////////////
+// ELF Header Constants
+
+// File type
+#define ET_NONE        0
+#define ET_REL         1
+#define ET_EXEC        2
+#define ET_DYN         3
+#define ET_CORE        4
+#define ET_LOOS   0xFE00
+#define ET_HIOS   0xFEFF
+#define ET_LOPROC 0xFF00
+#define ET_HIPROC 0xFFFF
+
+
+#define EM_NONE          0   // No machine
+#define EM_M32           1   // AT&T WE 32100
+#define EM_SPARC         2   // SUN SPARC
+#define EM_386           3   // Intel 80386
+#define EM_68K           4   // Motorola m68k family
+#define EM_88K           5   // Motorola m88k family
+#define EM_486           6   // Intel 80486// Reserved for future use
+#define EM_860           7   // Intel 80860
+#define EM_MIPS          8   // MIPS R3000 (officially, big-endian only)
+#define EM_S370          9   // IBM System/370
+#define EM_MIPS_RS3_LE   10  // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated
+#define EM_res011        11  // Reserved
+#define EM_res012        12  // Reserved
+#define EM_res013        13  // Reserved
+#define EM_res014        14  // Reserved
+#define EM_PARISC        15  // HPPA
+#define EM_res016        16  // Reserved
+#define EM_VPP550        17  // Fujitsu VPP500
+#define EM_SPARC32PLUS   18  // Sun's "v8plus"
+#define EM_960           19  // Intel 80960
+#define EM_PPC           20  // PowerPC
+#define EM_PPC64         21  // 64-bit PowerPC
+#define EM_S390          22  // IBM S/390
+#define EM_SPU           23  // Sony/Toshiba/IBM SPU
+#define EM_res024        24  // Reserved
+#define EM_res025        25  // Reserved
+#define EM_res026        26  // Reserved
+#define EM_res027        27  // Reserved
+#define EM_res028        28  // Reserved
+#define EM_res029        29  // Reserved
+#define EM_res030        30  // Reserved
+#define EM_res031        31  // Reserved
+#define EM_res032        32  // Reserved
+#define EM_res033        33  // Reserved
+#define EM_res034        34  // Reserved
+#define EM_res035        35  // Reserved
+#define EM_V800          36  // NEC V800 series
+#define EM_FR20          37  // Fujitsu FR20
+#define EM_RH32          38  // TRW RH32
+#define EM_MCORE         39  // Motorola M*Core // May also be taken by Fujitsu MMA
+#define EM_RCE           39  // Old name for MCore
+#define EM_ARM           40  // ARM
+#define EM_OLD_ALPHA     41  // Digital Alpha
+#define EM_SH            42  // Renesas (formerly Hitachi) / SuperH SH
+#define EM_SPARCV9       43  // SPARC v9 64-bit
+#define EM_TRICORE       44  // Siemens Tricore embedded processor
+#define EM_ARC           45  // ARC Cores
+#define EM_H8_300        46  // Renesas (formerly Hitachi) H8/300
+#define EM_H8_300H       47  // Renesas (formerly Hitachi) H8/300H
+#define EM_H8S           48  // Renesas (formerly Hitachi) H8S
+#define EM_H8_500        49  // Renesas (formerly Hitachi) H8/500
+#define EM_IA_64         50  // Intel IA-64 Processor
+#define EM_MIPS_X        51  // Stanford MIPS-X
+#define EM_COLDFIRE      52  // Motorola Coldfire
+#define EM_68HC12        53  // Motorola M68HC12
+#define EM_MMA           54  // Fujitsu Multimedia Accelerator
+#define EM_PCP           55  // Siemens PCP
+#define EM_NCPU          56  // Sony nCPU embedded RISC processor
+#define EM_NDR1          57  // Denso NDR1 microprocesspr
+#define EM_STARCORE      58  // Motorola Star*Core processor
+#define EM_ME16          59  // Toyota ME16 processor
+#define EM_ST100         60  // STMicroelectronics ST100 processor
+#define EM_TINYJ         61  // Advanced Logic Corp. TinyJ embedded processor
+#define EM_X86_64        62  // Advanced Micro Devices X86-64 processor
+#define EM_PDSP          63  // Sony DSP Processor
+#define EM_PDP10         64  // Digital Equipment Corp. PDP-10
+#define EM_PDP11         65  // Digital Equipment Corp. PDP-11
+#define EM_FX66          66  // Siemens FX66 microcontroller
+#define EM_ST9PLUS       67  // STMicroelectronics ST9+ 8/16 bit microcontroller
+#define EM_ST7           68  // STMicroelectronics ST7 8-bit microcontroller
+#define EM_68HC16        69  // Motorola MC68HC16 Microcontroller
+#define EM_68HC11        70  // Motorola MC68HC11 Microcontroller
+#define EM_68HC08        71  // Motorola MC68HC08 Microcontroller
+#define EM_68HC05        72  // Motorola MC68HC05 Microcontroller
+#define EM_SVX           73  // Silicon Graphics SVx
+#define EM_ST19          74  // STMicroelectronics ST19 8-bit cpu
+#define EM_VAX           75  // Digital VAX
+#define EM_CRIS          76  // Axis Communications 32-bit embedded processor
+#define EM_JAVELIN       77  // Infineon Technologies 32-bit embedded cpu
+#define EM_FIREPATH      78  // Element 14 64-bit DSP processor
+#define EM_ZSP           79  // LSI Logic's 16-bit DSP processor
+#define EM_MMIX          80  // Donald Knuth's educational 64-bit processor
+#define EM_HUANY         81  // Harvard's machine-independent format
+#define EM_PRISM         82  // SiTera Prism
+#define EM_AVR           83  // Atmel AVR 8-bit microcontroller
+#define EM_FR30          84  // Fujitsu FR30
+#define EM_D10V          85  // Mitsubishi D10V
+#define EM_D30V          86  // Mitsubishi D30V
+#define EM_V850          87  // NEC v850
+#define EM_M32R          88  // Renesas M32R (formerly Mitsubishi M32R)
+#define EM_MN10300       89  // Matsushita MN10300
+#define EM_MN10200       90  // Matsushita MN10200
+#define EM_PJ            91  // picoJava
+#define EM_OPENRISC      92  // OpenRISC 32-bit embedded processor
+#define EM_ARC_A5        93  // ARC Cores Tangent-A5
+#define EM_XTENSA        94  // Tensilica Xtensa Architecture
+#define EM_VIDEOCORE     95  // Alphamosaic VideoCore processor
+#define EM_TMM_GPP       96  // Thompson Multimedia General Purpose Processor
+#define EM_NS32K         97  // National Semiconductor 32000 series
+#define EM_TPC           98  // Tenor Network TPC processor
+#define EM_SNP1K         99  // Trebia SNP 1000 processor
+#define EM_ST200         100 // STMicroelectronics ST200 microcontroller
+#define EM_IP2K          101 // Ubicom IP2022 micro controller
+#define EM_MAX           102 // MAX Processor
+#define EM_CR            103 // National Semiconductor CompactRISC
+#define EM_F2MC16        104 // Fujitsu F2MC16
+#define EM_MSP430        105 // TI msp430 micro controller
+#define EM_BLACKFIN      106 // ADI Blackfin
+#define EM_SE_C33        107 // S1C33 Family of Seiko Epson processors
+#define EM_SEP           108 // Sharp embedded microprocessor
+#define EM_ARCA          109 // Arca RISC Microprocessor
+#define EM_UNICORE       110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
+#define EM_EXCESS        111 // eXcess: 16/32/64-bit configurable embedded CPU
+#define EM_DXP           112 // Icera Semiconductor Inc. Deep Execution Processor
+#define EM_ALTERA_NIOS2  113 // Altera Nios II soft-core processor
+#define EM_CRX           114 // National Semiconductor CRX
+#define EM_XGATE         115 // Motorola XGATE embedded processor
+#define EM_C166          116 // Infineon C16x/XC16x processor
+#define EM_M16C          117 // Renesas M16C series microprocessors
+#define EM_DSPIC30F      118 // Microchip Technology dsPIC30F Digital Signal Controller
+#define EM_CE            119 // Freescale Communication Engine RISC core
+#define EM_M32C          120 // Renesas M32C series microprocessors
+#define EM_res121        121 // Reserved
+#define EM_res122        122 // Reserved
+#define EM_res123        123 // Reserved
+#define EM_res124        124 // Reserved
+#define EM_res125        125 // Reserved
+#define EM_res126        126 // Reserved
+#define EM_res127        127 // Reserved
+#define EM_res128        128 // Reserved
+#define EM_res129        129 // Reserved
+#define EM_res130        130 // Reserved
+#define EM_TSK3000       131 // Altium TSK3000 core
+#define EM_RS08          132 // Freescale RS08 embedded processor
+#define EM_res133        133 // Reserved
+#define EM_ECOG2         134 // Cyan Technology eCOG2 microprocessor
+#define EM_SCORE         135 // Sunplus Score
+#define EM_SCORE7        135 // Sunplus S+core7 RISC processor
+#define EM_DSP24         136 // New Japan Radio (NJR) 24-bit DSP Processor
+#define EM_VIDEOCORE3    137 // Broadcom VideoCore III processor
+#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture
+#define EM_SE_C17        139 // Seiko Epson C17 family
+#define EM_TI_C6000      140 // Texas Instruments TMS320C6000 DSP family
+#define EM_TI_C2000      141 // Texas Instruments TMS320C2000 DSP family
+#define EM_TI_C5500      142 // Texas Instruments TMS320C55x DSP family
+#define EM_res143        143 // Reserved
+#define EM_res144        144 // Reserved
+#define EM_res145        145 // Reserved
+#define EM_res146        146 // Reserved
+#define EM_res147        147 // Reserved
+#define EM_res148        148 // Reserved
+#define EM_res149        149 // Reserved
+#define EM_res150        150 // Reserved
+#define EM_res151        151 // Reserved
+#define EM_res152        152 // Reserved
+#define EM_res153        153 // Reserved
+#define EM_res154        154 // Reserved
+#define EM_res155        155 // Reserved
+#define EM_res156        156 // Reserved
+#define EM_res157        157 // Reserved
+#define EM_res158        158 // Reserved
+#define EM_res159        159 // Reserved
+#define EM_MMDSP_PLUS    160 // STMicroelectronics 64bit VLIW Data Signal Processor
+#define EM_CYPRESS_M8C   161 // Cypress M8C microprocessor
+#define EM_R32C          162 // Renesas R32C series microprocessors
+#define EM_TRIMEDIA      163 // NXP Semiconductors TriMedia architecture family
+#define EM_QDSP6         164 // QUALCOMM DSP6 Processor
+#define EM_8051          165 // Intel 8051 and variants
+#define EM_STXP7X        166 // STMicroelectronics STxP7x family
+#define EM_NDS32         167 // Andes Technology compact code size embedded RISC processor family
+#define EM_ECOG1         168 // Cyan Technology eCOG1X family
+#define EM_ECOG1X        168 // Cyan Technology eCOG1X family
+#define EM_MAXQ30        169 // Dallas Semiconductor MAXQ30 Core Micro-controllers
+#define EM_XIMO16        170 // New Japan Radio (NJR) 16-bit DSP Processor
+#define EM_MANIK         171 // M2000 Reconfigurable RISC Microprocessor
+#define EM_CRAYNV2       172 // Cray Inc. NV2 vector architecture
+#define EM_RX            173 // Renesas RX family
+#define EM_METAG         174 // Imagination Technologies META processor architecture
+#define EM_MCST_ELBRUS   175 // MCST Elbrus general purpose hardware architecture
+#define EM_ECOG16        176 // Cyan Technology eCOG16 family
+#define EM_CR16          177 // National Semiconductor CompactRISC 16-bit processor
+#define EM_ETPU          178 // Freescale Extended Time Processing Unit
+#define EM_SLE9X         179 // Infineon Technologies SLE9X core
+#define EM_L1OM          180 // Intel L1OM
+#define EM_INTEL181      181 // Reserved by Intel
+#define EM_INTEL182      182 // Reserved by Intel
+#define EM_res183        183 // Reserved by ARM
+#define EM_res184        184 // Reserved by ARM
+#define EM_AVR32         185 // Atmel Corporation 32-bit microprocessor family
+#define EM_STM8          186 // STMicroeletronics STM8 8-bit microcontroller
+#define EM_TILE64        187 // Tilera TILE64 multicore architecture family
+#define EM_TILEPRO       188 // Tilera TILEPro multicore architecture family
+#define EM_MICROBLAZE    189 // Xilinx MicroBlaze 32-bit RISC soft processor core
+#define EM_CUDA          190 // NVIDIA CUDA architecture 
+#define EM_TILEGX        191 // Tilera TILE-Gx multicore architecture family
+#define EM_CLOUDSHIELD   192 // CloudShield architecture family
+#define EM_COREA_1ST     193 // KIPO-KAIST Core-A 1st generation processor family
+#define EM_COREA_2ND     194 // KIPO-KAIST Core-A 2nd generation processor family
+#define EM_ARC_COMPACT2  195 // Synopsys ARCompact V2
+#define EM_OPEN8         196 // Open8 8-bit RISC soft processor core
+#define EM_RL78          197 // Renesas RL78 family
+#define EM_VIDEOCORE5    198 // Broadcom VideoCore V processor
+#define EM_78KOR         199 // Renesas 78KOR family
+#define EM_56800EX       200 // Freescale 56800EX Digital Signal Controller (DSC)
+#define EM_BA1           201 // Beyond BA1 CPU architecture
+#define EM_BA2           202 // Beyond BA2 CPU architecture
+#define EM_XCORE         203 // XMOS xCORE processor family
+#define EM_MCHP_PIC      204 // Microchip 8-bit PIC(r) family
+#define EM_INTEL205      205 // Reserved by Intel
+#define EM_INTEL206      206 // Reserved by Intel
+#define EM_INTEL207      207 // Reserved by Intel
+#define EM_INTEL208      208 // Reserved by Intel
+#define EM_INTEL209      209 // Reserved by Intel
+#define EM_KM32          210 // KM211 KM32 32-bit processor
+#define EM_KMX32         211 // KM211 KMX32 32-bit processor
+#define EM_KMX16         212 // KM211 KMX16 16-bit processor
+#define EM_KMX8          213 // KM211 KMX8 8-bit processor
+#define EM_KVARC         214 // KM211 KVARC processor
+#define EM_CDP           215 // Paneve CDP architecture family
+#define EM_COGE          216 // Cognitive Smart Memory Processor
+#define EM_COOL          217 // iCelero CoolEngine
+#define EM_NORC          218 // Nanoradio Optimized RISC
+#define EM_CSR_KALIMBA   219 // CSR Kalimba architecture family
+#define EM_Z80           220 // Zilog Z80
+#define EM_VISIUM        221 // Controls and Data Services VISIUMcore processor
+#define EM_FT32          222 // FTDI Chip FT32 high performance 32-bit RISC architecture
+#define EM_MOXIE         223 // Moxie processor family
+#define EM_AMDGPU        224 // AMD GPU architecture
+#define EM_RISCV         243 // RISC-V
+#define EM_LANAI         244 // Lanai processor
+#define EM_CEVA          245 // CEVA Processor Architecture Family
+#define EM_CEVA_X2       246 // CEVA X2 Processor Family
+#define EM_BPF           247 // Linux BPF – in-kernel virtual machine
+
+// File version
+#define EV_NONE    0
+#define EV_CURRENT 1
+
+// Identification index
+#define EI_MAG0        0
+#define EI_MAG1        1
+#define EI_MAG2        2
+#define EI_MAG3        3
+#define EI_CLASS       4
+#define EI_DATA        5
+#define EI_VERSION     6
+#define EI_OSABI       7
+#define EI_ABIVERSION  8
+#define EI_PAD         9
+#define EI_NIDENT     16
+
+// Magic number
+#define ELFMAG0 0x7F
+#define ELFMAG1  'E'
+#define ELFMAG2  'L'
+#define ELFMAG3  'F'
+
+// File class
+#define ELFCLASSNONE 0
+#define ELFCLASS32   1
+#define ELFCLASS64   2
+
+// Encoding
+#define ELFDATANONE 0
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+// OS extensions
+#define ELFOSABI_NONE     0 // No extensions or unspecified
+#define ELFOSABI_HPUX     1 // Hewlett-Packard HP-UX
+#define ELFOSABI_NETBSD   2 // NetBSD
+#define ELFOSABI_LINUX    3 // Linux
+#define ELFOSABI_SOLARIS  6 // Sun Solaris
+#define ELFOSABI_AIX      7 // AIX
+#define ELFOSABI_IRIX     8 // IRIX
+#define ELFOSABI_FREEBSD  9 // FreeBSD
+#define ELFOSABI_TRU64   10 // Compaq TRU64 UNIX
+#define ELFOSABI_MODESTO 11 // Novell Modesto
+#define ELFOSABI_OPENBSD 12 // Open BSD
+#define ELFOSABI_OPENVMS 13 // Open VMS
+#define ELFOSABI_NSK     14 // Hewlett-Packard Non-Stop Kernel
+#define ELFOSABI_AROS    15 // Amiga Research OS
+#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS
+//                       64-255 Architecture-specific value range
+
+
+
+/////////////////////
+// Sections constants
+
+// Section indexes
+#define SHN_UNDEF          0
+#define SHN_LORESERVE 0xFF00
+#define SHN_LOPROC    0xFF00
+#define SHN_HIPROC    0xFF1F
+#define SHN_LOOS      0xFF20
+#define SHN_HIOS      0xFF3F
+#define SHN_ABS       0xFFF1
+#define SHN_COMMON    0xFFF2
+#define SHN_XINDEX    0xFFFF
+#define SHN_HIRESERVE 0xFFFF
+
+// Section types
+#define SHT_NULL                   0
+#define SHT_PROGBITS               1
+#define SHT_SYMTAB                 2
+#define SHT_STRTAB                 3
+#define SHT_RELA                   4
+#define SHT_HASH                   5
+#define SHT_DYNAMIC                6
+#define SHT_NOTE                   7
+#define SHT_NOBITS                 8
+#define SHT_REL                    9
+#define SHT_SHLIB                 10
+#define SHT_DYNSYM                11
+#define SHT_INIT_ARRAY            14
+#define SHT_FINI_ARRAY            15
+#define SHT_PREINIT_ARRAY         16
+#define SHT_GROUP                 17
+#define SHT_SYMTAB_SHNDX          18
+#define SHT_LOOS          0x60000000
+#define SHT_HIOS          0x6fffffff
+#define SHT_LOPROC        0x70000000
+#define SHT_HIPROC        0x7FFFFFFF
+#define SHT_LOUSER        0x80000000
+#define SHT_HIUSER        0xFFFFFFFF
+
+// Section attribute flags
+#define SHF_WRITE                   0x1
+#define SHF_ALLOC                   0x2
+#define SHF_EXECINSTR               0x4
+#define SHF_MERGE                  0x10
+#define SHF_STRINGS                0x20
+#define SHF_INFO_LINK              0x40
+#define SHF_LINK_ORDER             0x80
+#define SHF_OS_NONCONFORMING      0x100
+#define SHF_GROUP                 0x200
+#define SHF_TLS                   0x400
+#define SHF_MASKOS           0x0ff00000
+#define SHF_MASKPROC         0xF0000000
+
+// Section group flags
+#define GRP_COMDAT          0x1
+#define GRP_MASKOS   0x0ff00000
+#define GRP_MASKPROC 0xf0000000
+
+// Symbol binding
+#define STB_LOCAL     0
+#define STB_GLOBAL    1
+#define STB_WEAK      2
+#define STB_LOOS     10
+#define STB_HIOS     12
+#define STB_MULTIDEF 13
+#define STB_LOPROC   13
+#define STB_HIPROC   15
+
+// Symbol types
+#define STT_NOTYPE   0
+#define STT_OBJECT   1
+#define STT_FUNC     2
+#define STT_SECTION  3
+#define STT_FILE     4
+#define STT_COMMON   5
+#define STT_TLS      6
+#define STT_LOOS    10
+#define STT_HIOS    12
+#define STT_LOPROC  13
+#define STT_HIPROC  15
+
+// Symbol visibility
+#define STV_DEFAULT   0
+#define STV_INTERNAL  1
+#define STV_HIDDEN    2
+#define STV_PROTECTED 3
+
+// Undefined name
+#define STN_UNDEF 0
+
+// Relocation types
+#define R_386_NONE         0
+#define R_X86_64_NONE      0
+#define R_386_32           1
+#define R_X86_64_64        1
+#define R_386_PC32         2
+#define R_X86_64_PC32      2
+#define R_386_GOT32        3
+#define R_X86_64_GOT32     3
+#define R_386_PLT32        4
+#define R_X86_64_PLT32     4
+#define R_386_COPY         5
+#define R_X86_64_COPY      5
+#define R_386_GLOB_DAT     6
+#define R_X86_64_GLOB_DAT  6
+#define R_386_JMP_SLOT     7
+#define R_X86_64_JUMP_SLOT 7
+#define R_386_RELATIVE     8
+#define R_X86_64_RELATIVE  8
+#define R_386_GOTOFF       9
+#define R_X86_64_GOTPCREL  9
+#define R_386_GOTPC       10
+#define R_X86_64_32       10
+#define R_X86_64_32S      11
+#define R_X86_64_16       12
+#define R_X86_64_PC16     13
+#define R_X86_64_8        14
+#define R_X86_64_PC8      15
+#define R_X86_64_DTPMOD64 16
+#define R_X86_64_DTPOFF64 17
+#define R_X86_64_TPOFF64  18
+#define R_X86_64_TLSGD    19
+#define R_X86_64_TLSLD    20
+#define R_X86_64_DTPOFF32 21
+#define R_X86_64_GOTTPOFF 22
+#define R_X86_64_TPOFF32  23
+#define R_X86_64_PC64     24
+#define R_X86_64_GOTOFF64 25
+#define R_X86_64_GOTPC32  26
+#define R_X86_64_GOT64    27
+#define R_X86_64_GOTPCREL64      28
+#define R_X86_64_GOTPC64  29
+#define R_X86_64_GOTPLT64 30
+#define R_X86_64_PLTOFF64 31
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL    35
+#define R_X86_64_TLSDESC         36
+#define R_X86_64_IRELATIVE       37
+#define R_X86_64_GNU_VTINHERIT  250
+#define R_X86_64_GNU_VTENTRY    251
+
+// Segment types
+#define PT_NULL             0
+#define PT_LOAD             1
+#define PT_DYNAMIC          2
+#define PT_INTERP           3
+#define PT_NOTE             4
+#define PT_SHLIB            5
+#define PT_PHDR             6
+#define PT_TLS              7
+#define PT_LOOS    0x60000000
+#define PT_HIOS    0x6fffffff
+#define PT_LOPROC  0x70000000
+#define PT_HIPROC  0x7FFFFFFF
+
+// Segment flags
+#define PF_X                 1 // Execute
+#define PF_W                 2 // Write
+#define PF_R                 4 // Read
+#define PF_MASKOS   0x0ff00000 // Unspecified
+#define PF_MASKPROC 0xf0000000 // Unspecified
+
+// Dynamic Array Tags
+#define DT_NULL              0
+#define DT_NEEDED            1
+#define DT_PLTRELSZ          2
+#define DT_PLTGOT            3
+#define DT_HASH              4
+#define DT_STRTAB            5
+#define DT_SYMTAB            6
+#define DT_RELA              7
+#define DT_RELASZ            8
+#define DT_RELAENT           9
+#define DT_STRSZ            10
+#define DT_SYMENT           11
+#define DT_INIT             12
+#define DT_FINI             13
+#define DT_SONAME           14
+#define DT_RPATH            15
+#define DT_SYMBOLIC         16
+#define DT_REL              17
+#define DT_RELSZ            18
+#define DT_RELENT           19
+#define DT_PLTREL           20
+#define DT_DEBUG            21
+#define DT_TEXTREL          22
+#define DT_JMPREL           23
+#define DT_BIND_NOW         24
+#define DT_INIT_ARRAY       25
+#define DT_FINI_ARRAY       26
+#define DT_INIT_ARRAYSZ     27
+#define DT_FINI_ARRAYSZ     28
+#define DT_RUNPATH          29
+#define DT_FLAGS            30
+#define DT_ENCODING         32
+#define DT_PREINIT_ARRAY    32
+#define DT_PREINIT_ARRAYSZ  33
+#define DT_MAXPOSTAGS       34
+#define DT_LOOS     0x6000000D
+#define DT_HIOS     0x6ffff000
+#define DT_LOPROC   0x70000000
+#define DT_HIPROC   0x7FFFFFFF
+
+// DT_FLAGS values
+#define DF_ORIGIN     0x1
+#define DF_SYMBOLIC   0x2
+#define DF_TEXTREL    0x4
+#define DF_BIND_NOW   0x8
+#define DF_STATIC_TLS 0x10
+
+
+// ELF file header
+struct Elf32_Ehdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf_Half    e_type;
+    Elf_Half    e_machine;
+    Elf_Word    e_version;
+    Elf32_Addr  e_entry;
+    Elf32_Off   e_phoff;
+    Elf32_Off   e_shoff;
+    Elf_Word    e_flags;
+    Elf_Half    e_ehsize;
+    Elf_Half    e_phentsize;
+    Elf_Half    e_phnum;
+    Elf_Half    e_shentsize;
+    Elf_Half    e_shnum;
+    Elf_Half    e_shstrndx;
+};
+
+struct Elf64_Ehdr {
+    unsigned char e_ident[EI_NIDENT];
+    Elf_Half    e_type;
+    Elf_Half    e_machine;
+    Elf_Word    e_version;
+    Elf64_Addr  e_entry;
+    Elf64_Off   e_phoff;
+    Elf64_Off   e_shoff;
+    Elf_Word    e_flags;
+    Elf_Half    e_ehsize;
+    Elf_Half    e_phentsize;
+    Elf_Half    e_phnum;
+    Elf_Half    e_shentsize;
+    Elf_Half    e_shnum;
+    Elf_Half    e_shstrndx;
+};
+
+
+// Section header
+struct Elf32_Shdr {
+    Elf_Word   sh_name;
+    Elf_Word   sh_type;
+    Elf_Word   sh_flags;
+    Elf32_Addr sh_addr;
+    Elf32_Off  sh_offset;
+    Elf_Word   sh_size;
+    Elf_Word   sh_link;
+    Elf_Word   sh_info;
+    Elf_Word   sh_addralign;
+    Elf_Word   sh_entsize;
+};
+
+struct Elf64_Shdr {
+    Elf_Word   sh_name;
+    Elf_Word   sh_type;
+    Elf_Xword  sh_flags;
+    Elf64_Addr sh_addr;
+    Elf64_Off  sh_offset;
+    Elf_Xword  sh_size;
+    Elf_Word   sh_link;
+    Elf_Word   sh_info;
+    Elf_Xword  sh_addralign;
+    Elf_Xword  sh_entsize;
+};
+
+
+// Segment header
+struct Elf32_Phdr {
+    Elf_Word   p_type;
+    Elf32_Off  p_offset;
+    Elf32_Addr p_vaddr;
+    Elf32_Addr p_paddr;
+    Elf_Word   p_filesz;
+    Elf_Word   p_memsz;
+    Elf_Word   p_flags;
+    Elf_Word   p_align;
+};
+
+struct Elf64_Phdr {
+    Elf_Word   p_type;
+    Elf_Word   p_flags;
+    Elf64_Off  p_offset;
+    Elf64_Addr p_vaddr;
+    Elf64_Addr p_paddr;
+    Elf_Xword  p_filesz;
+    Elf_Xword  p_memsz;
+    Elf_Xword  p_align;
+};
+
+
+// Symbol table entry
+struct Elf32_Sym {
+    Elf_Word      st_name;
+    Elf32_Addr    st_value;
+    Elf_Word      st_size;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf_Half      st_shndx;
+};
+
+struct Elf64_Sym {
+    Elf_Word      st_name;
+    unsigned char st_info;
+    unsigned char st_other;
+    Elf_Half      st_shndx;
+    Elf64_Addr    st_value;
+    Elf_Xword     st_size;
+};
+
+
+#define ELF_ST_BIND(i)   ((i)>>4)
+#define ELF_ST_TYPE(i)   ((i)&0xf)
+#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
+
+#define ELF_ST_VISIBILITY(o) ((o)&0x3)
+
+
+// Relocation entries
+struct Elf32_Rel {
+    Elf32_Addr r_offset;
+    Elf_Word   r_info;
+};
+
+struct Elf32_Rela {
+    Elf32_Addr r_offset;
+    Elf_Word   r_info;
+    Elf_Sword  r_addend;
+};
+
+struct Elf64_Rel {
+    Elf64_Addr r_offset;
+    Elf_Xword  r_info;
+};
+
+struct Elf64_Rela {
+    Elf64_Addr r_offset;
+    Elf_Xword  r_info;
+    Elf_Sxword r_addend;
+};
+
+
+#define ELF32_R_SYM(i)    ((i)>>8)
+#define ELF32_R_TYPE(i)   ((unsigned char)(i))
+#define ELF32_R_INFO(s,t) (((s)<<8 )+(unsigned char)(t))
+
+#define ELF64_R_SYM(i)    ((i)>>32)
+#define ELF64_R_TYPE(i)   ((i)&0xffffffffL)
+#define ELF64_R_INFO(s,t) ((((int64_t)s)<<32)+((t)&0xffffffffL))
+
+// Dynamic structure
+struct Elf32_Dyn {
+    Elf_Sword d_tag;
+    union {
+        Elf_Word   d_val;
+        Elf32_Addr d_ptr;
+    } d_un;
+};
+
+struct Elf64_Dyn {
+    Elf_Sxword d_tag;
+    union {
+        Elf_Xword  d_val;
+        Elf64_Addr d_ptr;
+    } d_un;
+};
+
+} // namespace ELFIO
+
+#endif // ELFTYPES_H
diff --git a/backend/src/elfio/elfio.hpp b/backend/src/elfio/elfio.hpp
new file mode 100644
index 0000000..3a86c93
--- /dev/null
+++ b/backend/src/elfio/elfio.hpp
@@ -0,0 +1,848 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_HPP
+#define ELFIO_HPP
+
+#ifdef _MSC_VER
+#pragma warning ( push )
+#pragma warning(disable:4996)
+#pragma warning(disable:4355)
+#pragma warning(disable:4244)
+#endif
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+#include <vector>
+#include <deque>
+#include <iterator>
+#include <typeinfo>
+
+#include <elfio/elf_types.hpp>
+#include <elfio/elfio_utils.hpp>
+#include <elfio/elfio_header.hpp>
+#include <elfio/elfio_section.hpp>
+#include <elfio/elfio_segment.hpp>
+#include <elfio/elfio_strings.hpp>
+
+#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \
+TYPE                                           \
+get_##FNAME() const                            \
+{                                              \
+    return header->get_##FNAME();              \
+}
+
+#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME ) \
+TYPE                                               \
+get_##FNAME() const                                \
+{                                                  \
+    return header->get_##FNAME();                  \
+}                                                  \
+void                                               \
+set_##FNAME( TYPE val )                            \
+{                                                  \
+    header->set_##FNAME( val );                    \
+}                                                  \
+
+namespace ELFIO {
+
+//------------------------------------------------------------------------------
+class elfio
+{
+  public:
+//------------------------------------------------------------------------------
+    elfio() : sections( this ), segments( this )
+    {
+        header           = 0;
+        current_file_pos = 0;
+        create( ELFCLASS32, ELFDATA2LSB );
+    }
+
+//------------------------------------------------------------------------------
+    ~elfio()
+    {
+        clean();
+    }
+
+//------------------------------------------------------------------------------
+    void create( unsigned char file_class, unsigned char encoding )
+    {
+        clean();
+        convertor.setup( encoding );
+        header = create_header( file_class, encoding );
+        create_mandatory_sections();
+    }
+
+//------------------------------------------------------------------------------
+    bool load( const std::string& file_name )
+    {
+        std::ifstream stream;
+        stream.open( file_name.c_str(), std::ios::in | std::ios::binary );
+        if ( !stream ) {
+            return false;
+        }
+
+        return load(stream);
+    }
+
+//------------------------------------------------------------------------------
+    bool load( std::istream &stream )
+    {
+        clean();
+
+        unsigned char e_ident[EI_NIDENT];
+
+        // Read ELF file signature
+        stream.seekg( 0 );
+        stream.read( reinterpret_cast<char*>( &e_ident ), sizeof( e_ident ) );
+
+        // Is it ELF file?
+        if ( stream.gcount() != sizeof( e_ident ) ||
+             e_ident[EI_MAG0] != ELFMAG0    ||
+             e_ident[EI_MAG1] != ELFMAG1    ||
+             e_ident[EI_MAG2] != ELFMAG2    ||
+             e_ident[EI_MAG3] != ELFMAG3 ) {
+            return false;
+        }
+
+        if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) &&
+             ( e_ident[EI_CLASS] != ELFCLASS32 )) {
+            return false;
+        }
+
+        convertor.setup( e_ident[EI_DATA] );
+
+        header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] );
+        if ( 0 == header ) {
+            return false;
+        }
+        if ( !header->load( stream ) ) {
+            return false;
+        }
+
+        load_sections( stream );
+        load_segments( stream );
+
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    bool save( const std::string& file_name )
+    {
+        std::ofstream f( file_name.c_str(), std::ios::out | std::ios::binary );
+
+        if ( !f ) {
+            return false;
+        }
+
+        bool is_still_good = true;
+
+        // Define layout specific header fields
+        // The position of the segment table is fixed after the header.
+        // The position of the section table is variable and needs to be fixed
+        // before saving.
+        header->set_segments_num( segments.size() );
+        header->set_segments_offset( segments.size() ? header->get_header_size() : 0 );
+        header->set_sections_num( sections.size() );
+        header->set_sections_offset( 0 );
+
+        // Layout the first section right after the segment table
+        current_file_pos = header->get_header_size() +
+                    header->get_segment_entry_size() * header->get_segments_num();
+
+        is_still_good = layout_segments_and_their_sections();
+        is_still_good = is_still_good && layout_sections_without_segments();
+        is_still_good = is_still_good && layout_section_table();
+
+        is_still_good = is_still_good && save_header( f );
+        is_still_good = is_still_good && save_sections( f );
+        is_still_good = is_still_good && save_segments( f );
+
+        f.close();
+
+        return is_still_good;
+    }
+
+//------------------------------------------------------------------------------
+    // ELF header access functions
+    ELFIO_HEADER_ACCESS_GET( unsigned char, class              );
+    ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version        );
+    ELFIO_HEADER_ACCESS_GET( unsigned char, encoding           );
+    ELFIO_HEADER_ACCESS_GET( Elf_Word,      version            );
+    ELFIO_HEADER_ACCESS_GET( Elf_Half,      header_size        );
+    ELFIO_HEADER_ACCESS_GET( Elf_Half,      section_entry_size );
+    ELFIO_HEADER_ACCESS_GET( Elf_Half,      segment_entry_size );
+
+    ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi                 );
+    ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version            );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf_Half,      type                   );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf_Half,      machine                );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf_Word,      flags                  );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr,    entry                  );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off,     sections_offset        );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off,     segments_offset        );
+    ELFIO_HEADER_ACCESS_GET_SET( Elf_Half,      section_name_str_index );
+
+//------------------------------------------------------------------------------
+    const endianess_convertor& get_convertor() const
+    {
+        return convertor;
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Xword get_default_entry_size( Elf_Word section_type ) const
+    {
+        switch( section_type ) {
+        case SHT_RELA:
+            if ( header->get_class() == ELFCLASS64 ) {
+                return sizeof( Elf64_Rela );
+            }
+            else {
+                return sizeof( Elf32_Rela );
+            }
+        case SHT_REL:
+            if ( header->get_class() == ELFCLASS64 ) {
+                return sizeof( Elf64_Rel );
+            }
+            else {
+                return sizeof( Elf32_Rel );
+            }
+        case SHT_SYMTAB:
+            if ( header->get_class() == ELFCLASS64 ) {
+                return sizeof( Elf64_Sym );
+            }
+            else {
+                return sizeof( Elf32_Sym );
+            }
+        case SHT_DYNAMIC:
+            if ( header->get_class() == ELFCLASS64 ) {
+                return sizeof( Elf64_Dyn );
+            }
+            else {
+                return sizeof( Elf32_Dyn );
+            }
+        default:
+            return 0;
+        }
+    }
+
+//------------------------------------------------------------------------------
+  private:
+//------------------------------------------------------------------------------
+    void clean()
+    {
+        delete header;
+        header = 0;
+
+        std::vector<section*>::const_iterator it;
+        for ( it = sections_.begin(); it != sections_.end(); ++it ) {
+            delete *it;
+        }
+        sections_.clear();
+
+        std::vector<segment*>::const_iterator it1;
+        for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) {
+            delete *it1;
+        }
+        segments_.clear();
+    }
+
+//------------------------------------------------------------------------------
+    elf_header* create_header( unsigned char file_class, unsigned char encoding )
+    {
+        elf_header* new_header = 0;
+
+        if ( file_class == ELFCLASS64 ) {
+            new_header = new elf_header_impl< Elf64_Ehdr >( &convertor,
+                                                            encoding );
+        }
+        else if ( file_class == ELFCLASS32 ) {
+            new_header = new elf_header_impl< Elf32_Ehdr >( &convertor,
+                                                            encoding );
+        }
+        else {
+            return 0;
+        }
+
+        return new_header;
+    }
+
+//------------------------------------------------------------------------------
+    section* create_section()
+    {
+        section*      new_section;
+        unsigned char file_class = get_class();
+
+        if ( file_class == ELFCLASS64 ) {
+            new_section = new section_impl<Elf64_Shdr>( &convertor );
+        }
+        else if ( file_class == ELFCLASS32 ) {
+            new_section = new section_impl<Elf32_Shdr>( &convertor );
+        }
+        else {
+            return 0;
+        }
+
+        new_section->set_index( (Elf_Half)sections_.size() );
+        sections_.push_back( new_section );
+
+        return new_section;
+    }
+
+
+//------------------------------------------------------------------------------
+    segment* create_segment()
+    {
+        segment*      new_segment;
+        unsigned char file_class = header->get_class();
+
+        if ( file_class == ELFCLASS64 ) {
+            new_segment = new segment_impl<Elf64_Phdr>( &convertor );
+        }
+        else if ( file_class == ELFCLASS32 ) {
+            new_segment = new segment_impl<Elf32_Phdr>( &convertor );
+        }
+        else {
+            return 0;
+        }
+
+        new_segment->set_index( (Elf_Half)segments_.size() );
+        segments_.push_back( new_segment );
+
+        return new_segment;
+    }
+
+//------------------------------------------------------------------------------
+    void create_mandatory_sections()
+    {
+        // Create null section without calling to 'add_section' as no string
+        // section containing section names exists yet
+        section* sec0 = create_section();
+        sec0->set_index( 0 );
+        sec0->set_name( "" );
+        sec0->set_name_string_offset( 0 );
+
+        set_section_name_str_index( 1 );
+        section* shstrtab = sections.add( ".shstrtab" );
+        shstrtab->set_type( SHT_STRTAB );
+        shstrtab->set_addr_align( 1 );
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Half load_sections( std::istream& stream )
+    {
+        Elf_Half  entry_size = header->get_section_entry_size();
+        Elf_Half  num        = header->get_sections_num();
+        Elf64_Off offset     = header->get_sections_offset();
+
+        for ( Elf_Half i = 0; i < num; ++i ) {
+            section* sec = create_section();
+            sec->load( stream, (std::streamoff)offset + i * entry_size );
+            sec->set_index( i );
+            // To mark that the section is not permitted to reassign address
+            // during layout calculation
+            sec->set_address( sec->get_address() );
+        }
+
+        Elf_Half shstrndx = get_section_name_str_index();
+
+        if ( SHN_UNDEF != shstrndx ) {
+            string_section_accessor str_reader( sections[shstrndx] );
+            for ( Elf_Half i = 0; i < num; ++i ) {
+                Elf_Word offset = sections[i]->get_name_string_offset();
+                const char* p = str_reader.get_string( offset );
+                if ( p != 0 ) {
+                    sections[i]->set_name( p );
+                }
+            }
+        }
+
+        return num;
+    }
+
+//------------------------------------------------------------------------------
+    bool load_segments( std::istream& stream )
+    {
+        Elf_Half  entry_size = header->get_segment_entry_size();
+        Elf_Half  num        = header->get_segments_num();
+        Elf64_Off offset     = header->get_segments_offset();
+
+        for ( Elf_Half i = 0; i < num; ++i ) {
+            segment* seg;
+            unsigned char file_class = header->get_class();
+
+            if ( file_class == ELFCLASS64 ) {
+                seg = new segment_impl<Elf64_Phdr>( &convertor );
+            }
+            else if ( file_class == ELFCLASS32 ) {
+                seg = new segment_impl<Elf32_Phdr>( &convertor );
+            }
+            else {
+                return false;
+            }
+
+            seg->load( stream, (std::streamoff)offset + i * entry_size );
+            seg->set_index( i );
+
+            // Add sections to the segments (similar to readelfs algorithm)
+            Elf64_Off segBaseOffset = seg->get_offset();
+            Elf64_Off segEndOffset  = segBaseOffset + seg->get_file_size();
+            Elf64_Off segVBaseAddr = seg->get_virtual_address();
+            Elf64_Off segVEndAddr  = segVBaseAddr + seg->get_memory_size();
+            for( Elf_Half j = 0; j < sections.size(); ++j ) {
+                const section* psec = sections[j];
+
+                // SHF_ALLOC sections are matched based on the virtual address
+                // otherwise the file offset is matched
+                if( psec->get_flags() & SHF_ALLOC
+                      ? (segVBaseAddr <= psec->get_address()
+                          && psec->get_address() + psec->get_size()
+                           <= segVEndAddr)
+                      : (segBaseOffset <= psec->get_offset()
+                          && psec->get_offset() + psec->get_size()
+                           <= segEndOffset)) {
+                      seg->add_section_index( psec->get_index(),
+                                              psec->get_addr_align() );
+                }
+            }
+
+            // Add section into the segments' container
+            segments_.push_back( seg );
+        }
+
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    bool save_header( std::ofstream& f )
+    {
+        return header->save( f );
+    }
+
+//------------------------------------------------------------------------------
+    bool save_sections( std::ofstream& f )
+    {
+        for ( unsigned int i = 0; i < sections_.size(); ++i ) {
+            section *sec = sections_.at(i);
+
+            std::streampos headerPosition =
+                (std::streamoff)header->get_sections_offset() +
+                header->get_section_entry_size() * sec->get_index();
+
+            sec->save(f,headerPosition,sec->get_offset());
+        }
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    bool save_segments( std::ofstream& f )
+    {
+        for ( unsigned int i = 0; i < segments_.size(); ++i ) {
+            segment *seg = segments_.at(i);
+
+            std::streampos headerPosition = header->get_segments_offset()  +
+                header->get_segment_entry_size()*seg->get_index();
+
+            seg->save( f, headerPosition, seg->get_offset() );
+        }
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    bool is_section_without_segment( unsigned int section_index )
+    {
+        bool found = false;
+        
+        for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) {
+            for ( unsigned int k = 0;
+                  !found && ( k < segments[j]->get_sections_num() );
+                  ++k ) {
+                found = segments[j]->get_section_index_at( k ) == section_index;
+            }
+        }
+
+        return !found;
+    }
+
+//------------------------------------------------------------------------------
+    bool is_subsequence_of( segment* seg1, segment* seg2 )
+    {
+        // Return 'true' if sections of seg1 are a subset of sections in seg2
+        const std::vector<Elf_Half>& sections1 = seg1->get_sections();
+        const std::vector<Elf_Half>& sections2 = seg2->get_sections();
+
+        bool found = false;
+        if ( sections1.size() <  sections2.size() ) {
+            found = std::includes( sections2.begin(), sections2.end(),
+                                   sections1.begin(), sections1.end() );
+        }
+
+        return found;
+    }
+
+//------------------------------------------------------------------------------
+    std::vector<segment*> get_ordered_segments( )
+    {
+        std::vector<segment*> res;
+        std::deque<segment*>  worklist;
+        
+        res.reserve(segments.size());
+        std::copy( segments_.begin(), segments_.end(),
+                   std::back_inserter( worklist )) ;
+
+        // Bring the segments which start at address 0 to the front
+        size_t nextSlot = 0;
+        for( size_t i = 0; i < worklist.size(); ++i ) {
+            if( i != nextSlot && worklist[i]->is_offset_initialized()
+                && worklist[i]->get_offset() == 0 ) {
+                std::swap(worklist[i],worklist[nextSlot]);
+                ++nextSlot;
+            }
+        }
+
+        while ( !worklist.empty() ) {
+            segment *seg = worklist.front();
+            worklist.pop_front();
+
+            size_t i = 0;
+            for ( ; i < worklist.size(); ++i ) {
+                if ( is_subsequence_of( seg, worklist[i] ) ) {
+                    break;
+                }
+            }
+
+            if ( i < worklist.size() )
+                worklist.push_back(seg);
+            else
+                res.push_back(seg);
+        }
+
+        return res;
+    }
+
+
+//------------------------------------------------------------------------------
+    bool layout_sections_without_segments( )
+    {
+        for ( unsigned int i = 0; i < sections_.size(); ++i ) {
+            if ( is_section_without_segment( i ) ) {
+                section *sec = sections_[i];
+
+                Elf_Xword section_align = sec->get_addr_align();
+                if ( section_align > 1 && current_file_pos % section_align != 0 ) {
+                    current_file_pos += section_align -
+                                            current_file_pos % section_align;
+                }
+
+                if ( 0 != sec->get_index() )
+                  sec->set_offset(current_file_pos);
+
+                if ( SHT_NOBITS != sec->get_type() &&
+                     SHT_NULL   != sec->get_type() ) {
+                    current_file_pos += sec->get_size();
+                }
+            }
+        }
+
+        return true;
+    }
+
+
+//------------------------------------------------------------------------------
+    bool layout_segments_and_their_sections( )
+    {
+        std::vector<segment*>  worklist;
+        std::vector<bool>      section_generated(sections.size(),false);
+
+        // Get segments in a order in where segments which contain a
+        // sub sequence of other segments are located at the end
+        worklist = get_ordered_segments();
+
+        for ( unsigned int i = 0; i < worklist.size(); ++i ) {
+            Elf_Xword segment_memory   = 0;
+            Elf_Xword segment_filesize = 0;
+            Elf_Xword seg_start_pos    = current_file_pos;
+            segment* seg               = worklist[i];
+
+            // Special case: PHDR segment
+            // This segment contains the program headers but no sections
+            if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
+                seg_start_pos = header->get_segments_offset();
+                segment_memory = segment_filesize =
+                    header->get_segment_entry_size() * header->get_segments_num();
+            }
+            // Special case:
+            // Segments which start with the NULL section and have further sections
+            else if ( seg->get_sections_num() > 1
+                      && sections[seg->get_section_index_at( 0 )]->get_type() == SHT_NULL ) {
+                seg_start_pos = 0;
+                if ( seg->get_sections_num() ) {
+                    segment_memory = segment_filesize = current_file_pos;
+                }
+            }
+            // New segments with not generated sections
+            // have to be aligned
+            else if ( seg->get_sections_num()
+                     && !section_generated[seg->get_section_index_at( 0 )] ) {
+                Elf64_Off cur_page_alignment = current_file_pos % seg->get_align();
+                Elf64_Off req_page_alignment = seg->get_virtual_address() % seg->get_align();
+                Elf64_Off error              = req_page_alignment - cur_page_alignment;
+
+                current_file_pos += ( seg->get_align() + error ) % seg->get_align();
+                seg_start_pos = current_file_pos;
+            }
+            else if ( seg->get_sections_num() ) {
+                seg_start_pos = sections[seg->get_section_index_at( 0 )]->get_offset();
+            }
+
+            // Write segment's data
+            for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) {
+                Elf_Half index = seg->get_section_index_at( j );
+
+                section* sec = sections[ index ];
+
+                // The NULL section is always generated
+                if ( SHT_NULL == sec->get_type()) {
+                    section_generated[index] = true;
+                    continue;
+                }
+
+                Elf_Xword secAlign = 0;
+                // Fix up the alignment
+                if ( !section_generated[index] && sec->is_address_initialized()
+                    && SHT_NOBITS != sec->get_type()
+                    && SHT_NULL != sec->get_type() ) {
+                    // Align the sections based on the virtual addresses
+                    // when possible (this is what matters for execution)
+                    Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address();
+                    Elf64_Off cur_offset = current_file_pos - seg_start_pos;
+                    secAlign             = req_offset - cur_offset;
+                }
+                else if (!section_generated[index]) {
+                    // If no address has been specified then only the section
+                    // alignment constraint has to be matched
+					Elf_Xword align = sec->get_addr_align();
+					if (align == 0) {
+						align = 1;
+					}
+                    Elf64_Off error = current_file_pos % align;
+                    secAlign = ( align - error ) % align;
+                }
+                else {
+                    // Alignment for already generated sections
+                    secAlign = sec->get_offset() - seg_start_pos - segment_filesize;
+                }
+
+                // Determine the segment file and memory sizes
+                // Special case .tbss section (NOBITS) in non TLS segment
+                if ( (sec->get_flags() & SHF_ALLOC)
+                    && !( (sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS)
+                          && ( SHT_NOBITS == sec->get_type())) )
+                    segment_memory += sec->get_size() + secAlign;
+                if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
+                    segment_filesize += sec->get_size() + secAlign;
+
+                // Nothing to be done when generating nested segments
+                if(section_generated[index]) {
+                    continue;
+                }
+
+                current_file_pos += secAlign;
+
+                // Set the section addresses when missing
+                if ( !sec->is_address_initialized() )
+                    sec->set_address( seg->get_virtual_address()
+                                      + current_file_pos - seg_start_pos);
+
+                if ( 0 != sec->get_index() )
+                  sec->set_offset(current_file_pos);
+
+                if ( SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type() )
+                  current_file_pos += sec->get_size();
+                section_generated[index] = true;
+            }
+
+            seg->set_file_size( segment_filesize );
+            seg->set_memory_size( segment_memory );
+            seg->set_offset(seg_start_pos);
+        }
+
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    bool layout_section_table()
+    {
+        // Simply place the section table at the end for now
+        Elf64_Off alignmentError = current_file_pos % 4;
+        current_file_pos += ( 4 - alignmentError ) % 4;
+        header->set_sections_offset(current_file_pos);
+        return true;
+    }
+
+
+//------------------------------------------------------------------------------
+  public:
+    friend class Sections;
+    class Sections {
+      public:
+//------------------------------------------------------------------------------
+        Sections( elfio* parent_ ) :
+            parent( parent_ )
+        {
+        }
+
+//------------------------------------------------------------------------------
+        Elf_Half size() const
+        {
+            return (Elf_Half)parent->sections_.size();
+        }
+
+//------------------------------------------------------------------------------
+        section* operator[]( unsigned int index ) const
+        {
+            section* sec = 0;
+            
+            if ( index < parent->sections_.size() ) {
+                sec = parent->sections_[index];
+            }
+            
+            return sec;
+        }
+
+//------------------------------------------------------------------------------
+        section* operator[]( const std::string& name ) const
+        {
+            section* sec = 0;
+
+            std::vector<section*>::const_iterator it;
+            for ( it = parent->sections_.begin();
+                  it != parent->sections_.end();
+                  ++it ) {
+                if ( (*it)->get_name() == name ) {
+                    sec = *it;
+                    break;
+                }
+            }
+
+            return sec;
+        }
+
+//------------------------------------------------------------------------------
+        section* add( const std::string& name )
+        {
+            section* new_section = parent->create_section();
+            new_section->set_name( name );
+
+            Elf_Half str_index = parent->get_section_name_str_index();
+            section* string_table( parent->sections_[str_index] );
+            string_section_accessor str_writer( string_table );
+            Elf_Word pos = str_writer.add_string( name );
+            new_section->set_name_string_offset( pos );
+
+            return new_section;
+        }
+        
+//------------------------------------------------------------------------------
+        std::vector<section*>::iterator begin() {
+            return parent->sections_.begin();
+        }
+
+//------------------------------------------------------------------------------
+        std::vector<section*>::iterator end() {
+            return parent->sections_.end();
+        }
+
+//------------------------------------------------------------------------------
+      private:
+        elfio* parent;
+    } sections;
+
+//------------------------------------------------------------------------------
+  public:
+    friend class Segments;
+    class Segments {
+      public:
+//------------------------------------------------------------------------------
+        Segments( elfio* parent_ ) :
+            parent( parent_ )
+        {
+        }
+
+//------------------------------------------------------------------------------
+        Elf_Half size() const
+        {
+            return (Elf_Half)parent->segments_.size();
+        }
+
+//------------------------------------------------------------------------------
+        segment* operator[]( unsigned int index ) const
+        {
+            return parent->segments_[index];
+        }
+
+
+//------------------------------------------------------------------------------
+        segment* add()
+        {
+            return parent->create_segment();
+        }
+
+//------------------------------------------------------------------------------
+        std::vector<segment*>::iterator begin() {
+            return parent->segments_.begin();
+        }
+
+//------------------------------------------------------------------------------
+        std::vector<segment*>::iterator end() {
+            return parent->segments_.end();
+        }
+
+//------------------------------------------------------------------------------
+      private:
+        elfio* parent;
+    } segments;
+
+//------------------------------------------------------------------------------
+  private:
+    elf_header*           header;
+    std::vector<section*> sections_;
+    std::vector<segment*> segments_;
+    endianess_convertor   convertor;
+
+    Elf_Xword current_file_pos;
+};
+
+} // namespace ELFIO
+
+#include <elfio/elfio_symbols.hpp>
+#include <elfio/elfio_note.hpp>
+#include <elfio/elfio_relocation.hpp>
+#include <elfio/elfio_dynamic.hpp>
+
+#ifdef _MSC_VER
+#pragma warning ( pop )
+#endif
+
+#endif // ELFIO_HPP
diff --git a/backend/src/elfio/elfio_dump.hpp b/backend/src/elfio/elfio_dump.hpp
new file mode 100644
index 0000000..232b4f1
--- /dev/null
+++ b/backend/src/elfio/elfio_dump.hpp
@@ -0,0 +1,972 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_DUMP_HPP
+#define ELFIO_DUMP_HPP
+
+#include <algorithm>
+#include <string>
+#include <ostream>
+#include <sstream>
+#include <iomanip>
+#include <elfio/elfio.hpp>
+
+namespace ELFIO {
+
+
+static struct class_table_t {
+    const char  key;
+    const char* str;
+} class_table [] = 
+{
+    { ELFCLASS32, "ELF32" },
+    { ELFCLASS64, "ELF64" },
+};
+
+
+static struct endian_table_t {
+    const char  key;
+    const char* str;
+} endian_table [] = 
+{
+    { ELFDATANONE, "None"          },
+    { ELFDATA2LSB, "Little endian" },
+    { ELFDATA2MSB, "Big endian"    },
+};
+
+
+static struct version_table_t {
+    const Elf64_Word key;
+    const char*      str;
+} version_table [] = 
+{
+    { EV_NONE   , "None"    },
+    { EV_CURRENT, "Current" },
+};
+
+
+static struct type_table_t {
+    const Elf32_Half key;
+    const char*      str;
+} type_table [] = 
+{
+    { ET_NONE, "No file type"       },
+    { ET_REL , "Relocatable file"   },
+    { ET_EXEC, "Executable file"    },
+    { ET_DYN , "Shared object file" },
+    { ET_CORE, "Core file"          },
+};
+
+
+static struct machine_table_t {
+    const Elf64_Half key;
+    const char*      str;
+} machine_table [] = 
+{
+    { EM_NONE         , "No machine"                                                              },
+    { EM_M32          , "AT&T WE 32100"                                                           },
+    { EM_SPARC        , "SUN SPARC"                                                               },
+    { EM_386          , "Intel 80386"                                                             },
+    { EM_68K          , "Motorola m68k family"                                                    },
+    { EM_88K          , "Motorola m88k family"                                                    },
+    { EM_486          , "Intel 80486// Reserved for future use"                                   },
+    { EM_860          , "Intel 80860"                                                             },
+    { EM_MIPS         , "MIPS R3000 (officially, big-endian only)"                                },
+    { EM_S370         , "IBM System/370"                                                          },
+    { EM_MIPS_RS3_LE  , "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated"                  },
+    { EM_res011       , "Reserved"                                                                },
+    { EM_res012       , "Reserved"                                                                },
+    { EM_res013       , "Reserved"                                                                },
+    { EM_res014       , "Reserved"                                                                },
+    { EM_PARISC       , "HPPA"                                                                    },
+    { EM_res016       , "Reserved"                                                                },
+    { EM_VPP550       , "Fujitsu VPP500"                                                          },
+    { EM_SPARC32PLUS  , "Sun's v8plus"                                                            },
+    { EM_960          , "Intel 80960"                                                             },
+    { EM_PPC          , "PowerPC"                                                                 },
+    { EM_PPC64        , "64-bit PowerPC"                                                          },
+    { EM_S390         , "IBM S/390"                                                               },
+    { EM_SPU          , "Sony/Toshiba/IBM SPU"                                                    },
+    { EM_res024       , "Reserved"                                                                },
+    { EM_res025       , "Reserved"                                                                },
+    { EM_res026       , "Reserved"                                                                },
+    { EM_res027       , "Reserved"                                                                },
+    { EM_res028       , "Reserved"                                                                },
+    { EM_res029       , "Reserved"                                                                },
+    { EM_res030       , "Reserved"                                                                },
+    { EM_res031       , "Reserved"                                                                },
+    { EM_res032       , "Reserved"                                                                },
+    { EM_res033       , "Reserved"                                                                },
+    { EM_res034       , "Reserved"                                                                },
+    { EM_res035       , "Reserved"                                                                },
+    { EM_V800         , "NEC V800 series"                                                         },
+    { EM_FR20         , "Fujitsu FR20"                                                            },
+    { EM_RH32         , "TRW RH32"                                                                },
+    { EM_MCORE        , "Motorola M*Core // May also be taken by Fujitsu MMA"                     },
+    { EM_RCE          , "Old name for MCore"                                                      },
+    { EM_ARM          , "ARM"                                                                     },
+    { EM_OLD_ALPHA    , "Digital Alpha"                                                           },
+    { EM_SH           , "Renesas (formerly Hitachi) / SuperH SH"                                  },
+    { EM_SPARCV9      , "SPARC v9 64-bit"                                                         },
+    { EM_TRICORE      , "Siemens Tricore embedded processor"                                      },
+    { EM_ARC          , "ARC Cores"                                                               },
+    { EM_H8_300       , "Renesas (formerly Hitachi) H8/300"                                       },
+    { EM_H8_300H      , "Renesas (formerly Hitachi) H8/300H"                                      },
+    { EM_H8S          , "Renesas (formerly Hitachi) H8S"                                          },
+    { EM_H8_500       , "Renesas (formerly Hitachi) H8/500"                                       },
+    { EM_IA_64        , "Intel IA-64 Processor"                                                   },
+    { EM_MIPS_X       , "Stanford MIPS-X"                                                         },
+    { EM_COLDFIRE     , "Motorola Coldfire"                                                       },
+    { EM_68HC12       , "Motorola M68HC12"                                                        },
+    { EM_MMA          , "Fujitsu Multimedia Accelerator"                                          },
+    { EM_PCP          , "Siemens PCP"                                                             },
+    { EM_NCPU         , "Sony nCPU embedded RISC processor"                                       },
+    { EM_NDR1         , "Denso NDR1 microprocesspr"                                               },
+    { EM_STARCORE     , "Motorola Star*Core processor"                                            },
+    { EM_ME16         , "Toyota ME16 processor"                                                   },
+    { EM_ST100        , "STMicroelectronics ST100 processor"                                      },
+    { EM_TINYJ        , "Advanced Logic Corp. TinyJ embedded processor"                           },
+    { EM_X86_64       , "Advanced Micro Devices X86-64 processor"                                 },
+    { EM_PDSP         , "Sony DSP Processor"                                                      },
+    { EM_PDP10        , "Digital Equipment Corp. PDP-10"                                          },
+    { EM_PDP11        , "Digital Equipment Corp. PDP-11"                                          },
+    { EM_FX66         , "Siemens FX66 microcontroller"                                            },
+    { EM_ST9PLUS      , "STMicroelectronics ST9+ 8/16 bit microcontroller"                        },
+    { EM_ST7          , "STMicroelectronics ST7 8-bit microcontroller"                            },
+    { EM_68HC16       , "Motorola MC68HC16 Microcontroller"                                       },
+    { EM_68HC11       , "Motorola MC68HC11 Microcontroller"                                       },
+    { EM_68HC08       , "Motorola MC68HC08 Microcontroller"                                       },
+    { EM_68HC05       , "Motorola MC68HC05 Microcontroller"                                       },
+    { EM_SVX          , "Silicon Graphics SVx"                                                    },
+    { EM_ST19         , "STMicroelectronics ST19 8-bit cpu"                                       },
+    { EM_VAX          , "Digital VAX"                                                             },
+    { EM_CRIS         , "Axis Communications 32-bit embedded processor"                           },
+    { EM_JAVELIN      , "Infineon Technologies 32-bit embedded cpu"                               },
+    { EM_FIREPATH     , "Element 14 64-bit DSP processor"                                         },
+    { EM_ZSP          , "LSI Logic's 16-bit DSP processor"                                        },
+    { EM_MMIX         , "Donald Knuth's educational 64-bit processor"                             },
+    { EM_HUANY        , "Harvard's machine-independent format"                                    },
+    { EM_PRISM        , "SiTera Prism"                                                            },
+    { EM_AVR          , "Atmel AVR 8-bit microcontroller"                                         },
+    { EM_FR30         , "Fujitsu FR30"                                                            },
+    { EM_D10V         , "Mitsubishi D10V"                                                         },
+    { EM_D30V         , "Mitsubishi D30V"                                                         },
+    { EM_V850         , "NEC v850"                                                                },
+    { EM_M32R         , "Renesas M32R (formerly Mitsubishi M32R)"                                 },
+    { EM_MN10300      , "Matsushita MN10300"                                                      },
+    { EM_MN10200      , "Matsushita MN10200"                                                      },
+    { EM_PJ           , "picoJava"                                                                },
+    { EM_OPENRISC     , "OpenRISC 32-bit embedded processor"                                      },
+    { EM_ARC_A5       , "ARC Cores Tangent-A5"                                                    },
+    { EM_XTENSA       , "Tensilica Xtensa Architecture"                                           },
+    { EM_VIDEOCORE    , "Alphamosaic VideoCore processor"                                         },
+    { EM_TMM_GPP      , "Thompson Multimedia General Purpose Processor"                           },
+    { EM_NS32K        , "National Semiconductor 32000 series"                                     },
+    { EM_TPC          , "Tenor Network TPC processor"                                             },
+    { EM_SNP1K        , "Trebia SNP 1000 processor"                                               },
+    { EM_ST200        , "STMicroelectronics ST200 microcontroller"                                },
+    { EM_IP2K         , "Ubicom IP2022 micro controller"                                          },
+    { EM_MAX          , "MAX Processor"                                                           },
+    { EM_CR           , "National Semiconductor CompactRISC"                                      },
+    { EM_F2MC16       , "Fujitsu F2MC16"                                                          },
+    { EM_MSP430       , "TI msp430 micro controller"                                              },
+    { EM_BLACKFIN     , "ADI Blackfin"                                                            },
+    { EM_SE_C33       , "S1C33 Family of Seiko Epson processors"                                  },
+    { EM_SEP          , "Sharp embedded microprocessor"                                           },
+    { EM_ARCA         , "Arca RISC Microprocessor"                                                },
+    { EM_UNICORE      , "Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University" },
+    { EM_EXCESS       , "eXcess: 16/32/64-bit configurable embedded CPU"                          },
+    { EM_DXP          , "Icera Semiconductor Inc. Deep Execution Processor"                       },
+    { EM_ALTERA_NIOS2 , "Altera Nios II soft-core processor"                                      },
+    { EM_CRX          , "National Semiconductor CRX"                                              },
+    { EM_XGATE        , "Motorola XGATE embedded processor"                                       },
+    { EM_C166         , "Infineon C16x/XC16x processor"                                           },
+    { EM_M16C         , "Renesas M16C series microprocessors"                                     },
+    { EM_DSPIC30F     , "Microchip Technology dsPIC30F Digital Signal Controller"                 },
+    { EM_CE           , "Freescale Communication Engine RISC core"                                },
+    { EM_M32C         , "Renesas M32C series microprocessors"                                     },
+    { EM_res121       , "Reserved"                                                                },
+    { EM_res122       , "Reserved"                                                                },
+    { EM_res123       , "Reserved"                                                                },
+    { EM_res124       , "Reserved"                                                                },
+    { EM_res125       , "Reserved"                                                                },
+    { EM_res126       , "Reserved"                                                                },
+    { EM_res127       , "Reserved"                                                                },
+    { EM_res128       , "Reserved"                                                                },
+    { EM_res129       , "Reserved"                                                                },
+    { EM_res130       , "Reserved"                                                                },
+    { EM_TSK3000      , "Altium TSK3000 core"                                                     },
+    { EM_RS08         , "Freescale RS08 embedded processor"                                       },
+    { EM_res133       , "Reserved"                                                                },
+    { EM_ECOG2        , "Cyan Technology eCOG2 microprocessor"                                    },
+    { EM_SCORE        , "Sunplus Score"                                                           },
+    { EM_SCORE7       , "Sunplus S+core7 RISC processor"                                          },
+    { EM_DSP24        , "New Japan Radio (NJR) 24-bit DSP Processor"                              },
+    { EM_VIDEOCORE3   , "Broadcom VideoCore III processor"                                        },
+    { EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture"                            },
+    { EM_SE_C17       , "Seiko Epson C17 family"                                                  },
+    { EM_TI_C6000     , "Texas Instruments TMS320C6000 DSP family"                                },
+    { EM_TI_C2000     , "Texas Instruments TMS320C2000 DSP family"                                },
+    { EM_TI_C5500     , "Texas Instruments TMS320C55x DSP family"                                 },
+    { EM_res143       , "Reserved"                                                                },
+    { EM_res144       , "Reserved"                                                                },
+    { EM_res145       , "Reserved"                                                                },
+    { EM_res146       , "Reserved"                                                                },
+    { EM_res147       , "Reserved"                                                                },
+    { EM_res148       , "Reserved"                                                                },
+    { EM_res149       , "Reserved"                                                                },
+    { EM_res150       , "Reserved"                                                                },
+    { EM_res151       , "Reserved"                                                                },
+    { EM_res152       , "Reserved"                                                                },
+    { EM_res153       , "Reserved"                                                                },
+    { EM_res154       , "Reserved"                                                                },
+    { EM_res155       , "Reserved"                                                                },
+    { EM_res156       , "Reserved"                                                                },
+    { EM_res157       , "Reserved"                                                                },
+    { EM_res158       , "Reserved"                                                                },
+    { EM_res159       , "Reserved"                                                                },
+    { EM_MMDSP_PLUS   , "STMicroelectronics 64bit VLIW Data Signal Processor"                     },
+    { EM_CYPRESS_M8C  , "Cypress M8C microprocessor"                                              },
+    { EM_R32C         , "Renesas R32C series microprocessors"                                     },
+    { EM_TRIMEDIA     , "NXP Semiconductors TriMedia architecture family"                         },
+    { EM_QDSP6        , "QUALCOMM DSP6 Processor"                                                 },
+    { EM_8051         , "Intel 8051 and variants"                                                 },
+    { EM_STXP7X       , "STMicroelectronics STxP7x family"                                        },
+    { EM_NDS32        , "Andes Technology compact code size embedded RISC processor family"       },
+    { EM_ECOG1        , "Cyan Technology eCOG1X family"                                           },
+    { EM_ECOG1X       , "Cyan Technology eCOG1X family"                                           },
+    { EM_MAXQ30       , "Dallas Semiconductor MAXQ30 Core Micro-controllers"                      },
+    { EM_XIMO16       , "New Japan Radio (NJR) 16-bit DSP Processor"                              },
+    { EM_MANIK        , "M2000 Reconfigurable RISC Microprocessor"                                },
+    { EM_CRAYNV2      , "Cray Inc. NV2 vector architecture"                                       },
+    { EM_RX           , "Renesas RX family"                                                       },
+    { EM_METAG        , "Imagination Technologies META processor architecture"                    },
+    { EM_MCST_ELBRUS  , "MCST Elbrus general purpose hardware architecture"                       },
+    { EM_ECOG16       , "Cyan Technology eCOG16 family"                                           },
+    { EM_CR16         , "National Semiconductor CompactRISC 16-bit processor"                     },
+    { EM_ETPU         , "Freescale Extended Time Processing Unit"                                 },
+    { EM_SLE9X        , "Infineon Technologies SLE9X core"                                        },
+    { EM_L1OM         , "Intel L1OM"                                                              },
+    { EM_INTEL181     , "Reserved by Intel"                                                       },
+    { EM_INTEL182     , "Reserved by Intel"                                                       },
+    { EM_res183       , "Reserved by ARM"                                                         },
+    { EM_res184       , "Reserved by ARM"                                                         },
+    { EM_AVR32        , "Atmel Corporation 32-bit microprocessor family"                          },
+    { EM_STM8         , "STMicroeletronics STM8 8-bit microcontroller"                            },
+    { EM_TILE64       , "Tilera TILE64 multicore architecture family"                             },
+    { EM_TILEPRO      , "Tilera TILEPro multicore architecture family"                            },
+    { EM_MICROBLAZE   , "Xilinx MicroBlaze 32-bit RISC soft processor core"                       },
+    { EM_CUDA         , "NVIDIA CUDA architecture "                                               },
+};
+
+
+static struct section_type_table_t {
+    const Elf64_Half key;
+    const char*      str;
+} section_type_table [] = 
+{
+    { SHT_NULL         , "NULL"          },
+    { SHT_PROGBITS     , "PROGBITS"      },
+    { SHT_SYMTAB       , "SYMTAB"        },
+    { SHT_STRTAB       , "STRTAB"        },
+    { SHT_RELA         , "RELA"          },
+    { SHT_HASH         , "HASH"          },
+    { SHT_DYNAMIC      , "DYNAMIC"       },
+    { SHT_NOTE         , "NOTE"          },
+    { SHT_NOBITS       , "NOBITS"        },
+    { SHT_REL          , "REL"           },
+    { SHT_SHLIB        , "SHLIB"         },
+    { SHT_DYNSYM       , "DYNSYM"        },
+    { SHT_INIT_ARRAY   , "INIT_ARRAY"    },
+    { SHT_FINI_ARRAY   , "FINI_ARRAY"    },
+    { SHT_PREINIT_ARRAY, "PREINIT_ARRAY" },
+    { SHT_GROUP        , "GROUP"         },
+    { SHT_SYMTAB_SHNDX , "SYMTAB_SHNDX " },
+};
+
+
+static struct segment_type_table_t {
+    const Elf_Word key;
+    const char*    str;
+} segment_type_table [] = 
+{
+    { PT_NULL   , "NULL"    },
+    { PT_LOAD   , "LOAD"    },
+    { PT_DYNAMIC, "DYNAMIC" },
+    { PT_INTERP , "INTERP"  },
+    { PT_NOTE   , "NOTE"    },
+    { PT_SHLIB  , "SHLIB"   },
+    { PT_PHDR   , "PHDR"    },
+    { PT_TLS    , "TLS"     },
+};
+
+
+static struct segment_flag_table_t {
+    const Elf_Word key;
+    const char*    str;
+} segment_flag_table [] = 
+{
+    { 0, ""    },
+    { 1, "X"   },
+    { 2, "W"   },
+    { 3, "WX"  },
+    { 4, "R"   },
+    { 5, "RX"  },
+    { 6, "RW"  },
+    { 7, "RWX" },
+};
+
+
+static struct symbol_bind_t {
+    const Elf_Word key;
+    const char*    str;
+} symbol_bind_table [] = 
+{
+    { STB_LOCAL   , "LOCAL"    },
+    { STB_GLOBAL  , "GLOBAL"   },
+    { STB_WEAK    , "WEAK"     },
+    { STB_LOOS    , "LOOS"     },
+    { STB_HIOS    , "HIOS"     },
+    { STB_MULTIDEF, "MULTIDEF" },
+    { STB_LOPROC  , "LOPROC"   },
+    { STB_HIPROC  , "HIPROC"   },
+};
+
+
+static struct symbol_type_t {
+    const Elf_Word key;
+    const char*    str;
+} symbol_type_table [] = 
+{
+    { STT_NOTYPE , "NOTYPE"  },
+    { STT_OBJECT , "OBJECT"  },
+    { STT_FUNC   , "FUNC"    },
+    { STT_SECTION, "SECTION" },
+    { STT_FILE   , "FILE"    },
+    { STT_COMMON , "COMMON"  },
+    { STT_TLS    , "TLS"     },
+    { STT_LOOS   , "LOOS"    },
+    { STT_HIOS   , "HIOS"    },
+    { STT_LOPROC , "LOPROC"  },
+    { STT_HIPROC , "HIPROC"  },
+};
+
+
+static struct dynamic_tag_t {
+    const Elf_Word key;
+    const char*    str;
+} dynamic_tag_table [] = 
+{
+    { DT_NULL           , "NULL"            },
+    { DT_NEEDED         , "NEEDED"          },
+    { DT_PLTRELSZ       , "PLTRELSZ"        },
+    { DT_PLTGOT         , "PLTGOT"          },
+    { DT_HASH           , "HASH"            },
+    { DT_STRTAB         , "STRTAB"          },
+    { DT_SYMTAB         , "SYMTAB"          },
+    { DT_RELA           , "RELA"            },
+    { DT_RELASZ         , "RELASZ"          },
+    { DT_RELAENT        , "RELAENT"         },
+    { DT_STRSZ          , "STRSZ"           },
+    { DT_SYMENT         , "SYMENT"          },
+    { DT_INIT           , "INIT"            },
+    { DT_FINI           , "FINI"            },
+    { DT_SONAME         , "SONAME"          },
+    { DT_RPATH          , "RPATH"           },
+    { DT_SYMBOLIC       , "SYMBOLIC"        },
+    { DT_REL            , "REL"             },
+    { DT_RELSZ          , "RELSZ"           },
+    { DT_RELENT         , "RELENT"          },
+    { DT_PLTREL         , "PLTREL"          },
+    { DT_DEBUG          , "DEBUG"           },
+    { DT_TEXTREL        , "TEXTREL"         },
+    { DT_JMPREL         , "JMPREL"          },
+    { DT_BIND_NOW       , "BIND_NOW"        },
+    { DT_INIT_ARRAY     , "INIT_ARRAY"      },
+    { DT_FINI_ARRAY     , "FINI_ARRAY"      },
+    { DT_INIT_ARRAYSZ   , "INIT_ARRAYSZ"    },
+    { DT_FINI_ARRAYSZ   , "FINI_ARRAYSZ"    },
+    { DT_RUNPATH        , "RUNPATH"         },
+    { DT_FLAGS          , "FLAGS"           },
+    { DT_ENCODING       , "ENCODING"        },
+    { DT_PREINIT_ARRAY  , "PREINIT_ARRAY"   },
+    { DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" },
+    { DT_MAXPOSTAGS     , "MAXPOSTAGS"      },
+};
+
+static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64;
+
+//------------------------------------------------------------------------------
+class dump
+{
+#define DUMP_DEC_FORMAT( width ) std::setw(width) << std::setfill( ' ' ) << \
+                                 std::dec << std::right
+#define DUMP_HEX_FORMAT( width ) std::setw(width) << std::setfill( '0' ) << \
+                                 std::hex << std::right
+#define DUMP_STR_FORMAT( width ) std::setw(width) << std::setfill( ' ' ) << \
+                                 std::hex << std::left
+
+  public:
+//------------------------------------------------------------------------------
+    static void
+    header( std::ostream& out, const elfio& reader )
+    {
+        out << "ELF Header"     << std::endl                               << std::endl
+            << "  Class:      " << str_class( reader.get_class() )         << std::endl
+            << "  Encoding:   " << str_endian( reader.get_encoding() )     << std::endl
+            << "  ELFVersion: " << str_version( reader.get_elf_version() ) << std::endl
+            << "  Type:       " << str_type( reader.get_type() )           << std::endl
+            << "  Machine:    " << str_machine( reader.get_machine() )     << std::endl
+            << "  Version:    " << str_version( reader.get_version() )     << std::endl
+            << "  Entry:      " << "0x" << std::hex << reader.get_entry()  << std::endl
+            << "  Flags:      " << "0x" << std::hex << reader.get_flags()  << std::endl
+            << std::endl;
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    section_headers( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half n = reader.sections.size();
+
+        if ( n == 0 ) {
+            return;
+        }
+
+        out << "Section Headers:" << std::endl;
+        if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
+            out << "[  Nr ] Type              Addr     Size     ES Flg Lk Inf Al Name" << std::endl;
+        }
+        else {                                    // Output for 64-bit
+            out << "[  Nr ] Type              Addr             Size             ES   Flg" << std::endl
+                << "        Lk   Inf  Al      Name" << std::endl;
+        }
+            
+        for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
+            section* sec = reader.sections[i];
+            section_header( out, i, sec, reader.get_class() );
+        }
+        
+        out << "Key to Flags: W (write), A (alloc), X (execute)\n\n"
+            << std::endl;
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    section_header( std::ostream& out, Elf_Half no, const section* sec,
+                    unsigned char elf_class )
+    {
+        std::ios_base::fmtflags original_flags = out.flags();
+
+        if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " "
+                << DUMP_HEX_FORMAT(  8 ) << sec->get_address()                  << " "
+                << DUMP_HEX_FORMAT(  8 ) << sec->get_size()                     << " "
+                << DUMP_HEX_FORMAT(  2 ) << sec->get_entry_size()               << " "
+                << DUMP_STR_FORMAT(  3 ) << section_flags( sec->get_flags() )   << " "
+                << DUMP_HEX_FORMAT(  2 ) << sec->get_link()                     << " "
+                << DUMP_HEX_FORMAT(  3 ) << sec->get_info()                     << " "
+                << DUMP_HEX_FORMAT(  2 ) << sec->get_addr_align()               << " "
+                << DUMP_STR_FORMAT( 17 ) << sec->get_name()                     << " "
+                << std::endl;
+        }
+        else {                           // Output for 64-bit
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() ) << " "
+                << DUMP_HEX_FORMAT( 16 ) << sec->get_address()                  << " "
+                << DUMP_HEX_FORMAT( 16 ) << sec->get_size()                     << " "
+                << DUMP_HEX_FORMAT(  4 ) << sec->get_entry_size()               << " "
+                << DUMP_STR_FORMAT(  3 ) << section_flags( sec->get_flags() )   << " "
+                << std::endl
+                << "        "
+                << DUMP_HEX_FORMAT(  4 ) << sec->get_link()                     << " "
+                << DUMP_HEX_FORMAT(  4 ) << sec->get_info()                     << " "
+                << DUMP_HEX_FORMAT(  4 ) << sec->get_addr_align()               << "    "
+                << DUMP_STR_FORMAT( 17 ) << sec->get_name()                     << " "
+                << std::endl;
+        }
+
+        out.flags(original_flags);
+
+        return; 
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    segment_headers( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half n = reader.segments.size();
+        if ( n == 0 ) {
+            return;
+        }
+
+        out << "Segment headers:" << std::endl;
+        if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
+            out << "[  Nr ] Type           VirtAddr PhysAddr FileSize Mem.Size Flags    Align"
+                << std::endl;
+        }
+        else {                                    // Output for 64-bit
+            out << "[  Nr ] Type           VirtAddr         PhysAddr         Flags" << std::endl
+                << "                       FileSize         Mem.Size         Align"
+                << std::endl;
+        }
+            
+        for ( Elf_Half i = 0; i < n; ++i ) {
+            segment* seg = reader.segments[i];
+            segment_header( out, i, seg, reader.get_class() );
+        }
+            
+        out << std::endl;
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    segment_header( std::ostream& out, Elf_Half no, const segment* seg,
+                    unsigned int elf_class )
+    {
+        std::ios_base::fmtflags original_flags = out.flags();
+
+        if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() )  << " "
+                << DUMP_HEX_FORMAT(  8 ) << seg->get_virtual_address()           << " "
+                << DUMP_HEX_FORMAT(  8 ) << seg->get_physical_address()          << " "
+                << DUMP_HEX_FORMAT(  8 ) << seg->get_file_size()                 << " "
+                << DUMP_HEX_FORMAT(  8 ) << seg->get_memory_size()               << " "
+                << DUMP_STR_FORMAT(  8 ) << str_segment_flag( seg->get_flags() ) << " "
+                << DUMP_HEX_FORMAT(  8 ) << seg->get_align()                     << " "
+                << std::endl;
+        }
+        else {                           // Output for 64-bit
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() )  << " "
+                << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address()           << " "
+                << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address()          << " "
+                << DUMP_STR_FORMAT( 16 ) << str_segment_flag( seg->get_flags() ) << " "
+                << std::endl
+                << "                       "
+                << DUMP_HEX_FORMAT( 16 ) << seg->get_file_size()                 << " "
+                << DUMP_HEX_FORMAT( 16 ) << seg->get_memory_size()               << " "
+                << DUMP_HEX_FORMAT( 16 ) << seg->get_align()                     << " "
+                << std::endl;
+        }
+
+        out.flags(original_flags);
+    }
+    
+//------------------------------------------------------------------------------
+    static void
+    symbol_tables( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half n = reader.sections.size();
+        for ( Elf_Half i = 0; i < n; ++i ) {    // For all sections
+            section* sec = reader.sections[i];
+            if ( SHT_SYMTAB == sec->get_type() || SHT_DYNSYM == sec->get_type() ) {
+                symbol_section_accessor symbols( reader, sec );
+
+                Elf_Xword     sym_no = symbols.get_symbols_num();
+                if ( sym_no > 0 ) {
+                    out << "Symbol table (" << sec->get_name() << ")" << std::endl;
+                    if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
+                        out << "[  Nr ] Value    Size     Type    Bind      Sect Name"
+                            << std::endl;
+                    }
+                    else {                                    // Output for 64-bit
+                        out << "[  Nr ] Value            Size             Type    Bind      Sect" << std::endl
+                            << "        Name"
+                            << std::endl;
+                    }
+                    for ( Elf_Half i = 0; i < sym_no; ++i ) {
+                        std::string   name;
+                        Elf64_Addr    value   = 0;
+                        Elf_Xword     size    = 0;
+                        unsigned char bind    = 0;
+                        unsigned char type    = 0;
+                        Elf_Half      section = 0;
+                        unsigned char other   = 0;
+                        symbols.get_symbol( i, name, value, size, bind, type, section, other );
+                        symbol_table( out, i, name, value, size, bind, type, section, reader.get_class() );
+                    }
+
+                    out << std::endl;
+                }
+            }
+        }
+    }
+    
+//------------------------------------------------------------------------------
+    static void
+    symbol_table( std::ostream& out,
+                  Elf_Half      no,
+                  std::string&  name,
+                  Elf64_Addr    value,
+                  Elf_Xword     size,
+                  unsigned char bind,
+                  unsigned char type,
+                  Elf_Half      section,
+                  unsigned int  elf_class )
+    {
+        std::ios_base::fmtflags original_flags = out.flags();
+
+        if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_HEX_FORMAT(  8 ) << value                   << " "
+                << DUMP_HEX_FORMAT(  8 ) << size                    << " "
+                << DUMP_STR_FORMAT(  7 ) << str_symbol_type( type ) << " "
+                << DUMP_STR_FORMAT(  8 ) << str_symbol_bind( bind ) << " "
+                << DUMP_DEC_FORMAT(  5 ) << section                 << " "
+                << DUMP_STR_FORMAT(  1 ) << name                    << " "
+                << std::endl;
+        }
+        else {                           // Output for 64-bit
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_HEX_FORMAT( 16 ) << value                   << " "
+                << DUMP_HEX_FORMAT( 16 ) << size                    << " "
+                << DUMP_STR_FORMAT(  7 ) << str_symbol_type( type ) << " "
+                << DUMP_STR_FORMAT(  8 ) << str_symbol_bind( bind ) << " "
+                << DUMP_DEC_FORMAT(  5 ) << section                 << " "
+                << std::endl
+                << "        "
+                << DUMP_STR_FORMAT(  1 ) << name                    << " "
+                << std::endl;
+        }
+
+        out.flags(original_flags);
+    }
+    
+//------------------------------------------------------------------------------
+    static void
+    notes( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half no = reader.sections.size();
+        for ( Elf_Half i = 0; i < no; ++i ) {                 // For all sections
+            section* sec = reader.sections[i];
+            if ( SHT_NOTE == sec->get_type() ) {              // Look at notes
+                note_section_accessor notes( reader, sec );
+                int no_notes = notes.get_notes_num();
+                if ( no > 0 ) {
+                    out << "Note section (" << sec->get_name() << ")" << std::endl
+                        << "    No Type     Name"
+                        << std::endl;
+                    for ( int j = 0; j < no_notes; ++j ) {    // For all notes
+                        Elf_Word    type;
+                        std::string name;
+                        void*       desc;
+                        Elf_Word    descsz;
+                    
+                        if ( notes.get_note(j, type, name, desc, descsz) ) {
+                            // 'name' usually contains \0 at the end. Try to fix it
+                            name = name.c_str();
+                            note( out, j, type, name );
+                        }
+                    }
+                    
+                    out << std::endl;
+                }
+            }
+        }
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    note( std::ostream&      out,
+          int                no,
+          Elf_Word           type,
+          const std::string& name )
+    {
+        out << "  [" 
+            << DUMP_DEC_FORMAT( 2 ) << no
+            << "] "
+            << DUMP_HEX_FORMAT( 8 ) << type << " "
+            << DUMP_STR_FORMAT( 1 ) << name
+            << std::endl;
+    }
+    
+//------------------------------------------------------------------------------
+    static void
+    dynamic_tags( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half n = reader.sections.size();
+        for ( Elf_Half i = 0; i < n; ++i ) {    // For all sections
+            section* sec = reader.sections[i];
+            if ( SHT_DYNAMIC == sec->get_type() ) {
+                dynamic_section_accessor dynamic( reader, sec );
+
+                Elf_Xword dyn_no = dynamic.get_entries_num();
+                if ( dyn_no > 0 ) {
+                    out << "Dynamic section (" << sec->get_name() << ")" << std::endl;
+                    out << "[  Nr ] Tag              Name/Value" << std::endl;
+                    for ( int i = 0; i < dyn_no; ++i ) {
+                        Elf_Xword   tag   = 0;
+                        Elf_Xword   value = 0;
+                        std::string str;
+                        dynamic.get_entry( i, tag, value, str );
+                        dynamic_tag( out, i, tag, value, str, reader.get_class() );
+                        if ( DT_NULL == tag ) {
+                            break;
+                        }
+                    }
+
+                    out << std::endl;
+                }
+            }
+        }
+    }
+    
+//------------------------------------------------------------------------------
+    static void
+    dynamic_tag( std::ostream& out,
+                 int           no,
+                 Elf_Xword     tag,
+                 Elf_Xword     value,
+                 std::string   str,
+                 unsigned int  /*elf_class*/ )
+    {
+            out << "[" 
+                << DUMP_DEC_FORMAT(  5 ) << no
+                << "] "
+                << DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " ";
+            if ( str.empty() ) {
+                out << DUMP_HEX_FORMAT( 16 ) << value                  << " ";
+            }
+            else {
+                out << DUMP_STR_FORMAT( 32 ) << str                    << " ";
+            }
+            out << std::endl;
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    section_data( std::ostream& out, const section* sec )
+    {
+        std::ios_base::fmtflags original_flags = out.flags();
+
+        out << sec->get_name() << std::endl;
+        const char* pdata = sec->get_data();
+        if ( pdata ){
+            ELFIO::Elf_Xword i;
+            for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES ); ++i ) {
+                if ( i % 16 == 0 ) {
+                    out << "[" <<  DUMP_HEX_FORMAT( 8 ) << i << "]";
+                }
+
+                out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF );
+
+                if ( i % 16 == 15 ) {
+                    out << std::endl;
+                }
+            }
+            if ( i % 16 != 0 ) {
+                out << std::endl;
+            }
+
+            out.flags(original_flags);
+        }
+
+        return; 
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    section_datas( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half n = reader.sections.size();
+
+        if ( n == 0 ) {
+            return;
+        }
+
+        out << "Section Data:" << std::endl;
+
+        for ( Elf_Half i = 1; i < n; ++i ) { // For all sections
+            section* sec = reader.sections[i];
+            if ( sec->get_type() == SHT_NOBITS ) {
+                continue;
+            }
+            section_data( out, sec );
+        }
+
+        out << std::endl;
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    segment_data( std::ostream& out, Elf_Half no, const segment* seg )
+    {
+        std::ios_base::fmtflags original_flags = out.flags();
+
+        out << "Segment # " << no << std::endl;
+        const char* pdata = seg->get_data();
+        if ( pdata ) {
+            ELFIO::Elf_Xword i;
+            for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES ); ++i ) {
+                if ( i % 16 == 0 ) {
+                    out << "[" <<  DUMP_HEX_FORMAT( 8 ) << i << "]";
+                }
+
+                out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF );
+
+                if ( i % 16 == 15 ) {
+                    out << std::endl;
+                }
+            }
+            if ( i % 16 != 0 ) {
+                out << std::endl;
+            }
+
+            out.flags(original_flags);
+        }
+
+        return; 
+    }
+
+//------------------------------------------------------------------------------
+    static void
+    segment_datas( std::ostream& out, const elfio& reader )
+    {
+        Elf_Half n = reader.segments.size();
+
+        if ( n == 0 ) {
+            return;
+        }
+
+        out << "Segment Data:" << std::endl;
+
+        for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
+            segment* seg = reader.segments[i];
+            segment_data( out, i, seg );
+        }
+
+        out << std::endl;
+    }
+    
+  private:
+//------------------------------------------------------------------------------
+    template< typename T, typename K >
+    std::string
+    static
+    find_value_in_table( const T& table, const K& key )
+    {
+        std::string res = "?";
+        for ( unsigned int i = 0; i < sizeof( table )/sizeof( table[0] ); ++i ) {
+            if ( table[i].key == key ) {
+                res = table[i].str;
+                break;
+            }
+        }
+
+        return res;
+    }
+
+
+//------------------------------------------------------------------------------
+    template< typename T, typename K >
+    static
+    std::string
+    format_assoc( const T& table, const K& key )
+    {
+        std::string str = find_value_in_table( table, key );
+        if ( str == "?" ) {
+            std::ostringstream oss;
+            oss << str << " (0x" << std::hex << key << ")";
+            str = oss.str();
+        }
+
+        return str;
+    }
+
+
+//------------------------------------------------------------------------------
+    template< typename T >
+    static
+    std::string
+    format_assoc( const T& table, const char key )
+    {
+        return format_assoc( table, (const int)key );
+    }
+
+    
+//------------------------------------------------------------------------------
+    static
+    std::string
+    section_flags( Elf_Xword flags )
+    {
+        std::string ret = "";
+        if ( flags & SHF_WRITE ) {
+            ret += "W";
+        }
+        if ( flags & SHF_ALLOC ) {
+            ret += "A";
+        }
+        if ( flags & SHF_EXECINSTR ) {
+            ret += "X";
+        }
+
+        return ret;
+    }
+
+
+//------------------------------------------------------------------------------
+#define STR_FUNC_TABLE( name )                    \
+    template< typename T >                        \
+    static                                        \
+    std::string                                   \
+    str_##name( const T key )                     \
+    {                                             \
+        return format_assoc( name##_table, key ); \
+    }
+
+    STR_FUNC_TABLE( class )
+    STR_FUNC_TABLE( endian )
+    STR_FUNC_TABLE( version )
+    STR_FUNC_TABLE( type )
+    STR_FUNC_TABLE( machine )
+    STR_FUNC_TABLE( section_type )
+    STR_FUNC_TABLE( segment_type )
+    STR_FUNC_TABLE( segment_flag )
+    STR_FUNC_TABLE( symbol_bind )
+    STR_FUNC_TABLE( symbol_type )
+    STR_FUNC_TABLE( dynamic_tag )
+
+#undef STR_FUNC_TABLE
+#undef DUMP_DEC_FORMAT
+#undef DUMP_HEX_FORMAT
+#undef DUMP_STR_FORMAT
+}; // class dump
+    
+
+}; // namespace ELFIO
+
+#endif // ELFIO_DUMP_HPP
diff --git a/backend/src/elfio/elfio_dynamic.hpp b/backend/src/elfio/elfio_dynamic.hpp
new file mode 100644
index 0000000..6f2d041
--- /dev/null
+++ b/backend/src/elfio/elfio_dynamic.hpp
@@ -0,0 +1,253 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_DYNAMIC_HPP
+#define ELFIO_DYNAMIC_HPP
+
+namespace ELFIO {
+
+//------------------------------------------------------------------------------
+class dynamic_section_accessor
+{
+  public:
+//------------------------------------------------------------------------------
+    dynamic_section_accessor( const elfio& elf_file_, section* section_ ) :
+                              elf_file( elf_file_ ),
+                              dynamic_section( section_ )
+    {
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Xword
+    get_entries_num() const
+    {
+        Elf_Xword nRet = 0;
+
+        if ( 0 != dynamic_section->get_entry_size() ) {
+            nRet = dynamic_section->get_size() / dynamic_section->get_entry_size();
+        }
+
+        return nRet;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    get_entry( Elf_Xword    index,
+               Elf_Xword&   tag,
+               Elf_Xword&   value,
+               std::string& str ) const
+    {
+        if ( index >= get_entries_num() ) {    // Is index valid
+            return false;
+        }
+
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            generic_get_entry_dyn< Elf32_Dyn >( index, tag, value );
+        }
+        else {
+            generic_get_entry_dyn< Elf64_Dyn >( index, tag, value );
+        }
+
+        // If the tag may have a string table reference, prepare the string
+        if ( tag == DT_NEEDED ||
+             tag == DT_SONAME ||
+             tag == DT_RPATH  ||
+             tag == DT_RUNPATH ) {
+            string_section_accessor strsec =
+                elf_file.sections[ get_string_table_index() ];
+            const char* result = strsec.get_string( value );
+            if ( 0 == result ) {
+                str.clear();
+                return false;
+            }
+            str = result;
+        }
+        else {
+            str.clear();
+        }
+
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( Elf_Xword& tag,
+               Elf_Xword& value )
+    {
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            generic_add_entry< Elf32_Dyn >( tag, value );
+        }
+        else {
+            generic_add_entry< Elf64_Dyn >( tag, value );
+        }
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( Elf_Xword&   tag,
+               std::string& str )
+    {
+        string_section_accessor strsec =
+            elf_file.sections[ get_string_table_index() ];
+        Elf_Xword value = strsec.add_string( str );
+        add_entry( tag, value );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_string_table_index() const
+    {
+        return (Elf_Half)dynamic_section->get_link();
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    void
+    generic_get_entry_dyn( Elf_Xword  index,
+                           Elf_Xword& tag,
+                           Elf_Xword& value ) const
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        // Check unusual case when dynamic section has no data
+        if( dynamic_section->get_data() == 0 ||
+            ( index + 1 ) * dynamic_section->get_entry_size() > dynamic_section->get_size() ) {
+            tag   = DT_NULL;
+            value = 0;
+            return;
+        }
+
+        const T* pEntry = reinterpret_cast<const T*>(
+                dynamic_section->get_data() +
+                index * dynamic_section->get_entry_size() );
+        tag = convertor( pEntry->d_tag );
+        switch ( tag ) {
+        case DT_NULL:
+        case DT_SYMBOLIC:
+        case DT_TEXTREL:
+        case DT_BIND_NOW:
+            value = 0;
+            break;
+        case DT_NEEDED:
+        case DT_PLTRELSZ:
+        case DT_RELASZ:
+        case DT_RELAENT:
+        case DT_STRSZ:
+        case DT_SYMENT:
+        case DT_SONAME:
+        case DT_RPATH:
+        case DT_RELSZ:
+        case DT_RELENT:
+        case DT_PLTREL:
+        case DT_INIT_ARRAYSZ:
+        case DT_FINI_ARRAYSZ:
+        case DT_RUNPATH:
+        case DT_FLAGS:
+        case DT_PREINIT_ARRAYSZ:
+            value = convertor( pEntry->d_un.d_val );
+            break;
+        case DT_PLTGOT:
+        case DT_HASH:
+        case DT_STRTAB:
+        case DT_SYMTAB:
+        case DT_RELA:
+        case DT_INIT:
+        case DT_FINI:
+        case DT_REL:
+        case DT_DEBUG:
+        case DT_JMPREL:
+        case DT_INIT_ARRAY:
+        case DT_FINI_ARRAY:
+        case DT_PREINIT_ARRAY:
+        default:
+            value = convertor( pEntry->d_un.d_ptr );
+            break;
+        }
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    void
+    generic_add_entry( Elf_Xword tag, Elf_Xword value )
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        T entry;
+
+        switch ( tag ) {
+        case DT_NULL:
+        case DT_SYMBOLIC:
+        case DT_TEXTREL:
+        case DT_BIND_NOW:
+            value = 0;
+        case DT_NEEDED:
+        case DT_PLTRELSZ:
+        case DT_RELASZ:
+        case DT_RELAENT:
+        case DT_STRSZ:
+        case DT_SYMENT:
+        case DT_SONAME:
+        case DT_RPATH:
+        case DT_RELSZ:
+        case DT_RELENT:
+        case DT_PLTREL:
+        case DT_INIT_ARRAYSZ:
+        case DT_FINI_ARRAYSZ:
+        case DT_RUNPATH:
+        case DT_FLAGS:
+        case DT_PREINIT_ARRAYSZ:
+            entry.d_un.d_val = convertor( value );
+            break;
+        case DT_PLTGOT:
+        case DT_HASH:
+        case DT_STRTAB:
+        case DT_SYMTAB:
+        case DT_RELA:
+        case DT_INIT:
+        case DT_FINI:
+        case DT_REL:
+        case DT_DEBUG:
+        case DT_JMPREL:
+        case DT_INIT_ARRAY:
+        case DT_FINI_ARRAY:
+        case DT_PREINIT_ARRAY:
+        default:
+            entry.d_un.d_ptr = convertor( value );
+            break;
+        }
+
+        entry.d_tag = convertor( tag );
+
+        dynamic_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    const elfio& elf_file;
+    section*     dynamic_section;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_DYNAMIC_HPP
diff --git a/backend/src/elfio/elfio_header.hpp b/backend/src/elfio/elfio_header.hpp
new file mode 100644
index 0000000..d689a88
--- /dev/null
+++ b/backend/src/elfio/elfio_header.hpp
@@ -0,0 +1,146 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELF_HEADER_HPP
+#define ELF_HEADER_HPP
+
+#include <iostream>
+
+namespace ELFIO {
+
+class elf_header
+{
+  public:
+    virtual ~elf_header() {};
+    virtual bool load( std::istream& stream )       = 0;
+    virtual bool save( std::ostream& stream ) const = 0;
+
+    // ELF header functions
+    ELFIO_GET_ACCESS_DECL( unsigned char, class              );
+    ELFIO_GET_ACCESS_DECL( unsigned char, elf_version        );
+    ELFIO_GET_ACCESS_DECL( unsigned char, encoding           );
+    ELFIO_GET_ACCESS_DECL( Elf_Word,      version            );
+    ELFIO_GET_ACCESS_DECL( Elf_Half,      header_size        );
+    ELFIO_GET_ACCESS_DECL( Elf_Half,      section_entry_size );
+    ELFIO_GET_ACCESS_DECL( Elf_Half,      segment_entry_size );
+
+    ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi          );
+    ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version     );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Half,      type            );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Half,      machine         );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,      flags           );
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr,    entry           );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Half,      sections_num    );
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Off,     sections_offset );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Half,      segments_num    );
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Off,     segments_offset );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Half,      section_name_str_index );
+};
+
+
+template< class T > struct elf_header_impl_types;
+template<> struct elf_header_impl_types<Elf32_Ehdr> {
+    typedef Elf32_Phdr Phdr_type;
+    typedef Elf32_Shdr Shdr_type;
+    static const unsigned char file_class = ELFCLASS32;
+};
+template<> struct elf_header_impl_types<Elf64_Ehdr> {
+    typedef Elf64_Phdr Phdr_type;
+    typedef Elf64_Shdr Shdr_type;
+    static const unsigned char file_class = ELFCLASS64;
+};
+
+template< class T > class elf_header_impl : public elf_header
+{
+  public:
+    elf_header_impl( endianess_convertor* convertor_,
+                     unsigned char encoding )
+    {
+        convertor = convertor_;
+
+        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
+
+        header.e_ident[EI_MAG0]    = ELFMAG0;
+        header.e_ident[EI_MAG1]    = ELFMAG1;
+        header.e_ident[EI_MAG2]    = ELFMAG2;
+        header.e_ident[EI_MAG3]    = ELFMAG3;
+        header.e_ident[EI_CLASS]   = elf_header_impl_types<T>::file_class;
+        header.e_ident[EI_DATA]    = encoding;
+        header.e_ident[EI_VERSION] = EV_CURRENT;
+        header.e_version           = EV_CURRENT;
+        header.e_version           = (*convertor)( header.e_version );
+        header.e_ehsize            = ( sizeof( header ) );
+        header.e_ehsize            = (*convertor)( header.e_ehsize );
+        header.e_shstrndx          = (*convertor)( (Elf_Half)1 );
+        header.e_phentsize         = sizeof( typename elf_header_impl_types<T>::Phdr_type );
+        header.e_shentsize         = sizeof( typename elf_header_impl_types<T>::Shdr_type );
+        header.e_phentsize         = (*convertor)( header.e_phentsize );
+        header.e_shentsize         = (*convertor)( header.e_shentsize );
+    }
+
+    bool
+    load( std::istream& stream )
+    {
+        stream.seekg( 0 );
+        stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
+
+        return (stream.gcount() == sizeof( header ) );
+    }
+
+    bool
+    save( std::ostream& stream ) const
+    {
+        stream.seekp( 0 );
+        stream.write( reinterpret_cast<const char*>( &header ), sizeof( header ) );
+
+        return stream.good();
+    }
+
+    // ELF header functions
+    ELFIO_GET_ACCESS( unsigned char, class,              header.e_ident[EI_CLASS] );
+    ELFIO_GET_ACCESS( unsigned char, elf_version,        header.e_ident[EI_VERSION] );
+    ELFIO_GET_ACCESS( unsigned char, encoding,           header.e_ident[EI_DATA] );
+    ELFIO_GET_ACCESS( Elf_Word,      version,            header.e_version );
+    ELFIO_GET_ACCESS( Elf_Half,      header_size,        header.e_ehsize );
+    ELFIO_GET_ACCESS( Elf_Half,      section_entry_size, header.e_shentsize );
+    ELFIO_GET_ACCESS( Elf_Half,      segment_entry_size, header.e_phentsize );
+
+    ELFIO_GET_SET_ACCESS( unsigned char, os_abi,          header.e_ident[EI_OSABI] );
+    ELFIO_GET_SET_ACCESS( unsigned char, abi_version,     header.e_ident[EI_ABIVERSION] );
+    ELFIO_GET_SET_ACCESS( Elf_Half,      type,            header.e_type );
+    ELFIO_GET_SET_ACCESS( Elf_Half,      machine,         header.e_machine );
+    ELFIO_GET_SET_ACCESS( Elf_Word,      flags,           header.e_flags );
+    ELFIO_GET_SET_ACCESS( Elf_Half,      section_name_str_index, header.e_shstrndx );
+    ELFIO_GET_SET_ACCESS( Elf64_Addr,    entry,           header.e_entry );
+    ELFIO_GET_SET_ACCESS( Elf_Half,      sections_num,    header.e_shnum );
+    ELFIO_GET_SET_ACCESS( Elf64_Off,     sections_offset, header.e_shoff );
+    ELFIO_GET_SET_ACCESS( Elf_Half,      segments_num,    header.e_phnum );
+    ELFIO_GET_SET_ACCESS( Elf64_Off,     segments_offset, header.e_phoff );
+
+  private:
+    T header;
+    endianess_convertor* convertor;
+};
+
+} // namespace ELFIO
+
+#endif // ELF_HEADER_HPP
diff --git a/backend/src/elfio/elfio_note.hpp b/backend/src/elfio/elfio_note.hpp
new file mode 100644
index 0000000..35c6fe3
--- /dev/null
+++ b/backend/src/elfio/elfio_note.hpp
@@ -0,0 +1,166 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_NOTE_HPP
+#define ELFIO_NOTE_HPP
+
+namespace ELFIO {
+
+//------------------------------------------------------------------------------
+// There are discrepancies in documentations. SCO documentation
+// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section)
+// requires 8 byte entries alignment for 64-bit ELF file,
+// but Oracle's definition uses the same structure
+// for 32-bit and 64-bit formats.
+// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html)
+//
+// It looks like EM_X86_64 Linux implementation is similar to Oracle's
+// definition. Therefore, the same alignment works for both formats
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+class note_section_accessor
+{
+  public:
+//------------------------------------------------------------------------------
+    note_section_accessor( const elfio& elf_file_, section* section_ ) :
+                           elf_file( elf_file_ ), note_section( section_ )
+    {
+        process_section();
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    get_notes_num() const
+    {
+        return (Elf_Word)note_start_positions.size();
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    get_note( Elf_Word     index,
+              Elf_Word&    type,
+              std::string& name,
+              void*&       desc,
+              Elf_Word&    descSize ) const
+    {
+        if ( index >= note_section->get_size() ) {
+            return false;
+        }
+
+        const char* pData = note_section->get_data() + note_start_positions[index];
+        int align = sizeof( Elf_Word );
+
+        const endianess_convertor& convertor = elf_file.get_convertor();
+        type = convertor( *(Elf_Word*)( pData + 2*align ) );
+        Elf_Word namesz = convertor( *(Elf_Word*)( pData ) );
+        descSize = convertor( *(Elf_Word*)( pData + sizeof( namesz ) ) );
+        Elf_Word max_name_size = note_section->get_size() - note_start_positions[index];
+        if ( namesz            > max_name_size ||
+             namesz + descSize > max_name_size ) {
+            return false;
+        }
+        name.assign( pData + 3*align, namesz - 1);
+        if ( 0 == descSize ) {
+            desc = 0;
+        }
+        else {
+            desc = const_cast<char*> ( pData + 3*align +
+                                       ( ( namesz + align - 1 )/align )*align );
+        }
+
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    void add_note( Elf_Word           type,
+                   const std::string& name,
+                   const void*        desc,
+                   Elf_Word           descSize )
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        int align            = sizeof( Elf_Word );
+        Elf_Word nameLen     = (Elf_Word)name.size() + 1;
+        Elf_Word nameLenConv = convertor( nameLen );
+        std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align );
+        Elf_Word descSizeConv = convertor( descSize );
+        buffer.append( reinterpret_cast<char*>( &descSizeConv ), align );
+        type = convertor( type );
+        buffer.append( reinterpret_cast<char*>( &type ), align );
+        buffer.append( name );
+        buffer.append( 1, '\x00' );
+        const char pad[] = { '\0', '\0', '\0', '\0' };
+        if ( nameLen % align != 0 ) {
+            buffer.append( pad, align - nameLen % align );
+        }
+        if ( desc != 0 && descSize != 0 ) {
+            buffer.append( reinterpret_cast<const char*>( desc ), descSize );
+            if ( descSize % align != 0 ) {
+                buffer.append( pad, align - descSize % align );
+            }
+        }
+
+        note_start_positions.push_back( note_section->get_size() );
+        note_section->append_data( buffer );
+    }
+
+  private:
+//------------------------------------------------------------------------------
+    void process_section()
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+        const char* data                     = note_section->get_data();
+        Elf_Xword   size                     = note_section->get_size();
+        Elf_Xword   current                  = 0;
+
+        note_start_positions.clear();
+
+        // Is it empty?
+        if ( 0 == data || 0 == size ) {
+            return;
+        }
+
+        int align = sizeof( Elf_Word );
+        while ( current + 3*align <= size ) {
+            note_start_positions.push_back( current );
+            Elf_Word namesz = convertor(
+                            *(Elf_Word*)( data + current ) );
+            Elf_Word descsz = convertor(
+                            *(Elf_Word*)( data + current + sizeof( namesz ) ) );
+
+            current += 3*sizeof( Elf_Word ) +
+                       ( ( namesz + align - 1 ) / align ) * align +
+                       ( ( descsz + align - 1 ) / align ) * align;
+        }
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    const elfio&           elf_file;
+    section*               note_section;
+    std::vector<Elf_Xword> note_start_positions;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_NOTE_HPP
diff --git a/backend/src/elfio/elfio_relocation.hpp b/backend/src/elfio/elfio_relocation.hpp
new file mode 100644
index 0000000..d13d8b2
--- /dev/null
+++ b/backend/src/elfio/elfio_relocation.hpp
@@ -0,0 +1,369 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_RELOCATION_HPP
+#define ELFIO_RELOCATION_HPP
+
+namespace ELFIO {
+
+template<typename T> struct get_sym_and_type;
+template<> struct get_sym_and_type< Elf32_Rel >
+{
+    static int get_r_sym( Elf_Xword info )
+    {
+        return ELF32_R_SYM( (Elf_Word)info );
+    }
+    static int get_r_type( Elf_Xword info )
+    {
+        return ELF32_R_TYPE( (Elf_Word)info );
+    }
+};
+template<> struct get_sym_and_type< Elf32_Rela >
+{
+    static int get_r_sym( Elf_Xword info )
+    {
+        return ELF32_R_SYM( (Elf_Word)info );
+    }
+    static int get_r_type( Elf_Xword info )
+    {
+        return ELF32_R_TYPE( (Elf_Word)info );
+    }
+};
+template<> struct get_sym_and_type< Elf64_Rel >
+{
+    static int get_r_sym( Elf_Xword info )
+    {
+        return ELF64_R_SYM( info );
+    }
+    static int get_r_type( Elf_Xword info )
+    {
+        return ELF64_R_TYPE( info );
+    }
+};
+template<> struct get_sym_and_type< Elf64_Rela >
+{
+    static int get_r_sym( Elf_Xword info )
+    {
+        return ELF64_R_SYM( info );
+    }
+    static int get_r_type( Elf_Xword info )
+    {
+        return ELF64_R_TYPE( info );
+    }
+};
+
+
+//------------------------------------------------------------------------------
+class relocation_section_accessor
+{
+  public:
+//------------------------------------------------------------------------------
+    relocation_section_accessor( const elfio& elf_file_, section* section_ ) :
+                                 elf_file( elf_file_ ),
+                                 relocation_section( section_ )
+    {
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Xword
+    get_entries_num() const
+    {
+        Elf_Xword nRet = 0;
+
+        if ( 0 != relocation_section->get_entry_size() ) {
+            nRet = relocation_section->get_size() / relocation_section->get_entry_size();
+        }
+
+        return nRet;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    get_entry( Elf_Xword   index,
+               Elf64_Addr& offset,
+               Elf_Word&   symbol,
+               Elf_Word&   type,
+               Elf_Sxword& addend ) const
+    {
+        if ( index >= get_entries_num() ) {    // Is index valid
+            return false;
+        }
+
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            if ( SHT_REL == relocation_section->get_type() ) {
+                generic_get_entry_rel< Elf32_Rel >( index, offset, symbol,
+                                                    type,  addend );
+            }
+            else if ( SHT_RELA == relocation_section->get_type() ) {
+                generic_get_entry_rela< Elf32_Rela >( index, offset, symbol,
+                                                      type,  addend );
+            }
+        }
+        else {
+            if ( SHT_REL == relocation_section->get_type() ) {
+                generic_get_entry_rel< Elf64_Rel >( index, offset, symbol,
+                                                    type,  addend );
+            }
+            else if ( SHT_RELA == relocation_section->get_type() ) {
+                generic_get_entry_rela< Elf64_Rela >( index, offset, symbol,
+                                                      type,  addend );
+            }
+        }
+
+        return true;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    get_entry( Elf_Xword    index,
+               Elf64_Addr&  offset,
+               Elf64_Addr&  symbolValue,
+               std::string& symbolName,
+               Elf_Word&    type,
+               Elf_Sxword&  addend,
+               Elf_Sxword&  calcValue ) const
+    {
+        // Do regular job
+        Elf_Word symbol;
+        bool ret = get_entry( index, offset, symbol, type, addend );
+
+        // Find the symbol
+        Elf_Xword     size;
+        unsigned char bind;
+        unsigned char symbolType;
+        Elf_Half      section;
+        unsigned char other;
+
+        symbol_section_accessor symbols( elf_file, elf_file.sections[get_symbol_table_index()] );
+        ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue,
+                                         size, bind, symbolType, section, other );
+
+        if ( ret ) { // Was it successful?
+            switch ( type ) {
+            case R_386_NONE:        // none
+                calcValue = 0;
+                break;
+            case R_386_32:          // S + A
+                calcValue = symbolValue + addend;
+                break;
+            case R_386_PC32:        // S + A - P
+                calcValue = symbolValue + addend - offset;
+                break;
+            case R_386_GOT32:       // G + A - P
+                calcValue = 0;
+                break;
+            case R_386_PLT32:       // L + A - P
+                calcValue = 0;
+                break;
+            case R_386_COPY:        // none
+                calcValue = 0;
+                break;
+            case R_386_GLOB_DAT:    // S
+            case R_386_JMP_SLOT:    // S
+                calcValue = symbolValue;
+                break;
+            case R_386_RELATIVE:    // B + A
+                calcValue = addend;
+                break;
+            case R_386_GOTOFF:      // S + A - GOT
+                calcValue = 0;
+                break;
+            case R_386_GOTPC:       // GOT + A - P
+                calcValue = 0;
+                break;
+            default:                // Not recognized symbol!
+                calcValue = 0;
+                break;
+            }
+        }
+
+        return ret;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( Elf64_Addr offset, Elf_Xword info )
+    {
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            generic_add_entry< Elf32_Rel >( offset, info );
+        }
+        else {
+            generic_add_entry< Elf64_Rel >( offset, info );
+        }
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type )
+    {
+        Elf_Xword info;
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            info = ELF32_R_INFO( (Elf_Xword)symbol, type );
+        }
+        else {
+            info = ELF64_R_INFO((Elf_Xword)symbol, type );
+        }
+
+        add_entry( offset, info );
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
+    {
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            generic_add_entry< Elf32_Rela >( offset, info, addend );
+        }
+        else {
+            generic_add_entry< Elf64_Rela >( offset, info, addend );
+        }
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type,
+               Elf_Sxword addend )
+    {
+        Elf_Xword info;
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            info = ELF32_R_INFO( (Elf_Xword)symbol, type );
+        }
+        else {
+            info = ELF64_R_INFO( (Elf_Xword)symbol, type );
+        }
+
+        add_entry( offset, info, addend );
+    }
+
+//------------------------------------------------------------------------------
+    void
+    add_entry( string_section_accessor str_writer,
+               const char* str,
+               symbol_section_accessor sym_writer,
+               Elf64_Addr value,
+               Elf_Word size,
+               unsigned char sym_info,
+               unsigned char other,
+               Elf_Half shndx,
+               Elf64_Addr offset,
+               unsigned char type )
+    {
+        Elf_Word str_index = str_writer.add_string( str );
+        Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size,
+                                                   sym_info, other, shndx );
+        add_entry( offset, sym_index, type );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_symbol_table_index() const
+    {
+        return (Elf_Half)relocation_section->get_link();
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    void
+    generic_get_entry_rel( Elf_Xword   index,
+                           Elf64_Addr& offset,
+                           Elf_Word&   symbol,
+                           Elf_Word&   type,
+                           Elf_Sxword& addend ) const
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        const T* pEntry = reinterpret_cast<const T*>(
+                relocation_section->get_data() +
+                index * relocation_section->get_entry_size() );
+        offset        = convertor( pEntry->r_offset );
+        Elf_Xword tmp = convertor( pEntry->r_info );
+        symbol        = get_sym_and_type<T>::get_r_sym( tmp );
+        type          = get_sym_and_type<T>::get_r_type( tmp );
+        addend        = 0;
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    void
+    generic_get_entry_rela( Elf_Xword   index,
+                            Elf64_Addr& offset,
+                            Elf_Word&   symbol,
+                            Elf_Word&   type,
+                            Elf_Sxword& addend ) const
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        const T* pEntry = reinterpret_cast<const T*>(
+                relocation_section->get_data() +
+                index * relocation_section->get_entry_size() );
+        offset        = convertor( pEntry->r_offset );
+        Elf_Xword tmp = convertor( pEntry->r_info );
+        symbol        = get_sym_and_type<T>::get_r_sym( tmp );
+        type          = get_sym_and_type<T>::get_r_type( tmp );
+        addend        = convertor( pEntry->r_addend );
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    void
+    generic_add_entry( Elf64_Addr offset, Elf_Xword info )
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        T entry;
+        entry.r_offset = offset;
+        entry.r_info   = info;
+        entry.r_offset = convertor( entry.r_offset );
+        entry.r_info   = convertor( entry.r_info );
+
+        relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    void
+    generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        T entry;
+        entry.r_offset = offset;
+        entry.r_info   = info;
+        entry.r_addend = addend;
+        entry.r_offset = convertor( entry.r_offset );
+        entry.r_info   = convertor( entry.r_info );
+        entry.r_addend = convertor( entry.r_addend );
+
+        relocation_section->append_data( reinterpret_cast<char*>( &entry ), sizeof( entry ) );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    const elfio& elf_file;
+    section*     relocation_section;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_RELOCATION_HPP
diff --git a/backend/src/elfio/elfio_section.hpp b/backend/src/elfio/elfio_section.hpp
new file mode 100644
index 0000000..b2c9b45
--- /dev/null
+++ b/backend/src/elfio/elfio_section.hpp
@@ -0,0 +1,296 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_SECTION_HPP
+#define ELFIO_SECTION_HPP
+
+#include <string>
+#include <iostream>
+
+namespace ELFIO {
+
+class section
+{
+    friend class elfio;
+  public:
+    virtual ~section() {};
+
+    ELFIO_GET_ACCESS_DECL    ( Elf_Half,    index              );
+    ELFIO_GET_SET_ACCESS_DECL( std::string, name               );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    type               );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   flags              );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    info               );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    link               );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   addr_align         );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   entry_size         );
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr,  address            );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,   size               );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,    name_string_offset );
+
+    virtual const char* get_data() const                                = 0;
+    virtual void        set_data( const char* pData, Elf_Word size )    = 0;
+    virtual void        set_data( const std::string& data )             = 0;
+    virtual void        append_data( const char* pData, Elf_Word size ) = 0;
+    virtual void        append_data( const std::string& data )          = 0;
+
+  protected:
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, offset );
+    ELFIO_SET_ACCESS_DECL( Elf_Half,  index  );
+    
+    virtual void load( std::istream&  f,
+                       std::streampos header_offset ) = 0;
+    virtual void save( std::ostream&  f,
+                       std::streampos header_offset,
+                       std::streampos data_offset )   = 0;
+    virtual bool is_address_initialized() const       = 0;
+};
+
+
+template< class T >
+class section_impl : public section
+{
+  public:
+//------------------------------------------------------------------------------
+    section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ )
+    {
+        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
+        is_address_set = false;
+        data           = 0;
+        data_size      = 0;
+    }
+
+//------------------------------------------------------------------------------
+    ~section_impl()
+    {
+        delete [] data;
+    }
+
+//------------------------------------------------------------------------------
+    // Section info functions
+    ELFIO_GET_SET_ACCESS( Elf_Word,   type,               header.sh_type      );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  flags,              header.sh_flags     );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  size,               header.sh_size      );
+    ELFIO_GET_SET_ACCESS( Elf_Word,   link,               header.sh_link      );
+    ELFIO_GET_SET_ACCESS( Elf_Word,   info,               header.sh_info      );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  addr_align,         header.sh_addralign );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  entry_size,         header.sh_entsize   );
+    ELFIO_GET_SET_ACCESS( Elf_Word,   name_string_offset, header.sh_name      );
+    ELFIO_GET_ACCESS    ( Elf64_Addr, address,            header.sh_addr      );
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_index() const
+    {
+        return index;
+    }
+
+
+//------------------------------------------------------------------------------
+    std::string
+    get_name() const
+    {
+        return name;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    set_name( std::string name_ )
+    {
+        name = name_;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    set_address( Elf64_Addr value )
+    {
+        header.sh_addr = value;
+        header.sh_addr = (*convertor)( header.sh_addr );
+        is_address_set = true;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    is_address_initialized() const
+    {
+        return is_address_set;
+    }
+
+//------------------------------------------------------------------------------
+    const char*
+    get_data() const
+    {
+        return data;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    set_data( const char* raw_data, Elf_Word size )
+    {
+        if ( get_type() != SHT_NOBITS ) {
+            delete [] data;
+            try {
+                data = new char[size];
+            } catch (const std::bad_alloc&) {
+                data      = 0;
+                data_size = 0;
+                size      = 0;
+            }
+            if ( 0 != data && 0 != raw_data ) {
+                data_size = size;
+                std::copy( raw_data, raw_data + size, data );
+            }
+        }
+
+        set_size( size );
+    }
+
+//------------------------------------------------------------------------------
+    void
+    set_data( const std::string& str_data )
+    {
+        return set_data( str_data.c_str(), (Elf_Word)str_data.size() );
+    }
+
+//------------------------------------------------------------------------------
+    void
+    append_data( const char* raw_data, Elf_Word size )
+    {
+        if ( get_type() != SHT_NOBITS ) {
+            if ( get_size() + size < data_size ) {
+                std::copy( raw_data, raw_data + size, data + get_size() );
+            }
+            else {
+                data_size = 2*( data_size + size);
+                char* new_data;
+                try {
+                    new_data = new char[data_size];
+                } catch (const std::bad_alloc&) {
+                    new_data = 0;
+                    size     = 0;
+                }
+                if ( 0 != new_data ) {
+                    std::copy( data, data + get_size(), new_data );
+                    std::copy( raw_data, raw_data + size, new_data + get_size() );
+                    delete [] data;
+                    data = new_data;
+                }
+            }
+            set_size( get_size() + size );
+        }
+    }
+
+//------------------------------------------------------------------------------
+    void
+    append_data( const std::string& str_data )
+    {
+        return append_data( str_data.c_str(), (Elf_Word)str_data.size() );
+    }
+
+//------------------------------------------------------------------------------
+  protected:
+//------------------------------------------------------------------------------
+    ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset );
+
+//------------------------------------------------------------------------------
+    void
+    set_index( Elf_Half value )
+    {
+        index = value;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    load( std::istream&  stream,
+          std::streampos header_offset )
+    {
+        std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ), '\0' );
+        stream.seekg( header_offset );
+        stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
+
+        Elf_Xword size = get_size();
+        if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() ) {
+            try {
+                data = new char[size];
+            } catch (const std::bad_alloc&) {
+                data      = 0;
+                data_size = 0;
+            }
+            if ( 0 != size ) {
+                stream.seekg( (*convertor)( header.sh_offset ) );
+                stream.read( data, size );
+                data_size = size;
+            }
+        }
+    }
+
+//------------------------------------------------------------------------------
+    void
+    save( std::ostream&  f,
+          std::streampos header_offset,
+          std::streampos data_offset )
+    {
+        if ( 0 != get_index() ) {
+            header.sh_offset = data_offset;
+            header.sh_offset = (*convertor)( header.sh_offset );
+        }
+
+        save_header( f, header_offset );
+        if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL &&
+             get_size() != 0 && data != 0 ) {
+            save_data( f, data_offset );
+        }
+    }
+
+//------------------------------------------------------------------------------
+  private:
+//------------------------------------------------------------------------------
+    void
+    save_header( std::ostream&  f,
+                 std::streampos header_offset ) const
+    {
+        f.seekp( header_offset );
+        f.write( reinterpret_cast<const char*>( &header ), sizeof( header ) );
+    }
+
+//------------------------------------------------------------------------------
+    void
+    save_data( std::ostream&  f,
+               std::streampos data_offset ) const
+    {
+        f.seekp( data_offset );
+        f.write( get_data(), get_size() );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    T                          header;
+    Elf_Half                   index;
+    std::string                name;
+    char*                      data;
+    Elf_Word                   data_size;
+    const endianess_convertor* convertor;
+    bool                       is_address_set;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_SECTION_HPP
diff --git a/backend/src/elfio/elfio_segment.hpp b/backend/src/elfio/elfio_segment.hpp
new file mode 100644
index 0000000..35f17e9
--- /dev/null
+++ b/backend/src/elfio/elfio_segment.hpp
@@ -0,0 +1,220 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_SEGMENT_HPP
+#define ELFIO_SEGMENT_HPP
+
+#include <iostream>
+#include <vector>
+
+namespace ELFIO {
+
+class segment
+{
+    friend class elfio;
+  public:
+    virtual ~segment() {};
+
+    ELFIO_GET_ACCESS_DECL    ( Elf_Half,   index            );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,   type             );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Word,   flags            );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  align            );
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address  );
+    ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  file_size        );
+    ELFIO_GET_SET_ACCESS_DECL( Elf_Xword,  memory_size      );
+    ELFIO_GET_ACCESS_DECL( Elf64_Off, offset );
+
+    virtual const char* get_data() const = 0;
+
+    virtual Elf_Half add_section_index( Elf_Half index, Elf_Xword addr_align ) = 0;
+    virtual Elf_Half get_sections_num()                                  const = 0;
+    virtual Elf_Half get_section_index_at( Elf_Half num )                const = 0;
+    virtual bool is_offset_initialized()                                 const = 0;
+
+  protected:
+    ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
+    ELFIO_SET_ACCESS_DECL( Elf_Half,  index  );
+    
+    virtual const std::vector<Elf_Half>& get_sections() const               = 0;
+    virtual void load( std::istream& stream, std::streampos header_offset ) = 0;
+    virtual void save( std::ostream& f,      std::streampos header_offset,
+                                             std::streampos data_offset )   = 0;
+};
+
+
+//------------------------------------------------------------------------------
+template< class T >
+class segment_impl : public segment
+{
+  public:
+//------------------------------------------------------------------------------
+    segment_impl( endianess_convertor* convertor_ ) :
+        convertor( convertor_ )
+    {
+        is_offset_set = false;
+        std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' );
+        data = 0;
+    }
+
+//------------------------------------------------------------------------------
+    virtual ~segment_impl()
+    {
+        delete [] data;
+    }
+
+//------------------------------------------------------------------------------
+    // Section info functions
+    ELFIO_GET_SET_ACCESS( Elf_Word,   type,             ph.p_type   );
+    ELFIO_GET_SET_ACCESS( Elf_Word,   flags,            ph.p_flags  );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  align,            ph.p_align  );
+    ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address,  ph.p_vaddr  );
+    ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr  );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  file_size,        ph.p_filesz );
+    ELFIO_GET_SET_ACCESS( Elf_Xword,  memory_size,      ph.p_memsz  );
+    ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset );
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_index() const
+    {
+        return index;
+    }
+
+//------------------------------------------------------------------------------
+    const char*
+    get_data() const
+    {
+        return data;
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    add_section_index( Elf_Half sec_index, Elf_Xword addr_align )
+    {
+        sections.push_back( sec_index );
+        if ( addr_align > get_align() ) {
+            set_align( addr_align );
+        }
+
+        return (Elf_Half)sections.size();
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_sections_num() const
+    {
+        return (Elf_Half)sections.size();
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_section_index_at( Elf_Half num ) const
+    {
+        if ( num < sections.size() ) {
+            return sections[num];
+        }
+
+        return -1;
+    }
+
+//------------------------------------------------------------------------------
+  protected:
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+    void
+    set_offset( Elf64_Off value )
+    {
+        ph.p_offset = value;
+        ph.p_offset = (*convertor)( ph.p_offset );
+        is_offset_set = true;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    is_offset_initialized() const
+    {
+        return is_offset_set;
+    }
+
+//------------------------------------------------------------------------------
+    const std::vector<Elf_Half>&
+    get_sections() const
+    {
+        return sections;
+    }
+    
+//------------------------------------------------------------------------------
+    void
+    set_index( Elf_Half value )
+    {
+        index = value;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    load( std::istream&  stream,
+          std::streampos header_offset )
+    {
+        stream.seekg( header_offset );
+        stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );
+        is_offset_set = true;
+
+        if ( PT_NULL != get_type() && 0 != get_file_size() ) {
+            stream.seekg( (*convertor)( ph.p_offset ) );
+            Elf_Xword size = get_file_size();
+            try {
+                data = new char[size];
+            } catch (const std::bad_alloc&) {
+                data = 0;
+            }
+            if ( 0 != data ) {
+                stream.read( data, size );
+            }
+        }
+    }
+
+//------------------------------------------------------------------------------
+    void save( std::ostream&  f,
+               std::streampos header_offset,
+               std::streampos data_offset )
+    {
+        ph.p_offset = data_offset;
+        ph.p_offset = (*convertor)(ph.p_offset);
+        f.seekp( header_offset );
+        f.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    T                     ph;
+    Elf_Half              index;
+    char*                 data;
+    std::vector<Elf_Half> sections;
+    endianess_convertor*  convertor;
+    bool                  is_offset_set;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_SEGMENT_HPP
diff --git a/backend/src/elfio/elfio_strings.hpp b/backend/src/elfio/elfio_strings.hpp
new file mode 100644
index 0000000..df952a2
--- /dev/null
+++ b/backend/src/elfio/elfio_strings.hpp
@@ -0,0 +1,96 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_STRINGS_HPP
+#define ELFIO_STRINGS_HPP
+
+#include <cstdlib>
+#include <cstring>
+#include <string>
+
+namespace ELFIO {
+
+//------------------------------------------------------------------------------
+class string_section_accessor
+{
+  public:
+//------------------------------------------------------------------------------
+    string_section_accessor( section* section_ ) :
+                             string_section( section_ )
+    {
+    }
+
+
+//------------------------------------------------------------------------------
+    const char*
+    get_string( Elf_Word index ) const
+    {
+        if ( string_section ) {
+            if ( index < string_section->get_size() ) {
+                const char* data = string_section->get_data();
+                if ( 0 != data ) {
+                    return data + index;
+                }
+            }
+        }
+
+        return 0;
+    }
+
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    add_string( const char* str )
+    {
+        Elf_Word current_position = 0;
+        
+        if (string_section) {
+            // Strings are addeded to the end of the current section data
+            current_position = (Elf_Word)string_section->get_size();
+
+            if ( current_position == 0 ) {
+                char empty_string = '\0';
+                string_section->append_data( &empty_string, 1 );
+                current_position++;
+            }
+            string_section->append_data( str, (Elf_Word)std::strlen( str ) + 1 );
+        }
+
+        return current_position;
+    }
+
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    add_string( const std::string& str )
+    {
+        return add_string( str.c_str() );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    section* string_section;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_STRINGS_HPP
diff --git a/backend/src/elfio/elfio_symbols.hpp b/backend/src/elfio/elfio_symbols.hpp
new file mode 100644
index 0000000..80e498d
--- /dev/null
+++ b/backend/src/elfio/elfio_symbols.hpp
@@ -0,0 +1,278 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_SYMBOLS_HPP
+#define ELFIO_SYMBOLS_HPP
+
+namespace ELFIO {
+
+//------------------------------------------------------------------------------
+class symbol_section_accessor
+{
+  public:
+//------------------------------------------------------------------------------
+    symbol_section_accessor( const elfio& elf_file_, section* symbol_section_ ) :
+                             elf_file( elf_file_ ),
+                             symbol_section( symbol_section_ )
+    {
+        find_hash_section();
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Xword
+    get_symbols_num() const
+    {
+        Elf_Xword nRet = 0;
+        if ( 0 != symbol_section->get_entry_size() ) {
+            nRet = symbol_section->get_size() / symbol_section->get_entry_size();
+        }
+
+        return nRet;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    get_symbol( Elf_Xword      index,
+                std::string&   name,
+                Elf64_Addr&    value,
+                Elf_Xword&     size,
+                unsigned char& bind,
+                unsigned char& type,
+                Elf_Half&      section_index,
+                unsigned char& other ) const
+    {
+        bool ret = false;
+
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            ret = generic_get_symbol<Elf32_Sym>( index, name, value, size, bind,
+                                                 type, section_index, other );
+        }
+        else {
+            ret = generic_get_symbol<Elf64_Sym>( index, name, value, size, bind,
+                                                 type, section_index, other );
+        }
+
+        return ret;
+    }
+
+//------------------------------------------------------------------------------
+    bool
+    get_symbol( const std::string& name,
+                Elf64_Addr&        value,
+                Elf_Xword&         size,
+                unsigned char&     bind,
+                unsigned char&     type,
+                Elf_Half&          section_index,
+                unsigned char&     other ) const
+    {
+        bool ret = false;
+
+        if ( 0 != get_hash_table_index() ) {
+            Elf_Word nbucket = *(Elf_Word*)hash_section->get_data();
+            Elf_Word nchain  = *(Elf_Word*)( hash_section->get_data() +
+                                   sizeof( Elf_Word ) );
+            Elf_Word val     = elf_hash( (const unsigned char*)name.c_str() );
+
+            Elf_Word y   = *(Elf_Word*)( hash_section->get_data() +
+                               ( 2 + val % nbucket ) * sizeof( Elf_Word ) );
+            std::string   str;
+            get_symbol( y, str, value, size, bind, type, section_index, other );
+            while ( str != name && STN_UNDEF != y && y < nchain ) {
+                y = *(Elf_Word*)( hash_section->get_data() +
+                        ( 2 + nbucket + y ) * sizeof( Elf_Word ) );
+                get_symbol( y, str, value, size, bind, type, section_index, other );
+            }
+            if (  str == name ) {
+                ret = true;
+            }
+        }
+
+        return ret;
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size,
+                unsigned char info, unsigned char other,
+                Elf_Half shndx )
+    {
+        Elf_Word nRet;
+
+        if ( symbol_section->get_size() == 0 ) {
+            if ( elf_file.get_class() == ELFCLASS32 ) {
+                nRet = generic_add_symbol<Elf32_Sym>( 0, 0, 0, 0, 0, 0 );
+            }
+            else {
+                nRet = generic_add_symbol<Elf64_Sym>( 0, 0, 0, 0, 0, 0 );
+            }
+        }
+
+        if ( elf_file.get_class() == ELFCLASS32 ) {
+            nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info, other,
+                                                  shndx );
+        }
+        else {
+            nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info, other,
+                                                  shndx );
+        }
+
+        return nRet;
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size,
+                unsigned char bind, unsigned char type, unsigned char other,
+                Elf_Half shndx )
+    {
+        return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other, shndx );
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    add_symbol( string_section_accessor& pStrWriter, const char* str,
+                Elf64_Addr value, Elf_Xword size,
+                unsigned char info, unsigned char other,
+                Elf_Half shndx )
+    {
+        Elf_Word index = pStrWriter.add_string( str );
+        return add_symbol( index, value, size, info, other, shndx );
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Word
+    add_symbol( string_section_accessor& pStrWriter, const char* str,
+                Elf64_Addr value, Elf_Xword size,
+                unsigned char bind, unsigned char type, unsigned char other,
+                Elf_Half shndx )
+    {
+        return add_symbol( pStrWriter, str, value, size, ELF_ST_INFO( bind, type ), other, shndx );
+    }
+
+//------------------------------------------------------------------------------
+  private:
+//------------------------------------------------------------------------------
+    void
+    find_hash_section()
+    {
+        hash_section       = 0;
+        hash_section_index = 0;
+        Elf_Half nSecNo = elf_file.sections.size();
+        for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) {
+            const section* sec = elf_file.sections[i];
+            if ( sec->get_link() == symbol_section->get_index() ) {
+                hash_section       = sec;
+                hash_section_index = i;
+            }
+        }
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_string_table_index() const
+    {
+        return (Elf_Half)symbol_section->get_link();
+    }
+
+//------------------------------------------------------------------------------
+    Elf_Half
+    get_hash_table_index() const
+    {
+        return hash_section_index;
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    bool
+    generic_get_symbol( Elf_Xword index,
+                        std::string& name, Elf64_Addr& value,
+                        Elf_Xword& size,
+                        unsigned char& bind, unsigned char& type,
+                        Elf_Half& section_index,
+                        unsigned char& other ) const
+    {
+        bool ret = false;
+
+        if ( index < get_symbols_num() ) {
+            const T* pSym = reinterpret_cast<const T*>(
+                symbol_section->get_data() +
+                    index * symbol_section->get_entry_size() );
+
+            const endianess_convertor& convertor = elf_file.get_convertor();
+
+            section* string_section = elf_file.sections[get_string_table_index()];
+            string_section_accessor str_reader( string_section );
+            const char* pStr = str_reader.get_string( convertor( pSym->st_name ) );
+            if ( 0 != pStr ) {
+                name = pStr;
+            }
+            value   = convertor( pSym->st_value );
+            size    = convertor( pSym->st_size );
+            bind    = ELF_ST_BIND( pSym->st_info );
+            type    = ELF_ST_TYPE( pSym->st_info );
+            section_index = convertor( pSym->st_shndx );
+            other   = pSym->st_other;
+
+            ret = true;
+        }
+
+        return ret;
+    }
+
+//------------------------------------------------------------------------------
+    template< class T >
+    Elf_Word
+    generic_add_symbol( Elf_Word name, Elf64_Addr value, Elf_Xword size,
+                        unsigned char info, unsigned char other,
+                        Elf_Half shndx )
+    {
+        const endianess_convertor& convertor = elf_file.get_convertor();
+
+        T entry;
+        entry.st_name  = convertor( name );
+        entry.st_value = value;
+        entry.st_value = convertor( entry.st_value );
+        entry.st_size  = size;
+        entry.st_size  = convertor( entry.st_size );
+        entry.st_info  = convertor( info );
+        entry.st_other = convertor( other );
+        entry.st_shndx = convertor( shndx );
+
+        symbol_section->append_data( reinterpret_cast<char*>( &entry ),
+                                     sizeof( entry ) );
+
+        Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1;
+
+        return nRet;
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    const elfio&   elf_file;
+    section*       symbol_section;
+    Elf_Half       hash_section_index;
+    const section* hash_section;
+};
+
+} // namespace ELFIO
+
+#endif // ELFIO_SYMBOLS_HPP
diff --git a/backend/src/elfio/elfio_utils.hpp b/backend/src/elfio/elfio_utils.hpp
new file mode 100644
index 0000000..f8423bd
--- /dev/null
+++ b/backend/src/elfio/elfio_utils.hpp
@@ -0,0 +1,209 @@ 
+/*
+Copyright (C) 2001-2015 by Serge Lamikhov-Center
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef ELFIO_UTILS_HPP
+#define ELFIO_UTILS_HPP
+
+#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \
+    TYPE get_##NAME() const                   \
+    {                                         \
+        return (*convertor)( FIELD );         \
+    }
+#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \
+    void set_##NAME( TYPE value )             \
+    {                                         \
+        FIELD = value;                        \
+        FIELD = (*convertor)( FIELD );        \
+    }
+#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD ) \
+    TYPE get_##NAME() const                       \
+    {                                             \
+        return (*convertor)( FIELD );             \
+    }                                             \
+    void set_##NAME( TYPE value )                 \
+    {                                             \
+        FIELD = value;                            \
+        FIELD = (*convertor)( FIELD );            \
+    }
+
+#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) \
+    virtual TYPE get_##NAME() const = 0
+
+#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \
+    virtual void set_##NAME( TYPE value ) = 0
+
+#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \
+    virtual TYPE get_##NAME() const = 0;        \
+    virtual void set_##NAME( TYPE value ) = 0
+
+namespace ELFIO {
+
+//------------------------------------------------------------------------------
+class endianess_convertor {
+  public:
+//------------------------------------------------------------------------------
+    endianess_convertor()
+    {
+        need_conversion = false;
+    }
+
+//------------------------------------------------------------------------------
+    void
+    setup( unsigned char elf_file_encoding )
+    {
+        need_conversion = ( elf_file_encoding != get_host_encoding() );
+    }
+
+//------------------------------------------------------------------------------
+    uint64_t
+    operator()( uint64_t value ) const
+    {
+        if ( !need_conversion ) {
+            return value;
+        }
+        value =
+            ( ( value & 0x00000000000000FFull ) << 56 ) |
+            ( ( value & 0x000000000000FF00ull ) << 40 ) |
+            ( ( value & 0x0000000000FF0000ull ) << 24 ) |
+            ( ( value & 0x00000000FF000000ull ) <<  8 ) |
+            ( ( value & 0x000000FF00000000ull ) >>  8 ) |
+            ( ( value & 0x0000FF0000000000ull ) >> 24 ) |
+            ( ( value & 0x00FF000000000000ull ) >> 40 ) |
+            ( ( value & 0xFF00000000000000ull ) >> 56 );
+
+        return value;
+    }
+
+//------------------------------------------------------------------------------
+    int64_t
+    operator()( int64_t value ) const
+    {
+        if ( !need_conversion ) {
+            return value;
+        }
+        return (int64_t)(*this)( (uint64_t)value );
+    }
+
+//------------------------------------------------------------------------------
+    uint32_t
+    operator()( uint32_t value ) const
+    {
+        if ( !need_conversion ) {
+            return value;
+        }
+        value =
+            ( ( value & 0x000000FF ) << 24 ) |
+            ( ( value & 0x0000FF00 ) <<  8 ) |
+            ( ( value & 0x00FF0000 ) >>  8 ) |
+            ( ( value & 0xFF000000 ) >> 24 );
+
+        return value;
+    }
+
+//------------------------------------------------------------------------------
+    int32_t
+    operator()( int32_t value ) const
+    {
+        if ( !need_conversion ) {
+            return value;
+        }
+        return (int32_t)(*this)( (uint32_t)value );
+    }
+
+//------------------------------------------------------------------------------
+    uint16_t
+    operator()( uint16_t value ) const
+    {
+        if ( !need_conversion ) {
+            return value;
+        }
+        value =
+            ( ( value & 0x00FF ) <<  8 ) |
+            ( ( value & 0xFF00 ) >>  8 );
+
+        return value;
+    }
+
+//------------------------------------------------------------------------------
+    int16_t
+    operator()( int16_t value ) const
+    {
+        if ( !need_conversion ) {
+            return value;
+        }
+        return (int16_t)(*this)( (uint16_t)value );
+    }
+
+//------------------------------------------------------------------------------
+    int8_t
+    operator()( int8_t value ) const
+    {
+        return value;
+    }
+
+//------------------------------------------------------------------------------
+    uint8_t
+    operator()( uint8_t value ) const
+    {
+        return value;
+    }
+
+//------------------------------------------------------------------------------
+  private:
+//------------------------------------------------------------------------------
+    unsigned char
+    get_host_encoding() const
+    {
+        static const int tmp = 1;
+        if ( 1 == *(char*)&tmp ) {
+            return ELFDATA2LSB;
+        }
+        else {
+            return ELFDATA2MSB;
+        }
+    }
+
+//------------------------------------------------------------------------------
+  private:
+    bool need_conversion;
+};
+
+
+//------------------------------------------------------------------------------
+inline
+uint32_t
+elf_hash( const unsigned char *name )
+{
+    uint32_t h = 0, g;
+    while ( *name ) {
+        h = (h << 4) + *name++;
+        g = h & 0xf0000000;
+        if ( g != 0 )
+            h ^= g >> 24;
+        h &= ~g;
+    }
+    return h;
+}
+
+} // namespace ELFIO
+
+#endif // ELFIO_UTILS_HPP