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

Last change on this file was 5299, checked in by bird, 24 years ago

Made it compile by fixing header trouble and stubbing virtual functions.

File size: 12.0 KB
Line 
1/* $Id: elf2lx.cpp,v 1.7 2001-03-11 16:49:16 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#define INCL_OS2KRNL_LDR /* LdrRead */
18#ifdef RING0
19 #define INCL_NOAPI /* RING0: No apis. */
20#else /*RING3*/
21 #define INCL_DOSPROCESS /* RING3: DosSleep. */
22 #define INCL_OS2KRNL_LDR_NOAPIS /* No apis */
23#endif
24
25/*******************************************************************************
26* Header Files *
27*******************************************************************************/
28#include <os2.h> /* OS/2 header file. */
29#include "types.h" /* Types used by the next two files. */
30#include <newexe.h> /* OS/2 NE structs and definitions. */
31#include <exe386.h> /* OS/2 LX structs and definitions. */
32#include "elf.h" /* Elf binary format definitions. */
33
34#include "devSegDf.h" /* Win32k segment definitions. */
35
36#include "malloc.h" /* win32k malloc (resident). Not C library! */
37#include "smalloc.h" /* win32k swappable heap. */
38#include "rmalloc.h" /* win32k resident heap. */
39
40#include <string.h> /* C library string.h. */
41#include <stdlib.h> /* C library stdlib.h. */
42#include <stddef.h> /* C library stddef.h. */
43#include <stdarg.h> /* C library stdarg.h. */
44
45#include "vprintf.h" /* win32k printf and vprintf. Not C library! */
46#include "dev32.h" /* 32-Bit part of the device driver. (SSToDS) */
47#include "OS2Krnl.h" /* kernel structs. (SFN) */
48
49#include "modulebase.h" /* ModuleBase class definitions, ++. */
50#include "elf2lx.h" /* Elf2Lx class definitions. */
51
52
53
54/**
55 * Initiation and termination code for libraries.
56 *
57 * How will OS2NIX initiate libraries?
58 * -A library will register with the OS2NIX dll on init and deregister on
59 * termintation.
60 * -If this is before the executable has registered its self, the library
61 * will not be initiated yet. The initiation will take place when the
62 * executable register.
63 * -If it is a dynamically loaded library, we'll initiate it during registation.
64 * Or we could initiate it when the load library call returns, ie. after
65 * DosLoadModule. It depends on how we may resolv addresses of external symbols.
66 *
67 */
68static UCHAR achInitTermCode[] =
69{
70 0xCC
71};
72
73
74/**
75 * Startup code for executables.
76 *
77 * How will OS2NIX start an Elf executable?
78 * -An executable will register with the OS2NIX dll on startup.
79 * -During this registration it'll resolv addresses of external symbols for
80 * the executable and all the libraries registered at this time. It will then
81 * call the initiation routines for the libraries. Finally it will start
82 * the executable.
83 * -If this was a forked process then other steps has to be taken during registration?
84 *
85 */
86static UCHAR achStartupCode[] =
87{
88 0xCC
89};
90
91
92
93/**
94 * Constructor. Initiates all data members and sets hFile.
95 * @param hFile Filehandle.
96 * @status Partially implemented.
97 * @author knut st. osmundsen
98 * @remark Remember to update this everytime a new parameter is added.
99 */
100Elf2Lx::Elf2Lx(SFN hFile) :
101 ModuleBase(hFile)
102{
103 memset(&LXHdr, 0, sizeof(LXHdr));
104 LXHdr.e32_magic[0] = E32MAGIC1;
105 LXHdr.e32_magic[1] = E32MAGIC2;
106 LXHdr.e32_border = E32LEBO;
107 LXHdr.e32_worder = E32LEWO;
108 LXHdr.e32_level = E32LEVEL;
109 LXHdr.e32_cpu = E32CPU386;
110 LXHdr.e32_os = NE_OS2;
111 LXHdr.e32_pagesize = PAGESIZE;
112 LXHdr.e32_objtab = sizeof(LXHdr);
113}
114
115
116/**
117 * Destructor.
118 * @status stub
119 * @author knut st. osmundsen
120 */
121Elf2Lx::~Elf2Lx()
122{
123
124}
125
126
127/**
128 * Initiates the Elf2Lx object - builds the virtual LX image.
129 * When this function completes the object is no longer in init-mode.
130 * @returns NO_ERROR on success.
131 * ERROR_NOT_ENOUGH_MEMORY
132 * ERROR_INVALID_EXE_SIGNATURE
133 * ERROR_BAD_EXE_FORMAT
134 * Error code returned by ReadAt.
135 * Error codes from the make* methods.
136 * @param pszFilename Module filename.
137 * @precond Called in init-mode.
138 * @sketch
139 * 0. pszFilename & pszModuleName.
140 * 1. Read the Elf header.
141 * 2. Verify the header.
142 * 3. Read Program headers.
143 * 4.
144 *
145 * 5.
146 * 6.
147 * 7. Start converting the sections by adding the headerobject. (headerobject, see previous chapter).
148 * 8. Iterate thru the sectiontable converting the section to objects.
149 * 8a. Convert characteristics to flags
150 * 8b. Virtual/physical size (see note in code)
151 * 8c. Add object.
152 * 9.Find where the TIB fix is to be placed. (see 3.1.1 for placements.) Place the TIB fix.
153 * 9a. At the end of the header object.
154 * 9b. After MZ-Header (In the dos stub!).
155 * 9c.Add separate TIBFix object.
156 * 10.Add stack object.
157 * 11.Align section. (Fix which is applied to EXEs/Dlls which contain no fixups and has an
158 * alignment which is not a multiple of 64Kb. The sections are concatenated into one big object.
159 * 12.Update the LXHeader with info which is finalized now. (Stacksize, GUI/CUI, characteristics,...)
160 * 13.Convert exports.
161 * 14.Convert base relocations (fixups). Remember to add the fixup for RegisterPe2LxDll/Exe.
162 * 15.Make object table.
163 * 16.Make object page table.
164 * 17.Completing the LX header.
165 * 18.Set offLXFile in the object array.
166 * 19.The conversion method is completed. Object is now usable.
167 * 20.Dump virtual LX-file
168 * return successfully.
169 * @status Completely implemented; tested.
170 * @author knut st. osmundsen
171 */
172ULONG Elf2Lx::init(PCSZ pszFilename)
173{
174 APIRET rc;
175 unsigned cb; /* helper variable, used to hold sizes in bytes. */
176
177 #ifdef DEBUG
178 if (!fInitTime)
179 {
180 printIPE(("init(..) called when not in init mode!\n"));
181 return ERROR_INITMETHOD_NOT_INITTIME;
182 }
183 #endif
184
185 printInf(("Started processing %s\n", pszFilename));
186
187 /*
188 * 0.pszFilename & pszModuleName.
189 */
190 rc = ModuleBase::init(pszFilename);
191 if (rc != NO_ERROR)
192 return rc;
193
194 /*
195 * 1.Read the Elf header.
196 */
197 pEhdr = (Elf32_Ehdr*)malloc(sizeof(*pEhdr));
198 if (pEhdr == NULL)
199 return ERROR_NOT_ENOUGH_MEMORY;
200 rc = ReadAt(hFile, pEhdr->e_phoff, paPhdrs, pEhdr->e_phentsize * pEhdr->e_phnum);
201 if (rc != NO_ERROR)
202 {
203 printErr(("Failed to read Elf header\n"));
204 return rc;
205 }
206
207 /*
208 * 2.Check that it is a valid header. Fail if invalid.
209 */
210 if (!Elf2Lx::validHeader(pEhdr))
211 {
212 printErr(("Not a valid Elf format\n"));
213 return ERROR_BAD_EXE_FORMAT;
214 }
215
216 /*
217 * 3.Read program table.
218 */
219 cb = pEhdr->e_phentsize * pEhdr->e_phnum;
220 paPhdrs = (Elf32_Phdr*)malloc(cb);
221 if (paPhdrs == NULL)
222 return ERROR_NOT_ENOUGH_MEMORY;
223 rc = ReadAt(hFile, pEhdr->e_phoff, paPhdrs, cb);
224 if (rc != NO_ERROR)
225 {
226 printErr(("Failed to read program headers, off=0x%08x, size=0x%08x\n",
227 pEhdr->e_phoff, cb));
228 return rc;
229 }
230
231 /*
232 * 4.
233 */
234
235 return rc;
236}
237
238
239
240
241/**
242 * Check if the passed in header struct is an Elf header valid for
243 * this system.
244 * @returns TRUE: valid header.
245 * FALSE: invalid header.
246 * @param pEhdr Pointer to elf header.
247 * @status completely implemented.
248 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
249 */
250BOOL Elf2Lx::validHeader(Elf32_Ehdr *pEhdr)
251{
252 /*
253 * Checks.
254 */
255 if (*(PULONG)pEhdr == ELFMAGICLSB /* Elf magic */
256 && pEhdr->e_ident[EI_CLASS] == ELFCLASS32 /* 32-bit format */
257 && pEhdr->e_ident[EI_DATA] == ELFDATA2LSB /* Little endian */
258 && pEhdr->e_ident[EI_VERSION] == EV_CURRENT /* Format version */
259 && (pEhdr->e_type == ET_EXEC || /* Filetype Exec or Library */
260 pEhdr->e_type == ET_DYN)
261 && (pEhdr->e_machine == EM_386 || /* Machine type 386 (or 486) */
262 pEhdr->e_machine == EM_486)
263 && pEhdr->e_version == EV_CURRENT /* Format version */
264 && pEhdr->e_flags == EF_386_NONE /* No flags for 386 and 486 */
265 && pEhdr->e_ehsize >= sizeof(*pEhdr) /* Elf header not smaller than ours. */
266 && pEhdr->e_phentsize >= sizeof(Elf32_Phdr) /* Program header size not smaller than ours. */
267 && pEhdr->e_shentsize >= sizeof(Elf32_Shdr) /* Section header size not smaller than ours. */
268 && pEhdr->e_phnum < 128 /* An image with more that 128 program headers is supicious! */
269 )
270 return TRUE;
271 return FALSE;
272}
273
274
275/**
276 * Read data from the virtual LX-file.
277 * @param offLXFile Offset (into the virtual lx file) of the data to read
278 * @param pvBuffer Pointer to buffer where data is to be put.
279 * @param cbToRead Bytes to be read.
280 * @param fpBuffer Flags which was spesified to the ldrRead call.
281 * @parma pMTE Pointer to MTE which was specified to the ldrRead call.
282 * @return NO_ERROR if successful something else if not.
283 * @status completely implmented; tested.
284 * @author knut st. osmundsen
285 */
286ULONG Elf2Lx::read(ULONG offLXFile, PVOID pvBuffer, ULONG fpBuffer, ULONG cbToRead, PMTE pMTE)
287{
288 NOREF(offLXFile);
289 NOREF(pvBuffer);
290 NOREF(fpBuffer);
291 NOREF(cbToRead);
292 NOREF(pMTE);
293 return ERROR_READ_FAULT;
294}
295
296
297/**
298 * Applies relocation fixups to a page which is being loaded.
299 * @returns NO_ERROR on success?
300 * error code on error?
301 * @param pMTE Pointer Module Table Entry.
302 * @param iObject Index into the object table. (0-based)
303 * @param iPageTable Index into the page table. (0-based)
304 * @param pvPage Pointer to the page which is being loaded.
305 * @param ulPageAddress Address of page.
306 * @param pvPTDA Pointer to Per Task Data Aera
307 *
308 * @sketch Find RVA.
309 * @remarks Some more information on relocations:
310 */
311ULONG Elf2Lx::applyFixups(PMTE pMTE, ULONG iObject, ULONG iPageTable, PVOID pvPage,
312 ULONG ulPageAddress, PVOID pvPTDA)
313{
314 NOREF(pMTE);
315 NOREF(iObject);
316 NOREF(iPageTable);
317 NOREF(pvPage);
318 NOREF(ulPageAddress);
319 NOREF(pvPTDA);
320 return ERROR_READ_FAULT;
321}
322
323
324/**
325 * Writes the virtual LX file to a file. (Ring 3 only!)
326 * @returns NO_ERROR on success. Error code on error.
327 * @param pszLXFilename Pointer to name of the LX file.
328 * @sketch Find size of the virtual LX-file.
329 * Open the output file.
330 * LOOP while more to left of file
331 * BEGIN
332 * read into buffer from virtual LX-file.
333 * write to output file.
334 * END
335 * return success or errorcode.
336 * @status compeletely implemented; tested.
337 * @author knut st. osmundsen
338 */
339ULONG Elf2Lx::writeFile(PCSZ pszLXFilename)
340{
341 NOREF(pszLXFilename);
342 return ERROR_WRITE_FAULT;
343}
344
345
346/**
347 * Dumps info on the virtual Lx file.
348 * Currently it only dumps sizes and offsets.
349 * @status partially implemented.
350 * @author knut st. osmundsen
351 */
352VOID Elf2Lx::dumpVirtualLxFile()
353{
354
355}
356
Note: See TracBrowser for help on using the repository browser.