<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4100091590694628472</id><updated>2026-08-05T16:11:14.237-04:00</updated><category term="F#"/><category term="Functional Programming"/><category term="F# Programming"/><category term="C#"/><category term="Self Note"/><category term="Algorithms"/><category term="Azure"/><category term="Visual Studio"/><category term="RISCV"/><category term="LINQ"/><category term="Windows Phone 7"/><category term="Performance"/><category term="Azure SQL"/><category term="PowerShell"/><category term="SQL"/><category term="Silverlight"/><category term="NLP"/><category term="WPF"/><category term="Finance"/><category term="Interview"/><category term="Quantum"/><category term="XNA"/><category term="Being A Tech Manager"/><category term="Cloud"/><category term="ELF"/><category term="GPGPU"/><category term="Big Data"/><category term="DevOps"/><category term="Extensibility"/><category term="HTML5"/><category term="Hadoop"/><category term="JavaScript"/><category term="MS Word"/><category term="Q#"/><category term="TypeScript"/><category term=".NetCore"/><category term="Asp.net"/><category term="Automation"/><category term="Blazor"/><category term="LLVM"/><category term="Linux"/><category term="Mono"/><category term="New Machine"/><category term="NodeJS"/><category term="Parsing"/><category term="Pratt"/><category term="Python"/><category term="Quant"/><category term="Testing"/><category term="VSCode"/><category term="WSL"/><category term="WebAssembly"/><category term="docker"/><title type='text'>Apollo 13 - Tao Liu&#39;s blog</title><subtitle type='html'>Failure is not an option.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>257</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-4727332566013084889</id><published>2026-08-04T14:10:42.192-04:00</published><updated>2026-08-04T14:10:42.193-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><title type='text'>Bringing the RISC-V Simulator into VS Code</title><content type='html'>&lt;div&gt;&lt;p class=&quot;MsoNormal&quot;&gt;One of the goals of my RiscV toolchain project has always been more than
simply generating RISC-V assembly.&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;I want to build a complete toolchain that makes writing,
compiling, and debugging RISC-V programs feel natural. This week, I reached
another milestone: &lt;b&gt;my RISC-V simulator can now debug programs directly
inside Visual Studio Code.&lt;/b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Seeing breakpoints, registers, and single-step execution
inside VS Code is surprisingly satisfying. It makes the project feel much
closer to a real development environment.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnb8KpnPssRNTjBk9pHVaqngQF55CR0ZppKkSY4x5gYmHmx0nhiptybNmXw4ObrSp6kn8MJIl1mhLm2NrjUadhtzPxk4dryx2wHlvKoMMSU9g2UPwMX3QocqN0GhKm8a-UUhkrN0jMTwqrapaXYsJp9QExcRwu8VNbwBMyjqH9ilBmf4o1w53DUnB1cAA/s1276/VSCodeDebugger.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;689&quot; data-original-width=&quot;1276&quot; height=&quot;216&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnb8KpnPssRNTjBk9pHVaqngQF55CR0ZppKkSY4x5gYmHmx0nhiptybNmXw4ObrSp6kn8MJIl1mhLm2NrjUadhtzPxk4dryx2wHlvKoMMSU9g2UPwMX3QocqN0GhKm8a-UUhkrN0jMTwqrapaXYsJp9QExcRwu8VNbwBMyjqH9ilBmf4o1w53DUnB1cAA/w400-h216/VSCodeDebugger.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/b&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Why a VS Code Debugger?&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;When developing a compiler, debugging generated assembly is
just as important as generating it.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Previously, my workflow looked something like this:&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;ol start=&quot;1&quot; style=&quot;margin-top: 0cm;&quot; type=&quot;1&quot;&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;Compile
     C source code.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;Generate
     RISC-V assembly.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;Run
     the simulator.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;Print
     register values.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;Repeat.&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;That works for small programs, but it quickly becomes
painful as the compiler grows.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Having an interactive debugger completely changes the
experience.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Instead of inserting print statements everywhere, I can now:&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;set
     breakpoints&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;single-step
     through instructions&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;inspect
     registers&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;follow
     the execution flow&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;verify
     generated assembly interactively&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;It dramatically shortens the feedback loop when tracking
down compiler bugs.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Using the Debug Adapter Protocol&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Rather than inventing my own debugger UI, I decided to
integrate with &lt;b&gt;Visual Studio Code&#39;s Debug Adapter Protocol (DAP).&lt;/b&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;This means the extension can take advantage of the debugger
interface that developers already know.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Currently the debugger supports:&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;ul style=&quot;margin-top: 0cm;&quot; type=&quot;disc&quot;&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;launching
     a RISC-V program&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;breakpoints&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;stepping
     through instructions&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;viewing
     all integer registers&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;inspecting
     the current execution point&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
 &lt;li class=&quot;MsoNormal&quot;&gt;displaying
     the call stack&lt;o:p&gt;&lt;/o:p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Because the simulator acts as the debugging backend, every
