Executin

看视频学习

Binary Format

  • 执行档的格式的格式会根据 OS 不同,而有所不同
  • 执行档:可执行文件在计算机科学上,指一种内容可被电脑解释为程序的电脑文件。通常可执行文件内,含有以二进制编码的微处理器指令,也因此可执行文件有时称为二进制档。
  • OS:一般指操作系统
    • Linux - ELF
    • Windows - PE
  • 在 Binary 的开头会有个 magic number 栏位,方便让 OS 辨认是属于什么类型的档案
    • 在 Linux 下可以使用 file 来 检视(检视:检验查看)

Segment

段是指占用数据文件空间的通称,或数据库对象使用的空间的集合;段可以有表段、索引段、回滚段、临时段和高速缓存段等;

  • 在程序执行时期才有的概念,基本上会根据读写执行权限及特性来分为数个 segment
  • 一般来说可分为 rodata、data、code、stack、heap 等 segment
    • data : rw-
    • code : r-x
    • stack : rw-
    • heap : rw-
    • r – 可读
    • w – 可写
    • x – 可执行

Execution Flow (执行流程)

  • What happened when we execute an elf file?
    • #./hello
  • 在一般情况下程式会在 disk 中,而 kernel 会通过一连串的过程将程序式 mapping(映射) 到记忆体中去执行
    Executin
  • 我们在 shell 执行一个 elf 时
    • 会先去fork 一个 process
    • child 再去使用 execve 执行
  • sys_execve()
    • 检查参数 ex: argv , envp
  • do_execve()
    • 搜寻执行档位置
    • 读取执行档前 128 byte 获取执行档的资讯
      • e.g. magic number
  • search_binary_handler()
    • 利用前面所获取的资讯来呼叫相对应的handler
    • e.g. load_script()、load_elf_binary()
  • load_elf_binary()
    • 检查及获取 program header 资讯
    • 如果是 dynamic linking(动态链路) 则利用 .interp 这个 section 来确定 loader 路径
    • 将 program header 记录的位置 mapping 到 memory 中,e.g. code segment 位置
    • 将 sys_execve 的 return address 改为 loader (ld.so) 的 entry point
      • static linking 下则会时 elf 的 entry point
  • How program maps to virtual memory
    • 在 program header 中
      • 记录着那些 segment 应该 mapping 到什么位置,以及该 segment 的读写执行权限
      • 记录那些 section 属于那些 segment
        • 当 program mapping 记忆体时会根据权限的不同分为好几个 segment
        • 一个 segment 可以包含0个到多个 section
  • How program maps to virtual memory
    Executin
    • readelf -l binary
      • 查看 program header
    • readelf -S binary
      • 查看 section header
    • readelf -d binary
      • 查看 dynamic section 内容
  • ld.so
    • 载入 elf 所需的 shared library
      • 这部分会记录在 elf 中的 DT_NEED中
    • 初始化 GOT
    • 其他相关初始化的动作
      • ex:将 symbol table 合并到 global symbo table 等等
    • 在 ld.so 执行完后会跳到 _start 开始执行主要程式Executin
  • _start
    • 将下列项目传给 libc_start_main
      • 环境变数起始位置
      • main 的位置(通常在第一个参数)
      • .init
        • 呼叫 main 之前的初始化工作
      • .fini
        • 程序结束前的收尾工作
  • _libc_start_main
    • 执行 .init
    • 执行 main
      • 主程式部分
    • 执行 .fini
    • 执行 exit 结束程式
上一篇:java的技术调用栈图示例


下一篇:Hibernate5使用注解方式(转)