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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [fs/] [binfmt_elf.c] - Blame information for rev 707

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * linux/fs/binfmt_elf.c
3
 *
4
 * These are the functions used to load ELF format executables as used
5
 * on SVr4 machines.  Information on the format may be found in the book
6
 * "UNIX SYSTEM V RELEASE 4 Programmers Guide: Ansi C and Programming Support
7
 * Tools".
8
 *
9
 * Copyright 1993, 1994: Eric Youngdale (ericy@cais.com).
10
 */
11
 
12
#include <linux/module.h>
13
 
14
#include <linux/fs.h>
15
#include <linux/stat.h>
16
#include <linux/sched.h>
17
#include <linux/mm.h>
18
#include <linux/mman.h>
19
#include <linux/a.out.h>
20
#include <linux/errno.h>
21
#include <linux/signal.h>
22
#include <linux/binfmts.h>
23
#include <linux/string.h>
24
#include <linux/fcntl.h>
25
#include <linux/ptrace.h>
26
#include <linux/malloc.h>
27
#include <linux/shm.h>
28
#include <linux/personality.h>
29
#include <linux/elfcore.h>
30
 
31
#include <asm/segment.h>
32
#include <asm/pgtable.h>
33
 
34
#include <linux/config.h>
35
 
36
#define DLINFO_ITEMS 12
37
 
38
#include <linux/elf.h>
39
 
40 707 simons
#define JUMP_TO_MAIN 0
41
#define STACK_SIZE (2*PAGE_SIZE)
42 199 simons
 
43
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
44
 
45
#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
46
#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
47
 
48
static struct linux_binfmt elf_format =
49
{
50
#ifndef MODULE
51
        NULL, NULL, load_elf_binary, NULL, NULL
52
#else
53
  NULL, &mod_use_count_, load_elf_binary, load_elf_library, elf_core_dump
54
#endif
55
};
56
 
57
struct sec_add {
58
        unsigned long pm_add;
59
        unsigned long vm_add;
60
        int len;
61
} sec[ELF_SECTION_NB];
62
 
63
unsigned short *or32_consth_add = (unsigned short *)NULL;
64
unsigned long or32_consth_rel;
65
 
66 707 simons
#if JUMP_TO_MAIN
67 199 simons
unsigned long *create_elf_tables(char *p, int argc, int envc, struct pt_regs *regs)
68
{
69
        unsigned long *argv, *envp;
70
        unsigned long *sp;
71
 
72
        /*
73
         * Force 16 byte alignment here for generality.
74
         */
75
        sp = (unsigned long *) (~15UL & (unsigned long) p);
76
        sp -= 2;
77
        sp -= envc + 1;
78
        envp = sp;
79
        sp -= argc + 1;
80
        argv = sp;
81
 
82
        regs->gprs[1] = argc;
83
        put_user((unsigned long) argc, --sp);
84
        current->mm->arg_start = (unsigned long) p;
85
        regs->gprs[2] = (unsigned long) argv;
86
        while (argc-- > 0) {
87
                put_user(p, argv++);
88
                while (get_user(p++))   /* nothing */
89
                        ;
90
        }
91
        put_user(0, argv);
92
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
93
        regs->gprs[3] = (unsigned long) envp;
94
        while (envc-- > 0) {
95
                put_user(p, envp++);
96
                while (get_user(p++))   /* nothing */
97
                        ;
98
        }
99
        put_user(0, envp);
100
        current->mm->env_end = (unsigned long) p;
101
        return sp;
102
}
103 707 simons
#else
104
unsigned long *create_elf_tables(char *p, int argc, int envc, struct pt_regs *regs)
105
{
106
        unsigned long *argv, *envp;
107
        unsigned long *sp;
108 199 simons
 
109 707 simons
        /*
110
         * Force 16 byte alignment here for generality.
111
         */
112
        sp = (unsigned long *) (~15UL & (unsigned long) p);
113
        sp -= 2;
114
        sp -= envc + 1;
115
        envp = sp;
116
        sp -= argc + 1;
117
        argv = sp;
118
 
119
        regs->gprs[1] = sp;
120
        put_user((unsigned long) argc, --sp);
121
        current->mm->arg_start = (unsigned long) p;
122
        while (argc-- > 0) {
123
                put_user(p, argv++);
124
                while (get_user(p++))   /* nothing */
125
                        ;
126
        }
127
        put_user(0, argv);
128
        current->mm->arg_end = current->mm->env_start = (unsigned long) p;
129
        while (envc-- > 0) {
130
                put_user(p, envp++);
131
                while (get_user(p++))   /* nothing */
132
                        ;
133
        }
134
        put_user(0, envp);
135
        current->mm->env_end = (unsigned long) p;
136
        return sp;
137
}
138
#endif
139
 
