OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [loader/] [libs/] [elf/] [src/] [elf.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Australian Public Licence B (OZPLB)
3
 *
4
 * Version 1-0
5
 *
6
 * Copyright (c) 2004 University of New South Wales
7
 *
8
 * All rights reserved.
9
 *
10
 * Developed by: Operating Systems and Distributed Systems Group (DiSy)
11
 *               University of New South Wales
12
 *               http://www.disy.cse.unsw.edu.au
13
 *
14
 * Permission is granted by University of New South Wales, free of charge, to
15
 * any person obtaining a copy of this software and any associated
16
 * documentation files (the "Software") to deal with the Software without
17
 * restriction, including (without limitation) the rights to use, copy,
18
 * modify, adapt, merge, publish, distribute, communicate to the public,
19
 * sublicense, and/or sell, lend or rent out copies of the Software, and
20
 * to permit persons to whom the Software is furnished to do so, subject
21
 * to the following conditions:
22
 *
23
 *     * Redistributions of source code must retain the above copyright
24
 *       notice, this list of conditions and the following disclaimers.
25
 *
26
 *     * Redistributions in binary form must reproduce the above
27
 *       copyright notice, this list of conditions and the following
28
 *       disclaimers in the documentation and/or other materials provided
29
 *       with the distribution.
30
 *
31
 *     * Neither the name of University of New South Wales, nor the names of its
32
 *       contributors, may be used to endorse or promote products derived
33
 *       from this Software without specific prior written permission.
34
 *
35
 * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
36
 * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
37
 * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
38
 * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
39
 * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
40
 * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
41
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
42
 * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
43
 * ERRORS, WHETHER OR NOT DISCOVERABLE.
44
 *
45
 * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
46
 * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
47
 * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
48
 * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
49
 * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
50
 * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
51
 * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
52
 * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
53
 * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
54
 * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
55
 * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
56
 * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
57
 * DAMAGES OR OTHER LIABILITY.
58
 *
59
 * If applicable legislation implies representations, warranties, or
60
 * conditions, or imposes obligations or liability on University of New South
61
 * Wales or one of its contributors in respect of the Software that
62
 * cannot be wholly or partly excluded, restricted or modified, the
63
 * liability of University of New South Wales or the contributor is limited, to
64
 * the full extent permitted by the applicable legislation, at its
65
 * option, to:
66
 * a.  in the case of goods, any one or more of the following:
67
 * i.  the replacement of the goods or the supply of equivalent goods;
68
 * ii.  the repair of the goods;
69
 * iii. the payment of the cost of replacing the goods or of acquiring
70
 *  equivalent goods;
71
 * iv.  the payment of the cost of having the goods repaired; or
72
 * b.  in the case of services:
73
 * i.  the supplying of the services again; or
74
 * ii.  the payment of the cost of having the services supplied again.
75
 *
76
 * The construction, validity and performance of this licence is governed
77
 * by the laws in force in New South Wales, Australia.
78
 */
79
void *str;
80
#include <elf/elf.h>
81
#include <string.h>
82
#include <stdio.h>
83
 
84
/*
85
 * Checks that elfFile points to a valid elf file. Returns 0 if the elf
86
 * file is valid, < 0 if invalid.
87
 */
88
 
89
#define ISELF32(elfFile) ( ((struct Elf32_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS32 )
90
#define ISELF64(elfFile) ( ((struct Elf64_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS64 )
91
 
92
int
93
elf_checkFile(void *elfFile)
94
{
95
        return ISELF32 (elfFile)
96
                ? elf32_checkFile(elfFile)
97
                : elf64_checkFile(elfFile);
98
}
99
 
100
/* Program Headers Access functions */
101
uint16_t
102
elf_getNumProgramHeaders(void *elfFile)
103
{
104
        return ISELF32 (elfFile)
105
                ? elf32_getNumProgramHeaders(elfFile)
106
                : elf64_getNumProgramHeaders(elfFile);
107
}
108
 
109
uint32_t
110
elf_getProgramHeaderFlags(void *elfFile, uint16_t ph)
111
{
112
        return ISELF32 (elfFile)
113
                ? elf32_getProgramHeaderFlags(elfFile, ph)
114
                : elf64_getProgramHeaderFlags(elfFile, ph);
115
}
116
 
117
uint32_t
118
elf_getProgramHeaderType(void *elfFile, uint16_t ph)
119
{
120
        return ISELF32 (elfFile)
121
                ? elf32_getProgramHeaderType(elfFile, ph)
122
                : elf64_getProgramHeaderType(elfFile, ph);
123
}
124
 
125
uint64_t
126
elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph)
127
{
128
        return ISELF32 (elfFile)
129
                ? elf32_getProgramHeaderPaddr(elfFile, ph)
130
                : elf64_getProgramHeaderPaddr(elfFile, ph);
131
}
132
 
