summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorpixel <pixel>2004-07-17 14:48:33 +0000
committerpixel <pixel>2004-07-17 14:48:33 +0000
commit926333756c8f54894bbfb93d7870ba079943aa66 (patch)
tree0434949c7cb9f775ea0a276b9218bd6663e008a2 /lib
parent1a39ba55a9c112df610b5a06d4044dd3ab6331ab (diff)
Adding elf support for archives
Diffstat (limited to 'lib')
-rw-r--r--lib/Input.cc52
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);