void setDeviceList(JNIEnv* env, libusb_device** list, int size, jobject object) { SET_POINTER(env, list, object, "deviceListPointer"); jclass cls = (*env)->GetObjectClass(env, object); jfieldID field = (*env)->GetFieldID(env, cls, "size", "I"); (*env)->SetIntField(env, object, field, size); }
void setDeviceList(JNIEnv* env, libusb_device* const *list, jint size, jobject object) { SET_POINTER(env, list, object, "deviceListPointer"); // We already have the class from the previous call. field = (*env)->GetFieldID(env, cls, "size", "I"); (*env)->SetIntField(env, object, field, size); }
/* * Break up ADDR_ALL into ADDR_P and ADDR_COUNT_P */ void _dmalloc_address_break(const char *addr_all, DMALLOC_PNT *addr_p, unsigned long *addr_count_p) { char *colon_p; SET_POINTER(addr_p, (DMALLOC_PNT)hex_to_long(addr_all)); if (addr_count_p != NULL) { colon_p = strchr(addr_all, ':'); if (colon_p != NULL) { *addr_count_p = loc_atoul(colon_p + 1); } } }
/* * Read in a rc file from PATH and process it looking for the * specified DEBUG_VALUE or TAG_FIND token. It passes back the * returned debug value in DEBUG_P. Passes back the matching TOKEN of * TOKEN_SIZE. * * Returns FILE_NOT_FOUND, FILE_FOUND, or TOKEN_FOUND. */ static int read_rc_file(const char *path, const long debug_value, const char *tag_find, long *debug_p, char *token, const int token_size) { FILE *infile; int found_b = 0; char next_token[64]; long new_debug; /* open the path */ infile = fopen(path, "r"); if (infile == NULL) { return FILE_NOT_FOUND; } /* run through the tokens, looking for a match */ while (read_next_token(infile, &new_debug, next_token, sizeof(next_token)) == 1) { /* are we looking for a tag? */ if (tag_find != NULL && strcmp(tag_find, next_token) == 0) { found_b = 1; break; } /* are we looking for a debug-value? */ if (debug_value > 0 && debug_value == new_debug) { found_b = 1; break; } } (void)fclose(infile); SET_POINTER(debug_p, new_debug); if (token != NULL) { (void)loc_snprintf(token, token_size, "config file token: %s", next_token); } if (found_b) { return TOKEN_FOUND; } else { return FILE_FOUND; } }
/* * static void *alloc_mem * * DESCRIPTION: * * Allocate space for bytes inside of an already open memory pool. * * RETURNS: * * Success - Pointer to the address to use. * * Failure - NULL * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool. If NULL then it will do a * normal malloc. * * byte_size -> Number of bytes to allocate in the pool. Must be >0. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ static void *alloc_mem(mpool_t *mp_p, const unsigned long byte_size, int *error_p) { unsigned long size, fence; void *addr; /* make sure we have enough bytes */ if (byte_size < MIN_ALLOCATION) { size = MIN_ALLOCATION; } else { size = byte_size; } if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { fence = 0; } else { fence = FENCE_SIZE; } /* get our free space + the space for the fence post */ addr = get_space(mp_p, size + fence, error_p); if (addr == NULL) { /* error_p set in get_space */ return NULL; } if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) { write_magic((char *)addr + size); } /* maintain our stats */ mp_p->mp_alloc_c++; mp_p->mp_user_alloc += size; if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) { mp_p->mp_max_alloc = mp_p->mp_user_alloc; } SET_POINTER(error_p, MPOOL_ERROR_NONE); return addr; }
/* * Process the values of dmalloc environ variable(s) from ENVIRON * string. */ void _dmalloc_environ_process(const char *env_str, DMALLOC_PNT *addr_p, unsigned long *addr_count_p, unsigned int *debug_p, unsigned long *interval_p, int *lock_on_p, char **logpath_p, char **start_file_p, int *start_line_p, unsigned long *start_iter_p, unsigned long *start_size_p, unsigned long *limit_p) { char *env_p, *this_p; char buf[1024]; int len, done_b = 0; unsigned int flags = 0; attr_t *attr_p; SET_POINTER(addr_p, NULL); SET_POINTER(addr_count_p, 0); SET_POINTER(debug_p, 0); SET_POINTER(interval_p, 0); SET_POINTER(lock_on_p, 0); SET_POINTER(logpath_p, NULL); SET_POINTER(start_file_p, NULL); SET_POINTER(start_line_p, 0); SET_POINTER(start_iter_p, 0); SET_POINTER(start_size_p, 0); SET_POINTER(limit_p, 0); /* make a copy */ (void)strncpy(buf, env_str, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; /* handle each of tokens, in turn */ for (env_p = buf, this_p = buf; ! done_b; env_p++, this_p = env_p) { /* find the comma of end */ for (;; env_p++) { if (*env_p == '\0') { done_b = 1; break; } if (*env_p == ',' && (env_p == buf || *(env_p - 1) != '\\')) { break; } } /* should we strip ' ' or '\t' here? */ if (this_p == env_p) { continue; } *env_p = '\0'; len = strlen(ADDRESS_LABEL); if (strncmp(this_p, ADDRESS_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; _dmalloc_address_break(this_p, addr_p, addr_count_p); continue; } len = strlen(DEBUG_LABEL); if (strncmp(this_p, DEBUG_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; SET_POINTER(debug_p, hex_to_long(this_p)); continue; } len = strlen(INTERVAL_LABEL); if (strncmp(this_p, INTERVAL_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; SET_POINTER(interval_p, loc_atoul(this_p)); continue; } len = strlen(LOCK_ON_LABEL); if (strncmp(this_p, LOCK_ON_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; SET_POINTER(lock_on_p, atoi(this_p)); continue; } /* get the dmalloc logfile name into a holding variable */ len = strlen(LOGFILE_LABEL); if (strncmp(this_p, LOGFILE_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; (void)strncpy(log_path, this_p, sizeof(log_path)); log_path[sizeof(log_path) - 1] = '\0'; SET_POINTER(logpath_p, log_path); continue; } /* * start checking the heap after X iterations OR * start at a file:line combination */ len = strlen(START_LABEL); if (strncmp(this_p, START_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; _dmalloc_start_break(this_p, start_file_p, start_line_p, start_iter_p, start_size_p); continue; } /* set the memory limit to the library */ len = strlen(LIMIT_LABEL); if (strncmp(this_p, LIMIT_LABEL, len) == 0 && *(this_p + len) == ASSIGNMENT_CHAR) { this_p += len + 1; SET_POINTER(limit_p, loc_atoul(this_p)); continue; } /* need to check the short/long debug options */ for (attr_p = attributes; attr_p->at_string != NULL; attr_p++) { if (strcmp(this_p, attr_p->at_string) == 0) { flags |= attr_p->at_value; break; } } if (attr_p->at_string != NULL) { continue; } } /* append the token settings to the debug setting */ if (debug_p != NULL) { if (*debug_p == 0) { *debug_p = flags; } else { *debug_p |= flags; } } }
/* * Break up START_ALL into SFILE_P, SLINE_P, and SCOUNT_P */ void _dmalloc_start_break(char *start_all, char **start_file_p, int *start_line_p, unsigned long *start_iter_p, unsigned long *start_size_p) { char *start_p; start_p = strchr(start_all, ':'); if (start_p != NULL) { (void)strncpy(start_file, start_all, sizeof(start_file)); start_file[sizeof(start_file) - 1] = '\0'; SET_POINTER(start_file_p, start_file); start_p = start_file + (start_p - start_all); *start_p = '\0'; SET_POINTER(start_line_p, atoi(start_p + 1)); SET_POINTER(start_iter_p, 0); SET_POINTER(start_size_p, 0); } else if (start_all[0] == 's') { SET_POINTER(start_file_p, NULL); SET_POINTER(start_line_p, 0); SET_POINTER(start_iter_p, 0); SET_POINTER(start_size_p, loc_atoul(start_all + 1)); } else { SET_POINTER(start_file_p, NULL); SET_POINTER(start_line_p, 0); if (start_all[0] == 'c') { SET_POINTER(start_iter_p, loc_atoul(start_all + 1)); } else { SET_POINTER(start_iter_p, loc_atoul(start_all)); } SET_POINTER(start_size_p, 0); } }
void setContext(JNIEnv* env, const libusb_context* context, jobject object) { SET_POINTER(env, context, object, "contextPointer"); }
void setContainerIdDescriptor(JNIEnv* env, const struct libusb_container_id_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "containerIdDescriptorPointer"); }
void setHotplugCallbackHandle(JNIEnv* env, const libusb_hotplug_callback_handle hotplugHandle, jobject object) { SET_POINTER(env, hotplugHandle, object, "hotplugCallbackHandleValue"); }
void setSsEndpointCompanionDescriptor(JNIEnv* env, const struct libusb_ss_endpoint_companion_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "ssEndpointCompanionDescriptorPointer"); }
void setBosDescriptor(JNIEnv* env, struct libusb_bos_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "bosDescriptorPointer"); }
/* * Read in the next token from INFILE. It passes back the returned * debug value in DEBUG_P. Passes back the matching TOKEN of * TOKEN_SIZE. Returns 1 if there was a next else 0. */ static int read_next_token(FILE *infile, long *debug_p, char *token, const int token_size) { int cont_b = 0, found_b = 0; long new_debug = 0; char buf[1024], *tok_p, *buf_p; while (fgets(buf, sizeof(buf), infile) != NULL) { /* ignore comments and empty lines */ if (buf[0] == '#' || buf[0] == '\n') { continue; } /* chop off the ending \n */ buf_p = strrchr(buf, '\n'); SET_POINTER(buf_p, '\0'); buf_p = buf; /* if we're not continuing then we need to process a tag */ if (! cont_b) { /* get the first token on the line */ tok_p = strsep(&buf_p, TOKENIZE_EQUALS); if (tok_p == NULL) { continue; } if (*tok_p == '\0') { (void)fprintf(stderr, "Invalid start of line: %s\n", buf_p); continue; } /* save the token */ if (token != NULL) { (void)strncpy(token, tok_p, token_size); token[token_size - 1] = '\0'; } found_b = 1; } cont_b = 0; while (1) { /* get the next token */ tok_p = strsep(&buf_p, TOKENIZE_CHARS); if (tok_p == NULL) { break; } if (*tok_p == '\0') { continue; } /* do we have a continuation character? */ if (strcmp(tok_p, "\\") == 0) { cont_b = 1; break; } new_debug |= token_to_value(tok_p); } /* are we done? */ if (! cont_b) { break; } } SET_POINTER(debug_p, new_debug); if (found_b) { return 1; } else { return 0; } }
/* * static void *alloc_pages * * DESCRIPTION: * * Allocate space for a number of memory pages in the memory pool. * * RETURNS: * * Success - New pages of memory * * Failure - NULL * * ARGUMENTS: * * mp_p <-> Pointer to our memory pool. * * page_n -> Number of pages to alloc. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ static void *alloc_pages(mpool_t *mp_p, const unsigned int page_n, int *error_p) { void *mem, *fill_mem; unsigned long size, fill; int state; /* are we over our max-pages? */ if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) { SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES); return NULL; } size = SIZE_OF_PAGES(mp_p, page_n); #ifdef DEBUG (void)printf("allocating %u pages or %lu bytes\n", page_n, size); #endif if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) { mem = sbrk(size); if (mem == (void *)-1) { SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); return NULL; } fill = (unsigned long)mem % mp_p->mp_page_size; if (fill > 0) { fill = mp_p->mp_page_size - fill; fill_mem = sbrk(fill); if (fill_mem == (void *)-1) { SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); return NULL; } if ((char *)fill_mem != (char *)mem + size) { SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG); return NULL; } mem = (char *)mem + fill; } } else { state = MAP_PRIVATE; #ifdef MAP_FILE state |= MAP_FILE; #endif #ifdef MAP_VARIABLE state |= MAP_VARIABLE; #endif /* mmap from /dev/zero */ mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state, mp_p->mp_fd, mp_p->mp_top); if (mem == (void *)MAP_FAILED) { if (errno == ENOMEM) { SET_POINTER(error_p, MPOOL_ERROR_NO_MEM); } else { SET_POINTER(error_p, MPOOL_ERROR_MMAP); } return NULL; } mp_p->mp_top += size; if (mp_p->mp_addr != NULL) { mp_p->mp_addr = (char *)mp_p->mp_addr + size; } } mp_p->mp_page_c += page_n; SET_POINTER(error_p, MPOOL_ERROR_NONE); return mem; }
void setConfigDescriptor(JNIEnv* env, struct libusb_config_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "configDescriptorPointer"); }
/* * static void *get_space * * DESCRIPTION: * * Moved a pointer into our free lists. * * RETURNS: * * Success - New address that we can use. * * Failure - NULL * * ARGUMENTS: * * mp_p <-> Pointer to the memory pool. * * byte_size -> Size of the address space that we need. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ static void *get_space(mpool_t *mp_p, const unsigned long byte_size, int *error_p) { mpool_block_t *block_p; mpool_free_t free_pnt; int ret; unsigned long size; unsigned int bit_c, page_n, left; void *free_addr = NULL, *free_end; size = byte_size; while ((size & (sizeof(void *) - 1)) > 0) { size++; } /* * First we check the free lists looking for something with enough * pages. Maybe we should only look X bits higher in the list. * * XXX: this is where we'd do the best fit. We'd look for the * closest match. We then could put the rest of the allocation that * we did not use in a lower free list. Have a define which states * how deep in the free list to go to find the closest match. */ for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) { if (mp_p->mp_free[bit_c] != NULL) { free_addr = mp_p->mp_free[bit_c]; break; } } /* * If we haven't allocated any blocks or if the last block doesn't * have enough memory then we need a new block. */ if (bit_c > MAX_BITS) { /* we need to allocate more space */ page_n = PAGES_IN_SIZE(mp_p, size); /* now we try and get the pages we need/want */ block_p = alloc_pages(mp_p, page_n, error_p); if (block_p == NULL) { /* error_p set in alloc_pages */ return NULL; } /* init the block header */ block_p->mb_magic = BLOCK_MAGIC; block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n); block_p->mb_next_p = mp_p->mp_first_p; block_p->mb_magic2 = BLOCK_MAGIC; /* * We insert it into the front of the queue. We could add it to * the end but there is not much use. */ mp_p->mp_first_p = block_p; if (mp_p->mp_last_p == NULL) { mp_p->mp_last_p = block_p; } free_addr = FIRST_ADDR_IN_BLOCK(block_p); #ifdef DEBUG (void)printf("had to allocate space for %lx of %lu bytes\n", (long)free_addr, size); #endif free_end = (char *)free_addr + size; left = (char *)block_p->mb_bounds_p - (char *)free_end; } else { if (bit_c < min_bit_free_next) { mp_p->mp_free[bit_c] = NULL; /* calculate the number of left over bytes */ left = bits_to_size(bit_c) - size; } else if (bit_c < min_bit_free_next) { /* grab the next pointer from the freed address into our list */ memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *)); /* calculate the number of left over bytes */ left = bits_to_size(bit_c) - size; } else { /* grab the free structure from the address */ memcpy(&free_pnt, free_addr, sizeof(free_pnt)); mp_p->mp_free[bit_c] = free_pnt.mf_next_p; /* are we are splitting up a multiblock chunk into fewer blocks? */ if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) { ret = split_block(mp_p, free_addr, size); if (ret != MPOOL_ERROR_NONE) { SET_POINTER(error_p, ret); return NULL; } /* left over memory was taken care of in split_block */ left = 0; } else { /* calculate the number of left over bytes */ left = free_pnt.mf_size - size; } } #ifdef DEBUG (void)printf("found a free block at %lx of %lu bytes\n", (long)free_addr, left + size); #endif free_end = (char *)free_addr + size; } /* * If we have memory left over then we free it so someone else can * use it. We do not free the space if we just allocated a * multi-block chunk because we need to have every allocation easily * find the start of the block. Every user address % page-size * should take us to the start of the block. */ if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) { /* free the rest of the block */ ret = free_pointer(mp_p, free_end, left); if (ret != MPOOL_ERROR_NONE) { SET_POINTER(error_p, ret); return NULL; } } /* update our bounds */ if (free_addr > mp_p->mp_bounds_p) { mp_p->mp_bounds_p = free_addr; } else if (free_addr < mp_p->mp_min_p) { mp_p->mp_min_p = free_addr; } return free_addr; }
void setDeviceHandle(JNIEnv* env, const libusb_device_handle* deviceHandle, jobject object) { SET_POINTER(env, deviceHandle, object, "deviceHandlePointer"); }
/* * mpool_t *mpool_open * * DESCRIPTION: * * Open/allocate a new memory pool. * * RETURNS: * * Success - Pool pointer which must be passed to mpool_close to * deallocate. * * Failure - NULL * * ARGUMENTS: * * flags -> Flags to set attributes of the memory pool. See the top * of mpool.h. * * page_size -> Set the internal memory page-size. This must be a * multiple of the getpagesize() value. Set to 0 for the default. * * start_addr -> Starting address to try and allocate memory pools. * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled. * * error_p <- Pointer to integer which, if not NULL, will be set with * a mpool error code. */ mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size, void *start_addr, int *error_p) { mpool_block_t *block_p; int page_n, ret; mpool_t mp, *mp_p; void *free_addr; if (! enabled_b) { startup(); } /* zero our temp struct */ memset(&mp, 0, sizeof(mp)); mp.mp_magic = MPOOL_MAGIC; mp.mp_flags = flags; mp.mp_alloc_c = 0; mp.mp_user_alloc = 0; mp.mp_max_alloc = 0; mp.mp_page_c = 0; /* mp.mp_page_size set below */ /* mp.mp_blocks_bit_n set below */ /* mp.mp_fd set below */ /* mp.mp_top set below */ /* mp.mp_addr set below */ mp.mp_log_func = NULL; mp.mp_min_p = NULL; mp.mp_bounds_p = NULL; mp.mp_first_p = NULL; mp.mp_last_p = NULL; mp.mp_magic2 = MPOOL_MAGIC; /* get and sanity check our page size */ if (page_size > 0) { mp.mp_page_size = page_size; if (mp.mp_page_size % getpagesize() != 0) { SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID); return NULL; } } else { mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT; if (mp.mp_page_size % 1024 != 0) { SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE); return NULL; } } if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) { mp.mp_fd = -1; mp.mp_addr = NULL; mp.mp_top = 0; } else { /* open dev-zero for our mmaping */ mp.mp_fd = open("/dev/zero", O_RDWR, 0); if (mp.mp_fd < 0) { SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO); return NULL; } mp.mp_addr = start_addr; /* we start at the front of the file */ mp.mp_top = 0; } /* * Find out how many pages we need for our mpool structure. * * NOTE: this adds possibly unneeded space for mpool_block_t which * may not be in this block. */ page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t)); /* now allocate us space for the actual struct */ mp_p = alloc_pages(&mp, page_n, error_p); if (mp_p == NULL) { if (mp.mp_fd >= 0) { (void)close(mp.mp_fd); mp.mp_fd = -1; } return NULL; } /* * NOTE: we do not normally free the rest of the block here because * we want to lesson the chance of an allocation overwriting the * main structure. */ if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) { /* we add a block header to the front of the block */ block_p = (mpool_block_t *)mp_p; /* init the block header */ block_p->mb_magic = BLOCK_MAGIC; block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n); block_p->mb_next_p = NULL; block_p->mb_magic2 = BLOCK_MAGIC; /* the mpool pointer is then the 2nd thing in the block */ mp_p = FIRST_ADDR_IN_BLOCK(block_p); free_addr = (char *)mp_p + sizeof(mpool_t); /* free the rest of the block */ ret = free_pointer(&mp, free_addr, (char *)block_p->mb_bounds_p - (char *)free_addr); if (ret != MPOOL_ERROR_NONE) { if (mp.mp_fd >= 0) { (void)close(mp.mp_fd); mp.mp_fd = -1; } /* NOTE: after this line mp_p will be invalid */ (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n), BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)); SET_POINTER(error_p, ret); return NULL; } /* * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool * header is not on the block linked list. */ /* now copy our tmp structure into our new memory area */ memcpy(mp_p, &mp, sizeof(mpool_t)); /* we setup min/max to our current address which is as good as any */ mp_p->mp_min_p = block_p; mp_p->mp_bounds_p = block_p->mb_bounds_p; } else { /* now copy our tmp structure into our new memory area */ memcpy(mp_p, &mp, sizeof(mpool_t)); /* we setup min/max to our current address which is as good as any */ mp_p->mp_min_p = mp_p; mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n); } SET_POINTER(error_p, MPOOL_ERROR_NONE); return mp_p; }
void setSsUsbDeviceCapabilityDescriptor(JNIEnv* env, const struct libusb_ss_usb_device_capability_descriptor* descriptor, jobject object) { SET_POINTER(env, descriptor, object, "ssUsbDeviceCapabilityDescriptorPointer"); }