diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-07-07 20:07:30 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-07-08 22:52:24 +0200 |
| commit | 306ca0571c5d906ce76df97bd1ea54f4e0e50240 (patch) | |
| tree | a579718e096c53dc5386f4af2fbabb3318eaf1ed /executor/executor.h | |
| parent | 93213ec0d3c4522c8844a51b718eb56ce62f395b (diff) | |
prog, pkg/compiler: support fmt type
fmt type allows to convert intergers and resources
to string representation.
Diffstat (limited to 'executor/executor.h')
| -rw-r--r-- | executor/executor.h | 108 |
1 files changed, 74 insertions, 34 deletions
diff --git a/executor/executor.h b/executor/executor.h index 0bb0ea2cf..d3632ae43 100644 --- a/executor/executor.h +++ b/executor/executor.h @@ -36,6 +36,12 @@ const uint64 arg_result = 1; const uint64 arg_data = 2; const uint64 arg_csum = 3; +const uint64 binary_format_native = 0; +const uint64 binary_format_bigendian = 1; +const uint64 binary_format_strdec = 2; +const uint64 binary_format_strhex = 3; +const uint64 binary_format_stroct = 4; + const uint64 no_copyout = -1; enum sandbox_type { @@ -186,9 +192,9 @@ uint32* write_output(uint32 v); void write_completed(uint32 completed); uint64 read_input(uint64** input_posp, bool peek = false); uint64 read_arg(uint64** input_posp); -uint64 read_const_arg(uint64** input_posp, uint64* size_p, uint64* bf_off_p, uint64* bf_len_p); +uint64 read_const_arg(uint64** input_posp, uint64* size_p, uint64* bf, uint64* bf_off_p, uint64* bf_len_p); uint64 read_result(uint64** input_posp); -void copyin(char* addr, uint64 val, uint64 size, uint64 bf_off, uint64 bf_len); +void copyin(char* addr, uint64 val, uint64 size, uint64 bf, uint64 bf_off, uint64 bf_len); bool copyout(char* addr, uint64 size, uint64* res); void cover_open(); void cover_enable(thread_t* th); @@ -341,15 +347,17 @@ retry: uint64 typ = read_input(&input_pos); switch (typ) { case arg_const: { - uint64 size, bf_off, bf_len; - uint64 arg = read_const_arg(&input_pos, &size, &bf_off, &bf_len); - copyin(addr, arg, size, bf_off, bf_len); + uint64 size, bf, bf_off, bf_len; + uint64 arg = read_const_arg(&input_pos, &size, &bf, &bf_off, &bf_len); + copyin(addr, arg, size, bf, bf_off, bf_len); break; } case arg_result: { - uint64 size = read_input(&input_pos); + uint64 meta = read_input(&input_pos); + uint64 size = meta & 0xff; + uint64 bf = meta >> 8; uint64 val = read_result(&input_pos); - copyin(addr, val, size, 0, 0); + copyin(addr, val, size, bf, 0, 0); break; } case arg_data: { @@ -367,9 +375,8 @@ retry: uint64 csum_kind = read_input(&input_pos); switch (csum_kind) { case arg_csum_inet: { - if (size != 2) { + if (size != 2) fail("inet checksum must be 2 bytes, not %llu", size); - } debug("calculating checksum for %p\n", csum_addr); struct csum_inet csum; csum_inet_init(&csum); @@ -398,7 +405,7 @@ retry: } uint16 csum_value = csum_inet_digest(&csum); debug("writing inet checksum %hx to %p\n", csum_value, csum_addr); - copyin(csum_addr, csum_value, 2, 0, 0); + copyin(csum_addr, csum_value, 2, binary_format_native, 0, 0); break; } default: @@ -754,24 +761,47 @@ static bool dedup(uint32 sig) return false; } -void copyin(char* addr, uint64 val, uint64 size, uint64 bf_off, uint64 bf_len) +void copyin(char* addr, uint64 val, uint64 size, uint64 bf, uint64 bf_off, uint64 bf_len) { - NONFAILING(switch (size) { - case 1: - STORE_BY_BITMASK(uint8, addr, val, bf_off, bf_len); - break; - case 2: - STORE_BY_BITMASK(uint16, addr, val, bf_off, bf_len); - break; - case 4: - STORE_BY_BITMASK(uint32, addr, val, bf_off, bf_len); - break; - case 8: - STORE_BY_BITMASK(uint64, addr, val, bf_off, bf_len); - break; - default: - fail("copyin: bad argument size %llu", size); - }); + if (bf != binary_format_native && (bf_off != 0 || bf_len != 0)) + fail("bitmask for string format %llu/%llu", bf_off, bf_len); + switch (bf) { + case binary_format_native: + NONFAILING(switch (size) { + case 1: + STORE_BY_BITMASK(uint8, addr, val, bf_off, bf_len); + break; + case 2: + STORE_BY_BITMASK(uint16, addr, val, bf_off, bf_len); + break; + case 4: + STORE_BY_BITMASK(uint32, addr, val, bf_off, bf_len); + break; + case 8: + STORE_BY_BITMASK(uint64, addr, val, bf_off, bf_len); + break; + default: + fail("copyin: bad argument size %llu", size); + }); + break; + case binary_format_strdec: + if (size != 20) + fail("bad strdec size %llu", size); + NONFAILING(sprintf((char*)addr, "%020llu", val)); + break; + case binary_format_strhex: + if (size != 18) + fail("bad strhex size %llu", size); + NONFAILING(sprintf((char*)addr, "0x%016llx", val)); + break; + case binary_format_stroct: + if (size != 23) + fail("bad stroct size %llu", size); + NONFAILING(sprintf((char*)addr, "%023llo", val)); + break; + default: + fail("unknown binary format %llu", bf); + } } bool copyout(char* addr, uint64 size, uint64* res) @@ -802,11 +832,19 @@ uint64 read_arg(uint64** input_posp) uint64 typ = read_input(input_posp); switch (typ) { case arg_const: { - uint64 size, bf_off, bf_len; - return read_const_arg(input_posp, &size, &bf_off, &bf_len); + uint64 size, bf, bf_off, bf_len; + uint64 val = read_const_arg(input_posp, &size, &bf, &bf_off, &bf_len); + if (bf != binary_format_native) + fail("bad argument binary format %llu", bf); + if (bf_off != 0 || bf_len != 0) + fail("bad argument bitfield %llu/%llu", bf_off, bf_len); + return val; } case arg_result: { - read_input(input_posp); // size + uint64 meta = read_input(input_posp); + uint64 bf = meta >> 8; + if (bf != binary_format_native) + fail("bad result argument format %llu", bf); return read_result(input_posp); } default: @@ -814,17 +852,18 @@ uint64 read_arg(uint64** input_posp) } } -uint64 read_const_arg(uint64** input_posp, uint64* size_p, uint64* bf_off_p, uint64* bf_len_p) +uint64 read_const_arg(uint64** input_posp, uint64* size_p, uint64* bf_p, uint64* bf_off_p, uint64* bf_len_p) { uint64 meta = read_input(input_posp); uint64 val = read_input(input_posp); *size_p = meta & 0xff; - bool be = meta & (1 << 8); + uint64 bf = (meta >> 8) & 0xff; *bf_off_p = (meta >> 16) & 0xff; *bf_len_p = (meta >> 24) & 0xff; uint64 pid_stride = meta >> 32; val += pid_stride * procid; - if (be) { + if (bf == binary_format_bigendian) { + bf = binary_format_native; switch (*size_p) { case 2: val = htobe16(val); @@ -836,9 +875,10 @@ uint64 read_const_arg(uint64** input_posp, uint64* size_p, uint64* bf_off_p, uin val = htobe64(val); break; default: - fail("bad big-endian int size %d", (int)*size_p); + fail("bad big-endian int size %llu", *size_p); } } + *bf_p = bf; return val; } |