instruction executed is under complete control of the debugger.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;Connecting the Pieces&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;This project has gradually evolved into several independent
components that now work together:&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;C Source&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; │&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;font-family: &amp;quot;Arial&amp;quot;,sans-serif;&quot;&gt;▼&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;C Compiler&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; │&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;font-family: &amp;quot;Arial&amp;quot;,sans-serif;&quot;&gt;▼&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;RISC-V Assembly&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; │&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;font-family: &amp;quot;Arial&amp;quot;,sans-serif;&quot;&gt;▼&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Simulator&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; │&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;font-family: &amp;quot;Arial&amp;quot;,sans-serif;&quot;&gt;▼&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&amp;nbsp;VS Code Debugger&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Each component was originally developed independently.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Connecting them together has been one of the most rewarding
parts of the project.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;When I hit &lt;b&gt;F5&lt;/b&gt; in VS Code, the debugger launches the
simulator, loads the executable, and immediately allows me to step through the
generated instructions.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;That is a much nicer workflow than running individual
command-line tools.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;b&gt;The Screenshot&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;The screenshot below shows the debugger paused on an
instruction.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;On the left, VS Code displays the complete register set.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;On the right, the current instruction is highlighted while
breakpoints are shown directly in the editor.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;Watching the register values change after each instruction
has already helped me identify several code-generation issues that would have
been much harder to diagnose otherwise.&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/4727332566013084889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/4727332566013084889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/4727332566013084889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/4727332566013084889'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/08/bringing-risc-v-simulator-into-vs-code.html' title='Bringing the RISC-V Simulator into VS Code'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnb8KpnPssRNTjBk9pHVaqngQF55CR0ZppKkSY4x5gYmHmx0nhiptybNmXw4ObrSp6kn8MJIl1mhLm2NrjUadhtzPxk4dryx2wHlvKoMMSU9g2UPwMX3QocqN0GhKm8a-UUhkrN0jMTwqrapaXYsJp9QExcRwu8VNbwBMyjqH9ilBmf4o1w53DUnB1cAA/s72-w400-h216-c/VSCodeDebugger.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-6882045912590393427</id><published>2026-08-04T07:20:54.775-04:00</published><updated>2026-08-04T09:41:29.072-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><title type='text'>RisvV C Compiler Dev Journal - 20260804</title><content type='html'>&lt;h1&gt;72 Test Cases, &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt;, and Function Pointers&lt;/h1&gt;&lt;p&gt;Today I reached another milestone on my RISC-V C compiler project with Rust. The regression suite has now grown to &lt;strong&gt;72 executable test cases&lt;/strong&gt;, and this milestone adds support for two important C language features: &lt;strong&gt;&lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;function pointers&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;I&#39;ve been following a simple rule throughout this project: &lt;strong&gt;every new language feature must come with at least one regression test&lt;/strong&gt;. This gives me confidence to continue improving the compiler without worrying about breaking functionality that was implemented earlier.&lt;/p&gt;&lt;p&gt;The compiler has gradually evolved from handling simple expressions into supporting a substantial subset of the C language. So far it includes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;variables and arithmetic expressions&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code inline=&quot;&quot;&gt;if&lt;/code&gt;, &lt;code inline=&quot;&quot;&gt;while&lt;/code&gt;, and &lt;code inline=&quot;&quot;&gt;for&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;functions and recursion&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;pointers and pointer arithmetic&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;arrays&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;structures&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code inline=&quot;&quot;&gt;union&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code inline=&quot;&quot;&gt;enum&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;function pointers&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Adding &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;Although &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt; does not introduce a new type, it is an important C language feature that allows programmers to create aliases for existing types.&lt;/p&gt;&lt;p&gt;Supporting &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt; required extending the compiler&#39;s symbol table and type system so that type aliases could be correctly distinguished from ordinary identifiers and resolved during semantic analysis.&lt;/p&gt;&lt;p&gt;With &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt; in place, complex declarations become much easier to read. This is especially important for function pointers, where the original C syntax can quickly become difficult to understand.&lt;/p&gt;&lt;p&gt;For example:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;typedef int (*BinOp)(int, int);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;is much cleaner than repeatedly writing the full function pointer declaration throughout a program.&lt;/p&gt;&lt;h2&gt;Why Function Pointers?&lt;/h2&gt;&lt;p&gt;Function pointers are one of the features that make C both flexible and powerful. They enable callbacks, dispatch tables, state machines, and many programming patterns commonly found in embedded software, operating systems, and low-level libraries.&lt;/p&gt;&lt;p&gt;Supporting function pointers required more than just parsing a complicated declaration. The compiler now needs to correctly handle:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;function pointer type resolution&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;assignments between functions and function pointer variables&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;indirect function calls&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;passing function pointers as parameters&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;returning function pointers from functions&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;function pointers stored inside arrays and structures&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Test Case #72&lt;/h2&gt;&lt;p&gt;To validate both &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt; and function pointer support, I created a regression test that combines several real-world usage patterns into a single program.&lt;/p&gt;&lt;p&gt;The test covers:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;a &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt; for a function pointer type&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;multiple arithmetic callback functions&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;an array of function pointers&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;passing function pointers as parameters&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;returning a function pointer from another function&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;storing function pointers inside a structure&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;indirect function calls through variables, arrays, and structure members&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The test program defines several operations (&lt;code inline=&quot;&quot;&gt;add&lt;/code&gt;, &lt;code inline=&quot;&quot;&gt;sub&lt;/code&gt;, &lt;code inline=&quot;&quot;&gt;mul&lt;/code&gt;, and &lt;code inline=&quot;&quot;&gt;negate_via&lt;/code&gt;) and exercises different ways of invoking them through function pointers.&lt;/p&gt;&lt;p&gt;The expected final result is &lt;strong&gt;42&lt;/strong&gt;, which becomes the regression check for the entire feature set.&lt;/p&gt;&lt;p&gt;This type of test is especially valuable because it validates the interaction between multiple compiler components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;parsing&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;type resolution&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;semantic analysis&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;function call generation&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;memory layout handling&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;RISC-V code generation&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;A More Stable Foundation&lt;/h2&gt;&lt;p&gt;One thing I&#39;ve noticed during recent development is that segmentation faults have become much less common.&lt;/p&gt;&lt;p&gt;Earlier in the project, adding a new language feature often exposed issues deep inside the compiler. These problems usually came from assumptions that were valid when the compiler was smaller but became incorrect as more language features were introduced.&lt;/p&gt;&lt;p&gt;Recently, the development process has changed. Most of my effort is now spent adding new capabilities and expanding test coverage rather than debugging compiler crashes.&lt;/p&gt;&lt;p&gt;I believe this is a sign that the compiler framework itself is becoming more stable. The internal architecture, type system, and regression framework are mature enough to support continued growth.&lt;/p&gt;&lt;p&gt;There are still many bugs to discover, but it is encouraging to see the project moving from &quot;building the foundation&quot; toward &quot;expanding capabilities.&quot;&lt;/p&gt;&lt;h2&gt;Growing the Regression Suite&lt;/h2&gt;&lt;p&gt;The compiler now includes &lt;strong&gt;72 executable regression tests&lt;/strong&gt;, and this number has become more meaningful than simply counting implemented features.&lt;/p&gt;&lt;p&gt;Every bug I fix becomes a permanent regression test.&lt;/p&gt;&lt;p&gt;Every new language feature adds another executable example.&lt;/p&gt;&lt;p&gt;Over time, the regression suite is becoming a living specification of what the compiler supports.&lt;/p&gt;&lt;p&gt;This approach also makes future optimization work safer because I can quickly verify that improvements do not break existing functionality.&lt;/p&gt;&lt;h2&gt;What&#39;s Next?&lt;/h2&gt;&lt;p&gt;With many core C language features now implemented, including &lt;code inline=&quot;&quot;&gt;struct&lt;/code&gt;, &lt;code inline=&quot;&quot;&gt;union&lt;/code&gt;, &lt;code inline=&quot;&quot;&gt;enum&lt;/code&gt;, &lt;code inline=&quot;&quot;&gt;typedef&lt;/code&gt;, and function pointers, the next phase of development will focus on improving compiler maturity in two areas.&lt;/p&gt;&lt;p&gt;The first area is &lt;strong&gt;expanding floating-point support&lt;/strong&gt;. The compiler already has basic floating-point functionality, and the next step is to add more comprehensive regression tests covering more complex scenarios, including floating-point expressions, conversions, function calls, and interactions between integer and floating-point types.&lt;/p&gt;&lt;p&gt;The goal is not only to make floating-point programs compile, but also to build confidence that the generated RISC-V code behaves correctly across a wider range of real-world cases.&lt;/p&gt;&lt;p&gt;The second area is &lt;strong&gt;optimization&lt;/strong&gt;. Up to this point, the primary focus has been correctness, language coverage, and compiler stability. With the framework becoming more mature and the regression suite growing, the next challenge is improving the quality of generated code.&lt;/p&gt;&lt;p&gt;Future optimization work will explore areas such as:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;improving generated instruction sequences&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;reducing unnecessary operations&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;peephole optimization&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;intermediate representation improvements&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;exploring more advanced compiler optimization techniques&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This marks an important transition for the project: moving from:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&quot;Can the compiler correctly compile C programs?&quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;toward:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&quot;Can the compiler generate efficient RISC-V code?&quot;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I&#39;m looking forward to this next stage of the journey.&lt;/p&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/6882045912590393427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/6882045912590393427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/6882045912590393427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/6882045912590393427'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/08/c-compiler-dev-journal-20260804.html' title='RisvV C Compiler Dev Journal - 20260804'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-5024163240357815515</id><published>2026-05-07T10:26:36.894-04:00</published><updated>2026-05-07T10:26:36.894-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>SelfNote: Register Spillover and Replacement</title><content type='html'>This is post is to record some notes when I refine my register allocation study/design when dealing with RiscV processors.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First i need a function to decide how to move register SetB from SetA where available register set is present as &quot;available&quot;. The return value are tuple. The 1st element is Vec&amp;lt;(register name0, register name1)&amp;gt;. The spillover are register set.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The replacement is used to perform replacement operation to move register to conflicted status to free register. register name0 is being replaced by register name1. The spillover are registers required to push to stack.&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style=&quot;border-color: currentcolor; border-image: initial; border-style: none; border-width: medium; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;&lt;div&gt;MoveAway(setA, setB, available) -&amp;gt; (replacement, spillover)&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; if setA ∩ setB = φ { (φ, φ ) }&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; else&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; overlap = setA ∩ setB&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; replacement = overlap zip available&amp;nbsp; &amp;nbsp;//this will generate vec&amp;lt;(reg name0, reg name1)&amp;gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; spillover = overlap - available&amp;nbsp;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And this function can be simplifed to&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style=&quot;border-color: currentcolor; border-image: initial; border-style: none; border-width: medium; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;&lt;div&gt;&lt;div&gt;MoveAway(setA, setB, available) -&amp;gt; (replacement, spillover)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; overlap = setA ∩ setB&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; replacement = overlap zip available&amp;nbsp; &amp;nbsp;//this will generate vec&amp;lt;(reg name0, reg name1)&amp;gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; spillover = overlap - available&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/5024163240357815515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/5024163240357815515' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/5024163240357815515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/5024163240357815515'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/05/selfnote-register-spillover-and.html' title='SelfNote: Register Spillover and Replacement'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-9071418226714377391</id><published>2026-04-20T06:52:00.003-04:00</published><updated>2026-04-20T07:24:36.098-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="VSCode"/><title type='text'>Building My First RISC-V VSCode Extension (and Everything That Went Wrong)</title><content type='html'>&lt;h1&gt;&lt;br /&gt;&lt;/h1&gt;&lt;p&gt;I set out to build a simple VSCode extension for RISC-V assembly. The idea sounded straightforward: define a new language, hook up a Rust-based parser through LSP, and get syntax highlighting plus diagnostics. I’ve built compilers before—how hard could this be? It turns out, the hard part wasn’t the compiler at all. It was everything around it.&lt;/p&gt;&lt;h2&gt;The Setup&lt;/h2&gt;&lt;p&gt;On paper, the architecture was clean. A TypeScript extension runs inside VSCode, launches a Rust-based language server, and that server parses &lt;code inline=&quot;&quot;&gt;.rv.s&lt;/code&gt; files, reports errors, and sends back semantic tokens for highlighting. In development mode, everything worked beautifully. I could open a file and immediately see highlighting, introduce an error and watch diagnostics appear exactly where I expected. It felt solid, and at that point I thought I was basically done. I wasn’t.&lt;/p&gt;&lt;h2&gt;The VSIX Reality Check&lt;/h2&gt;&lt;p&gt;The moment I packaged everything into a &lt;code inline=&quot;&quot;&gt;.vsix&lt;/code&gt; and installed it, things broke—quietly. There was no highlighting, no diagnostics, and no logs. The extension just sat there stuck on “Activating…”. That’s when it really clicked: dev mode hides problems, but packaging reveals them.&lt;/p&gt;&lt;h2&gt;The First Wall: Missing Dependencies&lt;/h2&gt;&lt;p&gt;The first real clue came from an error saying it couldn’t find &lt;code inline=&quot;&quot;&gt;vscode-languageclient/node&lt;/code&gt;. That was confusing because it was clearly listed in my &lt;code inline=&quot;&quot;&gt;package.json&lt;/code&gt;. The issue, as it turned out, was entirely self-inflicted. VSCode extensions don’t bundle dependencies automatically, and I had explicitly excluded &lt;code inline=&quot;&quot;&gt;node_modules&lt;/code&gt; in &lt;code inline=&quot;&quot;&gt;.vscodeignore&lt;/code&gt;. In other words, I built an extension and then removed part of it before shipping. Once I included &lt;code inline=&quot;&quot;&gt;node_modules&lt;/code&gt; again, that problem disappeared. Simple in hindsight, but not obvious when you’re in the middle of it.&lt;/p&gt;&lt;h2&gt;The Silent Failure: LSP Not Starting&lt;/h2&gt;&lt;p&gt;After fixing dependencies, the extension still didn’t work. This time there wasn’t even an error—just silence. That silence made it harder to debug than an actual crash. The issue turned out to be the path to the Rust binary. In development, I was using a relative path like &lt;code inline=&quot;&quot;&gt;server/target/release/rust_keyword_lsp_server.exe&lt;/code&gt;, which worked because everything ran inside my workspace. But once installed, VSCode runs the extension from a completely different location, so that path no longer pointed to anything valid. The fix was to resolve paths using &lt;code inline=&quot;&quot;&gt;context.extensionPath&lt;/code&gt;. Once I did that, the server finally started.&lt;/p&gt;&lt;h2&gt;The Subtle Killer: stdout&lt;/h2&gt;&lt;p&gt;Then came one of the most subtle bugs in the entire process. My parser used &lt;code inline=&quot;&quot;&gt;println!&lt;/code&gt; to print errors, which is perfectly normal in Rust. But in an LSP setup, stdout is not for logging—it’s the protocol itself. Every time I printed something, I was corrupting the JSON stream between the server and VSCode. The client would silently disconnect, making it look like the server never started. There was no obvious error pointing to this. The fix was simply to use &lt;code inline=&quot;&quot;&gt;eprintln!&lt;/code&gt; instead, sending logs to stderr. One small change, but it made a massive difference.&lt;/p&gt;&lt;h2&gt;The Debugging Breakthrough: Developer Tools&lt;/h2&gt;&lt;p&gt;At one point, I realized I was essentially debugging blind. There were no logs, no clear signals, just a stuck extension. That changed when I discovered the developer tools in VSCode through “Help → Toggle Developer Tools”. This was a turning point. Suddenly I could see activation errors, inspect console logs, catch missing modules immediately, and verify runtime paths. Before this, I was guessing. After this, I was actually debugging. If you’re building a VSCode extension and not using this, you’re making things much harder than they need to be.&lt;/p&gt;&lt;h2&gt;Packaging Is a Minefield&lt;/h2&gt;&lt;p&gt;Even after getting everything working, packaging still had its own set of traps. I had to carefully tune &lt;code inline=&quot;&quot;&gt;.vscodeignore&lt;/code&gt; to exclude Rust source code and large build folders, include only the release binary, and still keep all required Node dependencies. A single mistake here could break the extension again in ways that looked completely unrelated. It became clear that packaging isn’t just cleanup—it’s part of the system itself.&lt;/p&gt;&lt;h2&gt;What I Learned&lt;/h2&gt;&lt;p&gt;The biggest surprise in all of this was where the complexity actually lives. It’s not in parsing, not in Rust, and not even in the LSP protocol. It’s in the boundaries: the differences between development and packaged environments, stdout versus stderr, relative paths versus resolved ones, and what exists locally versus what actually gets shipped. Each of these seems small on its own, but together they create a system where things can fail silently in ways that are hard to reason about.&lt;/p&gt;&lt;h2&gt;Where It Ended Up&lt;/h2&gt;&lt;p&gt;After working through all of that, I ended up with a VSIX that installs cleanly, a Rust LSP that starts reliably, working diagnostics, and semantic highlighting for RISC-V assembly. More importantly, I now understand the real challenges of building tooling inside VSCode, and they’re not where I initially expected them to be.&lt;/p&gt;&lt;h2&gt;Closing Thought&lt;/h2&gt;&lt;p&gt;If you’re building an LSP-based extension, expect the bugs to come from the edges, not the core. Your parser will probably work, and your design will probably make sense. But the thing that breaks everything might be something as small as a single &lt;code inline=&quot;&quot;&gt;println!&lt;/code&gt;, and you won’t see it coming.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Eventually, I got instruction and registers highlight works.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgvMM3evbQMUmV3OoSacgqt7n5_6Ze126ss8PabiSjAMwBCojuAxq48KIeLqS8XYTC0oJRoT6tjcb2VEg_GdcAB8-9UxqwOL_3ytaPkrdkC0ORB4FT4lRR0n08ljE5WSKp_ftNk62D19f4zKyXwk4QTn2Qci_kwF7yLx-zgys5TeATd9PZqZCHZea03S8I&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1431&quot; data-original-width=&quot;1074&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgvMM3evbQMUmV3OoSacgqt7n5_6Ze126ss8PabiSjAMwBCojuAxq48KIeLqS8XYTC0oJRoT6tjcb2VEg_GdcAB8-9UxqwOL_3ytaPkrdkC0ORB4FT4lRR0n08ljE5WSKp_ftNk62D19f4zKyXwk4QTn2Qci_kwF7yLx-zgys5TeATd9PZqZCHZea03S8I=w300-h400&quot; width=&quot;300&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/9071418226714377391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/9071418226714377391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/9071418226714377391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/9071418226714377391'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/04/building-my-first-risc-v-vscode.html' title='Building My First RISC-V VSCode Extension (and Everything That Went Wrong)'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEgvMM3evbQMUmV3OoSacgqt7n5_6Ze126ss8PabiSjAMwBCojuAxq48KIeLqS8XYTC0oJRoT6tjcb2VEg_GdcAB8-9UxqwOL_3ytaPkrdkC0ORB4FT4lRR0n08ljE5WSKp_ftNk62D19f4zKyXwk4QTn2Qci_kwF7yLx-zgys5TeATd9PZqZCHZea03S8I=s72-w300-h400-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-4828023938335370315</id><published>2026-03-25T16:09:00.003-04:00</published><updated>2026-03-25T16:09:53.648-04:00</updated><title type='text'>Rust FlameGraph</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;cargo install Flamegraph&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;cargo flamegraph --bin &amp;lt;my binary&amp;gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Please note that &amp;lt;my binary&amp;gt; does not need to add .exe on windows.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;The call stack is up side down. The top most element is the funnction at lower level. Now let&#39;s see if i can get more time on debuggin rather than waiting for the code finish.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhEiRIowBob7hFXwq0e_wSiHE1hl69g5Kn5YB0PYKCad82NlHMV_lWEctRCeplSN0tHEZheLkC4qCcbaD4loE21_2AEktjlXnaaG35BXIN9yYmfPbcYIqUUp7FdGe7J4H_DAZJd0GZLon3ahIcsPERyaYu3tSfmxyXGWdm4KkrexT2MLwJdk5FQAuHlth4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1030&quot; data-original-width=&quot;2455&quot; height=&quot;168&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEhEiRIowBob7hFXwq0e_wSiHE1hl69g5Kn5YB0PYKCad82NlHMV_lWEctRCeplSN0tHEZheLkC4qCcbaD4loE21_2AEktjlXnaaG35BXIN9yYmfPbcYIqUUp7FdGe7J4H_DAZJd0GZLon3ahIcsPERyaYu3tSfmxyXGWdm4KkrexT2MLwJdk5FQAuHlth4=w400-h168&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/4828023938335370315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/4828023938335370315' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/4828023938335370315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/4828023938335370315'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/03/rust-flamegraph.html' title='Rust FlameGraph'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEhEiRIowBob7hFXwq0e_wSiHE1hl69g5Kn5YB0PYKCad82NlHMV_lWEctRCeplSN0tHEZheLkC4qCcbaD4loE21_2AEktjlXnaaG35BXIN9yYmfPbcYIqUUp7FdGe7J4H_DAZJd0GZLon3ahIcsPERyaYu3tSfmxyXGWdm4KkrexT2MLwJdk5FQAuHlth4=s72-w400-h168-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-1755776623294310134</id><published>2026-03-21T11:09:52.648-04:00</published><updated>2026-03-21T11:09:52.648-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Parsing"/><category scheme="http://www.blogger.com/atom/ns#" term="Pratt"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>Left &amp; Right Asscociate in Parsing</title><content type='html'>&lt;div&gt;I made the same mistake again when using Pratt parsing. I almost messed up the left asscociate and right asscociate. If an operator is left asscociate, the generated AST will be a tree lean-to-left. For struct, union, and other composite types, left asscoiate can expose the member as the right node. This can make the code generation much easier, because I know the type for the dot operator.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For example, StructA.structB.a, the lean-to-left tree can expose the &quot;a&quot; as the right node and I can easily find out the whole expression StructA.structB.a is what type. I did not set assignment as an operator, the assignment can be lean-to-right tree.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hopefully this self-note can let me remember this rule and won&#39;t miss this case in the future.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/1755776623294310134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/1755776623294310134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1755776623294310134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1755776623294310134'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/03/left-right-asscociate-in-parsing.html' title='Left &amp; Right Asscociate in Parsing'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-3981246138916985811</id><published>2026-03-07T12:14:00.003-05:00</published><updated>2026-03-07T12:14:44.943-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ELF"/><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>RiscV GCC Dynamic GOT layout </title><content type='html'>&lt;div&gt;I&#39;ve been struggling with the Linux ELF&#39;s dynamic link format for days. All GPT&#39;s provided wrong answer and they&#39;re wrong in the same way.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The correct GOT layout for Linux ELF for RiscV are like the following if there are two external funtions. These two functions are funct0 and funct1.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;ffffffff ffffffff is reserved data&lt;/li&gt;&lt;li&gt;00000000 00000000 is reserved data&lt;/li&gt;&lt;li&gt;GOT[funct0]&lt;/li&gt;&lt;li&gt;GOT[funct1]&lt;/li&gt;&lt;li&gt;.dynamic virutal address&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;#1 and #2 are linker map and resolver address. These fields will be set by dynamic linker (or called dynamic loader).&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unlike GPT&#39;s info, .dynamic virtual address is set to the first slot. The .dynamic virtual address is set as the last element.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/3981246138916985811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/3981246138916985811' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3981246138916985811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3981246138916985811'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/03/riscv-gcc-dynamic-got-layout.html' title='RiscV GCC Dynamic GOT layout '/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-1039723265316997175</id><published>2026-02-22T20:29:00.003-05:00</published><updated>2026-02-22T20:29:32.094-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="LLVM"/><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>Foray into LLVM - Intercept RiscV Assembly Code Generation</title><content type='html'>This weekend, I started my adventure to hook my assembler / linker to LLVM. The first step is to see what&#39;s the right position to intercept the asm code generation. I highly suggest anyone who is interested in LLVM to start with the offical web site forum, especially&amp;nbsp;&lt;a href=&quot;https://discourse.llvm.org/t/beginner-resources-documentation/5872/10&quot;&gt;Beginner Resources + Documentation - Beginners - LLVM Discussion Forums&lt;/a&gt;. Personally, I did not want to bother anyone on forum, but that document is a good start.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And I did use ChatGPT and Google Gemini. The following is the comparison between these two systems. Gemini seems confident; however, its solution does not fit and I was struggle with endless compile error, missing include files, and link errors. In the end, I gave up on Gemini. ChatGPT&#39;s solution is more accurate on the architect level and the code is more accurate. Although GPT tried to lead me, it did not succeed. 😅 That&#39;s because those beginner resource on LLVM web site and some coding experience.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I did is to add &quot;TALIU&quot; label before all the instructions. The final assembly generated is like the following:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div&gt;TALIU:&amp;nbsp; li&amp;nbsp; &amp;nbsp; &amp;nbsp; a0, 42&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div&gt;TALIU:&amp;nbsp; ret&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;GPT&#39;s solution is to replace&amp;nbsp;&lt;span style=&quot;color: #af00db; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #af00db; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #795e26; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;RISCVInstPrinter&lt;/span&gt;&lt;span style=&quot;background-color: white; color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;(MAI, MII, MRI); in&lt;/span&gt;&amp;nbsp;the&amp;nbsp;&lt;span style=&quot;background-color: white; color: #795e26; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;createRISCVMCInstPrinter.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The createRISCVMCInstPrinter is located in&amp;nbsp;llvm-project\llvm\lib\Target\RISCV\MCTargetDesc\RISCVMCTargetDesc.cpp. I use my own InstPrinter replace the existing RISCVInstPrinter. The .h definition is&amp;nbsp;&lt;/p&gt;&lt;div style=&quot;background-color: white; line-height: 19px;&quot;&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;namespace&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;llvm&lt;/span&gt; {&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;class&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;MyRISCVInstPrinter&lt;/span&gt; : &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;RISCVInstPrinter&lt;/span&gt; {&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;public:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #af00db;&quot;&gt;using&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;RISCVInstPrinter&lt;/span&gt;::RISCVInstPrinter;&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #795e26;&quot;&gt;printInst&lt;/span&gt;(&lt;span style=&quot;color: blue;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;MCInst&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #001080;&quot;&gt;MI&lt;/span&gt;, &lt;span style=&quot;color: blue;&quot;&gt;uint64_t&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;Address&lt;/span&gt;, &lt;span style=&quot;color: #267f99;&quot;&gt;StringRef&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;Annot&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: blue;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;MCSubtargetInfo&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #001080;&quot;&gt;STI&lt;/span&gt;, &lt;span style=&quot;color: #267f99;&quot;&gt;raw_ostream&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #001080;&quot;&gt;O&lt;/span&gt;) &lt;span style=&quot;color: blue;&quot;&gt;override&lt;/span&gt;;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; };&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;}&lt;span style=&quot;color: green;&quot;&gt; // namespace llvm&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: green;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; white-space: normal;&quot;&gt;And the .c file is like the following.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; white-space: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;line-height: 19px;&quot;&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: #af00db;&quot;&gt;#include&lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #a31515;&quot;&gt;&quot;MyRISCVInstPrinter.h&quot;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;namespace&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;llvm&lt;/span&gt; {&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;void&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;MyRISCVInstPrinter&lt;/span&gt;::&lt;span style=&quot;color: #795e26;&quot;&gt;printInst&lt;/span&gt;(&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;MCInst&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #001080;&quot;&gt;MI&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;uint64_t&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;Address&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #267f99;&quot;&gt;StringRef&lt;/span&gt; &lt;span style=&quot;color: #001080;&quot;&gt;Annot&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: blue;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #267f99;&quot;&gt;MCSubtargetInfo&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #001080;&quot;&gt;STI&lt;/span&gt;,&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #267f99;&quot;&gt;raw_ostream&lt;/span&gt; &lt;span style=&quot;color: blue;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #001080;&quot;&gt;OS&lt;/span&gt;) {&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; OS &lt;span style=&quot;color: black;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #a31515;&quot;&gt;&quot;TALIU: &quot;&lt;/span&gt;;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #267f99;&quot;&gt;RISCVInstPrinter&lt;/span&gt;::&lt;span style=&quot;color: #795e26;&quot;&gt;printInst&lt;/span&gt;(MI, Address, Annot, STI, OS);&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&amp;nbsp; &amp;nbsp; }&lt;/div&gt;&lt;br /&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;}&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; white-space: normal;&quot;&gt;After this, make sure the build command (under build folder) is &quot;&lt;/span&gt;ninja LLVMRISCVCodeGen LLVMAsmPrinter&quot; with configuration command &quot;cmake -G Ninja -DLLVM_ENABLE_PROJECTS=&quot;&quot; -DLLVM_TARGETS_TO_BUILD=&quot;RISCV&quot; -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../llvm&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Gemini told me to do &quot;cmake --build . --target llvm-mc&quot; and does not work. Given my limited experience with llvm, I don&#39;t fully understand why.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; white-space: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;color: #3b3b3b; font-family: Consolas, &amp;quot;Courier New&amp;quot;, monospace; font-size: 14px; white-space: pre;&quot;&gt;&lt;span style=&quot;color: black; font-family: &amp;quot;Times New Roman&amp;quot;; font-size: medium; white-space: normal;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/1039723265316997175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/1039723265316997175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1039723265316997175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1039723265316997175'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/02/foray-into-llvm-intercept-riscv.html' title='Foray into LLVM - Intercept RiscV Assembly Code Generation'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-3385187882023641058</id><published>2026-02-14T07:09:00.001-05:00</published><updated>2026-02-14T07:28:18.716-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ELF"/><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>Dynamic ELF Structure - Endless Segment Fault</title><content type='html'>&lt;div&gt;I created a RiscV assembler and linker. One of the challenges I was facing is to understand the ELF dynamic structure and make it work on a new chip (RiscV). The first challenge is the segment and section and how the segment header and section header work together. I want to post a few posts about the ELF and dynamic ELF from scratch. The &lt;a href=&quot;https://apollo13cn.blogspot.com/2026/02/riscv-assembly-gotplt-index-calculation.html&quot;&gt;previosu post (GOT/PLT)&lt;/a&gt; is part of my assembler / linker work.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Before you start the work, make sure you have WSL ready with RiscV support ready. Although the RiscV support is not mandatory, but you will find it very helpful if your WSL can support RiscV binary execution.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ok, let me start from ELF structure with a diagram. ELF standard is big and I struggled a lot to put this thing into my head. Frankly, I still do not have something to learn about this ELF.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My assembler/linker generate ELF binary and let libc modify the PLT/GOT data, and eventually invoke the &quot;printf&quot; function. Even the target instruction is RiscV, but the ELF format is same for RiscV and other CPU/chips.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The following digram has two columns. The 1st column is binary data in th file. The layout of these binary files can be in a different order, but the concept is there. The 2nd column is the segment which is runtime memory structure. The linkage from two columns shows how the data from file mapped into the runtime memory.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Another view to read these two columns are. Left column contains ELF header, program headers, sections, and section headers. The data on the right is how segment is created in the memory and section data is loaded into those segment.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are tons of attributes about these sections and segments. Let&#39;s leave it for the later posts. The important thing are: what are data, how the data mapped to runtime memory.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;use read-elf command from linux, it shows there are program headers. Those program headers describe this runtime memory contains what data (from which section). I use the following diagram shows its origin. Please note that these memory ranges can overlap. For example, the PHDR loads all program headers data and the PHDR segment is located inside the 1st load segment. The first loaded segment contains PHDR and also it also load the ELF header. If you do the dynamic ELF, this first section is mandatory; otherwise, segment fault will be the result.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Those green color blocks are same case. They&#39;re programers but overlaps with other segments.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, the note section is loaded to memory as well. I do not think it&#39;s mandatory, but note section is the last thing I added before I concluded the dynamic ELF generation work. The Interp segment is another case where the INTERP overlap with another segment.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgIV7jZzjiV9ZKTPLzSVNZEGCiOtDNHHTPvX0oGBIaRPTJRJcGgdvuW1fUisMG7wbNMRYOzldc59Smg8HfK9d811Xjt0RKAh8RZpu5VC4KEx8h1FdaEMMKjSSTXfrypRgre3S5it4P-UyBUrCh0897AqjIQNvTpGmGLnDEp86qwUxk6xYWobH5UnoeQFWI&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1274&quot; data-original-width=&quot;892&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEgIV7jZzjiV9ZKTPLzSVNZEGCiOtDNHHTPvX0oGBIaRPTJRJcGgdvuW1fUisMG7wbNMRYOzldc59Smg8HfK9d811Xjt0RKAh8RZpu5VC4KEx8h1FdaEMMKjSSTXfrypRgre3S5it4P-UyBUrCh0897AqjIQNvTpGmGLnDEp86qwUxk6xYWobH5UnoeQFWI=s16000&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/3385187882023641058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/3385187882023641058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3385187882023641058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3385187882023641058'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/02/dynamic-elf-structure-endless-segment.html' title='Dynamic ELF Structure - Endless Segment Fault'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEgIV7jZzjiV9ZKTPLzSVNZEGCiOtDNHHTPvX0oGBIaRPTJRJcGgdvuW1fUisMG7wbNMRYOzldc59Smg8HfK9d811Xjt0RKAh8RZpu5VC4KEx8h1FdaEMMKjSSTXfrypRgre3S5it4P-UyBUrCh0897AqjIQNvTpGmGLnDEp86qwUxk6xYWobH5UnoeQFWI=s72-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-659525533557965576</id><published>2026-02-04T20:13:00.004-05:00</published><updated>2026-02-04T21:53:43.800-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>RiscV Assembly Got/PLT index Calculation</title><content type='html'>&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;I searched many online document about RiscV PLT table and how the relocation works. Eventually I got my own version working. This is my notes in case one day I will forget.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;Based on
the PLT/GOT RISC V code, the lazy binding code is like the following two
tables. The first one is the PLT[0] code stub where the _dl_runtime_resolver
code is being invoked. The t3 stores the _dl_runtime_resolver address and the
jr t3 is to call that function. That function will requires two parameters: t0
holds the link map address, and t1 holds the function (e.g. printf) offset in
the .got.plt. In the code, t2 is used as temporary register.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;The summary
is below&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;&lt;p class=&quot;MsoListParagraphCxSpFirst&quot; style=&quot;mso-list: l1 level1 lfo2; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;t3 is the _dl_runtime_resolver function
address stored in GOT&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;MsoListParagraphCxSpMiddle&quot; style=&quot;mso-list: l1 level1 lfo2; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;t0 is the link map address in GOT&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;MsoListParagraphCxSpMiddle&quot; style=&quot;mso-list: l1 level1 lfo2; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;t1 is the function (e.g. printf)
offset in .got.plt&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;MsoListParagraphCxSpLast&quot; style=&quot;mso-list: l1 level1 lfo2; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;t2 is temporary register&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;







