From: Sasha Goldshtein Date: Wed, 3 May 2017 11:07:23 +0000 (-0400) Subject: cc: Work around verifier error when reading USDT probe arguments X-Git-Tag: submit/tizen_4.0/20171018.110122~125^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2070a2aefb0bb30f675d0ebdfb804b5873bb0200;p=platform%2Fupstream%2Fbcc.git cc: Work around verifier error when reading USDT probe arguments The code generated by the USDT helpers for reading probe arguments occasionally caused a verifier error due to a construct similar to the following: ``` switch (ctx->ip) { case 0xaaaa: *dest = ctx->cx; break; case 0xbbbb: *dest = ctx->dx; break; } ``` This would generate an instruction sequence that attempts to access ctx through an offset that is not statically known, which confuses the verifier. This was reported in #751, #829, and #1133, and likely seen by others as well. The workaround, suggested by @yonghong-song, is to force memory writes by using the volatile modifier, which precludes this specific optimization. Resolves #751, #829, #1133. --- diff --git a/src/cc/usdt.cc b/src/cc/usdt.cc index 7d1dd57d..ef929d71 100644 --- a/src/cc/usdt.cc +++ b/src/cc/usdt.cc @@ -152,10 +152,10 @@ bool Probe::usdt_getarg(std::ostream &stream) { for (size_t arg_n = 0; arg_n < arg_count; ++arg_n) { std::string ctype = largest_arg_type(arg_n); - std::string cptr = tfm::format("*((%s *)dest)", ctype); + std::string cptr = tfm::format("*((volatile %s *)dest)", ctype); tfm::format(stream, - "static inline int _bpf_readarg_%s_%d(" + "static __always_inline int _bpf_readarg_%s_%d(" "struct pt_regs *ctx, void *dest, size_t len) {\n" " if (len != sizeof(%s)) return -1;\n", attached_to_.value(), arg_n + 1, ctype);