140 199 simons
static unsigned long putstring(unsigned long p, char * string)
141
{
142
        unsigned long l = strlen(string)+1;
143
        p -= l;
144
        memcpy((void*)p, string, l);
145
        return p;
146
}
147
 
148
static unsigned long putstringarray(unsigned long p, int count, char ** array)
149
{
150
        while(count) {
151
                p=putstring(p, array[--count]);
152
        }
153
        return p;
154
}
155
 
156 701 simons
static unsigned long stringarraylen(int count, char ** array)
157
{
158
        int l = 4;
159
        while(count) {
160
                l += strlen(array[--count]);
161
                l++;
162
                l+=4;
163
        }
164
        return l;
165
}
166
 
167 199 simons
int do_relocate(int dst_indx,
168
                int rel_nb,
169
                struct elf32_rel *rel_ptr,
170
                struct elf32_sym *sym_ptr,
171
                struct sec_add *sec)
172
{
173
        struct elf32_sym *sym_tab;
174
        void *rel_loc;
175
        unsigned long tmp;
176
        int src_indx;
177
        int i;
178
 
179
        for(i = 0; i < rel_nb; i++, rel_ptr++) {
180 707 simons
 
181 199 simons
                /* Symbol tab */
182
                sym_tab = sym_ptr + (rel_ptr->r_info >> 8);
183
                /* Section index of section that contains symbol */
184
                src_indx = sym_tab->st_shndx;
185
                /* Location in physical memory to which this relocation
186
                   is refering to */
187
                rel_loc = (void *)(rel_ptr->r_offset + sec[dst_indx].pm_add);
188
                if((rel_ptr->r_info & 0x000000ff) == R_OR32_32) {
189
                        *(unsigned long *)rel_loc = *(unsigned long *)rel_loc
190
                                                - sec[src_indx].vm_add
191
                                                + sec[src_indx].pm_add;
192
                }
193
                else if((rel_ptr->r_info & 0x000000ff) == R_OR32_16) {
194
                        *(unsigned short *)rel_loc = *(unsigned short *)rel_loc
195
                                                - sec[src_indx].vm_add
196
                                                + sec[src_indx].pm_add;
197
                }
198
                else if((rel_ptr->r_info & 0x000000ff) == R_OR32_8) {
199
                        *(unsigned char *)rel_loc = *(unsigned char *)rel_loc
200
                                                - sec[src_indx].vm_add
201
                                                + sec[src_indx].pm_add;
202
                }
203
                else if((rel_ptr->r_info & 0x000000ff) == R_OR32_CONSTH) {
204
                        or32_consth_add = (((unsigned short *)rel_loc) + 1);
205
                        or32_consth_rel = *or32_consth_add << 16;
206
                }
207
                else if((rel_ptr->r_info & 0x000000ff) == R_OR32_CONST) {
208
                        tmp = or32_consth_rel | *(((unsigned short *)rel_loc) + 1);
209 707 simons
                        tmp = tmp /*+ sym_tab->st_value */ - sec[src_indx].vm_add +
210 199 simons
                                                sec[src_indx].pm_add;
211
                        *(((unsigned short *)rel_loc) + 1) = tmp & 0x0000ffff;
212
                        if(or32_consth_add != (unsigned short *)NULL) {
213
                                *or32_consth_add = tmp >> 16;
214
                                or32_consth_add = (unsigned short *)NULL;
215
                                or32_consth_rel = 0;
216
                        }
217
                }
218
                else if((rel_ptr->r_info & 0x000000ff) == R_OR32_JUMPTARG) {
219
                        tmp = ((*(unsigned long *)rel_loc) & 0x03ffffff);
220
                        tmp = (tmp & 0x02000000) ? (tmp | 0xfc000000) : tmp;
221
                        tmp = tmp + ((sym_tab->st_value -
222
                                sec[src_indx].vm_add +
223
                                sec[src_indx].pm_add -
224
                                sec[dst_indx].pm_add) >> 2);
225
                        *(unsigned long *)rel_loc =
226
                                ((*(unsigned long *)rel_loc) & 0xfc000000) |
227
                                (tmp & 0x03ffffff);
228
                }
229
                else {
230
                        return -ELNRNG;
231
                }
232
        }
233
        return 0;
234
}
235
 
