Fork me on GitHub

root/fs/elf.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_elf
  2. elf_create_stack
  3. elf_load_interpreter
  4. elf_load

   1 /*
   2  * fiwix/fs/elf.c
   3  *
   4  * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/kernel.h>
   9 #include <fiwix/asm.h>
  10 #include <fiwix/types.h>
  11 #include <fiwix/buffer.h>
  12 #include <fiwix/fs.h>
  13 #include <fiwix/i386elf.h>
  14 #include <fiwix/mm.h>
  15 #include <fiwix/mman.h>
  16 #include <fiwix/fs.h>
  17 #include <fiwix/fcntl.h>
  18 #include <fiwix/process.h>
  19 #include <fiwix/errno.h>
  20 #include <fiwix/stdio.h>
  21 #include <fiwix/string.h>
  22 
  23 #define AT_ITEMS        12      /* ELF Auxiliary Vectors */
  24 
  25 static int check_elf(struct elf32_hdr *elf32_h)
  26 {
  27         if(elf32_h->e_ident[EI_MAG0] != ELFMAG0 ||
  28                 elf32_h->e_ident[EI_MAG1] != ELFMAG1 ||
  29                 elf32_h->e_ident[EI_MAG2] != ELFMAG2 ||
  30                 elf32_h->e_ident[EI_MAG3] != ELFMAG3 ||
  31                 (elf32_h->e_type != ET_EXEC && elf32_h->e_type != ET_DYN) ||
  32                 elf32_h->e_machine != EM_386) {
  33                 return -EINVAL;
  34         }
  35         return 0;
  36 }
  37 
  38 /*
  39  * Setup the initial process stack (System V ABI for i386)
  40  * ----------------------------------------------------------------------------
  41  * 0xBFFFFFFF
  42  *      +---------------+       \
  43  *      | envp[] str    |       |
  44  *      +---------------+       |
  45  *      | argv[] str    |       |
  46  *      +---------------+       |
  47  *      | NULL          |       |
  48  *      +---------------+       |
  49  *      | ELF Aux.Vect. |       |
  50  *      +---------------+       |
  51  *      | NULL          |       | elf_create_stack() setups this section
  52  *      +---------------+       |
  53  *      | envp[] ptr    |       |
  54  *      +---------------+       |
  55  *      | NULL          |       |
  56  *      +---------------+       |
  57  *      | argv[] ptr    |       |
  58  *      +---------------+       |
  59  *      | argc          |       |
  60  *      +---------------+       /
  61  *      | stack pointer | grows toward lower addresses
  62  *      +---------------+ ||
  63  *      |...............| \/
  64  *      |...............|
  65  *      |...............|
  66  *      |...............| /\
  67  *      +---------------+ ||
  68  *      |  brk (heap)   | grows toward higher addresses
  69  *      +---------------+
  70  *      | .bss section  |
  71  *      +---------------+
  72  *      | .data section |
  73  *      +---------------+
  74  *      | .text section |
  75  *      +---------------+
  76  * 0x08048000
  77  */
  78 static void elf_create_stack(struct binargs *barg, unsigned int *sp, unsigned int str_ptr, int at_base, struct elf32_hdr *elf32_h, unsigned int phdr_addr)
  79 {
  80         unsigned int n, addr;
  81         char *str;
  82 
  83         /* copy strings */
  84         for(n = 0; n < ARG_MAX; n++) {
  85                 if(barg->page[n]) {
  86                         addr = KERNEL_BASE_ADDR - ((ARG_MAX - n) * PAGE_SIZE);
  87                         memcpy_b((void *)addr, (void *)barg->page[n], PAGE_SIZE);
  88                 }
  89         }
  90 
  91 #ifdef __DEBUG__
  92         printk("sp = 0x%08x\n", sp);
  93 #endif /*__DEBUG__ */
  94 
  95         /* copy the value of 'argc' into the stack */
  96         current->argc = barg->argc;
  97         *sp = barg->argc;
  98 #ifdef __DEBUG__
  99         printk("at 0x%08x -> argc\n", sp);
 100 #endif /*__DEBUG__ */
 101         sp++;
 102 
 103         /* copy as many pointers to strings as 'argc' */
 104         current->argv = (char **)sp;
 105         for(n = 0; n < barg->argc; n++) {
 106                 *sp = str_ptr;
 107                 str = (char *)str_ptr;
 108 #ifdef __DEBUG__
 109                 printk("at 0x%08x -> str_ptr(%d) = 0x%08x (+ %d)\n", sp, n, str_ptr, strlen(str) + 1);
 110 #endif /*__DEBUG__ */
 111                 sp++;
 112                 str_ptr += strlen(str) + 1;
 113         }
 114 
 115         /* the last element of 'argv[]' must be a NULL-pointer */
 116         *sp = NULL;
 117 #ifdef __DEBUG__
 118         printk("at 0x%08x -> -------------- = 0x%08x\n", sp, 0);
 119 #endif /*__DEBUG__ */
 120         sp++;
 121 
 122         /* copy as many pointers to strings as 'envc' */
 123         current->envc = barg->envc;
 124         current->envp = (char **)sp;
 125         for(n = 0; n < barg->envc; n++) {
 126                 *sp = str_ptr;
 127                 str = (char *)str_ptr;
 128 #ifdef __DEBUG__
 129                 printk("at 0x%08x -> str_ptr(%d) = 0x%08x (+ %d)\n", sp, n, str_ptr, strlen(str) + 1);
 130 #endif /*__DEBUG__ */
 131                 sp++;
 132                 str_ptr += strlen(str) + 1;
 133         }
 134 
 135         /* the last element of 'envp[]' must be a NULL-pointer */
 136         *sp = NULL;
 137 #ifdef __DEBUG__
 138         printk("at 0x%08x -> -------------- = 0x%08x\n", sp, 0);
 139 #endif /*__DEBUG__ */
 140         sp++;
 141 
 142 
 143         /* copy the Auxiliar Table Items (dlinfo_items) */
 144         if(at_base) {
 145                 memset_l((void *)sp, AT_PHDR, 1);
 146 #ifdef __DEBUG__
 147                 printk("at 0x%08x -> AT_PHDR = %d", sp, *sp);
 148 #endif /*__DEBUG__ */
 149                 sp++;
 150 
 151                 memcpy_l((void *)sp, &phdr_addr, 1);
 152 #ifdef __DEBUG__
 153                 printk("\t\tAT_PHDR = 0x%08x\n", *sp);
 154 #endif /*__DEBUG__ */
 155                 sp++;
 156 
 157                 memset_l((void *)sp, AT_PHENT, 1);
 158 #ifdef __DEBUG__
 159                 printk("at 0x%08x -> AT_PHENT = %d", sp, *sp);
 160 #endif /*__DEBUG__ */
 161                 sp++;
 162 
 163                 memset_l((void *)sp, sizeof(struct elf32_phdr), 1);
 164 #ifdef __DEBUG__
 165                 printk("\t\tAT_PHENT = %d\n", *sp);
 166 #endif /*__DEBUG__ */
 167                 sp++;
 168 
 169                 memset_l((void *)sp, AT_PHNUM, 1);
 170 #ifdef __DEBUG__
 171                 printk("at 0x%08x -> AT_PHNUM = %d", sp, *sp);
 172 #endif /*__DEBUG__ */
 173                 sp++;
 174 
 175                 memset_l((void *)sp, 0, 1);
 176                 memcpy_w((void *)sp, &elf32_h->e_phnum, 1);
 177 #ifdef __DEBUG__
 178                 printk("\t\tAT_PHNUM = %d\n", *sp);
 179 #endif /*__DEBUG__ */
 180                 sp++;
 181 
 182                 memset_l((void *)sp, AT_PAGESZ, 1);
 183 #ifdef __DEBUG__
 184                 printk("at 0x%08x -> AT_PGSIZE = %d", sp, *sp);
 185 #endif /*__DEBUG__ */
 186                 sp++;
 187 
 188                 memset_l((void *)sp, PAGE_SIZE, 1);
 189 #ifdef __DEBUG__
 190                 printk("\t\tAT_PGSIZE = %d\n", *sp);
 191 #endif /*__DEBUG__ */
 192                 sp++;
 193 
 194                 memset_l((void *)sp, AT_BASE, 1);
 195 #ifdef __DEBUG__
 196                 printk("at 0x%08x -> AT_BASE = %d", sp, *sp);
 197 #endif /*__DEBUG__ */
 198                 sp++;
 199 
 200                 memset_l((void *)sp, at_base, 1);
 201 #ifdef __DEBUG__
 202                 printk("\t\tAT_BASE = 0x%08x\n", sp);
 203 #endif /*__DEBUG__ */
 204                 sp++;
 205 
 206                 memset_l((void *)sp, AT_FLAGS, 1);
 207 #ifdef __DEBUG__
 208                 printk("at 0x%08x -> AT_FLAGS = %d", sp, *sp);
 209 #endif /*__DEBUG__ */
 210                 sp++;
 211 
 212                 memset_l((void *)sp, NULL, 1);
 213 #ifdef __DEBUG__
 214                 printk("\t\tAT_FLAGS = %d\n", *sp);
 215 #endif /*__DEBUG__ */
 216                 sp++;
 217 
 218                 memset_l((void *)sp, AT_ENTRY, 1);
 219 #ifdef __DEBUG__
 220                 printk("at 0x%08x -> AT_ENTRY = %d ", sp, *sp);
 221 #endif /*__DEBUG__ */
 222                 sp++;
 223 
 224                 memcpy_l((void *)sp, &elf32_h->e_entry, 1);
 225 #ifdef __DEBUG__
 226                 printk("\t\tAT_ENTRY = 0x%08x\n", *sp);
 227 #endif /*__DEBUG__ */
 228                 sp++;
 229 
 230                 memset_l((void *)sp, AT_UID, 1);
 231 #ifdef __DEBUG__
 232                 printk("at 0x%08x -> AT_UID = %d", sp, *sp);
 233 #endif /*__DEBUG__ */
 234                 sp++;
 235 
 236                 memcpy_l((void *)sp, &current->uid, 1);
 237 #ifdef __DEBUG__
 238                 printk("\t\tAT_UID = %d\n", *sp);
 239 #endif /*__DEBUG__ */
 240                 sp++;
 241 
 242                 memset_l((void *)sp, AT_EUID, 1);
 243 #ifdef __DEBUG__
 244                 printk("at 0x%08x -> AT_EUID = %d", sp, *sp);
 245 #endif /*__DEBUG__ */
 246                 sp++;
 247 
 248                 memcpy_l((void *)sp, &current->euid, 1);
 249 #ifdef __DEBUG__
 250                 printk("\t\tAT_EUID = %d\n", *sp);
 251 #endif /*__DEBUG__ */
 252                 sp++;
 253 
 254                 memset_l((void *)sp, AT_GID, 1);
 255 #ifdef __DEBUG__
 256                 printk("at 0x%08x -> AT_GID = %d", sp, *sp);
 257 #endif /*__DEBUG__ */
 258                 sp++;
 259 
 260                 memcpy_l((void *)sp, &current->gid, 1);
 261 #ifdef __DEBUG__
 262                 printk("\t\tAT_GID = %d\n", *sp);
 263 #endif /*__DEBUG__ */
 264                 sp++;
 265 
 266                 memset_l((void *)sp, AT_EGID, 1);
 267 #ifdef __DEBUG__
 268                 printk("at 0x%08x -> AT_EGID = %d", sp, *sp);
 269 #endif /*__DEBUG__ */
 270                 sp++;
 271 
 272                 memcpy_l((void *)sp, &current->egid, 1);
 273 #ifdef __DEBUG__
 274                 printk("\t\tAT_EGID = %d\n", *sp);
 275 #endif /*__DEBUG__ */
 276                 sp++;
 277         }
 278 
 279         memset_l((void *)sp, AT_NULL, 1);
 280 #ifdef __DEBUG__
 281         printk("at 0x%08x -> AT_NULL = %d", sp, *sp);
 282 #endif /*__DEBUG__ */
 283         sp++;
 284 
 285         *sp = NULL;
 286 #ifdef __DEBUG__
 287         printk("\t\tAT_NULL = %d\n", *sp);
 288 #endif /*__DEBUG__ */
 289 
 290 #ifdef __DEBUG__
 291         for(n = 0; n < barg->argc; n++) {
 292                 printk("at 0x%08x -> argv[%d] = '%s'\n", current->argv[n], n, current->argv[n]);
 293         }
 294         for(n = 0; n < barg->envc; n++) {
 295                 printk("at 0x%08x -> envp[%d] = '%s'\n", current->envp[n], n, current->envp[n]);
 296         }
 297 #endif /*__DEBUG__ */
 298 }
 299 
 300 static int elf_load_interpreter(struct inode *ii)
 301 {
 302         int n, errno;
 303         struct buffer *buf;
 304         struct elf32_hdr *elf32_h;
 305         struct elf32_phdr *elf32_ph, *last_ptload;
 306         __blk_t block;
 307         unsigned int start, end, length;
 308         unsigned int prot;
 309         char *data;
 310         char type;
 311 
 312         if((block = bmap(ii, 0, FOR_READING)) < 0) {
 313                 return block;
 314         }
 315         if(!(buf = bread(ii->dev, block, ii->sb->s_blocksize))) {
 316                 return -EIO;
 317         }
 318 
 319         /*
 320          * The contents of the buffer is copied and then freed immediately to
 321          * make sure that it won't conflict while zeroing the BSS fractional
 322          * page, in case that the same block is requested during the page fault.
 323          */
 324         if(!(data = (void *)kmalloc())) {
 325                 brelse(buf);
 326                 return -ENOMEM;
 327         }
 328         memcpy_b(data, buf->data, ii->sb->s_blocksize);
 329         brelse(buf);
 330 
 331         elf32_h = (struct elf32_hdr *)data;
 332         if(check_elf(elf32_h)) {
 333                 kfree((unsigned int)data);
 334                 return -ELIBBAD;
 335         }
 336 
 337         last_ptload = NULL;
 338         for(n = 0; n < elf32_h->e_phnum; n++) {
 339                 elf32_ph = (struct elf32_phdr *)(data + elf32_h->e_phoff + (sizeof(struct elf32_phdr) * n));
 340                 if(elf32_ph->p_type == PT_LOAD) {
 341 #ifdef __DEBUG__
 342                         printk("p_offset = 0x%08x\n", elf32_ph->p_offset);
 343                         printk("p_vaddr  = 0x%08x\n", elf32_ph->p_vaddr);
 344                         printk("p_paddr  = 0x%08x\n", elf32_ph->p_paddr);
 345                         printk("p_filesz = 0x%08x\n", elf32_ph->p_filesz);
 346                         printk("p_memsz  = 0x%08x\n\n", elf32_ph->p_memsz);
 347 #endif /*__DEBUG__ */
 348                         start = (elf32_ph->p_vaddr & PAGE_MASK) + MMAP_START;
 349                         length = (elf32_ph->p_vaddr & ~PAGE_MASK) + elf32_ph->p_filesz;
 350                         type = P_DATA;
 351                         prot = 0;
 352                         if(elf32_ph->p_flags & PF_R) {
 353                                 prot = PROT_READ;
 354                         }
 355                         if(elf32_ph->p_flags & PF_W) {
 356                                 prot |= PROT_WRITE;
 357                         }
 358                         if(elf32_ph->p_flags & PF_X) {
 359                                 prot |= PROT_EXEC;
 360                                 type = P_TEXT;
 361                         }
 362                         errno = do_mmap(ii, start, length, prot, MAP_PRIVATE | MAP_FIXED, elf32_ph->p_offset & PAGE_MASK, type, O_RDONLY);
 363                         if(errno < 0 && errno > -PAGE_SIZE) {
 364                                 kfree((unsigned int)data);
 365                                 send_sig(current, SIGSEGV);
 366                                 return -ENOEXEC;
 367                         }
 368                         last_ptload = elf32_ph;
 369                 }
 370         }
 371 
 372         if(!last_ptload) {
 373                 printk("WARNING: 'last_ptload' is NULL!\n");
 374         }
 375         elf32_ph = last_ptload;
 376 
 377         /* zero-fill the fractional page of the DATA section */
 378         end = PAGE_ALIGN(elf32_ph->p_vaddr + elf32_ph->p_filesz) + MMAP_START;
 379         start = (elf32_ph->p_vaddr + elf32_ph->p_filesz) + MMAP_START;
 380         length = end - start;
 381 
 382         /* this will generate a page fault which will load the page in */
 383         memset_b((void *)start, NULL, length);
 384 
 385         /* setup the BSS section */
 386         start = (elf32_ph->p_vaddr + elf32_ph->p_filesz) + MMAP_START;
 387         start = PAGE_ALIGN(start);
 388         end = (elf32_ph->p_vaddr + elf32_ph->p_memsz) + MMAP_START;
 389         end = PAGE_ALIGN(end);
 390         length = end - start;
 391         errno = do_mmap(NULL, start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, 0, P_BSS, 0);
 392         if(errno < 0 && errno > -PAGE_SIZE) {
 393                 kfree((unsigned int)data);
 394                 send_sig(current, SIGSEGV);
 395                 return -ENOEXEC;
 396         }
 397         kfree((unsigned int)data);
 398         return elf32_h->e_entry + MMAP_START;
 399 }
 400 
 401 int elf_load(struct inode *i, struct binargs *barg, struct sigcontext *sc, char *data)
 402 {
 403         int n, errno;
 404         struct elf32_hdr *elf32_h;
 405         struct elf32_phdr *elf32_ph, *last_ptload;
 406         struct inode *ii;
 407         unsigned int start, end, length;
 408         unsigned int prot;
 409         char *interpreter;
 410         int at_base, phdr_addr;
 411         char type;
 412         unsigned int ae_ptr_len, ae_str_len;
 413         unsigned int sp, str;
 414 
 415         elf32_h = (struct elf32_hdr *)data;
 416         if(check_elf(elf32_h)) {
 417                 if(current->pid == INIT) {
 418                         PANIC("%s has an unrecognized binary format.\n", INIT_PROGRAM);
 419                 }
 420                 return -ENOEXEC;
 421         }
 422 
 423         if(elf32_h->e_phnum < 1) {
 424                 printk("%s(): no program headers.");
 425                 return -ENOEXEC;
 426         }
 427 
 428         /* check if an interpreter is required */
 429         interpreter = NULL;
 430         ii = NULL;
 431         phdr_addr = at_base = 0;
 432         for(n = 0; n < elf32_h->e_phnum; n++) {
 433                 elf32_ph = (struct elf32_phdr *)(data + elf32_h->e_phoff + (sizeof(struct elf32_phdr) * n));
 434                 if(elf32_ph->p_type == PT_INTERP) {
 435                         at_base = MMAP_START;
 436                         interpreter = data + elf32_ph->p_offset;
 437                         if(namei(interpreter, &ii, NULL, FOLLOW_LINKS)) {
 438                                 printk("%s(): can't find interpreter '%s'.\n", __FUNCTION__, interpreter);
 439                                 send_sig(current, SIGSEGV);
 440                                 return -ELIBACC;
 441                         }
 442 #ifdef __DEBUG__
 443                         printk("p_offset = 0x%08x\n", elf32_ph->p_offset);
 444                         printk("p_vaddr  = 0x%08x\n", elf32_ph->p_vaddr);
 445                         printk("p_paddr  = 0x%08x\n", elf32_ph->p_paddr);
 446                         printk("p_filesz = 0x%08x\n", elf32_ph->p_filesz);
 447                         printk("p_memsz  = 0x%08x\n", elf32_ph->p_memsz);
 448                         printk("using interpreter '%s'\n", interpreter);
 449 #endif /*__DEBUG__ */
 450                 }
 451         }
 452 
 453         /*
 454          * calculate the final size of 'ae_ptr_len' based on:
 455          *  - argc = 4 bytes (unsigned int)
 456          *  - barg.argc = (num. of pointers to strings + 1 NULL) x 4 bytes (unsigned int)
 457          *  - barg.envc = (num. of pointers to strings + 1 NULL) x 4 bytes (unsigned int)
 458          */
 459         ae_ptr_len = (1 + (barg->argc + 1) + (barg->envc + 1)) * sizeof(unsigned int);
 460         ae_str_len = barg->argv_len + barg->envp_len;
 461         if(ae_ptr_len + ae_str_len > (ARG_MAX * PAGE_SIZE)) {
 462                 printk("WARNING: %s(): argument list (%d) exceeds ARG_MAX (%d)!\n", __FUNCTION__, ae_ptr_len + ae_str_len, ARG_MAX * PAGE_SIZE);
 463                 return -E2BIG;
 464         }
 465 
 466 #ifdef __DEBUG__
 467         printk("argc=%d (argv_len=%d) envc=%d (envp_len=%d)  ae_ptr_len=%d ae_str_len=%d\n", barg->argc, barg->argv_len, barg->envc, barg->envp_len, ae_ptr_len, ae_str_len);
 468 #endif /*__DEBUG__ */
 469 
 470 
 471         /* point of no return */
 472 
 473         release_binary();
 474         current->rss = 0;
 475 
 476         current->entry_address = elf32_h->e_entry;
 477         if(interpreter) {
 478                 errno = elf_load_interpreter(ii);
 479                 if(errno < 0) {
 480                         printk("%s(): unable to load the interpreter '%s'.\n", __FUNCTION__, interpreter);
 481                         iput(ii);
 482                         send_sig(current, SIGKILL);
 483                         return errno;
 484                 }
 485                 current->entry_address = errno;
 486                 iput(ii);
 487         }
 488 
 489         last_ptload = NULL;
 490         for(n = 0; n < elf32_h->e_phnum; n++) {
 491                 elf32_ph = (struct elf32_phdr *)(data + elf32_h->e_phoff + (sizeof(struct elf32_phdr) * n));
 492                 if(elf32_ph->p_type == PT_PHDR) {
 493                         phdr_addr = elf32_ph->p_vaddr;
 494                 }
 495                 if(elf32_ph->p_type == PT_LOAD) {
 496                         start = elf32_ph->p_vaddr & PAGE_MASK;
 497                         length = (elf32_ph->p_vaddr & ~PAGE_MASK) + elf32_ph->p_filesz;
 498                         type = P_DATA;
 499                         prot = 0;
 500                         if(elf32_ph->p_flags & PF_R) {
 501                                 prot = PROT_READ;
 502                         }
 503                         if(elf32_ph->p_flags & PF_W) {
 504                                 prot |= PROT_WRITE;
 505                         }
 506                         if(elf32_ph->p_flags & PF_X) {
 507                                 prot |= PROT_EXEC;
 508                                 type = P_TEXT;
 509                         }
 510                         errno = do_mmap(i, start, length, prot, MAP_PRIVATE | MAP_FIXED, elf32_ph->p_offset & PAGE_MASK, type, O_RDONLY);
 511                         if(errno < 0 && errno > -PAGE_SIZE) {
 512                                 send_sig(current, SIGSEGV);
 513                                 return -ENOEXEC;
 514                         }
 515                         last_ptload = elf32_ph;
 516                 }
 517         }
 518 
 519         elf32_ph = last_ptload;
 520 
 521         /* zero-fill the fractional page of the DATA section */
 522         end = PAGE_ALIGN(elf32_ph->p_vaddr + elf32_ph->p_filesz);
 523         start = elf32_ph->p_vaddr + elf32_ph->p_filesz;
 524         length = end - start;
 525 
 526         /* this will generate a page fault which will load the page in */
 527         memset_b((void *)start, NULL, length);
 528 
 529         /* setup the BSS section */
 530         start = elf32_ph->p_vaddr + elf32_ph->p_filesz;
 531         start = PAGE_ALIGN(start);
 532         end = elf32_ph->p_vaddr + elf32_ph->p_memsz;
 533         end = PAGE_ALIGN(end);
 534         length = end - start;
 535         errno = do_mmap(NULL, start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, 0, P_BSS, 0);
 536         if(errno < 0 && errno > -PAGE_SIZE) {
 537                 send_sig(current, SIGSEGV);
 538                 return -ENOEXEC;
 539         }
 540         current->brk_lower = start;
 541 
 542         /* setup the HEAP section */
 543         start = elf32_ph->p_vaddr + elf32_ph->p_memsz;
 544         start = PAGE_ALIGN(start);
 545         length = PAGE_SIZE;
 546         errno = do_mmap(NULL, start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, 0, P_HEAP, 0);
 547         if(errno < 0 && errno > -PAGE_SIZE) {
 548                 send_sig(current, SIGSEGV);
 549                 return -ENOEXEC;
 550         }
 551         current->brk = start;
 552 
 553         /* setup the STACK section */
 554         sp = KERNEL_BASE_ADDR - 4;      /* formerly 0xBFFFFFFC */
 555         sp -= ae_str_len;
 556         str = sp;       /* this is the address of the first string (argv[0]) */
 557         sp &= ~3;
 558         sp -= at_base ? (AT_ITEMS * 2) * sizeof(unsigned int) : 2 * sizeof(unsigned int);
 559         sp -= ae_ptr_len;
 560         length = KERNEL_BASE_ADDR - (sp & PAGE_MASK);
 561         errno = do_mmap(NULL, sp & PAGE_MASK, length, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_FIXED, 0, P_STACK, 0);
 562         if(errno < 0 && errno > -PAGE_SIZE) {
 563                 send_sig(current, SIGSEGV);
 564                 return -ENOEXEC;
 565         }
 566 
 567         elf_create_stack(barg, (unsigned int *)sp, str, at_base, elf32_h, phdr_addr);
 568 
 569         /* set %esp to point to 'argc' */
 570         sc->oldesp = sp;
 571         sc->eflags = 0x202;     /* FIXME: linux 2.2 = 0x292 */
 572         sc->eip = current->entry_address;
 573         sc->err = 0;
 574         sc->eax = 0;
 575         sc->ecx = 0;
 576         sc->edx = 0;
 577         sc->ebx = 0;
 578         sc->ebp = 0;
 579         sc->esi = 0;
 580         sc->edi = 0;
 581         return 0;
 582 }

/* [previous][next][first][last][top][bottom][index][help] */