Rizin
unix-like reverse engineering framework and cli tools
cdb_make.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: D. J. Bernstein <djb@cr.yp.to>
2 // SPDX-License-Identifier: CC-PDDC
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "sdb.h"
7 #include "cdb.h"
8 #include "cdb_make.h"
9 #include "sdb_private.h"
10 
11 #if __APPLE__
12 // for MAC_OS_X_VERSION_10_6
13 #include <AvailabilityMacros.h>
14 #endif
15 
16 #define ALIGNMENT sizeof(void *)
17 
18 char *cdb_alloc(ut32 n) {
19 #if __APPLE__ && defined(MAC_OS_X_VERSION_10_6)
20  void *ret = NULL;
21  return posix_memalign(&ret, ALIGNMENT, n) ? NULL : ret;
22 #elif __WINDOWS__ && !__CYGWIN__
23  return _aligned_malloc(n, ALIGNMENT);
24 #else
25  return malloc(n);
26 #endif
27 }
28 
29 void cdb_alloc_free(void *x) {
30 #if __WINDOWS__ && !__CYGWIN__
31  _aligned_free(x);
32 #else
33  free(x);
34 #endif
35 }
36 
37 int cdb_make_start(struct cdb_make *c, int fd) {
38  int i;
39  c->head = 0;
40  c->split = 0;
41  c->hash = 0;
42  c->numentries = 0;
43  c->fd = fd;
44  c->pos = sizeof(c->final);
45  buffer_init(&c->b, (BufferOp)write, fd, c->bspace, sizeof(c->bspace));
46  c->memsize = 1;
47  for (i = 0; i < 256; i++) {
48  c->count[i] = 0;
49  }
50  return seek_set(fd, c->pos);
51 }
52 
53 static inline int incpos(struct cdb_make *c, ut32 len) {
54  ut32 newpos = c->pos + len;
55  if (newpos < len) {
56  return 0;
57  }
58  c->pos = newpos;
59  return 1;
60 }
61 
62 #define R_ANEW(x) (x *)cdb_alloc(sizeof(x))
63 int cdb_make_addend(struct cdb_make *c, ut32 keylen, ut32 datalen, ut32 h) {
64  ut32 u;
65  struct cdb_hplist *head = c->head;
66  if (!head || (head->num >= CDB_HPLIST)) {
67  if (!(head = R_ANEW(struct cdb_hplist))) {
68  return 0;
69  }
70  head->num = 0;
71  head->next = c->head;
72  c->head = head;
73  }
74  head->hp[head->num].h = h;
75  head->hp[head->num].p = c->pos;
76  head->num++;
77  c->numentries++;
78  c->count[255 & h]++;
79  u = c->count[255 & h] * 2;
80  if (u > c->memsize) {
81  c->memsize = u;
82  }
83  return incpos(c, KVLSZ + keylen + datalen);
84 }
85 
86 static int pack_kvlen(ut8 *buf, ut32 klen, ut32 vlen) {
87  if (klen > SDB_CDB_MAX_KEY) {
88  return 0; // 0xff = 254 chars+trailing zero
89  }
90  if (vlen >= SDB_CDB_MAX_VALUE) {
91  return 0;
92  }
93  buf[0] = (ut8)klen;
94  buf[1] = (ut8)((vlen)&0xff);
95  buf[2] = (ut8)((vlen >> 8) & 0xff);
96  buf[3] = (ut8)((vlen >> 16) & 0xff);
97  return 1;
98 }
99 
100 int cdb_make_addbegin(struct cdb_make *c, ut32 keylen, ut32 datalen) {
101  ut8 buf[KVLSZ];
102  if (!pack_kvlen(buf, keylen, datalen)) {
103  return 0;
104  }
105  return buffer_putalign(&c->b, (const char *)buf, KVLSZ);
106 }
107 
108 int cdb_make_add(struct cdb_make *c, const char *key, ut32 keylen, const char *data, ut32 datalen) {
109  /* add tailing \0 to allow mmap to work later */
110  keylen++;
111  datalen++;
112  if (!cdb_make_addbegin(c, keylen, datalen)) {
113  return 0;
114  }
115  if (!buffer_putalign(&c->b, key, keylen)) {
116  return 0;
117  }
118  if (!buffer_putalign(&c->b, data, datalen)) {
119  return 0;
120  }
121  return cdb_make_addend(c, keylen, datalen, sdb_hash(key));
122 }
123 
124 int cdb_make_finish(struct cdb_make *c) {
125  int i;
126  char buf[8];
127  struct cdb_hp *hp;
128  struct cdb_hplist *x, *n;
129  ut32 len, u, memsize, count, where;
130 
131  memsize = c->memsize + c->numentries;
132  if (memsize > (UT32_MAX / sizeof(struct cdb_hp))) {
133  return 0;
134  }
135  c->split = (struct cdb_hp *)cdb_alloc(memsize * sizeof(struct cdb_hp));
136  if (!c->split) {
137  return 0;
138  }
139  c->hash = c->split + c->numentries;
140 
141  for (u = i = 0; i < 256; i++) {
142  u += c->count[i]; /* bounded by numentries, so no overflow */
143  c->start[i] = u;
144  }
145 
146  for (x = c->head; x; x = x->next) {
147  i = x->num;
148  while (i--) {
149  c->split[--c->start[255 & x->hp[i].h]] = x->hp[i];
150  }
151  }
152 
153  for (i = 0; i < 256; i++) {
154  count = c->count[i];
155  len = count << 1;
156  ut32_pack(c->final + 4 * i, c->pos);
157  for (u = 0; u < len; u++) {
158  c->hash[u].h = c->hash[u].p = 0;
159  }
160  hp = c->split + c->start[i];
161  for (u = 0; u < count; u++) {
162  where = (hp->h >> 8) % len;
163  while (c->hash[where].p) {
164  if (++where == len) {
165  where = 0;
166  }
167  }
168  c->hash[where] = *hp++;
169  }
170  for (u = 0; u < len; u++) {
171  ut32_pack(buf, c->hash[u].h);
172  ut32_pack(buf + 4, c->hash[u].p);
173  if (!buffer_putalign(&c->b, buf, 8)) {
174  return 0;
175  }
176  if (!incpos(c, 8)) {
177  return 0;
178  }
179  }
180  }
181 
182  if (!buffer_flush(&c->b)) {
183  return 0;
184  }
185  if (!seek_set(c->fd, 0)) {
186  return 0;
187  }
188  // free childs
189  for (x = c->head; x;) {
190  n = x->next;
191  cdb_alloc_free(x);
192  x = n;
193  }
194  cdb_alloc_free(c->split);
195  return buffer_putflush(&c->b, c->final, sizeof c->final);
196 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
int buffer_putalign(buffer *s, const char *buf, ut32 len)
Definition: buffer.c:36
int buffer_putflush(buffer *s, const char *buf, ut32 len)
Definition: buffer.c:56
int buffer_flush(buffer *s)
Definition: buffer.c:27
void buffer_init(buffer *s, BufferOp op, int fd, char *buf, ut32 len)
Definition: buffer.c:6
int(* BufferOp)(int, const char *, int)
Definition: buffer.h:13
#define KVLSZ
Definition: cdb.h:14
#define R_ANEW(x)
Definition: cdb_make.c:62
int cdb_make_start(struct cdb_make *c, int fd)
Definition: cdb_make.c:37
static int incpos(struct cdb_make *c, ut32 len)
Definition: cdb_make.c:53
void cdb_alloc_free(void *x)
Definition: cdb_make.c:29
int cdb_make_addend(struct cdb_make *c, ut32 keylen, ut32 datalen, ut32 h)
Definition: cdb_make.c:63
#define ALIGNMENT
Definition: cdb_make.c:16
int cdb_make_finish(struct cdb_make *c)
Definition: cdb_make.c:124
int cdb_make_add(struct cdb_make *c, const char *key, ut32 keylen, const char *data, ut32 datalen)
Definition: cdb_make.c:108
int cdb_make_addbegin(struct cdb_make *c, ut32 keylen, ut32 datalen)
Definition: cdb_make.c:100
char * cdb_alloc(ut32 n)
Definition: cdb_make.c:18
static int pack_kvlen(ut8 *buf, ut32 klen, ut32 vlen)
Definition: cdb_make.c:86
#define CDB_HPLIST
Definition: cdb_make.h:14
#define NULL
Definition: cris-opc.c:27
static static fork write
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 count
Definition: sflib.h:98
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
#define ut8
Definition: dcpu16.h:8
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
void * malloc(size_t size)
Definition: malloc.c:123
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
#define UT32_MAX
Definition: rz_types_base.h:99
#define SDB_CDB_MAX_VALUE
Definition: sdb.h:19
RZ_API ut32 sdb_hash(const char *key)
Definition: util.c:22
#define SDB_CDB_MAX_KEY
Definition: sdb.h:21
static void ut32_pack(char s[4], ut32 u)
Definition: sdb_private.h:25
static int seek_set(int fd, off_t pos)
Definition: sdb_private.h:21
#define c(i)
Definition: sha256.c:43
#define h(i)
Definition: sha256.c:48
ut32 h
Definition: cdb_make.h:17
static const z80_opcode fd[]
Definition: z80_tab.h:997