Rizin
unix-like reverse engineering framework and cli tools
cdb.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: D. J. Bernstein
2 // SPDX-FileCopyrightText: 2014-2016 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: CC-PDDC
4 
5 #include <stdio.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include "cdb.h"
9 #if HAVE_HEADER_SYS_MMAN_H
10 #include <sys/mman.h>
11 #endif
12 #include "sdb_private.h"
13 
14 /* XXX: this code must be rewritten . too slow */
15 bool cdb_getkvlen(struct cdb *c, ut32 *klen, ut32 *vlen, ut32 pos) {
16  ut8 buf[4] = { 0 };
17  *klen = *vlen = 0;
18  if (!cdb_read(c, (char *)buf, sizeof(buf), pos)) {
19  return false;
20  }
21  *klen = (ut32)buf[0];
22  *vlen = (ut32)(buf[1] | ((ut32)buf[2] << 8) | ((ut32)buf[3] << 16));
23  if (*vlen > CDB_MAX_VALUE) {
24  *vlen = CDB_MAX_VALUE; // untaint value for coverity
25  return false;
26  }
27  return true;
28 }
29 
30 void cdb_free(struct cdb *c) {
31  if (!c->map) {
32  return;
33  }
34 #if HAVE_HEADER_SYS_MMAN_H
35  (void)munmap(c->map, c->size);
36 #else
37  free(c->map);
38 #endif
39  c->map = NULL;
40 }
41 
42 void cdb_findstart(struct cdb *c) {
43  c->loop = 0;
44 #if !HAVE_HEADER_SYS_MMAN_H
45  if (c->fd != -1) {
46  lseek(c->fd, 0, SEEK_SET);
47  }
48 #endif
49 }
50 
51 bool cdb_init(struct cdb *c, int fd) {
52  struct stat st;
53  if (fd != c->fd && c->fd != -1) {
54  close(c->fd);
55  }
56  c->fd = fd;
58  if (fd != -1 && !fstat(fd, &st) && st.st_size > 4 && st.st_size != (off_t)UT64_MAX) {
59 #if HAVE_HEADER_SYS_MMAN_H
60  char *x = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
61  if (x == MAP_FAILED) {
62  eprintf("Cannot mmap %d\n", (int)st.st_size);
63  return false;
64  }
65  if (c->map) {
66  munmap(c->map, c->size);
67  }
68 #else
69  char *x = calloc(1, st.st_size);
70  if (!x) {
71  eprintf("Cannot malloc %d\n", (int)st.st_size);
72  return false;
73  }
74  /* TODO: read by chunks instead of a big huge syscall */
75  if (read(fd, x, st.st_size) != st.st_size) {
76  /* handle read error */
77  }
78  free(c->map);
79 #endif
80  c->map = x;
81  c->size = st.st_size;
82  return true;
83  }
84  c->map = NULL;
85  c->size = 0;
86  return false;
87 }
88 
89 bool cdb_read(struct cdb *c, char *buf, ut32 len, ut32 pos) {
90  if (c->map) {
91  if ((pos > c->size) || (c->size - pos < len)) {
92  return false;
93  }
94  if (!buf) {
95  return false;
96  }
97  memcpy(buf, c->map + pos, len);
98  return true;
99  }
100  if (c->fd == -1 || !seek_set(c->fd, pos)) {
101  return false;
102  }
103  while (len > 0) {
104  int r = (int)read(c->fd, buf, len);
105  if (r < 1 || (ut32)r != len) {
106  return false;
107  }
108  buf += r;
109  len -= r;
110  }
111  return true;
112 }
113 
114 static int match(struct cdb *c, const char *key, ut32 len, ut32 pos) {
115  char buf[32];
116  const size_t szb = sizeof buf;
117  while (len > 0) {
118  int n = (szb > len) ? len : szb;
119  if (!cdb_read(c, buf, n, pos)) {
120  return -1;
121  }
122  if (memcmp(buf, key, n)) {
123  return 0;
124  }
125  pos += n;
126  key += n;
127  len -= n;
128  }
129  return 1;
130 }
131 
132 int cdb_findnext(struct cdb *c, ut32 u, const char *key, ut32 len) {
133  char buf[8];
134  ut32 pos;
135  int m;
136  len++;
137  if (c->fd == -1) {
138  return -1;
139  }
140  c->hslots = 0;
141  if (!c->loop) {
142  const int bufsz = ((u + 1) & 0xFF) ? sizeof(buf) : sizeof(buf) / 2;
143  if (!cdb_read(c, buf, bufsz, (u << 2) & 1023)) {
144  return -1;
145  }
146  /* hslots = (hpos_next - hpos) / 8 */
147  ut32_unpack(buf, &c->hpos);
148  if (bufsz == sizeof(buf)) {
149  ut32_unpack(buf + 4, &pos);
150  } else {
151  pos = c->size;
152  }
153  if (pos < c->hpos) {
154  return -1;
155  }
156  c->hslots = (pos - c->hpos) / (2 * sizeof(ut32));
157  if (!c->hslots) {
158  return 0;
159  }
160  c->khash = u;
161  u = ((u >> 8) % c->hslots) << 3;
162  c->kpos = c->hpos + u;
163  }
164  while (c->loop < c->hslots) {
165  if (!cdb_read(c, buf, sizeof(buf), c->kpos)) {
166  return 0;
167  }
168  ut32_unpack(buf + 4, &pos);
169  if (!pos) {
170  return 0;
171  }
172  c->loop++;
173  c->kpos += sizeof(buf);
174  if (c->kpos == c->hpos + (c->hslots << 3)) {
175  c->kpos = c->hpos;
176  }
177  ut32_unpack(buf, &u);
178  if (u == c->khash) {
179  if (!cdb_getkvlen(c, &u, &c->dlen, pos) || !u) {
180  return -1;
181  }
182  if (u == len) {
183  if ((m = match(c, key, len, pos + KVLSZ)) == -1) {
184  return 0;
185  }
186  if (m == 1) {
187  c->dpos = pos + KVLSZ + len;
188  return 1;
189  }
190  }
191  }
192  }
193  return 0;
194 }
size_t len
Definition: 6502dis.c:15
bool cdb_init(struct cdb *c, int fd)
Definition: cdb.c:51
bool cdb_getkvlen(struct cdb *c, ut32 *klen, ut32 *vlen, ut32 pos)
Definition: cdb.c:15
void cdb_free(struct cdb *c)
Definition: cdb.c:30
static int match(struct cdb *c, const char *key, ut32 len, ut32 pos)
Definition: cdb.c:114
bool cdb_read(struct cdb *c, char *buf, ut32 len, ut32 pos)
Definition: cdb.c:89
void cdb_findstart(struct cdb *c)
Definition: cdb.c:42
int cdb_findnext(struct cdb *c, ut32 u, const char *key, ut32 len)
Definition: cdb.c:132
#define CDB_MAX_VALUE
Definition: cdb.h:16
#define KVLSZ
Definition: cdb.h:14
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset fstat
Definition: sflib.h:107
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep lseek
Definition: sflib.h:113
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags mmap
Definition: sflib.h:115
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset munmap
Definition: sflib.h:43
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
#define eprintf(x, y...)
Definition: rlcc.c:7
#define UT64_MAX
Definition: rz_types_base.h:86
static int seek_set(int fd, off_t pos)
Definition: sdb_private.h:21
static void ut32_unpack(char s[4], ut32 *u)
Definition: sdb_private.h:43
static int
Definition: sfsocketcall.h:114
#define PROT_READ
Definition: sftypes.h:95
#define MAP_SHARED
Definition: sftypes.h:101
int off_t
Definition: sftypes.h:41
#define c(i)
Definition: sha256.c:43
Definition: cdb.h:20
Definition: sftypes.h:80
int pos
Definition: main.c:11
static const z80_opcode fd[]
Definition: z80_tab.h:997
#define SEEK_SET
Definition: zip.c:88
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115