about summary refs log tree commit diff stats
path: root/cpp/003trace.test.cc
blob: 0acf88071ac9c0d04acd05e90c34f041e9e8a5fc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
void test_trace_check_compares() {
  CHECK_TRACE_CONTENTS("test layer", "");
  trace("test layer") << "foo";
  CHECK_TRACE_CONTENTS("test layer", "foo");
}

void test_trace_check_filters_layers() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  CHECK_TRACE_CONTENTS("test layer 1", "foo");
}

void test_trace_check_ignores_other_lines() {
  trace("test layer 1") << "foo";
  trace("test layer 1") << "bar";
  CHECK_TRACE_CONTENTS("test layer 1", "foo");
}

void test_trace_ignores_trailing_whitespace() {
  trace("test layer 1") << "foo\n";
  CHECK_TRACE_CONTENTS("test layer 1", "foo");
}

void test_trace_check_always_finds_empty_lines() {
  CHECK_TRACE_CONTENTS("test layer 1", "");
}

void test_trace_check_treats_empty_layers_as_wildcards() {
  trace("test layer 1") << "foo";
  CHECK_TRACE_CONTENTS("", "foo");
}

void test_trace_check_multiple_lines_at_once() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  CHECK_TRACE_CONTENTS("", "foobar");
}

void test_trace_check_always_finds_empty_lines2() {
  CHECK_TRACE_CONTENTS("test layer 1", "");
}

void test_trace_orders_across_layers() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  trace("test layer 1") << "qux";
  CHECK_TRACE_CONTENTS("", "foobarqux");
}

void test_trace_orders_across_layers2() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  trace("test layer 1") << "qux";
  CHECK_TRACE_CONTENTS("foobarqux");
}

void test_trace_checks_ordering_spanning_multiple_layers() {
  trace("layer1") << "foo";
  trace("layer2") << "bar";
  trace("layer1") << "qux";
  CHECK_TRACE_CONTENTS("layer1: foolayer2: barlayer1: qux");
}

void test_trace_segments_within_layers() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  new_trace_frame("test layer 1");
  trace("test layer 1") << "qux";
  CHECK_TRACE_CONTENTS("test layer 1", "fooqux");
  CHECK_TRACE_CONTENTS("test layer 1", 0, "foo");
  CHECK_TRACE_DOESNT_CONTAIN("test layer 1", 1, "foo");
}

void test_trace_checks_ordering_across_layers_and_frames() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  new_trace_frame("test layer 1");
  trace("test layer 1") << "qux";
  CHECK_TRACE_CONTENTS("test layer 1/0: footest layer 2: bartest layer 1: qux");
  CHECK_TRACE_CONTENTS("test layer 1: footest layer 2: bartest layer 1/1: qux");
}

void trace_test_fn(int n) {
  if (n == 0) return;
  new_trace_frame("foo");
  trace("foo") << "before: " << n;
  trace_test_fn(n-1);
  trace("foo") << "after: " << n;
}

void test_trace_keeps_level_together() {
  CHECK_TRACE_CONTENTS("foo", "");
  trace_test_fn(4);
  CHECK_TRACE_CONTENTS("foo", 2, "before: 3after: 3");
}

void test_trace_supports_multiple_layers() {
  trace("test layer 1") << "foo";
  trace("test layer 2") << "bar";
  trace("test layer 1") << "qux";
  CHECK_TRACE_CONTENTS("test layer 1,test layer 2", "foobarqux");
}

void test_trace_supports_hierarchical_layers() {
  trace("test layer/a") << "foo";
  trace("different layer/c") << "foo 2";
  trace("test layer/b") << "bar";
  CHECK_TRACE_CONTENTS("test layer/", "foobar");
}

void test_trace_supports_count() {
  trace("test layer 1") << "foo";
  trace("test layer 1") << "foo";
  CHECK_EQ(trace_count("test layer 1", "foo"), 2);
}

void test_trace_supports_count2() {
  trace("test layer 1") << "foo";
  trace("test layer 1") << "bar";
  CHECK_EQ(trace_count("test layer 1"), 2);
}

// pending: DUMP tests
// pending: readable_contents() adds newline if necessary.
// pending: raise also prints to stderr.
// pending: raise doesn't print to stderr if Hide_warnings is set.
// pending: raise doesn't have to be saved if Hide_warnings is set, just printed.
// pending: raise prints to stderr if Trace_stream is NULL.
// pending: raise prints to stderr if Trace_stream is NULL even if Hide_warnings is set.
// pending: raise << ... die() doesn't die if Hide_warnings is set.



// can't check trace because trace methods call 'split'

void test_split_returns_at_least_one_elem() {
  vector<string> result = split("", ",");
  CHECK_EQ(result.size(), 1);
  CHECK_EQ(result[0], "");
}

void test_split_returns_entire_input_when_no_delim() {
  vector<string> result = split("abc", ",");
  CHECK_EQ(result.size(), 1);
  CHECK_EQ(result[0], "abc");
}

void test_split_works() {
  vector<string> result = split("abc,def", ",");
  CHECK_EQ(result.size(), 2);
  CHECK_EQ(result[0], "abc");
  CHECK_EQ(result[1], "def");
}