133
uint64_t
134
elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph)
135
{
136
        return ISELF32 (elfFile)
137
                ? elf32_getProgramHeaderVaddr(elfFile, ph)
138
                : elf64_getProgramHeaderVaddr(elfFile, ph);
139
}
140
 
141
uint64_t
142
elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph)
143
{
144
        return ISELF32 (elfFile)
145
                ? elf32_getProgramHeaderMemorySize(elfFile, ph)
146
                : elf64_getProgramHeaderMemorySize(elfFile, ph);
147
}
148
 
149
uint64_t
150
elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph)
151
{
152
        return ISELF32 (elfFile)
153
                ? elf32_getProgramHeaderFileSize(elfFile, ph)
154
                : elf64_getProgramHeaderFileSize(elfFile, ph);
155
}
156
 
157
uint64_t
158
elf_getProgramHeaderOffset(void *elfFile, uint16_t ph)
159
{
160
        return ISELF32 (elfFile)
161
                ? elf32_getProgramHeaderOffset(elfFile, ph)
162
                : elf64_getProgramHeaderOffset(elfFile, ph);
163
}
164
 
165
char *
166
elf_getSegmentStringTable(void *elfFile)
167
{
168
        return ISELF32 (elfFile)
169
                ? elf32_getSegmentStringTable(elfFile)
170
                : elf64_getSegmentStringTable(elfFile);
171
}
172
 
173
char *
174
elf_getStringTable(void *elfFile, int string_segment)
175
{
176
        return ISELF32 (elfFile)
177
                ? elf32_getStringTable(elfFile)
178
                : elf64_getStringTable(elfFile, string_segment);
179
}
180
 
181
 
182
unsigned
183
elf_getNumSections(void *elfFile)
184
{
185
        return ISELF32 (elfFile)
186
                ? elf32_getNumSections(elfFile)
187
                : elf64_getNumSections(elfFile);
188
}
189
 
190
char *
191
elf_getSectionName(void *elfFile, int i)
192
{
193
        return ISELF32 (elfFile)
194
                ? elf32_getSectionName(elfFile, i)
195
                : elf64_getSectionName(elfFile, i);
196
}
197
 
198
uint32_t
199
elf_getSectionFlags(void *elfFile, int i)
200
{
201
        return ISELF32 (elfFile)
202
                ? elf32_getSectionFlags(elfFile, i)
203
                : elf64_getSectionFlags(elfFile, i);
204
}
205
 
206
uint32_t
207
elf_getSectionType(void *elfFile, int i)
208
{
209
        return ISELF32 (elfFile)
210
                ? elf32_getSectionType(elfFile, i)
211
                : elf64_getSectionType(elfFile, i);
212
}
213
 
214
uint64_t
215
elf_getSectionSize(void *elfFile, int i)
216
{
217
        return ISELF32 (elfFile)
218
                ? elf32_getSectionSize(elfFile, i)
219
                : elf64_getSectionSize(elfFile, i);
220
}
221
 
222
uint64_t
223
elf_getSectionAddr(void *elfFile, int i)
224
{
225
        return ISELF32 (elfFile)
226
                ? elf32_getSectionAddr(elfFile, i)
227
                : elf64_getSectionAddr(elfFile, i);
228
}
229
 
230
 
231
void *
232
elf_getSection(void *elfFile, int i)
233
{
234
        return ISELF32 (elfFile)
235
                ? elf32_getSection(elfFile, i)
236
                : elf64_getSection(elfFile, i);
237
}
238
 
239
void *
240
elf_getSectionNamed(void *elfFile, char *_str)
241
{
242
        return ISELF32 (elfFile)
243
                ? elf32_getSectionNamed(elfFile, _str)
244
                : elf64_getSectionNamed(elfFile, _str);
245
}
246
 
247
void
248
elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr,
249
                         uint64_t *p_paddr, uint64_t *p_filesz, uint64_t *p_offset,
250
                         uint64_t *p_memsz)
251
{
252
        *p_vaddr = elf_getProgramHeaderVaddr(elfFile, ph);
253
        *p_paddr = elf_getProgramHeaderPaddr(elfFile, ph);
254
        *p_filesz = elf_getProgramHeaderFileSize(elfFile, ph);
255
        *p_offset = elf_getProgramHeaderOffset(elfFile, ph);
256
        *p_memsz = elf_getProgramHeaderMemorySize(elfFile, ph);
257
}
258
 
259
uint64_t
260
elf_getEntryPoint(void *elfFile)
261
{
262
        return ISELF32 (elfFile)
263
                ? elf32_getEntryPoint (elfFile)
264
                : elf64_getEntryPoint (elfFile);
265
}
266
 
267
void
268
elf_fprintf(FILE *f, void *file, int size, const char *name, int flags)
269
{
270
        elf32_fprintf(f, file, size, name, flags);
271
 
272
}
273
 
