// Print a classic memory dump with configurable base and grouping. void memdump(const char* data, size_t length, u_int8_t base, u_int8_t gsize, u_int8_t gcount) { int group_size = gsize; int group_count = gcount; int line_width = group_size * group_count; unsigned int offset = 0; while (length > offset) { const char* line = &data[offset]; size_t lineMax = MIN((length - offset), line_width); printf(" %p %06u |", &line[0], offset); for (int c = 0; c < lineMax; c++) { if ( (c % group_size) == 0 ) printf(" "); char* str = memstr(&line[c], 1, base); printf("%s ", str); FREE_BUFFER(str); } printf("|"); for (int c = 0; c < lineMax; c++) { if ( (c % group_size) == 0 ) printf(" "); char chr = line[c] & 0xFF; if (chr < 32) // ASCII unprintable chr = '.'; printf("%c", chr); } printf(" |\n"); offset += line_width; } }
/* validate a path as OK */ void validatePath(char **path) { struct Buffer_char pathok; struct stat sbuf; char *rpath; if (!*path) return; /* first make sure it's absolute */ if (**path != '/') { *path = NULL; return; } /* then get its real path (don't worry about deallocation, there aren't * many of these) */ *path = realpath(*path, NULL); if (*path == NULL) return; /* then check the ok file */ INIT_BUFFER(pathok); WRITE_BUFFER(pathok, *path, strlen(*path)); WRITE_STR_BUFFER(pathok, OKFILE); WRITE_STR_BUFFER(pathok, "\0"); if (stat(pathok.buf, &sbuf) < 0) { /* file not found or otherwise very bad, kill it */ *path = NULL; FREE_BUFFER(pathok); return; } FREE_BUFFER(pathok); if (sbuf.st_uid != geteuid()) { /* wrong owner */ *path = NULL; return; } /* it's valid */ }
void VbufReqd( // ENSURE BUFFER IS OF SUFFICIENT SIZE VBUF *vbuf, // - VBUF structure size_t reqd ) // - required size { char *new_buffer; // - old buffer if( reqd >= vbuf->len ) { reqd = BUFFER_SIZE( reqd ); new_buffer = _MemoryAllocate( reqd ); stxvcpy( new_buffer, vbuf->buf, vbuf->used ); FREE_BUFFER( vbuf ); vbuf->buf = new_buffer; vbuf->len = reqd; } }
ssize_t hfs_read_range(void* buffer, const HFSVolume *hfs, size_t size, size_t offset) { debug("Reading from volume at (%d, %d)", offset, size); // Range check. if (hfs->length && offset > hfs->length) { error("Request for logical offset larger than the size of the volume (%d, %d)", offset, hfs->length); errno = ESPIPE; // Illegal seek return -1; } if ( hfs->length && (offset + size) > hfs->length ) { size = hfs->length - offset; debug("Adjusted read to (%d, %d)", offset, size); } if (size < 1) { error("Zero-size request."); errno = EINVAL; return -1; } // The range starts somewhere in this block. size_t start_block = (size_t)(offset / hfs->block_size); // Offset of the request within the start block. size_t byte_offset = (offset % hfs->block_size); // Add a block to the read if the offset is not block-aligned. size_t block_count = (size / hfs->block_size) + ( ((offset + size) % hfs->block_size) ? 1 : 0); // Use the calculated size instead of the passed size to account for block alignment. char* read_buffer; INIT_BUFFER(read_buffer, block_count * hfs->block_size); // Fetch the data into a read buffer (it may fail). ssize_t read_blocks = hfs_read_blocks(read_buffer, hfs, block_count, start_block); // On success, copy the output. if (read_blocks) memcpy(buffer, read_buffer + byte_offset, size); // Clean up. FREE_BUFFER(read_buffer); // The amount we added to the buffer. return size; }
int main(int argc, char **argv) { struct Buffer_charp rpaths; struct Buffer_char options; char *wpath = NULL, *arg; char *envpaths; int i, j, argi, tmpi; unsigned long mountflags = 0; int allowclear = 0, clear = 0, userwpath = 1; INIT_BUFFER(rpaths); WRITE_ONE_BUFFER(rpaths, NULL); /* filled in by forced dir later */ /* get all the paths out of the environment */ envpaths = getenv(PATHENV); if (envpaths && envpaths[0]) { char *saveptr; arg = strtok_r(envpaths, ":", &saveptr); while (arg) { WRITE_ONE_BUFFER(rpaths, arg); arg = strtok_r(NULL, ":", &saveptr); } } /* get all the paths out of the args */ for (argi = 1; argi < argc; argi++) { arg = argv[argi]; if (arg[0] == '-') { if (!strcmp(arg, "-w") && argi < argc - 1) { argi++; wpath = argv[argi]; } else if (!strcmp(arg, "-r")) { /* reset current paths (ignore environment) */ rpaths.bufused = 1; allowclear = 1; } else if (!strcmp(arg, "--") && argi < argc - 1) { argi++; break; } else { fprintf(stderr, "Unrecognized option %s\n", arg); } } else { WRITE_ONE_BUFFER(rpaths, arg); } } if (argi >= argc) { if (getuid() != geteuid()) { fprintf(stderr, "Only root may remount an existing view\n"); return 1; } mountflags |= MS_REMOUNT; } /* validate all our paths */ for (i = 1; i < rpaths.bufused; i++) { validatePath(&rpaths.buf[i]); } validatePath(&wpath); rpaths.buf[0] = FORCEDIR; if (!wpath) { wpath = DEFAULTWRITEDIR; userwpath = 0; } /* make sure there are no duplicates */ for (i = 1; i < rpaths.bufused; i++) { if (!rpaths.buf[i]) continue; if (!strcmp(rpaths.buf[i], wpath)) { rpaths.buf[i] = NULL; continue; } for (j = 0; j < i; j++) { if (rpaths.buf[j] && !strcmp(rpaths.buf[i], rpaths.buf[j])) { rpaths.buf[i] = NULL; break; } } } /* are we trying to clear /usr? */ if (rpaths.bufused == 1) { /* no options = unmount all */ if (!allowclear) { fprintf(stderr, "To explicitly clear all /usr mounts, -r must be specified\n"); return 1; } clear = 1; } /* perform the mount */ if (!(mountflags & MS_REMOUNT)) SF(tmpi, unshare, -1, (CLONE_NEWNS)); if (clear) { do { tmpi = umount("/usr"); } while (tmpi == 0); if (errno != EINVAL) perror("/usr"); } else { /* first mount */ INIT_BUFFER(options); WRITE_STR_BUFFER(options, "br:"); WRITE_BUFFER(options, wpath, strlen(wpath) + 1); tmpi = mount("none", BASE, "aufs", mountflags, options.buf); if (tmpi == -1 && (mountflags & MS_REMOUNT)) { /* OK, we tried to remount, maybe it just wasn't mounted though */ mountflags &= ~(MS_REMOUNT); tmpi = mount("none", BASE, "aufs", mountflags, options.buf); } /* remaining mounts */ for (i = 0; tmpi != -1 && i < rpaths.bufused; i++) { if (!rpaths.buf[i]) continue; options.bufused = 0; WRITE_STR_BUFFER(options, "append:"); WRITE_BUFFER(options, rpaths.buf[i], strlen(rpaths.buf[i])); if (!userwpath) WRITE_STR_BUFFER(options, "=rw"); WRITE_STR_BUFFER(options, "\0"); tmpi = mount("none", BASE, "aufs", mountflags|MS_REMOUNT, options.buf); } if (tmpi == -1) { perror("mount"); return 1; } } /* drop privs */ SF(tmpi, setuid, -1, (getuid())); SF(tmpi, setgid, -1, (getgid())); /* free our mount options */ FREE_BUFFER(options); /* add it to the environment */ INIT_BUFFER(options); for (i = 0; i < rpaths.bufused; i++) { arg = rpaths.buf[i]; if (arg) { if (options.bufused) WRITE_STR_BUFFER(options, ":"); WRITE_BUFFER(options, arg, strlen(arg)); } } WRITE_STR_BUFFER(options, "\0"); SF(tmpi, setenv, -1, (PATHENV, options.buf, 1)); FREE_BUFFER(options); if (userwpath) { SF(tmpi, setenv, -1, (WRITEENV, wpath, 1)); } else { SF(tmpi, unsetenv, -1, (WRITEENV)); } /* then run it */ if (argi < argc) { execvp(argv[argi], argv + argi); fprintf(stderr, "[usrview] "); perror(argv[argi]); return 1; } else { return 0; } }
void VbufFree( // FREE BUFFER VBUF *vbuf ) // - VBUF structure { FREE_BUFFER( vbuf ); VbufInit( vbuf ); }
static void check_init (tree exp, words before) { tree tmp; again: switch (TREE_CODE (exp)) { case VAR_DECL: case PARM_DECL: if (! FIELD_STATIC (exp) && DECL_NAME (exp) != NULL_TREE && DECL_NAME (exp) != this_identifier_node) { int index = DECL_BIT_INDEX (exp); /* We don't want to report and mark as non-initialized class initialization flags. */ if (! LOCAL_CLASS_INITIALIZATION_FLAG_P (exp) && index >= 0 && ! ASSIGNED_P (before, index)) { parse_error_context (wfl, "Variable %qs may not have been initialized", IDENTIFIER_POINTER (DECL_NAME (exp))); /* Suppress further errors. */ DECL_BIT_INDEX (exp) = -2; } } break; case COMPONENT_REF: check_init (TREE_OPERAND (exp, 0), before); if ((tmp = get_variable_decl (exp)) != NULL_TREE) { int index = DECL_BIT_INDEX (tmp); if (index >= 0 && ! ASSIGNED_P (before, index)) { parse_error_context (wfl, "variable %qs may not have been initialized", IDENTIFIER_POINTER (DECL_NAME (tmp))); /* Suppress further errors. */ DECL_BIT_INDEX (tmp) = -2; } } break; case MODIFY_EXPR: tmp = TREE_OPERAND (exp, 0); /* We're interested in variable declaration and parameter declaration when they're declared with the `final' modifier. */ if ((tmp = get_variable_decl (tmp)) != NULL_TREE) { int index; check_init (TREE_OPERAND (exp, 1), before); check_final_reassigned (tmp, before); index = DECL_BIT_INDEX (tmp); if (index >= 0) { SET_ASSIGNED (before, index); CLEAR_UNASSIGNED (before, index); } /* Minor optimization. See comment for start_current_locals. If we're optimizing for class initialization, we keep this information to check whether the variable is definitely assigned when once we checked the whole function. */ if (! STATIC_CLASS_INIT_OPT_P () /* FIXME */ && ! DECL_FINAL (tmp) && index >= start_current_locals && index == num_current_locals - 1) { num_current_locals--; DECL_BIT_INDEX (tmp) = -1; } break; } else if (TREE_CODE (tmp = TREE_OPERAND (exp, 0)) == COMPONENT_REF) { tree decl; check_init (tmp, before); check_init (TREE_OPERAND (exp, 1), before); decl = TREE_OPERAND (tmp, 1); if (DECL_FINAL (decl)) final_assign_error (DECL_NAME (decl)); break; } else if (TREE_CODE (tmp) == COMPONENT_REF && IS_ARRAY_LENGTH_ACCESS (tmp)) { /* We can't emit a more specific message here, because when compiling to bytecodes we don't get here. */ final_assign_error (length_identifier_node); } else goto binop; case BLOCK: if (BLOCK_EXPR_BODY (exp)) { tree decl = BLOCK_EXPR_DECLS (exp); int words_needed; word* tmp; int i; int save_start_current_locals = start_current_locals; int save_num_current_words = num_current_words; start_current_locals = num_current_locals; for (; decl != NULL_TREE; decl = TREE_CHAIN (decl)) { DECL_BIT_INDEX (decl) = num_current_locals++; } words_needed = WORDS_NEEDED (2 * num_current_locals); if (words_needed > num_current_words) { tmp = ALLOC_WORDS (words_needed); COPY (tmp, before); num_current_words = words_needed; } else tmp = before; for (i = start_current_locals; i < num_current_locals; i++) { CLEAR_ASSIGNED (tmp, i); SET_UNASSIGNED (tmp, i); } check_init (BLOCK_EXPR_BODY (exp), tmp); /* Re-set DECL_BIT_INDEX since it is also DECL_POINTER_ALIAS_SET. */ for (decl = BLOCK_EXPR_DECLS (exp); decl != NULL_TREE; decl = TREE_CHAIN (decl)) { if (LOCAL_CLASS_INITIALIZATION_FLAG_P (decl)) { int index = DECL_BIT_INDEX (decl); tree fndecl = DECL_CONTEXT (decl); if (fndecl && METHOD_STATIC (fndecl) && (DECL_INITIAL (decl) == boolean_true_node || (index >= 0 && ASSIGNED_P (tmp, index)))) *(htab_find_slot (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl), DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) = DECL_FUNCTION_INIT_TEST_CLASS (decl); } DECL_BIT_INDEX (decl) = -1; } num_current_locals = start_current_locals; start_current_locals = save_start_current_locals; if (tmp != before) { num_current_words = save_num_current_words; COPY (before, tmp); FREE_WORDS (tmp); } } break; case LOOP_EXPR: { /* The JLS 2nd edition discusses a complication determining definite unassignment of loop statements. They define a "hypothetical" analysis model. We do something much simpler: We just disallow assignments inside loops to final variables declared outside the loop. This means we may disallow some contrived assignments that the JLS allows, but I can't see how anything except a very contrived testcase (a do-while whose condition is false?) would care. */ struct alternatives alt; int save_loop_current_locals = loop_current_locals; int save_start_current_locals = start_current_locals; loop_current_locals = num_current_locals; start_current_locals = num_current_locals; BEGIN_ALTERNATIVES (before, alt); alt.block = exp; check_init (TREE_OPERAND (exp, 0), before); END_ALTERNATIVES (before, alt); loop_current_locals = save_loop_current_locals; start_current_locals = save_start_current_locals; return; } case EXIT_EXPR: { struct alternatives *alt = alternatives; DECLARE_BUFFERS(when_true, 2); words when_false = when_true + num_current_words; #ifdef ENABLE_JC1_CHECKING if (TREE_CODE (alt->block) != LOOP_EXPR) abort (); #endif check_bool_init (TREE_OPERAND (exp, 0), before, when_false, when_true); done_alternative (when_true, alt); COPY (before, when_false); RELEASE_BUFFERS(when_true); return; } case LABELED_BLOCK_EXPR: { struct alternatives alt; BEGIN_ALTERNATIVES (before, alt); alt.block = exp; if (LABELED_BLOCK_BODY (exp)) check_init (LABELED_BLOCK_BODY (exp), before); done_alternative (before, &alt); END_ALTERNATIVES (before, alt); return; } case EXIT_BLOCK_EXPR: { tree block = TREE_OPERAND (exp, 0); struct alternatives *alt = alternatives; while (alt->block != block) alt = alt->outer; done_alternative (before, alt); SET_ALL (before); return; } case SWITCH_EXPR: { struct alternatives alt; word buf[2]; check_init (TREE_OPERAND (exp, 0), before); BEGIN_ALTERNATIVES (before, alt); alt.saved = ALLOC_BUFFER(buf, num_current_words); COPY (alt.saved, before); alt.block = exp; check_init (TREE_OPERAND (exp, 1), before); done_alternative (before, &alt); if (! SWITCH_HAS_DEFAULT (exp)) done_alternative (alt.saved, &alt); FREE_BUFFER(alt.saved, buf); END_ALTERNATIVES (before, alt); return; } case CASE_EXPR: case DEFAULT_EXPR: { int i; struct alternatives *alt = alternatives; while (TREE_CODE (alt->block) != SWITCH_EXPR) alt = alt->outer; COPYN (before, alt->saved, WORDS_NEEDED (2 * alt->num_locals)); for (i = alt->num_locals; i < num_current_locals; i++) CLEAR_ASSIGNED (before, i); break; } case TRY_EXPR: { tree try_clause = TREE_OPERAND (exp, 0); tree clause = TREE_OPERAND (exp, 1); word buf[2*2]; words tmp = (num_current_words <= 2 ? buf : ALLOC_WORDS (2 * num_current_words)); words save = tmp + num_current_words; struct alternatives alt; BEGIN_ALTERNATIVES (before, alt); COPY (save, before); COPY (tmp, save); check_init (try_clause, tmp); done_alternative (tmp, &alt); for ( ; clause != NULL_TREE; clause = TREE_CHAIN (clause)) { tree catch_clause = TREE_OPERAND (clause, 0); COPY (tmp, save); check_init (catch_clause, tmp); done_alternative (tmp, &alt); } if (tmp != buf) { FREE_WORDS (tmp); } END_ALTERNATIVES (before, alt); } return; case TRY_FINALLY_EXPR: { DECLARE_BUFFERS(tmp, 1); COPY (tmp, before); check_init (TREE_OPERAND (exp, 0), before); check_init (TREE_OPERAND (exp, 1), tmp); UNION (before, before, tmp); RELEASE_BUFFERS(tmp); } return; case RETURN_EXPR: case THROW_EXPR: if (TREE_OPERAND (exp, 0)) check_init (TREE_OPERAND (exp, 0), before); goto never_continues; case ERROR_MARK: never_continues: SET_ALL (before); return; case COND_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: { DECLARE_BUFFERS(when_true, 2); words when_false = when_true + num_current_words; check_bool_init (exp, before, when_false, when_true); INTERSECT (before, when_false, when_true); RELEASE_BUFFERS(when_true); } break; case NOP_EXPR: if (IS_EMPTY_STMT (exp)) break; /* ... else fall through ... */ case UNARY_PLUS_EXPR: case NEGATE_EXPR: case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: case TRUTH_NOT_EXPR: case BIT_NOT_EXPR: case CONVERT_EXPR: case BIT_FIELD_REF: case FLOAT_EXPR: case FIX_TRUNC_EXPR: case INDIRECT_REF: case ADDR_EXPR: case NON_LVALUE_EXPR: case INSTANCEOF_EXPR: case FIX_CEIL_EXPR: case FIX_FLOOR_EXPR: case FIX_ROUND_EXPR: case ABS_EXPR: /* Avoid needless recursion. */ exp = TREE_OPERAND (exp, 0); goto again; case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: case POSTDECREMENT_EXPR: case POSTINCREMENT_EXPR: tmp = get_variable_decl (TREE_OPERAND (exp, 0)); if (tmp != NULL_TREE && DECL_FINAL (tmp)) final_assign_error (DECL_NAME (tmp)); /* Avoid needless recursion. */ exp = TREE_OPERAND (exp, 0); goto again; case SAVE_EXPR: if (IS_INIT_CHECKED (exp)) return; IS_INIT_CHECKED (exp) = 1; exp = TREE_OPERAND (exp, 0); goto again; case COMPOUND_EXPR: case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR: case TRUNC_DIV_EXPR: case TRUNC_MOD_EXPR: case RDIV_EXPR: case LSHIFT_EXPR: case RSHIFT_EXPR: case URSHIFT_EXPR: case BIT_AND_EXPR: case BIT_XOR_EXPR: case BIT_IOR_EXPR: case EQ_EXPR: case NE_EXPR: case GT_EXPR: case GE_EXPR: case LT_EXPR: case LE_EXPR: case MAX_EXPR: case MIN_EXPR: case ARRAY_REF: case LROTATE_EXPR: case RROTATE_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case CEIL_MOD_EXPR: case FLOOR_MOD_EXPR: case ROUND_MOD_EXPR: case EXACT_DIV_EXPR: case UNLT_EXPR: case UNLE_EXPR: case UNGT_EXPR: case UNGE_EXPR: case UNEQ_EXPR: case LTGT_EXPR: binop: check_init (TREE_OPERAND (exp, 0), before); /* Avoid needless recursion, especially for COMPOUND_EXPR. */ exp = TREE_OPERAND (exp, 1); goto again; case RESULT_DECL: case FUNCTION_DECL: case INTEGER_CST: case REAL_CST: case STRING_CST: case JAVA_EXC_OBJ_EXPR: break; case NEW_CLASS_EXPR: case CALL_EXPR: { tree func = TREE_OPERAND (exp, 0); tree x = TREE_OPERAND (exp, 1); if (TREE_CODE (func) == ADDR_EXPR) func = TREE_OPERAND (func, 0); check_init (func, before); for ( ; x != NULL_TREE; x = TREE_CHAIN (x)) check_init (TREE_VALUE (x), before); if (func == throw_node) goto never_continues; } break; case NEW_ARRAY_INIT: { tree x = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)); for ( ; x != NULL_TREE; x = TREE_CHAIN (x)) check_init (TREE_VALUE (x), before); } break; case EXPR_WITH_FILE_LOCATION: { location_t saved_location = input_location; tree saved_wfl = wfl; tree body = EXPR_WFL_NODE (exp); if (IS_EMPTY_STMT (body)) break; wfl = exp; #ifdef USE_MAPPED_LOCATION input_location = EXPR_LOCATION (exp); #else input_filename = EXPR_WFL_FILENAME (exp); input_line = EXPR_WFL_LINENO (exp); #endif check_init (body, before); input_location = saved_location; wfl = saved_wfl; } break; default: internal_error ("internal error in check-init: tree code not implemented: %s", tree_code_name [(int) TREE_CODE (exp)]); } }
int client_main(void) { int fd, r, n, m, wait = 0, retries,pid; void *binder, *cookie; bcmd_txn_t *txn; bwr_t bwr; inst_buf_t *inst, *inst_reply; inst_entry_t *entry, copy; unsigned char rbuf[RBUF_SIZE], *ibuf, *p; struct timeval ref, delta; char labels[INST_MAX_ENTRIES][8]; unsigned long long total_usecs[INST_MAX_ENTRIES]; unsigned long long min[INST_MAX_ENTRIES],max[INST_MAX_ENTRIES],record[INST_MAX_ENTRIES]; FILE *fp; if (!share_cpus) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(id + 1, &cpuset); r = sched_setaffinity(0, sizeof(cpuset), &cpuset); if (!r) printf("client %d is bound to CPU %d\n", id, id + 1); else fprintf(stderr, "client %d failed to be bound to CPU %d\n", id, id + 1); } fd = open("/dev/binder", O_RDWR); if (fd < 0) { fprintf(stderr, "client %d failed to open binder device\n", id); return -1; } #if (!defined(INLINE_TRANSACTION_DATA)) if (mmap(NULL, 128 * 1024, PROT_READ, MAP_PRIVATE, fd, 0) == MAP_FAILED) { fprintf(stderr, "server failed to mmap shared buffer\n"); return -1; } #endif while (1) { r = lookup_service(fd, service, sizeof(service) / 2, &binder, &cookie); if (r < 0) { fprintf(stderr, "client %d failed to find the instrumentation service\n", id); return -1; } else if (r > 0) break; if (wait++ > 1) fprintf(stderr, "client %d still waiting on instrumentation service to be ready\n", id); sleep(1); } printf("client %d found instrumentation service\n", id); txn = create_transaction(0, binder, cookie, 0, NULL, sizeof(inst_buf_t) + data_SZ, NULL, 0); if (!txn) { fprintf(stderr, "client %d failed to prepare transaction buffer\n", id); return -1; } bwr.write_buffer = (unsigned long)txn; bwr.read_buffer = (unsigned long)rbuf; inst = (inst_buf_t *)txn->tdata.data.ptr.buffer; INST_INIT(inst); ibuf = malloc((iterations + 1) * sizeof(inst_entry_t) * INST_MAX_ENTRIES); if (!ibuf) fprintf(stderr, "client %d failed to allocate instrumentation buffer\n", id); p = ibuf; n = iterations + 1; while (n-- > 0) { INST_BEGIN(inst); retries = 2; bwr.write_size = sizeof(*txn); bwr.write_consumed = 0; bwr.read_size = sizeof(rbuf); bwr.read_consumed = 0; INST_ENTRY(inst, "C_SEND"); ioctl_write++; wait_reply: ioctl_read++; r = ioctl(fd, BINDER_WRITE_READ, &bwr); if (r < 0) { fprintf(stderr, "client %d failed ioctl\n", id); return r; } INST_RECORD(©); r = client_parse_command(id, rbuf, bwr.read_consumed, &inst_reply); if (r < 0) return r; if (!inst_reply) { //hexdump(rbuf, bwr.read_consumed); if (retries-- > 0) { bwr.write_size = 0; bwr.read_consumed = 0; goto wait_reply; } else { fprintf(stderr, "client %d failed to receive reply\n", id); return -1; } } memcpy(inst, inst_reply, sizeof(*inst)+data_SZ); //acsiidump(inst_reply,sizeof(*inst)+data_SZ); INST_ENTRY_COPY(inst, "C_RECV", ©); INST_END(inst, &p); #if (defined(SIMULATE_FREE_BUFFER) || !defined(INLINE_TRANSACTION_DATA)) if (FREE_BUFFER(fd, inst_reply) < 0) { fprintf(stderr, "client %d: failed to free shared buffer\n", id); return -1; } #endif } if (output_file) { if (clients > 1) { char *p = malloc(strlen(output_file) + 16); if (!p) { fprintf(stderr, "client %d failed to alloc memory for filename\n", id); return -1; } sprintf(p, "%s-%d", output_file, id); output_file = p; } fp = fopen(output_file, "w"); if (!fp) { fprintf(stderr, "client %d failed to open dump file\n", id); return -1; } } else fp = stdout; memset(total_usecs, 0, sizeof(total_usecs)); memset(max,0,sizeof(max)); memset(min,255,sizeof(min)); entry = (inst_entry_t *)ibuf; int i; //acsiidump(ibuf,80); for (n = 0; n < inst->seq; n++) { for (m = 0; m < inst->next_entry; m++) { if (n > 0) { if (m == 0) { if (time_ref == 0) // absolute time ref.tv_sec = ref.tv_usec = 0; else ref = entry->tv; } delta.tv_sec = entry->tv.tv_sec - ref.tv_sec; delta.tv_usec = entry->tv.tv_usec - ref.tv_usec; if (delta.tv_usec < 0) { delta.tv_sec--; delta.tv_usec += 1000000; } record[m] = delta.tv_sec * 1000000 + delta.tv_usec; //fprintf(fp, "%ld.%06ld\t", delta.tv_sec, delta.tv_usec); if (time_ref > 0) { total_usecs[m] += delta.tv_sec * 1000000 + delta.tv_usec; if( m == inst->next_entry -1) { if (min[m] > record[m] ) { for( i = 0; i < inst->next_entry; i++ ) { min[i] = record[i]; } } if (max[m] < record[m] ) { for( i = 0; i < inst->next_entry; i++ ) { max[i] = record[i]; } } } } if (time_ref > 1) // relative to the previous entry ref = entry->tv; } else { //fprintf(fp, "%8s\t", entry->label); if (time_ref > 0) strcpy(labels[m], entry->label); } entry++; } //fprintf(fp, "\n"); } if (fp != stdout) fclose(fp); free(txn); pid =getpid(); printf("client(%d) %d: ioctl read: %u\n",pid,id, ioctl_read); printf("client(%d) %d: ioctl write: %u\n",pid,id, ioctl_write); printf("client(%d) %d: ioctl buffer: %u\n",pid,id, ioctl_buffer); if (time_ref > 0 && iterations > 0) { int pos = 0,minpos=0,maxpos=0; char *buf = malloc(64 * m); char *minbuf = malloc(64 * m); char *maxbuf = malloc(64 * m); if (!buf||!minbuf||!maxbuf) return 1; for (n = 0; n < m; n++) { pos += sprintf(buf + pos, "\t%s: %lld.%02lldus\n", labels[n], (total_usecs[n] / iterations), (total_usecs[n] % iterations) * 100 / iterations); minpos += sprintf(minbuf + minpos, "\t%s: %lldus\n", labels[n], min[n]); maxpos += sprintf(maxbuf + maxpos, "\t%s: %lldus\n", labels[n], max[n]); } printf("client %d: average results:\n%s\n", id, buf); printf("client %d: min results:\n%s\n", id, minbuf); printf("client %d: max results:\n%s\n", id, maxbuf); free(buf); free(minbuf); free(maxbuf); } return 0; }
int server_main(void) { int fd, r, len; void *binder, *cookie; bwr_t bwr; unsigned char rbuf[RBUF_SIZE], *p; bcmd_txn_t *reply; tdata_t *tdata = NULL; inst_buf_t *inst; inst_entry_t copy; if (!share_cpus) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); r = sched_setaffinity(0, sizeof(cpuset), &cpuset); if (!r) printf("server is bound to CPU 0\n"); else fprintf(stderr, "server failed to be bound to CPU 0\n"); } fd = open("/dev/binder", O_RDWR); if (fd < 0) { fprintf(stderr, "failed to open binder device\n"); return -1; } #if (!defined(INLINE_TRANSACTION_DATA)) if (mmap(NULL, 128 * 1024, PROT_READ, MAP_PRIVATE, fd, 0) == MAP_FAILED) { fprintf(stderr, "server failed to mmap shared buffer\n"); return -1; } #endif binder = SVC_BINDER; cookie = SVC_COOKIE; r = add_service(fd, binder, cookie, service, sizeof(service) / 2); if (r < 0) { printf("server failed to add instrumentation service\n"); return -1; } printf("server added instrumentation service\n"); r = start_looper(fd); if (r < 0) { printf("server failed to start looper\n"); return -1; } bwr.read_buffer = (unsigned long)rbuf; while (1) { bwr.read_size = sizeof(rbuf); bwr.read_consumed = 0; bwr.write_size = 0; ioctl_read++; r = ioctl(fd, BINDER_WRITE_READ, &bwr); if (r < 0) { fprintf(stderr, "server failed ioctl\n"); return r; } INST_RECORD(©); p = rbuf; len = bwr.read_consumed; while (len > 0) { r = server_parse_command(p, len, &tdata, &reply); //hexdump(tdata, bwr.read_consumed); if (r < 0) return r; p += r; len -= r; #if (defined(SIMULATE_FREE_BUFFER) || !defined(INLINE_TRANSACTION_DATA)) if (tdata) FREE_BUFFER(fd, (void *)tdata->data.ptr.buffer); #endif if (!reply) { //hexdump(rbuf, bwr.read_consumed); continue; } inst = (inst_buf_t *)reply->tdata.data.ptr.buffer; INST_ENTRY_COPY(inst, "S_RECV", ©); //acsiidump(inst,sizeof(*inst)+data_SZ); bwr.write_buffer = (unsigned long)reply; bwr.write_size = sizeof(*reply); bwr.write_consumed = 0; bwr.read_size = 0; INST_ENTRY(inst, "S_REPLY"); ioctl_write++; r = ioctl(fd, BINDER_WRITE_READ, &bwr); if (r < 0) { fprintf(stderr, "server failed reply ioctl\n"); return r; } #if (!defined(INLINE_TRANSACTION_DATA)) free(reply); #endif } } free(reply); return 0; }
int add_service(int fd, void *binder, void *cookie, uint16_t *name, int len) { unsigned char buf[1024], *p; obj_t *obj; size_t *offsets; bcmd_txn_t *txn; tdata_t *tdata; int r; p = buf; // strict_policy *(uint32_t *)p = 0; p += 4; // svcmgr_id *(uint32_t *)p = sizeof(svcmgr_id) / 2; p += 4; memcpy(p, svcmgr_id, sizeof(svcmgr_id)); p += sizeof(svcmgr_id); *(uint16_t *)p = 0; p += 2; p = (unsigned char *)ALIGN((unsigned long)p); // name *(uint32_t *)p = len; p += 4; memcpy(p, name, len * 2); p += len * 2; *(uint16_t *)p = 0; p += 2; p = (unsigned char *)ALIGN((unsigned long)p); // flat_binder_obj obj = (obj_t *)p; obj->type = BINDER_TYPE_BINDER; obj->flags = 0; obj->binder = binder; obj->cookie = cookie; p = (unsigned char *)(obj + 1); // offsets offsets = (size_t *)p; *offsets = (unsigned char *)obj - buf; txn = create_transaction(0, NULL, NULL, 3, buf, p - buf, (unsigned char *)offsets, 4); if (!txn) return -1; r = simple_transact(fd, txn, &tdata, buf, sizeof(buf)); if (r < 0) return r; if (tdata->data_size != 4 || *(unsigned int *)tdata->data.ptr.buffer) { fprintf(stderr, "server invalid reply data received\n"); return -1; } #if (defined(SIMULATE_FREE_BUFFER) || !defined(INLINE_TRANSACTION_DATA)) if (FREE_BUFFER(fd, (void *)tdata->data.ptr.buffer) < 0) { fprintf(stderr, "failed to free shared buffer\n"); return -1; } #endif free(txn); return 0; }