&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;The
hdr_size is the PLT[0] size which is two 16 bytes (32 bytes) size section. It
has 8 instructions. In the following code, PTRSIZE = 4 if 32bits and PTRSIZE =
8 if 64bits&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoCaption&quot; style=&quot;break-after: avoid; page-break-after: avoid;&quot;&gt;&lt;a name=&quot;_Ref204179417&quot;&gt;Table
&lt;/a&gt;&lt;!--[if supportFields]&gt;&lt;span style=&#39;mso-bookmark:_Ref204179417&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span style=&#39;mso-bookmark:_Ref204179417&#39;&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;SEQ Table \* ARABIC &lt;span style=&#39;mso-element:
field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;1&lt;!--[if supportFields]&gt;&lt;span
style=&#39;mso-bookmark:_Ref204179417&#39;&gt;&lt;/span&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;![endif]--&gt; PLT[0] Code Stub&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-yfti-tbllook: 1184;&quot;&gt;
 &lt;tbody&gt;&lt;tr&gt;
  &lt;td style=&quot;border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0cm 5.4pt; width: 467.5pt;&quot; valign=&quot;top&quot; width=&quot;623&quot;&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;1:&amp;nbsp;
  auipc&amp;nbsp; t2, %pcrel_hi(.got.plt)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  sub&amp;nbsp;&amp;nbsp;&amp;nbsp; t1, t1, t3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # shifted .got.plt offset +
  hdr size + 12&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  l[w|d] t3, %pcrel_lo(1b)(t2)&amp;nbsp;&amp;nbsp;&amp;nbsp;
  # _dl_runtime_resolve&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  addi&amp;nbsp;&amp;nbsp; t1, t1, -(hdr size + 12)
  # shifted .got.plt offset, hdr_size is PLT0 size (32 bytes)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  addi&amp;nbsp;&amp;nbsp; t0, t2,
  %pcrel_lo(1b)&amp;nbsp;&amp;nbsp;&amp;nbsp; # &amp;amp;.got.plt&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  srli&amp;nbsp;&amp;nbsp; t1, t1, log2(16/PTRSIZE)
  # .got.plt offset&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  l[w|d] t0, PTRSIZE(t0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  # link map&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  jr&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t3&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;And the
above code is invoked by the following code. The following code is a function
(e.g. printf) stub in plt section.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoCaption&quot; style=&quot;break-after: avoid; page-break-after: avoid;&quot;&gt;&lt;a name=&quot;_Ref204179411&quot;&gt;Table
&lt;/a&gt;&lt;!--[if supportFields]&gt;&lt;span style=&#39;mso-bookmark:_Ref204179411&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span style=&#39;mso-bookmark:_Ref204179411&#39;&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;SEQ Table \* ARABIC &lt;span style=&#39;mso-element:
field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;2&lt;!--[if supportFields]&gt;&lt;span
style=&#39;mso-bookmark:_Ref204179411&#39;&gt;&lt;/span&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;![endif]--&gt; PLT[N] Code Stub&lt;o:p&gt;&lt;/o:p&gt;&lt;/p&gt;

&lt;table border=&quot;1&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;MsoTableGrid&quot; style=&quot;border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0cm 5.4pt 0cm 5.4pt; mso-yfti-tbllook: 1184;&quot;&gt;
 &lt;tbody&gt;&lt;tr&gt;
  &lt;td style=&quot;border: 1pt solid windowtext; mso-border-alt: solid windowtext .5pt; padding: 0cm 5.4pt; width: 467.5pt;&quot; valign=&quot;top&quot; width=&quot;623&quot;&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;1:&amp;nbsp;
  auipc&amp;nbsp;&amp;nbsp; t3,
  %pcrel_hi(function@.got.plt)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  l[w|d]&amp;nbsp; t3, %pcrel_lo(1b)(t3)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  jalr&amp;nbsp;&amp;nbsp;&amp;nbsp; t1, t3&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;p class=&quot;MsoNormal&quot; style=&quot;line-height: normal; margin-bottom: 0cm;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
  nop&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span lang=&quot;EN-US&quot;&gt;How to get offset in t1
register&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;The t1 is
used to compute the got.plt offset from the plt code stub. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;When the
code called from &lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;u&gt;&lt;span lang=EN-US
style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;REF _Ref204179411 \h &lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;\* MERGEFORMAT &lt;span style=&#39;mso-element:field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;![endif]--&gt;&lt;u&gt;Table
2 PLT[N] Code Stub&lt;/u&gt;&lt;u&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:data&gt;08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200300034003100370039003400310031000000&lt;/w:data&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;/span&gt;&lt;/u&gt;&lt;!--[if supportFields]&gt;&lt;u&gt;&lt;span lang=EN-US
style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;![endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt; to &lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;u&gt;&lt;span
lang=EN-US style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;REF _Ref204179417 \h &lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;\* MERGEFORMAT &lt;span style=&#39;mso-element:field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;![endif]--&gt;&lt;u&gt;Table
1 PLT[0] Code Stub&lt;/u&gt;&lt;u&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:data&gt;08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200300034003100370039003400310037000000&lt;/w:data&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;/span&gt;&lt;/u&gt;&lt;!--[if supportFields]&gt;&lt;u&gt;&lt;span lang=EN-US
style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;![endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;. The first time the &lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;span
lang=EN-US style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;REF _Ref204179411 \h &lt;span style=&#39;mso-element:
field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;Table 2 PLT[N] Code Stub&lt;span lang=&quot;EN-US&quot;&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:data&gt;08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200300034003100370039003400310031000000&lt;/w:data&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;span lang=EN-US
style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt; is called, the &lt;/span&gt;&lt;a href=&quot;mailto:function@.got.plt&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;function@.got.plt&lt;/span&gt;&lt;/a&gt;&lt;span lang=&quot;EN-US&quot;&gt; is points to PLT[0]. The PLT[0]’s
job is to update the &lt;/span&gt;&lt;a href=&quot;mailto:function@.got.plt&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;function@.got.plt&lt;/span&gt;&lt;/a&gt;&lt;span lang=&quot;EN-US&quot;&gt; to actually function address. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;!--[if supportFields]&gt;&lt;span lang=EN-US style=&#39;mso-ansi-language:
EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;REF _Ref204179411 \h &lt;span style=&#39;mso-element:
field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;Table 2 PLT[N] Code Stub&lt;span lang=&quot;EN-US&quot;&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:data&gt;08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200300034003100370039003400310031000000&lt;/w:data&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;span lang=EN-US
style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt; set t1 and t3 to the following
value&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoListParagraphCxSpFirst&quot; style=&quot;mso-list: l0 level1 lfo1; text-indent: -18pt;&quot;&gt;&lt;!--[if !supportLists]--&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;t1 = &amp;amp;nop = &amp;amp;PLT[N] + 12, &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoListParagraphCxSpMiddle&quot; style=&quot;margin-left: 72pt; mso-add-space: auto; mso-list: l0 level2 lfo1; text-indent: -18pt;&quot;&gt;&lt;!--[if !supportLists]--&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: &amp;quot;Courier New&amp;quot;; mso-ansi-language: EN-US; mso-fareast-font-family: &amp;quot;Courier New&amp;quot;;&quot;&gt;o&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;
&lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;12
is from 3 instruction and each instruction is 4 bytes&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoListParagraphCxSpLast&quot; style=&quot;mso-list: l0 level1 lfo1; text-indent: -18pt;&quot;&gt;&lt;!--[if !supportLists]--&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;t3 = &amp;amp;PLT[0]&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;In the &lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;span
lang=EN-US style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-begin&#39;&gt;&lt;/span&gt;&lt;span
style=&#39;mso-spacerun:yes&#39;&gt; &lt;/span&gt;REF _Ref204179417 \h &lt;span style=&#39;mso-element:
field-separator&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;Table 1 PLT[0] Code Stub&lt;span lang=&quot;EN-US&quot;&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;w:data&gt;08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F005200650066003200300034003100370039003400310037000000&lt;/w:data&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;/span&gt;&lt;!--[if supportFields]&gt;&lt;span lang=EN-US
style=&#39;mso-ansi-language:EN-US&#39;&gt;&lt;span style=&#39;mso-element:field-end&#39;&gt;&lt;/span&gt;&lt;/span&gt;&lt;![endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;, the t1 was computed &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;t1 = [t1 –
t3 – (hdr_size + 12)] &amp;gt;&amp;gt; &lt;/span&gt;&lt;!--[if gte msEquation 12]&gt;&lt;m:oMath&gt;&lt;m:sSub&gt;&lt;m:sSubPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:sSubPr&gt;&lt;m:e&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;log&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:e&gt;&lt;m:sub&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;2&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:sub&gt;&lt;/m:sSub&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;PTRSIZE&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;!--[if !msEquation]--&gt;&lt;span face=&quot;&amp;quot;Calibri&amp;quot;,sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: DengXian; mso-fareast-language: ZH-CN; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-text-raise: -8.0pt; position: relative; top: 8pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shapetype
 id=&quot;_x0000_t75&quot; coordsize=&quot;21600,21600&quot; o:spt=&quot;75&quot; o:preferrelative=&quot;t&quot;
 path=&quot;m@4@5l@4@11@9@11@9@5xe&quot; filled=&quot;f&quot; stroked=&quot;f&quot;&gt;
 &lt;v:stroke joinstyle=&quot;miter&quot;/&gt;
 &lt;v:formulas&gt;
  &lt;v:f eqn=&quot;if lineDrawn pixelLineWidth 0&quot;/&gt;
  &lt;v:f eqn=&quot;sum @0 1 0&quot;/&gt;
  &lt;v:f eqn=&quot;sum 0 0 @1&quot;/&gt;
  &lt;v:f eqn=&quot;prod @2 1 2&quot;/&gt;
  &lt;v:f eqn=&quot;prod @3 21600 pixelWidth&quot;/&gt;
  &lt;v:f eqn=&quot;prod @3 21600 pixelHeight&quot;/&gt;
  &lt;v:f eqn=&quot;sum @0 0 1&quot;/&gt;
  &lt;v:f eqn=&quot;prod @6 1 2&quot;/&gt;
  &lt;v:f eqn=&quot;prod @7 21600 pixelWidth&quot;/&gt;
  &lt;v:f eqn=&quot;sum @8 21600 0&quot;/&gt;
  &lt;v:f eqn=&quot;prod @7 21600 pixelHeight&quot;/&gt;
  &lt;v:f eqn=&quot;sum @10 21600 0&quot;/&gt;
 &lt;/v:formulas&gt;
 &lt;v:path o:extrusionok=&quot;f&quot; gradientshapeok=&quot;t&quot; o:connecttype=&quot;rect&quot;/&gt;
 &lt;o:lock v:ext=&quot;edit&quot; aspectratio=&quot;t&quot;/&gt;
&lt;/v:shapetype&gt;&lt;v:shape id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot; style=&#39;width:60pt;
 height:22.5pt&#39;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png&quot;
  o:title=&quot;&quot; chromakey=&quot;white&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img height=&quot;30&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAtCAMAAABS+V+kAAAAAXNSR0IArs4c6QAAAK5QTFRFAAAAAAAAAAA6AABmADo6ADpmADqQAGa2OgAAOgA6OjoAOjo6OjpmOjqQOmaQOma2OpC2OpDbZgAAZgA6ZjoAZjo6ZmZmZmaQZpC2ZpDbZrbbZrb/kDoAkDo6kGYAkGY6kLa2kLbbkNvbkNv/tmYAtmY6tpA6tpBmtra2ttvbttv/tv//25A625Bm27Zm27aQ29uQ29u229vb29v/2////7Zm/9uQ/9u2//+2///bgfvTWAAAAAF0Uk5TAEDm2GYAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAZdEVYdFNvZnR3YXJlAE1pY3Jvc29mdCBPZmZpY2V/7TVxAAAC+0lEQVRYR+1XaVsaMRDebJUurYV2iz1WekdRXKC1e/7/P9Y5E/TRruxG2g/kg8A4yWTeeedIFB3WAYGdEFiPf4h+/SUZFTvtHaC8mZln17x/Nc72ZjYqp0UuhvNYPR/gxy5bxXCTvtllVwBdMZzH3xfv3l8FOPCxR4hha46/Xs7N2WO3Dddjw+0cCd2k+6N1tG2Yzf9lNakxz4c7Syco1Oh4p2HQCBWNdh5naL9KpkWUd59qw2QdQgcLM6maGXP8rQvGJtV606UZ+P/VHqvqrauXhM4/WFZZAB3FmMlSrtAu4NfJ5emTVV2gIp+9TkZLIKQEnBjaWtdvwiOiFaY0lPDiv+SYCMNbhRNLLh+azTlHXKRPGX+xpNy2ZNhf426lp1wdvtAEhzi/5bjkNv+zXbyAeqCkCwW7lg/2VMkl/vOHNZknXSi7cCI3ESGVOO6YhvG39CdMXfX3FhYB1Oix+s/XyV/62mJD11Uw3F6ATUjgZVTPxK8mhS+rj77DNGmo1qk+A39jGkVr6Cjx9LfIob8cZZFzs7u5hon9+Ws6x00v7Tw00PffUxHWz9ZCGNzKKYsnBdxL8hnCwsITUsNuHE+uUYb3LVkLg8ha3LPvW8Jg16jvMBoDUMEoV43PIhzdc8o5ENYEDGTE1a8ZfuN9Od5ayhTFrkoemj+BcHDUT2VaSe3LqjbHG44ogW94En6ykF4QdHgJP4UYuNHVZZo/3z7Y8TangMfRB54SgX4KlUSe8lomWSE7Px5IaHW69JmgZBmWG4SUeFMlEi4UthcEDUDNjHCQOm6S1qe+HR7xbM854TkKGEgERZJxlfCw6Z5ubtQgrd5zvvX89YkO+Ppcr3lgVsyFWBIKZESvtf00cbYoeP5xSj81oFqUvaSXXYicz0L3HqVw0tSAdGabEmIp+zRu09bqVb83+/YLYa2lgISABVaN7ObmM1cLxJuJtaHUJUjqeT+soQ65Bok1icjFQsi7UbHGTMQKJorECN4jJaz7adMvFIdd/xkCfwA0dVTpBsNWYQAAAABJRU5ErkJggg==&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;80&quot; /&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = [&amp;amp;PLT[N] + 12 - &amp;amp;PLT[0] –
hdr_size – 12] &amp;gt;&amp;gt; &lt;/span&gt;&lt;!--[if gte msEquation 12]&gt;&lt;m:oMath&gt;&lt;m:sSub&gt;&lt;m:sSubPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:sSubPr&gt;&lt;m:e&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;log&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:e&gt;&lt;m:sub&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;2&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:sub&gt;&lt;/m:sSub&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;PTRSIZE&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;!--[if !msEquation]--&gt;&lt;span face=&quot;&amp;quot;Calibri&amp;quot;,sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: DengXian; mso-fareast-language: ZH-CN; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-text-raise: -8.0pt; position: relative; top: 8pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shape
 id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot; style=&#39;width:60pt;height:22.5pt&#39;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png&quot;
  o:title=&quot;&quot; chromakey=&quot;white&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img height=&quot;30&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAtCAMAAABS+V+kAAAAAXNSR0IArs4c6QAAAK5QTFRFAAAAAAAAAAA6AABmADo6ADpmADqQAGa2OgAAOgA6OjoAOjo6OjpmOjqQOmaQOma2OpC2OpDbZgAAZgA6ZjoAZjo6ZmZmZmaQZpC2ZpDbZrbbZrb/kDoAkDo6kGYAkGY6kLa2kLbbkNvbkNv/tmYAtmY6tpA6tpBmtra2ttvbttv/tv//25A625Bm27Zm27aQ29uQ29u229vb29v/2////7Zm/9uQ/9u2//+2///bgfvTWAAAAAF0Uk5TAEDm2GYAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAZdEVYdFNvZnR3YXJlAE1pY3Jvc29mdCBPZmZpY2V/7TVxAAAC+0lEQVRYR+1XaVsaMRDebJUurYV2iz1WekdRXKC1e/7/P9Y5E/TRruxG2g/kg8A4yWTeeedIFB3WAYGdEFiPf4h+/SUZFTvtHaC8mZln17x/Nc72ZjYqp0UuhvNYPR/gxy5bxXCTvtllVwBdMZzH3xfv3l8FOPCxR4hha46/Xs7N2WO3Dddjw+0cCd2k+6N1tG2Yzf9lNakxz4c7Syco1Oh4p2HQCBWNdh5naL9KpkWUd59qw2QdQgcLM6maGXP8rQvGJtV606UZ+P/VHqvqrauXhM4/WFZZAB3FmMlSrtAu4NfJ5emTVV2gIp+9TkZLIKQEnBjaWtdvwiOiFaY0lPDiv+SYCMNbhRNLLh+azTlHXKRPGX+xpNy2ZNhf426lp1wdvtAEhzi/5bjkNv+zXbyAeqCkCwW7lg/2VMkl/vOHNZknXSi7cCI3ESGVOO6YhvG39CdMXfX3FhYB1Oix+s/XyV/62mJD11Uw3F6ATUjgZVTPxK8mhS+rj77DNGmo1qk+A39jGkVr6Cjx9LfIob8cZZFzs7u5hon9+Ws6x00v7Tw00PffUxHWz9ZCGNzKKYsnBdxL8hnCwsITUsNuHE+uUYb3LVkLg8ha3LPvW8Jg16jvMBoDUMEoV43PIhzdc8o5ENYEDGTE1a8ZfuN9Od5ayhTFrkoemj+BcHDUT2VaSe3LqjbHG44ogW94En6ykF4QdHgJP4UYuNHVZZo/3z7Y8TangMfRB54SgX4KlUSe8lomWSE7Px5IaHW69JmgZBmWG4SUeFMlEi4UthcEDUDNjHCQOm6S1qe+HR7xbM854TkKGEgERZJxlfCw6Z5ubtQgrd5zvvX89YkO+Ppcr3lgVsyFWBIKZESvtf00cbYoeP5xSj81oFqUvaSXXYicz0L3HqVw0tSAdGabEmIp+zRu09bqVb83+/YLYa2lgISABVaN7ObmM1cLxJuJtaHUJUjqeT+soQ65Bok1icjFQsi7UbHGTMQKJorECN4jJaz7adMvFIdd/xkCfwA0dVTpBsNWYQAAAABJRU5ErkJggg==&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;80&quot; /&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;= [&amp;amp;PLT[N] - &amp;amp;PLT[0] – hdr_size]
&amp;gt;&amp;gt; &lt;/span&gt;&lt;!--[if gte msEquation 12]&gt;&lt;m:oMath&gt;&lt;m:sSub&gt;&lt;m:sSubPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:sSubPr&gt;&lt;m:e&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;log&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:e&gt;&lt;m:sub&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;2&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:sub&gt;&lt;/m:sSub&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;PTRSIZE&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;!--[if !msEquation]--&gt;&lt;span face=&quot;&amp;quot;Calibri&amp;quot;,sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: DengXian; mso-fareast-language: ZH-CN; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-text-raise: -8.0pt; position: relative; top: 8pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shape
 id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot; style=&#39;width:60pt;height:22.5pt&#39;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png&quot;
  o:title=&quot;&quot; chromakey=&quot;white&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img height=&quot;30&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAtCAMAAABS+V+kAAAAAXNSR0IArs4c6QAAAK5QTFRFAAAAAAAAAAA6AABmADo6ADpmADqQAGa2OgAAOgA6OjoAOjo6OjpmOjqQOmaQOma2OpC2OpDbZgAAZgA6ZjoAZjo6ZmZmZmaQZpC2ZpDbZrbbZrb/kDoAkDo6kGYAkGY6kLa2kLbbkNvbkNv/tmYAtmY6tpA6tpBmtra2ttvbttv/tv//25A625Bm27Zm27aQ29uQ29u229vb29v/2////7Zm/9uQ/9u2//+2///bgfvTWAAAAAF0Uk5TAEDm2GYAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAZdEVYdFNvZnR3YXJlAE1pY3Jvc29mdCBPZmZpY2V/7TVxAAAC+0lEQVRYR+1XaVsaMRDebJUurYV2iz1WekdRXKC1e/7/P9Y5E/TRruxG2g/kg8A4yWTeeedIFB3WAYGdEFiPf4h+/SUZFTvtHaC8mZln17x/Nc72ZjYqp0UuhvNYPR/gxy5bxXCTvtllVwBdMZzH3xfv3l8FOPCxR4hha46/Xs7N2WO3Dddjw+0cCd2k+6N1tG2Yzf9lNakxz4c7Syco1Oh4p2HQCBWNdh5naL9KpkWUd59qw2QdQgcLM6maGXP8rQvGJtV606UZ+P/VHqvqrauXhM4/WFZZAB3FmMlSrtAu4NfJ5emTVV2gIp+9TkZLIKQEnBjaWtdvwiOiFaY0lPDiv+SYCMNbhRNLLh+azTlHXKRPGX+xpNy2ZNhf426lp1wdvtAEhzi/5bjkNv+zXbyAeqCkCwW7lg/2VMkl/vOHNZknXSi7cCI3ESGVOO6YhvG39CdMXfX3FhYB1Oix+s/XyV/62mJD11Uw3F6ATUjgZVTPxK8mhS+rj77DNGmo1qk+A39jGkVr6Cjx9LfIob8cZZFzs7u5hon9+Ws6x00v7Tw00PffUxHWz9ZCGNzKKYsnBdxL8hnCwsITUsNuHE+uUYb3LVkLg8ha3LPvW8Jg16jvMBoDUMEoV43PIhzdc8o5ENYEDGTE1a8ZfuN9Od5ayhTFrkoemj+BcHDUT2VaSe3LqjbHG44ogW94En6ykF4QdHgJP4UYuNHVZZo/3z7Y8TangMfRB54SgX4KlUSe8lomWSE7Px5IaHW69JmgZBmWG4SUeFMlEi4UthcEDUDNjHCQOm6S1qe+HR7xbM854TkKGEgERZJxlfCw6Z5ubtQgrd5zvvX89YkO+Ppcr3lgVsyFWBIKZESvtf00cbYoeP5xSj81oFqUvaSXXYicz0L3HqVw0tSAdGabEmIp+zRu09bqVb83+/YLYa2lgISABVaN7ObmM1cLxJuJtaHUJUjqeT+soQ65Bok1icjFQsi7UbHGTMQKJorECN4jJaz7adMvFIdd/xkCfwA0dVTpBsNWYQAAAABJRU5ErkJggg==&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;80&quot; /&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp; (where
hdr_size is the PLT[0] size, it is 32bytes, refer to the diagram below)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;= [(N-1)*16] &amp;gt;&amp;gt; &lt;/span&gt;&lt;!--[if gte msEquation 12]&gt;&lt;m:oMath&gt;&lt;m:sSub&gt;&lt;m:sSubPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:sSubPr&gt;&lt;m:e&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;log&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:e&gt;&lt;m:sub&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;2&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:sub&gt;&lt;/m:sSub&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;PTRSIZE&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;!--[if !msEquation]--&gt;&lt;span face=&quot;&amp;quot;Calibri&amp;quot;,sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: DengXian; mso-fareast-language: ZH-CN; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-text-raise: -8.0pt; position: relative; top: 8pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shape
 id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot; style=&#39;width:60pt;height:22.5pt&#39;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image001.png&quot;
  o:title=&quot;&quot; chromakey=&quot;white&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img height=&quot;30&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAAtCAMAAABS+V+kAAAAAXNSR0IArs4c6QAAAK5QTFRFAAAAAAAAAAA6AABmADo6ADpmADqQAGa2OgAAOgA6OjoAOjo6OjpmOjqQOmaQOma2OpC2OpDbZgAAZgA6ZjoAZjo6ZmZmZmaQZpC2ZpDbZrbbZrb/kDoAkDo6kGYAkGY6kLa2kLbbkNvbkNv/tmYAtmY6tpA6tpBmtra2ttvbttv/tv//25A625Bm27Zm27aQ29uQ29u229vb29v/2////7Zm/9uQ/9u2//+2///bgfvTWAAAAAF0Uk5TAEDm2GYAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAZdEVYdFNvZnR3YXJlAE1pY3Jvc29mdCBPZmZpY2V/7TVxAAAC+0lEQVRYR+1XaVsaMRDebJUurYV2iz1WekdRXKC1e/7/P9Y5E/TRruxG2g/kg8A4yWTeeedIFB3WAYGdEFiPf4h+/SUZFTvtHaC8mZln17x/Nc72ZjYqp0UuhvNYPR/gxy5bxXCTvtllVwBdMZzH3xfv3l8FOPCxR4hha46/Xs7N2WO3Dddjw+0cCd2k+6N1tG2Yzf9lNakxz4c7Syco1Oh4p2HQCBWNdh5naL9KpkWUd59qw2QdQgcLM6maGXP8rQvGJtV606UZ+P/VHqvqrauXhM4/WFZZAB3FmMlSrtAu4NfJ5emTVV2gIp+9TkZLIKQEnBjaWtdvwiOiFaY0lPDiv+SYCMNbhRNLLh+azTlHXKRPGX+xpNy2ZNhf426lp1wdvtAEhzi/5bjkNv+zXbyAeqCkCwW7lg/2VMkl/vOHNZknXSi7cCI3ESGVOO6YhvG39CdMXfX3FhYB1Oix+s/XyV/62mJD11Uw3F6ATUjgZVTPxK8mhS+rj77DNGmo1qk+A39jGkVr6Cjx9LfIob8cZZFzs7u5hon9+Ws6x00v7Tw00PffUxHWz9ZCGNzKKYsnBdxL8hnCwsITUsNuHE+uUYb3LVkLg8ha3LPvW8Jg16jvMBoDUMEoV43PIhzdc8o5ENYEDGTE1a8ZfuN9Od5ayhTFrkoemj+BcHDUT2VaSe3LqjbHG44ogW94En6ykF4QdHgJP4UYuNHVZZo/3z7Y8TangMfRB54SgX4KlUSe8lomWSE7Px5IaHW69JmgZBmWG4SUeFMlEi4UthcEDUDNjHCQOm6S1qe+HR7xbM854TkKGEgERZJxlfCw6Z5ubtQgrd5zvvX89YkO+Ppcr3lgVsyFWBIKZESvtf00cbYoeP5xSj81oFqUvaSXXYicz0L3HqVw0tSAdGabEmIp+zRu09bqVb83+/YLYa2lgISABVaN7ObmM1cLxJuJtaHUJUjqeT+soQ65Bok1icjFQsi7UbHGTMQKJorECN4jJaz7adMvFIdd/xkCfwA0dVTpBsNWYQAAAABJRU5ErkJggg==&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;80&quot; /&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;= &lt;/span&gt;&lt;!--[if gte msEquation 12]&gt;&lt;m:oMath&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16(&lt;/m:r&gt;&lt;m:r&gt;N&lt;/m:r&gt;&lt;m:r&gt;-&lt;/m:r&gt;&lt;m:r&gt;1)&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;m:sSup&gt;&lt;m:sSupPr&gt;&lt;span
     style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
     mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
     italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:sSupPr&gt;&lt;m:e&gt;&lt;i
     style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
     &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;2&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:e&gt;&lt;m:sup&gt;&lt;m:sSub&gt;&lt;m:sSubPr&gt;&lt;span
       style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
       mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
       italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:sSubPr&gt;&lt;m:e&gt;&lt;i
       style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
       &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;log&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:e&gt;&lt;m:sub&gt;&lt;i
       style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
       &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;2&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:sub&gt;&lt;/m:sSub&gt;&lt;i
     style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
     &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;(&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
       style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
       mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
       italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
       style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
       &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;i
       style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
       &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;PTRSIZE&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;i
     style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
     &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;)&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:sup&gt;&lt;/m:sSup&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;!--[if !msEquation]--&gt;&lt;span face=&quot;&amp;quot;Calibri&amp;quot;,sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: DengXian; mso-fareast-language: ZH-CN; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-text-raise: -12.5pt; position: relative; top: 12.5pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shape id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot;
 style=&#39;width:59.5pt;height:27.5pt&#39;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image006.png&quot;
  o:title=&quot;&quot; chromakey=&quot;white&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img height=&quot;37&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHcAAAA3CAMAAAABvyXUAAAAAXNSR0IArs4c6QAAAMlQTFRFAAAAAAAAAAA6AABmADo6ADpmADqQAGaQAGa2OgAAOgA6OgBmOjoAOjo6OjpmOjqQOmaQOma2OpC2OpDbZgAAZgA6ZgBmZjoAZjo6ZjpmZjqQZmZmZmaQZma2ZpBmZpC2ZrbbZrb/kDoAkDo6kDpmkGY6kJCQkLa2kLbbkNvbkNv/tmYAtmY6tmZmtpA6tpBmtra2ttu2ttvbttv/tv+2tv//25A625Bm27Zm27aQ2/+22//b2////7Zm/9uQ/9u2/9vb//+2///bsJnsoQAAAAF0Uk5TAEDm2GYAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAZdEVYdFNvZnR3YXJlAE1pY3Jvc29mdCBPZmZpY2V/7TVxAAAD90lEQVRYR+1Y2XbTMBC1XFKS0pS2CU3ZU5ew1IUCAdcFL1j//1HM3JG8xSG2c04eOJkX27JGd1ZpRo6zp70FyhZIF5MWBglOly1mrZsSHt2YX+lidBjxe4KhQKmh42hPqas6r+FJxpa1M/7DTB38FK77ozlQnWwqQD5+ZdO67gVP8sTwdsWNz6LA4AauFT4gNYm094Y1zZ7VlCrxOL5M7UMGt1DLqptd/JiS3WOxfYWsrE5sjdUd2awRuJ/uXr76TvyxUTx5Gvn0arRvxrUydod1DK6vBh++emxYqwMBJqOJ9tjZvjIk+uX6rjq/tQSyhvbYnBkb1i7qX/Hor7p7K7jaa5NwjbKUcYFuHc6Agfu+KWRzfbfGdXxWG7jGzsiRbMo5vD6u+ttZe+6c101GZ6Qq/CtxFSCOfdVgSMvDXCt7SisHkz5MvHYyU2rwkV4kRmPsVvRYWbjEs00ercrXYTPoMHWzHdonZe99slkIORc20xbnQvPiuzgHN6u1n9HSAnZT3/GzpXT7aQ0WCE0pl16Oz3dnoPDk0h4a25SwnQX+Yw6rLcqqzpjCIIekP6DD66znEr3YgJtNH0dOuHpC9lqxHRNwUd10KzWS0UYx08V8vQz3LsrLw6UT5nV+w+yAipcqbTzjkpP1oUpFCBHVmQulHnFtspao+K7+2xSK+rpfxVSXIKiFHSqTlOQ9hUDpTLnjcsnY1Ja0c311VnZRadlMSAwj7TFaMjqPqCkosTS1JX1wpc/ICYUnamWf6lSAw+PhmKpJpCYLse3BxXBYKCd2L9AEkqWQoYmTcpNSm95HU8NTxeVqHJknkJQL0hlBQrZ8dfqWuPrumMzI+eEP09e/vWGUAo3A9edjYxBzu4Ag49sFSpU5NypC3KTxE92Fvh3hLw8RN91ISPUvUzAG//pqThjs1UARHrUGLhKb8nDwzdwqhJK3Jp7ZJpra3/hgyR4xzRJj8HbhH9C+gcuAKWw0pDVH/AZTAhLXBGLBlQ0Gw6YdCk2im/yF8oQRTOCR7AVbh8e4cZEAuaYveIvfCJYVKfqlIi8QxWUi9oiiCYbl4Mqe8wTZr7jTlEDL+38ZmyH41LnEhG1I0TibbxKVV7FgYpIKcSvmvmUGcaPwYn/mBl98gYQD8Rg6N/KvJJ39l0EaM4XtX+zPRdjW0Zu+S4dNLi+P5e1h6pXumDQ+IP7Q0e/KZs1/tUGttJ+5yxgTQmDPR1iIGLT20sG+iG843pDmCOxAt0UM5vdaGOPgjCmXaEHCkWk8pr+wpfGdX0KYXx1gKSFtENLRZ+5w4P9YuTcPtKcqvpukaXwfIjlLhijeDJbYgy5odktmG/lXgbBbgfZo/4MF/gJjqoYk45uvPAAAAABJRU5ErkJggg==&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;79&quot; /&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;= &lt;/span&gt;&lt;!--[if gte msEquation 12]&gt;&lt;m:oMath&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
   style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
   mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
   italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
   style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:&quot;Cambria Math&quot;,serif;
   mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16(&lt;/m:r&gt;&lt;m:r&gt;N&lt;/m:r&gt;&lt;m:r&gt;-&lt;/m:r&gt;&lt;m:r&gt;1)&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;span
     style=&#39;font-family:&quot;Cambria Math&quot;,serif;mso-ascii-font-family:&quot;Cambria Math&quot;;
     mso-hansi-font-family:&quot;Cambria Math&quot;;mso-ansi-language:EN-US;font-style:
     italic;mso-bidi-font-style:normal&#39;&gt;&lt;m:ctrlPr&gt;&lt;/m:ctrlPr&gt;&lt;/span&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;i
     style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
     &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;16&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;i
     style=&#39;mso-bidi-font-style:normal&#39;&gt;&lt;span lang=EN-US style=&#39;font-family:
     &quot;Cambria Math&quot;,serif;mso-ansi-language:EN-US&#39;&gt;&lt;m:r&gt;PTRSIZE&lt;/m:r&gt;&lt;/span&gt;&lt;/i&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;!--[if !msEquation]--&gt;&lt;span face=&quot;&amp;quot;Calibri&amp;quot;,sans-serif&quot; lang=&quot;EN-US&quot; style=&quot;font-size: 12pt; line-height: 115%; mso-ansi-language: EN-US; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: &amp;quot;Times New Roman&amp;quot;; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: DengXian; mso-fareast-language: ZH-CN; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-text-raise: -13.5pt; position: relative; top: 13.5pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shape id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot;
 style=&#39;width:37pt;height:28.5pt&#39;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image008.png&quot;
  o:title=&quot;&quot; chromakey=&quot;white&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img height=&quot;38&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAA5CAMAAACmuE0sAAAAAXNSR0IArs4c6QAAALRQTFRFAAAAAAAAAAA6AABmADo6ADpmADqQAGaQAGa2OgAAOgA6OgBmOjo6OjpmOjqQOmaQOma2OpC2OpDbZgAAZgA6ZgBmZjoAZjo6ZjqQZmZmZmaQZpBmZrbbZrb/kDoAkDo6kDpmkGY6kJCQkLa2kLbbkNvbkNv/tmYAtmY6tpA6tpBmtra2ttvbttv/tv+2tv//25A625Bm27Zm27aQ2/+22////7Zm/9uQ/9u2/9vb//+2///btUhdYgAAAAF0Uk5TAEDm2GYAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAAZdEVYdFNvZnR3YXJlAE1pY3Jvc29mdCBPZmZpY2V/7TVxAAAC1klEQVRYR+1Xa3fTMAy1UzraUaBrWMejyyiPeTwKWUaTEP///4WuZCdxWihZOTvlnOpLbEW6lhTLvlHqKP+iAuVy9hcw6fNVaJWdXjtFuRyfrDEuWJVqPVLKJlpfdnGdTzHxrjC4m+vBd7G8PV0wkKpi8TX8qoq7ETY+xRPnS9b5dJ06qDTyS6QUDIlN3iCe6kV76dBHGTF14qCaxX1Q1fm3mBLOJelA/PIq9ynxa6dOo4+fX73+ilVdeMWztaGhi3E7lF9W3jooo4fvvyTIyK9EGMV4ZhMUzmgnEkUdVVhIUdsEeVTIyNuZS2h/dEsVQNmk/U3aUAzoiweMNHrX+kjd+iKCTShlEBxDuQT5Q1cx9tbvyx4kaJNoAdNiPKWAuFZS9pS/nNFb9r33gVe9fWlVCMyLudbDDzSQr5LzXqfHxlZv+XQ2w2b44b7bkl+j2mUabpY/QbUbZ7udtPNuCdt5u/09D5ndi/+vFr5D938+YAUyd3CXF5OzvZbNnl74VuxcK71hf7quDk/c3jDiIAeEGVKXT+8J4d0Yqoofr1W2eTr0w2YoPiU3b8J+SOo24vvhZKWy+obsCeEqxRuXLoql1o9wIB7lQCuw7wlzoGkdfFhgwNQbC5AWEdAqPJmW2Jsxv4WKOptYs3AMMRG2UQv63hJTzAcrmxDREy4EN3SxGVA7M7uNwUbMaE3sBSM2EUpYC9/q5JbOmOJUL4kLsQ4kBuDKXtGM6Q9GhAS21KJDNRRIXgni2BBaJn7lHDqjz4Qge1rJHNPNafVAwFgjoml8ODleDR1zLaqVHjIXce8qXgBzKWu3VG4u5XB1qDlambT+KSxP2GSk7NvmXwK6Fq2r04eOcYm6u7TFjJBWqjonBJ5zERu5aU7b+teEdaD/OW0Iy4RXzKCzn5Aiz2v6znC0Ufy/BbFPR/C1BlHW0fXdhAqCXzUyAw2XvUThNqOw8MfZA1bgFw4VVBmMI7O9AAAAAElFTkSuQmCC&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;49&quot; /&gt;&lt;!--[endif]--&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;= (N-1)PTRSIZE&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p align=&quot;center&quot; class=&quot;MsoNormal&quot; style=&quot;text-align: center; text-indent: 11pt;&quot;&gt;&lt;!--[if gte vml 1]&gt;&lt;v:shape
 id=&quot;_x0000_i1025&quot; type=&quot;#_x0000_t75&quot; style=&#39;width:282pt;height:248.5pt&#39; o:ole=&quot;&quot;&gt;
 &lt;v:imagedata src=&quot;file:///C:/Users/ttliu/AppData/Local/Temp/msohtmlclip1/01/clip_image010.emz&quot;
  o:title=&quot;&quot;/&gt;
