{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/linux-android-binary-load-execution/",
  "atlas": "https://www.pystone.net/?node=linux-android-binary-load-execution#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/linux-android-binary-load-execution.md",
  "context": "https://www.pystone.net/notes/linux-android-binary-load-execution.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:linux-android-binary-load-execution",
  "slug": "linux-android-binary-load-execution",
  "title": "Linux 或 Android 系统中的二进制可执行程序加载和执行过程",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "Linux 或 Android 系统中的二进制可执行程序加载和执行过程",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "d827815d5f3d24016ad0a1a4baf965d4a2a5e95269005d4c292cd6634b75980c",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "Linux 或 Android 系统中的二进制可执行程序加载和执行过程",
      "anchor": "linux-或-android-系统中的二进制可执行程序加载和执行过程",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#linux-%E6%88%96-android-%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%8F%AF%E6%89%A7%E8%A1%8C%E7%A8%8B%E5%BA%8F%E5%8A%A0%E8%BD%BD%E5%92%8C%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B"
    },
    {
      "depth": 3,
      "text": "1. 程序启动（Load）",
      "anchor": "1-程序启动load",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#1-%E7%A8%8B%E5%BA%8F%E5%90%AF%E5%8A%A8load"
    },
    {
      "depth": 3,
      "text": "2. 地址空间分配",
      "anchor": "2-地址空间分配",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#2-%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E5%88%86%E9%85%8D"
    },
    {
      "depth": 3,
      "text": "3. 程序执行（Execute）",
      "anchor": "3-程序执行execute",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#3-%E7%A8%8B%E5%BA%8F%E6%89%A7%E8%A1%8Cexecute"
    },
    {
      "depth": 3,
      "text": "4. 动态链接过程（动态链接的程序）",
      "anchor": "4-动态链接过程动态链接的程序",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#4-%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E8%BF%87%E7%A8%8B%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E7%9A%84%E7%A8%8B%E5%BA%8F"
    },
    {
      "depth": 3,
      "text": "5. 栈与堆的管理",
      "anchor": "5-栈与堆的管理",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#5-%E6%A0%88%E4%B8%8E%E5%A0%86%E7%9A%84%E7%AE%A1%E7%90%86"
    },
    {
      "depth": 3,
      "text": "6. 系统调用与中断处理",
      "anchor": "6-系统调用与中断处理",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#6-%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E4%B8%8E%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86"
    },
    {
      "depth": 3,
      "text": "7. 相关工具与底层支持",
      "anchor": "7-相关工具与底层支持",
      "citation": "https://www.pystone.net/notes/linux-android-binary-load-execution/#7-%E7%9B%B8%E5%85%B3%E5%B7%A5%E5%85%B7%E4%B8%8E%E5%BA%95%E5%B1%82%E6%94%AF%E6%8C%81"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "本层中的“Linux 或 Android 系统中的二进制可执行程序加载和执行过程”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#%E6%9C%AC%E5%B1%82"
    }
  ],
  "contentMarkdown": "# Linux 或 Android 系统中的二进制可执行程序加载和执行过程\n\n﻿# Linux 或 Android 系统中的二进制可执行程序加载和执行过程\n\n\n### **1. 程序启动（Load）**\n\n- **用户请求程序启动**：\n  用户通过命令行（Linux）或点击应用图标（Android）启动程序。\n\n- **调用execve()系统调用**：\n  在 Linux 和 Android 中，`execve()` 是启动新程序的核心系统调用。该调用会加载指定的可执行文件，并将其映像加载到内存中。`execve()` 会替换当前进程的映像，因此，它会加载一个新的程序并初始化它的执行环境。\n\n  ```c\n  execve(\"/path/to/program\", argv, envp);\n  ```\n\n- **操作系统加载器（Linker/Loader）**：\n  操作系统加载器负责加载程序及其所需的库文件，解析 ELF 文件的头部、程序段等，并将其映射到进程的虚拟地址空间。\n\n  - **ld-linux.so / ld.so**：动态链接器，Linux 中负责动态链接的加载（即加载共享库）。它处理对 `.so` 库的依赖解析，并执行符号链接。\n\n- **加载可执行文件**：\n  加载器会按照 ELF 格式解析程序头信息，确定程序入口点、加载程序的各个段（如 `.text`，`.data`）到内存。\n\n### **2. 地址空间分配**\n\n- **虚拟内存管理**：\n  每个进程有独立的虚拟地址空间，由操作系统通过虚拟内存管理机制映射到物理内存。这允许程序使用较大的地址空间并且隔离进程之间的内存。\n\n- **程序段加载**：\n  - **代码段（.text）**：存储程序执行的指令。\n  - **数据段（.data）**：存储已初始化的全局变量。\n  - **未初始化数据段（.bss）**：存储未初始化的全局变量。\n\n- **堆和栈的分配**：\n  - **堆**：程序动态分配内存（通过 `malloc()` 和 `free()` 等）。\n  - **栈**：存储函数调用、局部变量等。栈的大小通常由操作系统设定，并随着函数调用/返回进行变化。\n\n### **3. 程序执行（Execute）**\n\n- **操作系统内核准备好执行环境**：\n  在程序加载到内存后，操作系统内核将控制权交给用户空间，程序从入口点（通常是 `main()` 函数）开始执行。\n\n- **CPU执行指令**：\n  - CPU根据程序计数器（PC）指向的内存地址获取下一条指令。\n  - 指令被解码并执行，执行的操作包括数据处理、内存读写、跳转等。\n\n- **上下文切换与调度**：\n  - 操作系统根据调度策略（如时间片轮转、优先级调度等）决定哪个进程或线程运行。上下文切换是操作系统中通过保存和恢复寄存器状态来实现的。\n\n### **4. 动态链接过程（动态链接的程序）**\n\n- **动态链接器（Dynamic Linker）**：\n  动态链接器负责在程序运行时加载共享库并解析符号。它的工作包括：\n\n  - **加载共享库**：在程序启动时，加载器会根据动态段（`.dynamic`）中的信息，加载所需的共享库（如 `libc.so`）。\n\n  - **符号解析与重定位**：链接器会解析程序中的符号，寻找符号地址，并将程序中的符号重定位到实际的内存地址。\n\n- **GOT与PLT**：\n  动态链接的核心机制之一是 **全局偏移表（GOT）** 和 **过程链接表（PLT）**。当程序首次调用共享库的函数时：\n  - **PLT**：会先跳转到动态链接器，动态链接器会解析符号并修改 **GOT** 表中的函数地址，确保后续调用直接跳转到共享库中的正确函数。\n\n### **5. 栈与堆的管理**\n\n- **栈管理**：\n  栈用于保存局部变量和函数调用信息。每当一个函数被调用时，栈帧会被创建，保存当前函数的局部变量和返回地址。\n\n  - 栈空间的分配由操作系统负责管理，程序员不能直接控制栈的分配和释放。栈在函数调用返回时会自动清理。\n\n- **堆管理**：\n  堆用于动态内存分配。程序员使用 `malloc()`、`calloc()` 等函数来从堆中请求内存，并通过 `free()` 来释放内存。\n\n  - 堆的内存分配由操作系统管理，通常会通过内存池或者内存堆管理算法来优化性能（如 `ptmalloc` 或 `glibc` 中的 malloc 实现）。\n\n### **6. 系统调用与中断处理**\n\n- **系统调用**：\n  程序与操作系统之间的交互是通过系统调用来实现的。常见的系统调用有 `read()`、`write()`、`open()` 等。\n\n  - 系统调用使用软中断（如 `int 0x80` 或 `syscall` 指令）进入内核模式，从而由操作系统内核处理请求。\n\n- **中断处理**：\n  CPU支持硬件中断和软件中断。硬件中断通常来自外部设备（如定时器、I/O设备等），而软件中断则来自程序自身（例如异常、错误或系统调用）。\n\n  - 操作系统通过中断向 CPU 通知特殊事件，然后处理该事件（例如内存访问错误或定时器到期）。\n\n### **7. 相关工具与底层支持**\n\n- **链接器（Linker）**：\n  - **ld**：Linux中的标准链接器，负责将目标文件（.o）链接成可执行文件。它处理符号解析、地址重定位、库链接等操作。\n\n- **动态链接器（Dynamic Linker）**：\n  - **ld-linux.so**：在 Linux 中，`ld-linux.so` 负责程序启动时动态链接共享库。\n  - **linker**：在 Android 中，`linker` 是负责加载共享库并解析符号的工具。\n\n- **调试工具**：\n  - **GDB**（GNU Debugger）：用于调试程序，能够在程序执行时暂停，查看栈信息、变量值等。\n  - **LLDB**：Android 使用 LLDB 作为调试工具，与 GDB 类似，专门针对 Android 平台进行优化。\n\n- **内存管理**：\n  - 操作系统内核提供虚拟内存管理，使用 **页表** 和 **交换空间**（Swap Space）来管理内存的分配与回收。\n  - 动态内存分配（如 `malloc()`、`free()`）由操作系统提供支持，通常通过内存堆管理算法（如 `ptmalloc`）实现。\n"
}
