diff options
author | pixel <pixel> | 2004-07-17 14:48:33 +0000 |
---|---|---|
committer | pixel <pixel> | 2004-07-17 14:48:33 +0000 |
commit | 926333756c8f54894bbfb93d7870ba079943aa66 (patch) | |
tree | 0434949c7cb9f775ea0a276b9218bd6663e008a2 /lib | |
parent | 1a39ba55a9c112df610b5a06d4044dd3ab6331ab (diff) |
Adding elf support for archives
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Input.cc | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/lib/Input.cc b/lib/Input.cc index f8762d9..992b39a 100644 --- a/lib/Input.cc +++ b/lib/Input.cc @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: Input.cc,v 1.44 2004-05-03 13:04:37 pixel Exp $ */ +/* $Id: Input.cc,v 1.45 2004-07-17 14:48:33 pixel Exp $ */ #include <stdio.h> #include <string.h> @@ -261,6 +261,36 @@ struct PEsection_t { Uint32 Chars; } PACKED; +struct elf_header_t { + union { + Uint8 raw[16]; + struct e_ident_t { + Uint8 ei_magic[4]; + Uint8 ei_class; + Uint8 ei_data; + Uint8 ei_version; + } cook; + } e_ident; + Uint16 e_type; + Uint16 e_machine; + Uint32 e_version; + Uint32 e_entry; + Uint32 e_phoff; + Uint32 e_shoff; + Uint32 e_flags; + Uint16 e_ehsize; + Uint16 e_phentsize; + Uint16 e_phnum; + Uint16 e_shentsize; + Uint16 e_shnum; + Uint16 e_shstrndx; +} PACKED; + +struct elf_section_t { + Uint32 sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_size; + Uint32 sh_link, sh_info, sh_addralign, sh_entsize; +} PACKED; + void Archive::create() throw (GeneralException) { char buffer[1024]; int len; @@ -276,8 +306,9 @@ void Archive::create() throw (GeneralException) { case ARCHIVE_EXECUTABLE: startptr = archive->tell(); sig = archive->readU32(); + archive->seek(-4, SEEK_CUR); if ((sig & 0xffff) == 0x5a4d) { /* MZ */ - archive->seek(56, SEEK_CUR); + archive->seek(60, SEEK_CUR); sig = archive->readU32(); archive->seek(sig - 64, SEEK_CUR); sig = archive->readU32(); @@ -294,6 +325,23 @@ void Archive::create() throw (GeneralException) { maxptr = ptr; } archive->seek(startptr - archive->tell() + maxptr, SEEK_CUR); + } else if (sig == 0x464c457f) { /* ELF */ + elf_header_t head; + elf_section_t sec; + int cur_end, max_end = 0; + int i; + + archive->read(&head, sizeof(head)); + archive->seek(startptr + head.e_shoff); + + for (i = 0; i < head.e_shnum; i++) { + archive->read(&sec, sizeof(elf_section_t)); + archive->seek(head.e_shentsize - sizeof(elf_section_t), SEEK_CUR); + cur_end = sec.sh_offset + sec.sh_size; + if (cur_end > max_end) + max_end = cur_end; + } + archive->seek(startptr + max_end); } case ARCHIVE_BUILTIN: memset(buffer, 0, 4); |