274
bool
275
elf_getMemoryBounds(void *elfFile, bool phys, uint64_t *min, uint64_t *max)
276
{
277
        uint64_t mem_min = UINT64_MAX;
278
        uint64_t mem_max = 0;
279
        int i;
280
 
281
        if (elf_checkFile(elfFile) != 0) {
282
                return false;
283
        }
284
 
285
        for(i=0; i < elf_getNumProgramHeaders(elfFile); i++) {
286
                uint64_t sect_min, sect_max;
287
 
288
                if (elf_getProgramHeaderMemorySize(elfFile, i) == 0) {
289
                        continue;
290
                }
291
 
292
                if (phys) {
293
                        sect_min = elf_getProgramHeaderPaddr(elfFile, i);
294
                } else {
295
                        sect_min = elf_getProgramHeaderVaddr(elfFile, i);
296
                }
297
 
298
                sect_max = sect_min + elf_getProgramHeaderMemorySize(elfFile, i);
299
 
300
                if (sect_max > mem_max) {
301
                        mem_max = sect_max;
302
                }
303
                if (sect_min < mem_min) {
304
                        mem_min = sect_min;
305
                }
306
        }
307
        *min = mem_min;
308
        *max = mem_max;
309
 
310
        return true;
311
};
312
 
313
bool
314
elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr)
315
{
316
        uint64_t min = elf_getProgramHeaderVaddr(elfFile, ph);
317
        uint64_t max = min + elf_getProgramHeaderMemorySize(elfFile, ph);
318
        if (vaddr >= min && vaddr < max) {
319
                return true;
320
        } else {
321
                return false;
322
        }
323
}
324
 
325
uint64_t
326
elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr)
327
{
328
        uint64_t ph_phys = elf_getProgramHeaderPaddr(elfFile, ph);
329
        uint64_t ph_virt = elf_getProgramHeaderVaddr(elfFile, ph);
330
        uint64_t paddr;
331
 
332
        paddr = vaddr - ph_virt + ph_phys;
333
 
334
        return paddr;
335
}
336
 
337
bool
338
elf_loadFile(void *elfFile, bool phys)
339
{
340
        int i;
341
        int num_pheaders;
342
        int pheader_offset;
343
        int pheader_type;
344
        if (elf_checkFile(elfFile) != 0) {
345
                return false;
346
        }
347
 
348
        num_pheaders = elf_getNumProgramHeaders(elfFile);
349
        pheader_offset = elf_getProgramHeaderOffset(elfFile, 0);
350
        //printf("Number of program headers: %d\n", num_pheaders);
351
        //printf("Program header offset of first header from file beginning: 0x%p\n",pheader_offset);
352
 
353
        /*
354
         * FIXME:
355
         * This should have a linked list of mapped ranges so that it can check
356
         * at run-time whether any images are overlapping in their LMA and refuse to load.
357
         */
358
        for(i=0; i < num_pheaders; i++) {
359
                /* Load that section */
360
                uint64_t dest, src;
361
                uint32_t clrsize;
362
                size_t len;
363
                if (phys) {
364
                        dest = elf_getProgramHeaderPaddr(elfFile, i);
365
                //      printf("Elf file pheader physical: 0x%x\n", (unsigned int)dest);
366
                //      printf("Elf file pheader virtual: 0x%x\n",
367
                //             (unsigned int)elf_getProgramHeaderVaddr(elfFile,i));
368
                } else {
369
                //      printf("Elf file pheader virtual: 0x%x\n", (unsigned int)dest);
370
                        dest = elf_getProgramHeaderVaddr(elfFile, i);
371
                }
372
                len = elf_getProgramHeaderFileSize(elfFile, i);
373
        //      printf("This section's size in file: %p\n", len);
374
                src = (uint64_t) (uintptr_t) elfFile + elf_getProgramHeaderOffset(elfFile, i);
375
        //      printf("Elf program header offset: %p\n", src);
376
                pheader_type = elf_getProgramHeaderType(elfFile, i);
377
        //      printf("Elf program header type: %p\n", pheader_type);
378
// Comment
379
//printf("Copying to range from 0x%x to 0x%x of size: 0x%x\n", (unsigned int)dest, (unsigned int)dest + (unsigned int)len, (unsigned int)len);
380
                memcpy((void*) (uintptr_t) dest, (void*) (uintptr_t) src, len);
381
                dest += len;
382
                clrsize = elf_getProgramHeaderMemorySize(elfFile, i) - len;
383
//              printf("Clearing memory... starting from %x, size: %x\n", (unsigned int)dest, (unsigned int)clrsize);
384
                memset((void*) (uintptr_t) dest, 0, clrsize);
385
//              printf("Memory cleared.\n");
386
        }
387
// And this one
388
//      printf("\n");
389
 
390
        return true;
391
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.