PageSourceSearch

https://0xc0ffee.netlify.app/assets/22-elf-loader-p2.html-Cz9FyAGT.js

js 0xc0ffee.netlify.app collected 2026-10-03 10:23:48 UTC 37,490 bytes, 148 lines download raw bytes

1import{_ as n,c as a,e,o as p}from"./app-CjUkjRdW.js";const t={};function o(l,s){return p(),a("div",null,s[0]||(s[0]=[e(`<h1 id="elf-loader-part-2" tabindex="-1"><a class="header-anchor" href="#elf-loader-part-2"><span>ELF Loader (Part 2)</span></a></h1><p>So far we have the code that loads the task image into memory in the <code>tasks</code> module. We also have code that applies relocations in the <code>loader</code> module. Now that we&#39;re going to deal with ELF, it&#39;s time to move all task loading code into the <code>loader</code> module (which will use the <code>elf</code> module to read the ELF file).</p><h2 id="loading-elf" tabindex="-1"><a class="header-anchor" href="#loading-elf"><span>Loading ELF</span></a></h2><p>We don&#39;t have a filesystem yet, so we are still going to rely on the user task being loaded by the bootloader into memory, until we implement a filesystem. The task loader will use the in-memory ELF binary to &quot;load&quot; the task by:</p><ul><li>allocating enough virtual memory for the task</li><li>mapping virtual memory to physical memory with the correct permissions</li><li>copying the loadable segments into their respective virtual memory regions</li><li>applying relocation entries to the loaded segments</li><li>identifying the entry point and returning it to the caller</li></ul><p>Let&#39;s start by adding a new proc to the <code>loader</code> module to load an ELF binary, given the address of the raw ELF image in memory. The first step is to iterate over the segments and build a corresponding list of page-aligned VM regions.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
2<span class="line"></span>
3<span class="line"><span class="token keyword">import</span> elf</span>
4<span class="line"><span class="token keyword">import</span> vmm</span>
5<span class="line"></span>
6<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
7<span class="line">  <span class="token keyword">let</span> image <span class="token operator">=</span> <span class="token function">initElfImage</span><span class="token punctuation">(</span>imagePtr<span class="token punctuation">)</span></span>
8<span class="line"></span>
9<span class="line">  <span class="token comment"># get a list of page-aligned memory regions to be mapped</span></span>
10<span class="line">  <span class="token keyword">var</span> vmRegions<span class="token operator">:</span> seq<span class="token punctuation">[</span>VMRegion<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">@</span><span class="token punctuation">[</span><span class="token punctuation">]</span></span>
11<span class="line">  <span class="token function">for</span> <span class="token punctuation">(</span>i<span class="token punctuation">,</span> ph<span class="token punctuation">)</span> <span class="token operator">in</span> <span class="token function">segments</span><span class="token punctuation">(</span>image<span class="token punctuation">)</span><span class="token operator">:</span></span>
12<span class="line">    <span class="token keyword">if</span> ph<span class="token operator">.</span><span class="token keyword">type</span> <span class="token operator">==</span> ElfProgramHeaderType<span class="token operator">.</span>Load<span class="token operator">:</span></span>
13<span class="line">      <span class="token keyword">if</span> ph<span class="token operator">.</span>align <span class="token operator">!=</span> PageSize<span class="token operator">:</span></span>
14<span class="line">        <span class="token keyword">raise</span> <span class="token function">newException</span><span class="token punctuation">(</span>LoaderError<span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token string">&quot;Unsupported alignment {ph.align:#x} for segment {i}&quot;</span><span class="token punctuation">)</span></span>
15<span class="line">
15      <span class="token keyword">let</span> startOffset <span class="token operator">=</span> ph<span class="token operator">.</span>vaddr <span class="token operator">mod</span> PageSize</span>
16<span class="line">      <span class="token keyword">let</span> startPage <span class="token operator">=</span> ph<span class="token operator">.</span>vaddr <span class="token operator">-</span> startOffset</span>
17<span class="line">      <span class="token keyword">let</span> numPages <span class="token operator">=</span> <span class="token punctuation">(</span>startOffset <span class="token operator">+</span> ph<span class="token operator">.</span>memsz <span class="token operator">+</span> PageSize <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">div</span> PageSize</span>
18<span class="line">      <span class="token keyword">let</span> region <span class="token operator">=</span> <span class="token function">VMRegion</span><span class="token punctuation">(</span></span>
19<span class="line">        start<span class="token operator">:</span> startPage<span class="token operator">.</span>VirtAddr<span class="token punctuation">,</span></span>
20<span class="line">        npages<span class="token operator">:</span> numPages<span class="token punctuation">,</span></span>
21<span class="line">        flags<span class="token operator">:</span> <span class="token function">cast[VMRegionFlags]</span><span class="token punctuation">(</span>ph<span class="token operator">.</span>flags<span class="token punctuation">)</span><span class="token punctuation">,</span></span>
22<span class="line">      <span class="token punctuation">)</span></span>
23<span class="line">      vmRegions<span class="token operator">.</span><span class="token function">add</span><span class="token punctuation">(</span>region<span class="token punctuation">)</span></span>
24<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Notice that we need to keep track of the segment flags as well, as they will be used to set the page permissions. We didn&#39;t have that <code>flags</code> field on <code>VMRegion</code> before, so let&#39;s add it now:</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/vmm.nim</span></span>
25<span class="line"></span>
26<span class="line"><span class="token keyword">type</span></span>
27<span class="line">  VMRegion<span class="token operator">*</span> <span class="token operator">=</span> <span class="token keyword">object</span></span>
28<span class="line">    start<span class="token operator">*:</span> VirtAddr</span>
29<span class="line">    npages<span class="token operator">*:</span> uint64</span>
30<span class="line highlighted">    flags<span class="token operator">*:</span> VMRegionFlags</span>
31<span class="line highlighted"></span>
32<span class="line highlighted">  VMRegionFlag<span class="token operator">*</span> <span class="token operator">=</span> <span class="token keyword">enum</span></span>
33<span class="line highlighted">    Execute <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">&quot;E&quot;</span><span class="token punctuation">)</span></span>
34<span class="line highlighted">
34    Write   <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">&quot;W&quot;</span><span class="token punctuation">)</span></span>
35<span class="line highlighted">    Read    <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token string">&quot;R&quot;</span><span class="token punctuation">)</span></span>
36<span class="line highlighted">  VMRegionFlags<span class="token operator">*</span> <span class="token punctuation">{.</span>size<span class="token operator">:</span> <span class="token function">sizeof</span><span class="token punctuation">(</span>uint32<span class="token punctuation">)</span><span class="token punctuation">.}</span> <span class="token operator">=</span> set<span class="token punctuation">[</span>VMRegionFlag<span class="token punctuation">]</span></span>
37<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Now, let&#39;s validate a couple of assumptions: (1) there must be at least one segment, and (2) the address of the start page of the first segment must be zero, since the ELF binary is supposed to be relocatable (i.e. a PIE).</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
38<span class="line"></span>
39<span class="line"><span class="token keyword">type</span></span>
40<span class="line">  LoaderError<span class="token operator">*</span> <span class="token operator">=</span> <span class="token keyword">object</span> <span class="token operator">of</span> CatchableError</span>
41<span class="line"></span>
42<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
43<span class="line">  <span class="token operator">...</span></span>
44<span class="line"></span>
45<span class="line">  <span class="token keyword">if</span> vmRegions<span class="token operator">.</span>len <span class="token operator">==</span> <span class="token number">0</span><span class="token operator">:</span></span>
46<span class="line">    <span class="token keyword">raise</span> <span class="token function">newException</span><span class="token punctuation">(</span>LoaderError<span class="token punctuation">,</span> <span class="token string">&quot;No loadable segments found&quot;</span><span class="token punctuation">)</span></span>
47<span class="line"></span>
48<span class="line">  <span class="token keyword">if</span> vmRegions<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">.</span>start<span class="token operator">.</span>uint64 <span class="token operator">!=</span> <span class="token number">0</span><span class="token operator">:</span></span>
49<span class="line">    <span class="token keyword">raise</span> <span class="token function">newException</span><span class="token punctuation">(</span>LoaderError<span class="token punctuation">,</span> <span class="token string">&quot;Expecting a PIE binary with a base address of 0&quot;</span><span class="token punctuation">)</span></span>
50<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Now, we have two options to allocate the required VM regions:</p><ol><li>Allocate a single large region that spans all segments</li><li>Allocate one region per segment</li></ol><p>The first option is simpler, but it may waste memory if the segments are not contiguous. The second is more complex because we have to maintain the relative positions of the segments to the base of the first segment. Our virtual memory allocator is not prepared to handle this yet (it allocates regions in a best-fit manner), so we&#39;ll go with the first option for now.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
51<span class="line"></span>
52<span class="line"><span class="token keyword">
52import</span> std<span class="token operator">/</span>algorithm</span>
53<span class="line"><span class="token operator">...</span></span>
54<span class="line"></span>
55<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
56<span class="line">  <span class="token operator">...</span></span>
57<span class="line"></span>
58<span class="line">  <span class="token comment"># calculate total memory size</span></span>
59<span class="line">  vmRegions <span class="token operator">=</span> vmRegions<span class="token operator">.</span><span class="token function">sortedByIt</span><span class="token punctuation">(</span>it<span class="token operator">.</span>start<span class="token punctuation">)</span></span>
60<span class="line">  <span class="token keyword">let</span> memSize <span class="token operator">=</span> vmRegions<span class="token punctuation">[</span><span class="token operator">^</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token operator">.</span><span class="token keyword">end</span> <span class="token operator">-!</span> vmRegions<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token operator">.</span>start</span>
61<span class="line">  <span class="token keyword">let</span>
61 pageCount <span class="token operator">=</span> <span class="token punctuation">(</span>memSize <span class="token operator">+</span> PageSize <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">div</span> PageSize</span>
62<span class="line"></span>
63<span class="line">  <span class="token comment"># allocate a single contiguous region for the user image</span></span>
64<span class="line">  <span class="token keyword">let</span> taskRegion <span class="token operator">=</span> <span class="token function">vmalloc</span><span class="token punctuation">(</span>uspace<span class="token punctuation">,</span> pageCount<span class="token punctuation">)</span></span>
65<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Remember that the individual regions in the <code>vmRegions</code> list assume that the first region starts at 0. We need to adjust the start of each region to the base of the <code>taskRegion</code>:</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
66<span class="line"></span>
67<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
68<span class="line">  <span class="token operator">...</span></span>
69<span class="line"></span>
70<span class="line">  <span class="token comment"># adjust the individual regions&#39; start addresses based on taskRegion.start</span></span>
71<span class="line">  <span class="token keyword">for</span> region <span class="token operator">in</span> vmRegions<span class="token operator">.</span>mitems<span class="token operator">:</span></span>
72<span class="line">    region<span class="token operator">.</span>start <span class="token operator">=</span> taskRegion<span class="token operator">.</span>start <span class="token operator">+!</span> region<span class="token operator">.</span>start<span class="token operator">.</span>uint64</span>
73<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Now we need to map the regions to physical memory. In addition to mapping them in the user address space, we also need to temporarily map them in the kernel address space so we can copy the segments into the user space.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
74<span class="line"></span>
75<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
76<span class="line">  <span class="token operator">...</span></span>
77<span class="line"></span>
78<span class="line">  <span class="token comment"># map each region into the page tables, making sure to set the R/W and NX flags as needed</span></span>
79<span class="line">  <span class="token keyword">var</span> kpml4 <span class="token operator">=</span> <span class="token function">getActivePML4</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
80<span class="line">  <span class="token keyword">
80for</span> region <span class="token operator">in</span> vmRegions<span class="token operator">:</span></span>
81<span class="line">    <span class="token keyword">let</span> access <span class="token operator">=</span> <span class="token keyword">if</span> region<span class="token operator">.</span>flags<span class="token operator">.</span><span class="token function">contains</span><span class="token punctuation">(</span>Write<span class="token punctuation">)</span><span class="token operator">:</span> paReadWrite <span class="token keyword">else</span><span class="token operator">:</span> paRead</span>
82<span class="line">    <span class="token keyword">let</span> noExec <span class="token operator">=</span> <span class="token operator">not</span> region<span class="token operator">.</span>flags<span class="token operator">.</span><span class="token function">contains</span><span class="token punctuation">(</span>Execute<span class="token punctuation">)</span></span>
83<span class="line">    <span class="token keyword">let</span> physAddr <span class="token operator">=</span> <span class="token function">vmmap</span><span class="token punctuation">(</span>region<span class="token punctuation">,</span> pml4<span class="token punctuation">,</span> access<span class="token punctuation">,</span> pmUser<span class="token punctuation">,</span> noExec<span class="token punctuation">)</span></span>
84<span class="line">    <span class="token comment"># temporarily map the region in kernel space so that we can copy the segments and apply relocations</span></span>
85<span class="line">    <span class="token function">mapRegion</span><span class="token punctuation">(</span></span>
86<span class="line">      pml4 <span class="token operator">=</span> kpml4<span class="token punctuation">,</span></span>
87<span class="line">      virtAddr <span class="token operator">=</span> region<span class="token operator">.</span>start<span class="token punctuation">,</span></span>
88<span class="line">      physAddr <span class="token operator">=</span> physAddr<span class="token punctuation">,</span></span>
89<span class="line">      pageCount <span class="token operator">=</span> region<span class="token operator">.</span>npages<span class="token punctuation">,</span></span>
90<span class="line">      pageAccess <span class="token operator">=</span> paReadWrite<span class="token punctuation">,</span></span>
91<span class="line">      pageMode <span class="token operator">=</span> pmSupervisor<span class="token punctuation">,</span></span>
92<span class="line">      noExec <span class="token operator">=</span> true<span class="token punctuation">,</span></span>
93<span class="line">    <span class="token punctuation">)</span></span>
94<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>OK, we&#39;re now ready to copy the segments into their respective regions. Remember that some segments may have a memory size (<code>memsz</code>) that is larger than the corresponding size in the file (<code>filesz</code>), as is the case with BSS segments. In such cases, we need to zero-fill the remaining memory.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
95<span class="line"></span>
96<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
97<span class="line">  <span class="token operator">...</span></span>
98<span class="line"></span>
99<span class="line">  <span class="token comment"># copy loadable segments from the image to the user memory</span></span>
100<span class="line">  <span class="token function">
100for</span> <span class="token punctuation">(</span>i<span class="token punctuation">,</span> ph<span class="token punctuation">)</span> <span class="token operator">in</span> <span class="token function">segments</span><span class="token punctuation">(</span>image<span class="token punctuation">)</span><span class="token operator">:</span></span>
101<span class="line">    <span class="token keyword">if</span> ph<span class="token operator">.</span><span class="token keyword">type</span> <span class="token operator">!=</span> ElfProgramHeaderType<span class="token operator">.</span>Load<span class="token operator">:</span></span>
102<span class="line">      <span class="token keyword">continue</span></span>
103<span class="line">    <span class="token keyword">let</span> dest <span class="token operator">=</span> <span class="token function">cast[pointer]</span><span class="token punctuation">(</span>taskRegion<span class="token operator">.</span>start <span class="token operator">+!</span> ph<span class="token operator">.</span>vaddr<span class="token punctuation">)</span></span>
104<span class="line">    <span class="token keyword">let</span> src <span class="token operator">=</span> <span class="token function">cast[pointer]</span><span class="token punctuation">(</span>imagePtr <span class="token operator">+!</span> ph<span class="token operator">.</span>offset<span class="token punctuation">)</span></span>
105<span class="line">    <span class="token function">copyMem</span><span class="token punctuation">(</span>dest<span class="token punctuation">,</span> src<span class="token punctuation">,</span> ph<span class="token operator">.</span>filesz<span class="token punctuation">)</span></span>
106<span class="line">    <span class="token keyword">if</span> ph<span class="token operator">.</span>filesz <span class="token operator">&lt;</span> ph<span class="token operator">.</span>memsz<span class="token operator">:</span></span>
107<span class="line">      <span class="token function">zeroMem</span><span class="token punctuation">(</span><span class="token function">cast[pointer]</span><span class="token punctuation">(</span><span class="token function">cast[uint64]</span><span class="token punctuation">(</span>dest<span class="token punctuation">)</span> <span class="token operator">+</span> ph<span class="token operator">.</span>filesz<span class="token punctuation">)</span><span class="token punctuation">,</span> ph<span class="token operator">.</span>memsz <span class="token operator">-</span> ph<span class="token operator">.</span>filesz<span class="token punctuation">)</span></span>
108<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>The segments are now loaded into memory. The next step is to apply any relocations that may be needed. Relocation metadata is stored in a segment of type <code>DYNAMIC</code>. We need to find this segment in the ELF image and pass its offset to the <code>applyRelocations</code> proc.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
109<span class="line"></span>
110<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
111<span class="line">  <span class="token operator">...</span></span>
112<span class="line"></span>
113<span class="line">  <span class="token keyword">var</span> dynOffset<span class="token operator">:</span> int <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span></span>
114<span class="line"></span>
115<span class="line">  <span class="token function">
115for</span> <span class="token punctuation">(</span>i<span class="token punctuation">,</span> ph<span class="token punctuation">)</span> <span class="token operator">in</span> <span class="token function">segments</span><span class="token punctuation">(</span>image<span class="token punctuation">)</span><span class="token operator">:</span></span>
116<span class="line">    <span class="token keyword">if</span> ph<span class="token operator">.</span><span class="token keyword">type</span> <span class="token operator">==</span> ElfProgramHeaderType<span class="token operator">.</span>Dynamic<span class="token operator">:</span></span>
117<span class="line">      dynOffset <span class="token operator">=</span> <span class="token function">cast[int]</span><span class="token punctuation">(</span>ph<span class="token operator">.</span>vaddr<span class="token punctuation">)</span></span>
118<span class="line"></span>
119<span class="line">  <span class="token keyword">if</span> dynOffset <span class="token operator">==</span> <span class="token operator">-</span><span class="token number">1</span><span class="token operator">:</span></span>
120<span class="line">    <span class="token keyword">raise</span> <span class="token function">newException</span><span class="token punctuation">(</span>LoaderError<span class="token punctuation">,</span> <span class="token string">&quot;No dynamic section found&quot;</span><span class="token punctuation">)</span></span>
121<span class="line"></span>
122<span class="line">  <span class="token function">applyRelocations</span><span class="token punctuation">(</span></span>
123<span class="line">    image <span class="token operator">=</span> <span class="token keyword">cast</span><span class="token punctuation">[</span><span class="token keyword">ptr</span> UncheckedArray<span class="token punctuation">[</span>byte<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">(</span>taskRegion<span class="token operator">.</span>start<span class="token punctuation">)</span><span class="token punctuation">,</span></span>
124<span class="line">    dynOffset <span class="token operator">=</span> <span class="token function">cast[uint64]</span><span class="token punctuation">(</span>dynOffset<span class="token punctuation">)</span><span class="token punctuation">,</span></span>
125<span class="line">  <span class="token punctuation">)</span></span>
126<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>We&#39;re almost done. We no longer need the kernel&#39;s temporary mapping of the user task&#39;s memory, so we can unmap the regions now.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
127<span class="line"></span>
128<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span> <span class="token operator">=</span></span>
129<span class="line">  <span class="token operator">...</span></span>
130<span class="line"></span>
131<span class="line">  <span class="token comment"># unmap the user image from kernel space</span></span>
132<span class="line">  <span class="token keyword">for</span> region <span class="token operator">in</span> vmRegions<span class="token operator">:</span></span>
133<span class="line">    <span class="token function">unmapRegion</span><span class="token punctuation">(</span>kpml4<span class="token punctuation">,</span> region<span class="token operator">.</span>start<span class="token punctuation">,</span> region<span class="token operator">.</span>
133npages<span class="token punctuation">)</span></span>
134<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Finally, we need to return information about the loaded task to the caller, particularly the VM region where the task was loaded and the entry point.</p><div class="language-nim line-numbers-mode" data-highlighter="prismjs" data-ext="nim" data-title="nim"><pre><code><span class="line"><span class="token comment"># src/kernel/loader.nim</span></span>
135<span class="line"></span>
136<span class="line"><span class="token keyword">type</span></span>
137<span class="line">  LoadedElfImage<span class="token operator">*</span> <span class="token operator">=</span> <span class="token keyword">object</span></span>
138<span class="line">    vmRegion<span class="token operator">*:</span> VMRegion</span>
139<span class="line">    entryPoint<span class="token operator">*:</span> pointer</span>
140<span class="line"></span>
141<span class="line"><span class="token keyword">proc</span> <span class="token function">load<span class="token operator">*</span></span><span class="token punctuation">(</span>imagePtr<span class="token operator">:</span> pointer<span class="token punctuation">)</span><span class="token operator">:</span> LoadedElfImage <span class="token operator">=</span></span>
142<span class="line">  <span class="token operator">...</span></span>
143<span class="line"></span>
144<span class="line">  result <span class="token operator">=</span> <span class="token function">LoadedElfImage</span><span class="token punctuation">(</span></span>
145<span class="line">    vmRegion<span class="token operator">:</span> taskRegion<span class="token punctuation">,</span></span>
146<span class="line">    entryPoint<span class="token operator">:</span> <span class="token function">cast[pointer]</span><span class="token punctuation">(</span>taskRegion<span class="token operator">.</span>start <span class="token operator">+!</span> image<span class="token operator">.</span>header<span class="token operator">.</span>entry<span class="token punctuation">)</span></span>
147<span class="line">  <span class="token punctuation">)</span></span>
148<span class="line"></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div>`,27)]))}const c=n(t,[["render",o],["__file","22-elf-loader-p2.html.vue"]]),r=JSON.parse(`{"path":"/osdev/22-elf-loader-p2.html","title":"ELF Loader (Part 2)","lang":"en-US","frontmatter":{},"headers":[{"level":2,"title":"Loading ELF","slug":"loading-elf","link":"#loading-elf","children":[]}],"git":{"updatedTime":1744638230000},"filePathRelative":"osdev/22-elf-loader-p2.md","excerpt":"\\n<p>So far we have the code that loads the task image into memory in the <code>tasks</code> module. We\\nalso have code that applies relocations in the <code>loader</code> module. Now that we're going to\\ndeal with ELF, it's time to move all task loading code into the <code>loader</code> module (which\\nwill use the <code>elf</code> module to read the ELF file).</p>"}`);export{c as comp,r as data};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.