void test_split_works2() {
  vector<string> result = split("abc,def,ghi", ",");
  CHECK_EQ(result.size(), 3);
  CHECK_EQ(result[0], "abc");
  CHECK_EQ(result[1], "def");
  CHECK_EQ(result[2], "ghi");
}

void test_split_handles_multichar_delim() {
  vector<string> result = split("abc,,def,,ghi", ",,");
  CHECK_EQ(result.size(), 3);
  CHECK_EQ(result[0], "abc");
  CHECK_EQ(result[1], "def");
  CHECK_EQ(result[2], "ghi");
}

                                                                                                                                                                                                                                                                                                                          


                                                                                                                                                                                                                                    



                                                                                                                               
                                                                                                                                                                                                                                                                                                                




                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                    
                                                                                                                                                                                               
                                                                                                                                                                                                                                               





                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                         




                                                                                                                                                                                                        


                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  



















                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                                                                                                                                                                                                                                              




                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                 

                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                           























                                                                                                                                                                                                                                                                                                                                                                                                                       




                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

























                                                                                                                                                                                                                                                                                                                                                                                                 



                                     
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 012elf.cc</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="cpp">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="minimal-light">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #000000; background-color: #c6c6c6; }
body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; }
a { color:inherit; }
* { font-size:12pt; font-size: 1em; }
.CommentedCode { color: #8a8a8a; }
.LineNr { }
.Normal { color: #000000; background-color: #c6c6c6; padding-bottom: 1px; }
.Comment { color: #005faf; }
.Delimiter { color: #c000c0; }
.Special { color: #d70000; }
.Identifier { color: #af5f00; }
.Constant { color: #008787; }
.PreProc { color: #c000c0; }
.cSpecial { color: #008000; }
-->
</style>

<script type='text/javascript'>
<!--

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<a href='https://github.com/akkartik/mu/blob/master/012elf.cc'>https://github.com/akkartik/mu/blob/master/012elf.cc</a>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr">  1 </span><span class="Comment">//: Loading SubX programs from ELF binaries.</span>
<span id="L2" class="LineNr">  2 </span><span class="Comment">//: This will allow us to run them natively on a Linux kernel.</span>
<span id="L3" class="LineNr">  3 </span><span class="Comment">//: Based on <a href="https://github.com/kragen/stoneknifeforth/blob/702d2ebe1b/386.c">https://github.com/kragen/stoneknifeforth/blob/702d2ebe1b/386.c</a></span>
<span id="L4" class="LineNr">  4 </span>
<span id="L5" class="LineNr">  5 </span><span class="Delimiter">:(before &quot;End Main&quot;)</span>
<span id="L6" class="LineNr">  6 </span>assert<span class="Delimiter">(</span>argc &gt; <span class="Constant">1</span><span class="Delimiter">);</span>
<span id="L7" class="LineNr">  7 </span><span class="Normal">if</span> <span class="Delimiter">(</span><a href='001help.cc.html#L96'>is_equal</a><span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
<span id="L8" class="LineNr">  8 </span>  <span class="Comment">// Outside of tests, traces must be explicitly requested.</span>
<span id="L9" class="LineNr">  9 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span><span class="Special"><a href='003trace.cc.html#L446'>Trace_file</a></span><span class="Delimiter">.</span>is_open<span class="Delimiter">())</span> <span class="Special"><a href='003trace.cc.html#L72'>Trace_stream</a></span> = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span>
<span id="L10" class="LineNr"> 10 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;=== Starting to run&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L11" class="LineNr"> 11 </span>  assert<span class="Delimiter">(</span>argc &gt; <span class="Constant">2</span><span class="Delimiter">);</span>
<span id="L12" class="LineNr"> 12 </span>  <a href='000organization.cc.html#L148'>reset</a><span class="Delimiter">();</span>
<span id="L13" class="LineNr"> 13 </span>  cerr &lt;&lt; std::hex<span class="Delimiter">;</span>
<span id="L14" class="LineNr"> 14 </span>  <a href='012elf.cc.html#L22'>load_elf</a><span class="Delimiter">(</span>argv[<span class="Constant">2</span>]<span class="Delimiter">,</span> argc<span class="Delimiter">,</span> argv<span class="Delimiter">);</span>
<span id="L15" class="LineNr"> 15 </span>  <span class="Normal">while</span> <span class="Delimiter">(</span><a href='010---vm.cc.html#L32'>EIP</a> &lt; <span class="Special"><a href='010---vm.cc.html#L163'>End_of_program</a></span><span class="Delimiter">)</span>  <span class="Comment">// weak final-gasp termination check</span>
<span id="L16" class="LineNr"> 16 </span>    <a href='010---vm.cc.html#L270'>run_one_instruction</a><span class="Delimiter">();</span>
<span id="L17" class="LineNr"> 17 </span>  <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;executed past end of the world: &quot;</span> &lt;&lt; <a href='010---vm.cc.html#L32'>EIP</a> &lt;&lt; <span class="Constant">&quot; vs &quot;</span> &lt;&lt; <span class="Special"><a href='010---vm.cc.html#L163'>End_of_program</a></span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L18" class="LineNr"> 18 </span>  <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span>
<span id="L19" class="LineNr"> 19 </span><span class="Delimiter">}</span>
<span id="L20" class="LineNr"> 20 </span>
<span id="L21" class="LineNr"> 21 </span><span class="Delimiter">:(code)</span>
<span id="L22" class="LineNr"> 22 </span><span class="Normal">void</span> <a href='012elf.cc.html#L22'>load_elf</a><span class="Delimiter">(</span><span class="Normal">const</span> string&amp; filename<span class="Delimiter">,</span> <span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L23" class="LineNr"> 23 </span>  <span class="Normal">int</span> fd = open<span class="Delimiter">(</span>filename<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> O_RDONLY<span class="Delimiter">);</span>
<span id="L24" class="LineNr"> 24 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>fd &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; filename<span class="Delimiter">.</span>c_str<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: open&quot;</span> &lt;&lt; <a href='012elf.cc.html#L177'>perr</a><span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L25" class="LineNr"> 25 </span>  <span class="Normal">off_t</span> size = lseek<span class="Delimiter">(</span>fd<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">SEEK_END</span><span class="Delimiter">);</span>
<span id="L26" class="LineNr"> 26 </span>  lseek<span class="Delimiter">(</span>fd<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">SEEK_SET</span><span class="Delimiter">);</span>
<span id="L27" class="LineNr"> 27 </span>  <span class="Normal">uint8_t</span>* elf_contents = <span class="Normal">static_cast</span>&lt;<span class="Normal">uint8_t</span>*&gt;<span class="Delimiter">(</span>malloc<span class="Delimiter">(</span>size<span class="Delimiter">));</span>
<span id="L28" class="LineNr"> 28 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>elf_contents == <span class="Constant">NULL</span><span class="Delimiter">)</span> <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;malloc(&quot;</span> &lt;&lt; size &lt;&lt; <span class="Constant">')'</span> &lt;&lt; <a href='012elf.cc.html#L177'>perr</a><span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L29" class="LineNr"> 29 </span>  <span class="Normal">ssize_t</span> read_size = read<span class="Delimiter">(</span>fd<span class="Delimiter">,</span> elf_contents<span class="Delimiter">,</span> size<span class="Delimiter">);</span>
<span id="L30" class="LineNr"> 30 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>size != read_size<span class="Delimiter">)</span> <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;read → &quot;</span> &lt;&lt; size &lt;&lt; <span class="Constant">&quot; (!= &quot;</span> &lt;&lt; read_size &lt;&lt; <span class="Constant">')'</span> &lt;&lt; <a href='012elf.cc.html#L177'>perr</a><span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L31" class="LineNr"> 31 </span>  <a href='012elf.cc.html#L35'>load_elf_contents</a><span class="Delimiter">(</span>elf_contents<span class="Delimiter">,</span> size<span class="Delimiter">,</span> argc<span class="Delimiter">,</span> argv<span class="Delimiter">);</span>
<span id="L32" class="LineNr"> 32 </span>  free<span class="Delimiter">(</span>elf_contents<span class="Delimiter">);</span>
<span id="L33" class="LineNr"> 33 </span><span class="Delimiter">}</span>
<span id="L34" class="LineNr"> 34 </span>
<span id="L35" class="LineNr"> 35 </span><span class="Normal">void</span> <a href='012elf.cc.html#L35'>load_elf_contents</a><span class="Delimiter">(</span><span class="Normal">uint8_t</span>* elf_contents<span class="Delimiter">,</span> <span class="Normal">size_t</span> size<span class="Delimiter">,</span> <span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L36" class="LineNr"> 36 </span>  <span class="Normal">uint8_t</span> magic[<span class="Constant">5</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span>
<span id="L37" class="LineNr"> 37 </span>  memcpy<span class="Delimiter">(</span>magic<span class="Delimiter">,</span> elf_contents<span class="Delimiter">,</span> <span class="Constant">4</span><span class="Delimiter">);</span>
<span id="L38" class="LineNr"> 38 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>memcmp<span class="Delimiter">(</span>magic<span class="Delimiter">,</span> <span class="Constant">&quot;\177ELF&quot;</span><span class="Delimiter">,</span> <span class="Constant">4</span><span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span>
<span id="L39" class="LineNr"> 39 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Invalid ELF file; starts with \&quot;&quot; &lt;&lt; magic &lt;&lt; '&quot;</span>' &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L40" class="LineNr"> 40 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>elf_contents[<span class="Constant">4</span>] != <span class="Constant">1</span><span class="Delimiter">)</span>
<span id="L41" class="LineNr"> 41 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Only 32-bit ELF files (4-byte words; virtual addresses up to 4GB) supported.\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L42" class="LineNr"> 42 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>elf_contents[<span class="Constant">5</span>] != <span class="Constant">1</span><span class="Delimiter">)</span>
<span id="L43" class="LineNr"> 43 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Only little-endian ELF files supported.\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L44" class="LineNr"> 44 </span>  <span class="Comment">// unused: remaining 10 bytes of e_ident</span>
<span id="L45" class="LineNr"> 45 </span>  <span class="Normal">uint32_t</span> e_machine_type = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[<span class="Constant">16</span>]<span class="Delimiter">);</span>
<span id="L46" class="LineNr"> 46 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>e_machine_type != <span class="Constant">0x00030002</span><span class="Delimiter">)</span>
<span id="L47" class="LineNr"> 47 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;ELF type/machine 0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; e_machine_type &lt;&lt; <span class="Constant">&quot; isn't i386 executable\n&quot;</span> &lt;&lt; die<span class="Delimiter">();</span>
<span id="L48" class="LineNr"> 48 </span>  <span class="Comment">// unused: e_version. We only support version 1, and later versions will be backwards compatible.</span>
<span id="L49" class="LineNr"> 49 </span>  <span class="Normal">uint32_t</span> e_entry = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[<span class="Constant">24</span>]<span class="Delimiter">);</span>
<span id="L50" class="LineNr"> 50 </span>  <span class="Normal">uint32_t</span> e_phoff = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[<span class="Constant">28</span>]<span class="Delimiter">);</span>
<span id="L51" class="LineNr"> 51 </span>  <span class="Comment">// unused: e_shoff</span>
<span id="L52" class="LineNr"> 52 </span>  <span class="Comment">// unused: e_flags</span>
<span id="L53" class="LineNr"> 53 </span>  <span class="Normal">uint32_t</span> e_ehsize = <a href='012elf.cc.html#L172'>u16_in</a><span class="Delimiter">(</span>&amp;elf_contents[<span class="Constant">40</span>]<span class="Delimiter">);</span>
<span id="L54" class="LineNr"> 54 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>e_ehsize &lt; <span class="Constant">52</span><span class="Delimiter">)</span> <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Invalid binary; ELF header too small\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L55" class="LineNr"> 55 </span>  <span class="Normal">uint32_t</span> e_phentsize = <a href='012elf.cc.html#L172'>u16_in</a><span class="Delimiter">(</span>&amp;elf_contents[<span class="Constant">42</span>]<span class="Delimiter">);</span>
<span id="L56" class="LineNr"> 56 </span>  <span class="Normal">uint32_t</span> e_phnum = <a href='012elf.cc.html#L172'>u16_in</a><span class="Delimiter">(</span>&amp;elf_contents[<span class="Constant">44</span>]<span class="Delimiter">);</span>
<span id="L57" class="LineNr"> 57 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Constant">90</span><span class="Delimiter">,</span> <span class="Constant">&quot;load&quot;</span><span class="Delimiter">)</span> &lt;&lt; e_phnum &lt;&lt; <span class="Constant">&quot; entries in the program header, each &quot;</span> &lt;&lt; e_phentsize &lt;&lt; <span class="Constant">&quot; bytes long&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L58" class="LineNr"> 58 </span>  <span class="Comment">// unused: e_shentsize</span>
<span id="L59" class="LineNr"> 59 </span>  <span class="Comment">// unused: e_shnum</span>
<span id="L60" class="LineNr"> 60 </span>  <span class="Comment">// unused: e_shstrndx</span>
<span id="L61" class="LineNr"> 61 </span>
<span id="L62" class="LineNr"> 62 </span>  set&lt;<span class="Normal">uint32_t</span>&gt; overlap<span class="Delimiter">;</span>  <span class="Comment">// to detect overlapping segments</span>
<span id="L63" class="LineNr"> 63 </span>  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">size_t</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; e_phnum<span class="Delimiter">;</span>  ++i<span class="Delimiter">)</span>
<span id="L64" class="LineNr"> 64 </span>    <a href='012elf.cc.html#L105'>load_segment_from_program_header</a><span class="Delimiter">(</span>elf_contents<span class="Delimiter">,</span> i<span class="Delimiter">,</span> size<span class="Delimiter">,</span> e_phoff + i*e_phentsize<span class="Delimiter">,</span> e_ehsize<span class="Delimiter">,</span> overlap<span class="Delimiter">);</span>
<span id="L65" class="LineNr"> 65 </span>
<span id="L66" class="LineNr"> 66 </span>  <span class="Comment">// initialize code and stack</span>
<span id="L67" class="LineNr"> 67 </span>  assert<span class="Delimiter">(</span>overlap<span class="Delimiter">.</span>find<span class="Delimiter">(</span><a href='012elf.cc.html#L150'>STACK_SEGMENT</a><span class="Delimiter">)</span> == overlap<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
<span id="L68" class="LineNr"> 68 </span>  <span class="Special"><a href='010---vm.cc.html#L160'>Mem</a></span><span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>vma<span class="Delimiter">(</span><a href='012elf.cc.html#L150'>STACK_SEGMENT</a><span class="Delimiter">));</span>
<span id="L69" class="LineNr"> 69 </span>  assert<span class="Delimiter">(</span>overlap<span class="Delimiter">.</span>find<span class="Delimiter">(</span><a href='012elf.cc.html#L151'>AFTER_STACK</a><span class="Delimiter">)</span> == overlap<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
<span id="L70" class="LineNr"> 70 </span>  <span class="Comment">// The stack grows downward.</span>
<span id="L71" class="LineNr"> 71 </span>  <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u = <a href='012elf.cc.html#L151'>AFTER_STACK</a><span class="Delimiter">;</span>
<span id="L72" class="LineNr"> 72 </span>  <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[EBP]<span class="Delimiter">.</span>u = <span class="Constant">0</span><span class="Delimiter">;</span>
<span id="L73" class="LineNr"> 73 </span>  <a href='010---vm.cc.html#L32'>EIP</a> = e_entry<span class="Delimiter">;</span>
<span id="L74" class="LineNr"> 74 </span>
<span id="L75" class="LineNr"> 75 </span>  <span class="Comment">// initialize args on stack</span>
<span id="L76" class="LineNr"> 76 </span>  <span class="Comment">// no envp for now</span>
<span id="L77" class="LineNr"> 77 </span>  <span class="Comment">// we wastefully use a separate page of memory for argv</span>
<span id="L78" class="LineNr"> 78 </span>  <span class="Special"><a href='010---vm.cc.html#L160'>Mem</a></span><span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>vma<span class="Delimiter">(</span><a href='012elf.cc.html#L152'>ARGV_DATA_SEGMENT</a><span class="Delimiter">));</span>
<span id="L79" class="LineNr"> 79 </span>  <span class="Normal">uint32_t</span> argv_data = <a href='012elf.cc.html#L152'>ARGV_DATA_SEGMENT</a><span class="Delimiter">;</span>
<span id="L80" class="LineNr"> 80 </span>  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = argc-<span class="Constant">1</span><span class="Delimiter">;</span>  i &gt;= <span class="Comment">/*</span><span class="Comment">skip 'subx_bin' and 'run'</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span>  --i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L81" class="LineNr"> 81 </span>    <a href='012elf.cc.html#L92'>push</a><span class="Delimiter">(</span>argv_data<span class="Delimiter">);</span>
<span id="L82" class="LineNr"> 82 </span>    <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">size_t</span> j = <span class="Constant">0</span><span class="Delimiter">;</span>  j &lt;= strlen<span class="Delimiter">(</span>argv[i]<span class="Delimiter">);</span>  ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L83" class="LineNr"> 83 </span>      assert<span class="Delimiter">(</span>overlap<span class="Delimiter">.</span>find<span class="Delimiter">(</span>argv_data<span class="Delimiter">)</span> == overlap<span class="Delimiter">.</span>end<span class="Delimiter">());</span>  <span class="Comment">// don't bother comparing ARGV and STACK</span>
<span id="L84" class="LineNr"> 84 </span>      <a href='010---vm.cc.html#L237'>write_mem_u8</a><span class="Delimiter">(</span>argv_data<span class="Delimiter">,</span> argv[i][j]<span class="Delimiter">);</span>
<span id="L85" class="LineNr"> 85 </span>      argv_data += <span class="Normal">sizeof</span><span class="Delimiter">(</span><span class="Normal">char</span><span class="Delimiter">);</span>
<span id="L86" class="LineNr"> 86 </span>      assert<span class="Delimiter">(</span>argv_data &lt; <a href='012elf.cc.html#L152'>ARGV_DATA_SEGMENT</a> + <a href='010---vm.cc.html#L95'>SEGMENT_ALIGNMENT</a><span class="Delimiter">);</span>
<span id="L87" class="LineNr"> 87 </span>    <span class="Delimiter">}</span>
<span id="L88" class="LineNr"> 88 </span>  <span class="Delimiter">}</span>
<span id="L89" class="LineNr"> 89 </span>  <a href='012elf.cc.html#L92'>push</a><span class="Delimiter">(</span>argc-<span class="Comment">/*</span><span class="Comment">skip 'subx_bin' and 'run'</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">);</span>
<span id="L90" class="LineNr"> 90 </span><span class="Delimiter">}</span>
<span id="L91" class="LineNr"> 91 </span>
<span id="L92" class="LineNr"> 92 </span><span class="Normal">void</span> <a href='012elf.cc.html#L92'>push</a><span class="Delimiter">(</span><span class="Normal">uint32_t</span> val<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L93" class="LineNr"> 93 </span>  <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u -= <span class="Constant">4</span><span class="Delimiter">;</span>
<span id="L94" class="LineNr"> 94 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span><span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u &lt; <a href='012elf.cc.html#L150'>STACK_SEGMENT</a><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L95" class="LineNr"> 95 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;The stack overflowed its segment. &quot;</span>
<span id="L96" class="LineNr"> 96 </span>          &lt;&lt; <span class="Constant">&quot;Maybe SPACE_FOR_SEGMENT should be larger? &quot;</span>
<span id="L97" class="LineNr"> 97 </span>          &lt;&lt; <span class="Constant">&quot;Or you need to carve out an exception for the stack segment &quot;</span>
<span id="L98" class="LineNr"> 98 </span>          &lt;&lt; <span class="Constant">&quot;to be larger.\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L99" class="LineNr"> 99 </span>  <span class="Delimiter">}</span>
<span id="L100" class="LineNr">100 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;decrementing <a href='010---vm.cc.html#L20'>ESP</a> to 0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u &lt;&lt; end<span class="Delimiter">();</span>
<span id="L101" class="LineNr">101 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;pushing value 0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; val &lt;&lt; end<span class="Delimiter">();</span>
<span id="L102" class="LineNr">102 </span>  <a href='010---vm.cc.html#L245'>write_mem_u32</a><span class="Delimiter">(</span><span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u<span class="Delimiter">,</span> val<span class="Delimiter">);</span>
<span id="L103" class="LineNr">103 </span><span class="Delimiter">}</span>
<span id="L104" class="LineNr">104 </span>
<span id="L105" class="LineNr">105 </span><span class="Normal">void</span> <a href='012elf.cc.html#L105'>load_segment_from_program_header</a><span class="Delimiter">(</span><span class="Normal">uint8_t</span>* elf_contents<span class="Delimiter">,</span> <span class="Normal">int</span> segment_index<span class="Delimiter">,</span> <span class="Normal">size_t</span> size<span class="Delimiter">,</span> <span class="Normal">uint32_t</span> offset<span class="Delimiter">,</span> <span class="Normal">uint32_t</span> e_ehsize<span class="Delimiter">,</span> set&lt;<span class="Normal">uint32_t</span>&gt;&amp; overlap<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L106" class="LineNr">106 </span>  <span class="Normal">uint32_t</span> p_type = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[offset]<span class="Delimiter">);</span>
<span id="L107" class="LineNr">107 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Constant">90</span><span class="Delimiter">,</span> <span class="Constant">&quot;load&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;program header at offset &quot;</span> &lt;&lt; offset &lt;&lt; <span class="Constant">&quot;: type &quot;</span> &lt;&lt; p_type &lt;&lt; end<span class="Delimiter">();</span>
<span id="L108" class="LineNr">108 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>p_type != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L109" class="LineNr">109 </span>    <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Constant">90</span><span class="Delimiter">,</span> <span class="Constant">&quot;load&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;ignoring segment at offset &quot;</span> &lt;&lt; offset &lt;&lt; <span class="Constant">&quot; of non PT_LOAD type &quot;</span> &lt;&lt; p_type &lt;&lt; <span class="Constant">&quot; (see <a href="http://refspecs.linuxbase.org/elf/elf.pdf">http://refspecs.linuxbase.org/elf/elf.pdf</a>)&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L110" class="LineNr">110 </span>    <span class="Identifier">return</span><span class="Delimiter">;</span>
<span id="L111" class="LineNr">111 </span>  <span class="Delimiter">}</span>
<span id="L112" class="LineNr">112 </span>  <span class="Normal">uint32_t</span> p_offset = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[offset + <span class="Constant">4</span>]<span class="Delimiter">);</span>
<span id="L113" class="LineNr">113 </span>  <span class="Normal">uint32_t</span> p_vaddr = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[offset + <span class="Constant">8</span>]<span class="Delimiter">);</span>
<span id="L114" class="LineNr">114 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>e_ehsize &gt; p_vaddr<span class="Delimiter">)</span> <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Invalid binary; program header overlaps ELF header\n&quot;</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L115" class="LineNr">115 </span>  <span class="Comment">// unused: p_paddr</span>
<span id="L116" class="LineNr">116 </span>  <span class="Normal">uint32_t</span> p_filesz = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[offset + <span class="Constant">16</span>]<span class="Delimiter">);</span>
<span id="L117" class="LineNr">117 </span>  <span class="Normal">uint32_t</span> p_memsz = <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span>&amp;elf_contents[offset + <span class="Constant">20</span>]<span class="Delimiter">);</span>
<span id="L118" class="LineNr">118 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>p_filesz != p_memsz<span class="Delimiter">)</span>
<span id="L119" class="LineNr">119 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Can't yet handle segments where p_filesz != p_memsz (see <a href="http://refspecs.linuxbase.org/elf/elf.pdf">http://refspecs.linuxbase.org/elf/elf.pdf</a>)\n&quot;</span> &lt;&lt; die<span class="Delimiter">();</span>
<span id="L120" class="LineNr">120 </span>
<span id="L121" class="LineNr">121 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>p_offset + p_filesz &gt; size<span class="Delimiter">)</span>
<span id="L122" class="LineNr">122 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Invalid binary; segment at offset &quot;</span> &lt;&lt; offset &lt;&lt; <span class="Constant">&quot; is too large: wants to end at &quot;</span> &lt;&lt; p_offset+p_filesz &lt;&lt; <span class="Constant">&quot; but the file ends at &quot;</span> &lt;&lt; size &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; <a href='003trace.cc.html#L173'>die</a><span class="Delimiter">();</span>
<span id="L123" class="LineNr">123 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>p_memsz &gt;= <a href='010---vm.cc.html#L95'>SEGMENT_ALIGNMENT</a><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L124" class="LineNr">124 </span>    <a href='003trace.cc.html#L226'>raise</a> &lt;&lt; <span class="Constant">&quot;Code segment too small for SubX; for now please manually increase SEGMENT_ALIGNMENT.\n&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L125" class="LineNr">125 </span>    <span class="Identifier">return</span><span class="Delimiter">;</span>
<span id="L126" class="LineNr">126 </span>  <span class="Delimiter">}</span>
<span id="L127" class="LineNr">127 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Constant">90</span><span class="Delimiter">,</span> <span class="Constant">&quot;load&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;blitting file offsets (&quot;</span> &lt;&lt; p_offset &lt;&lt; <span class="Constant">&quot;, &quot;</span> &lt;&lt; <span class="Delimiter">(</span>p_offset+p_filesz<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;) to addresses (&quot;</span> &lt;&lt; p_vaddr &lt;&lt; <span class="Constant">&quot;, &quot;</span> &lt;&lt; <span class="Delimiter">(</span>p_vaddr+p_memsz<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">')'</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L128" class="LineNr">128 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>size &gt; p_memsz<span class="Delimiter">)</span> size = p_memsz<span class="Delimiter">;</span>
<span id="L129" class="LineNr">129 </span>  <span class="Special"><a href='010---vm.cc.html#L160'>Mem</a></span><span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>vma<span class="Delimiter">(</span>p_vaddr<span class="Delimiter">));</span>
<span id="L130" class="LineNr">130 </span>  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">size_t</span> i = <span class="Constant">0</span><span class="Delimiter">;</span>  i &lt; p_filesz<span class="Delimiter">;</span>  ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L131" class="LineNr">131 </span>    assert<span class="Delimiter">(</span>overlap<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p_vaddr+i<span class="Delimiter">)</span> == overlap<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
<span id="L132" class="LineNr">132 </span>    <a href='010---vm.cc.html#L237'>write_mem_u8</a><span class="Delimiter">(</span>p_vaddr+i<span class="Delimiter">,</span> elf_contents[p_offset+i]<span class="Delimiter">);</span>
<span id="L133" class="LineNr">133 </span>    overlap<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>p_vaddr+i<span class="Delimiter">);</span>
<span id="L134" class="LineNr">134 </span>  <span class="Delimiter">}</span>
<span id="L135" class="LineNr">135 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>segment_index == <span class="Constant">0</span> &amp;&amp; <span class="Special"><a href='010---vm.cc.html#L163'>End_of_program</a></span> &lt; p_vaddr+p_memsz<span class="Delimiter">)</span>
<span id="L136" class="LineNr">136 </span>    <span class="Special"><a href='010---vm.cc.html#L163'>End_of_program</a></span> = p_vaddr+p_memsz<span class="Delimiter">;</span>
<span id="L137" class="LineNr">137 </span><span class="Delimiter">}</span>
<span id="L138" class="LineNr">138 </span>
<span id="L139" class="LineNr">139 </span><span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span id="L140" class="LineNr">140 </span><span class="Comment">// Very primitive/fixed/insecure ELF segments for now.</span>
<span id="L141" class="LineNr">141 </span><span class="Comment">//   --- inaccessible:        0x00000000 -&gt; 0x08047fff</span>
<span id="L142" class="LineNr">142 </span><span class="Comment">//   code:                    0x09000000 -&gt; 0x09ffffff (specified in ELF binary)</span>
<span id="L143" class="LineNr">143 </span><span class="Comment">//   data:                    0x0a000000 -&gt; 0x0affffff (specified in ELF binary)</span>
<span id="L144" class="LineNr">144 </span><span class="Comment">//                      --- heap gets mmap'd somewhere here ---</span>
<span id="L145" class="LineNr">145 </span><span class="Comment">//   stack:                   0xbdffffff -&gt; 0xbd000000 (downward; not in ELF binary)</span>
<span id="L146" class="LineNr">146 </span><span class="Comment">//   argv hack:               0xbf000000 -&gt; 0xbfffffff (not in ELF binary)</span>
<span id="L147" class="LineNr">147 </span><span class="Comment">//   --- reserved for kernel: 0xc0000000 -&gt; ...</span>
<span id="L148" class="LineNr">148 </span><span class="Normal">const</span> <span class="Normal">uint32_t</span> <a href='012elf.cc.html#L148'>START_HEAP</a>        = <span class="Constant">0x0b000000</span><span class="Delimiter">;</span>
<span id="L149" class="LineNr">149 </span><span class="Normal">const</span> <span class="Normal">uint32_t</span> <a href='012elf.cc.html#L149'>END_HEAP</a>          = <span class="Constant">0xbd000000</span><span class="Delimiter">;</span>
<span id="L150" class="LineNr">150 </span><span class="Normal">const</span> <span class="Normal">uint32_t</span> <a href='012elf.cc.html#L150'>STACK_SEGMENT</a>     = <span class="Constant">0xbd000000</span><span class="Delimiter">;</span>
<span id="L151" class="LineNr">151 </span><span class="Normal">const</span> <span class="Normal">uint32_t</span> <a href='012elf.cc.html#L151'>AFTER_STACK</a>       = <span class="Constant">0xbe000000</span><span class="Delimiter">;</span>
<span id="L152" class="LineNr">152 </span><span class="Normal">const</span> <span class="Normal">uint32_t</span> <a href='012elf.cc.html#L152'>ARGV_DATA_SEGMENT</a> = <span class="Constant">0xbf000000</span><span class="Delimiter">;</span>
<span id="L153" class="LineNr">153 </span><span class="Comment">// When updating the above memory map, don't forget to update `mmap`'s</span>
<span id="L154" class="LineNr">154 </span><span class="Comment">// implementation in the 'syscalls' layer.</span>
<span id="L155" class="LineNr">155 </span><span class="Delimiter">:(before &quot;End Dump Info for Instruction&quot;)</span>
<span id="L156" class="LineNr">156 </span><span class="CommentedCode">//? dump_stack();  // slow</span>
<span id="L157" class="LineNr">157 </span><span class="Delimiter">:(code)</span>
<span id="L158" class="LineNr">158 </span><span class="Normal">void</span> <a href='012elf.cc.html#L158'>dump_stack</a><span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span id="L159" class="LineNr">159 </span>  ostringstream out<span class="Delimiter">;</span>
<span id="L160" class="LineNr">160 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;stack:&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L161" class="LineNr">161 </span>  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">uint32_t</span> a = AFTER_STACK-<span class="Constant">4</span><span class="Delimiter">;</span>  a &gt; <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u<span class="Delimiter">;</span>  a -= <span class="Constant">4</span><span class="Delimiter">)</span>
<span id="L162" class="LineNr">162 </span>    <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; a &lt;&lt; <span class="Constant">&quot; =&gt; 0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; <a href='010---vm.cc.html#L178'>read_mem_u32</a><span class="Delimiter">(</span>a<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L163" class="LineNr">163 </span>  <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u &lt;&lt; <span class="Constant">&quot; =&gt; 0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; <a href='010---vm.cc.html#L178'>read_mem_u32</a><span class="Delimiter">(</span><span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  &lt;=== ESP&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L164" class="LineNr">164 </span>  <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">uint32_t</span> a = <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u-<span class="Constant">4</span><span class="Delimiter">;</span>  a &gt; <span class="Special"><a href='010---vm.cc.html#L31'>Reg</a></span>[ESP]<span class="Delimiter">.</span>u-<span class="Constant">40</span><span class="Delimiter">;</span>  a -= <span class="Constant">4</span><span class="Delimiter">)</span>
<span id="L165" class="LineNr">165 </span>    <a href='003trace.cc.html#L96'>trace</a><span class="Delimiter">(</span><span class="Special">Callstack_depth</span>+<span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; a &lt;&lt; <span class="Constant">&quot; =&gt; 0x&quot;</span> &lt;&lt; <a href='010---vm.cc.html#L401'>HEXWORD</a> &lt;&lt; <a href='010---vm.cc.html#L178'>read_mem_u32</a><span class="Delimiter">(</span>a<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
<span id="L166" class="LineNr">166 </span><span class="Delimiter">}</span>
<span id="L167" class="LineNr">167 </span>
<span id="L168" class="LineNr">168 </span><span class="Normal">inline</span> <span class="Normal">uint32_t</span> <a href='012elf.cc.html#L168'>u32_in</a><span class="Delimiter">(</span><span class="Normal">uint8_t</span>* p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L169" class="LineNr">169 </span>  <span class="Identifier">return</span> p[<span class="Constant">0</span>] | p[<span class="Constant">1</span>] &lt;&lt; <span class="Constant">8</span> | p[<span class="Constant">2</span>] &lt;&lt; <span class="Constant">16</span> | p[<span class="Constant">3</span>] &lt;&lt; <span class="Constant">24</span><span class="Delimiter">;</span>
<span id="L170" class="LineNr">170 </span><span class="Delimiter">}</span>
<span id="L171" class="LineNr">171 </span>
<span id="L172" class="LineNr">172 </span><span class="Normal">inline</span> <span class="Normal">uint16_t</span> <a href='012elf.cc.html#L172'>u16_in</a><span class="Delimiter">(</span><span class="Normal">uint8_t</span>* p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L173" class="LineNr">173 </span>  <span class="Identifier">return</span> p[<span class="Constant">0</span>] | p[<span class="Constant">1</span>] &lt;&lt; <span class="Constant">8</span><span class="Delimiter">;</span>
<span id="L174" class="LineNr">174 </span><span class="Delimiter">}</span>
<span id="L175" class="LineNr">175 </span>
<span id="L176" class="LineNr">176 </span><span class="Delimiter">:(before &quot;End Types&quot;)</span>
<span id="L177" class="LineNr">177 </span><span class="Normal">struct</span> <a href='012elf.cc.html#L177'>perr</a> <span class="Delimiter">{};</span>
<span id="L178" class="LineNr">178 </span><span class="Delimiter">:(code)</span>
<span id="L179" class="LineNr">179 </span>ostream&amp; <span class="Normal">operator</span>&lt;&lt;<span class="Delimiter">(</span>ostream&amp; os<span class="Delimiter">,</span> <a href='012elf.cc.html#L177'>perr</a> <span class="Comment">/*</span><span class="Comment">unused</span><span class="Comment">*/</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span id="L180" class="LineNr">180 </span>  <span class="Normal">if</span> <span class="Delimiter">(</span>errno<span class="Delimiter">)</span>
<span id="L181" class="LineNr">181 </span>    os &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; strerror<span class="Delimiter">(</span>errno<span class="Delimiter">);</span>
<span id="L182" class="LineNr">182 </span>  <span class="Identifier">return</span> os<span class="Delimiter">;</span>
<span id="L183" class="LineNr">183 </span><span class="Delimiter">}</span>
<span id="L184" class="LineNr">184 </span>
<span id="L185" class="LineNr">185 </span><span class="Delimiter">:(before &quot;End Includes&quot;)</span>
<span id="L186" class="LineNr">186 </span><span class="PreProc">#include </span><span class="Constant">&lt;sys/types.h&gt;</span>
<span id="L187" class="LineNr">187 </span><span class="PreProc">#include </span><span class="Constant">&lt;sys/stat.h&gt;</span>
<span id="L188" class="LineNr">188 </span><span class="PreProc">#include </span><span class="Constant">&lt;fcntl.h&gt;</span>
<span id="L189" class="LineNr">189 </span><span class="PreProc">#include </span><span class="Constant">&lt;stdarg.h&gt;</span>
<span id="L190" class="LineNr">190 </span><span class="PreProc">#include </span><span class="Constant">&lt;errno.h&gt;</span>
<span id="L191" class="LineNr">191 </span><span class="PreProc">#include </span><span class="Constant">&lt;unistd.h&gt;</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->