Add procname to lttng_ust_statedump information
[lttng-ust.git] / liblttng-ust / lttng-ust-statedump.c
CommitLineData
cf73e0fe
AB
1/*
2 * Copyright (C) 2013 Paul Woegerer <paul_woegerer@mentor.com>
3 * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
97c7c238 4 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
cf73e0fe
AB
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
cf73e0fe 21#define _GNU_SOURCE
1ddceb36 22#define _LGPL_SOURCE
8e2aed3f 23#include <link.h>
cf73e0fe 24#include <limits.h>
cf73e0fe 25#include <stdio.h>
8e2aed3f
AB
26#include <stdint.h>
27#include <stdlib.h>
97c7c238 28#include <stdbool.h>
8e2aed3f
AB
29#include <sys/types.h>
30#include <unistd.h>
cf73e0fe 31
8e2aed3f 32#include <lttng/ust-elf.h>
97c7c238 33#include <helper.h>
cf73e0fe
AB
34#include "lttng-tracer-core.h"
35#include "lttng-ust-statedump.h"
97c7c238 36#include "jhash.h"
6f626d28 37#include "getenv.h"
94be38e8 38#include "compat.h"
cf73e0fe
AB
39
40#define TRACEPOINT_DEFINE
97c7c238
MD
41#include "ust_lib.h" /* Only define. */
42
cf73e0fe
AB
43#define TRACEPOINT_CREATE_PROBES
44#define TP_SESSION_CHECK
97c7c238 45#include "lttng-ust-statedump-provider.h" /* Define and create probes. */
cf73e0fe
AB
46
47struct dl_iterate_data {
cf73e0fe 48 int exec_found;
97c7c238
MD
49 bool first;
50 bool cancel;
cf73e0fe
AB
51};
52
f60e49df 53struct bin_info_data {
cf73e0fe 54 void *base_addr_ptr;
97c7c238 55 char resolved_path[PATH_MAX];
8e2aed3f
AB
56 char *dbg_file;
57 uint8_t *build_id;
58 uint64_t memsz;
59 size_t build_id_len;
cf73e0fe 60 int vdso;
8e2aed3f 61 uint32_t crc;
f5eb039d 62 uint8_t is_pic;
c5c4fd82
MD
63 uint8_t has_build_id;
64 uint8_t has_debug_link;
cf73e0fe
AB
65};
66
97c7c238
MD
67struct lttng_ust_dl_node {
68 struct bin_info_data bin_data;
69 struct cds_hlist_node node;
70 bool traced;
71 bool marked;
72};
73
74#define UST_DL_STATE_HASH_BITS 8
75#define UST_DL_STATE_TABLE_SIZE (1 << UST_DL_STATE_HASH_BITS)
76struct cds_hlist_head dl_state_table[UST_DL_STATE_TABLE_SIZE];
77
cf73e0fe
AB
78typedef void (*tracepoint_cb)(struct lttng_session *session, void *priv);
79
97c7c238
MD
80static
81struct lttng_ust_dl_node *alloc_dl_node(const struct bin_info_data *bin_data)
82{
83 struct lttng_ust_dl_node *e;
84
85 e = zmalloc(sizeof(struct lttng_ust_dl_node));
86 if (!e)
87 return NULL;
88 if (bin_data->dbg_file) {
89 e->bin_data.dbg_file = strdup(bin_data->dbg_file);
90 if (!e->bin_data.dbg_file)
91 goto error;
92 }
93 if (bin_data->build_id) {
94 e->bin_data.build_id = zmalloc(bin_data->build_id_len);
95 if (!e->bin_data.build_id)
96 goto error;
97 memcpy(e->bin_data.build_id, bin_data->build_id,
98 bin_data->build_id_len);
99 }
100 e->bin_data.base_addr_ptr = bin_data->base_addr_ptr;
101 memcpy(e->bin_data.resolved_path, bin_data->resolved_path, PATH_MAX);
102 e->bin_data.memsz = bin_data->memsz;
103 e->bin_data.build_id_len = bin_data->build_id_len;
104 e->bin_data.vdso = bin_data->vdso;
105 e->bin_data.crc = bin_data->crc;
106 e->bin_data.is_pic = bin_data->is_pic;
107 e->bin_data.has_build_id = bin_data->has_build_id;
108 e->bin_data.has_debug_link = bin_data->has_debug_link;
109 return e;
110
111error:
112 free(e->bin_data.build_id);
113 free(e->bin_data.dbg_file);
114 free(e);
115 return NULL;
116}
117
118static
119void free_dl_node(struct lttng_ust_dl_node *e)
120{
121 free(e->bin_data.build_id);
122 free(e->bin_data.dbg_file);
123 free(e);
124}
125
126/* Return 0 if same, nonzero if not. */
127static
128int compare_bin_data(const struct bin_info_data *a,
129 const struct bin_info_data *b)
130{
131 if (a->base_addr_ptr != b->base_addr_ptr)
132 return -1;
133 if (strcmp(a->resolved_path, b->resolved_path) != 0)
134 return -1;
135 if (a->dbg_file && !b->dbg_file)
136 return -1;
137 if (!a->dbg_file && b->dbg_file)
138 return -1;
139 if (a->dbg_file && strcmp(a->dbg_file, b->dbg_file) != 0)
140 return -1;
141 if (a->build_id && !b->build_id)
142 return -1;
143 if (!a->build_id && b->build_id)
144 return -1;
145 if (a->build_id_len != b->build_id_len)
146 return -1;
147 if (a->build_id &&
148 memcmp(a->build_id, b->build_id, a->build_id_len) != 0)
149 return -1;
150 if (a->memsz != b->memsz)
151 return -1;
152 if (a->vdso != b->vdso)
153 return -1;
154 if (a->crc != b->crc)
155 return -1;
156 if (a->is_pic != b->is_pic)
157 return -1;
158 if (a->has_build_id != b->has_build_id)
159 return -1;
160 if (a->has_debug_link != b->has_debug_link)
161 return -1;
162 return 0;
163}
164
165static
166struct lttng_ust_dl_node *find_or_create_dl_node(struct bin_info_data *bin_data)
167{
168 struct cds_hlist_head *head;
169 struct lttng_ust_dl_node *e;
170 unsigned int hash;
171 bool found = false;
172
173 hash = jhash(&bin_data->base_addr_ptr,
174 sizeof(bin_data->base_addr_ptr), 0);
175 head = &dl_state_table[hash & (UST_DL_STATE_TABLE_SIZE - 1)];
176 cds_hlist_for_each_entry_2(e, head, node) {
177 if (compare_bin_data(&e->bin_data, bin_data) != 0)
178 continue;
179 found = true;
180 break;
181 }
182 if (!found) {
183 /* Create */
184 e = alloc_dl_node(bin_data);
185 if (!e)
186 return NULL;
187 cds_hlist_add_head(&e->node, head);
188 }
189 return e;
190}
191
192static
193void remove_dl_node(struct lttng_ust_dl_node *e)
194{
195 cds_hlist_del(&e->node);
196}
197
cf73e0fe
AB
198/*
199 * Trace statedump event into all sessions owned by the caller thread
200 * for which statedump is pending.
201 */
202static
97c7c238 203void trace_statedump_event(tracepoint_cb tp_cb, void *owner, void *priv)
cf73e0fe
AB
204{
205 struct cds_list_head *sessionsp;
206 struct lttng_session *session;
207
cf73e0fe
AB
208 sessionsp = _lttng_get_sessions();
209 cds_list_for_each_entry(session, sessionsp, node) {
210 if (session->owner != owner)
211 continue;
212 if (!session->statedump_pending)
213 continue;
214 tp_cb(session, priv);
215 }
cf73e0fe
AB
216}
217
218static
f60e49df 219void trace_bin_info_cb(struct lttng_session *session, void *priv)
cf73e0fe 220{
f60e49df 221 struct bin_info_data *bin_data = (struct bin_info_data *) priv;
cf73e0fe 222
f60e49df
AB
223 tracepoint(lttng_ust_statedump, bin_info,
224 session, bin_data->base_addr_ptr,
c5c4fd82
MD
225 bin_data->resolved_path, bin_data->memsz,
226 bin_data->is_pic, bin_data->has_build_id,
227 bin_data->has_debug_link);
8e2aed3f
AB
228}
229
230static
231void trace_build_id_cb(struct lttng_session *session, void *priv)
232{
f60e49df 233 struct bin_info_data *bin_data = (struct bin_info_data *) priv;
8e2aed3f
AB
234
235 tracepoint(lttng_ust_statedump, build_id,
f60e49df
AB
236 session, bin_data->base_addr_ptr,
237 bin_data->build_id, bin_data->build_id_len);
8e2aed3f
AB
238}
239
240static
241void trace_debug_link_cb(struct lttng_session *session, void *priv)
242{
f60e49df 243 struct bin_info_data *bin_data = (struct bin_info_data *) priv;
8e2aed3f
AB
244
245 tracepoint(lttng_ust_statedump, debug_link,
f60e49df
AB
246 session, bin_data->base_addr_ptr,
247 bin_data->dbg_file, bin_data->crc);
cf73e0fe
AB
248}
249
94be38e8
JR
250static
251void procname_cb(struct lttng_session *session, void *priv)
252{
253 char *procname = (char *) priv;
254 tracepoint(lttng_ust_statedump, procname, session, procname);
255}
256
cf73e0fe
AB
257static
258void trace_start_cb(struct lttng_session *session, void *priv)
259{
260 tracepoint(lttng_ust_statedump, start, session);
261}
262
263static
264void trace_end_cb(struct lttng_session *session, void *priv)
265{
266 tracepoint(lttng_ust_statedump, end, session);
267}
268
8e2aed3f 269static
c5c4fd82
MD
270int get_elf_info(struct bin_info_data *bin_data)
271{
8e2aed3f 272 struct lttng_ust_elf *elf;
c5c4fd82 273 int ret = 0, found;
8e2aed3f 274
f60e49df 275 elf = lttng_ust_elf_create(bin_data->resolved_path);
8e2aed3f
AB
276 if (!elf) {
277 ret = -1;
278 goto end;
279 }
280
f60e49df 281 ret = lttng_ust_elf_get_memsz(elf, &bin_data->memsz);
8e2aed3f
AB
282 if (ret) {
283 goto end;
284 }
285
c5c4fd82 286 found = 0;
f60e49df 287 ret = lttng_ust_elf_get_build_id(elf, &bin_data->build_id,
c5c4fd82
MD
288 &bin_data->build_id_len,
289 &found);
8e2aed3f
AB
290 if (ret) {
291 goto end;
292 }
c5c4fd82
MD
293 bin_data->has_build_id = !!found;
294 found = 0;
f60e49df 295 ret = lttng_ust_elf_get_debug_link(elf, &bin_data->dbg_file,
c5c4fd82
MD
296 &bin_data->crc,
297 &found);
8e2aed3f
AB
298 if (ret) {
299 goto end;
300 }
c5c4fd82 301 bin_data->has_debug_link = !!found;
8e2aed3f 302
f60e49df 303 bin_data->is_pic = lttng_ust_elf_is_pic(elf);
f5eb039d 304
8e2aed3f
AB
305end:
306 lttng_ust_elf_destroy(elf);
307 return ret;
308}
309
cf73e0fe 310static
97c7c238
MD
311void trace_baddr(struct bin_info_data *bin_data, void *owner)
312{
313 trace_statedump_event(trace_bin_info_cb, owner, bin_data);
314
315 if (bin_data->has_build_id)
316 trace_statedump_event(trace_build_id_cb, owner, bin_data);
317
318 if (bin_data->has_debug_link)
319 trace_statedump_event(trace_debug_link_cb, owner, bin_data);
320}
321
322static
323int extract_baddr(struct bin_info_data *bin_data)
cf73e0fe 324{
c5c4fd82 325 int ret = 0;
97c7c238 326 struct lttng_ust_dl_node *e;
8e2aed3f 327
f60e49df 328 if (!bin_data->vdso) {
c5c4fd82 329 ret = get_elf_info(bin_data);
8e2aed3f
AB
330 if (ret) {
331 goto end;
332 }
333 } else {
f60e49df 334 bin_data->memsz = 0;
fd783031
MD
335 bin_data->has_build_id = 0;
336 bin_data->has_debug_link = 0;
8e2aed3f
AB
337 }
338
97c7c238
MD
339 e = find_or_create_dl_node(bin_data);
340 if (!e) {
341 ret = -1;
8e2aed3f
AB
342 goto end;
343 }
97c7c238 344 e->marked = true;
8e2aed3f 345end:
97c7c238
MD
346 free(bin_data->build_id);
347 bin_data->build_id = NULL;
348 free(bin_data->dbg_file);
349 bin_data->dbg_file = NULL;
8e2aed3f 350 return ret;
cf73e0fe
AB
351}
352
353static
97c7c238 354void trace_statedump_start(void *owner)
cf73e0fe 355{
97c7c238 356 trace_statedump_event(trace_start_cb, owner, NULL);
cf73e0fe
AB
357}
358
359static
97c7c238 360void trace_statedump_end(void *owner)
cf73e0fe 361{
97c7c238 362 trace_statedump_event(trace_end_cb, owner, NULL);
cf73e0fe
AB
363}
364
365static
97c7c238 366void iter_begin(struct dl_iterate_data *data)
cf73e0fe 367{
97c7c238 368 unsigned int i;
cf73e0fe 369
d34e6761
MD
370 /*
371 * UST lock nests within dynamic loader lock.
372 *
97c7c238 373 * Hold this lock across handling of the module listing to
d34e6761
MD
374 * protect memory allocation at early process start, due to
375 * interactions with libc-wrapper lttng malloc instrumentation.
376 */
377 if (ust_lock()) {
97c7c238
MD
378 data->cancel = true;
379 return;
d34e6761
MD
380 }
381
97c7c238
MD
382 /* Ensure all entries are unmarked. */
383 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
384 struct cds_hlist_head *head;
385 struct lttng_ust_dl_node *e;
386
387 head = &dl_state_table[i];
388 cds_hlist_for_each_entry_2(e, head, node)
389 assert(!e->marked);
390 }
391}
392
393static
394void trace_lib_load(const struct bin_info_data *bin_data, void *ip)
395{
396 tracepoint(lttng_ust_lib, load,
397 ip, bin_data->base_addr_ptr, bin_data->resolved_path,
398 bin_data->memsz, bin_data->has_build_id,
399 bin_data->has_debug_link);
400
401 if (bin_data->has_build_id) {
402 tracepoint(lttng_ust_lib, build_id,
403 ip, bin_data->base_addr_ptr, bin_data->build_id,
404 bin_data->build_id_len);
405 }
406
407 if (bin_data->has_debug_link) {
408 tracepoint(lttng_ust_lib, debug_link,
409 ip, bin_data->base_addr_ptr, bin_data->dbg_file,
410 bin_data->crc);
411 }
412}
413
414static
415void trace_lib_unload(const struct bin_info_data *bin_data, void *ip)
416{
417 tracepoint(lttng_ust_lib, unload, ip, bin_data->base_addr_ptr);
418}
419
420static
421void iter_end(struct dl_iterate_data *data, void *ip)
422{
423 unsigned int i;
424
2eb235ec
MD
425 if (data->cancel)
426 goto end;
97c7c238
MD
427 /*
428 * Iterate on hash table.
429 * For each marked, traced, do nothing.
430 * For each marked, not traced, trace lib open event. traced = true.
431 * For each unmarked, traced, trace lib close event. remove node.
432 * For each unmarked, not traced, remove node.
433 */
434 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
435 struct cds_hlist_head *head;
436 struct lttng_ust_dl_node *e;
437
438 head = &dl_state_table[i];
439 cds_hlist_for_each_entry_2(e, head, node) {
440 if (e->marked) {
441 if (!e->traced) {
442 trace_lib_load(&e->bin_data, ip);
443 e->traced = true;
444 }
b891574e 445 e->marked = false;
97c7c238
MD
446 } else {
447 if (e->traced)
448 trace_lib_unload(&e->bin_data, ip);
449 remove_dl_node(e);
450 free_dl_node(e);
451 }
97c7c238
MD
452 }
453 }
2eb235ec 454end:
97c7c238
MD
455 ust_unlock();
456}
457
458static
459int extract_bin_info_events(struct dl_phdr_info *info, size_t size, void *_data)
460{
461 int j, ret = 0;
462 struct dl_iterate_data *data = _data;
463
464 if (data->first) {
465 iter_begin(data);
466 data->first = false;
467 }
468
469 if (data->cancel)
470 goto end;
471
cf73e0fe 472 for (j = 0; j < info->dlpi_phnum; j++) {
f60e49df 473 struct bin_info_data bin_data;
cf73e0fe
AB
474
475 if (info->dlpi_phdr[j].p_type != PT_LOAD)
476 continue;
477
97c7c238
MD
478 memset(&bin_data, 0, sizeof(bin_data));
479
cf73e0fe 480 /* Calculate virtual memory address of the loadable segment */
97c7c238 481 bin_data.base_addr_ptr = (void *) info->dlpi_addr +
cf73e0fe
AB
482 info->dlpi_phdr[j].p_vaddr;
483
484 if ((info->dlpi_name == NULL || info->dlpi_name[0] == 0)) {
485 /*
486 * Only the first phdr without a dlpi_name
487 * encountered is considered as the program
488 * executable. The rest are vdsos.
489 */
490 if (!data->exec_found) {
491 ssize_t path_len;
492 data->exec_found = 1;
493
494 /*
495 * Use /proc/self/exe to resolve the
496 * executable's full path.
497 */
498 path_len = readlink("/proc/self/exe",
97c7c238 499 bin_data.resolved_path,
cf73e0fe
AB
500 PATH_MAX - 1);
501 if (path_len <= 0)
502 break;
503
97c7c238 504 bin_data.resolved_path[path_len] = '\0';
f60e49df 505 bin_data.vdso = 0;
cf73e0fe 506 } else {
97c7c238
MD
507 snprintf(bin_data.resolved_path,
508 PATH_MAX - 1, "[vdso]");
f60e49df 509 bin_data.vdso = 1;
cf73e0fe
AB
510 }
511 } else {
512 /*
513 * For regular dl_phdr_info entries check if
f60e49df 514 * the path to the binary really exists. If not,
cf73e0fe
AB
515 * treat as vdso and use dlpi_name as 'path'.
516 */
97c7c238
MD
517 if (!realpath(info->dlpi_name,
518 bin_data.resolved_path)) {
519 snprintf(bin_data.resolved_path,
520 PATH_MAX - 1, "[%s]",
cf73e0fe 521 info->dlpi_name);
f60e49df 522 bin_data.vdso = 1;
89be5359 523 } else {
f60e49df 524 bin_data.vdso = 0;
cf73e0fe
AB
525 }
526 }
527
97c7c238 528 ret = extract_baddr(&bin_data);
d34e6761 529 break;
cf73e0fe 530 }
d34e6761 531end:
d34e6761 532 return ret;
cf73e0fe
AB
533}
534
cf73e0fe 535static
97c7c238
MD
536void ust_dl_table_statedump(void *owner)
537{
538 unsigned int i;
539
540 if (ust_lock())
541 goto end;
542
543 /* Statedump each traced table entry into session for owner. */
544 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
545 struct cds_hlist_head *head;
546 struct lttng_ust_dl_node *e;
547
548 head = &dl_state_table[i];
549 cds_hlist_for_each_entry_2(e, head, node) {
550 if (e->traced)
551 trace_baddr(&e->bin_data, owner);
552 }
553 }
554
555end:
556 ust_unlock();
557}
558
559void lttng_ust_dl_update(void *ip)
cf73e0fe
AB
560{
561 struct dl_iterate_data data;
562
6f626d28 563 if (lttng_getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
97c7c238 564 return;
cf73e0fe 565
c362addf
MD
566 /*
567 * Fixup lttng-ust TLS when called from dlopen/dlclose
568 * instrumentation.
569 */
570 lttng_ust_fixup_tls();
571
cf73e0fe 572 data.exec_found = 0;
97c7c238
MD
573 data.first = true;
574 data.cancel = false;
cf73e0fe
AB
575 /*
576 * Iterate through the list of currently loaded shared objects and
97c7c238 577 * generate tables entries for loadable segments using
f60e49df 578 * extract_bin_info_events.
97c7c238
MD
579 * Removed libraries are detected by mark-and-sweep: marking is
580 * done in the iteration over libraries, and sweeping is
581 * performed by iter_end().
cf73e0fe 582 */
f60e49df 583 dl_iterate_phdr(extract_bin_info_events, &data);
97c7c238
MD
584 if (data.first)
585 iter_begin(&data);
586 iter_end(&data, ip);
587}
cf73e0fe 588
97c7c238
MD
589/*
590 * Generate a statedump of base addresses of all shared objects loaded
591 * by the traced application, as well as for the application's
592 * executable itself.
593 */
594static
595int do_baddr_statedump(void *owner)
596{
6f626d28 597 if (lttng_getenv("LTTNG_UST_WITHOUT_BADDR_STATEDUMP"))
97c7c238
MD
598 return 0;
599 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
600 ust_dl_table_statedump(owner);
cf73e0fe
AB
601 return 0;
602}
603
94be38e8
JR
604static
605int do_procname_statedump(void *owner)
606{
607 if (lttng_getenv("LTTNG_UST_WITHOUT_PROCNAME_STATEDUMP"))
608 return 0;
609
610 trace_statedump_event(procname_cb, owner, lttng_ust_sockinfo_get_procname(owner));
611 return 0;
612}
613
cf73e0fe
AB
614/*
615 * Generate a statedump of a given traced application. A statedump is
616 * delimited by start and end events. For a given (process, session)
617 * pair, begin/end events are serialized and will match. However, in a
618 * session, statedumps from different processes may be
619 * interleaved. The vpid context should be used to identify which
620 * events belong to which process.
8002ea62
MD
621 *
622 * Grab the ust_lock outside of the RCU read-side lock because we
623 * perform synchronize_rcu with the ust_lock held, which can trigger
624 * deadlocks otherwise.
cf73e0fe
AB
625 */
626int do_lttng_ust_statedump(void *owner)
627{
8002ea62 628 ust_lock_nocheck();
cf73e0fe 629 trace_statedump_start(owner);
8002ea62
MD
630 ust_unlock();
631
94be38e8 632 do_procname_statedump(owner);
cf73e0fe 633 do_baddr_statedump(owner);
8002ea62
MD
634
635 ust_lock_nocheck();
cf73e0fe 636 trace_statedump_end(owner);
8002ea62 637 ust_unlock();
cf73e0fe
AB
638
639 return 0;
640}
641
642void lttng_ust_statedump_init(void)
643{
644 __tracepoints__init();
645 __tracepoints__ptrs_init();
646 __lttng_events_init__lttng_ust_statedump();
97c7c238
MD
647 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
648}
649
650static
651void ust_dl_state_destroy(void)
652{
653 unsigned int i;
654
655 for (i = 0; i < UST_DL_STATE_TABLE_SIZE; i++) {
656 struct cds_hlist_head *head;
657 struct lttng_ust_dl_node *e, *tmp;
658
659 head = &dl_state_table[i];
660 cds_hlist_for_each_entry_safe_2(e, tmp, head, node)
661 free_dl_node(e);
662 CDS_INIT_HLIST_HEAD(head);
663 }
cf73e0fe
AB
664}
665
666void lttng_ust_statedump_destroy(void)
667{
668 __lttng_events_exit__lttng_ust_statedump();
669 __tracepoints__ptrs_destroy();
670 __tracepoints__destroy();
97c7c238 671 ust_dl_state_destroy();
cf73e0fe 672}
This page took 0.053873 seconds and 4 git commands to generate.