6xxx strlen and 9xxx conclusions.
[libguestfs-talks.git] / 2020-frama-c / 6200-strlen-2.html
diff --git a/2020-frama-c/6200-strlen-2.html b/2020-frama-c/6200-strlen-2.html
new file mode 100644 (file)
index 0000000..5e27410
--- /dev/null
@@ -0,0 +1,51 @@
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<link rel="stylesheet" href="style.css" type="text/css"/>
+<script src="code.js" type="text/javascript"></script>
+
+<h1>glibc strlen (part 2)</h1>
+
+<pre class="code">
+  const unsigned long int *longword_ptr;
+  unsigned long int longword, himagic, lomagic;
+
+  longword_ptr = (unsigned long int *) char_ptr;
+
+  himagic = 0x80808080L;
+  lomagic = 0x01010101L;
+  himagic = ((himagic << 16) << 16) | himagic;
+  lomagic = ((lomagic << 16) << 16) | lomagic;
+
+  for (;;)
+    {
+      longword = *longword_ptr++;
+
+      if (((longword - lomagic) & ~longword & himagic) != 0)
+       {
+         <span class="comment">/* Which of the bytes was the zero?  If none of them were, it was
+            a misfire; continue the search.  */</span>
+
+         const char *cp = (const char *) (longword_ptr - 1);
+
+         if (cp[0] == 0)
+           return cp - str;
+         if (cp[1] == 0)
+           return cp - str + 1;
+         if (cp[2] == 0)
+           return cp - str + 2;
+         if (cp[3] == 0)
+           return cp - str + 3;
+         if (sizeof (longword) > 4)
+           {
+             if (cp[4] == 0)
+               return cp - str + 4;
+             if (cp[5] == 0)
+               return cp - str + 5;
+             if (cp[6] == 0)
+               return cp - str + 6;
+             if (cp[7] == 0)
+               return cp - str + 7;
+           }
+       }
+    }
+}
+</pre>