about summary refs log tree commit diff stats
path: root/linux/bootstrap/029syscalls.cc
blob: 84a6af34a5435d83e80466d70b0616e99cc1cec2 (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
:(before "End Initialize Op Names")
put_new(Name, "cd", "software interrupt (int)");

:(before "End Single-Byte Opcodes")
case 0xcd: {  // int imm8 (software interrupt)
  trace(Callstack_depth+1, "run") << "syscall" << end();
  uint8_t code = next();
  if (code != 0x80) {
    raise << "Unimplemented interrupt code " << HEXBYTE << code << '\n' << end();
    raise << "  Only `int 80h` supported for now.\n" << end();
    break;
  }
  process_int80();
  break;
}

:(code)
void process_int80() {
  switch (Reg[EAX].u) {
  case 1:
    exit(/*exit code*/Reg[EBX].u);
    break;
  case 3:
    trace(Callstack_depth+1, "run") << "read: " << Reg[EBX].u << ' ' << Reg[ECX].u << ' ' << Reg[EDX].u << end();
    Reg[EAX].i = read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u);
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "read: " << strerror(errno) << '\n' << end();
    break;
  case 4:
    trace(Callstack_depth+1, "run") << "write: " << Reg[EBX].u << ' ' << Reg[ECX].u << ' ' << Reg[EDX].u << end();
    trace(Callstack_depth+1, "run") << Reg[ECX].u << " => " << mem_addr_string(Reg[ECX].u, Reg[EDX].u) << end();
    Reg[EAX].i = write(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u);
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "write: " << strerror(errno) << '\n' << end();
    break;
  case 5: {
    check_flags(ECX);
    check_mode(EDX);
    trace(Callstack_depth+1, "run") << "open: " << Reg[EBX].u << ' ' << Reg[ECX].u << end();
    trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end();
    Reg[EAX].i = open(/*filename*/mem_addr_kernel_string(Reg[EBX].u), /*flags*/Reg[ECX].u, /*mode*/0640);
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "open: " << strerror(errno) << '\n' << end();
    break;
  }
  case 6:
    trace(Callstack_depth+1, "run") << "close: " << Reg[EBX].u << end();
    Reg[EAX].i = close(/*file descriptor*/Reg[EBX].u);
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "close: " << strerror(errno) << '\n' << end();
    break;
  case 8:
    check_mode(ECX);
    trace(Callstack_depth+1, "run") << "creat: " << Reg[EBX].u << end();
    trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end();
    Reg[EAX].i = creat(/*filename*/mem_addr_kernel_string(Reg[EBX].u), /*mode*/0640);
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "creat: " << strerror(errno) << '\n' << end();
    break;
  case 10:
    trace(Callstack_depth+1, "run") << "unlink: " << Reg[EBX].u << end();
    trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end();
    Reg[EAX].i = unlink(/*filename*/mem_addr_kernel_string(Reg[EBX].u));
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "unlink: " << strerror(errno) << '\n' << end();
    break;
  case 38:
    trace(Callstack_depth+1, "run") << "rename: " << Reg[EBX].u << " -> " << Reg[ECX].u << end();
    trace(Callstack_depth+1, "run") << Reg[EBX].u << " => " << mem_addr_kernel_string(Reg[EBX].u) << end();
    trace(Callstack_depth+1, "run") << Reg[ECX].u << " => " << mem_addr_kernel_string(Reg[ECX].u) << end();
    Reg[EAX].i = rename(/*old filename*/mem_addr_kernel_string(Reg[EBX].u), /*new filename*/mem_addr_kernel_string(Reg[ECX].u));
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].i << end();
    if (Reg[EAX].i == -1) raise << "rename: " << strerror(errno) << '\n' << end();
    break;
  case 90:  // mmap: allocate memory outside existing segment allocations
    trace(Callstack_depth+1, "run") << "mmap: allocate new segment" << end();
    // Ignore most arguments for now: address hint, protection flags, sharing flags, fd, offset.
    // We only support anonymous maps.
    Reg[EAX].u = new_segment(/*length*/read_mem_u32(Reg[EBX].u+0x4));
    trace(Callstack_depth+1, "run") << "result: " << Reg[EAX].u << end();
    break;
  case 0xa2:  // nanosleep
    cerr << "not sleeping\n";
    break;
  default:
    raise << HEXWORD << EIP << ": unimplemented syscall " << Reg[EAX].u << '\n' << end();
  }
}

