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

Subversion Repositories or1k_old

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

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

powered by: WebSVN 2.1.0

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