linux可执行文件的加载和运行之一(5)

int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
{
     int try,retval;
     struct linux_binfmt *fmt;
#ifdef __alpha__
     /* handle /sbin/loader.. */
     {
       struct exec * eh = (struct exec *) bprm->buf;
       if (!bprm->loader && eh->fh.f_magic == 0x183 &&
          (eh->fh.f_flags & 0x3000) == 0x3000)
       {
          struct file * file;
          unsigned long loader;
          allow_write_access(bprm->file);
          fput(bprm->file);
          bprm->file = NULL;
          loader = bprm->vma->vm_end - sizeof(void *);
          file = open_exec("/sbin/loader");
          retval = PTR_ERR(file);
          if (IS_ERR(file))
              return retval;
          /* Remember if the application is TASO. */
          bprm->sh_bang = eh->ah.entry < 0x100000000UL;
          bprm->file = file;
          bprm->loader = loader;
          retval = prepare_binprm(bprm);
          if (retval<0)
              return retval;
          /* should call search_binary_handler recursively here,
            but it does not matter */
       }
     }
#endif
     retval = security_bprm_check(bprm);
     if (retval)
          return retval;
     /* kernel module loader fixup */
     /* so we don't try to load run modprobe in kernel space. */
     set_fs(USER_DS);
     retval = audit_bprm(bprm);
     if (retval)
          return retval;
     retval = -ENOENT;
     //这里会循环两次.待模块加载之后再遍历一次
     for (try=0; try<2; try++) {
          read_lock(&binfmt_lock);
          list_for_each_entry(fmt, &formats, lh) {
              //加载函数
              int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
              if (!fn)
                   continue;
              if (!try_module_get(fmt->module))
                   continue;
              read_unlock(&binfmt_lock);
              //运行加载函数,如果加载末成功,则继续遍历
              retval = fn(bprm, regs);
              //加载成功了
              if (retval >= 0) {
                   put_binfmt(fmt);
                   allow_write_access(bprm->file);
                   if (bprm->file)
                        fput(bprm->file);
                   bprm->file = NULL;
                   current->did_exec = 1;
                   proc_exec_connector(current);
                   return retval;
              }
              read_lock(&binfmt_lock);
              put_binfmt(fmt);
              if (retval != -ENOEXEC || bprm->mm == NULL)
                   break;
              if (!bprm->file) {
                   read_unlock(&binfmt_lock);
                   return retval;
              }
          }
          read_unlock(&binfmt_lock);
          //所有模块加载这个可执行文件失败,则加载其它模块再试一次
          if (retval != -ENOEXEC || bprm->mm == NULL) {
              break;
              //CONFIG_KMOD:动态加载模块标志
#ifdef CONFIG_KMOD
          }else{
#define printable(c) (((c)=='t') || ((c)=='n') || (0x20<=(c) && (c)<=0x7e))
              if (printable(bprm->buf[0]) &&
                printable(bprm->buf[1]) &&
                printable(bprm->buf[2]) &&
                printable(bprm->buf[3]))
                   break; /* -ENOEXEC */
              request_module("binfmt-%04x", *(unsigned short *)(&bprm->buf[2]));
#endif
          }
     }
     return retval;
}

 

  到这里,我们看到了可执行文件的加载过程,接下来,我们以a.out型的可执文件的加载过程为例.来看一看linux怎么处理可执行文件的.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值