source: trunk/src/win32k/elf2lx/elf2lx.cpp@ 5086

Last change on this file since 5086 was 5086, checked in by bird, 25 years ago

Moved ldrCalls.h into the OS2Krnl.h tree as OS2KLDR.h.
Also moved the Ldr definitions from OS2Krnl.h and into OS2KLDR.h.

File size: 9.5 KB
Line 
1/* $Id: elf2lx.cpp,v 1.6 2001-02-10 11:11:42 bird Exp $
2 *
3 * Elf2Lx - implementation.
4 *
5 * Copyright (c) 1999-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11
12/*******************************************************************************
13* Defined Constants And Macros *
14*******************************************************************************/
15#define FOR_EXEHDR 1 /* To make all object flags OBJ???. */
16#define INCL_DOSERRORS /* DOS Error codes. */
17#ifdef RING0
18 #define INCL_OS2KRNL_LDR /* LdrRead */
19 #define INCL_NOAPI /* RING0: No apis. */
20#else /*RING3*/
21 #define INCL_DOSPROCESS /* RING3: DosSleep. */
22#endif
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <os2.h> /* OS/2 header file. */
28#include "types.h" /* Types used by the next two files. */
29#include <newexe.h> /* OS/2 NE structs and definitions. */
30#include <exe386.h> /* OS/2 LX structs and definitions. */
31
32#include "devSegDf.h" /* Win32k segment definitions. */
33
34#include "malloc.h" /* win32k malloc (resident). Not C library! */
35#include "smalloc.h" /* win32k swappable heap. */
36#include "rmalloc.h" /* win32k resident heap. */
37
38#include <string.h> /* C library string.h. */
39#include <stdlib.h> /* C library stdlib.h. */
40#include <stddef.h> /* C library stddef.h. */
41#include <stdarg.h> /* C library stdarg.h. */
42
43#include "vprintf.h" /* win32k printf and vprintf. Not C library! */
44#include "dev32.h" /* 32-Bit part of the device driver. (SSToDS) */
45#include "OS2Krnl.h" /* kernel structs. (SFN) */
46
47#include "elf.h" /* Elf binary format definitions. */
48#include "modulebase.h" /* ModuleBase class definitions, ++. */
49#include "elf2lx.h" /* Elf2Lx class definitions. */
50
51
52
53/**
54 * Initiation and termination code for libraries.
55 *
56 * How will OS2NIX initiate libraries?
57 * -A library will register with the OS2NIX dll on init and deregister on
58 * termintation.
59 * -If this is before the executable has registered its self, the library
60 * will not be initiated yet. The initiation will take place when the
61 * executable register.
62 * -If it is a dynamically loaded library, we'll initiate it during registation.
63 * Or we could initiate it when the load library call returns, ie. after
64 * DosLoadModule. It depends on how we may resolv addresses of external symbols.
65 *
66 */
67static UCHAR achInitTermCode[] =
68{
69 0xCC
70};
71
72
73/**
74 * Startup code for executables.
75 *
76 * How will OS2NIX start an Elf executable?
77 * -An executable will register with the OS2NIX dll on startup.
78 * -During this registration it'll resolv addresses of external symbols for
79 * the executable and all the libraries registered at this time. It will then
80 * call the initiation routines for the libraries. Finally it will start
81 * the executable.
82 * -If this was a forked process then other steps has to be taken during registration?
83 *
84 */
85static UCHAR achStartupCode[] =
86{
87 0xCC
88};
89
90
91
92/**
93 * Constructor. Initiates all data members and sets hFile.
94 * @param hFile Filehandle.
95 * @status Partially implemented.
96 * @author knut st. osmundsen
97 * @remark Remember to update this everytime a new parameter is added.
98 */
99Elf2Lx::Elf2Lx(SFN hFile) :
100 ModuleBase(hFile)
101{
102 memset(&LXHdr, 0, sizeof(LXHdr));
103 LXHdr.e32_magic[0] = E32MAGIC1;
104 LXHdr.e32_magic[1] = E32MAGIC2;
105 LXHdr.e32_border = E32LEBO;
106 LXHdr.e32_worder = E32LEWO;
107 LXHdr.e32_level = E32LEVEL;
108 LXHdr.e32_cpu = E32CPU386;
109 LXHdr.e32_os = NE_OS2;
110 LXHdr.e32_pagesize = PAGESIZE;
111 LXHdr.e32_objtab = sizeof(LXHdr);
112}
113
114
115/**
116 * Destructor.
117 * @status stub
118 * @author knut st. osmundsen
119 */
120Elf2Lx::~Elf2Lx()
121{
122
123}
124
125
126/**
127 * Initiates the Elf2Lx object - builds the virtual LX image.
128 * When this function completes the object is no longer in init-mode.
129 * @returns NO_ERROR on success.
130 * ERROR_NOT_ENOUGH_MEMORY
131 * ERROR_INVALID_EXE_SIGNATURE
132 * ERROR_BAD_EXE_FORMAT
133 * Error code returned by ReadAt.
134 * Error codes from the make* methods.
135 * @param pszFilename Module filename.
136 * @precond Called in init-mode.
137 * @sketch
138 * 0. pszFilename & pszModuleName.
139 * 1. Read the Elf header.
140 * 2. Verify the header.
141 * 3. Read Program headers.
142 * 4.
143 *
144 * 5.
145 * 6.
146 * 7. Start converting the sections by adding the headerobject. (headerobject, see previous chapter).
147 * 8. Iterate thru the sectiontable converting the section to objects.
148 * 8a. Convert characteristics to flags
149 * 8b. Virtual/physical size (see note in code)
150 * 8c. Add object.
151 * 9.Find where the TIB fix is to be placed. (see 3.1.1 for placements.) Place the TIB fix.
152 * 9a. At the end of the header object.
153 * 9b. After MZ-Header (In the dos stub!).
154 * 9c.Add separate TIBFix object.
155 * 10.Add stack object.
156 * 11.Align section. (Fix which is applied to EXEs/Dlls which contain no fixups and has an
157 * alignment which is not a multiple of 64Kb. The sections are concatenated into one big object.
158 * 12.Update the LXHeader with info which is finalized now. (Stacksize, GUI/CUI, characteristics,...)
159 * 13.Convert exports.
160 * 14.Convert base relocations (fixups). Remember to add the fixup for RegisterPe2LxDll/Exe.
161 * 15.Make object table.
162 * 16.Make object page table.
163 * 17.Completing the LX header.
164 * 18.Set offLXFile in the object array.
165 * 19.The conversion method is completed. Object is now usable.
166 * 20.Dump virtual LX-file
167 * return successfully.
168 * @status Completely implemented; tested.
169 * @author knut st. osmundsen
170 */
171ULONG Elf2Lx::init(PCSZ pszFilename)
172{
173 APIRET rc;
174 unsigned cb; /* helper variable, used to hold sizes in bytes. */
175
176 #ifdef DEBUG
177 if (!fInitTime)
178 {
179 printIPE(("init(..) called when not in init mode!\n"));
180 return ERROR_INITMETHOD_NOT_INITTIME;
181 }
182 #endif
183
184 printInf(("Started processing %s\n", pszFilename));
185
186 /*
187 * 0.pszFilename & pszModuleName.
188 */
189 rc = ModuleBase::init(pszFilename);
190 if (rc != NO_ERROR)
191 return rc;
192
193 /*
194 * 1.Read the Elf header.
195 */
196 pEhdr = (Elf32_Ehdr*)malloc(sizeof(*pEhdr));
197 if (pEhdr == NULL)
198 return ERROR_NOT_ENOUGH_MEMORY;
199 rc = ReadAt(hFile, pEhdr->e_phoff, paPhdrs, pEhdr->e_phentsize * pEhdr->e_phnum);
200 if (rc != NO_ERROR)
201 {
202 printErr(("Failed to read Elf header\n"));
203 return rc;
204 }
205
206 /*
207 * 2.Check that it is a valid header. Fail if invalid.
208 */
209 if (!Elf2Lx::validHeader(pEhdr))
210 {
211 printErr(("Not a valid Elf format\n"));
212 return ERROR_BAD_EXE_FORMAT;
213 }
214
215 /*
216 * 3.Read program table.
217 */
218 cb = pEhdr->e_phentsize * pEhdr->e_phnum;
219 paPhdrs = (Elf32_Phdr*)malloc(cb);
220 if (paPhdrs == NULL)
221 return ERROR_NOT_ENOUGH_MEMORY;
222 rc = ReadAt(hFile, pEhdr->e_phoff, paPhdrs, cb);
223 if (rc != NO_ERROR)
224 {
225 printErr(("Failed to read program headers, off=0x%08x, size=0x%08x\n",
226 pEhdr->e_phoff, cb));
227 return rc;
228 }
229
230 /*
231 * 4.
232 */
233
234 return rc;
235}
236
237
238
239
240/**
241 * Check if the passed in header struct is an Elf header valid for
242 * this system.
243 * @returns TRUE: valid header.
244 * FALSE: invalid header.
245 * @param pEhdr Pointer to elf header.
246 * @status completely implemented.
247 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
248 */
249BOOL Elf2Lx::validHeader(Elf32_Ehdr *pEhdr)
250{
251 /*
252 * Checks.
253 */
254 if (*(PULONG)pEhdr == ELFMAGICLSB /* Elf magic */
255 && pEhdr->e_ident[EI_CLASS] == ELFCLASS32 /* 32-bit format */
256 && pEhdr->e_ident[EI_DATA] == ELFDATA2LSB /* Little endian */
257 && pEhdr->e_ident[EI_VERSION] == EV_CURRENT /* Format version */
258 && (pEhdr->e_type == ET_EXEC || /* Filetype Exec or Library */
259 pEhdr->e_type == ET_DYN)
260 && (pEhdr->e_machine == EM_386 || /* Machine type 386 (or 486) */
261 pEhdr->e_machine == EM_486)
262 && pEhdr->e_version == EV_CURRENT /* Format version */
263 && pEhdr->e_flags == EF_386_NONE /* No flags for 386 and 486 */
264 && pEhdr->e_ehsize >= sizeof(*pEhdr) /* Elf header not smaller than ours. */
265 && pEhdr->e_phentsize >= sizeof(Elf32_Phdr) /* Program header size not smaller than ours. */
266 && pEhdr->e_shentsize >= sizeof(Elf32_Shdr) /* Section header size not smaller than ours. */
267 && pEhdr->e_phnum < 128 /* An image with more that 128 program headers is supicious! */
268 )
269 return TRUE;
270 return FALSE;
271}
272
Note: See TracBrowser for help on using the repository browser.