&lt;/v:shape&gt;&lt;![endif]--&gt;&lt;!--[if !vml]--&gt;&lt;img border=&quot;0&quot; height=&quot;331&quot; src=&quot;data:image/emf;base64,iVBORw0KGgoAAAANSUhEUgAAAjQAAAHxCAYAAAB6RiaZAAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAAB7hSURBVHja7d1PaFyHgcfx90IPPWTT9OakGq+WUhJSKLHGpotEXR2MLLducQ4hVYyJIXjcNWbYXbdMQmnlQll0WNDo1PayTnrJ/oceJLZNik+Fbi572EOJVLPnFt8L+2feznszb+bNmzeakTSa0UifH3xJJM+MjCLsT957MxP88Ic/DCRJkmY53wRNpWq1+vLt27eXx1X8eL6vkgQ00kS7ePHij+fn5x+Pq0996lN/9H2VJKCRZvsHOQgi3wdJAhoJaCRJQCMBjSQJaCSgkSQBjYDG90GSgEYCGkkS0EhAI0kCGgloJElAI6CRJAGNNLHur5QexAgJym++v9/tHt4sX2/erhHMrX5U2dh4FmgkSUCjwtbXb71QDoInCTCSSk9Xq+sXsrfZ2Kg8uzoXfNS9TRCVbz68nv21/MfZ23ZqA+bNcvB+evui30P+1xaChQ9vra+/ADSSJKBRYclRkMwRkBgbpZX7D4pAk0Jjvbp6oRQET+OP87/Wg6Xkdgsf5zGSBU2Kmd7HLn2SogpoJElAo9FAE5SfxGDI42IQaFKUxEdcjgqaPKjSx0tRBTSSJKDR0FJAzM3N/Tp/umcYaGJ0HBU0yfU0uWtpskeJgEaSBDQaWvb6lexpoIWg9HF62iePluToTPuoznGBJv0c0EiSgEYjYSbGRfa6mDwi8hf6Zq+xcYRGkgQ0mmrZ62e6AAmeJqefMsjYDy2uoZEkAY2mWv4ZRV3kjH4U5sjPcso/q+mQz3La2Nj4tP+mkgQ0OqOlgOlWfrK2Xv1C6xTT8OtkCl93pn3EZRTQxLVfaK/hdWgkSUCjmSkPmv1yhEaSBDQ6saA50FsfZK7zGQQa31dJAhpptn+Qm6Cp1WrP+15IEtBIMw0a3wdJAhpp5kFTq9XO+V5IEtBIMw0a3wdJAhpp5kETH6HxTCdJAhpppkHj+yBJQCPNPGjiozOuo5EkoJEm1htvvHFjeXn54bhyhEaSgEaaeK+99trtcYJmZWXlL+PH9Vo0kgQ0kiRJQCNNO0doJAloJEmSgEaadp7lJElAI0mSBDTStGu/Fs3zvheSBDSSJElAI00zR2gkCWgkSZKARpp2jtBIEtBIkiQBjTTtvBaNJAGNJEkS0EjTzmvRSBLQSJIkAY10EnKERpKARpIkCWikaecIjSQBjSRJEtBI084RGkkCGkmSJKCRpl18hCZ+PRrfC0kCGkmSJKCRppn3dJIkoJEkSQIaado5QiNJQCNJkgQ00rRzhEaSgEaSJAlopGnntWgkCWgkSZKARjoJuY5GkoBGkiQJaKRp5123JQloJEmSgEaado7QSBLQSDOfp21LEtBIM58jNJIENNLM5wiNJAGNBDWSJKCRgEaSBDQS0EiSgEYCGkkCGgloJElAI00/T92WJKCRJEkCGmnaOUIjSUAjSZIENNK0i4/QuDBYkoBGkiQJaKRp9+DBg3nfB0kCGkmSJKCRplmtVjvn+yBJQCNJkgQ00jRzhEaSgEY6DaB5fnl5+aGkyVetVv/spPxZEL+Ew5UrV2q+n0AjzWSLi4sbly9fjtbX1yVNsBs3bkSXLl365yAIwpPwZ0H8jMcmCtZnFTMvv/zyv7766quPmt/PZ/zZDjQ6g8V/EMR/uJrZZPfee+9FX/7yl08MaGa911577a0maP4OaIBGQGNmQAM0QCMBjZkBDdAAjQQ0ZkAjoAEaCWjMgAZogAZoBDRmBjRAAzQS0JgZ0AAN0EhAYwY0AhqgkYDGDGiAxvcDaAQ0ZgY0QAM0EtCYGdAADdBIQGMGNAIaoJGAxgxogMb3A2gENGYGNEADNBLQmBnQAA3QSEBjBjQCGqCRgMYMaIBGQCOgMTOgARqgkYDGzIAGaIBGAhozoBHQAI0ENGZAAzQCGgGNmQEN0ACNBDRmBjRAAzQS0JgBjYAGaCSgMQMaoBHQCGjMDGiABmgkoDEzoAEaoJGAxgxoBDRAIwGNGdAAjYBGQGNmQAM0QCMBjZkBDdAAjQQ0ZkAjoAEaCWjMgAZoBDQCGjMDGqABGglozAxogAZoJKAxAxoBDdBIQGMGNEAj3wQBjZkBDdAAjQQ0ZgY0QAM0EtCYAY2ABmgkoDEDGqABGt8EAY2ZAQ3QAI0ENGYGNEADNBLQmAGNgAZoJKAxAxqgARoJaMwMaIAGaCSgMTOgARqgkYDGDGgENEAjAY0Z0ABNvo2NyrOr5y/+9Fat9uIot39YrZ6rbGw8CzQS0JgZ0JwY0Kyv33qhHJR+c+Xe98rD/hvE+LlaCn5ZXlv/xrj+ez18sPrq+SD4/YW1d7953D8DfkAENGYGNEBzLKBxhEYCGjOg0VhBs1YO3guD8u9er9U+l73NvdXSX7c+f++lLGjS01Xx5681P19aufedIIjC/b9WsBvOXf3o9Urtucwpr5+s3V/5eikI/tB83EazqLTy7e9mH2v9Vvnrzc//b+vz/3io64P8gAhozAxoTjVogr0YEhfWvv/Nagcvtc+lR2SeKa+9X6tVXoxvFzaVEd8u/u+VYqhUCj65tHZ/bXX15tuD/jvGp5ZKQfk38eOuV1cvXFqtvh2DpegIUQyo5td8L4XLm+XgUfx7iD++v1r6q7B09cMUREAjAY0Z0ABN3ymnGDHX2kdhYnikCCk65ZRiKAXOvl/nVvnrRRDJf/34a54Pzv82/bgDoWp1rnNUqFT6YJRTZEAjoDEzoAGabzy8Wb4elFabCKk8Nxg0o11/kx5pCeNTSgvf+ll69CX/GPFt/nTl3oP0dNPD1qmm/4tPQ2U7zEXEfkAENGYGNGcaNLWxgKYHNu3raLKP0fp6V3+ZPYoz6MjOYfIDIqAxM6A5o6ecek7/tI+W5K+hOShoklNZpWsfxEd+0sdYuffG9eY//z3/WIf9GkAjoDEzoDmboFlIQZM9CtN6hlP7lM/c1Y+uXgz/5TBHaNZzp47SU0Yd0KyUf9B7amnhSXrtTvoMp6JfAxoJaMyABmjOVL4JAhqbze3Vo6Uw7FxEWNluRI0D3X8ruX942Psb0AAN0EhAc8q2U4nCsPdZCkVI2KsvNQGxGNV3i+mwczcsfJyeKttRo9EFzWCI7ER3M2CJu1N02527ydcEGqABmsGlp6rC9gvj9ZR5IT2gkYDmVIAmi4K9raXkc4ubu93PDQFN7/ai+lITJIubUeHN9wNN+9fCFD+Z308faoAGaIDGERoJaGwQaFKQBEEl2m6rYlKgaR3p6X7d9PG2ih4PaIAGaIBGAhobDJp+wEwGNO1TTZmjMz3QCe70QgdogAZogEYCGhsKmnDCoGl/PnuqK//72dwFGqABmlGKXyRvVt592w+IgMaOCTQpSOodkEwENG2gFIKmfR1Nz32ABmiAprDWa8iUf5F9TZie163JvF5M3+er1TmgkYBmtkHTSD8V9l8oPEHQjPyMJqABGqApLP+u2DFwVlerr6f/LdO3OLhXe/2lcvnmD+L3Z+o8G2oKz3zyAyKgsbGBpvfpnP1wmfoRmrojNEADNOM63ZQclcm8F1Ra8hYKBZ8HGgloZgY0w1AwmWtotlxDAzRAM5bTTYPf9iA9ElNaufed9J2zh0EHaCSgAZpDPMspuDPgWU75p3MDDdAAzcigeZh9z6a5lV/l0dK6X7CXvsEl0EhAAzSHBk329WYafdDpezo30AAN0PT18MHqq9l34h54yiko/y69MHi/ozZAIwHNqQRNfMpnOB6O8ErBCVLap53aemkdnSnAFNAADdAc+JRT/ja1WuVPYsw8U157P72IGGgkoJlB0LQAUdkZAprkadNhwXs0FR21SY+01A8Omszvqfs18q8cDDRAAzSDio+2XGsCJXtR8MNq9VxlY+PZzsfJ6afyXnyEZq0cvDdNzACNgMZmd0PfnPIgGAMaoAGafPGznLKnj+LTUKUg+EOQeYPK+FqZ9erqhfNB8Psg98aVF9beneh1NH5ABDQ2+6A5ikSABmiAprBpPf0aaCSgOWOgaT09O2z/3+CBQXLU+xvQnHLQjHIdDdBIQGMGNDrRoJm1fBMENGYGNEADNBLQmBnQAA3QSEBjBjQCGqCRgMYMaIDmIMWvM7N6/uJPb9VqL07y95889bt07e+P45lTfkAENGYGNGcMNNN8BtOwd/EGGglozIAGaI4dNN0X3DvcqwInr29TXntv3K8q7AdEQGNmQHOGQVPNvclk/ghK+/TUT+LTU/GvhZ1XBC49TUGUvgt3aeXb381Cpf3u27vh3NWP0tNMrVccLv8m/XpAIwGNGdAAzRFAE+zFb1cQH215eLN8vQmUP6TAyb4vU/4Vg/NviRB/nN4+eQfu0tXktvFbIqRwif/90mr17fg+x3W6yw+IgMbMgMYppw5MvnfvysL54Pxv019rA+ZBFjApaLJHW+LbJkdzSqUPmvddiJGU4ib7tePbXM298SXQSEBjBjRAMxbQ3EuOzLyZHGlJ0VKr3XqxCD4d0LRPNWXflDL7xpSdU1QL3/pZesQHaCSgMQMaoDlm0LQu1k1PM91fu7QWlG/2XMDbB5oR3sAygU37OhqgkYDGDGiAZqzX0DzTPnKSR0YKnlIp+CQPj+yznEa9Hia5nqZ07YPk2hrX0EhAYwY0QDM+0JR/ce1a6W87p4ySIyiV53qOqmSe/ZTWPc3UepZT64Li7GmnhSfxffKno9LTUMf14np+QAQ0ZgY0Zww0o5Q9BTULj+sHREBjZkADNIWnpMZ9nctxvkKxHxABjZkBDdDMfL4JAhozAxqgARoJaMwMaIAGaCSgMQMaAQ3QSEBjBjRAAzS+CQIaMwMaoAEaCWjMDGiABmgkoDEDGgEN0EhAYwY0QAM0EtCYGdAADdBIQGNmQAM0QCMBjRnQCGiARgIaM6ABGqCRgMbMgAZogEYCGjMDGqABGglozIBGQAM0EtCYAQ3QAI0ENGYGNEADNBLQmBnQAA3QSEBjBjQCGqCRgMYMaIAGaCSgMTOgARqgkYDGzIAGaIBGAhozoBHQAI0ENGZAAzRAIwGNmQEN0ACNBDRmBjRAAzQS0JgBjYAGaCSgMQMaoAEaCWjMDGiABmgkoDEzoAEaoJGAxgxoBDRAIwGNGdAADdBIQGNmQAM0QCMBjZkBDdAAjQQ0ZkAjoAEaCWjMgAZogEYCGjMDGqABGglozAxogAZoJKAxAxoBDdBI+S5fvvyjt956K3r8+LGkCVar1aKLFy/+/CSBplKp/Pnt27eXZ7GvfOUrf9MEzSOgARqd0V555ZV/OnfuXNT8g0DSBDt//nz0+c9//j9Pyl/ATWCdm5+f/1Wzx7Pa1772tb9wxAto5JSTmTnlJKCRgMbMgEZAIwGNGdBIQCMBjRnQSEAjoDEzoBHQSEBjZkAjoJGAxgxoJKCRgMYMaCSgEdCYGdAIaCSgMTOgEdBIQGMGNBLQSEBjBjQS0AhozAxoBDQS0JgZ0AhoJKAxAxoJaCSgMQMaCWgENGYGNAIaCWjMDGgENBLQmAGNBDQS0JgBjQQ0AhozAxoBjQQ0ZgY0AhoJaMyARgIaCWjMgEYCGgGNmQGNgEYCGpvi9urRUhhGzb8okyrbjahxoPtvJfcPD3t/AxoBjQQ0p2w7lSgMgw4uBiFjr77UBMRiVN8tpsPO3bDwcXqqbEeNRhc0+0NkL6ovtdAy8HY7d5OvCTRAI6CRgAZo+lCwt7WUfG5xc7f7uSGgKcTI4mZUePMhoEm+1ihHcIAGaAQ0EtDYINCkIAmCSrTdaEwWNAlSwmix3sTUMLAADdAIaCSgscGg6QfMJI/QjAwWoAEaAY0ENDYUNCHQAA3QCGgkoJlZ0KQgqXdAAjRAIwGNBDSzAZpG+qmw/0JhoAEaCWgkoDnpoOl9inU/XIAGaCSgkYDmxINmGAqABmgkoJGABmiABmgkoBHQAA3QAA3QCGgkoLExgWZzdxQ8jBc0dzIXLAMN0AhoJKCxASho4mJnCGi2et+OYL8LiGPQbOWe9j0yaNq/n+L3g+q+cjHQAI2ARgIam+5GPUIzEsaABmgENBLQ2LRBcxSJAA3QCGgkoLHpgWYrAU047N20j+v+BjQCGglozIBGAhoJaMyARgIaAY2ZAY2ARgIaMwMaAY0ENGZAIwGNBDRmQCMBjYDGzIBGQCMBjZkBjYBGAhozoJGARgIaM6CRgEZAY2ZAI6CRgMbMgEZAIwGNGdBIQCMBjRnQSEAjoDEzoBHQSEBjZkAjoJGAxgxoJKCRgMYMaCSgEdCYGdAIaCSgMTOgEdBIQGMGNBLQSEBjBjQS0AhozAxoBDQS0JgZ0AhopEm0uLi4MT8/H331q1+VNMFefvnl6Etf+tIO0AhopDHU/D/E+vLychQfpZE0uW7cuBGD5kOgEdBITjmZOeUkAY0ENGZAI6CRgMbMgEZAIwGNGdAAjYBGAhozoJGARgIaM6AR0EhAY2ZAI6CRgMYMaPxZJKCRgMYMaCSgEdAAjRnQCGgkoDEzoBHQSEBjBjT+LBLQSEBjBjQS0AhogMYMaAQ0EtCYGdAIaCSgMQMaCWgkoDEDGgloBDRAYwY0AhoJaMwMaAQ0EtCYAY0ENBLQmAGNBDQCGjMDGgGNBDRmBjQCGglozIBGAhoJaMyARgIaAY2dmu3Vo6UwjJp/USZVthtR40D330ruHx72/gY0AhoJaE7ZdipRGAYdXAxCxl59qQmIxai+W0yHnbth4eP0VNmOGo0uaIohshfVl/KPdSfabjSKvmhyO6ABGgGNBDRA04eCva2l5HOLm7vdzw0BTSFKFjejwpvvA5oERil8Wp+J7iZHcwpQAzRAI6CRgMYGgSYFSRBUOoiYFGgKH60NrDv52wMN0AhoJKCxwaDpB8w0QZPCJXvECGiARkAjAY2NBprwJIGm4PZAAzQCGglobDBoUpDUOyCZJmhaFxwXfG2gARoBjQQ01geaRvqpsP9C4WmBpn3b3guFgQZoBDQS0FgBaHqfYt0Pl+mApvUMpzBzcTLQAI2ARgIaGwiaYSiYPGjS16PZ52sCDdAIaCSgsZMMmvSF+vb9fQEN0AhoJKCxkwqa1jOswmixvrs/VIAGaAQ0EtDYYUCzuTsKHo4AmjZSgjvxRcBDvhLQAI2ARgIa66KgiYudIaDZah016X+PpqKjNnvRVu5p36OBpn2/ge8Jlbs4GGiARkAjAY1NbQd9Yb19MQY0QCOgkYDGpg2ao0gEaIBGQCMBjU0PNFutF8trn0o6MEiOen8DGgGNBDRmQCMBjQQ0ZkAjAY2AxsyARkAjAY2ZAY2ARgIaM6CRgEYCGjOgkYBGQGNmQCOgkYDGzIBGQCMBjRnQSEAjAY0Z0EhAI6AxM6AR0EhAY2ZAI6CRgMYMaCSgkYDGDGgkoBHQmBnQCGgkoDEzoBHQSEBjBjQS0EhAYwY0EtAIaMwMaAQ0EtCYGdAIaCSgMQMaCWgkoDEDGgloBDRmBjQCGmmmQNNoNPwNYzbBPXr0CGgENNK4av6BuvXcc8/9z9zc3B8lTa7Pfvaz//3KK6/8G9AIaKQxdPny5R8tLy9H8VEaSZPrxo0b0cLCws+BRkAjjfGUk5lNdq6hEdBIQGMGNBLQSEBjBjQCGglozAxoBDQS0JgBDdAIaCSgMQMaCWgkoDEDGgGNBDRmBjQCGglozIAGaAQ0EtCYAY0ENBLQmAGNgEYCGjMDGgGNBDRmQAM0AhoJaMyARgIaCWjMgEZAIwGNmQGNgEYCGjOgARoBjQQ0ZkAjAY0ENGZAI6CRgMbMgEZAIwGNGdAAjYBGAhozoJGARgIaM6AR0EhAY2ZAI6CRgMYMaPxZJKCRgMby26tHS2EYNf+iTKpsN6LGge6/ldw/POz9DWgENBLQnLLtVKIwDDq4GISMvfpSExCLUX23mA47d8PCx+mpsh01Gl3QFENkL6ov5R5rcTPabTSKvmhyO6ABGgGNBDRA04eCva2l5HOLm7vdzw0BTSFKEogU/fJg0CQwSuHT+s20juYUPRbQAI2ARgIaGwSaFCRBUIm227KYFGgKHy3+2uFitJl/MKABGgGNBDQ2GDT9gJk+aArgAjRAI6CRgMaGgiY8GaBpXZ/TPVoENEAjoJGAxkYATQqSegck0wJNC1ZhtFjf7b8t0ACNgEYCGusDTSP9VNh/ofAEQZN/xlRycXLxDYEGaAQ0EtBYNOBp2/1wmd4pp53obvKaMy4KBhoBjQQ0NgQ0w1AwzWtoOk/dvrPde6QGaIBGQCMBjc0MaAY9HtAAjYBGAhqbHdC0TztVHKEBGgGNBDQ2BtDE17EMx8NhQdOCS/YC5e5bIRRgCmiARkCj4+nBgwfz8V/A4yx+TKABmuMDzd3kadGVnSGg2Wo9fbr/PZqKjtrsRVu5p32PBpru76fnawx6HKABGgGNZgM08/Pzj+N/Ag3QnKod+JTTfhgDGqAR0Ggm/jIHGqA51aA5ikSABmgENAIaoLHpgab1NOywfUrpwCA56v0NaAQ0AhqgMQMaCWgENEBjBjQS0AAN0JgZ0AhoBDRAY2ZAI6AR0ACNGdBIQCOgARozoJGA5qR2f6X0IHlV0/Kb749y+4c3y9eT28+tflTZ2HgWaIDGDGgENOppff3WC+UgeNJ9+fTS09Xq+oX01zc2Ks+uzgUfZV9evXzz4fXsr6UfD7p9pzZg3iwH7+cfIwjKT26tr7/Qg5gMYOLf50Kw8GH2NkADNGZAI6BRIRxibJRW7j/IAyUFyHp19UIpCJ7GHxeBpgdLyW0XPs4jpBg0QZT9ukADNGZAIwHNwUDTPjqSHq0pOuKS/VwMkvhoyzhBU15Z+X4pKH2SHh0CGqAxAxoJaEYuBcXc3Nyvs6eThoEmPpoyVtA0P06hBDRAYwY0EtAcqOw1NJ3TSgkeSh/HR0vyaEnQ0T6iM27QtG7fOkoDNEBjBjQS0BwIM11MtK6NyeIhf5HvftfXHBU08cfJM6CakKnevPStg4Lm8uXLP6rVas/HHzf/eW5jY+PT6cdAY2ZAI6A5pWWvn+kCJHianH5qn/rZDy3HAZrO0aGbq2+XSqv/MK4jNDFsTjtwgMYMaAQ0Z/MITeYUTy9yukdiJg2azlGa3OvOjPuU02k8kgM0ZkAjoDnjR2myrxdTfrK2Xv1C+tow6b/vB5qe+2cRckjQdB53CtfQ5I/kxP8ONGYGNAIa9ZUFzchHk6Z0UfAsAQdozIBGQKMJg+ZQb32QezXhSYCmqBg1aScJOkBjBjQCGs14037adh4407gmB2jMgEZAI6A5FuRkT1mlAY0Z0EhAo5kBzShHc8Z5qgpozIBGQCOgORFHcrIBjRnQSEADNDNfHjkpfoDGDGgENAKamS3FTPa6nCxwUtA0Gg1/w5hNcI8ePQIaAY2AZlxHci5evPjjz3zmM9Hzzz8vacJ98Ytf/BXQCGgENGP6Hty+fTt6/PixpAn27rvvOkIjoDmrNf/iXZ6fn388rpr/h/RfV65ceeesg8Y1NGaTn2toBDRnuPg0SYyacTZL77sENGZAIwGNBDRmQCOgkYDGzIBGQCMBjZkBjYBGAhozoJGARgIaM6AR0EhAY2ZAI6CRgMbMgEZAIwGNGdBIQCMBjRnQCGgkoDEzoBHQSEBjZkAjoJGAxgxoJKCRgMYMaAQ0EtCYGdAIaCSgMTOgEdBIQGMGNBLQSEBjBjQCGglozAxoBDQS0JgBDdAIaCSgMQMaCWgkoDEDGgGNBDRmBjQCGglozIAGaAQ0EtDYwO3Vo6UwjJp/USZVthtR40D330ruHx72/gY0AhoJaE7ZdipRGAYdXAxCxl59qQmIxai+W0yHnbth4eP0VNmOGo0uaIZDZCe6m8InvW/vF02+JtAAjYBGAhqg6UPB3tZS8rnFzd3u54aApnd7UX2pCZzFzajw5iOCJvmaYQA0QCOgkYDGDg6aFCRBUIm224qYPGhaR2cW65tRJT5KAzRAI6CRgMYOBpp+wEwaNMkprMV68/7t005AAzQCGglo7FCgCacEmp5fBxqgEdBIQGOHAk0KknoHJJMETffoTPIR0ACNgEYCGjsAaBrpp8L+C4UnBZoEKdmvAzRAI6CRgMZGBE3vU6z74TIZ0LTv14MXoAEaAY0ENDYiaEZ6CvVxg6Z9dGZzt9EPmjsxaBpAAzQCGglo7GSDZpQX51usd18bB2iARkAjAY2dONAM+A065QQ0AhoJaGy8oElOBwEN0EhAIwHNyQJNjIImLnaGgCZ5O4Sw4DRQ0VGbvWgr97Tvo4ImBBqgEdBIQGMnagcCzTCMAQ3QCGgkoLFpg+YoEgEaoBHQSEBj0wPNVgKasH3a6sAgOer9DWgENBLQmAGNBDQS0JgBjQQ0AhozAxoBjQQ0ZgY0AhoJaMyARgIaCWjMgEYCGgGNmQGNgEYCGjMDGgGNBDRmQCMBjQQ0ZkAjAY2AxsyARkAjAY2ZAY2ARgIaM6CRgEYCGjOgkYBGQGNmQCOgkYDGzIBGQCMBjRnQSEAjAY0Z0EhAI6AxM6AR0EhAY2ZAI6CRgMYMaCSgkYDGDGgkoBHQmBnQCGikmQHN7du3o8ePH0uaYO+88w7QCGikcfXGG2/ceOmll/5D0uS7fv16FWgENJIkSUAjSZJOe/8PTtOuKOIGlgoAAAAASUVORK5CYII=&quot; v:shapes=&quot;_x0000_i1025&quot; width=&quot;376&quot; /&gt;&lt;!--[endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;
 &lt;o:OLEObject Type=&quot;Embed&quot; ProgID=&quot;Visio.Drawing.15&quot; ShapeID=&quot;_x0000_i1025&quot;
  DrawAspect=&quot;Content&quot; ObjectID=&quot;_1831740988&quot;&gt;
 &lt;/o:OLEObject&gt;
