Page MenuHomePhabricator

[libFuzzer] Enable on i386
ClosedPublic

Authored by metzman on Apr 24 2019, 7:52 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

metzman created this revision.Apr 24 2019, 7:52 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptApr 24 2019, 7:52 AM
Herald added subscribers: llvm-commits, Restricted Project, mgorny. · View Herald Transcript
metzman updated this revision to Diff 196463.Apr 24 2019, 8:40 AM
  • fix comment
metzman updated this revision to Diff 196465.Apr 24 2019, 8:48 AM
  • change order
metzman retitled this revision from [libFuzzer] Enable for i386 to [libFuzzer] Enable on i386.Apr 24 2019, 8:51 AM
metzman marked an inline comment as done.

Please take a look.

compiler-rt/cmake/config-ix.cmake
233 ↗(On Diff #196465)

Should I explicitly disable i386 on non-Linux if I don't really care about them?
When I tested this it didn't get built on Windows which I'm fine with.

kcc removed a reviewer: kcc.Apr 25 2019, 5:59 PM

Matt, please take a look.

compiler-rt/test/fuzzer/fork.test
15 ↗(On Diff #196465)

no need for a regex, just remove extra zeroes.

compiler-rt/test/fuzzer/lit.cfg
28 ↗(On Diff #196465)

That's not true:

% clang++ -m32 -fsanitize=address ~/misc-c/leak.cc && ./a.out

132478==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:

#0 0x810cf89 in operator new(unsigned int) /usr/local/google/home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:105:3
#1 0x8063e01 in __cxx_global_var_init (/usr/local/google/home/kcc/llvm-build/a.out+0x8063e01)
#2 0x8063e68 in _GLOBAL__sub_I_leak.cc (/usr/local/google/home/kcc/llvm-build/a.out+0x8063e68)
#3 0x810f63a in __libc_csu_init (/usr/local/google/home/kcc/llvm-build/a.out+0x810f63a)

SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).

morehouse added inline comments.Apr 26 2019, 11:26 AM
compiler-rt/lib/fuzzer/CMakeLists.txt
128 ↗(On Diff #196465)

Why is this argument necessary?

compiler-rt/test/fuzzer/dataflow.test
2 ↗(On Diff #196465)

Any idea why this fails on x86?

compiler-rt/test/fuzzer/only-some-bytes.test
2 ↗(On Diff #196465)

Any idea why this doesn't work for x86?

compiler-rt/test/fuzzer/trace-malloc-threaded.test
4 ↗(On Diff #196465)

Any idea why this doesn't work for x86?

metzman updated this revision to Diff 197125.Apr 29 2019, 8:59 AM
metzman marked 9 inline comments as done.
  • remove stale comment
  • remove extra zeros
  • fix broken test
metzman added inline comments.Apr 29 2019, 9:08 AM
compiler-rt/lib/fuzzer/CMakeLists.txt
128 ↗(On Diff #196465)

Without it we get this error: /usr/bin/ld: Relocatable linking with relocations from format elf32-i386 (/home/user/llvm-build/lib/clang/9.0.0/lib/linux/libclang_rt.fuzzer-i386.a(FuzzerCrossOver.cpp.o)) to format elf64-x86-64 (fuzzer.o) is not supported

Interestingly, this has been a problem with libFuzzer before, see here.

compiler-rt/test/fuzzer/dataflow.test
2 ↗(On Diff #196465)

Dataflow afaik only supports x86_64 Linux.

compiler-rt/test/fuzzer/fork.test
15 ↗(On Diff #196465)

Done.

compiler-rt/test/fuzzer/lit.cfg
28 ↗(On Diff #196465)

My bad, stale comment.

compiler-rt/test/fuzzer/only-some-bytes.test
2 ↗(On Diff #196465)

Dataflow afaik only supports x86_64 Linux.

compiler-rt/test/fuzzer/trace-malloc-threaded.test
4 ↗(On Diff #196465)

Got it working, it's because most of the i386 addresses begin with 0xf instead of 0x[0-9]

morehouse added inline comments.Apr 29 2019, 9:48 AM
compiler-rt/lib/fuzzer/CMakeLists.txt
128 ↗(On Diff #196465)

The error sounds like we're trying to mix 32-bit and 64-bit. So maybe we should address that instead?

I also notice that the documentation for some linkers (gold) say that -m is obsolete.

metzman marked an inline comment as done.Apr 29 2019, 3:17 PM
metzman added inline comments.
compiler-rt/lib/fuzzer/CMakeLists.txt
128 ↗(On Diff #196465)

The error sounds like we're trying to mix 32-bit and 64-bit.

I'm not sure this the case.

The command that causes this failure is

/usr/bin/ld --whole-archive /home/user/llvm-project/build-x862/lib/clang/9.0.0/lib/linux/libclang_rt.fuzzer-i386.a --no-whole-archive /home/user/llvm-project/build-x862/projects/compiler-rt/lib/fuzzer/libcxx_fuzzer_i386/lib/libc++.a -r -o fuzzer.o

Minimized:

/usr/bin/ld -r --whole-archive /home/user/llvm-project/build-x862/lib/clang/9.0.0/lib/linux/libclang_rt.fuzzer-i386.a -o fuzzer.o

But /home/user/llvm-project/build-x862/lib/clang/9.0.0/lib/linux/libclang_rt.fuzzer-i386.a only contains 32 bit code afaict:

objdump -d /home/user/llvm-project/build-x862/lib/clang/9.0.0/lib/linux/libclang_rt.fuzzer_no_main-i386.a | grep "\.o"
FuzzerCrossOver.cpp.o:     file format elf32-i386
FuzzerDataFlowTrace.cpp.o:     file format elf32-i386
FuzzerDriver.cpp.o:     file format elf32-i386
FuzzerExtFunctionsDlsym.cpp.o:     file format elf32-i386
FuzzerExtFunctionsWeak.cpp.o:     file format elf32-i386
FuzzerExtFunctionsWindows.cpp.o:     file format elf32-i386
FuzzerExtraCounters.cpp.o:     file format elf32-i386
FuzzerFork.cpp.o:     file format elf32-i386
FuzzerIO.cpp.o:     file format elf32-i386
FuzzerIOPosix.cpp.o:     file format elf32-i386
FuzzerIOWindows.cpp.o:     file format elf32-i386
FuzzerLoop.cpp.o:     file format elf32-i386
FuzzerMerge.cpp.o:     file format elf32-i386
FuzzerMutate.cpp.o:     file format elf32-i386
FuzzerSHA1.cpp.o:     file format elf32-i386
FuzzerTracePC.cpp.o:     file format elf32-i386
FuzzerUtil.cpp.o:     file format elf32-i386
FuzzerUtilDarwin.cpp.o:     file format elf32-i386
FuzzerUtilFuchsia.cpp.o:     file format elf32-i386
FuzzerUtilLinux.cpp.o:     file format elf32-i386
FuzzerUtilPosix.cpp.o:     file format elf32-i386
FuzzerUtilWindows.cpp.o:     file format elf32-i386

gold and lld can run /usr/bin/ld.bfd -r --whole-archive ~/llvm-project/build-x862/lib/clang/9.0.0/lib/linux/libclang_rt.fuzzer-i386.a -o fuzzer.o just fine by the way.
When I run file on the output, it says:

fuzzer.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), with debug_info, not stripped

Which would be surprising if I actually was including 64 bit code.
I think this is just a bug/quirk in GNU ld that needs -m elf_i386 to be solved.

You can verify ld needs this using this simple reproducer:

$ echo "int x() { return 0; }" > x.cc
$ g++ -m32 -c x.cc
$ ar qc x.a x.o
$ ld -r --whole-archive x.a -o x2.o
ld: Relocatable linking with relocations from format elf32-i386 (x.a(x.o)) to format elf64-x86-64 (x2.o) is not supported
This revision is now accepted and ready to land.Apr 30 2019, 9:47 AM
Closed by commit rL359585: [libFuzzer] Enable for i386 (authored by metzman, committed by ). · Explain WhyApr 30 2019, 10:59 AM
This revision was automatically updated to reflect the committed changes.