Exemple #1
0
unsigned int bitmap_find_zero_bit(const unsigned long *bitmap,
		unsigned int nbits, unsigned int start) {
	const unsigned long *p, *pend;
	unsigned long tmp;

	if (start >= nbits)
		return nbits;

	p = bitmap + BITMAP_OFFSET(start);
	pend = bitmap + BITMAP_OFFSET(nbits);

	tmp = *p | ((1 << BITMAP_SHIFT(start)) - 1);

	while (p < pend) {
		if (~tmp)
			goto found;
		tmp = *(++p);
	}

	tmp |= ~(1 << BITMAP_SHIFT(nbits)) + 1;
	if (!~tmp)
		return nbits;
found:
	return LONG_BIT * (p - bitmap) + bit_ctz(~tmp);
}
Exemple #2
0
unsigned int bitmap_find_bit(const unsigned long *bitmap,
		unsigned int nbits, unsigned int start) {
	const unsigned long *p = bitmap + BITMAP_OFFSET(start);  /* start word */
	unsigned int shift = BITMAP_SHIFT(start);  /* within the start word */
	unsigned int result = start - shift;  /* LONG_BIT-aligned down start */
	unsigned long tmp;

	if (start >= nbits)
		return nbits;

	nbits -= result;
	tmp = *(p++) & (~0x0ul << shift);  /* mask out the beginning */

	while (nbits > LONG_BIT) {
		if (tmp)
			goto found;
		result += LONG_BIT;
		nbits -= LONG_BIT;
		tmp = *(p++);
	}

	tmp &= (~0x0ul >> (LONG_BIT - nbits));  /* ...and the ending */
	if (!tmp)
		return result + nbits;

found:
	return result + bit_ctz(tmp);
}
Exemple #3
0
static inline bool
bb_table_add(bb_table_t *table, bb_entry_t *entry)
{
    byte *bm;
    uint idx, offs, addr_end, idx_end, offs_end, i;
    if (table == BB_TABLE_IGNORE)
        return false;
    if (table->size <= entry->start + entry->size) {
        WARN(3, "Wrong range "PFX"-"PFX" or table size "PFX" for table "PFX"\n",
             (ptr_uint_t)entry->start,
             (ptr_uint_t)entry->start + entry->size,
             (ptr_uint_t)table->size,
             (ptr_uint_t)table);
        return false;
    }
    bm  = table->bm;
    idx = BITMAP_INDEX(entry->start);
    /* we assume that the whole bb is seen if its start addr is seen */
    if (bm[idx] == BB_TABLE_RANGE_SET)
        return false;
    offs = BITMAP_OFFSET(entry->start);
    if (TEST(BITMAP_MASK(offs), bm[idx]))
        return false;
    /* now we add a new bb */
    PRINT(6, "Add "PFX"-"PFX" in table "PFX"\n",
          (ptr_uint_t)entry->start,
          (ptr_uint_t)entry->start + entry->size,
          (ptr_uint_t)table);
    addr_end = entry->start + entry->size - 1;
    idx_end  = BITMAP_INDEX(addr_end);
    offs_end = (idx_end > idx) ? BITS_PER_BYTE-1 : BITMAP_OFFSET(addr_end);
    /* first byte in the bitmap */
    bm[idx] |= bitmap_set[offs][offs_end];
    /* set all the middle byte */
    for (i = idx + 1; i < idx_end; i++)
        bm[i] = BB_TABLE_RANGE_SET;
    /* last byte in the bitmap */
    if (idx_end > idx) {
        offs_end = BITMAP_OFFSET(addr_end);
        bm[idx_end] |= bitmap_set[0][offs_end];
    }
    return true;
}
Exemple #4
0
static inline int
bb_table_lookup(bb_table_t *table, uint addr)
{
    byte *bm = table->bm;
    PRINT(5, "lookup "PFX" in bb table "PFX"\n",
          (ptr_uint_t)addr, (ptr_uint_t)table);
    /* We see this and it seems to be erroneous data from the pdb,
     * xref drsym_enumerate_lines() from drsyms.
     */
    if (table->size <= addr)
        return BB_TABLE_ENTRY_INVALID;
    if (bm[BITMAP_INDEX(addr)] == 0xff ||
        TEST(BITMAP_MASK(BITMAP_OFFSET(addr)), bm[BITMAP_INDEX(addr)]))
        return BB_TABLE_ENTRY_SET;
    return BB_TABLE_ENTRY_CLEAR;
}