static bool entryeq(TERMTYPE *t1, TERMTYPE *t2) /* are two terminal types equal */ { int i; for (i = 0; i < BOOLCOUNT; i++) if (t1->Booleans[i] != t2->Booleans[i]) return(FALSE); for (i = 0; i < NUMCOUNT; i++) if (t1->Numbers[i] != t2->Numbers[i]) return(FALSE); for (i = 0; i < STRCOUNT; i++) if (capcmp(t1->Strings[i], t2->Strings[i])) return(FALSE); return(TRUE); }
static bool entryeq(TERMTYPE *t1, TERMTYPE *t2) /* are two entries equivalent? */ { unsigned i; for (i = 0; i < NUM_BOOLEANS(t1); i++) if (t1->Booleans[i] != t2->Booleans[i]) return (FALSE); for (i = 0; i < NUM_NUMBERS(t1); i++) if (t1->Numbers[i] != t2->Numbers[i]) return (FALSE); for (i = 0; i < NUM_STRINGS(t1); i++) if (capcmp((PredIdx) i, t1->Strings[i], t2->Strings[i])) return (FALSE); return (TRUE); }
static void compare_predicate(int type, int idx, const char *name) /* predicate function to use for entry difference reports */ { register TERMTYPE *t1 = &term[0]; register TERMTYPE *t2 = &term[1]; char *s1, *s2; switch(type) { case BOOLEAN: switch(compare) { case C_DIFFERENCE: if (t1->Booleans[idx] != t2->Booleans[idx]) (void) printf("\t%s: %c:%c.\n", name, t1->Booleans[idx] ? 'T' : 'F', t2->Booleans[idx] ? 'T' : 'F'); break; case C_COMMON: if (t1->Booleans[idx] && t2->Booleans[idx]) (void) printf("\t%s= T.\n", name); break; case C_NAND: if (!t1->Booleans[idx] && !t2->Booleans[idx]) (void) printf("\t!%s.\n", name); break; } break; case NUMBER: switch(compare) { case C_DIFFERENCE: if (t1->Numbers[idx] != t2->Numbers[idx]) (void) printf("\t%s: %d:%d.\n", name, t1->Numbers[idx], t2->Numbers[idx]); break; case C_COMMON: if (t1->Numbers[idx]!=-1 && t2->Numbers[idx]!=-1 && t1->Numbers[idx] == t2->Numbers[idx]) (void) printf("\t%s= %d.\n", name, t1->Numbers[idx]); break; case C_NAND: if (t1->Numbers[idx]==-1 && t2->Numbers[idx] == -1) (void) printf("\t!%s.\n", name); break; } break; case STRING: s1 = t1->Strings[idx]; s2 = t2->Strings[idx]; switch(compare) { case C_DIFFERENCE: if (capcmp(s1, s2)) { char buf1[BUFSIZ], buf2[BUFSIZ]; if (s1 == (char *)NULL) (void) strcpy(buf1, "NULL"); else { (void) strcpy(buf1, "'"); (void) strcat(buf1, _nc_tic_expand(s1, outform==F_TERMINFO)); (void) strcat(buf1, "'"); } if (s2 == (char *)NULL) (void) strcpy(buf2, "NULL"); else { (void) strcpy(buf2, "'"); (void) strcat(buf2, _nc_tic_expand(s2, outform==F_TERMINFO)); (void) strcat(buf2, "'"); } (void) printf("\t%s: %s, %s.\n", name, buf1, buf2); } break; case C_COMMON: if (s1 && s2 && !capcmp(s1, s2)) (void) printf("\t%s= '%s'.\n", name, _nc_tic_expand(s1, outform==F_TERMINFO)); break; case C_NAND: if (!s1 && !s2) (void) printf("\t!%s.\n", name); break; } break; } }
static int use_predicate(int type, int idx) /* predicate function to use for use decompilation */ { TERMTYPE *tp; switch(type) { case BOOLEAN: { int is_set = FALSE; /* * This assumes that multiple use entries are supposed * to contribute the logical or of their boolean capabilities. * This is true if we take the semantics of multiple uses to * be 'each capability gets the first non-default value found * in the sequence of use entries'. */ for (tp = &term[1]; tp < term + termcount; tp++) if (tp->Booleans[idx]) { is_set = TRUE; break; } if (is_set != term->Booleans[idx]) return(!is_set); else return(FAIL); } case NUMBER: { int value = ABSENT_NUMERIC; /* * We take the semantics of multiple uses to be 'each * capability gets the first non-default value found * in the sequence of use entries'. */ for (tp = &term[1]; tp < term + termcount; tp++) if (tp->Numbers[idx] >= 0) { value = tp->Numbers[idx]; break; } if (value != term->Numbers[idx]) return(value != ABSENT_NUMERIC); else return(FAIL); } case STRING: { char *termstr, *usestr = ABSENT_STRING; termstr = term->Strings[idx]; /* * We take the semantics of multiple uses to be 'each * capability gets the first non-default value found * in the sequence of use entries'. */ for (tp = &term[1]; tp < term + termcount; tp++) if (tp->Strings[idx]) { usestr = tp->Strings[idx]; break; } if (usestr == ABSENT_STRING && termstr == ABSENT_STRING) return(FAIL); else if (!usestr || !termstr || capcmp(usestr, termstr)) return(TRUE); else return(FAIL); } } return(FALSE); /* pacify compiler */ }
static int use_predicate(unsigned type, PredIdx idx) /* predicate function to use for use decompilation */ { ENTRY *ep; switch (type) { case BOOLEAN: { int is_set = FALSE; /* * This assumes that multiple use entries are supposed * to contribute the logical or of their boolean capabilities. * This is true if we take the semantics of multiple uses to * be 'each capability gets the first non-default value found * in the sequence of use entries'. * * Note that cancelled or absent booleans are stored as FALSE, * unlike numbers and strings, whose cancelled/absent state is * recorded in the terminfo database. */ for (ep = &entries[1]; ep < entries + termcount; ep++) if (ep->tterm.Booleans[idx] == TRUE) { is_set = entries[0].tterm.Booleans[idx]; break; } if (is_set != entries[0].tterm.Booleans[idx]) return (!is_set); else return (FAIL); } case NUMBER: { int value = ABSENT_NUMERIC; /* * We take the semantics of multiple uses to be 'each * capability gets the first non-default value found * in the sequence of use entries'. */ for (ep = &entries[1]; ep < entries + termcount; ep++) if (VALID_NUMERIC(ep->tterm.Numbers[idx])) { value = ep->tterm.Numbers[idx]; break; } if (value != entries[0].tterm.Numbers[idx]) return (value != ABSENT_NUMERIC); else return (FAIL); } case STRING: { char *termstr, *usestr = ABSENT_STRING; termstr = entries[0].tterm.Strings[idx]; /* * We take the semantics of multiple uses to be 'each * capability gets the first non-default value found * in the sequence of use entries'. */ for (ep = &entries[1]; ep < entries + termcount; ep++) if (ep->tterm.Strings[idx]) { usestr = ep->tterm.Strings[idx]; break; } if (usestr == ABSENT_STRING && termstr == ABSENT_STRING) return (FAIL); else if (!usestr || !termstr || capcmp(idx, usestr, termstr)) return (TRUE); else return (FAIL); } } return (FALSE); /* pacify compiler */ }
void remove_empty_vnodes(struct pmap_x86 *pmap, struct vnode *root, uint32_t entry, size_t len) { errval_t err; uint32_t end_entry = entry + len; for (struct vnode *n = root->u.vnode.children; n; n = n->next) { if (n->entry >= entry && n->entry < end_entry) { // sanity check and skip leaf entries if (!n->is_vnode) { continue; } // here we know that all vnodes we're interested in are // page tables assert(n->is_vnode); if (n->u.vnode.children) { remove_empty_vnodes(pmap, n, 0, PTABLE_SIZE); } // unmap err = vnode_unmap(root->u.vnode.cap, n->mapping); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: vnode_unmap: %s\n", err_getstring(err)); } // delete mapping cap first: underlying cap needs to exist for // this to work properly! err = cap_delete(n->mapping); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: cap_delete (mapping): %s\n", err_getstring(err)); } err = pmap->p.slot_alloc->free(pmap->p.slot_alloc, n->mapping); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: slot_free (mapping): %s\n", err_getstring(err)); } // delete capability err = cap_delete(n->u.vnode.cap); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: cap_delete (vnode): %s\n", err_getstring(err)); } if (!capcmp(n->u.vnode.cap, n->u.vnode.invokable)) { // invokable is always allocated in our cspace err = cap_destroy(n->u.vnode.invokable); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: cap_delete (vnode.invokable): %s\n", err_getstring(err)); } } err = pmap->p.slot_alloc->free(pmap->p.slot_alloc, n->u.vnode.cap); if (err_is_fail(err)) { debug_printf("remove_empty_vnodes: slot_free (vnode): %s\n", err_getstring(err)); } // remove vnode from list remove_vnode(root, n); slab_free(&pmap->slab, n); } } }
static void compare_predicate(int type, int idx, const char *name) /* predicate function to use for entry difference reports */ { register ENTRY *e1 = &entries[0]; register ENTRY *e2 = &entries[1]; char buf1[MAX_STRING], buf2[MAX_STRING]; int b1, b2; int n1, n2; char *s1, *s2; switch (type) { case CMP_BOOLEAN: b1 = e1->tterm.Booleans[idx]; b2 = e2->tterm.Booleans[idx]; switch (compare) { case C_DIFFERENCE: if (!(b1 == ABSENT_BOOLEAN && b2 == ABSENT_BOOLEAN) && b1 != b2) (void) printf("\t%s: %s%s%s.\n", name, dump_boolean(b1), bool_sep, dump_boolean(b2)); break; case C_COMMON: if (b1 == b2 && b1 != ABSENT_BOOLEAN) (void) printf("\t%s= %s.\n", name, dump_boolean(b1)); break; case C_NAND: if (b1 == ABSENT_BOOLEAN && b2 == ABSENT_BOOLEAN) (void) printf("\t!%s.\n", name); break; } break; case CMP_NUMBER: n1 = e1->tterm.Numbers[idx]; n2 = e2->tterm.Numbers[idx]; dump_numeric(n1, buf1); dump_numeric(n2, buf2); switch (compare) { case C_DIFFERENCE: if (!((n1 == ABSENT_NUMERIC && n2 == ABSENT_NUMERIC)) && n1 != n2) (void) printf("\t%s: %s, %s.\n", name, buf1, buf2); break; case C_COMMON: if (n1 != ABSENT_NUMERIC && n2 != ABSENT_NUMERIC && n1 == n2) (void) printf("\t%s= %s.\n", name, buf1); break; case C_NAND: if (n1 == ABSENT_NUMERIC && n2 == ABSENT_NUMERIC) (void) printf("\t!%s.\n", name); break; } break; case CMP_STRING: s1 = e1->tterm.Strings[idx]; s2 = e2->tterm.Strings[idx]; switch (compare) { case C_DIFFERENCE: if (capcmp(idx, s1, s2)) { dump_string(s1, buf1); dump_string(s2, buf2); if (strcmp(buf1, buf2)) (void) printf("\t%s: %s, %s.\n", name, buf1, buf2); } break; case C_COMMON: if (s1 && s2 && !capcmp(idx, s1, s2)) (void) printf("\t%s= '%s'.\n", name, TIC_EXPAND(s1)); break; case C_NAND: if (!s1 && !s2) (void) printf("\t!%s.\n", name); break; } break; case CMP_USE: /* unlike the other modes, this compares *all* use entries */ switch (compare) { case C_DIFFERENCE: if (!useeq(e1, e2)) { (void) fputs("\tuse: ", stdout); print_uses(e1, stdout); fputs(", ", stdout); print_uses(e2, stdout); fputs(".\n", stdout); } break; case C_COMMON: if (e1->nuses && e2->nuses && useeq(e1, e2)) { (void) fputs("\tuse: ", stdout); print_uses(e1, stdout); fputs(".\n", stdout); } break; case C_NAND: if (!e1->nuses && !e2->nuses) (void) printf("\t!use.\n"); break; } } }