Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1882 clevermous 1
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
2
/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
#include 
9
 
10
#define STUB_INFO_MAGIC "StubInfoMagic!!"
11
 
12
static _v2_prog_type type;
13
static int type_initialized = 0;
14
 
15
static
16
const _v2_prog_type *_check_v2_prog_internal (int pf);
17
 
18
const _v2_prog_type *_check_v2_prog(const char *program, int pf)
19
{
20
  const _v2_prog_type *prog_type;
21
 
22
  if (type_initialized && type.stubinfo)
23
    free(type.stubinfo);
24
  type_initialized = 1;
25
 
26
  memset(&type, 0, sizeof(type));
27
 
28
  if (program)
29
  {
30
    pf = open(program, O_RDONLY|O_BINARY);
31
    if (pf < 0)
32
      return &type;
33
  }
34
 
35
  prog_type = _check_v2_prog_internal(pf);
36
 
37
  if (program)
38
    close(pf);
39
 
40
  if (prog_type)
41
    type.valid = 1;
42
  return &type;
43
}
44
 
45
static
46
const _v2_prog_type *_check_v2_prog_internal (int pf)
47
{
48
  unsigned short header[5];
49
  lseek(pf, 0, SEEK_SET);
50
  if (read(pf, header, sizeof(header)) != sizeof(header))
51
    return NULL;
52
  if (header[0] == 0x010b || header[0] == 0x014c)
53
  {
54
    unsigned char firstbytes[1];
55
    unsigned long coffhdr[40];
56
 
57
    /* Seems to be an unstubbed COFF.  See what the first opcode
58
       is to determine if it's v1.x or v2 COFF (or an impostor).
59
 
60
       FIXME: the code here assumes that any COFF that's not a V1
61
       can only be V2.  What about other compilers that use COFF?  */
62
    type.object_format = _V2_OBJECT_FORMAT_COFF;
63
    if (lseek(pf, 2, 1) < 0
64
	|| read(pf, coffhdr, sizeof(coffhdr)) != sizeof(coffhdr)
65
	|| lseek(pf, coffhdr[10 + 5], 0) < 0
66
	|| read(pf, firstbytes, 1) != 1) /* scnptr */
67
        /* "Aha! An impostor!" (The Adventure game) */
68
      type.object_format = _V2_OBJECT_FORMAT_UNKNOWN;
69
    else if (firstbytes[0] != 0xa3) /* opcode of movl %eax, 0x12345678 (V1) */
70
           type.version.v.major = 2;
71
         else
72
           type.version.v.major = 1;
73
    type.exec_format = _V2_EXEC_FORMAT_COFF;
74
  }
75
  else if (header[0] == 0x5a4d)	/* "MZ" */
76
  {
77
    char go32stub[9];
78
    unsigned long coff_start = (unsigned long)header[2]*512L;
79
    unsigned long exe_start;
80
    type.exec_format = _V2_EXEC_FORMAT_EXE;
81
    if (header[1])
82
      coff_start += (long)header[1] - 512L;
83
    exe_start = (unsigned long)header[4]*16L;
84
    if (lseek(pf, exe_start, SEEK_SET) != exe_start)
85
      return NULL;
86
    if (read(pf, go32stub, 8) != 8)
87
      return NULL;
88
    go32stub[8] = 0;
89
    if (strcmp(go32stub, "go32stub") == 0)
90
    {
91
      type.version.v.major = 2;
92
      type.object_format = _V2_OBJECT_FORMAT_COFF;
93
      type.exec_format = _V2_EXEC_FORMAT_STUBCOFF;
94
    }
95
    else
96
    {
97
      int stub_offset;
98
      char magic[16];
99
      int struct_length;
100
      unsigned short coff_id;
101
      type.version.v.major = 1;
102
      if (lseek(pf, coff_start - 4, SEEK_SET) != coff_start-4)
103
        return NULL;
104
      if (read(pf, &stub_offset, 4) != 4)
105
        return NULL;
106
      if (read(pf, &coff_id, 2) != 2)
107
        return NULL;
108
      if (coff_id == 0x010b || coff_id == 0x014c)
109
      {
110
        type.object_format = _V2_OBJECT_FORMAT_COFF;
111
        type.exec_format = _V2_EXEC_FORMAT_STUBCOFF;
112
      }
113
      if (lseek(pf, stub_offset, 0) != stub_offset)
114
        return NULL;
115
      if (read(pf, magic, 16) != 16)
116
        return NULL;
117
      if (memcmp(STUB_INFO_MAGIC, magic, 16) == 0)
118
      {
119
        if (read(pf, &struct_length, 4) != 4)
120
          return NULL;
121
        type.stubinfo = (_v1_stubinfo *)malloc(struct_length);
122
        memcpy(type.stubinfo->magic, magic, 16);
123
        type.stubinfo->struct_length = struct_length;
124
        if (read(pf, type.stubinfo->go32, struct_length - 20)
125
            != struct_length - 20)
126
          return NULL;
127
        type.has_stubinfo = 1;
128
      }
129
    }
130
  }
131
  else if (header[0] == 0x2123)	/* "#!" */
132
  {
133
    type.exec_format = _V2_EXEC_FORMAT_UNIXSCRIPT;
134
  }
135
  return &type;
136
}
137