236 707 simons
#if JUMP_TO_MAIN
237 199 simons
unsigned long do_find_main(int sym_nb, struct elf32_sym *sym_prt, char *str_ptr)
238
{
239
        int i;
240
 
241
        for(i = 0; i < sym_nb; i++, sym_prt++) {
242
                if(sym_prt->st_name == 0)
243
                        continue;
244
 
245
                if(strcmp(&str_ptr[sym_prt->st_name], "_main") == 0)
246
                        return (sym_prt->st_value + sec[sym_prt->st_shndx].pm_add);
247
        }
248
        return 0;
249
}
250 707 simons
#else
251
unsigned long do_find_start(int sym_nb, struct elf32_sym *sym_prt, char *str_ptr)
252
{
253
        int i;
254
 
255
        for(i = 0; i < sym_nb; i++, sym_prt++) {
256
                if(sym_prt->st_name == 0)
257
                        continue;
258
 
259
                if(strcmp(&str_ptr[sym_prt->st_name], "_start") == 0)
260
                        return (sym_prt->st_value + sec[sym_prt->st_shndx].pm_add);
261
        }
262
        return 0;
263
}
264
#endif
265 199 simons
/*
266
 * These are the functions used to load ELF style executables and shared
267
 * libraries.  There is no binary dependent code anywhere else.
268
 */
269
 
270
#define INTERPRETER_NONE 0
271
#define INTERPRETER_AOUT 1
272
#define INTERPRETER_ELF 2
273
 
274
 