// SubX is oblivious to file permissions, directories, symbolic links, terminals, and much else besides.
// Also ignoring any concurrency considerations for now.
void check_flags(int reg) {
  uint32_t flags = Reg[reg].u;
  if (flags != ((flags & O_RDONLY) | (flags & O_WRONLY))) {
    cerr << HEXWORD << EIP << ": most POSIX flags to the open() syscall are not supported. Just O_RDONLY and O_WRONLY for now. Zero concurrent access support.\n";
    exit(1);
  }
  if ((flags & O_RDONLY) && (flags & O_WRONLY)) {
    cerr << HEXWORD << EIP << ": can't open a file for both reading and writing at once. See http://man7.org/linux/man-pages/man2/open.2.html.\n";
    exit(1);
  }
}

void check_mode(int reg) {
  if (Reg[reg].u != 0600) {
    cerr << HEXWORD << EIP << ": SubX is oblivious to file permissions; register " << reg << " must be 0x180.\n";
    exit(1);
  }
}

:(before "End Globals")
// Very primitive/fixed/insecure mmap segments for now.
uint32_t Segments_allocated_above = END_HEAP;
:(code)
// always allocate multiples of the segment size
uint32_t new_segment(uint32_t length) {
  assert(length > 0);
  uint32_t result = (Segments_allocated_above - length) & 0xff000000;  // same number of zeroes as SEGMENT_ALIGNMENT
  if (result <= START_HEAP) {
    raise << "Allocated too many segments; the VM ran out of memory. "
          << "Maybe SEGMENT_ALIGNMENT can be smaller?\n" << die();
  }
  Mem.push_back(vma(result, result+length));
  Segments_allocated_above = result;
  return result;
}
click-row:number<span class="Special"> &lt;- </span>get t, <span class="Constant">row:offset</span> below-sandbox-editor?:boolean<span class="Special"> &lt;- </span>greater-or-equal click-row, first-sandbox-begins <span class="muControl">break-unless</span> below-sandbox-editor? <span class="Comment"># identify the sandbox whose output is being clicked on</span> sandbox:address:sandbox-data<span class="Special"> &lt;- </span>find-click-in-sandbox-output env, click-row <span class="muControl">break-unless</span> sandbox <span class="Comment"># toggle its expected-response, and save session</span> sandbox<span class="Special"> &lt;- </span>toggle-expected-response sandbox save-sandboxes env hide-screen screen screen<span class="Special"> &lt;- </span>render-sandbox-side screen, env, render screen<span class="Special"> &lt;- </span>update-cursor screen, recipes, current-sandbox, sandbox-in-focus?, env <span class="Comment"># no change in cursor</span> show-screen screen <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> ] <span class="muRecipe">def</span> find-click-in-sandbox-output env:address:programming-environment-data, click-row:number<span class="muRecipe"> -&gt; </span>sandbox:address:sandbox-data [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> <span class="Comment"># assert click-row &gt;= sandbox.starting-row-on-screen</span> sandbox:address:sandbox-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">sandbox:offset</span> start:number<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">starting-row-on-screen:offset</span> clicked-on-sandboxes?:boolean<span class="Special"> &lt;- </span>greater-or-equal click-row, start assert clicked-on-sandboxes?, <span class="Constant">[extract-sandbox called on click to sandbox editor]</span> <span class="Comment"># while click-row &lt; sandbox.next-sandbox.starting-row-on-screen</span> <span class="Delimiter">{</span> next-sandbox:address:sandbox-data<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">next-sandbox:offset</span> <span class="muControl">break-unless</span> next-sandbox next-start:number<span class="Special"> &lt;- </span>get *next-sandbox, <span class="Constant">starting-row-on-screen:offset</span> found?:boolean<span class="Special"> &lt;- </span>lesser-than click-row, next-start <span class="muControl">break-if</span> found? sandbox<span class="Special"> &lt;- </span>copy next-sandbox <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># return sandbox if click is in its output region</span> response-starting-row:number<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> <span class="muControl">return-unless</span> response-starting-row, <span class="Constant">0/no-click-in-sandbox-output</span> click-in-response?:boolean<span class="Special"> &lt;- </span>greater-or-equal click-row, response-starting-row <span class="muControl">return-unless</span> click-in-response?, <span class="Constant">0/no-click-in-sandbox-output</span> <span class="muControl">return</span> sandbox ] <span class="muRecipe">def</span> toggle-expected-response sandbox:address:sandbox-data<span class="muRecipe"> -&gt; </span>sandbox:address:sandbox-data [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> expected-response:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">expected-response:offset</span> <span class="Delimiter">{</span> <span class="Comment"># if expected-response is set, reset</span> <span class="muControl">break-unless</span> expected-response *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">expected-response:offset</span>, <span class="Constant">0</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="Comment"># if not, set expected response to the current response</span> <span class="muControl">break-if</span> expected-response response:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">response:offset</span> *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">expected-response:offset</span>, response <span class="Delimiter">}</span> ] <span class="Comment"># when rendering a sandbox, color it in red/green if expected response exists</span> <span class="muRecipe">after</span> <span class="Constant">&lt;render-sandbox-response&gt;</span> [ <span class="Delimiter">{</span> <span class="muControl">break-unless</span> sandbox-response *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span>, row expected-response:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">expected-response:offset</span> <span class="muControl">break-unless</span> expected-response <span class="Comment"># fall-through to print in grey</span> response-is-expected?:boolean<span class="Special"> &lt;- </span>equal expected-response, sandbox-response <span class="Delimiter">{</span> <span class="muControl">break-if</span> response-is-expected?:boolean row, screen<span class="Special"> &lt;- </span>render-text screen, sandbox-response, left, right, <span class="Constant">1/red</span>, row <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> response-is-expected?:boolean row, screen<span class="Special"> &lt;- </span>render-text screen, sandbox-response, left, right, <span class="Constant">2/green</span>, row <span class="Delimiter">}</span> <span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span> <span class="Delimiter">}</span> ] <span class="muRecipe">before</span> <span class="Constant">&lt;end-render-sandbox-reset-hidden&gt;</span> [ *sandbox<span class="Special"> &lt;- </span>put *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span>, <span class="Constant">0</span> ] </pre> </body> </html> <!-- vim: set foldmethod=manual : --> s="p">>load_once</strong></a>(self)</dt><dd><tt>calls&nbsp;<a href="#Directory-load">load</a>()&nbsp;if&nbsp;it&nbsp;has&nbsp;not&nbsp;been&nbsp;called&nbsp;at&nbsp;least&nbsp;once&nbsp;yet</tt></dd></dl> <dl><dt><a name="Directory-mark"><strong>mark</strong></a>(self, boolean)</dt></dl> <dl><dt><a name="Directory-set_mimetype"><strong>set_mimetype</strong></a>(self)</dt><dd><tt>assign&nbsp;attributes&nbsp;such&nbsp;as&nbsp;self.<strong>video</strong>&nbsp;according&nbsp;to&nbsp;the&nbsp;mimetype</tt></dd></dl> <dl><dt><a name="Directory-use"><strong>use</strong></a>(self)</dt><dd><tt>mark&nbsp;the&nbsp;filesystem-object&nbsp;as&nbsp;used&nbsp;at&nbsp;the&nbsp;current&nbsp;time</tt></dd></dl> <hr> Data and other attributes inherited from <a href="ranger.fsobject.fsobject.html#FileSystemObject">ranger.fsobject.fsobject.FileSystemObject</a>:<br> <dl><dt><strong>accessible</strong> = False</dl> <dl><dt><strong>audio</strong> = False</dl> <dl><dt><strong>basename</strong> = None</dl> <dl><dt><strong>basename_lower</strong> = None</dl> <dl><dt><strong>container</strong> = False</dl> <dl><dt><strong>content_loaded</strong> = False</dl> <dl><dt><strong>dirname</strong> = None</dl> <dl><dt><strong>document</strong> = False</dl> <dl><dt><strong>exists</strong> = False</dl> <dl><dt><strong>extension</strong> = None</dl> <dl><dt><strong>force_load</strong> = False</dl> <dl><dt><strong>image</strong> = False</dl> <dl><dt><strong>infostring</strong> = None</dl> <dl><dt><strong>islink</strong> = False</dl> <dl><dt><strong>last_used</strong> = None</dl> <dl><dt><strong>loaded</strong> = False</dl> <dl><dt><strong>marked</strong> = False</dl> <dl><dt><strong>media</strong> = False</dl> <dl><dt><strong>mimetype_tuple</strong> = ()</dl> <dl><dt><strong>path</strong> = None</dl> <dl><dt><strong>permissions</strong> = None</dl> <dl><dt><strong>readlink</strong> = None</dl> <dl><dt><strong>runnable</strong> = False</dl> <dl><dt><strong>size</strong> = 0</dl> <dl><dt><strong>stat</strong> = None</dl> <dl><dt><strong>stopped</strong> = False</dl> <dl><dt><strong>tagged</strong> = False</dl> <dl><dt><strong>type</strong> = 'unknown'</dl> <dl><dt><strong>video</strong> = False</dl> <hr> Data descriptors inherited from <a href="ranger.shared.mimetype.html#MimeTypeAware">ranger.shared.mimetype.MimeTypeAware</a>:<br> <dl><dt><strong>__dict__</strong></dt> <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd> </dl> <dl><dt><strong>__weakref__</strong></dt> <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd> </dl> <hr> Data and other attributes inherited from <a href="ranger.shared.mimetype.html#MimeTypeAware">ranger.shared.mimetype.MimeTypeAware</a>:<br> <dl><dt><strong>mimetypes</strong> = {}</dl> <hr> Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br> <dl><dt><strong>fm</strong> = None</dl> <hr> Methods inherited from <a href="ranger.ext.accumulator.html#Accumulator">ranger.ext.accumulator.Accumulator</a>:<br> <dl><dt><a name="Directory-move"><strong>move</strong></a>(self, relative<font color="#909090">=0</font>, absolute<font color="#909090">=None</font>)</dt></dl> <dl><dt><a name="Directory-pointer_is_synced"><strong>pointer_is_synced</strong></a>(self)</dt></dl> <dl><dt><a name="Directory-sync_index"><strong>sync_index</strong></a>(self, **kw)</dt></dl> <hr> Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br> <dl><dt><strong>settings</strong> = &lt;ranger.ext.openstruct.OpenStruct object at 0x154e450&gt;</dl> </td></tr></table> <p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#ffc8d8"> <td colspan=3 valign=bottom>&nbsp;<br> <font color="#000000" face="helvetica, arial"><a name="NoDirectoryGiven">class <strong>NoDirectoryGiven</strong></a>(<a href="builtins.html#Exception">builtins.Exception</a>)</font></td></tr> <tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td> <td width="100%"><dl><dt>Method resolution order:</dt> <dd><a href="ranger.fsobject.directory.html#NoDirectoryGiven">NoDirectoryGiven</a></dd> <dd><a href="builtins.html#Exception">builtins.Exception</a></dd> <dd><a href="builtins.html#BaseException">builtins.BaseException</a></dd> <dd><a href="builtins.html#object">builtins.object</a></dd> </dl> <hr> Data descriptors defined here:<br> <dl><dt><strong>__weakref__</strong></dt> <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd> </dl> <hr> Methods inherited from <a href="builtins.html#Exception">builtins.Exception</a>:<br> <dl><dt><a name="NoDirectoryGiven-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#NoDirectoryGiven-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;x.__class__.__doc__&nbsp;for&nbsp;signature</tt></dd></dl> <hr> Data and other attributes inherited from <a href="builtins.html#Exception">builtins.Exception</a>:<br> <dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object at 0x7f327d94a120&gt;<dd><tt>T.<a href="#NoDirectoryGiven-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl> <hr> Methods inherited from <a href="builtins.html#BaseException">builtins.BaseException</a>:<br> <dl><dt><a name="NoDirectoryGiven-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoDirectoryGiven-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl> <dl><dt><a name="NoDirectoryGiven-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#NoDirectoryGiven-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl> <dl><dt><a name="NoDirectoryGiven-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl> <dl><dt><a name="NoDirectoryGiven-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoDirectoryGiven-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl> <dl><dt><a name="NoDirectoryGiven-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoDirectoryGiven-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl> <dl><dt><a name="NoDirectoryGiven-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl> <dl><dt><a name="NoDirectoryGiven-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#NoDirectoryGiven-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl> <dl><dt><a name="NoDirectoryGiven-with_traceback"><strong>with_traceback</strong></a>(...)</dt><dd><tt><a href="builtins.html#Exception">Exception</a>.<a href="#NoDirectoryGiven-with_traceback">with_traceback</a>(tb)&nbsp;--<br> set&nbsp;self.<strong>__traceback__</strong>&nbsp;to&nbsp;tb&nbsp;and&nbsp;return&nbsp;self.</tt></dd></dl> <hr> Data descriptors inherited from <a href="builtins.html#BaseException">builtins.BaseException</a>:<br> <dl><dt><strong>__cause__</strong></dt> <dd><tt>exception&nbsp;cause</tt></dd> </dl> <dl><dt><strong>__context__</strong></dt> <dd><tt>exception&nbsp;context</tt></dd> </dl> <dl><dt><strong>__dict__</strong></dt> </dl> <dl><dt><strong>__traceback__</strong></dt> </dl> <dl><dt><strong>args</strong></dt> </dl> </td></tr></table></td></tr></table><p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#eeaa77"> <td colspan=3 valign=bottom>&nbsp;<br> <font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr> <tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td> <td width="100%"><dl><dt><a name="-sort_by_basename"><strong>sort_by_basename</strong></a>(path)</dt><dd><tt>returns&nbsp;path.basename&nbsp;(for&nbsp;sorting)</tt></dd></dl> <dl><dt><a name="-sort_by_directory"><strong>sort_by_directory</strong></a>(path)</dt><dd><tt>returns&nbsp;0&nbsp;if&nbsp;path&nbsp;is&nbsp;a&nbsp;directory,&nbsp;otherwise&nbsp;1&nbsp;(for&nbsp;sorting)</tt></dd></dl> </td></tr></table><p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#55aa55"> <td colspan=3 valign=bottom>&nbsp;<br> <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr> <tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td> <td width="100%"><strong>BAD_INFO</strong> = None</td></tr></table> </body></html>