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

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

Merged in the Grace branch. New Win32k!

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