275
static inline int do_load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
276
{
277
        struct elfhdr elf_ex;
278
        struct file *file;
279
        int i,j;
280
        int old_fs;
281
        struct elf32_shdr *elf_spnt, *elf_shdata;
282
        int elf_exec_fileno;
283
        unsigned long elf_entry = 0;
284 701 simons
        unsigned long code_start, code_end, code_len = 0;
285
        unsigned long data_start, data_end, data_len = 0;
286
        unsigned long bss_start, bss_end, bss_len = 0;
287
        unsigned long stack_len = 0;
288 625 simons
        int rel_indx, symtab_indx = 0, strtab_indx = 0;
289 199 simons
        struct elf32_rel *rel_ptr;
290 625 simons
        struct elf32_sym *sym_ptr = (struct elf32_sym *)0;
291
        char *str_ptr = (char *)0;
292 199 simons
        int retval;
293
 
294
        or32_consth_add = 0;
295
        or32_consth_rel = 0;
296 701 simons
 
297
        current->personality = PER_LINUX;
298
 
299
        elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
300
 
301
        if (elf_exec_fileno < 0)
302
                return elf_exec_fileno;
303
 
304
        file = current->files->fd[elf_exec_fileno];
305
 
306
 
307 199 simons
        elf_ex = *((struct elfhdr *) bprm->buf);        /* exec-header */
308
 
309
        /* First of all, some simple consistency checks */
310
        if (elf_ex.e_type != ET_REL ||
311 701 simons
 
312
                        !bprm->inode->i_op ||
313
                        !bprm->inode->i_op->default_file_ops ||
314
                        !bprm->inode->i_op->default_file_ops->mmap ||
315
                        elf_ex.e_ident[0] != 0x7f ||
316
                        strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0) {
317 199 simons
                return -ENOEXEC;
318
        }
319
 
320 701 simons
        if (flush_old_exec(bprm)) {
321
                return -ENOMEM;
322
        }
323
 
324 199 simons
        if(elf_ex.e_shnum > ELF_SECTION_NB)
325
                return -ETOOMANYSECT;
326
 
327
        for(i = 0; i < ELF_SECTION_NB; i++)
328
                sec[i].len = 0;
329
 
330
        /* Now read in all of the header information */
331 701 simons
        elf_shdata = (struct elf32_shdr *) kmalloc(elf_ex.e_shnum *
332
                        elf_ex.e_shentsize, GFP_KERNEL);
333 199 simons
 
334 701 simons
        if (elf_shdata == NULL)
335 199 simons
                return -ENOMEM;
336 701 simons
 
337 199 simons
        retval = read_exec(bprm->inode, elf_ex.e_shoff, (char *) elf_shdata,
338
                           elf_ex.e_shentsize * elf_ex.e_shnum, 1);
339 701 simons
 
340 199 simons
        if (retval < 0) {
341
                kfree(elf_shdata);
342
                return retval;
343
        }
344
 
345
        /* OK, This is the point of no return */
346
 
347
        current->mm->end_data = 0;
348
        current->mm->end_code = 0;
349
 
350
        /* Now we do a little grungy work by mmaping the ELF image into
351
           the memory.  At this point, we assume that at a variable
352
           address. */
353
 
354
        old_fs = get_fs();
355
        set_fs(get_ds());
356
 
357 701 simons
        /* Calculate the total size of memory needed */
358 199 simons
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; i++, elf_spnt++) {
359 701 simons
                if(elf_spnt->sh_type == SHT_PROGBITS) {
360
                        if(elf_spnt->sh_flags & SHF_EXECINSTR)
361
                                code_len += (elf_spnt->sh_size + 3) & ~(3);
362
                        else if(elf_spnt->sh_flags & SHF_ALLOC)
363
                                data_len += (elf_spnt->sh_size + 3) & ~(3);
364
                }
365
                else if(elf_spnt->sh_type == SHT_NOBITS) {
366
                        if(elf_spnt->sh_flags & SHF_ALLOC)
367
                                bss_len += (elf_spnt->sh_size + 3) & ~(3);
368
                }
369
        }
370 199 simons
 
371 707 simons
        /* Make room on stack for arguments & environment */
372
        stack_len = STACK_SIZE;
373
        stack_len += strlen(bprm->filename) + 1;
374
        stack_len += stringarraylen(bprm->envc, bprm->envp);
375
        stack_len += stringarraylen(bprm->argc, bprm->argv);
376
 
377 701 simons
        /* Allocate space */
378
        retval = (unsigned long)do_mmap(NULL,
379
                                        0,
380
                                        code_len + code_len + bss_len + stack_len,
381
                                        PROT_EXEC | PROT_WRITE | PROT_READ,
382
                                        0,
383
                                        0);
384 199 simons
 
385 701 simons
        if(retval > (unsigned long)-4096) {
386
                kfree(elf_shdata);
387
                return retval;
388
        }
389 199 simons
 
390 701 simons
        code_start = retval;
391
        code_end = code_start;
392
        data_start = code_start + code_len;
393
        data_end = data_start;
394
        bss_start = data_start + data_len;
395
        bss_end = bss_start;
396
 
397
        current->mm->executable = 0;
398
 
399
        /* Now copy sections in memory */
400
 
