<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 17, 2015 at 2:38 AM, Daniel Sanders <span dir="ltr"><<a href="mailto:Daniel.Sanders@imgtec.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=Daniel.Sanders@imgtec.com&cc=&bcc=&su=&body=','_blank');return false;">Daniel.Sanders@imgtec.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div lang="EN-GB" link="blue" vlink="purple">
<div><span class="">
<p class="MsoNormal">> I forgot to ask you to document the fuzzer at <a href="http://llvm.org/docs/LibFuzzer.html#fuzzing-components-of-llvm" target="_blank">http://llvm.org/docs/LibFuzzer.html#fuzzing-components-of-llvm</a><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
</span><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">Will do<u></u><u></u></span></p><span class="">
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal">> One problem: with the current structure of flags libFuzzer's -jobs=10 does not work... <u></u><u></u></p>
<p class="MsoNormal">> Thoughts? <u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
</span><p class="MsoNormal">Hmm. I see why that happens, each spawned thread is calling system() to spawn a subprocess and that system() call is given a command built from the fuzzer config. The resulting command lacks any of the non-fuzzer args and so the child llvm-mc-fuzzer
is trying to parse arguments meant for the underlying fuzzer. Why does it spawn a subprocess from the worker thread instead of doing the work directly inside the worker thread? Am I right in thinking that it's to stop a crash in one job from killing everything?<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">I can think of four options:<u></u><u></u></p>
<p><u></u><span>1.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:'Times New Roman'">
</span></span><u></u>fork() the new process instead of using system(). After the fork, the child should remove the effects of –job by setting it to 0 and reopen its stdout/stderr to achieve the same effect. This removes the need to reconstruct and reparse
the command line since fork() will duplicate the result of the parse in the child process. Unfortunately, I don't think there's a direct Windows equivalent to this outside of Cygwin.<u></u><u></u></p>
<p><u></u><span style="font-size:11pt;font-family:Calibri,sans-serif"><span>2.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:'Times New Roman'">
</span></span></span><u></u>Separate fuzzer option parsing from the driver call. I'm thinking something along the lines of this quick sketch:<br>
FlagDescription *Config = FuzzerDriver::ParseFlags(FuzzerArgv);<br>
return FuzzerDriver::FuzzerDriver(argv, Config, DisassembleOneInput);<br>
That would allow argv to differ from the options the fuzzer understands which are in FuzzerArgv.<span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u><u></u></span></p>
<p><u></u><span style="font-size:11pt;font-family:Calibri,sans-serif"><span>3.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:'Times New Roman'">
</span></span></span><u></u>Make it possible to extend the fuzzer option parsing. The CommandLine library can do this nicely but you probably don't want the additional dependency in libFuzzer. Llvm-mc-fuzzer could always change to libFuzzer's approach to
command line parsing.<span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u><u></u></span></p>
<p><u></u><span>4.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7pt;line-height:normal;font-family:'Times New Roman'">
</span></span><u></u>Make it possible to modify the command before the system() call. The client of libFuzzer could install a callback that allows it to modify a std::vector containing the desired Argv.</p></div></div></blockquote><div><br></div><div>I frankly like none of these, will need to think about it more... </div><div>It's probably not urgent for this particular fuzzer -- llvm-mc has pretty small inputs and we can fuzz lots out of it in a single process. </div><div>But will need to figure out for future uses like this. </div><div>Maybe, </div><div> 5. Add a libFuzzer option -target_options=-option1,param,-option2 </div><div>and run llvm-mc-fuzzer like "./bin/llvm-mc-fuzzer -target_options=-triple,x86_64-linux-gnu,-disassemble</div><div><br></div><div>BTW, I've found one llvm_unreachable with -triple x86_64-linux-gnu already... will file a bug. <br></div><div><br></div><div><br></div><div><br></div><div>--kcc </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-GB" link="blue" vlink="purple"><div><p><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif">If all OS's had fork() then I'd favour #1 but Windows rules that out. Out of the rest #2 is seems the most flexible but #3/#4 are simpler. What's your opinion?<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif"><u></u> <u></u></span></p>
<div style="border-style:none none none solid;border-left-color:blue;border-left-width:1.5pt;padding:0cm 0cm 0cm 4pt">
<div>
<div style="border-style:solid none none;border-top-color:rgb(181,196,223);border-top-width:1pt;padding:3pt 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:10pt;font-family:Tahoma,sans-serif">From:</span></b><span lang="EN-US" style="font-size:10pt;font-family:Tahoma,sans-serif"> Kostya Serebryany [mailto:<a href="mailto:kcc@google.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=kcc@google.com&cc=&bcc=&su=&body=','_blank');return false;">kcc@google.com</a>]
<br>
<b>Sent:</b> 17 September 2015 05:38<br>
<b>To:</b> Daniel Sanders<br>
<b>Cc:</b> LLVM Commits<br>
<b>Subject:</b> Re: [llvm] r247786 - llvm-mc-fuzzer: A fuzzing tool for the MC layer.<u></u><u></u></span></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">One problem: with the current structure of flags libFuzzer's -jobs=10 does not work... <u></u><u></u></p>
<div>
<p class="MsoNormal">Thoughts? <u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Wed, Sep 16, 2015 at 9:25 PM, Kostya Serebryany <<a href="mailto:kcc@google.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=kcc@google.com&cc=&bcc=&su=&body=','_blank');return false;">kcc@google.com</a>> wrote:<u></u><u></u></p>
<div>
<p class="MsoNormal">Cool! I'll add it to the bot when time permits. <u></u><u></u></p>
<div>
<p class="MsoNormal">I forgot to ask you to document the fuzzer<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">at <a href="http://llvm.org/docs/LibFuzzer.html#fuzzing-components-of-llvm" target="_blank">http://llvm.org/docs/LibFuzzer.html#fuzzing-components-of-llvm</a><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Feel free to do it w/o prior review. <u></u><u></u></p>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Wed, Sep 16, 2015 at 4:49 AM, Daniel Sanders via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=llvm-commits@lists.llvm.org&cc=&bcc=&su=&body=','_blank');return false;">llvm-commits@lists.llvm.org</a>> wrote:<u></u><u></u></p>
<p class="MsoNormal">Author: dsanders<br>
Date: Wed Sep 16 06:49:49 2015<br>
New Revision: 247786<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=247786&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=247786&view=rev</a><br>
Log:<br>
llvm-mc-fuzzer: A fuzzing tool for the MC layer.<br>
<br>
Summary:<br>
Only the disassembler is supported in this patch but it has already found a few<br>
issues in the Mips disassembler (mostly invalid instructions being successfully<br>
disassembled).<br>
<br>
Reviewers: kcc<br>
<br>
Subscribers: russell.gallop, silvas, kcc, llvm-commits<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D12723" target="_blank">http://reviews.llvm.org/D12723</a><br>
<br>
Added:<br>
llvm/trunk/tools/llvm-mc-fuzzer/<br>
llvm/trunk/tools/llvm-mc-fuzzer/CMakeLists.txt<br>
llvm/trunk/tools/llvm-mc-fuzzer/llvm-mc-fuzzer.cpp<br>
Modified:<br>
llvm/trunk/docs/LibFuzzer.rst<br>
<br>
Modified: llvm/trunk/docs/LibFuzzer.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LibFuzzer.rst?rev=247786&r1=247785&r2=247786&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LibFuzzer.rst?rev=247786&r1=247785&r2=247786&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/LibFuzzer.rst (original)<br>
+++ llvm/trunk/docs/LibFuzzer.rst Wed Sep 16 06:49:49 2015<br>
@@ -453,7 +453,14 @@ Trophies<br>
<br>
* llvm-as: <a href="https://llvm.org/bugs/show_bug.cgi?id=24639" target="_blank">
https://llvm.org/bugs/show_bug.cgi?id=24639</a><br>
<br>
-<br>
+ * Disassembler:<br>
+ * Mips: Discovered a number of untested instructions for the Mips target<br>
+ (see valid-mips*.s in <a href="http://reviews.llvm.org/rL247405" target="_blank">
http://reviews.llvm.org/rL247405</a>,<br>
+ <a href="http://reviews.llvm.org/rL247414" target="_blank">http://reviews.llvm.org/rL247414</a>,
<a href="http://reviews.llvm.org/rL247416" target="_blank">http://reviews.llvm.org/rL247416</a>,<br>
+ <a href="http://reviews.llvm.org/rL247417" target="_blank">http://reviews.llvm.org/rL247417</a>,
<a href="http://reviews.llvm.org/rL247420" target="_blank">http://reviews.llvm.org/rL247420</a>,<br>
+ and <a href="http://reviews.llvm.org/rL247422" target="_blank">http://reviews.llvm.org/rL247422</a>) as well some instructions that<br>
+ successfully disassembled on ISA's where they were not valid (see<br>
+ invalid-xfail.s files in the same commits).<br>
<br>
.. _pcre2: <a href="http://www.pcre.org/" target="_blank">http://www.pcre.org/</a><br>
<br>
<br>
Added: llvm/trunk/tools/llvm-mc-fuzzer/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc-fuzzer/CMakeLists.txt?rev=247786&view=auto" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc-fuzzer/CMakeLists.txt?rev=247786&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-mc-fuzzer/CMakeLists.txt (added)<br>
+++ llvm/trunk/tools/llvm-mc-fuzzer/CMakeLists.txt Wed Sep 16 06:49:49 2015<br>
@@ -0,0 +1,18 @@<br>
+if( LLVM_USE_SANITIZE_COVERAGE )<br>
+ include_directories(BEFORE<br>
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/Fuzzer)<br>
+<br>
+ set(LLVM_LINK_COMPONENTS<br>
+ AllTargetsDescs<br>
+ AllTargetsDisassemblers<br>
+ AllTargetsInfos<br>
+ MC<br>
+ MCDisassembler<br>
+ Support<br>
+ )<br>
+ add_llvm_tool(llvm-mc-fuzzer<br>
+ llvm-mc-fuzzer.cpp)<br>
+ target_link_libraries(llvm-mc-fuzzer<br>
+ LLVMFuzzerNoMain<br>
+ )<br>
+endif()<br>
<br>
Added: llvm/trunk/tools/llvm-mc-fuzzer/llvm-mc-fuzzer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc-fuzzer/llvm-mc-fuzzer.cpp?rev=247786&view=auto" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc-fuzzer/llvm-mc-fuzzer.cpp?rev=247786&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-mc-fuzzer/llvm-mc-fuzzer.cpp (added)<br>
+++ llvm/trunk/tools/llvm-mc-fuzzer/llvm-mc-fuzzer.cpp Wed Sep 16 06:49:49 2015<br>
@@ -0,0 +1,129 @@<br>
+//===--- llvm-mc-fuzzer.cpp - Fuzzer for the MC layer ---------------------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm-c/Disassembler.h"<br>
+#include "llvm-c/Target.h"<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/MC/SubtargetFeature.h"<br>
+#include "llvm/Support/CommandLine.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+#include "FuzzerInterface.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+const unsigned AssemblyTextBufSize = 80;<br>
+<br>
+enum ActionType {<br>
+ AC_Assemble,<br>
+ AC_Disassemble<br>
+};<br>
+<br>
+static cl::opt<ActionType><br>
+Action(cl::desc("Action to perform:"),<br>
+ cl::init(AC_Assemble),<br>
+ cl::values(clEnumValN(AC_Assemble, "assemble",<br>
+ "Assemble a .s file (default)"),<br>
+ clEnumValN(AC_Disassemble, "disassemble",<br>
+ "Disassemble strings of hex bytes"),<br>
+ clEnumValEnd));<br>
+<br>
+static cl::opt<std::string><br>
+ TripleName("triple", cl::desc("Target triple to assemble for, "<br>
+ "see -version for available targets"));<br>
+<br>
+static cl::opt<std::string><br>
+ MCPU("mcpu",<br>
+ cl::desc("Target a specific cpu type (-mcpu=help for details)"),<br>
+ cl::value_desc("cpu-name"), cl::init(""));<br>
+<br>
+static cl::list<std::string><br>
+ MAttrs("mattr", cl::CommaSeparated,<br>
+ cl::desc("Target specific attributes (-mattr=help for details)"),<br>
+ cl::value_desc("a1,+a2,-a3,..."));<br>
+// The feature string derived from -mattr's values.<br>
+std::string FeaturesStr;<br>
+<br>
+static cl::list<std::string><br>
+ FuzzerArgv("fuzzer-args", cl::Positional,<br>
+ cl::desc("Options to pass to the fuzzer"), cl::ZeroOrMore,<br>
+ cl::PositionalEatsArgs);<br>
+<br>
+void DisassembleOneInput(const uint8_t *Data, size_t Size) {<br>
+ char AssemblyText[AssemblyTextBufSize];<br>
+<br>
+ std::vector<uint8_t> DataCopy(Data, Data + Size);<br>
+<br>
+ LLVMDisasmContextRef Ctx = LLVMCreateDisasmCPUFeatures(<br>
+ TripleName.c_str(), MCPU.c_str(), FeaturesStr.c_str(), nullptr, 0,<br>
+ nullptr, nullptr);<br>
+ assert(Ctx);<br>
+ uint8_t *p = DataCopy.data();<br>
+ unsigned Consumed;<br>
+ do {<br>
+ Consumed = LLVMDisasmInstruction(Ctx, p, Size, 0, AssemblyText,<br>
+ AssemblyTextBufSize);<br>
+ Size -= Consumed;<br>
+ p += Consumed;<br>
+ } while (Consumed != 0);<br>
+ LLVMDisasmDispose(Ctx);<br>
+}<br>
+<br>
+int main(int argc, char **argv) {<br>
+ // The command line is unusual compared to other fuzzers due to the need to<br>
+ // specify the target. Options like -triple, -mcpu, and -mattr work like<br>
+ // their counterparts in llvm-mc, while -fuzzer-args collects options for the<br>
+ // fuzzer itself.<br>
+ //<br>
+ // Examples:<br>
+ //<br>
+ // Fuzz the big-endian MIPS32R6 disassembler using 100,000 inputs of up to<br>
+ // 4-bytes each and use the contents of ./corpus as the test corpus:<br>
+ // llvm-mc-fuzzer -triple mips-linux-gnu -mcpu=mips32r6 -disassemble \<br>
+ // -fuzzer-args -max_len=4 -runs=100000 ./corpus<br>
+ //<br>
+ // Infinitely fuzz the little-endian MIPS64R2 disassembler with the MSA<br>
+ // feature enabled using up to 64-byte inputs:<br>
+ // llvm-mc-fuzzer -triple mipsel-linux-gnu -mcpu=mips64r2 -mattr=msa \<br>
+ // -disassemble -fuzzer-args ./corpus<br>
+ //<br>
+ // If your aim is to find instructions that are not tested, then it is<br>
+ // advisable to constrain the maximum input size to a single instruction<br>
+ // using -max_len as in the first example. This results in a test corpus of<br>
+ // individual instructions that test unique paths. Without this constraint,<br>
+ // there will be considerable redundancy in the corpus.<br>
+<br>
+ LLVMInitializeAllTargetInfos();<br>
+ LLVMInitializeAllTargetMCs();<br>
+ LLVMInitializeAllDisassemblers();<br>
+<br>
+ cl::ParseCommandLineOptions(argc, argv);<br>
+<br>
+ // Package up features to be passed to target/subtarget<br>
+ // We have to pass it via a global since the callback doesn't<br>
+ // permit any user data.<br>
+ if (MAttrs.size()) {<br>
+ SubtargetFeatures Features;<br>
+ for (unsigned i = 0; i != MAttrs.size(); ++i)<br>
+ Features.AddFeature(MAttrs[i]);<br>
+ FeaturesStr = Features.getString();<br>
+ }<br>
+<br>
+ // Insert the program name into the FuzzerArgv.<br>
+ FuzzerArgv.insert(FuzzerArgv.begin(), argv[0]);<br>
+<br>
+ if (Action == AC_Assemble)<br>
+ errs() << "error: -assemble is not implemented\n";<br>
+ else if (Action == AC_Disassemble)<br>
+ return fuzzer::FuzzerDriver(FuzzerArgv, DisassembleOneInput);<br>
+<br>
+ llvm_unreachable("Unknown action");<br>
+ return 1;<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=llvm-commits@lists.llvm.org&cc=&bcc=&su=&body=','_blank');return false;">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><u></u><u></u></p>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div></div>
</div>
</div>
</blockquote></div><br></div></div>