Changeset View
Standalone View
compiler-rt/lib/fuzzer/FuzzerTracePC.h
Show First 20 Lines • Show All 188 Lines • ▼ Show 20 Lines | size_t ForEachNonZeroByte(const uint8_t *Begin, const uint8_t *End, | ||||
auto P = Begin; | auto P = Begin; | ||||
// Iterate by 1 byte until either the alignment boundary or the end. | // Iterate by 1 byte until either the alignment boundary or the end. | ||||
for (; reinterpret_cast<uintptr_t>(P) & StepMask && P < End; P++) | for (; reinterpret_cast<uintptr_t>(P) & StepMask && P < End; P++) | ||||
if (uint8_t V = *P) | if (uint8_t V = *P) | ||||
Handle8bitCounter(FirstFeature, P - Begin, V); | Handle8bitCounter(FirstFeature, P - Begin, V); | ||||
// Iterate by Step bytes at a time. | // Iterate by Step bytes at a time. | ||||
for (; P < End; P += Step) | for (; P < End; P += Step) | ||||
if (LargeType Bundle = *reinterpret_cast<const LargeType *>(P)) | if (LargeType Bundle = *reinterpret_cast<const LargeType *>(P)) { | ||||
Bundle = HostToLE(Bundle); | |||||
kcc: please remove the { that weren't there. | |||||
ok iii: ok | |||||
for (size_t I = 0; I < Step; I++, Bundle >>= 8) | for (size_t I = 0; I < Step; I++, Bundle >>= 8) | ||||
please avoid #ifdefs inside functions. FuzzerBuiltins.h is probably the place for such a function. Also, what about #include <endian.h> uint64_t htole64(uint64_t host_64bits); is that portable? kcc: please avoid #ifdefs inside functions.
If there is some logic that needs to depend on the… | |||||
I think this might not work as expected on 32-bit systems. I'll add a separate function. iii: I think this might not work as expected on 32-bit systems. I'll add a separate function. | |||||
No strong preference. % cat x.cc #include <endian.h> #include <stdint.h> uint64_t foo(uint64_t x) { return htole64(x); } % clang -O2 -S -o - x.cc -m32 movl 4(%esp), %eax movl 8(%esp), %edx retl % clang -O2 -S -o - x.cc movq %rdi, %rax retq htobe64 also looks nice, it translates into one bswapq on 64-bit and two bswapl on 32-bit, kcc: No strong preference.
I've just checked, on Linux x86_64: it inlines and works great.
Dunno… | |||||
My thinking is that LargeType is uintptr_t, so it will be uint32_t on a 32-bit system. uint32_t Bundle = 0xAABBCCDD; htole64(Bundle) would give us (uint64_t)0xDDCCBBAA00000000, and then when we cast it back to uint32_t, we'll get just 0. Isn't that right? So the idea I'm currently regtesting is: --- a/compiler-rt/lib/fuzzer/FuzzerUtil.h +++ b/compiler-rt/lib/fuzzer/FuzzerUtil.h @@ -106,6 +106,12 @@ inline uint8_t *RoundDownByPage(uint8_t *P) { return reinterpret_cast<uint8_t *>(X); } +#if __BYTE_ORDER == __LITTLE_ENDIAN +template <typename T> T HToLE(T X) { return X; } +#else +template <typename T> T HToLE(T X) { return Bswap(X); } +#endif + } // namespace fuzzer #endif // LLVM_FUZZER_UTIL_H ... it's in FuzzerUtil.h and not in FuzzerBuiltins.h, because it uses Bswap, which is defined in a separate header for MSVC. iii: My thinking is that LargeType is uintptr_t, so it will be uint32_t on a 32-bit system.
So if we… | |||||
Sounds good, thanks! kcc: Sounds good, thanks! | |||||
if (uint8_t V = Bundle & 0xff) | if (uint8_t V = Bundle & 0xff) | ||||
Handle8bitCounter(FirstFeature, P - Begin + I, V); | Handle8bitCounter(FirstFeature, P - Begin + I, V); | ||||
} | |||||
// Iterate by 1 byte until the end. | // Iterate by 1 byte until the end. | ||||
for (; P < End; P++) | for (; P < End; P++) | ||||
if (uint8_t V = *P) | if (uint8_t V = *P) | ||||
Handle8bitCounter(FirstFeature, P - Begin, V); | Handle8bitCounter(FirstFeature, P - Begin, V); | ||||
return End - Begin; | return End - Begin; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 81 Lines • Show Last 20 Lines |
please remove the { that weren't there.