401
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; i++, elf_spnt++) {
402
 
403
                if(elf_spnt->sh_type == SHT_PROGBITS && elf_spnt->sh_flags & SHF_EXECINSTR) {
404
 
405 707 simons
                        if(elf_spnt->sh_size == 0)
406
                                continue;
407
 
408 701 simons
                        retval = read_exec(bprm->inode, elf_spnt->sh_offset,
409
                                        (char *)code_end, elf_spnt->sh_size, 1);
410
 
411
                        if (retval < 0) {
412
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
413 199 simons
                                kfree(elf_shdata);
414 701 simons
                                return retval;
415 199 simons
                        }
416 701 simons
 
417
                        sec[i].pm_add = code_end;
418
                        sec[i].vm_add = elf_spnt->sh_addr;
419 199 simons
 
420 701 simons
                        code_end = code_end + ((elf_spnt->sh_size + 3) & ~(3));
421
                }
422
                else if (elf_spnt->sh_type == SHT_PROGBITS && elf_spnt->sh_flags & SHF_ALLOC) {
423
 
424 707 simons
                        if(elf_spnt->sh_size == 0)
425
                                continue;
426
 
427 701 simons
                        retval = read_exec(bprm->inode, elf_spnt->sh_offset,
428
                                        (char *)data_end, elf_spnt->sh_size, 1);
429
 
430
                        if (retval < 0) {
431
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
432
                                kfree(elf_shdata);
433
                                return retval;
434
                        }
435
 
436
                        sec[i].pm_add = data_end;
437 199 simons
                        sec[i].vm_add = elf_spnt->sh_addr;
438
 
439 701 simons
                        data_end = data_end + ((elf_spnt->sh_size + 3) & ~(3));
440 199 simons
                }
441 701 simons
                else if (elf_spnt->sh_type == SHT_NOBITS && elf_spnt->sh_flags & SHF_ALLOC) {
442
 
443 707 simons
                        if(elf_spnt->sh_size == 0)
444
                                continue;
445
 
446 701 simons
                        sec[i].pm_add = bss_end;
447
                        sec[i].vm_add = elf_spnt->sh_addr;
448
 
449
                        bss_end = bss_end + ((elf_spnt->sh_size + 3) & ~(3));
450
                }
451 199 simons
        }
452
 
453 701 simons
        /* Set bss and stack to zero */
454
        memset((void*)(bss_start), 0, bss_len + stack_len);
455
 
456 199 simons
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; elf_spnt++, i++) {
457
                if(elf_spnt->sh_type == SHT_SYMTAB && (elf_spnt->sh_size != 0)) {
458
                        struct elf32_shdr *link_shdr;
459
                        int sym_nb;
460
                        unsigned long retval;
461
 
462
                        /* Map symtab section */
463
                        retval = (unsigned long)do_mmap(NULL,
464
                                                        0,
465
                                                        elf_spnt->sh_size,
466
                                                        PROT_READ,
467
                                                        0,
468
                                                        0);
469
                        if(retval > (unsigned long)-4096) {
470
                                for(j = 0; j < elf_ex.e_shnum; j++)
471
                                                if(sec[j].len)
472
                                                        do_munmap(sec[j].pm_add, sec[j].len);
473 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
474 199 simons
                                kfree(elf_shdata);
475
                                return retval;
476
                        }
477
 
478 625 simons
                        symtab_indx = i;
479 199 simons
                        sec[symtab_indx].pm_add = retval;
480
                        sym_ptr = (struct elf32_sym *)retval;
481
                        sec[symtab_indx].len = elf_spnt->sh_size;
482
 
483
                        retval = read_exec(bprm->inode, elf_spnt->sh_offset,
484
                                        (char *)retval, elf_spnt->sh_size, 1);
485
                        if (retval < 0) {
486
                                for(j = 0; j < elf_ex.e_shnum; j++)
487
                                        if(sec[j].len)
488
                                                do_munmap(sec[j].pm_add, sec[j].len);
489 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
490 199 simons
                                kfree(elf_shdata);
491
                                return retval;
492
                        }
493
 
494
                        strtab_indx = elf_spnt->sh_link;
495
                        link_shdr = elf_shdata + strtab_indx;
496
 
497
                        /* Map strtab section */
498
                        retval = (unsigned long)do_mmap(NULL,
499
                                                        0,
500
                                                        link_shdr->sh_size,
501
                                                        PROT_READ,
502
                                                        0,
503
                                                        0);
504
                        if(retval > (unsigned long)-4096) {
505
                                for(j = 0; j < elf_ex.e_shnum; j++)
506
                                        if(sec[j].len)
507
                                                do_munmap(sec[j].pm_add, sec[j].len);
508 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
509
                                kfree(elf_shdata);
510
                                return retval;
511 199 simons
                        }
512
 
513
                        sec[strtab_indx].pm_add = retval;
514
                        str_ptr = (char *)retval;
515
                        sec[strtab_indx].len = link_shdr->sh_size;
516
 
517
                        retval = read_exec(bprm->inode, link_shdr->sh_offset,
518
                                        (char *)retval, link_shdr->sh_size, 1);
519
                        if (retval < 0) {
520
                                for(j = 0; j < elf_ex.e_shnum; j++)
521
                                        if(sec[j].len)
522
                                                do_munmap(sec[j].pm_add, sec[j].len);
523 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
524 199 simons
                                kfree(elf_shdata);
525
                                return retval;
526
                        }
527
 
528
                        sym_nb = sec[symtab_indx].len / sizeof(struct elf32_sym);
529 707 simons
#if JUMP_TO_MAIN
530 199 simons
                        elf_entry = do_find_main(sym_nb, sym_ptr, str_ptr);
531 707 simons
#else
532
                        elf_entry = do_find_start(sym_nb, sym_ptr, str_ptr);
533
#endif
534 199 simons
                        break;
535
                }
536
        }