&lt;/xml&gt;&lt;![endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;text-indent: 11pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;N starts from 1 because PLT[0] is reserved for
dynamic resolver. So the 1&lt;sup&gt;st&lt;/sup&gt; function is at 0 and 2&lt;sup&gt;nd&lt;/sup&gt;
function is at PTRSIZE. The PTRSIZE is the address data size. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoListParagraphCxSpFirst&quot; style=&quot;mso-list: l0 level1 lfo1; text-indent: -18pt;&quot;&gt;&lt;!--[if !supportLists]--&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;If 32bit address, the PTRSIZE is 4,
which is 4 bytes equals 32 bits. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoListParagraphCxSpLast&quot; style=&quot;mso-list: l0 level1 lfo1; text-indent: -18pt;&quot;&gt;&lt;!--[if !supportLists]--&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Symbol; mso-ansi-language: EN-US; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;&quot;&gt;·&lt;span style=&quot;font-family: &amp;quot;Times New Roman&amp;quot;; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;!--[endif]--&gt;&lt;span lang=&quot;EN-US&quot;&gt;If 64bit address, the PTRSIZE is 8,
which is 8 bytes equals 64 bits.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;Please note
the GOT.PLT has 1&lt;sup&gt;st&lt;/sup&gt; and 2&lt;sup&gt;nd&lt;/sup&gt; element to be reserved value.
The 1&lt;sup&gt;st&lt;/sup&gt; element is PLT[0] address and the 2&lt;sup&gt;nd&lt;/sup&gt; element is
link map address.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;h2&gt;&lt;span lang=&quot;EN-US&quot;&gt;Link map into t0&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/h2&gt;

&lt;p class=&quot;MsoNormal&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;The link
map is a reserve entry in got.plt section. The link_map is a data structure
used internally by the Linux dynamic linker (ld.so) to keep track of all shared
libraries (shared objects, .so files) loaded into a running process. &lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;Executable (.got.plt)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;&lt;span lang=&quot;ZH-CN&quot; style=&quot;font-family: DengXian; mso-ansi-language: EN-US; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;&quot;&gt;│&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;&lt;span lang=&quot;ZH-CN&quot; style=&quot;font-family: DengXian; mso-ansi-language: EN-US; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;&quot;&gt;├──&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt; [0] =&amp;gt; address of resolver entry
(__dl_runtime_resolve)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;&lt;span lang=&quot;ZH-CN&quot; style=&quot;font-family: DengXian; mso-ansi-language: EN-US; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;&quot;&gt;├──&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt; [1] =&amp;gt; pointer to link_map (used
by resolver)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;&lt;span lang=&quot;ZH-CN&quot; style=&quot;font-family: DengXian; mso-ansi-language: EN-US; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin;&quot;&gt;├──&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt; [2] =&amp;gt; address of function
(e.g., printf)&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class=&quot;MsoNormal&quot; style=&quot;margin-left: 36pt;&quot;&gt;Please note this is not the end. If you want to call printf, you will need to implement the gnu version table and hash algorithm. I tried both old hash algorithm and new hash algorithm, both works. My environemnt is QEMU and StarFive2 Ubuntu Linux.&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/659525533557965576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/659525533557965576' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/659525533557965576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/659525533557965576'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/02/riscv-assembly-gotplt-index-calculation.html' title='RiscV Assembly Got/PLT index Calculation'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-8018249126758588101</id><published>2026-01-13T22:15:00.001-05:00</published><updated>2026-01-13T22:15:06.661-05:00</updated><title type='text'>Rust Macro </title><content type='html'>&lt;div&gt;Rust macro is an interesting topic and it provides a way to generate code on the fly. One of the problem for Rust programmer is the code is not easy to understand, especially for compiler and low level programming.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The code is located at&amp;nbsp;&lt;a href=&quot;https://github.com/ttliu2000/rust_macro&quot;&gt;ttliu2000/rust_macro: Rust macro project to make rust programming easier.&lt;/a&gt;&amp;nbsp;which making my assembler / linker project code simpler. My background is C# and I will keep everything private and use accessor methods to access the code, which is heavy boilerplate code. Using the macro make the code more readable.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks to ChatGPT&#39;s help, I quickly start the project and get the feature in. So if you start to create macro, ask GPT first.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/8018249126758588101/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/8018249126758588101' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/8018249126758588101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/8018249126758588101'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/01/rust-macro.html' title='Rust Macro '/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-755386331016723149</id><published>2026-01-01T05:14:00.001-05:00</published><updated>2026-01-01T05:14:24.844-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ELF"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>Tao&#39;s Fragments: RiscV Linux lib ELF Generation</title><content type='html'>Today is Jan 1st, 2026. And I will be back with what is meaningful. Years ago, I decide to start a new journey. After working on Rust, Linux OS, ELF file format, RiscV chip/ABI, and assembler and linker, and started C language compiler. Let&#39;s see how compiler tech and latest AI can change how technology can make programmer&#39;s life easier.&amp;nbsp;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I feel I can start blog again and share some fragments of my work and ready for open source.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I&#39;ve done the ELF executable with dynamic link support, it means that I can use my assembler+linker to generate ELF binary to invoke printf in libc. I&#39;ve to say the RISCV&#39;s PLT/GOT RELA is really a headache, which can be topic for another fragemnt of mine. 😉&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today I finished the .so file generation and it can generate a library can be linked with gcc. Now I know why F# choose to support library after executable is done. And I know why F# library has its own printf. But anyway.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The .so ELF generation is simple, my test .s file is listed below. Please note that i added my own pseudo instruction for RiscV assembly language.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style=&quot;border: none; margin: 0 0 0 40px; padding: 0px;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div&gt;.data&lt;/div&gt;&lt;div&gt;.extern printf&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;tt_fmt: .string &quot;%d\n&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;const_float_or_string_value_104:&lt;/div&gt;&lt;div&gt;.string &quot;Array index access test, expected value 42 and actual value: %d\n&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;.text&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;.globl&amp;nbsp; add2&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; .type&amp;nbsp; &amp;nbsp;add2, @function&lt;/div&gt;&lt;div&gt;&lt;b&gt;add2:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; add&amp;nbsp; &amp;nbsp; &amp;nbsp;a0, a0, a1&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; ret&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; &lt;b&gt;.size&amp;nbsp; &amp;nbsp;add2, .-add2&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; exit 42&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;The .extern will trigger dynamic symbol structure generation. The key here is the add2 function related instruction which is in bold font.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;globl add2 is to add &quot;add2&quot; to the dynamic symbol (.dynsym) table.&lt;/li&gt;&lt;li&gt;add2 shows the starting point of add2 function and it will be used to compute the size of the add2 function.&amp;nbsp;&lt;/li&gt;&lt;li&gt;.size show the add2&#39;s size is equal to current (the small dot) minus add2.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;After these info being added to dynamic symbol table, the readelf -a shows the following:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiCnOlJXubPz4n6F5n2pjCtvW_N2Ov3V5LwVKSTzXj1GikEa3kI3W7I1suibQi0913ywbX1JLUePDZRJ823yrgUcdyYMu6HZTLNZKMpWDEdhO3m5RJfKAljvYjf4vkoIBlI8tuaEiEYXAl51qNZ_Cc9JijOBA_tF8wYuRmCRtoxK6AsLkGKD5Aky_nMu3A&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;232&quot; data-original-width=&quot;1177&quot; height=&quot;79&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEiCnOlJXubPz4n6F5n2pjCtvW_N2Ov3V5LwVKSTzXj1GikEa3kI3W7I1suibQi0913ywbX1JLUePDZRJ823yrgUcdyYMu6HZTLNZKMpWDEdhO3m5RJfKAljvYjf4vkoIBlI8tuaEiEYXAl51qNZ_Cc9JijOBA_tF8wYuRmCRtoxK6AsLkGKD5Aky_nMu3A=w400-h79&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;the riscv64 gcc link can link this shared library with c code and command is listed below:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote style=&quot;border: none; margin: 0 0 0 40px; padding: 0px;&quot;&gt;&lt;div&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;int add2(int a, int b);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;int main() {&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; printf(&quot;%d\n&quot;, add2(20, 22));&lt;/div&gt;&lt;div&gt;&amp;nbsp; &amp;nbsp; return 0;&lt;/div&gt;&lt;div&gt;}&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi_WdlANhsKdQm34pPrrFH2BqY4QjdpFOy2t427diRRiS_YZRD0XkIdBUbOis0ZVy24BbTpPrLqGefqhu8jOI3X6HZfKQigY2Pd8n2DYNoK9GyGH_6LjPLOysf-sJEPqKt3HCCo8bpaeDBeZVMDCeVCItkZKA0rS_Tgw3OCoYbd2Whu1MT7J2qms-T02-8&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;54&quot; data-original-width=&quot;1275&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEi_WdlANhsKdQm34pPrrFH2BqY4QjdpFOy2t427diRRiS_YZRD0XkIdBUbOis0ZVy24BbTpPrLqGefqhu8jOI3X6HZfKQigY2Pd8n2DYNoK9GyGH_6LjPLOysf-sJEPqKt3HCCo8bpaeDBeZVMDCeVCItkZKA0rS_Tgw3OCoYbd2Whu1MT7J2qms-T02-8=w640-h28&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;and the exeuction result shows 42 which is 20 + 22 from add2(20, 22).&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg-kTBkXlMUXAegy_2Fx1LmJ04kavXQ8FYtHx9fUfJzcQAITiehM_gkiJ4CN1A3uZZSmLbC6bFNGGo2NQsYzQDlvjmQLHkFvbRpwNlXZi0NBkrbgKk5-D20Tn3qNpyN3JxVDQ8Q8tOfC49uuHLt_GJmsT-v81z91V-f8qmLWBVXLJtku71pcrXf7nGRCc4&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;101&quot; data-original-width=&quot;1480&quot; height=&quot;28&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEg-kTBkXlMUXAegy_2Fx1LmJ04kavXQ8FYtHx9fUfJzcQAITiehM_gkiJ4CN1A3uZZSmLbC6bFNGGo2NQsYzQDlvjmQLHkFvbRpwNlXZi0NBkrbgKk5-D20Tn3qNpyN3JxVDQ8Q8tOfC49uuHLt_GJmsT-v81z91V-f8qmLWBVXLJtku71pcrXf7nGRCc4=w400-h28&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks to ChatGPT&#39;s which helps me to generate Linux command. Being a long time windows guy, I am still struggle to use correct Linux language, but let&#39;s see if this can change when I add more feature.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/755386331016723149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/755386331016723149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/755386331016723149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/755386331016723149'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2026/01/taos-fragments-riscv-linux-lib-elf.html' title='Tao&#39;s Fragments: RiscV Linux lib ELF Generation'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEiCnOlJXubPz4n6F5n2pjCtvW_N2Ov3V5LwVKSTzXj1GikEa3kI3W7I1suibQi0913ywbX1JLUePDZRJ823yrgUcdyYMu6HZTLNZKMpWDEdhO3m5RJfKAljvYjf4vkoIBlI8tuaEiEYXAl51qNZ_Cc9JijOBA_tF8wYuRmCRtoxK6AsLkGKD5Aky_nMu3A=s72-w400-h79-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-2513465990098052290</id><published>2025-12-19T14:01:00.002-05:00</published><updated>2025-12-19T14:01:10.691-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="RISCV"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>Compiler AST &amp; Mermaid</title><content type='html'>&lt;div&gt;I&#39;m interested in RISC compiler for a while. One of the challenge of a compiler is to process AST. Being a visual person, I am interested in seeing the structure in an image. So I generate the mermaid state diagram and can visualize the tree.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjw_l0jiVqbCYZSQtG1M8V_67r71maSHkJZ8QtczGEokreIClNR4eL8_aX-jDWDGcnQD3qjurYEAw_wgpQ1gLnPyWuxi0DeMQwRI54FVX9otaDq64QAd_Xq33cbvPdX0ZKuOSBtSOqpeejQyi-TNmtm3oLAPjjq89jqA7cDXOqYMbs27TBWyVNsYCE8TrI&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;&quot; data-original-height=&quot;1138&quot; data-original-width=&quot;1609&quot; height=&quot;453&quot; src=&quot;https://blogger.googleusercontent.com/img/a/AVvXsEjw_l0jiVqbCYZSQtG1M8V_67r71maSHkJZ8QtczGEokreIClNR4eL8_aX-jDWDGcnQD3qjurYEAw_wgpQ1gLnPyWuxi0DeMQwRI54FVX9otaDq64QAd_Xq33cbvPdX0ZKuOSBtSOqpeejQyi-TNmtm3oLAPjjq89jqA7cDXOqYMbs27TBWyVNsYCE8TrI=w640-h453&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/2513465990098052290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/2513465990098052290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/2513465990098052290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/2513465990098052290'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2025/12/compiler-ast-mermaid.html' title='Compiler AST &amp; Mermaid'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/a/AVvXsEjw_l0jiVqbCYZSQtG1M8V_67r71maSHkJZ8QtczGEokreIClNR4eL8_aX-jDWDGcnQD3qjurYEAw_wgpQ1gLnPyWuxi0DeMQwRI54FVX9otaDq64QAd_Xq33cbvPdX0ZKuOSBtSOqpeejQyi-TNmtm3oLAPjjq89jqA7cDXOqYMbs27TBWyVNsYCE8TrI=s72-w640-h453-c" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-8996169504459711118</id><published>2020-10-18T10:40:00.005-04:00</published><updated>2020-10-18T10:54:51.436-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>SelfNote: Enable Python in Visual Studio Interactive</title><content type='html'>&lt;div&gt;This note is to document how to configure Python interactive window in Visual Studio (not VS Code)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Reference a local library&lt;/h3&gt;&lt;div&gt;When I added a new .py file in the project, I cannot add it to the python interact window. The reason is the default path for python interact is under &quot;program files&quot;. The following command is to change the current working folder to a new folder:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px; text-align: left;&quot;&gt;&lt;div&gt;&lt;div&gt;import os&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;os.chdir(r&quot;c:\mycode\xyz\&quot;)&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Make sure the string is started with &quot;r&quot;.&amp;nbsp;&lt;/p&gt;&lt;h3 style=&quot;text-align: left;&quot;&gt;Reload a library&lt;/h3&gt;&lt;div style=&quot;text-align: left;&quot;&gt;After change a library, the new content is not loaded to the python interactive session by default. The following command is to reload the library into the session.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;import myModule &lt;span style=&quot;color: #38761d;&quot;&gt;#import my module&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;color: #6aa84f;&quot;&gt;#the following is to reload myModule&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;import importlib&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;blockquote style=&quot;border: none; margin: 0px 0px 0px 40px; padding: 0px;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;p style=&quot;text-align: left;&quot;&gt;importlib.reload(myModule&amp;nbsp;)&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Please note: myModule does not need quote or double quote&amp;nbsp;&lt;/p&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/8996169504459711118/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/8996169504459711118' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/8996169504459711118'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/8996169504459711118'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2020/10/selfnote-enable-python-in-visual-studio.html' title='SelfNote: Enable Python in Visual Studio Interactive'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-9182210136275142915</id><published>2020-08-07T14:54:00.001-04:00</published><updated>2020-08-07T14:54:07.397-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms"/><title type='text'>Matrix Multiplication &amp; Graph Reachable</title><content type='html'>&lt;div&gt;I have been struggling to find a good way to represent graph structure. There are number of graph library where Node and Edge are defined. I found that matrix can be used to represent a graph.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The row and column of the matrix represent the node in a graph. The element in the matrix is connection between two nodes. In a graph, this connection is called Edge. The following diagram represents a graph with 3 nodes and 3 edges.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmIO0Mp1aBwtTQe2TFCGnTzDEzVLCcOXZ6YAhWY-yDVhH0h1xIyh-n4L23ECtB5FC9MD1aNajZxFEkGwyPTnG3TGUgmVa9hUAdzEsyhK2MAnl0YZjqBDX-NsGCJ4xaUqH4ZE1Mfjt1LlQ/s396/Graph.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;300&quot; data-original-width=&quot;396&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmIO0Mp1aBwtTQe2TFCGnTzDEzVLCcOXZ6YAhWY-yDVhH0h1xIyh-n4L23ECtB5FC9MD1aNajZxFEkGwyPTnG3TGUgmVa9hUAdzEsyhK2MAnl0YZjqBDX-NsGCJ4xaUqH4ZE1Mfjt1LlQ/s0/Graph.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;In a matrix representation, it can be written as a matrix. Row and column are named A, B, and C. If there is an edge between two nodes, the corresponding cell is set to 1. For example, edge AB shows 1 in cell (A, B) in the grid. We can denote this matrix as M&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiArns20V0flVrkXpfCWCXa9h6QMEGgYZysytrbaRlLW-DEVgNCcAqhGl5IFjOfdsuADZSQhjuBDiKTpV_L5w4bSWP7YA_IMMRjADFSGuaCYTBpAaru7YXGAyEW8fikmZxuolgz1kq4IaY/s261/Matrix.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;174&quot; data-original-width=&quot;261&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiArns20V0flVrkXpfCWCXa9h6QMEGgYZysytrbaRlLW-DEVgNCcAqhGl5IFjOfdsuADZSQhjuBDiKTpV_L5w4bSWP7YA_IMMRjADFSGuaCYTBpAaru7YXGAyEW8fikmZxuolgz1kq4IaY/s0/Matrix.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Matrix &quot;multiplication&quot; to itself can reveal if a certain node can reach the other nodes in two steps. The &quot;multiplication&quot; operation is different from the linear algebra matrix multiplication.&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;blockquote&gt;K = M ⊗ M&lt;/blockquote&gt;&lt;p&gt;&amp;nbsp;Each element b in N can be calculated by the following formula, where N is the number of the nodes (or the column number of the matrix M).&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgmWPhTb_gvwdr4VJDixaFvRn_eK2XhCniTxY8FFYmhQ4b0zAbx6vyiKOxARCaatGqg8yGBpzcGZrg17QZIQ6DpWi1U7XsF1sK8YBwUQYnnirsr3UTVjRUP-R1jRcEXnmHBJw7UIgU8Q/s257/MatrixOp.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;145&quot; data-original-width=&quot;257&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMgmWPhTb_gvwdr4VJDixaFvRn_eK2XhCniTxY8FFYmhQ4b0zAbx6vyiKOxARCaatGqg8yGBpzcGZrg17QZIQ6DpWi1U7XsF1sK8YBwUQYnnirsr3UTVjRUP-R1jRcEXnmHBJw7UIgU8Q/s0/MatrixOp.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Two nodes i and j. If there j is reachable from i, either of the following two conditions are met:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;there is a direct edge between i and j&amp;nbsp;&lt;/li&gt;&lt;li&gt;there is a node p which is reachable from i and p can reach j&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Written as math language in the matrix M&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;M(i, j) = 1&lt;/li&gt;&lt;li&gt;彐p, M(i, p) = 1 and M(p, j) = 1&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Repeat the &quot;multiplication&quot; operation &lt;i&gt;logN&lt;/i&gt; times, it can calculate any node in a graph can be reachable from other nodes.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Finally, I can move away from a complicated node/edge definition into a formal math world. Hopefully the existing linear algebra can help me down the road.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/9182210136275142915/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/9182210136275142915' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/9182210136275142915'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/9182210136275142915'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2020/08/matrix-multiplication-graph-reachable.html' title='Matrix Multiplication &amp; Graph Reachable'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmIO0Mp1aBwtTQe2TFCGnTzDEzVLCcOXZ6YAhWY-yDVhH0h1xIyh-n4L23ECtB5FC9MD1aNajZxFEkGwyPTnG3TGUgmVa9hUAdzEsyhK2MAnl0YZjqBDX-NsGCJ4xaUqH4ZE1Mfjt1LlQ/s72-c/Graph.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-1633002526701951798</id><published>2020-02-19T18:11:00.001-05:00</published><updated>2020-02-19T18:11:46.268-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="New Machine"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>SelfNote: VSCode setup </title><content type='html'>Recently I started to use the Azure cloud machine to do my coding work. I can still do my coding in my laptop using full Visual Studio but an Azure VM with VSCode will be much convenient. Low tech but works. :)&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The following VSCode setup script helps me set up a new machine:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;open PowerShell&amp;nbsp;&lt;/li&gt;
&lt;li&gt;copy extension names to the clipboard (yes, Ctrl+C)&lt;/li&gt;
&lt;li&gt;run &lt;b&gt;get-clipboard | % { code --install-extension $_ }&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
DavidAnson.vscode-markdownlint&lt;/div&gt;
&lt;div&gt;
eamodio.gitlens&lt;/div&gt;
&lt;div&gt;
ms-azuretools.vscode-docker&lt;/div&gt;
&lt;div&gt;
ms-python.python&lt;/div&gt;
&lt;div&gt;
ms-vscode-remote.remote-wsl&lt;/div&gt;
&lt;div&gt;
ms-vscode.cpptools&lt;/div&gt;
&lt;div&gt;
ms-vscode.powershell&lt;/div&gt;
&lt;div&gt;
npclaudiu.vscode-gn&lt;/div&gt;
&lt;div&gt;
yzhang.markdown-all-in-one&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/1633002526701951798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/1633002526701951798' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1633002526701951798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1633002526701951798'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2020/02/selfnote-vscode-setup.html' title='SelfNote: VSCode setup '/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-1456481236792695192</id><published>2020-02-03T22:56:00.000-05:00</published><updated>2020-02-03T22:56:01.103-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>Docker  Image build clean up using PowerShell on local PC</title><content type='html'>When I run the docker image to do the debug on PC, I was struggling to keep the hard disk space consumption low and running the recent binary in &quot;Docker on Windows Desktop&quot;. This development stage, so I won&#39;t consider the Azure cloud for hosting.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I need a script to reclaim hard disk, remove the currently running container, build and run the new image in docker on windows desktop.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The following code first removes unused images and then gets the image running on the port 5555. I will have to play the string replace tricks using PowerShell. Please check &quot;-replace&quot; part for details.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
#prune unused image&lt;/div&gt;
&lt;div&gt;
docker image prune -f&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
#remove existing running docker image&lt;/div&gt;
&lt;div&gt;
$a = docker container ls --filter expose=5555&lt;/div&gt;
&lt;div&gt;
$a2 = $a | foreach-object {$_ -replace &#39;\s{3,}&#39;, &#39;&amp;nbsp; &#39;} | foreach-object {$_ -replace &#39;&amp;nbsp; &#39;, &quot;`t&quot;}&lt;/div&gt;
&lt;div&gt;
$obj = ConvertFrom-Csv -InputObject $a2 -Delimiter &quot;`t&quot;&lt;/div&gt;
&lt;div&gt;
if ($obj -ne $null)&lt;/div&gt;
&lt;div&gt;
{&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; docker rm -f&amp;nbsp; $obj.names&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;div&gt;
else&lt;/div&gt;
&lt;div&gt;
{&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; Write-Verbose &quot;cannot find running container image so won&#39;t remove&quot;&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
#build flask app and set its version to 1&lt;/div&gt;
&lt;div&gt;
docker build -t flaskapp:1 .&lt;/div&gt;
&lt;div&gt;
docker run -d -p 5555:5555 flaskapp:1&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
#test running instance&lt;/div&gt;
&lt;div&gt;
sleep -s 4&lt;/div&gt;
&lt;div&gt;
invoke-restmethod &quot;http://localhost:5555/api/health&quot;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/1456481236792695192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/1456481236792695192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1456481236792695192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1456481236792695192'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2020/02/docker-image-build-clean-up-using.html' title='Docker  Image build clean up using PowerShell on local PC'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-3335852786239452517</id><published>2020-01-19T10:26:00.002-05:00</published><updated>2020-01-26T12:09:27.749-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="NLP"/><category scheme="http://www.blogger.com/atom/ns#" term="Python"/><category scheme="http://www.blogger.com/atom/ns#" term="Self Note"/><title type='text'>SelfNote: Setup Spacy Module in Visual Studio</title><content type='html'>&lt;div&gt;
I guess not so many people use Visual Studio doing NLP with Python. I have been searching for a solution on how to add a Spacy module in Visual Studio. I kept getting cannot find en_core_web_sm module error and the only solution I could find is to run python -m spacy download en_core_web_sm. I was struggling to find where in the UI to run the Python command. And finally, the solution came.&lt;br /&gt;
&lt;br /&gt;
you noticed the &quot;Admin&quot; icon? yes, that is the key to solve the problem. With admin permission, you can open PowerShell and run &lt;b&gt;python -m spacy download en_core_web_sm&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
I installed en_core_web_sm, but it shows a warning message. And the &lt;b&gt;en_core_web_lg&lt;/b&gt; module can eliminate the warning.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDx08E9k9AqxJwB2m30Ihbn68NRIizXzJaBgwcmIXd-v_weCGKE3QCGyxMJhIWzoWhGu8SV91BQx1_CIygYqV37NmaDGbgq9uIdkznC38Mh-fLNNIV-wk2HHfDoN2KICxPdTtOvrYQ4P0/s1600/PythonVSModule.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;463&quot; data-original-width=&quot;690&quot; height=&quot;214&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDx08E9k9AqxJwB2m30Ihbn68NRIizXzJaBgwcmIXd-v_weCGKE3QCGyxMJhIWzoWhGu8SV91BQx1_CIygYqV37NmaDGbgq9uIdkznC38Mh-fLNNIV-wk2HHfDoN2KICxPdTtOvrYQ4P0/s320/PythonVSModule.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;script&gt;
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&quot;//platform.twitter.com/widgets.js&quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&quot;script&quot;,&quot;twitter-wjs&quot;);
&lt;/script&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/3335852786239452517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/3335852786239452517' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3335852786239452517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3335852786239452517'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2020/01/selfnote-setup-spacy-module-in-visual.html' title='SelfNote: Setup Spacy Module in Visual Studio'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDx08E9k9AqxJwB2m30Ihbn68NRIizXzJaBgwcmIXd-v_weCGKE3QCGyxMJhIWzoWhGu8SV91BQx1_CIygYqV37NmaDGbgq9uIdkznC38Mh-fLNNIV-wk2HHfDoN2KICxPdTtOvrYQ4P0/s72-c/PythonVSModule.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-1605391298023365083</id><published>2020-01-06T14:53:00.001-05:00</published><updated>2020-01-06T18:52:53.963-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="NLP"/><category scheme="http://www.blogger.com/atom/ns#" term="PowerShell"/><category scheme="http://www.blogger.com/atom/ns#" term="WSL"/><title type='text'>Standford NLP Quick Setup on Win10 with WSL</title><content type='html'>After setting up the &lt;a href=&quot;https://apollo13cn.blogspot.com/2018/11/move-nlp-ikvm-to-f.html&quot;&gt;Stanford NLP&lt;/a&gt; on my PC, I was struggling with how to run it faster. Then I ran into Windows Subsystem for Linux (WSL). I realize that the modification of Stanford NLP is not an option for me. I can use WSL to quickly start an NLP web service and start my work.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I ordered a more powerful VM from Azure and use PowerShell to set up the NLP environment.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;Enable WSL&lt;br /&gt;&lt;br /&gt;Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux&lt;br /&gt;&lt;br /&gt;It will trigger a reboot if WSL is not enabled&lt;/li&gt;
&lt;li&gt;Add Ubuntu disco to WSL&lt;br /&gt;&lt;br /&gt;# download ubuntu 18.04 as save it as Ubuntu.appx at local directory&lt;br /&gt;Invoke-WebRequest -Uri https://aka.ms/wsl-ubuntu-1804 -OutFile Ubuntu.appx -UseBasicParsing&lt;br /&gt;&lt;br /&gt;# add Ubuntu.appx to WSL&lt;br /&gt;Add-package Ubuntu.appx&lt;/li&gt;
&lt;li&gt;Download Standard NLP zip file and unzip it to the current folder&lt;br /&gt;&lt;br /&gt;# download the Stanford NLP and save the zip file locally as &quot;corenlp.zip&quot;&lt;br /&gt;Invoke-WebRequest -uri http://nlp.stanford.edu/software/stanford-corenlp-full-2018-10-05.zip -outfile corenlp.zip -UseBasicParsing&lt;br /&gt;&lt;br /&gt;# unzip the corenlp.zip&lt;br /&gt;Expand-Archive corenlp.zip -DestinationPath .\CoreNlp\&lt;/li&gt;
&lt;li&gt;install Java in WSL. Since Stanford NLP does not require Oracle Java, so I use Open Java to make the command shorter&lt;br /&gt;&lt;br /&gt;wsl sudo apt-get update&lt;br /&gt;wsl sudo apt-get install default-jdk&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
I go into WSL from PowerShell and launch Stanford NLP from WSL.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;go to WSL from Powershell by using &quot;wsl&quot;&lt;/li&gt;
&lt;li&gt;go to the folder which stores the unzipped Stanford NLP files in step 3&lt;/li&gt;
&lt;li&gt;run&amp;nbsp;java -mx4g -cp &quot;*&quot; edu.stanford.nlp.pipeline.StanfordCoreNLPServer&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Open Edge and go to http://localhost:9000/, it will show similar UI like http://corenlp.run.&lt;br /&gt;
&lt;br /&gt;
The PowerShell script used to access the localhost 9000 ports are listed below:&lt;br /&gt;
&lt;br /&gt;
$data = &quot;The quick brown fox jumped over the lazy dog.&quot;&lt;br /&gt;
$url2 = &#39;http://localhost:9000/?properties={&quot;annotators&quot;:&quot;tokenize,ssplit,pos,lemma,ner, entitymentions,depparse,parse,relation,openie,dcoref,kbp&quot;,&quot;outputFormat&quot;:&quot;json&quot;}&#39;&lt;br /&gt;
$r = Invoke-RestMethod -Uri $url2 -Method post -Body $data&lt;br /&gt;
&lt;br /&gt;
The annotators are listed &lt;a href=&quot;https://stanfordnlp.github.io/CoreNLP/annotators.html&quot;&gt;here &lt;/a&gt;in case you need it.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/1605391298023365083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/1605391298023365083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1605391298023365083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/1605391298023365083'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2020/01/standford-nlp-quick-setup-on-win10-with.html' title='Standford NLP Quick Setup on Win10 with WSL'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-6448468746320690338</id><published>2019-09-02T15:48:00.000-04:00</published><updated>2019-09-02T15:48:14.567-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Performance"/><title type='text'>6-Year-Old Rule?</title><content type='html'>The story begins recently I am indulging in the quantum computing programming whose foundation involves a lot of linear algebra. The direct consequence is I want to solve almost all problems using the complex number, vector, and matrix. The Mars Rover problem got my attention.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
The rover on the Mars surface only takes L, R, and M instruction. L means turn left. R means turn right. M means move 1 step forward. If the initial position is (0, 0) and facing North, what will be the location and facing direction after receiving couples of instructions?&amp;nbsp;&lt;/blockquote&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
This is a perfect opportunity to practice my math, I thought. The direction and location are all complex numbers. I can manipulate numbers to make the code concise! I convert the L, R, and M instruction to complex number &lt;i&gt;op&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;turn left L is complex (0, 1) where the real part is 0 and the imaginary part is 1&lt;/li&gt;
&lt;li&gt;turn right R is complex (0, -1)&lt;/li&gt;
&lt;li&gt;move forward M is complex number (1, 0)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The new location and direction can be computed like the following:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;new location += op.Real * Direction&amp;nbsp; //L and R&#39;s real part is 0, so it does not move location&lt;/li&gt;
&lt;li&gt;new direction *= op&amp;nbsp; //M is 1, so it has no effect on the direction&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
It looks cool and code is concise. I avoided those unpleasant&amp;nbsp;&lt;i&gt;switch &lt;/i&gt;statements.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Everything looks satisfying until I realize those expensive &lt;i&gt;multiply &lt;/i&gt;operations might be a performance problem. I wrote a simple solution using those &lt;i&gt;switch &lt;/i&gt;statements. The simple solution doubled the code. However, the performance is 30+% faster than my &quot;elegant&quot; one!&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I told my wife what was going on when I encountered her in the kitchen, with a little bit of frustration. She smiled and pointed my 6-year-old son. &quot;If the solution can be understand by him, it must be faster.&quot; she said, &quot;It requires a smaller brain so it runs faster.&quot;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Well, both algorithms are &lt;i&gt;O(n)&lt;/i&gt;. Maybe next time, I should think on the big O level.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/6448468746320690338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/6448468746320690338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/6448468746320690338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/6448468746320690338'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2019/09/6-year-old-rule.html' title='6-Year-Old Rule?'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-8781803083930526797</id><published>2019-03-03T11:27:00.000-05:00</published><updated>2019-03-03T11:27:00.339-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms"/><category scheme="http://www.blogger.com/atom/ns#" term="Q#"/><category scheme="http://www.blogger.com/atom/ns#" term="Quantum"/><title type='text'>Old stuff: my first IEEE paper on Computational Intelligence</title><content type='html'>Before I finished my college, I managed to publish a paper on evolutionary&amp;nbsp;computation (EC). The paper is on the encoding part. My next task is to use quantum to rewrite my algorithm. Well, there is a quantum genetic algorithm (QGA) there. However, I think with the latest decision on&amp;nbsp;&lt;a href=&quot;https://apollo13cn.blogspot.com/2018/12/microsoft-q-is-my-choice.html&quot;&gt;Q#&lt;/a&gt; and &lt;a href=&quot;https://apollo13cn.blogspot.com/2018/12/selfnotes-quantum-algorithms.html&quot;&gt;quantum algorithms&lt;/a&gt;. The paper link is &lt;a href=&quot;https://drive.google.com/file/d/1p3kRkEsVU2T_L_FVvxJ6y6J4O1Xa1kjI/view?usp=sharing&quot;&gt;here&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/8781803083930526797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/8781803083930526797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/8781803083930526797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/8781803083930526797'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2019/03/old-stuff-my-first-ieee-paper-on.html' title='Old stuff: my first IEEE paper on Computational Intelligence'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-2627112612242132237</id><published>2019-01-19T16:19:00.000-05:00</published><updated>2019-01-19T16:19:14.848-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Q#"/><category scheme="http://www.blogger.com/atom/ns#" term="Quantum"/><title type='text'>Microsoft Q# Day 1: Qubit Collapsed</title><content type='html'>After going through the &lt;a href=&quot;https://apollo13cn.blogspot.com/2018/12/selfnotes-quantum-algorithms.html&quot;&gt;quantum linear algebra&lt;/a&gt;, I am going to see some quantum concept by using Q#.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The first one I want to prove is measurement will collapse the qubit. I will use the AssertProb to verify the value with probability. The pseudo code is listed below:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;use H gate to set the qubit to superposition&lt;/li&gt;
&lt;li&gt;check the probability to 1 equals 0.5 (50%)&lt;/li&gt;
&lt;li&gt;measure the qubit&lt;/li&gt;
&lt;li&gt;check the qubit equals the measured value equals to 1 (100%). The qubit collapsed.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
the code listed below:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;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&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;namespace&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Quantum&lt;/span&gt;.&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;QSharpApplication2&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;open&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Microsoft&lt;/span&gt;.&lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Quantum&lt;/span&gt;.&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Primitive&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;open&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Microsoft&lt;/span&gt;.&lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Quantum&lt;/span&gt;.&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Canon&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
 &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;open&lt;/span&gt; &lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Microsoft&lt;/span&gt;.&lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Quantum&lt;/span&gt;.&lt;span style=&quot;color: #0e84b5; font-weight: bold;&quot;&gt;Extensions&lt;/span&gt;.&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Convert&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;

    operation &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Operation1&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;()&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Unit&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
        body&lt;span style=&quot;color: #333333;&quot;&gt;(...)&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            using &lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ancilla &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Qubit&lt;/span&gt;&lt;span style=&quot;color: #007020;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;H&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ancilla&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

    &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;AssertProb&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;PauliZ&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;ancilla&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Zero&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
    &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;AssertProb&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;([&lt;/span&gt;&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;PauliZ&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;ancilla&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;One&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;mutable&lt;/span&gt; gate &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;PauliZ&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;;&lt;/span&gt;
    &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;let&lt;/span&gt; mX &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Measure&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;([&lt;/span&gt;gate&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;ancilla&lt;span style=&quot;color: #333333;&quot;&gt;]);&lt;/span&gt;
    &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;AssertProb&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;([&lt;/span&gt;gate&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;ancilla&lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt; mX&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;e&lt;span style=&quot;color: #333333;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;

    &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Message&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;ToStringD&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;mX &lt;span style=&quot;color: #333333;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Zero&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;?&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #0000dd; font-weight: bold;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;.));&lt;/span&gt;

    &lt;span style=&quot;color: #bb0066; font-weight: bold;&quot;&gt;Reset&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;(&lt;/span&gt;ancilla&lt;span style=&quot;color: #333333;&quot;&gt;);&lt;/span&gt;
   &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/2627112612242132237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/2627112612242132237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/2627112612242132237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/2627112612242132237'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2019/01/microsoft-q-day-1-qubit-collapsed.html' title='Microsoft Q# Day 1: Qubit Collapsed'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-3635307520114890748</id><published>2018-12-26T21:59:00.000-05:00</published><updated>2018-12-26T21:59:11.369-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms"/><category scheme="http://www.blogger.com/atom/ns#" term="Quantum"/><title type='text'>Microsoft Q# is my choice</title><content type='html'>Today I am thinking to dig into the real quantum programming after learning the &lt;a href=&quot;https://apollo13cn.blogspot.com/2018/12/selfnotes-quantum-algorithms.html&quot;&gt;foundation &lt;/a&gt;part. There are three big players I was looking at on quantum programming framework/language. I hate to waste my time learning the framework or language itself. I&amp;nbsp;want to focus on so I can focus on solving the problem. I have three choices:&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;IBM, IBM Q&lt;/li&gt;
&lt;li&gt;Google Cirq&lt;/li&gt;
&lt;li&gt;Microsoft Q#&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
It seems IBM Q and Cirq are reusing the Python to provide a framework while Q# is a brand new language. It makes sense IBM and Google use Python as base as it has a good math library. However, I doubt this choice is the best choice. Like the GPU, quantum is special hardware. Cuda is a&amp;nbsp;like C language but it has its own features. For quantum computing, it has a totally different way to compute.&amp;nbsp;Therefore, I think the best way to use a new language, maybe it is just a DSL. C++ can be used to write a functional program, but the best way is still to use a functional programming language.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Also, the examples from those three companies show a huge difference. Q# provides the best sample pack so far. It has a quantum foundation, matrix computation, and programming language. It will help me a lot to adopt this new stuff.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The setup and debugging is the last thought. I had tried to step away from Microsoft stack; however, the debugging and the setup needs more time I expected. I was spoiled by double click and just working.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Anyway, the current Q# shows good progress and the watch, star, and pull request number is bigger than other players. I will continue to focus on the quantum basics, like matrix and math part, anyway.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/3635307520114890748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/3635307520114890748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3635307520114890748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/3635307520114890748'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2018/12/microsoft-q-is-my-choice.html' title='Microsoft Q# is my choice'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-6965459095221097316</id><published>2018-12-23T21:27:00.000-05:00</published><updated>2019-01-02T20:40:47.055-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Algorithms"/><category scheme="http://www.blogger.com/atom/ns#" term="Quantum"/><title type='text'>SelfNotes: Quantum Algorithms</title><content type='html'>I believe the quantum computing is the key to enable real AI. No matter how complicated the AI algorithm can be, the fundamental&amp;nbsp;computing power will make a real difference.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The huge difference between a classical computer and a quantum computer is so intriguing! It is the&amp;nbsp;first time that math can come back to computer science and guide its evolution. Also, the quantum algorithm is the first time it introduces the internal parallelism. Those existing algorithms barely considered parallelism when it is designed. Now the quantum can change this situation!&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The following are some notes about quantum algorithms. They are not related to any language implementation, it is just pure math. The only tool I want to use is &quot;that piece of meat between my ears&quot;. :)&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZqUF4Lh7VMyg8chHuEnMmg9VUl9pam2Sl58zVnlMenDhqB0Y0gUH_hyphenhyphen1EHs1Y4k5sdD2OeF15rCU_AG92wfUX-H6UhLXa-cE_I402ZVXe0F6usOs5L62Fmlk7_ogeAkQw4pKvoOgHb80/s1600/IMG_6394.HEIC&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZqUF4Lh7VMyg8chHuEnMmg9VUl9pam2Sl58zVnlMenDhqB0Y0gUH_hyphenhyphen1EHs1Y4k5sdD2OeF15rCU_AG92wfUX-H6UhLXa-cE_I402ZVXe0F6usOs5L62Fmlk7_ogeAkQw4pKvoOgHb80/s320/IMG_6394.HEIC&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjwCwqX9f8FpErgKBN8SEUe3R-LRGIlhpfLoXdh0_RlPyAWLUPqsKUPWKhh1ifzk0VvXX__rw7LVK-s77m-U7qrLtlHRHYej5ODdjwc1S4y2yyXQezbT-6fsTBbhGqrXaH1fQcTRabesM/s1600/IMG_6364.HEIC&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjwCwqX9f8FpErgKBN8SEUe3R-LRGIlhpfLoXdh0_RlPyAWLUPqsKUPWKhh1ifzk0VvXX__rw7LVK-s77m-U7qrLtlHRHYej5ODdjwc1S4y2yyXQezbT-6fsTBbhGqrXaH1fQcTRabesM/s320/IMG_6364.HEIC&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh72Y6WwLsOada-qcqTu1VcrCJh7KkJ1i4LF5oMI0ykbSPhhDhwntddKuTRz9mSigKJNsp6ddJ5Wn9-7PdJriIIHc-VXTMiqeU_N8zPO2oZqNaSKPMZf8V37bjAXPYettviyF-akckAe60/s1600/IMG_6344.HEIC&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh72Y6WwLsOada-qcqTu1VcrCJh7KkJ1i4LF5oMI0ykbSPhhDhwntddKuTRz9mSigKJNsp6ddJ5Wn9-7PdJriIIHc-VXTMiqeU_N8zPO2oZqNaSKPMZf8V37bjAXPYettviyF-akckAe60/s320/IMG_6344.HEIC&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9hzoatEQ6F8sOEqtYCz_nVa-bHRQcCd0HKa0exMnCpVOT3JOYy0DV4QaXdWCfkOSUPMSNhZQMTwD90WG0ezC6dstlaIOJ_MLsXlTMN-Roh7QtY2w6VdftZawDCbRVPnAoRE2PDzENHJQ/s1600/IMG_6182.HEIC&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9hzoatEQ6F8sOEqtYCz_nVa-bHRQcCd0HKa0exMnCpVOT3JOYy0DV4QaXdWCfkOSUPMSNhZQMTwD90WG0ezC6dstlaIOJ_MLsXlTMN-Roh7QtY2w6VdftZawDCbRVPnAoRE2PDzENHJQ/s320/IMG_6182.HEIC&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinbo2tJVPYu6QmX5B_Lz8w4gVmeyVxP2mz-SXW_Xzo4ePTAGaiLSoRoG8QVvvxuVCgPql7zElNhGhdK4Q8soc2YrxiFYDS_zhewI5yajOATJ5QIJhecxAr2XLaiueP_hXrKPz_7X1ZxmA/s1600/IMG_6411.HEIC&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1600&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinbo2tJVPYu6QmX5B_Lz8w4gVmeyVxP2mz-SXW_Xzo4ePTAGaiLSoRoG8QVvvxuVCgPql7zElNhGhdK4Q8soc2YrxiFYDS_zhewI5yajOATJ5QIJhecxAr2XLaiueP_hXrKPz_7X1ZxmA/s320/IMG_6411.HEIC&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH9DfUlHS-LaSCfxiDSnVEQe_YamZnu7RYYEkFvo8lB8z_-GWU4pGFnIFG_9jOc3s9rtNuYAiNnIQNrjraGnQ1MIX_WXyKVxmgSFwN8_ocpy1rMX-9Fil91x5kYgs49Qq_dDmOZYxS2Fk/s1600/IMG_6410.HEIC&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH9DfUlHS-LaSCfxiDSnVEQe_YamZnu7RYYEkFvo8lB8z_-GWU4pGFnIFG_9jOc3s9rtNuYAiNnIQNrjraGnQ1MIX_WXyKVxmgSFwN8_ocpy1rMX-9Fil91x5kYgs49Qq_dDmOZYxS2Fk/s320/IMG_6410.HEIC&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/6965459095221097316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/6965459095221097316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/6965459095221097316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/6965459095221097316'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2018/12/selfnotes-quantum-algorithms.html' title='SelfNotes: Quantum Algorithms'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZqUF4Lh7VMyg8chHuEnMmg9VUl9pam2Sl58zVnlMenDhqB0Y0gUH_hyphenhyphen1EHs1Y4k5sdD2OeF15rCU_AG92wfUX-H6UhLXa-cE_I402ZVXe0F6usOs5L62Fmlk7_ogeAkQw4pKvoOgHb80/s72-c/IMG_6394.HEIC" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4100091590694628472.post-4431919605448057384</id><published>2018-12-08T13:58:00.000-05:00</published><updated>2018-12-08T14:45:54.393-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Automation"/><category scheme="http://www.blogger.com/atom/ns#" term="NodeJS"/><category scheme="http://www.blogger.com/atom/ns#" term="TypeScript"/><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio"/><title type='text'>Automation with NodeJS-Puppeteer &amp; Visual Studio Code</title><content type='html'>I saw many attempts to automate the processing using commercial software. However, I do not see this is necessary if this task is not that huge. When more and more application is moving to the web-based. Automation of the&amp;nbsp;Chrome browser will automate most of the scenarios. Therefore, I feel 90% of those cases won&#39;t need to pay and still get the job done.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
First, we need to set up IDE. There are three files needs to be updated and placed in the place. Please make sure you put launch.json and tasks.json are under .vscode&amp;nbsp;folder.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;launch.json: it is used to launch the application with predefined tasks such as Typescript build.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;tsconfig.json is to used to build the application using Puppeteer&lt;/li&gt;
&lt;li&gt;tasks.json is to define the Typescript build process&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijiwxBwrwdqMlI114BraX9c0h4t1CsCEWo1MM8LkE8uELI97SSm5pAGFhhPXkVW9htg27AWO3uVP7BlHjeCt99VtDWxx-JiRClMXtNTS8yPWr_YI1E16pPp5NQSSJMlkVEwItEjwBTWoE/s1600/VSCodeIDE.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;281&quot; data-original-width=&quot;183&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijiwxBwrwdqMlI114BraX9c0h4t1CsCEWo1MM8LkE8uELI97SSm5pAGFhhPXkVW9htg27AWO3uVP7BlHjeCt99VtDWxx-JiRClMXtNTS8yPWr_YI1E16pPp5NQSSJMlkVEwItEjwBTWoE/s1600/VSCodeIDE.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
The content of these three files&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;launch.json&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;/div&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;// Use IntelliSense to learn about possible attributes.&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;// Hover to view descriptions of existing attributes.&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387&lt;/span&gt;
    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;0.2.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;configurations&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;request&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;launch&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;Launch Program&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;sourceMaps&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;preLaunchTask&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;TSC&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;program&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;${workspaceFolder}/app.ts&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;outFiles&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;
                &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;${workspaceFolder}/**/*.js&quot;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;]&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;&#39;&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;tasks.json&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;// See https://go.microsoft.com/fwlink/?LinkId=733558&lt;/span&gt;
    &lt;span style=&quot;color: #888888;&quot;&gt;// for the documentation about the tasks.json format&lt;/span&gt;
    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;2.0.0&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;tasks&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;label&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;TSC&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;typescript&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;tsconfig&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;tsconfig.json&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;problemMatcher&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;
                &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;$tsc&quot;&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;],&lt;/span&gt;
            &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;group&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;{&lt;/span&gt;
                &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;kind&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;/span&gt;
                &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;isDefault&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #007020;&quot;&gt;true&lt;/span&gt;
            &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
        &lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
    &lt;span style=&quot;color: #333333;&quot;&gt;]&lt;/span&gt;
&lt;span style=&quot;color: #333333;&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;tsconfig.json&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;{
    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;compilerOptions&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; {
        &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;target&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;es5&quot;&lt;/span&gt;,
        &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;module&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;commonjs&quot;&lt;/span&gt;,        
        &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;lib&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; [&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;es2015&quot;&lt;/span&gt;, &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;dom&quot;&lt;/span&gt;],
        &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;sourceMap&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;true&lt;/span&gt;
    },
    &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;include&quot;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; [
        &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;src&quot;&lt;/span&gt;,
        &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&quot;node_modules/@types/puppeteer/index.d.ts&quot;&lt;/span&gt;
      ]
}
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The &lt;b&gt;node_modules&lt;/b&gt; folder is created from the npm&amp;nbsp;command provided by the NodeJS framework. The command to run is listed the following. The first line is to install TypeScript compiler which is not installed by default with VS Code. The second line is to install Puppeteer. The last line is to install the library for Typescript to work with Puppeteer.&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
2
3&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;npm i -g typescript
npm i --save puppeteer
npm i --save-dev &lt;span style=&quot;color: #996633;&quot;&gt;@types&lt;/span&gt;/puppeteer
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
The last file is the Puppeteer file:&lt;br /&gt;
&lt;br /&gt;
&lt;!-- HTML generated using hilite.me --&gt;&lt;br /&gt;
&lt;div style=&quot;background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;&quot;&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;1
 2
 3
 4
 5
 6
 7
 8
 9
10&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;pre style=&quot;line-height: 125%; margin: 0;&quot;&gt;&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #333333;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;as&lt;/span&gt; puppeteer from &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;puppeteer&#39;&lt;/span&gt;
 
(async () &lt;span style=&quot;color: #333333;&quot;&gt;=&amp;gt;&lt;/span&gt; {
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;const&lt;/span&gt; browser &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; await puppeteer.launch();
  &lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;const&lt;/span&gt; page &lt;span style=&quot;color: #333333;&quot;&gt;=&lt;/span&gt; await browser.newPage();
  await page.&lt;span style=&quot;color: #008800; font-weight: bold;&quot;&gt;goto&lt;/span&gt;(&lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;http://www.google.com&#39;&lt;/span&gt;);
  await page.screenshot({path&lt;span style=&quot;color: #333333;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;background-color: #fff0f0;&quot;&gt;&#39;example.png&#39;&lt;/span&gt;});
 
  await browser.close();
})();
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://apollo13cn.blogspot.com/feeds/4431919605448057384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/4100091590694628472/4431919605448057384' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/4431919605448057384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4100091590694628472/posts/default/4431919605448057384'/><link rel='alternate' type='text/html' href='http://apollo13cn.blogspot.com/2018/12/automation-with-nodejs-puppeteer-visual.html' title='Automation with NodeJS-Puppeteer &amp; Visual Studio Code'/><author><name>Tao</name><uri>http://www.blogger.com/profile/10181624105046973883</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijiwxBwrwdqMlI114BraX9c0h4t1CsCEWo1MM8LkE8uELI97SSm5pAGFhhPXkVW9htg27AWO3uVP7BlHjeCt99VtDWxx-JiRClMXtNTS8yPWr_YI1E16pPp5NQSSJMlkVEwItEjwBTWoE/s72-c/VSCodeIDE.PNG" height="72" width="72"/><thr:total>0</thr:total></entry></feed>