Module Name: othersrc Committed By: dholland Date: Thu Dec 7 05:55:36 UTC 2017
Added Files: othersrc/external/bsd/testcompat: Makefile README othersrc/external/bsd/testcompat/gen: Makefile main.ml othersrc/external/bsd/testcompat/mk: base.mk ocaml.mk subdir.mk othersrc/external/bsd/testcompat/parser: Makefile lexer.mll parser.mly ptcheck.ml ptree.ml othersrc/external/bsd/testcompat/specs: cases.def mips.mach syscalls.def ultrix.kern othersrc/external/bsd/testcompat/support: Makefile pos.ml types.ml util.ml Log Message: Add some preliminary stuff in pursuit of testing compat syscalls. So far this just has some (partial) specs and some code for reading the specs in; it doesn't actually do anything yet... It is ocaml because ocaml is the least awful choice for prototyping compiler stuff. To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/testcompat/Makefile \ othersrc/external/bsd/testcompat/README cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/testcompat/gen/Makefile \ othersrc/external/bsd/testcompat/gen/main.ml cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/testcompat/mk/base.mk \ othersrc/external/bsd/testcompat/mk/ocaml.mk \ othersrc/external/bsd/testcompat/mk/subdir.mk cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/testcompat/parser/Makefile \ othersrc/external/bsd/testcompat/parser/lexer.mll \ othersrc/external/bsd/testcompat/parser/parser.mly \ othersrc/external/bsd/testcompat/parser/ptcheck.ml \ othersrc/external/bsd/testcompat/parser/ptree.ml cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/testcompat/specs/cases.def \ othersrc/external/bsd/testcompat/specs/mips.mach \ othersrc/external/bsd/testcompat/specs/syscalls.def \ othersrc/external/bsd/testcompat/specs/ultrix.kern cvs rdiff -u -r0 -r1.1 othersrc/external/bsd/testcompat/support/Makefile \ othersrc/external/bsd/testcompat/support/pos.ml \ othersrc/external/bsd/testcompat/support/types.ml \ othersrc/external/bsd/testcompat/support/util.ml Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: othersrc/external/bsd/testcompat/Makefile diff -u /dev/null othersrc/external/bsd/testcompat/Makefile:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/Makefile Thu Dec 7 05:55:35 2017 @@ -0,0 +1,6 @@ +TOP=. +include $(TOP)/mk/base.mk + +SUBDIRS=support parser gen + +include $(TOP)/mk/subdir.mk Index: othersrc/external/bsd/testcompat/README diff -u /dev/null othersrc/external/bsd/testcompat/README:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/README Thu Dec 7 05:55:35 2017 @@ -0,0 +1,25 @@ +Compat syscall testing framework. + +The general idea here is that we declare the following things: + - abstract syscalls + - kernel ABIs + - machines + - syscall ABIs (for the call sequence itself) + +and then for each syscall specify a set of test cases based on known +issues (in the syscall spec itself, in the ABIs, etc.) and then for +each combination generate an assembly-language sequence that exercises +the test case. + +These can then be assembled into static binaries that can be run +against an actual kernel (can't use rump for this, it needs to be +making actual syscalls at the machine level) without needing includes +or libraries for the compat environment. + +(This is desirable because old or foreign includes and libraries are +problematic; they can be hard to get, hard to build against, are +sometimes nonredistributable, etc.) + +The program that builds the tests is called, in a fit of originality, +"testcompatgen". It's written in OCaml because that's the least awful +of a variety of dismal choices for rapid compiler prototyping. Index: othersrc/external/bsd/testcompat/gen/Makefile diff -u /dev/null othersrc/external/bsd/testcompat/gen/Makefile:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/gen/Makefile Thu Dec 7 05:55:35 2017 @@ -0,0 +1,28 @@ +TOP=.. +include $(TOP)/mk/base.mk + +PROG=testcompatgen +SRCS=\ + main.ml + +SUPPORTDIR=../support +PARSERDIR=../parser + +# +# Note: unlike with normal Unix C libs, which work the other way +# around, OCAMLLIBS must be ordered with lower-level stuff first; +# otherwise the higher-level stuff won't link to it. +# + +#OCAMLLIBS+=unix.$(OCAMLLIBEXT) nums.$(OCAMLLIBEXT) +OCAMLLIBS+=nums.$(OCAMLLIBEXT) + +OCAMLINCS+=-I $(SUPPORTDIR) +OCAMLLIBS+=$(SUPPORTDIR)/libsupport.$(OCAMLLIBEXT) +OCAMLLIBDEPS+=$(SUPPORTDIR)/libsupport.$(OCAMLLIBEXT) + +OCAMLINCS+=-I $(PARSERDIR) +OCAMLLIBS+=$(PARSERDIR)/libparser.$(OCAMLLIBEXT) +OCAMLLIBDEPS+=$(PARSERDIR)/libparser.$(OCAMLLIBEXT) + +include $(TOP)/mk/ocaml.mk Index: othersrc/external/bsd/testcompat/gen/main.ml diff -u /dev/null othersrc/external/bsd/testcompat/gen/main.ml:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/gen/main.ml Thu Dec 7 05:55:35 2017 @@ -0,0 +1,39 @@ +(*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *) + +(* + * This is, for now, entirely a placeholder... + *) + +let _ = + let _ = Lexer.read "specs/syscalls.def" in + let _ = Lexer.read "specs/ultrix.kern" in + let _ = Lexer.read "specs/mips.mach" in + let _ = Lexer.read "specs/cases.def" in + () Index: othersrc/external/bsd/testcompat/mk/base.mk diff -u /dev/null othersrc/external/bsd/testcompat/mk/base.mk:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/mk/base.mk Thu Dec 7 05:55:36 2017 @@ -0,0 +1,69 @@ + +# Defaults for things that defs.mk sets + +# We don't worry about choosing a target here (you can build any or all) +# We also don't install anything (except in the outer source tree) so we +# don't need installation paths. + +# +# C +# +# Default C compiler. +# +CC=cc +CFLAGS=$(OPT) +OPT=-O +AR=ar +RANLIB=ranlib +LDFLAGS= +LIBS= + +# +# OCaml +# +# OCaml comes two ways: there's a native compiler that supports only +# some platforms, and a byte-compiler for the rest. This affects the +# output filenames. defs.mk should set OCAMLTYPE to either "byte" or +# "native" to choose one or the other. +# + +OCAML.byte=ocamlc +OCAMLOEXT.byte=cmo +OCAMLLIBEXT.byte=cma +OCAMLDEPNATIVE.byte= +OCAMLOPT.byte= # -g to debug, -p to profile +OCAMLPIC.byte= + +OCAML.native=ocamlopt +OCAMLOEXT.native=cmx +OCAMLLIBEXT.native=cmxa +OCAMLDEPNATIVE.native=-native +OCAMLOPT.native=-O2 # -g to debug, -p to profile +OCAMLPIC.native=-nodynlink -fno-PIC + +OCAML=$(OCAML.$(OCAMLTYPE)) +OCAMLOEXT=$(OCAMLOEXT.$(OCAMLTYPE)) +OCAMLLIBEXT=$(OCAMLLIBEXT.$(OCAMLTYPE)) +OCAMLDEPNATIVE=$(OCAMLDEPNATIVE.$(OCAMLTYPE)) +OCAMLOPT=$(OCAMLOPT.$(OCAMLTYPE)) +OCAMLPIC=$(OCAMLPIC.$(OCAMLTYPE)) + +OCAMLWARNS=-w +27+29+32+39+41+44+45 -warn-error +a \ + -safe-string -strict-formats +# -short-paths + +# these are the same either way +OCAMLIEXT=cmi +OCAMLDEP=ocamldep +OCAMLYACC=ocamlyacc +OCAMLLEX=ocamllex + +# default to native since most people's fast build machines are x86 +OCAMLTYPE=native +#OCAMLTYPE=byte + + +############################################################ + +-include $(GENTOP)/defs.mk + Index: othersrc/external/bsd/testcompat/mk/ocaml.mk diff -u /dev/null othersrc/external/bsd/testcompat/mk/ocaml.mk:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/mk/ocaml.mk Thu Dec 7 05:55:36 2017 @@ -0,0 +1,93 @@ +# +# This does either a program or a library depending on whether +# you set PROG or LIB. +# +# Add -I flags to OCAMLINCS. +# +# Note that OCAMLOPT is the debug/optimize setting, not a variable +# pointing to the ocamlopt program. +# + +OCAMLFLAGS?=$(OCAMLOPT) $(OCAMLWARNS) $(OCAMLINCS) $(OCAMLPIC) + +OCAMLLDFLAGS?=$(OCAMLINCS) +OCAMLLIBS?= +OCAMLLIBDEPS?= + +.if defined(LIB) +PRODUCT=lib$(LIB).$(OCAMLLIBEXT) +.elif defined(PROG) +PRODUCT=$(PROG) +.else +.error "Define either LIB or PROG" +.endif + +all: $(PRODUCT) + +.SUFFIXES: .ml .mli .mll .mly + +genfiles: ; + +# Don't use empty() because on older bsd make versions it doesn't +# work right with loop variables. +.for S in $(SRCS) +.if $(S:M*.mli) != "" +OBJS+=$(S:T:R).$(OCAMLIEXT) +.elif $(S:M*.ml) != "" || $(S:M*.mll) != "" || $(S:M*.mly) != "" +OBJS+=$(S:T:R).$(OCAMLOEXT) +.endif +.endfor + +$(PRODUCT): $(OBJS) $(OCAMLLIBDEPS) +.if defined(LIB) + $(OCAML) -a $(OCAMLLDFLAGS) $(OCAMLLIBS) $(OBJS:N*.$(OCAMLIEXT)) -o $@ +.else + $(OCAML) $(OCAMLLDFLAGS) $(OCAMLLIBS) $(OBJS:N*.$(OCAMLIEXT)) -o $@ +.endif + +.for S in $(SRCS:M*.mli) +$(S:T:R).$(OCAMLIEXT): $(S) + $(OCAML) $(OCAMLFLAGS) -c $(S) +.endfor + +.for S in $(SRCS:M*.ml) +$(S:T:R).$(OCAMLOEXT): $(S) + $(OCAML) $(OCAMLFLAGS) -c $(S) +.endfor + +.for S in $(SRCS:M*.mll) +$(S:T:R).ml: $(S) + $(OCAMLLEX) $(S) +$(S:T:R).$(OCAMLOEXT): $(S:T:R).ml + $(OCAML) $(OCAMLFLAGS) -c $(S:.mll=.ml) +genfiles: $(S:T:R).ml +.endfor + +.for S in $(SRCS:M*.mly) +$(S:T:R).mli $(S:T:R).ml: $(S) + $(OCAMLYACC) $(S) +$(S:T:R).$(OCAMLIEXT): $(S:T:R).mli + $(OCAML) $(OCAMLFLAGS) -c $(S:.mly=.mli) +$(S:T:R).$(OCAMLOEXT): $(S:T:R).ml $(S:T:R).$(OCAMLIEXT) + $(OCAML) $(OCAMLFLAGS) -c $(S:.mly=.ml) +genfiles: $(S:T:R).mli $(S:T:R).ml +.endfor + +depend: + $(MAKE) genfiles + $(OCAMLDEP) $(OCAMLDEPNATIVE) $(OCAMLINCS) $(SRCS:N*.mll:N*.mly) \ + $(SRCS:M*.mll:.mll=.ml) \ + $(SRCS:M*.mly:.mly=.mli) $(SRCS:M*.mly:.mly=.ml) \ + > .depend +-include .depend + +clean distclean: + rm -f *.$(OCAMLIEXT) *.$(OCAMLOEXT) *.cmo *.[oa] $(PRODUCT) +.for S in $(SRCS:M*.mll) + rm -f $(S:.mll=.ml) +.endfor +.for S in $(SRCS:M*.mly) + rm -f $(S:.mly=.mli) $(S:.mly=.ml) +.endfor + +.PHONY: all depend clean distclean Index: othersrc/external/bsd/testcompat/mk/subdir.mk diff -u /dev/null othersrc/external/bsd/testcompat/mk/subdir.mk:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/mk/subdir.mk Thu Dec 7 05:55:36 2017 @@ -0,0 +1,36 @@ +# +# This is a bit messy but it parallelizes... +# + +.if defined(TESTTARGETS) +TARGETS?=all run-tests show-diffs good +.else +TARGETS?=all depend install clean distclean +.endif + +.for T in $(TARGETS) +$(T): before-$(T) .WAIT $(T)-sub .WAIT after-$(T) + +before-$(T) after-$(T): ; + +.for D in $(SUBDIRS) + +.if $(D) == ".WAIT" +$(T)-sub: .WAIT +.else +$(T)-sub: $(T)-in-$(D) +$(T)-in-$(D): + (cd $(D) && $(MAKE) $(T)) || exit 1 +.PHONY: $(T)-in-$(D) +.endif # .WAIT + +.if $(T) == "show-diffs" +# force test diffs to be printed sequentially so they don't get +# interspersed in the output (which helps nothing) +$(T)-sub: .WAIT +.endif # show-diffs + +.endfor # SUBDIRS + +.PHONY: $(T) before-$(T) after-$(T) $(T)-sub +.endfor # TARGETS Index: othersrc/external/bsd/testcompat/parser/Makefile diff -u /dev/null othersrc/external/bsd/testcompat/parser/Makefile:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/parser/Makefile Thu Dec 7 05:55:36 2017 @@ -0,0 +1,13 @@ +TOP=.. +include $(TOP)/mk/base.mk + +LIB=parser +SRCS=\ + ptree.ml ptcheck.ml parser.mly lexer.mll + +SUPPORTDIR=../support +OCAMLINCS+=-I $(SUPPORTDIR) +#OCAMLLIBS+=$(SUPPORTDIR)/libsupport.$(OCAMLLIBEXT) +#OCAMLLIBDEPS+=$(SUPPORTDIR)/libsupport.$(OCAMLLIBEXT) + +include $(TOP)/mk/ocaml.mk Index: othersrc/external/bsd/testcompat/parser/lexer.mll diff -u /dev/null othersrc/external/bsd/testcompat/parser/lexer.mll:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/parser/lexer.mll Thu Dec 7 05:55:36 2017 @@ -0,0 +1,263 @@ +(* + * Copyright (c) 2016, 2017 + * The President and Fellows of Harvard College. + * + * Written by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *) + +(* + * Lexer for testcompat specs. + *) + +(* prologue code *) +{ +open Pos +open Parser + +(* positioning and text/value extraction *) + +let curfile = ref "" +let curline = ref 0 +let curcol = ref 0 + +let nl () = + curline := !curline + 1; + curcol := 1 + +let advance lexbuf = + let len = Lexing.lexeme_end lexbuf - Lexing.lexeme_start lexbuf in + curcol := !curcol + len + +let pos lexbuf = + let ret = { file = !curfile; line = !curline; column = !curcol; } in + advance lexbuf; + ret + +let posval' lexbuf f = + let x = f (Lexing.lexeme lexbuf) in + { pos = (pos lexbuf); x; } + +let posval lexbuf = + posval' lexbuf (fun x -> x) + +let text lexbuf = + (posval lexbuf).x + +(* string accumulation buffer *) + +let stringdata = ref (Buffer.create 64) +let stringstart = ref { file=""; line=0; column=0; } +let startstring lexbuf = + Buffer.clear !stringdata; + stringstart := pos lexbuf +let addstring s = + Buffer.add_string !stringdata s +let addchar c = + addstring (String.make 1 c) +let getstring () = + let s = Buffer.contents !stringdata in + let p0 = !stringstart in + { pos = p0; x = s; } + +(* identifiers and keywords *) + +let keywords = Types.stringmap_of_list [ + (* bloody ocaml, you can't partially apply data constructors *) + ("abi", (fun pos -> ABI pos)); + ("add", (fun pos -> ADD pos)); + ("allocate", (fun pos -> ALLOCATE pos)); + ("arg", (fun pos -> ARG pos)); + ("asm", (fun pos -> ASM pos)); + ("attributes", (fun pos -> ATTRIBUTES pos)); + ("calltable", (fun pos -> CALLTABLE pos)); + ("concretize", (fun pos -> CONCRETIZE pos)); + ("const", (fun pos -> CONST pos)); + ("enum", (fun pos -> ENUM pos)); + ("field", (fun pos -> FIELD pos)); + ("flag", (fun pos -> FLAG pos)); + ("flagword", (fun pos -> FLAGWORD pos)); + ("for", (fun pos -> FOR pos)); + ("in", (fun pos -> IN pos)); + ("match", (fun pos -> MATCH pos)); + ("out", (fun pos -> OUT pos)); + ("place", (fun pos -> PLACE pos)); + ("pointer", (fun pos -> POINTER pos)); + ("register", (fun pos -> REGISTER pos)); + ("ret", (fun pos -> RET pos)); + ("set", (fun pos -> SET pos)); + ("specialize", (fun pos -> SPECIALIZE pos)); + ("stack", (fun pos -> STACK pos)); + ("struct", (fun pos -> STRUCT pos)); + ("syscall", (fun pos -> SYSCALL pos)); + ("syscallframe", (fun pos -> SYSCALLFRAME pos)); + ("test", (fun pos -> TEST pos)); + ("type", (fun pos -> TYPE pos)); + ("var", (fun pos -> VAR pos)); +] + +let doident tval = + try + (Types.StringMap.find tval.x keywords) tval.pos + with Not_found -> + IDENT tval + +(* for invalid input *) +let badchar tval = + let postxt = Pos.string_of_pos tval.pos in + Util.say (postxt ^ ": Invalid input character " ^ tval.x); + Util.fail () + +let badstring pos = + let postxt = Pos.string_of_pos pos in + let postxt2 = Pos.string_of_pos !stringstart in + Util.say (postxt ^ ": Unterminated string constant"); + Util.say (postxt2 ^ ": String constant began here"); + Util.fail () + +(* end of prologue code *) +} + +(* common patterns *) + +let ws = [' ' '\t'] +let digit = ['0'-'9'] +let letter = ['a'-'z' 'A'-'Z' '_'] +let alnum = ['0'-'9' 'a'-'z' 'A'-'Z' '_'] + +(* states *) +rule base = parse + ws+ { advance lexbuf; base lexbuf } + | '\n' { nl (); base lexbuf } + | '#' { comment lexbuf; base lexbuf } + | digit alnum* { NUMBER (posval' lexbuf int_of_string) } + | '"' { startstring lexbuf; strconst lexbuf } + | letter alnum* { doident (posval lexbuf) } + | '-' '>' { RARROW (pos lexbuf) } + | '&' { AMP (pos lexbuf) } + | ':' { COLON (pos lexbuf) } + | ',' { COMMA (pos lexbuf) } + | '=' { EQ (pos lexbuf) } + | '+' { PLUS (pos lexbuf) } + | ';' { SEMIC (pos lexbuf) } + | '*' { STAR (pos lexbuf) } + | '(' { LPAREN (pos lexbuf) } + | ')' { RPAREN (pos lexbuf) } + | '[' { LBRACK (pos lexbuf) } + | ']' { RBRACK (pos lexbuf) } + | '{' { LBRACE (pos lexbuf) } + | '}' { RBRACE (pos lexbuf) } + | _ { badchar (posval lexbuf); base lexbuf } + | eof { EOF } + +and strconst = parse + [ ^ '"' '\n' ]+ { addstring (text lexbuf); strconst lexbuf } + | '\\' '"' { addchar '"'; advance lexbuf; strconst lexbuf } + | '"' { advance lexbuf; QSTRING (getstring ()) } (* done *) + | '\n' { badstring (pos lexbuf); QSTRING (getstring ())} + +(* this needs to be its own state to defeat the longest-match rule *) +and comment = parse + [ ^ '\n' ]* '\n' { nl (); } + +(* trailer code *) +{ + +let dump' pos txt = + print_string (Pos.string_of_pos pos ^ " " ^ txt); + print_newline () + +let rec dump f b = + match f b with + EOF -> () + | NUMBER pv -> dump' pv.pos ("NUMBER " ^ string_of_int pv.x); dump f b + | QSTRING pv -> dump' pv.pos ("QSTRING " ^ pv.x); dump f b + | IDENT pv -> dump' pv.pos ("IDENT " ^ pv.x); dump f b + | ABI pos -> dump' pos "ABI"; dump f b + | ADD pos -> dump' pos "ADD"; dump f b + | ALLOCATE pos -> dump' pos "ALLOCATE"; dump f b + | ARG pos -> dump' pos "ARG"; dump f b + | ASM pos -> dump' pos "ASM"; dump f b + | ATTRIBUTES pos -> dump' pos "ATTRIBUTES"; dump f b + | CALLTABLE pos -> dump' pos "CALLTABLE"; dump f b + | CONCRETIZE pos -> dump' pos "CONCRETIZE"; dump f b + | CONST pos -> dump' pos "CONST"; dump f b + | ENUM pos -> dump' pos "ENUM"; dump f b + | FIELD pos -> dump' pos "FIELD"; dump f b + | FLAG pos -> dump' pos "FLAG"; dump f b + | FLAGWORD pos -> dump' pos "FLAGWORD"; dump f b + | FOR pos -> dump' pos "FOR"; dump f b + | IN pos -> dump' pos "IN"; dump f b + | MATCH pos -> dump' pos "MATCH"; dump f b + | OUT pos -> dump' pos "OUT"; dump f b + | PLACE pos -> dump' pos "PLACE"; dump f b + | POINTER pos -> dump' pos "POINTER"; dump f b + | REGISTER pos -> dump' pos "REGISTER"; dump f b + | RET pos -> dump' pos "RET"; dump f b + | SET pos -> dump' pos "SET"; dump f b + | SPECIALIZE pos -> dump' pos "SPECIALIZE"; dump f b + | STACK pos -> dump' pos "STACK"; dump f b + | STRUCT pos -> dump' pos "STRUCT"; dump f b + | SYSCALL pos -> dump' pos "SYSCALL"; dump f b + | SYSCALLFRAME pos -> dump' pos "SYSCALLFRAME"; dump f b + | TEST pos -> dump' pos "TEST"; dump f b + | TYPE pos -> dump' pos "TYPE"; dump f b + | VAR pos -> dump' pos "VAR"; dump f b + | LBRACE pos -> dump' pos "LBRACE"; dump f b + | RBRACE pos -> dump' pos "RBRACE"; dump f b + | LBRACK pos -> dump' pos "LBRACK"; dump f b + | RBRACK pos -> dump' pos "RBRACK"; dump f b + | LPAREN pos -> dump' pos "LPAREN"; dump f b + | RPAREN pos -> dump' pos "RPAREN"; dump f b + | RARROW pos -> dump' pos "RARROW"; dump f b + | AMP pos -> dump' pos "AMP"; dump f b + | COLON pos -> dump' pos "COLON"; dump f b + | COMMA pos -> dump' pos "COMMA"; dump f b + | EQ pos -> dump' pos "EQ"; dump f b + | PLUS pos -> dump' pos "PLUS"; dump f b + | SEMIC pos -> dump' pos "SEMIC"; dump f b + | STAR pos -> dump' pos "STAR"; dump f b + +let read pathname = + curfile := pathname; + curline := 1; + curcol := 1; + let channel = open_in pathname in + let lexbuf = Lexing.from_channel channel in + let lexer = base in + let parser = Parser.file lexer in + try + (*dump lexer lexbuf;*) + let decls = parser lexbuf in + Ptcheck.check decls + with Parsing.Parse_error -> + let strings = [!curfile; string_of_int !curline; string_of_int !curcol] + in + let postxt = String.concat ":" strings in + let msg = postxt ^ ": Parse error" in + Util.crash msg + +} Index: othersrc/external/bsd/testcompat/parser/parser.mly diff -u /dev/null othersrc/external/bsd/testcompat/parser/parser.mly:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/parser/parser.mly Thu Dec 7 05:55:36 2017 @@ -0,0 +1,357 @@ +%{ +(*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *) + +open Pos +module T = Ptree + +%} + +%token EOF +%token <int Pos.posval> NUMBER +%token <string Pos.posval> QSTRING IDENT +/* reserved words */ +%token <Pos.pos> ABI ADD ALLOCATE ARG ASM ATTRIBUTES CALLTABLE +%token <Pos.pos> CONCRETIZE CONST ENUM FIELD FLAG FLAGWORD FOR IN +%token <Pos.pos> MATCH OUT PLACE POINTER REGISTER RET SET SPECIALIZE +%token <Pos.pos> STACK STRUCT SYSCALL SYSCALLFRAME TEST TYPE VAR +/* grouping punctuation */ +%token <Pos.pos> LBRACE RBRACE LBRACK RBRACK LPAREN RPAREN +/* multicharacter punctuation */ +%token <Pos.pos> RARROW +/* single-character punctuation */ +%token <Pos.pos> AMP COLON COMMA EQ PLUS SEMIC STAR + +%type <Ptree.decl list> file +%start file + +%% + +file: + decls EOF { List.rev $1 } +; + +decls: /* built in reverse order */ + /* nil */ { [] } + | decls decl { $2 :: $1 } +; + +decl: + type_decl { $1 } + | enum_decl { $1 } + | flagword_decl { $1 } + | struct_decl { $1 } + | syscall_decl { $1 } + | global_concretize { $1 } + | calltable_decl { $1 } + | setting_decl { $1 } + | specialize_block { $1 } + | abi_decl { $1 } + | syscallframe_decl { $1 } + | asm_decl { $1 } + | test_decl { $1 } +; + +type_decl: + TYPE IDENT SEMIC { T.TYPEDECL ($2.pos, $2.x) } +; + +enum_decl: + ENUM IDENT LBRACE RBRACE { T.ENUMDECL ($2.pos, $2.x, []) } + | ENUM IDENT LBRACE enumerators RBRACE + { T.ENUMDECL ($2.pos, $2.x, List.rev $4) } + | ENUM IDENT LBRACE enumerators COMMA RBRACE + { T.ENUMDECL ($2.pos, $2.x, List.rev $4) } +; + +enumerators: /* built in reverse order */ + enumerator { [$1] } + | enumerators COMMA enumerator { $3 :: $1 } +; + +enumerator: + IDENT { T.ENUMERATOR ($1.pos, $1.x) } +; + +flagword_decl: + FLAGWORD IDENT LBRACE flagerators RBRACE + { T.FLAGDECL ($2.pos, $2.x, List.rev $4) } +; + +flagerators: /* built in reverse order */ + /* nil */ { [] } + | flagerators flagerator { $2 :: $1 } +; + +flagerator: + FIELD IDENT COLON typename SEMIC { T.FLAGFIELD ($2.pos, $2.x, $4) } + | FLAG IDENT SEMIC { T.FLAG ($2.pos, $2.x) } +; + +struct_decl: + STRUCT IDENT LBRACE members RBRACE + { T.STRUCTDECL ($2.pos, $2.x, List.rev $4) } +; + +members: /* built in reverse order */ + /* nil */ { [] } + | members member { $2 :: $1 } +; + +member: + IDENT COLON typename SEMIC { T.MEMBER ($1.pos, $1.x, $3) } +; + +syscall_decl: + SYSCALL IDENT LBRACE syscall_elements RBRACE + { T.SYSCALL ($2.pos, $2.x, List.rev $4) } +; + +syscall_elements: /* built in reverse order */ + /* nil */ { [] } + | syscall_elements syscall_element { $2 :: $1 } +; + +syscall_element: + arg_decl { $1 } + | ret_decl { $1 } + | attributes_decl { $1 } + | local_concretize { $1 } +; + +arg_decl: + ARG IDENT COLON typename SEMIC { T.ARG ($2.pos, $2.x, $4) } +; + +ret_decl: + RET IDENT COLON typename SEMIC { T.RET ($2.pos, $2.x, $4) } +; + +attributes_decl: + ATTRIBUTES idents SEMIC { T.ATTRIBUTES (List.rev $2) } +; + +idents: /* built in reverse order */ + IDENT { [($1.pos, $1.x)] } + | idents IDENT { ($2.pos, $2.x) :: $1 } +; + +global_concretize: + CONCRETIZE IN idents concretize_block { T.CONCRETIZE_IN ($3, $4) } +; + +local_concretize: + CONCRETIZE concretize_block { T.CONCRETIZE $2 } +; + +concretize_block: + LBRACE concretize_body RBRACE { $2 } +; + +concretize_body: + FOR TYPE IDENT COMMA concretize_body + { T.CONCR_FORTYPE ($3.pos, $3.x, $5) } + | FOR VAR IDENT COMMA concretize_body + { T.CONCR_FORVAR ($3.pos, $3.x, $5) } + | MATCH ARG IDENT COLON typename COMMA concretize_body + { T.CONCR_MATCHARG ($3.pos, $3.x, $5, $7) } + | MATCH RET IDENT COLON typename COMMA concretize_body + { T.CONCR_MATCHRET ($3.pos, $3.x, $5, $7) } + | statements { T.CONCR_BLOCK (List.rev $1) } +; + +calltable_decl: + CALLTABLE map_literal { T.CALLTABLE $2 } +; + +setting_decl: + SET IDENT expr SEMIC { T.SETTING ($2.pos, $2.x, $3) } +; + +specialize_block: + SPECIALIZE LBRACE specialize_items RBRACE + { T.SPECIALIZE (List.rev $3) } +; + +specialize_items: /* built in reverse order */ + specialize_item { [$1] } + | specialize_items specialize_item { $2 :: $1 } +; + +specialize_item: + TYPE IDENT EQ typename SEMIC { T.SPEC_TYPE ($2.pos, $2.x, $4) } + | CONST IDENT EQ expr SEMIC { T.SPEC_VALUE ($2.pos, $2.x, $4) } +; + +abi_decl: + ABI IDENT LBRACE abi_items RBRACE { T.ABI ($2.pos, $2.x, List.rev $4) } +; + +abi_items: /* built in reverse order */ + abi_item { [$1] } + | abi_items abi_item { $2 :: $1 } +; + +abi_item: + setting_decl { $1 } + | syscallframe_decl { $1 } + | asm_decl { $1 } +; + +syscallframe_decl: + SYSCALLFRAME LBRACE syscallframe_elements RBRACE + { T.SYSCALLFRAME (List.rev $3) } +; + +syscallframe_elements: /* built in reverse order */ + syscallframe_element { [$1] } + | syscallframe_elements syscallframe_element { $2 :: $1 } +; + +syscallframe_element: + setting_decl { $1 } + | PLACE NUMBER placement { T.PLACE ($2.pos, $2.x, $3) } +; + +placement: + REGISTER QSTRING SEMIC { T.PLACEREG ($2.pos, $2.x) } + | STACK SEMIC { T.PLACESTACK ($1, T.E_NUMBER ($1, 0)) } + | STACK PLUS expr SEMIC { T.PLACESTACK ($2, $3) } +; + +asm_decl: + ASM LBRACE asm_elements RBRACE { T.ASM (List.rev $3) } +; + +asm_elements: /* built in reverse order */ + asm_element { [$1] } + | asm_elements asm_element { $2 :: $1 } +; + +asm_element: + IDENT QSTRING SEMIC { T.ASMELEMENT ($1.pos, $1.x, $2.x) } +; + +test_decl: + TEST IDENT STAR SEMIC { T.TEST ($2.pos, $2.x, None) } + | TEST IDENT LBRACE machines RBRACE { T.TEST ($2.pos, $2.x, Some $4) } +; + +machines: /* built in reverse order */ + /* nil */ { [] } + | machines machine { $2 :: $1 } +; + +machine: + IDENT SEMIC { T.MACHINE ($1.pos, $1.x, None) } + | IDENT IDENT SEMIC { T.MACHINE ($1.pos, $1.x, Some $2.x) } +; + +/**************************************************************/ + +statements: /* built in reverse order */ + statement { [$1] } + | statements statement { $2 :: $1 } +; + +statement: + ADD ARG IDENT COLON typename SEMIC { T.ADDARG ($3.pos, $3.x, $5) } + | ADD RET IDENT COLON typename SEMIC { T.ADDRET ($3.pos, $3.x, $5) } + | ALLOCATE IDENT SEMIC { T.ALLOCATE ($2.pos, $2.x) } + | SET lvalue EQ expr SEMIC { T.SET ($1, $2, $4) } + | IDENT IDENT SEMIC { T.DO ($1.pos, $1.x, $1.x) } +; + +lvalue: + IDENT { T.L_PLAIN ($1.pos, $1.x) } + | base_expr LBRACK NUMBER RBRACK { T.L_ARRAY ($3.pos, $1, $3.x) } +; + +expr: + suffix_expr { $1 } + | AMP expr { T.E_ADDROF ($1, $2) } +; + +suffix_expr: + base_expr { $1 } + | suffix_expr LBRACK NUMBER RBRACK { T.E_ARRAY ($3.pos, $1, $3.x) } +; + +base_expr: + NUMBER { T.E_NUMBER ($1.pos, $1.x) } + | IDENT { T.E_READVAR ($1.pos, $1.x) } + | list_literal { T.E_LIST $1 } + | map_literal { T.E_MAP $1 } +; + +list_literal: + LBRACK listitems RBRACK { List.rev $2 } +; + +listitems: /* built in reverse order */ + expr { [$1] } + | listitems COMMA expr { $3 :: $1 } +; + +map_literal: + LBRACE mappings RBRACE { $2 } +; + +mappings: /* built in reverse order */ + /* nil */ { [] } + | mappings mapping { $2 :: $1 } +; + +mapping: + NUMBER RARROW expr SEMIC { T.MAPPING ($2, $1.x, $3) } +; + +typename: + IDENT { T.PLAINTYPE ($1.pos, $1.x) } + | IDENT LPAREN typeargs RPAREN { T.ARGTYPE ($1.pos, $1.x, $3) } + | direction POINTER LPAREN typename RPAREN { T.POINTER ($2, $1, $4) } +; + +typeargs: /* built in reverse order */ + typearg { [$1] } + | typeargs COMMA typearg { $3 :: $1 } +; + +typearg: + NUMBER { T.TNUMBER ($1.pos, $1.x) } + | typename { T.TTYPE $1 } +; + +direction: + IN { T.IN } + | OUT { T.OUT } +; + +%% + Index: othersrc/external/bsd/testcompat/parser/ptcheck.ml diff -u /dev/null othersrc/external/bsd/testcompat/parser/ptcheck.ml:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/parser/ptcheck.ml Thu Dec 7 05:55:36 2017 @@ -0,0 +1,31 @@ +(*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *) + +(* XXX write this *) +let check decls = decls Index: othersrc/external/bsd/testcompat/parser/ptree.ml diff -u /dev/null othersrc/external/bsd/testcompat/parser/ptree.ml:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/parser/ptree.ml Thu Dec 7 05:55:36 2017 @@ -0,0 +1,112 @@ +(*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *) + +type direction = IN | OUT + +type typearg = + TNUMBER of Pos.pos * int + | TTYPE of typename +and typename = + PLAINTYPE of Pos.pos * string + | ARGTYPE of Pos.pos * string * typearg list + | POINTER of Pos.pos * direction * typename + +type expr = + E_NUMBER of Pos.pos * int + | E_READVAR of Pos.pos * string + | E_ADDROF of Pos.pos * expr + | E_ARRAY of Pos.pos * expr * int + | E_LIST of expr list + | E_MAP of mapping list +and mapping = + MAPPING of Pos.pos * int * expr + +type lvalue = + L_PLAIN of Pos.pos * string + | L_ARRAY of Pos.pos * expr * int + +type statement = + ADDARG of Pos.pos * string * typename + | ADDRET of Pos.pos * string * typename + | ALLOCATE of Pos.pos * string + | SET of Pos.pos * lvalue * expr + | DO of Pos.pos * string * string + +type concretize = + CONCR_FORTYPE of Pos.pos * string * concretize + | CONCR_FORVAR of Pos.pos * string * concretize + | CONCR_MATCHARG of Pos.pos * string * typename * concretize + | CONCR_MATCHRET of Pos.pos * string * typename * concretize + | CONCR_BLOCK of statement list + +type specialization = + SPEC_TYPE of Pos.pos * string * typename + | SPEC_VALUE of Pos.pos * string * expr + +type enumerator = + ENUMERATOR of Pos.pos * string + +type flagerator = + FLAGFIELD of Pos.pos * string * typename + | FLAG of Pos.pos * string + +type structmember = + MEMBER of Pos.pos * string * typename + +type syscallelement = + ARG of Pos.pos * string * typename + | RET of Pos.pos * string * typename + | ATTRIBUTES of (Pos.pos * string) list + | CONCRETIZE of concretize + +type placement = + PLACEREG of Pos.pos * string + | PLACESTACK of Pos.pos * expr + +type asmelement = + ASMELEMENT of Pos.pos * string * string + +type machine = + MACHINE of Pos.pos * string * string option + +type decl = + TYPEDECL of Pos.pos * string + | ENUMDECL of Pos.pos * string * enumerator list + | FLAGDECL of Pos.pos * string * flagerator list + | STRUCTDECL of Pos.pos * string * structmember list + | SYSCALL of Pos.pos * string * syscallelement list + | CONCRETIZE_IN of (Pos.pos * string) list * concretize + | CALLTABLE of mapping list + | SETTING of Pos.pos * string * expr + | SPECIALIZE of specialization list + | ABI of Pos.pos * string * decl list + | SYSCALLFRAME of decl list + | PLACE of Pos.pos * int * placement + | ASM of asmelement list + | TEST of Pos.pos * string * machine list option Index: othersrc/external/bsd/testcompat/specs/cases.def diff -u /dev/null othersrc/external/bsd/testcompat/specs/cases.def:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/specs/cases.def Thu Dec 7 05:55:36 2017 @@ -0,0 +1,43 @@ + +# +# This list is rather ambitious +# + +test freebsd *; +test linux *; +test netbsd *; + +test irix { + m68k; + mips O32; + mips O64; + mips N32; + mips N64; +} + +test osf1 { + alpha; +} + +test solaris { + sparc32; + sparc64; + i386; + x86_64; +} + +test sunos { + m68k; + sparc32; + sparc64; +} + +test svr4 { + i386; + x86_64; +} + +test ultrix { + mips O32; + vax; +} Index: othersrc/external/bsd/testcompat/specs/mips.mach diff -u /dev/null othersrc/external/bsd/testcompat/specs/mips.mach:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/specs/mips.mach Thu Dec 7 05:55:36 2017 @@ -0,0 +1,37 @@ +# +# MIPS machine specification +# + +abi O32 { + set sizes ilp32; + + syscallframe { + set minstacksize 16; + set minargsize 4; + set argsizes [4, 8]; + set alignargs { 4 -> 4; 8 -> 8; }; + place 0 register "$4"; # a0 + place 1 register "$5"; # a1 + place 2 register "$6"; # a2 + place 3 register "$7"; # a3 + place 4 stack + 16; + } + + asm { + load_reg_int32 "li %r, %d"; + load_reg_sym "la %r, %s"; + store_reg_stack "sw %r, %d($29)"; # $29 = sp + dosyscall "syscall"; + data_32 ".word %d"; + data_8 ".byte %d"; + } +} + +#abi O64 { +#} + +#abi N32 { +#} + +#abi N64 { +#} Index: othersrc/external/bsd/testcompat/specs/syscalls.def diff -u /dev/null othersrc/external/bsd/testcompat/specs/syscalls.def:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/specs/syscalls.def Thu Dec 7 05:55:36 2017 @@ -0,0 +1,858 @@ +# +# Abstract syscalls. +# +# (These are general specifications of syscalls that exist on many +# platforms and many targets. They are then specialized later.) +# + +# +# Abstract types. These C types are built in: +# int uint long ulong +# but these are used only where a call *always* has that type +# (e.g. the exit code argument to exit); otherwise an abstract +# type is used, and made up if necessary. +# + +type string; # character string +type data; # block of data + +type dev_t; # packaged device major/minor numbers +type fd_t; # file handle (usually int) +type gid_t; # group id +type mode_t; # file permissions +type modeandtype_t; # mode_t with file type bits as well +type pid_t; # process id +type size_t; # memory size +type uid_t; # user id +type waitstatus_t; # wait result + +# flags to open (usually int) +enum accmode { + O_RDONLY, + O_WRONLY, + O_RDWR +} +flagword openflags_t { + field O_ACCMODE: accmode; + flag O_CREAT; + flag O_EXCL; + flag O_TRUNC; + # XXX ... +} + +# protections used by mmap +enum vm_prot_t { + PROT_READ, PROT_WRITE, PROT_EXEC +} + +# mmap flags +flagword mmapflags_t { + # XXX +} +flagword mremapflags_t { + # XXX +} + +# signals +enum signal_t { + SIGHUP, + SIGBUS, + SIGSEGV, + # XXX ... +} + +struct stat { + # XXX: any need to put anything here? +} + +# +# Process calls +# + +syscall getpid { + ret pid: pid_t; +} + +syscall getppid { + ret ppid: pid_t; +} + +syscall getpid_with_ppid { + ret pid: pid_t; + ret ppid: pid_t; +} + +syscall fork { + ret pid: pid_t; + attributes fork; +} + +syscall vfork { + ret pid: pid_t; + attributes vfork; +} + +syscall execv { + arg prog: string; + arg argv: array(string); +} + +syscall execve { + arg prog: string; + arg argv: zeroarray(string); + arg env: zeroarray(string); +} + +syscall exit { + arg code: int; + attributes noreturn; +} + +syscall wait { + ret pid: pid_t; + ret status: waitstatus_t; +} + +#getrusage + +enum rlimit_t { + # XXX +} +struct rlimit { + cur: rlim_t; + max: rlim_t; +} +syscall getrlimit { + arg what: rlimit_t; + arg limit: rlimit; +} + +syscall chdir { + arg path: string; +} + +syscall getcwd { + ret path: string; +} + +syscall chroot { + arg path: string; +} + +syscall getpgrp { + ret pgrp: pid_t; +} + +syscall setpgid { # also BSD setpgrp + arg pid: pid_t; + arg pgid: pid_t; +} + +syscall sysv_setpgrp { + ret pgid: pid_t; +} + +#getpriority +#setpriority + +# +# File handle calls +# + +syscall open { + arg path: string; + arg flags: openflags_t; + arg mode: mode_t; + ret fd: fd_t; +} + +syscall creat { + arg path: string; + arg mode: mode_t; + ret fd: fd_t; +} + +syscall pipe { + ret rfd: fd_t; + ret wfd: fd_t; +} + +syscall dup { + arg ofd: fd_t; + ret nfd: fd_t; +} + +syscall dup2 { + arg ofd: fd_t; + arg nfd: fd_t; + ret result: fd_t; +} + +syscall vhangup { +} + +syscall close { + arg fd: fd_t; +} + +syscall getdtablesize { + ret num: fd_t; +} + +# +# File operations +# + +syscall read { + arg fd: fd_t; + arg max: size_t; + ret data: data; +} + +syscall write { + arg fd: fd_t; + arg data: data; + ret written: size_t; +} + +#readv +#writev +#pread +#pwrite +#preadv +#pwritev + +syscall getdirentries { + arg fd: fd_t; + # XXX ... +} + +syscall lseek { + arg fd: fd_t; + arg offset: off_t; + arg whence: int; + ret result: off_t; +} + +syscall fsync { + arg fd: fd_t; +} + +syscall fdatasync { + arg fd: fd_t; +} + +syscall fcntl { + arg fd: fd_t; + arg op: fcntl_t; + arg wdata: data; + ret rdata: data; + attributes fcntl; +} + +syscall ioctl { + arg fd: fd_t; + arg op: ioctl_t; + arg wdata: data; + ret rdata: data; + attributes ioctl; +} + +# +# Path operations +# + +syscall mkfifo { + arg path: string; + arg mode: modeandtype_t; +} + +syscall mknod { + arg path: string; + arg mode: modeandtype_t; + arg dev: dev_t; +} + +syscall mkdir { + arg path: string; + arg mode: mode_t; +} + +syscall rmdir { + arg path: string; +} + +flagword accessflags_t { + flag F_OK; + flag R_OK; + flag W_OK; + flag X_OK; +} +syscall access { + arg path: string; + arg how: accessflags_t; +} + +syscall link { + arg oldpath: string; + arg newpath: string; +} + +syscall rename { + arg oldpath: string; + arg newpath: string; +} + +syscall symlink { + arg oldpath: string; + arg linktext: string; +} + +syscall readlink { + arg path: string; + ret text: data; +} + +syscall unlink { + arg path: string; +} + + +# +# File and path operations +# + +syscall chmod { + arg path: string; + arg mode: mode_t; +} + +syscall lchmod { + arg path: string; + arg mode: mode_t; +} + +syscall fchmod { + arg fd: fd_t; + arg mode: mode_t; +} + +syscall chown { + arg path: string; + arg uid: uid_t; + arg gid: gid_t; +} + +syscall lchown { + arg path: string; + arg uid: uid_t; + arg gid: gid_t; +} + +syscall fchown { + arg fd: fd_t; + arg uid: uid_t; + arg gid: gid_t; +} + +syscall stat { + arg path: string; + ret buf: stat; +} + +syscall lstat { + arg path: string; + ret buf: stat; +} + +syscall fstat { + arg fd: fd_t; + ret buf: stat; +} + +syscall statfs { + arg path: string; + ret buf: statfs; +} + +syscall lstatfs { + arg path: string; + ret buf: statfs; +} + +syscall fstatfs { + arg fd: fd_t; + ret buf: statfs; +} + +syscall statvfs { + arg path: string; + ret buf: statvfs; +} + +syscall lstatvfs { + arg path: string; + ret buf: statvfs; +} + +syscall fstatvfs { + arg fd: fd_t; + ret buf: statvfs; +} + +concretize in + stat lstat fstat + statfs lstatfs fstatfs + statvfs lstatvfs fstatvfs +{ + for type t, + for var buf, + match ret buf: t, + + #add arg bufptr: out pointer(t); + #allocate buf; + #set bufptr = &buf; + pointerret buf; +} + +syscall utimes { + arg path: string; + arg atime: timeval; + arg mtime: timeval; +} + +syscall lutimes { + arg path: string; + arg atime: timeval; + arg mtime: timeval; +} + +syscall futimes { + arg fd: fd_t; + arg atime: timeval; + arg mtime: timeval; +} + +syscall utimens { + arg path: string; + arg atime: timespec; + arg mtime: timespec; +} + +syscall lutimens { + arg path: string; + arg atime: timespec; + arg mtime: timespec; +} + +syscall futimens { + arg fd: fd_t; + arg atime: timespec; + arg mtime: timespec; +} + +concretize in + utimes lutimes futimes + utimens lutimens futimens +{ + for type t, + match arg atime: t, + match arg mtime: t, + + add arg times: in pointer(fixarray(t, 2)); + allocate atime; + allocate mtime; + set times[0] = &atime; + set times[1] = &mtime; +} + +syscall truncate { + arg path: string; + ret len: off_t; +} + +syscall ftruncate { + arg fd: fd_t; + ret len: off_t; +} + +# +# Misc FS calls +# + +syscall sync { +} + +#getmnt +#getfsstat +#getvfsstat + +# this is an old sysv form of statfs +struct ustat { + f_tfree: daddr_t; + f_tinode: uint; + f_fname: string; + f_fpack: string; +} +syscall ustat { + arg dev: dev_t; + ret data: ustat; + concretize { + pointerret data; + } +} + +# +# The world has a wide variety of mount and unmount calls. +# + +syscall mount_foo { + arg dev: string; + arg mountpoint: string; + arg rdonly: bool; + arg mnttype: mounttypes; + arg data: data; +} + +# +# VM calls +# + +syscall brk { + arg addr: uintptr_t; +} + +syscall sbrk { + arg change: intptr_t; + ret addr: uintptr_t; +} + +syscall sstk { + arg change: intptr_t; + ret addr: uintptr_t; +} + +syscall getpagesize { + ret size: size_t; +} + +syscall mmap { + arg addr: uintptr_t; + arg len: size_t; + arg prot: vm_prot_t; + arg flags: mmapflags_t; + arg fd: fd_t; + arg pos: off_t; +} + +syscall mremap { + arg oldaddr: uintptr_t; + arg oldsize: size_t; + arg newaddr: uintptr_t; + arg newsize: size_t; + arg flags: mremapflags_t; +} + +syscall munmap { + arg addr: uintptr_t; + arg size: size_t; +} + +syscall mprotect { + arg addr: uintptr_t; + arg size: size_t; + arg prot: vm_prot_t; +} + +syscall mincore { + arg addr: uintptr_t; + arg size: size_t; + ret info: data; +} + +enum vadvisearg_t { + VA_NORM, VA_ANOM, VA_SEQL, VA_FLUSH +} +syscall vadvise { + arg mode: vadvisearg_t; +} + +enum madvisearg_t { + MADV_NORMAL, MADV_RANDOM, MADV_SEQUENTIAL, + MADV_WILLNEED, MADV_DONTNEED, MADV_FREE +} +syscall madvise { + arg addr: uintptr_t; + arg size: size_t; + arg mode: madvisearg_t; +} + +# +# Security calls +# + +syscall umask { + arg mask: mode_t; + ret oldmask: mode_t; +} + +syscall issetugid { + ret is: bool; +} + +syscall setuid { + arg uid: uid_t; +} + +syscall seteuid { + arg uid: uid_t; +} + +syscall setreuid { + arg ruid: uid_t; + arg euid: uid_t; +} + +syscall setresuid { + arg ruid: uid_t; + arg euid: uid_t; + arg suid: uid_t; +} + +syscall setgid { + arg gid: gid_t; +} + +syscall setegid { + arg gid: gid_t; +} + +syscall setregid { + arg rgid: gid_t; + arg egid: gid_t; +} + +syscall setresgid { + arg rgid: gid_t; + arg egid: gid_t; + arg sgid: gid_t; +} + +syscall getuid { + ret uid: uid_t; +} + +syscall geteuid { + ret euid: uid_t; +} + +syscall getgid { + ret gid: gid_t; +} + +syscall getegid { + ret egid: gid_t; +} + +syscall setgroups { + arg groups: countarray(gid_t); +} + +syscall getgroups { + arg max: ngroups_t; + ret groups: countarray(gid_t); +} + +# +# Signals +# + +syscall kill { + arg pid: pid_t; + arg sig: signal_t; +} + +syscall killpg { + arg pgid: pid_t; + arg sig: signal_t; +} + +syscall sigreturn { + # XXX +} + +syscall sigvec { + arg sig: signal_t; + arg nstate: sigvec; + ret ostate: sigvec; + concretize { + pointerret ostate; + } +} + +syscall sigaction { + arg sig: signal_t; + arg nstate: sigaction; + ret ostate: sigaction; + concretize { + pointerret ostate; + } +} + +syscall sigstack { + arg sig: signal_t; + arg nstate: sigstack; + ret ostate: sigstack; + concretize { + pointerret ostate; + } +} + +syscall sigaltstack { + arg sig: signal_t; + arg nstate: sigaltstack; + ret ostate: sigaltstack; + concretize { + pointerret ostate; + } +} + +syscall sigblock { + arg mask: int; # XXX should this be a type? +} + +syscall sigsetmask { + arg mask: int; # XXX should this be a type? +} + +syscall sigsuspend { + arg mask: int; # XXX should this be a type? +} + +syscall sigpending { + ret mask: int; # XXX should this be a type? +} + + +# +# Sockets +# + +#socket +#bind +#connect +#listen +#accept +#socketpair +#getsockname +#getpeername +#getsockopt +#setsockopt +#send +#recv +#sendto +#recvfrom +#sendmsg +#recvmsg +#shutdown + +# +# Events +# + +#select + +# +# Time +# + +#setitimer +#getitimer +#gettimeofday +#settimeofday +#adjtime +#adjtimex + +# +# sysvipc +# + +#shmsys +#semsys +#msgsys + +# +# NFS +# + +#nfssvc +#getfh +#fhopen +#exportfs + +# +# Old weird stuff +# + +# +# Misc +# + +syscall gethostname { + ret name: string; + concretize { + #add arg buf: out pointer(countarray(char)); + #add arg max: size_t; + #allocate name MAXHOSTNAMELEN; + #set buf = &name; + #set max = MAXHOSTNAMELEN; + #add ret len; + #post length name = len; + bufferret name; + } +} + +syscall sethostname { + arg name: string; +} + +syscall getdomainname { + ret name: string; + concretize { + bufferret name; + } +} + +syscall setdomainname { + arg name: string; +} + +#gethostid + +struct uname { + # XXX +} +syscall uname { + ret data: uname; + concretize { + pointerret data; + } +} + +syscall profil { + arg buf: uintptr_t; + arg size: size_t; + arg offset: uintptr_t; + arg scale: uint; +} + +syscall acct { + arg path: string; +} + +#quotactl + +syscall reboot { + # XXX should we have a type here? + arg flags: int; +} Index: othersrc/external/bsd/testcompat/specs/ultrix.kern diff -u /dev/null othersrc/external/bsd/testcompat/specs/ultrix.kern:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/specs/ultrix.kern Thu Dec 7 05:55:36 2017 @@ -0,0 +1,184 @@ +# +# Ultrix kernel interface. +# + +calltable { + 1 -> exit; + 2 -> fork; + 3 -> read; + 4 -> write; + 5 -> open; + 6 -> close; + 7 -> wait; + 8 -> creat; + 9 -> link; + 10 -> unlink; + 11 -> execv; + 12 -> chdir; + 14 -> mknod; + 15 -> chmod; + 16 -> chown; + 17 -> bkr; + 19 -> lseek; + 20 -> getpid; + 21 -> ultrix_mount; + 23 -> setuid; + 24 -> getuid; + 33 -> access; + 36 -> sync; + 37 -> kill; + 38 -> stat; + 40 -> lstat; + 41 -> dup; + 42 -> pipe; + 44 -> profil; + 47 -> getgid; + 51 -> acct; + 54 -> ioctl; + 55 -> reboot; + 57 -> symlink; + 58 -> readlink; + 59 -> execve; + 60 -> umask; + 61 -> chroot; + 62 -> fstat; + 64 -> getpagesize; + 65 -> mremap; + 66 -> vfork; + 69 -> sbrk; + 70 -> sstk; + 71 -> mmap; + 72 -> vadvise; + 73 -> munmap; + 74 -> mprotect; + 75 -> madvise; + 76 -> vhangup; + 78 -> mincore; + 79 -> getgroups; + 80 -> setgroups; + 81 -> getpgrp; + 82 -> setpgrp; + 83 -> setitimer; + 84 -> wait3; + 85 -> swapon; + 86 -> getitimer; + 87 -> gethostname; + 88 -> sethostname; + 89 -> getdtablesize; + 90 -> dup2; + 92 -> fcntl; + 93 -> select; + 95 -> fsync; + 96 -> setpriority; + 97 -> socket; + 98 -> connect; + 99 -> accept; + 100 -> getpriority; + 101 -> send; + 102 -> recv; + 103 -> sigreturn; + 104 -> bind; + 105 -> setsockopt; + 106 -> lisen; + 108 -> sigvec; + 109 -> sigblock; + 110 -> sigsetmask; + 112 -> sigstack; + 113 -> recvmsg; + 114 -> sendmsg; + 116 -> gettimeofday; + 117 -> getrusage; + 118 -> getsockopt; + 120 -> readv; + 121 -> writev; + 122 -> settimeofday; + 123 -> fchown; + 124 -> fchmod; + 125 -> recvfrom; + 126 -> setreuid; + 127 -> setregid; + 128 -> rename; + 129 -> truncate; + 130 -> ftruncate; + 131 -> flock; + 133 -> sendto; + 134 -> shutdown; + 135 -> socketpair; + 136 -> mkdir; + 137 -> rmdir; + 138 -> utimes; + 139 -> sigcleanup; + 140 -> adjtime; + 141 -> getpeername; + 142 -> gethostid; + 144 -> getrlimit; + 145 -> setrlimit; + 146 -> killpg; + 150 -> getsockname; + #152 -> cacheflush; + #153 -> cachectl; + 158 -> nfssvc; + 159 -> getdirentries; + 160 -> statfs; + 161 -> fstatfs; + 162 -> umount; + 164 -> getfh; + 165 -> getdomainname; + 166 -> setdomainname; + 168 -> quotactl; + 169 -> exportfs; + 170 -> ultrix_mount; + 172 -> msgctl; + 173 -> msgget; + 174 -> msgrcv; + 175 -> msgsnd; + 176 -> semctl; + 177 -> semget; + 178 -> semop; + 179 -> uname; + 180 -> shmsys; + 181 -> plock; + 182 -> lockf; + 183 -> ustat; + 184 -> getmnt; + 187 -> sigpending; + 188 -> setsid; + 189 -> waitpid; + 256 -> getsysinfo; + 257 -> setsysinfo; +} + +set mincall 0; +set maxcall 384; + +specialize { + type dev_t = int; + type fd_t = int; + type gid_t = int32_t; + type mode_t = int; + type modeandtype_t = int; + type off_t = long; + type pid_t = int; + type uid_t = int32_t; + type waitstatus_t = int; + + type openflags_t = int; + type accmode = bits(2); + const O_RDONLY = 0; + const O_WRONLY = 1; + const O_RDWR = 2; + #const O_CREAT = ?; + #const O_EXCL = ?; + #const O_TRUNC = ?; + + type vm_prot_t = int; + #const PROT_READ = ?; + #const PROT_WRITE = ?; + #const PROT_EXEC = ?; + + type signal_t = int; + const SIGHUP = 1; + const SIGBUS = 10; + const SIGSEGV = 11; +} + Index: othersrc/external/bsd/testcompat/support/Makefile diff -u /dev/null othersrc/external/bsd/testcompat/support/Makefile:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/support/Makefile Thu Dec 7 05:55:36 2017 @@ -0,0 +1,8 @@ +TOP=.. +include $(TOP)/mk/base.mk + +LIB=support +SRCS=\ + util.ml types.ml pos.ml + +include $(TOP)/mk/ocaml.mk Index: othersrc/external/bsd/testcompat/support/pos.ml diff -u /dev/null othersrc/external/bsd/testcompat/support/pos.ml:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/support/pos.ml Thu Dec 7 05:55:36 2017 @@ -0,0 +1,53 @@ +(* + * Copyright (c) 2016 + * The President and Fellows of Harvard College. + * + * Written by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + *) + +(* Source positions. *) + +type pos = { + file: string; + line: int; + column: int; +} + +(* position along with a value *) +type 't posval = { + pos: pos; + x: 't; +} + +let string_of_pos { file; line; column; } = + file ^ ":" ^ string_of_int line ^ ":" ^ string_of_int column + +let sayat pos msg = Util.say (string_of_pos pos ^ ": " ^ msg) +let failat pos msg = Util.say (string_of_pos pos ^ ": " ^ msg); Util.fail () +let crashat pos msg = Util.crash (string_of_pos pos ^ ": " ^ msg) + +let builtin = { file = "<built-in>"; line = 0; column = 0; } Index: othersrc/external/bsd/testcompat/support/types.ml diff -u /dev/null othersrc/external/bsd/testcompat/support/types.ml:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/support/types.ml Thu Dec 7 05:55:36 2017 @@ -0,0 +1,36 @@ +(*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *) + +module StringMap = Map.Make(String) +module StringSet = Set.Make(String) + +(* Why doesn't this come with Map? *) +let stringmap_of_list kvs = + let doadd z (k, v) = StringMap.add k v z in + List.fold_left doadd StringMap.empty kvs Index: othersrc/external/bsd/testcompat/support/util.ml diff -u /dev/null othersrc/external/bsd/testcompat/support/util.ml:1.1 --- /dev/null Thu Dec 7 05:55:36 2017 +++ othersrc/external/bsd/testcompat/support/util.ml Thu Dec 7 05:55:36 2017 @@ -0,0 +1,44 @@ +(*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by David A. Holland. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *) + +let say msg = + prerr_string msg; prerr_newline () + +let crash msg = + say msg; exit 1 + +let failures = ref 0 +let fail () = + failures := 1 + !failures + +let checkfail () = + if !failures = 1 then + crash "Fatal error." + else if !failures > 1 then + crash (string_of_int !failures ^ " fatal errors.")