537
 
538
        for(i = 0, elf_spnt = elf_shdata; i < elf_ex.e_shnum; elf_spnt++, i++) {
539
                if(elf_spnt->sh_type == SHT_REL && (elf_spnt->sh_size != 0)) {
540
                        struct elf32_shdr *link_shdr;
541
                        int rel_nb;
542
                        unsigned long retval;
543
 
544
                        /* Map rel section */
545
                        retval = (unsigned long)do_mmap(NULL,
546
                                                        0,
547
                                                        elf_spnt->sh_size,
548
                                                        PROT_READ,
549
                                                        0,
550
                                                        0);
551
                        if(retval > (unsigned long)-4096) {
552
                                for(j = 0; j < elf_ex.e_shnum; j++)
553
                                        if(sec[j].len)
554
                                                do_munmap(sec[j].pm_add, sec[j].len);
555 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
556
                                kfree(elf_shdata);
557
                                return retval;
558 199 simons
                        }
559
 
560
                        sec[i].pm_add = retval;
561
                        rel_ptr = (struct elf32_rel *)retval;
562
                        sec[i].len = elf_spnt->sh_size;
563
 
564
                        retval = read_exec(bprm->inode, elf_spnt->sh_offset,
565
                                        (char *)retval, elf_spnt->sh_size, 1);
566
                        if (retval < 0) {
567
                                for(j = 0; j < elf_ex.e_shnum; j++)
568
                                        if(sec[j].len)
569
                                                do_munmap(sec[j].pm_add, sec[j].len);
570 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
571 199 simons
                                kfree(elf_shdata);
572
                                return retval;
573
                        }
574
 
575
                        rel_indx = i;
576
                        link_shdr = elf_shdata + symtab_indx;
577
 
578
                        /* Now do relocations for the n-th section. n is read from
579
                           real setiona hader info field. */
580
 
581
                        rel_nb = sec[rel_indx].len / sizeof(struct elf32_rel);
582 625 simons
                        retval = do_relocate(elf_spnt->sh_info, rel_nb, rel_ptr, sym_ptr,  sec);
583 199 simons
 
584
                        if (retval < 0) {
585
                                for(j = 0; j < elf_ex.e_shnum; j++)
586
                                        if(sec[j].len)
587
                                                do_munmap(sec[j].pm_add, sec[j].len);
588 701 simons
                                do_munmap(code_start, code_len + code_len + bss_len + stack_len);
589 199 simons
                                kfree(elf_shdata);
590
                                return retval;
591
                        }
592
 
593
                        /* Now unmap rel section */
594
                        do_munmap(sec[rel_indx].pm_add, sec[rel_indx].len);
595
                        sec[rel_indx].len = 0;
596
                }
597
        }
