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

Last change on this file since 3832 was 2924, checked in by bird, 26 years ago

Started thinking thru writing...

File size: 9.4 KB
Line 
1/* $Id: elf2lx.cpp,v 1.3 2000-02-27 02:13:19 bird Exp $
2 *
3 * Elf2Lx - implementation.
4 *
5 * Copyright (c) 1999-2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.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_NOAPI /* RING0: No apis. */
19#else /*RING3*/
20 #define INCL_DOSPROCESS /* RING3: DosSleep. */
21#endif
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <os2.h> /* OS/2 header file. */
27#include "types.h" /* Types used by the next two files. */
28#include <newexe.h> /* OS/2 NE structs and definitions. */
29#include <exe386.h> /* OS/2 LX structs and definitions. */
30
31#include "malloc.h" /* win32k malloc (resident). Not C library! */
32#include "smalloc.h" /* win32k swappable heap. */
33#include "rmalloc.h" /* win32k resident heap. */
34
35#include <string.h> /* C library string.h. */
36#include <stdlib.h> /* C library stdlib.h. */
37#include <stddef.h> /* C library stddef.h. */
38#include <stdarg.h> /* C library stdarg.h. */
39
40#include "vprintf.h" /* win32k printf and vprintf. Not C library! */
41#include "dev32.h" /* 32-Bit part of the device driver. (SSToDS) */
42#include "OS2Krnl.h" /* kernel structs. (SFN) */
43#ifdef RING0
44 #include "ldrCalls.h" /* ldr* calls. (ldrRead) */
45#endif
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@pmsc.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.