<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kernel on bramp.net</title>
    <link>https://blog.bramp.net/</link>
    <description>Recent content in Kernel on bramp.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-GB</language>
    <lastBuildDate>Mon, 10 Aug 2009 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.bramp.net/tags/kernel/" rel="self" type="application/rss+xml" />
    
    <item>
      <title>memcmp broken in the FreeBSD kernel</title>
      <link>https://blog.bramp.net/post/2009/08/10/memcmp-broken-in-the-freebsd-kernel/</link>
      <pubDate>Mon, 10 Aug 2009 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2009/08/10/memcmp-broken-in-the-freebsd-kernel/</guid>
      <description><p>I’ve spent a day tracking down a bug in a FreeBSD kernel module I’m developing, and to my surprise the bug was due to memcmp being broken! For those that don’t know, memcmp is used to compare two byte strings and returns 0 if they are identical, a negative number of the first string is less than the second, and a positive number of the first string is greater than the second.</p>
<p>However, the implementation of memcmp in the FreeBSD kernel looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">static</span> <span class="kr">__inline</span> <span class="kt">int</span>
</span></span><span class="line"><span class="cl"><span class="nf">memcmp</span><span class="p">(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">b1</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">b2</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">len</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">(</span><span class="nf">bcmp</span><span class="p">(</span><span class="n">b1</span><span class="p">,</span> <span class="n">b2</span><span class="p">,</span> <span class="n">len</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The problem with this is that bcmp is defined to return 0 if the strings are identical, otherwise returns a non-zero integer. This is not the same as memcmp, and you would only notice this if you are testing the signedness of the return value. I suspect this has not been noticed because traditionally FreeBSD has favoured bcmp, and in the few cases it does uses memcmp it only compares it with zero.</p>
<p>There is some good news, obrien@ noticed this problem in September 2008 and commited a patch (svn r183299). However, it looks like this fix won’t be included until FreeBSD 8.0. In the mean time I’m implementing a minor hack to fix this.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">my_memcmp</span><span class="p">(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">s1</span><span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span><span class="n">s2</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="o">*</span><span class="n">p1</span> <span class="o">=</span> <span class="n">s1</span><span class="p">,</span> <span class="o">*</span><span class="n">p2</span> <span class="o">=</span> <span class="n">s2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">		<span class="k">do</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="p">(</span><span class="o">*</span><span class="n">p1</span><span class="o">++</span> <span class="o">!=</span> <span class="o">*</span><span class="n">p2</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">				<span class="k">return</span> <span class="p">(</span><span class="o">*--</span><span class="n">p1</span> <span class="o">-</span> <span class="o">*--</span><span class="n">p2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="o">--</span><span class="n">n</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="k">return</span> <span class="p">(</span><span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="cp">#define memcmp my_memcmp
</span></span></span></code></pre></div></description>
    </item>
    
    <item>
      <title>Autoload symbols for FreeBSD kernel module</title>
      <link>https://blog.bramp.net/post/2009/01/11/autoload-symbols-for-freebsd-kernel-module/</link>
      <pubDate>Sun, 11 Jan 2009 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bramp.net/post/2009/01/11/autoload-symbols-for-freebsd-kernel-module/</guid>
      <description><p>When debugging FreeBSD kernel modules with GDB, you have to tell GDB the correct symbols for the module, and the location the module is loaded in RAM. This is helpfully explained in the <a href="http://www.freebsd.org/doc/en/books/developers-handbook/kerneldebug-kld.html">FreeBSD Developers’ Handbook</a>. First you must load the module, then run kldstat, note down the address the module is loaded at, and finally execute a command in GDB that looks like the following.</p>
<pre tabindex="0"><code>add-symbol-file /sys/modules/linux/linux.ko 0xc0ae22d0
</code></pre><p>However, I find this process tedious, so instead I wrote a quick python script which can be used with an <a href="http://sourceware.org/gdb/wiki/PythonGdb">experimental gdb built with python scripting support</a>.</p>
<p>So here is the script:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">gdb</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">FreeBSD_ReloadModuleSymbols</span> <span class="p">(</span><span class="n">gdb</span><span class="o">.</span><span class="n">Command</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">	<span class="s2">&#34;Reloads the symbol files for all loaded kernel modules&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">def</span> <span class="fm">__init__</span> <span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">		<span class="nb">super</span> <span class="p">(</span><span class="n">FreeBSD_ReloadModuleSymbols</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span> <span class="p">(</span><span class="s2">&#34;reload-freebsd-module-symbols&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="n">gdb</span><span class="o">.</span><span class="n">COMMAND_FILES</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="n">gdb</span><span class="o">.</span><span class="n">COMPLETE_NONE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">def</span> <span class="nf">invoke</span> <span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arg</span><span class="p">,</span> <span class="n">from_tty</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">		<span class="n">link</span> <span class="o">=</span> <span class="n">gdb</span><span class="o">.</span><span class="n">parse_and_eval</span><span class="p">(</span><span class="s2">&#34;linker_files-&amp;gt;tqh_first&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">		<span class="k">while</span> <span class="n">link</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">			<span class="nb">print</span> <span class="n">link</span><span class="p">[</span><span class="s1">&#39;filename&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">string</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">			<span class="k">if</span> <span class="n">link</span><span class="p">[</span><span class="s1">&#39;filename&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">string</span><span class="p">()</span> <span class="o">!=</span> <span class="s2">&#34;kernel&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">				<span class="n">gdb</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span> <span class="s2">&#34;add-symbol-file &#34;</span> <span class="o">+</span> 
</span></span><span class="line"><span class="cl">					<span class="n">link</span><span class="p">[</span><span class="s1">&#39;pathname&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">string</span><span class="p">()</span> <span class="o">+</span> <span class="s2">&#34; &#34;</span> <span class="o">+</span>  
</span></span><span class="line"><span class="cl">					<span class="nb">str</span><span class="p">(</span><span class="n">link</span><span class="p">[</span><span class="s1">&#39;address&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">address</span><span class="p">())</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">			<span class="n">link</span> <span class="o">=</span> <span class="n">link</span><span class="p">[</span><span class="s1">&#39;link&#39;</span><span class="p">][</span><span class="s1">&#39;tqe_next&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">FreeBSD_ReloadModuleSymbols</span> <span class="p">()</span>
</span></span></code></pre></div><p>You load this by running the following command in GDB:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">source</span> freebsd_load_modules.py
</span></span></code></pre></div><p>Then the command <code>reload-freebsd-module-symbols</code> is magically added to GDB. Running this command will parse the linker table inside the FreeBSD kernel, determine which modules are loaded, and attempt to load their symbols.</p>
</description>
    </item>
    
  </channel>
</rss>