598
 
599
        /* Now unmap sym and str sections */
600
        do_munmap(sec[symtab_indx].pm_add, sec[symtab_indx].len);
601
        sec[symtab_indx].len = 0;
602
        do_munmap(sec[strtab_indx].pm_add, sec[strtab_indx].len);
603
        sec[strtab_indx].len = 0;
604
 
605
        set_fs(old_fs);
606
        kfree(elf_shdata);
607
 
608
        if (current->exec_domain && current->exec_domain->use_count)
609
                (*current->exec_domain->use_count)--;
610
        if (current->binfmt && current->binfmt->use_count)
611
                (*current->binfmt->use_count)--;
612
        current->exec_domain = lookup_exec_domain(current->personality);
613
        current->binfmt = &elf_format;
614
        if (current->exec_domain && current->exec_domain->use_count)
615
                (*current->exec_domain->use_count)++;
616
        if (current->binfmt && current->binfmt->use_count)
617
                (*current->binfmt->use_count)++;
618
 
619 701 simons
        bprm->p = bss_end + stack_len - 4;
620 199 simons
 
621
        bprm->p = putstringarray(bprm->p, 1, &bprm->filename);
622
 
623
        bprm->p = putstringarray(bprm->p, bprm->envc, bprm->envp);
624
 
625
        bprm->p = putstringarray(bprm->p, bprm->argc, bprm->argv);
626
 
627
        current->suid = current->euid = current->fsuid = bprm->e_uid;
628
        current->sgid = current->egid = current->fsgid = bprm->e_gid;
629
        current->flags &= ~PF_FORKNOEXEC;
630
        bprm->p = (unsigned long)create_elf_tables((char *) bprm->p, bprm->argc, bprm->envc, regs);
631
 
632 701 simons
        current->mm->brk = bss_end;
633
        current->mm->start_code  = code_start;
634
        current->mm->end_code = code_end;
635
        current->mm->start_data  = data_start;
636
        current->mm->end_data = data_end;
637 199 simons
        current->mm->start_stack = bprm->p;
638
 
639 701 simons
_print("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__);
640
_print("   start_code = %x\n", current->mm->start_code);
641
_print("   end_code = %x\n", current->mm->end_code);
642
_print("   start_data = %x\n", current->mm->start_data);
643
_print("   end_data = %x\n", current->mm->end_data);
644
_print("   start_brk = %x\n", current->mm->start_brk);
645
_print("   brk = %x\n", current->mm->brk);
646
_print("   start_stack = %x\n", current->mm->start_stack);
647
_print("   arg_start = %x\n", current->mm->arg_start);
648
_print("   env_start = %x\n", current->mm->env_start);
649
_print("   env_end = %x\n", current->mm->env_end);
650
_print("   elf_entry = %x\n", elf_entry);
651 199 simons
 
652
        start_thread(regs, elf_entry, bprm->p);
653
 
654
        if (current->flags & PF_PTRACED)
655
                send_sig(SIGTRAP, current, 0);
656
 
657
        return 0;
658
}
659
 
660
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
661
{
662
        int retval;
663
 
664
        MOD_INC_USE_COUNT;
665
        retval = do_load_elf_binary(bprm, regs);
666
        MOD_DEC_USE_COUNT;
667
        return retval;
668
}
669
 
670
int init_elf_binfmt(void)
671
{
672
        return register_binfmt(&elf_format);
673
}
674
 
675
#ifdef MODULE
676
 
677
int init_module(void)
678
{
679
        /* Install the COFF, ELF and XOUT loaders.
680
         * N.B. We *rely* on the table being the right size with the
681
         * right number of free slots...
682
         */
683
        return init_elf_binfmt();
684
}
685
 
686
 
687
void cleanup_module(void)
688
{
689
        /* Remove the COFF and ELF loaders. */
690
        unregister_binfmt(&elf_format);
691
}
692
 
693
#endif

powered by: WebSVN 2.1.0

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