source: trunk/kLdr/kLdr.c@ 2824

Last change on this file since 2824 was 2824, checked in by bird, 19 years ago

...

File size: 5.5 KB
Line 
1/* $Id: $ */
2/** @file
3 *
4 * kLdr - The Dynamic Loader.
5 *
6 * Copyright (c) 2006 knut st. osmundsen <bird@anduin.net>
7 *
8 *
9 * This file is part of kLdr.
10 *
11 * kLdr is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * kLdr is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with kLdr; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27/** @pg pg_kLdr kLdr - The Dynamic Loader
28 *
29 * The purpose of kLdr is to provide a generic interface for querying
30 * information about and loading executable image modules.
31 *
32 * kLdr defines the term executable image to include all kinds of files that contains
33 * binary code that can be executed on a CPU - linker objects (OBJs/Os), shared
34 * objects (SOs), dynamic link libraries (DLLs), executables (EXEs), and all kinds
35 * of kernel modules / device drivers (SYSs).
36 *
37 * kLdr provides two types of services:
38 * -# Inspect or/and load individual modules (kLdrMod).
39 * -# Work as a dynamic loader - construct and maintain an address space (kLdrDy).
40 *
41 * The kLdrMod API works on KLDRMOD structures where all the internals are exposed, while
42 * the kLdrDy API works opque KLDRDY structures. KLDRDY are in reality simple wrappers
43 * around KLDRMOD with some extra linking and attributes.
44 *
45 */
46
47
48#include "kLdr.h"
49#include "kLdrHlp.h"
50
51
52/*******************************************************************************
53* Global Variables *
54*******************************************************************************/
55/** Pointer to the head module (the executable).
56 * (This is exported, so no prefix.) */
57PKLDRMOD kLdrModuleHead = NULL;
58/** Pointer to the tail module.
59 * (This is exported, so no prefix.) */
60PKLDRMOD kLdrModuleTail = NULL;
61/** The Library search path. */
62char kLdrLibraryPath[4096];
63/** The executable flags. */
64uint32_t kLdrFlags;
65/** Bootstrap stack and temporary space. */
66char abStack[8192];
67/** Set if we've initialized the loader. */
68int fInitialized = 0;
69
70
71/*******************************************************************************
72* Internal Functions *
73*******************************************************************************/
74static int kldrInit(void);
75static int kldrTerm(void);
76
77
78/**
79 * Initialize the loader.
80 */
81int kldrInit(void)
82{
83 if (fInitialized)
84 return 0;
85 /** @todo */
86 return 0;
87}
88
89
90
91void kldrLoadExe(PKLDREXEARGS pArgs)
92{
93 /*
94 * Copy the arguments into the globals and do load init.
95 */
96 kLdrFlags = pArgs->fFlags;
97 kLdrMemCopy(kLdrLibraryPath, pArgs->szLibPath, KLDR_MIN(sizeof(pArgs->szLibPath), sizeof(kLdrLibraryPath)));
98 int rc = kldrInit();
99 if (rc)
100 kldrFailure(rc, "kLdr: Init failure, rc=%d\n", rc);
101
102 /*
103 * Open the executable module.
104 */
105 PKLDRMOD pExe;
106 kldrOpenExe(pArgs->szExecutable, &pExe);
107
108 /* Map the segments. */
109 kldrModMapSegments(pExe);
110
111 /*
112 * This is the point where we switch to the executable
113 * stack, allocating it if necessary.
114 */
115 void *pvBottom;
116 kldrModSetupStack(pExe, &pvBottom);
117 kldrLoadExecSwitchStack(pvBottom);
118}
119
120
121void kldrLoadExeOnNewStack(void)
122{
123 /*
124 * Load all dependant modules.
125 */
126 PKLDRMOD pCur;
127 do for (pCur = kLdrModuleHead; pCur; pCur = pCur->pNext)
128 {
129 if (pCur->enmState >= KLDRSTATE_DEPS)
130 continue;
131 kldrModLoadDeps(pCur);
132 }
133 while (pCur);
134
135 /*
136 * Do fixups (FIFO).
137 */
138 for (pCur = kLdrModuleHead; pCur; pCur = pCur->pNext)
139 {
140 if (pCur->enmState >= KLDRSTATE_FIXED)
141 continue;
142 kldrModFixup(pCur, 0);
143 }
144
145 /*
146 * Do module initialization.
147 */
148 for (pCur = kLdrModuleTail; pCur != kLdrModuleTail; pCur = pCur->pPrev)
149 {
150 if (pCur->enmState >= KLDRSTATE_INITED)
151 continue;
152 kldrModCallInit(pCur);
153 }
154
155 /*
156 * Get the executable start address and commit the work that's been done.
157 */
158 void *pvEntry;
159 kldrModGetExeEntry(&pvEntry);
160
161 for (pCur = kLdrModuleHead; pCur; pCur = pCur->pNext)
162 if (pCur->enmState == KLDRSTATE_INITED)
163 pCur->enmState = KLDRSTATE_LOADED;
164
165 kldrSemRelease();
166
167 /*
168 * We're now ready for starting the executable code.
169 */
170 kldrOSStartExe(pLdrModuleHead, pvEntry);
171}
172
173
174int kLdrLoadDll(const char *pszFilename, unsigned fFlags, void *pvmod)
175{
176
177 return -1;
178}
179
180
181
182
183/**
184 * Panic / failure
185 *
186 * @returns rc if we're in a position where we can return.
187 * @param rc Return code.
188 * @param pszFormat Message string. Limited fprintf like formatted.
189 * @param ... Message string arguments.
190 */
191int kldrFailure(int rc, const char *pszFormat, ...)
192{
193 kldrExit(1);
194 return rc;
195}
196
Note: See TracBrowser for help on using the repository browser.