Last active
September 29, 2018 07:59
-
-
Save ivanstepanovftw/051795fa9609d06676041044156c4ebf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Address Source Line Assembly CPU Time: Total CPU Time: Self Instructions Retired: Total Instructions Retired: Self | |
0xa238 0 Block 1: | |
0xa238 245 sub %r15, %rax 0.106s 0.106s 1.9% 2,586,300,000 | |
0xa23b 254 cmp $0x8, %rax 0.003s 0.003s 0.0% 37,000,000 | |
0xa23f 254 jbe 0xa418 <Block 9> 0.001s 0.001s 0.0% 0 | |
0xa245 0 Block 2: | |
0xa245 266 movq 0x30(%rsp), %rax 0.004s 0.004s 0.0% 44,400,000 | |
0xa24a 266 mov $0xffffffff, %ecx 0s 0s 0.0% 11,100,000 | |
0xa24f 266 movzxb (%rdx,%rax,1), %ebx 0.095s 0.095s 1.8% 2,430,900,000 | |
0xa253 266 leaq 0x8(%rax), %rdi 0.005s 0.005s 0.1% 70,300,000 | |
0xa257 266 movb %bl, 0x20(%rsp) 0s 0s 0.0% 14,800,000 | |
0xa25b 266 vmovdqax 0x20(%rsp), %xmm2 0.005s 0.004s 0.1% 111,000,000 | |
0xa261 266 vpinsrbb $0x1, 0x4(%rdx,%rax,1), %xmm2, %xmm0 1.676s 1.676s 24.6% 33,196,400,000 | |
0xa269 266 vpinsrbb $0x2, 0x8(%rdx,%rax,1), %xmm0, %xmm3 0.211s 0.211s 3.7% 5,057,900,000 | |
0xa271 255 mov $0x8, %eax 0.112s 0.112s 1.2% 1,687,200,000 | |
0xa276 266 vmovapsx %xmm3, 0x20(%rsp) 0.001s 0s 0.0% 0 | |
0xa27c 266 vmovdqax 0x20(%rsp), %xmm4 0.125s 0.125s 1.9% 2,578,900,000 | |
0xa282 266 vpinsrbb $0x3, 0x4(%rdx,%rdi,1), %xmm4, %xmm0 0.330s 0.330s 1.5% 1,961,000,000 | |
0xa28a 266 vmovapsx %xmm0, 0x20(%rsp) 0.230s 0.230s 0.0% 0 | |
0xa290 264 cmp $0x4, %rax 0.105s 0.105s 0.0% 3,700,000 | |
0xa294 264 jz 0xa2e0 <Block 7> | |
0xa296 0 Block 3: | |
0xa296 266 vpinsrbb $0x4, 0x8(%rdx,%rdi,1), %xmm0, %xmm0 | |
0xa29e 266 vmovapsx %xmm0, 0x20(%rsp) 0.001s 0.001s 0.0% 0 | |
0xa2a4 264 cmp $0x5, %rax 0.131s 0.131s 0.0% 0 | |
0xa2a8 264 jz 0xa2e0 <Block 7> | |
0xa2aa 0 Block 4: | |
0xa2aa 266 vpinsrbb $0x5, 0xc(%rdx,%rdi,1), %xmm0, %xmm0 | |
0xa2b2 266 vmovapsx %xmm0, 0x20(%rsp) | |
0xa2b8 264 cmp $0x6, %rax 0.109s 0.109s 0.0% 0 | |
0xa2bc 264 jz 0xa2e0 <Block 7> | |
0xa2be 0 Block 5: | |
0xa2be 266 vpinsrbb $0x6, 0x10(%rdx,%rdi,1), %xmm0, %xmm0 | |
0xa2c6 266 vmovapsx %xmm0, 0x20(%rsp) | |
0xa2cc 264 cmp $0x7, %rax 0.099s 0.099s 0.0% 3,700,000 | |
0xa2d0 264 jz 0xa2e0 <Block 7> | |
0xa2d2 0 Block 6: | |
0xa2d2 266 vpinsrbb $0x7, 0x14(%rdx,%rdi,1), %xmm0, %xmm5 | |
0xa2da 266 vmovapsx %xmm5, 0x20(%rsp) 0.001s 0.001s 0.0% 0 | |
0xa2e0 0 Block 7: | |
0xa2e0 282 movq 0x30(%rsp), %rax 0.096s 0.096s 0.0% 0 | |
0xa2e7 0 Block 8: | |
0xa2e7 282 andw 0x2(%rdx,%rax,1), %cx | |
0xa2ec 282 movw %cx, 0x28(%rsp) 0.003s 0.003s 0.0% 11,100,000 | |
0xa418 0 Block 9: | |
0xa418 282 mov $0xffffffff, %ecx 0s 0s 0.0% 3,700,000 | |
0xa41d 282 jnz 0xa5f0 <Block 13> | |
0xa423 0 Block 10: | |
0xa423 282 movq 0x30(%rsp), %rbx | |
0xa428 282 movzxb (%rdx,%rbx,1), %edi | |
0xa42c 282 movb %dil, 0x20(%rsp) | |
0xa431 282 vmovdqax 0x20(%rsp), %xmm6 0s 0s 0.0% 3,700,000 | |
0xa437 282 vpinsrbb $0x1, 0x4(%rdx,%rbx,1), %xmm6, %xmm0 0.001s 0.001s 0.0% 7,400,000 | |
0xa43f 282 vmovapsx %xmm0, 0x20(%rsp) 0s 0s 0.0% 3,700,000 | |
0xa445 282 cmp $0x2, %rax | |
0xa449 282 jz 0xa2e0 <Block 7> | |
0xa44f 0 Block 11: | |
0xa44f 282 vpinsrbb $0x2, 0x8(%rdx,%rbx,1), %xmm0, %xmm7 | |
0xa457 266 leaq 0x8(%rbx), %rdi | |
0xa45b 266 vmovapsx %xmm7, 0x20(%rsp) | |
0xa461 264 cmp $0x3, %rax | |
0xa465 264 jz 0xa2e0 <Block 7> | |
0xa46b 0 Block 12: | |
0xa46b 264 jmp 0xa27c | |
0xa5f0 0 Block 13: | |
0xa5f0 257 cmp $0x4, %rax 0s 0s 0.0% 3,700,000 | |
0xa5f4 257 sbb %edi, %edi | |
0xa5f6 257 and $0xfed0, %di | |
0xa5fb 257 sub $0x2cd, %di | |
0xa600 257 cmp $0x4, %rax | |
0xa604 257 sbb %ecx, %ecx | |
0xa606 257 and $0xfed0, %cx | |
0xa60b 257 sub $0x2c1, %cx | |
0xa610 258 cmp $0x1, %rax | |
0xa614 258 jnbe 0xa423 <Block 10> | |
0xa61a 0 Block 14: | |
0xa61a 259 test %rax, %rax | |
0xa61d 259 jnz 0xaa96 <Block 17> | |
0xa623 0 Block 15: | |
0xa623 259 xor %ecx, %ecx | |
0xa625 259 jmp 0xa2e0 <Block 7> | |
0xa62a 0 Block 16: | |
0xa62a 259 nopw %ax, (%rax,%rax,1) | |
0xaa96 0 Block 17: | |
0xaa96 266 movq 0x30(%rsp), %rax | |
0xaa9b 266 mov %edi, %ecx 0.001s 0.001s 0.0% 0 | |
0xaa9d 266 movzxb (%rdx,%rax,1), %eax 0s 0s 0.0% 3,700,000 | |
0xaaa1 266 movb %al, 0x20(%rsp) | |
0xaaa5 266 jmp 0xa2e0 <Block 7> | |
0xaaaa 0 Block 18: | |
0xaaaa 266 leaq (,%rax,8), %rbx | |
0xaab2 266 jmp 0xa51f |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Address Source Line Assembly CPU Time: Total CPU Time: Self Instructions Retired: Total Instructions Retired: Self | |
0x9e38 0 Block 1: | |
0x9e38 274 movq %r15, (%rsp) | |
0x9e3c 274 mov %r14, %r15 | |
0x9e3f 274 nop | |
0xa083 0 Block 2: | |
0xa083 245 sub %r15, %rax 36.039ms 36.039ms 0.5% 695,600,000 | |
0xa086 254 cmp $0x8, %rax 71.077ms 71.077ms 1.2% 1,650,200,000 | |
0xa08a 254 jnbe 0xa320 <Block 10> | |
0xa090 0 Block 3: | |
0xa090 256 mov $0xffffffff, %ecx | |
0xa095 256 jnz 0xa580 <Block 14> 0ms 0ms 0.0% 3,700,000 | |
0xa09b 0 Block 4: | |
0xa09b 270 movzxb (%rdi), %ebx | |
0xa09e 270 movb %bl, 0x4f(%rsp) | |
0xa0a2 271 movzxb 0x4(%rdx,%rbp,1), %ebx | |
0xa0a7 271 movb %bl, 0x68(%rsp) | |
0xa0ab 272 cmp $0x2, %rax | |
0xa0af 272 jz 0xa0f0 | |
0xa0b1 0 Block 5: | |
0xa0b1 272 movzxb 0x8(%rdx,%rbp,1), %ebx | |
0xa0b6 272 movb %bl, 0x69(%rsp) | |
0xa0ba 273 cmp $0x3, %rax | |
0xa0be 273 jz 0xa0f0 | |
0xa0c0 0 Block 6: | |
0xa0c0 273 movzxb 0xc(%rdx,%rbp,1), %ebx | |
0xa0c5 273 movb %bl, 0x6a(%rsp) | |
0xa0c9 274 cmp $0x4, %rax | |
0xa0cd 274 jz 0xa0f0 | |
0xa0cf 0 Block 7: | |
0xa0cf 274 movzxb 0x10(%rdx,%rbp,1), %ebx | |
0xa0d4 274 leaq 0x10(%rbp), %r8 | |
0xa0d8 274 movb %bl, 0x6b(%rsp) | |
0xa0dc 275 cmp $0x5, %rax | |
0xa0e0 275 jnz 0xa359 <Block 11> | |
0xa0e6 0 Block 8: | |
0xa0e6 275 nopw %ax, (%rax,%rax,1) 1.001ms 0ms 0.0% 0 | |
0xa0f5 0 Block 9: | |
0xa0f5 282 andw 0x2(%rdi), %cx 48.052ms 48.052ms 0.9% 1,191,400,000 | |
0xa320 0 Block 10: | |
0xa320 270 movzxb (%rdi), %eax 7.008ms 7.008ms 0.1% 74,000,000 | |
0xa323 274 leaq 0x10(%rbp), %r8 19.021ms 19.021ms 0.2% 270,100,000 | |
0xa327 270 movb %al, 0x4f(%rsp) 38.041ms 38.041ms 0.3% 440,300,000 | |
0xa32b 271 movzxb 0x4(%rdx,%rbp,1), %eax 76.082ms 76.082ms 1.0% 1,387,500,000 | |
0xa330 274 mov $0xffffffff, %ecx 3.003ms 3.003ms 0.1% 74,000,000 | |
0xa335 271 movb %al, 0x68(%rsp) 9.010ms 9.010ms 0.1% 81,400,000 | |
0xa339 272 movzxb 0x8(%rdx,%rbp,1), %eax 18.019ms 18.019ms 0.3% 399,600,000 | |
0xa33e 272 movb %al, 0x69(%rsp) 68.074ms 68.074ms 1.1% 1,472,600,000 | |
0xa342 273 movzxb 0xc(%rdx,%rbp,1), %eax 5.005ms 5.005ms 0.0% 55,500,000 | |
0xa347 273 movb %al, 0x6a(%rsp) 10.011ms 10.011ms 0.1% 207,200,000 | |
0xa34b 274 movzxb 0x10(%rdx,%rbp,1), %eax 33.036ms 33.036ms 0.4% 625,300,000 | |
0xa350 274 movb %al, 0x6b(%rsp) 61.066ms 61.066ms 0.9% 1,313,500,000 | |
0xa354 255 mov $0x8, %eax 3.003ms 3.003ms 0.1% 148,000,000 | |
0xa359 0 Block 11: | |
0xa359 275 movzxb 0x4(%rdx,%r8,1), %ebx 12.013ms 12.013ms 0.2% 303,400,000 | |
0xa35f 275 movb %bl, 0x6c(%rsp) 26.028ms 26.028ms 0.5% 721,500,000 | |
0xa363 275 cmp $0x6, %rax 68.074ms 68.074ms 1.2% 1,616,900,000 | |
0xa367 275 jz 0xa0f0 | |
0xa36d 0 Block 12: | |
0xa36d 276 movzxb 0x8(%rdx,%r8,1), %ebx 5.005ms 5.005ms 0.0% 40,700,000 | |
0xa373 276 movb %bl, 0x6d(%rsp) 13.014ms 13.014ms 0.2% 236,800,000 | |
0xa377 276 cmp $0x8, %rax 36.039ms 36.039ms 0.5% 710,400,000 | |
0xa37b 276 jnz 0xa0f0 | |
0xa381 0 Block 13: | |
0xa381 277 movzxb 0xc(%rdx,%r8,1), %eax 55.060ms 55.060ms 0.8% 1,095,200,000 | |
0xa387 277 movb %al, 0x6e(%rsp) 24.026ms 24.026ms 0.3% 425,500,000 | |
0xa38b 277 jmp 0xa0f0 29.031ms 29.031ms 0.4% 532,800,000 | |
0xa580 0 Block 14: | |
0xa580 277 cmp $0x3, %rax | |
0xa584 277 jnbe 0xaaa7 <Block 20> | |
0xa58a 0 Block 15: | |
0xa58a 277 cmp $0x1, %rax 0ms 0ms 0.0% 3,700,000 | |
0xa58e 277 jnbe 0xaab1 <Block 21> | |
0xa594 0 Block 16: | |
0xa594 277 test %rax, %rax | |
0xa597 277 jnz 0xaa96 <Block 19> | |
0xa59d 0 Block 17: | |
0xa59d 277 xor %ecx, %ecx | |
0xa59f 277 jmp 0xa0f0 | |
0xa5a4 0 Block 18: | |
0xa5a4 277 nopl %eax, (%rax) | |
0xaa96 0 Block 19: | |
0xaa96 277 movzxb (%rdi), %eax 0ms 0ms 0.0% 3,700,000 | |
0xaa99 277 mov $0xfffffc03, %ecx | |
0xaa9e 277 movb %al, 0x4f(%rsp) | |
0xaaa2 277 jmp 0xa0f0 | |
0xaaa7 0 Block 20: | |
0xaaa7 277 mov $0xfffffd3f, %ecx | |
0xaaac 277 jmp 0xa09b <Block 4> | |
0xaab1 0 Block 21: | |
0xaab1 277 mov $0xfffffc0f, %ecx | |
0xaab6 277 jmp 0xa09b <Block 4> | |
0xaabb 0 Block 22: | |
0xaabb 277 leaq (,%rax,8), %rbx | |
0xaac3 277 jmp 0xa517 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This file is part of Reverse Engine. | |
Array of scanner results. | |
Copyright (C) 2017-2018 Ivan Stepanov <[email protected]> | |
Copyright (C) 2015,2017 Sebastian Parschauer <[email protected]> | |
Copyright (C) 2017 Andrea Stacchiotti <[email protected]> | |
Copyright (C) 2010 WANG Lu <[email protected]> | |
Copyright (C) 2009 Eli Dupree <[email protected]> | |
This library is free software: you can redistribute it and/or modify | |
it under the terms of the GNU Lesser General Public License as published | |
by the Free Software Foundation; either version 3 of the License, or | |
(at your option) any later version. | |
This library is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU Lesser General Public License for more details. | |
You should have received a copy of the GNU Lesser General Public License | |
along with this library. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
#ifndef RE_SCANNER_HH | |
#define RE_SCANNER_HH | |
#include <cinttypes> | |
#include <memory> | |
#include <cmath> | |
#include <chrono> | |
#include <fcntl.h> | |
#include <sys/mman.h> | |
#include <chrono> | |
#include <deque> | |
#include <string> | |
#include <boost/iostreams/device/mapped_file.hpp> | |
#include <stdlib.h> | |
// | |
#include "core.hh" | |
#include "value.hh" | |
#include "scanroutines.hh" | |
#include <boost/date_time/posix_time/ptime.hpp> | |
#include <boost/date_time/microsec_time_clock.hpp> | |
class TestTimer | |
{ | |
public: | |
TestTimer(const std::string & name) : name(name), | |
start(boost::date_time::microsec_clock<boost::posix_time::ptime>::local_time()) | |
{ | |
} | |
~TestTimer() | |
{ | |
using namespace std; | |
using namespace boost; | |
posix_time::ptime now(date_time::microsec_clock<posix_time::ptime>::local_time()); | |
posix_time::time_duration d = now - start; | |
cout << fixed<<d.total_nanoseconds() / 1000000000.0 << " seconds "<< name << endl; | |
usleep(1000); | |
} | |
private: | |
std::string name; | |
boost::posix_time::ptime start; | |
}; | |
namespace RE { | |
namespace bio = boost::iostreams; | |
using namespace std; | |
using namespace std::chrono; | |
class match_t { | |
public: | |
uintptr_t address; | |
union { | |
mem64_t memory; | |
uint8_t *bytes; | |
}; | |
uint16_t flags; | |
explicit match_t(uintptr_t address, uint16_t userflag = flags_empty) { | |
this->address = address; | |
this->flags = userflag; | |
} | |
explicit match_t(uintptr_t address, mem64_t memory, uint16_t userflag = flags_empty) { | |
this->address = address; | |
this->memory = memory; | |
this->flags = userflag; | |
} | |
inline | |
match_flags | |
flag() | |
{ | |
if (this->flags & RE::flag_i64) return RE::flag_i64; | |
else if (this->flags & RE::flag_i32) return RE::flag_i32; | |
else if (this->flags & RE::flag_i16) return RE::flag_i16; | |
else if (this->flags & RE::flag_i8) return RE::flag_i8; | |
else if (this->flags & RE::flag_u64) return RE::flag_u64; | |
else if (this->flags & RE::flag_u32) return RE::flag_u32; | |
else if (this->flags & RE::flag_u16) return RE::flag_u16; | |
else if (this->flags & RE::flag_u8) return RE::flag_u8; | |
else if (this->flags & RE::flag_f64) return RE::flag_f64; | |
else if (this->flags & RE::flag_f32) return RE::flag_f32; | |
} | |
inline | |
std::string | |
flag2str() | |
{ | |
if (this->flags & RE::flag_i64) return "i64"; | |
else if (this->flags & RE::flag_i32) return "i32"; | |
else if (this->flags & RE::flag_i16) return "i16"; | |
else if (this->flags & RE::flag_i8) return "i8"; | |
else if (this->flags & RE::flag_u64) return "u64"; | |
else if (this->flags & RE::flag_u32) return "u32"; | |
else if (this->flags & RE::flag_u16) return "u16"; | |
else if (this->flags & RE::flag_u8) return "u8"; | |
else if (this->flags & RE::flag_f64) return "f64"; | |
else if (this->flags & RE::flag_f32) return "f32"; | |
} | |
inline | |
std::string | |
val2str() | |
{ | |
if (this->flags & RE::flag_i64) return std::to_string(this->memory.i64); | |
else if (this->flags & RE::flag_i32) return std::to_string(this->memory.i32); | |
else if (this->flags & RE::flag_i16) return std::to_string(this->memory.i16); | |
else if (this->flags & RE::flag_i8) return std::to_string(this->memory.i8); | |
else if (this->flags & RE::flag_u64) return std::to_string(this->memory.u64); | |
else if (this->flags & RE::flag_u32) return std::to_string(this->memory.u32); | |
else if (this->flags & RE::flag_u16) return std::to_string(this->memory.u16); | |
else if (this->flags & RE::flag_u8) return std::to_string(this->memory.u8); | |
else if (this->flags & RE::flag_f64) return std::to_string(this->memory.f64); | |
else if (this->flags & RE::flag_f32) return std::to_string(this->memory.f32); | |
} | |
inline | |
std::string | |
address2str() | |
{ | |
char *address_string; | |
const uint8_t *b = reinterpret_cast<const uint8_t *>(&this->address); | |
asprintf(&address_string, /*0x*/"%02x%02x%02x%02x%02x%02x", b[5], b[4], b[3], b[2], b[1], b[0]); | |
return string(address_string); | |
} | |
}; | |
/* Single match struct */ | |
//#pragma pack(push, 1) | |
struct byte_with_flags { | |
uint8_t byte; | |
match_flags flags; | |
}; | |
//#pragma pack(pop) | |
class swath_t | |
{ | |
public: | |
uintptr_t base_address; | |
// fixme[low]: slow, because 'new' calls constructor and copies data | |
std::vector<byte_with_flags> data; | |
explicit swath_t(uintptr_t base_address) { | |
this->base_address = base_address; | |
} | |
uintptr_t | |
remote_get(size_t n) { | |
return base_address + static_cast<uintptr_t>(n); | |
} | |
uintptr_t | |
remote_back() { | |
return remote_get(data.size() - 1); | |
} | |
/* for printable text representation */ | |
inline | |
void data_to_printable_string(char *buf, | |
int buf_length, | |
size_t index, | |
int string_length) | |
{ | |
long swath_length = this->data.size() - index; | |
/* TODO: what if length is too large ? */ | |
long max_length = (swath_length >= string_length) ? string_length : swath_length; | |
int i; | |
for(i = 0; i < max_length; i++) { | |
uint8_t byte = this->data[index + i].byte; | |
buf[i] = isprint(byte) ? byte : '.'; | |
} | |
buf[i] = 0; /* null-terminate */ | |
} | |
/* for bytearray representation */ | |
inline | |
void data_to_bytearray_text(char *buf, | |
int buf_length, | |
size_t index, | |
int bytearray_length) | |
{ | |
int i; | |
int bytes_used = 0; | |
long swath_length = this->data.size() - index; | |
/* TODO: what if length is too large ? */ | |
long max_length = (swath_length >= bytearray_length) ? | |
bytearray_length : swath_length; | |
for(i = 0; i < max_length; i++) { | |
uint8_t byte = this->data[index + i].byte; | |
/* TODO: check error here */ | |
snprintf(buf + bytes_used, buf_length - bytes_used, | |
(i < max_length - 1) ? "%02x " : "%02x", byte); | |
bytes_used += 3; | |
} | |
} | |
/* only at most sizeof(int64_t) bytes will be read, | |
if more bytes are needed (e.g. bytearray), | |
read them separately (for performance) */ | |
[[gnu::always_inline]] | |
value_t | |
inline __attribute__((always_inline)) | |
data_to_val_aux(size_t index, size_t swath_length) | |
{ | |
value_t val; | |
size_t max_bytes = swath_length - index; | |
/* Init all possible flags in a single go. | |
* Also init length to the maximum possible value */ | |
val.flags = flags_max; | |
/* NOTE: This does the right thing for VLT because the flags are in | |
* the same order as the number representation (for both endians), so | |
* that the zeroing of a flag does not change useful bits of `length`. */ | |
if (max_bytes > 8) | |
max_bytes = 8; | |
if (max_bytes < 8) val.flags &= ~flags_64b; | |
if (max_bytes < 4) val.flags &= ~flags_32b; | |
if (max_bytes < 2) val.flags &= ~flags_16b; | |
if (max_bytes < 1) val.flags = flags_empty; | |
/* Unrolling this will improve performance by 40% for gcc. icc is not affected. | |
* TODO to investigate */ | |
#ifdef loop_ | |
for(size_t i = 0; i < max_bytes; i++) { | |
/* Both uint8_t, no explicit casting needed */ | |
val.bytes[i] = data[index + i].byte; | |
} | |
#endif | |
#ifdef unrolled_ | |
if LIKELY(max_bytes > 0) { val.bytes[0] = data[index + 0].byte; | |
if LIKELY(max_bytes > 1) { val.bytes[1] = data[index + 1].byte; | |
if LIKELY(max_bytes > 2) { val.bytes[2] = data[index + 2].byte; | |
if LIKELY(max_bytes > 3) { val.bytes[3] = data[index + 3].byte; | |
if LIKELY(max_bytes > 4) { val.bytes[4] = data[index + 4].byte; | |
if LIKELY(max_bytes > 5) { val.bytes[5] = data[index + 5].byte; | |
if LIKELY(max_bytes > 6) { val.bytes[6] = data[index + 6].byte; | |
if LIKELY(max_bytes > 7) { val.bytes[7] = data[index + 7].byte; | |
}}}}}}}} | |
#endif | |
/* Truncate to the old flags, which are stored with the first matched byte */ | |
val.flags &= data[index].flags; | |
return val; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment