Coverage Report

Created: 2023-06-07 06:35

/src/e2fsprogs/lib/ext2fs/bitops.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * bitops.c --- Bitmap frobbing code.  See bitops.h for the inlined
3
 *  routines.
4
 *
5
 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
6
 *
7
 * %Begin-Header%
8
 * This file may be redistributed under the terms of the GNU Library
9
 * General Public License, version 2.
10
 * %End-Header%
11
 */
12
13
#include "config.h"
14
#include <stdio.h>
15
#if HAVE_SYS_TYPES_H
16
#include <sys/types.h>
17
#endif
18
19
#include "ext2_fs.h"
20
#include "ext2fs.h"
21
22
/*
23
 * C language bitmap functions written by Theodore Ts'o, 9/26/92.
24
 * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian
25
 * systems, as well as non-32 bit systems.
26
 */
27
28
int ext2fs_set_bit(unsigned int nr,void * addr)
29
129k
{
30
129k
  int   mask, retval;
31
129k
  unsigned char *ADDR = (unsigned char *) addr;
32
33
129k
  ADDR += nr >> 3;
34
129k
  mask = 1 << (nr & 0x07);
35
129k
  retval = mask & *ADDR;
36
129k
  *ADDR |= mask;
37
129k
  return retval;
38
129k
}
39
40
int ext2fs_clear_bit(unsigned int nr, void * addr)
41
0
{
42
0
  int   mask, retval;
43
0
  unsigned char *ADDR = (unsigned char *) addr;
44
45
0
  ADDR += nr >> 3;
46
0
  mask = 1 << (nr & 0x07);
47
0
  retval = mask & *ADDR;
48
0
  *ADDR &= ~mask;
49
0
  return retval;
50
0
}
51
52
int ext2fs_test_bit(unsigned int nr, const void * addr)
53
0
{
54
0
  int     mask;
55
0
  const unsigned char *ADDR = (const unsigned char *) addr;
56
57
0
  ADDR += nr >> 3;
58
0
  mask = 1 << (nr & 0x07);
59
0
  return (mask & *ADDR);
60
0
}
61
62
void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
63
      const char *description)
64
190k
{
65
190k
#ifndef OMIT_COM_ERR
66
190k
  if (description)
67
190k
    com_err(0, errcode, "#%lu for %s", arg, description);
68
0
  else
69
0
    com_err(0, errcode, "#%lu", arg);
70
190k
#endif
71
190k
}
72
73
/* Bitmap functions that take a 64-bit offset */
74
75
int ext2fs_set_bit64(__u64 nr, void * addr)
76
0
{
77
0
  int   mask, retval;
78
0
  unsigned char *ADDR = (unsigned char *) addr;
79
80
0
  ADDR += nr >> 3;
81
0
  mask = 1 << (nr & 0x07);
82
0
  retval = mask & *ADDR;
83
0
  *ADDR |= mask;
84
0
  return retval;
85
0
}
86
87
int ext2fs_clear_bit64(__u64 nr, void * addr)
88
0
{
89
0
  int   mask, retval;
90
0
  unsigned char *ADDR = (unsigned char *) addr;
91
92
0
  ADDR += nr >> 3;
93
0
  mask = 1 << (nr & 0x07);
94
0
  retval = mask & *ADDR;
95
0
  *ADDR &= ~mask;
96
0
  return retval;
97
0
}
98
99
int ext2fs_test_bit64(__u64 nr, const void * addr)
100
0
{
101
0
  int     mask;
102
0
  const unsigned char *ADDR = (const unsigned char *) addr;
103
104
0
  ADDR += nr >> 3;
105
0
  mask = 1 << (nr & 0x07);
106
0
  return (mask & *ADDR);
107
0
}
108
109
static unsigned int popcount8(unsigned int w)
110
0
{
111
0
  unsigned int res = w - ((w >> 1) & 0x55);
112
0
  res = (res & 0x33) + ((res >> 2) & 0x33);
113
0
  return (res + (res >> 4)) & 0x0F;
114
0
}
115
116
static unsigned int popcount32(unsigned int w)
117
0
{
118
0
  unsigned int res = w - ((w >> 1) & 0x55555555);
119
0
  res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
120
0
  res = (res + (res >> 4)) & 0x0F0F0F0F;
121
0
  res = res + (res >> 8);
122
0
  return (res + (res >> 16)) & 0x000000FF;
123
0
}
124
125
unsigned int ext2fs_bitcount(const void *addr, unsigned int nbytes)
126
0
{
127
0
  const unsigned char *cp = addr;
128
0
  const __u32 *p;
129
0
  unsigned int res = 0;
130
131
0
  while (((((uintptr_t) cp) & 3) != 0) && (nbytes > 0)) {
132
0
    res += popcount8(*cp++);
133
0
    nbytes--;
134
0
  }
135
0
  p = (const __u32 *) cp;
136
137
0
  while (nbytes > 4) {
138
0
    res += popcount32(*p++);
139
0
    nbytes -= 4;
140
0
  }
141
0
  cp = (const unsigned char *) p;
142
143
0
  while (nbytes > 0) {
144
0
    res += popcount8(*cp++);
145
0
    nbytes--;
146
0
  }
147
0
  return res;
148
0
}