From 5b1c1b2752bddf0d330f6ef4ba878f6108e77b43 Mon Sep 17 00:00:00 2001 From: "Ian A. Mason" Date: Mon, 28 Oct 2019 14:38:49 +0000 Subject: [PATCH] testing the cmd switches and environment settings. --- .gitignore | 1 + examples/nodejs/Makefile | 64 ++++++++++++++++++++++++++-- shared/environment.go | 34 ++++++++------- shared/extractor.go | 38 ++++++++--------- tests/entry_test.go | 2 +- tests/env_and_arg_test.go | 87 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 187 insertions(+), 39 deletions(-) create mode 100644 tests/env_and_arg_test.go diff --git a/.gitignore b/.gitignore index 1a62c0d..da443be 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ gowllvm +examples/nodejs \ No newline at end of file diff --git a/examples/nodejs/Makefile b/examples/nodejs/Makefile index 59a68da..cd2ff6a 100644 --- a/examples/nodejs/Makefile +++ b/examples/nodejs/Makefile @@ -6,7 +6,7 @@ SRC=node-${VERSION} TAR=${SRC}.tar.gz URL=https://nodejs.org/dist/${VERSION}/${TAR} -all: node.bc +all: node_from_bitcode bitcode: libnode.bc libzlib.bc libuv.bc libv8_base.bc libopenssl.bc node_main.bc \ @@ -14,7 +14,6 @@ bitcode: libnode.bc libzlib.bc libuv.bc libv8_base.bc libopenssl.bc node_main.bc libbrotili.bc libv8_libbase.bc libv8_sampler.bc libicuucx.bc libicudata.bc \ libicustubdata.bc libv8_snapshot.bc - ${TAR}: wget https://nodejs.org/dist/v10.16.0/node-v10.16.0.tar.gz @@ -23,17 +22,74 @@ ${SRC}: ${TAR} ${SRC}/Makefile: ${SRC} cd ${SRC}; CC=gclang CXX=gclang++ ./configure --openssl-no-asm - #make sure ${SRC}/node isn't earlier than ${SRC} +#make sure ${SRC}/node isn't earlier than ${SRC} touch ${SRC}/Makefile ${SRC}/node: ${SRC}/Makefile cd ${SRC}; CC=gclang CXX=gclang++ make - #make sure ${SRC}/node isn't earlier than ${SRC} +#make sure ${SRC}/node isn't earlier than ${SRC} touch ${SRC}/node node.bc: ${SRC}/node get-bc -o node.bc ${SRC}/node +libnode.bc: ${SRC}/node + get-bc -b -o libnode.bc ${SRC}/out/Release/obj.target/libnode.a + +libzlib.bc: ${SRC}/node + get-bc -b -o libzlib.bc ${SRC}/out/Release/obj.target/deps/zlib/libzlib.a + +libuv.bc: ${SRC}/node + get-bc -b -o libuv.bc ${SRC}/out/Release/obj.target/deps/uv/libuv.a + +libv8_base.bc: ${SRC}/node + get-bc -b -o libv8_base.bc ${SRC}/out/Release/obj.target/deps/v8/gypfiles/libv8_base.a + +libopenssl.bc: ${SRC}/node + get-bc -b -o libopenssl.bc ${SRC}/out/Release/obj.target/deps/openssl/libopenssl.a + +node_main.bc: ${SRC}/node + get-bc -b -o node_main.bc ${SRC}/out/Release/obj.target/node/src/node_main.o + +libv8_libplatform.bc: ${SRC}/node + get-bc -b -o libv8_libplatform.bc ${SRC}/out/Release/obj.target/deps/v8/gypfiles/libv8_libplatform.a + +libicui18n.bc: ${SRC}/node + get-bc -b -o libicui18n.bc ${SRC}/out/Release/obj.target/tools/icu/libicui18n.a + +libhttp_parser.bc: ${SRC}/node + get-bc -b -o libhttp_parser.bc ${SRC}/out/Release/obj.target/deps/http_parser/libhttp_parser.a + +libcares.bc: ${SRC}/node + get-bc -b -o libcares.bc ${SRC}/out/Release/obj.target/deps/cares/libcares.a + +libnghttp2.bc: ${SRC}/node + get-bc -b -o libnghttp2.bc ${SRC}/out/Release/obj.target/deps/nghttp2/libnghttp2.a + +libbrotili.bc: ${SRC}/node + get-bc -b -o libbrotli.bc ${SRC}/out/Release/obj.target/deps/brotli/libbrotli.a + +libv8_libbase.bc: ${SRC}/node + get-bc -b -o libv8_libbase.bc ${SRC}/out/Release/obj.target/deps/v8/gypfiles/libv8_libbase.a + +libv8_sampler.bc: ${SRC}/node + get-bc -b -o libv8_libsampler.bc ${SRC}/out/Release/obj.target/deps/v8/gypfiles/libv8_libsampler.a + +libicuucx.bc: ${SRC}/node + get-bc -b -o libicuucx.bc ${SRC}/out/Release/obj.target/tools/icu/libicuucx.a + +libicudata.bc: ${SRC}/node + get-bc -b -o libicudata.bc ${SRC}/out/Release/obj.target/tools/icu/libicudata.a + +libicustubdata.bc: ${SRC}/node + get-bc -b -o libicustubdata.bc ${SRC}/out/Release/obj.target/tools/icu/libicustubdata.a + +libv8_snapshot.bc: ${SRC}/node + get-bc -b -o libv8_snapshot.bc ${SRC}/out/Release/obj.target/deps/v8/gypfiles/libv8_snapshot.a + +node_from_bitcode: bitcode + clang++ -o node_from_bitcode -pthread -rdynamic -m64 node_main.bc libnode.bc libv8_libplatform.bc libicui18n.bc libzlib.bc libhttp_parser.bc libcares.bc libuv.bc libnghttp2.bc libbrotli.bc libopenssl.bc libv8_base.bc libv8_libbase.bc libv8_libsampler.bc libicuucx.bc libicudata.bc libicustubdata.bc libv8_snapshot.bc -ldl -lrt -lm + clean: make -C ${SRC} clean diff --git a/shared/environment.go b/shared/environment.go index ea75411..538ac04 100644 --- a/shared/environment.go +++ b/shared/environment.go @@ -98,21 +98,7 @@ const ( ) func init() { - - LLVMToolChainBinDir = os.Getenv(envpath) - LLVMCCName = os.Getenv(envcc) - LLVMCXXName = os.Getenv(envcxx) - LLVMARName = os.Getenv(envar) - LLVMLINKName = os.Getenv(envlnk) - - LLVMConfigureOnly = os.Getenv(envcfg) - LLVMBitcodeStorePath = os.Getenv(envbc) - - LLVMLoggingLevel = os.Getenv(envlvl) - LLVMLoggingFile = os.Getenv(envfile) - - LLVMObjcopy = os.Getenv(envobjcopy) - LLVMLd = os.Getenv(envld) + FetchEnvironment() } func printEnvironment() { @@ -129,3 +115,21 @@ func printEnvironment() { } } + +// used in testing +func FetchEnvironment() { + LLVMToolChainBinDir = os.Getenv(envpath) + LLVMCCName = os.Getenv(envcc) + LLVMCXXName = os.Getenv(envcxx) + LLVMARName = os.Getenv(envar) + LLVMLINKName = os.Getenv(envlnk) + + LLVMConfigureOnly = os.Getenv(envcfg) + LLVMBitcodeStorePath = os.Getenv(envbc) + + LLVMLoggingLevel = os.Getenv(envlvl) + LLVMLoggingFile = os.Getenv(envfile) + + LLVMObjcopy = os.Getenv(envobjcopy) + LLVMLd = os.Getenv(envld) +} diff --git a/shared/extractor.go b/shared/extractor.go index 85dab9e..a102283 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -51,7 +51,7 @@ import ( ) //for distilling the desired commandline options -type extractionArgs struct { +type ExtractionArgs struct { Failure bool // indicates failure in parsing the cmd line args Verbose bool // inform the user of what is going on WriteManifest bool // write a manifest of bitcode files used @@ -71,7 +71,7 @@ type extractionArgs struct { } //for printing out the parsed arguments, some have been skipped. -func (ea extractionArgs) String() string { +func (ea ExtractionArgs) String() string { format := ` ea.Verbose: %v @@ -91,7 +91,7 @@ ea.ArchiverName: %v ea.LlvmLinkerName, ea.ArchiverName) } -func parseSwitches(args []string) (ea extractionArgs) { +func ParseSwitches(args []string) (ea ExtractionArgs) { var flagSet *flag.FlagSet = flag.NewFlagSet(args[0], flag.ContinueOnError) @@ -146,7 +146,7 @@ func Extract(args []string) (exitCode int) { exitCode = 1 - ea := parseSwitches(args) + ea := ParseSwitches(args) if ea.Failure { return @@ -187,7 +187,7 @@ func Extract(args []string) (exitCode int) { } // Set arguments according to runtime OS -func setPlatform(ea *extractionArgs) (success bool) { +func setPlatform(ea *ExtractionArgs) (success bool) { switch platform := runtime.GOOS; platform { case osFREEBSD, osLINUX: ea.Extractor = extractSectionUnix @@ -213,7 +213,7 @@ func setPlatform(ea *extractionArgs) (success bool) { } // Create output filename if not given -func setOutputFile(ea *extractionArgs) { +func setOutputFile(ea *ExtractionArgs) { if ea.OutputFile == "" { if ea.InputType == fileTypeARCHIVE || ea.InputType == fileTypeTHINARCHIVE { var ext string @@ -256,7 +256,7 @@ func resolveTool(defaultPath string, envPath string, usrPath string) (path strin } -func handleExecutable(ea extractionArgs) (success bool) { +func handleExecutable(ea ExtractionArgs) (success bool) { // get the list of bitcode paths artifactPaths := ea.Extractor(ea.InputFile) @@ -291,7 +291,7 @@ func handleExecutable(ea extractionArgs) (success bool) { return } -func handleThinArchive(ea extractionArgs) (success bool) { +func handleThinArchive(ea ExtractionArgs) (success bool) { // List bitcode files to link var artifactFiles []string @@ -300,7 +300,7 @@ func handleThinArchive(ea extractionArgs) (success bool) { objectFiles = listArchiveFiles(ea, ea.InputFile) - LogInfo("handleThinArchive: extractionArgs = %v\nobjectFiles = %v\n", ea, objectFiles) + LogInfo("handleThinArchive: ExtractionArgs = %v\nobjectFiles = %v\n", ea, objectFiles) for index, obj := range objectFiles { LogInfo("obj = '%v'\n", obj) @@ -353,7 +353,7 @@ func handleThinArchive(ea extractionArgs) (success bool) { return } -func listArchiveFiles(ea extractionArgs, inputFile string) (contents []string) { +func listArchiveFiles(ea ExtractionArgs, inputFile string) (contents []string) { var arArgs []string arArgs = append(arArgs, "-t") arArgs = append(arArgs, inputFile) @@ -367,7 +367,7 @@ func listArchiveFiles(ea extractionArgs, inputFile string) (contents []string) { return } -func extractFile(ea extractionArgs, archive string, filename string, instance int) (success bool) { +func extractFile(ea ExtractionArgs, archive string, filename string, instance int) (success bool) { var arArgs []string if runtime.GOOS != osDARWIN { arArgs = append(arArgs, "xN") @@ -390,7 +390,7 @@ func extractFile(ea extractionArgs, archive string, filename string, instance in return } -func fetchTOC(ea extractionArgs, inputFile string) map[string]int { +func fetchTOC(ea ExtractionArgs, inputFile string) map[string]int { toc := make(map[string]int) contents := listArchiveFiles(ea, inputFile) @@ -418,14 +418,14 @@ func fetchTOC(ea extractionArgs, inputFile string) map[string]int { // archive using llvm-ar // //iam: 5/1/2018 -func handleArchive(ea extractionArgs) (success bool) { +func handleArchive(ea ExtractionArgs) (success bool) { // List bitcode files to link var bcFiles []string var artifactFiles []string inputFile, _ := filepath.Abs(ea.InputFile) - LogInfo("handleArchive: extractionArgs = %v\n", ea) + LogInfo("handleArchive: ExtractionArgs = %v\n", ea) // Create tmp dir tmpDirName, err := ioutil.TempDir("", "gllvm") @@ -511,7 +511,7 @@ func handleArchive(ea extractionArgs) (success bool) { return } -func archiveBcFiles(ea extractionArgs, bcFiles []string) (success bool) { +func archiveBcFiles(ea ExtractionArgs, bcFiles []string) (success bool) { // We do not want full paths in the archive, so we need to chdir into each // bitcode's folder. Handle this by calling llvm-ar once for all bitcode // files in the same directory @@ -554,7 +554,7 @@ func formatStdOut(stdout bytes.Buffer, usefulIndex int) string { return ret[0] } -func fetchArgMax(ea extractionArgs) (argMax int) { +func fetchArgMax(ea ExtractionArgs) (argMax int) { if ea.LinkArgSize == 0 { getArgMax := exec.Command("getconf", "ARG_MAX") var argMaxStr bytes.Buffer @@ -575,7 +575,7 @@ func fetchArgMax(ea extractionArgs) (argMax int) { return } -func linkBitcodeFilesIncrementally(ea extractionArgs, filesToLink []string, argMax int, linkArgs []string) (success bool) { +func linkBitcodeFilesIncrementally(ea ExtractionArgs, filesToLink []string, argMax int, linkArgs []string) (success bool) { var tmpFileList []string // Create tmp dir tmpDirName, err := ioutil.TempDir(".", "glinking") @@ -649,7 +649,7 @@ func linkBitcodeFilesIncrementally(ea extractionArgs, filesToLink []string, argM return } -func linkBitcodeFiles(ea extractionArgs, filesToLink []string) (success bool) { +func linkBitcodeFiles(ea ExtractionArgs, filesToLink []string) (success bool) { var linkArgs []string // Extracting the command line max size from the environment if it is not specified argMax := fetchArgMax(ea) @@ -732,7 +732,7 @@ func resolveBitcodePath(bcPath string) string { return bcPath } -func writeManifest(ea extractionArgs, bcFiles []string, artifactFiles []string) (success bool) { +func writeManifest(ea ExtractionArgs, bcFiles []string, artifactFiles []string) (success bool) { manifestFilename := ea.OutputFile + ".llvm.manifest" //only go into the gory details if we have a store around. if LLVMBitcodeStorePath != "" { diff --git a/tests/entry_test.go b/tests/entry_test.go index aaa7632..89cd4bb 100644 --- a/tests/entry_test.go +++ b/tests/entry_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -func Test_basic(t *testing.T) { +func Test_basic_functionality(t *testing.T) { args := []string{"../data/helloworld.c", "-o", "../data/hello"} exitCode := shared.Compile(args, "clang") diff --git a/tests/env_and_arg_test.go b/tests/env_and_arg_test.go new file mode 100644 index 0000000..549cb3f --- /dev/null +++ b/tests/env_and_arg_test.go @@ -0,0 +1,87 @@ +package test + +import ( + "fmt" + "os" + "github.com/SRI-CSL/gllvm/shared" + "testing" +) + +const ( + verbose = false +) + +func checkExecutables(t *testing.T, ea shared.ExtractionArgs, + llvmLinker string, llvmArchiver string, archiver string, + clang string, clangpp string){ + if ea.LlvmLinkerName != llvmLinker { + t.Errorf("ParseSwitches: LlvmLinkerName incorrect: %v\n", ea.LlvmLinkerName) + } + if ea.LlvmArchiverName != llvmArchiver { + t.Errorf("ParseSwitches: LlvmArchiverName incorrect: %v\n", ea.LlvmArchiverName) + } + if ea.ArchiverName != archiver { + t.Errorf("ParseSwitches: ArchiverName incorrect: %v\n", ea.ArchiverName) + } + + eclang := shared.GetCompilerExecName("clang") + if eclang != clang { + t.Errorf("C compiler not correct: %v\n", eclang) + } + eclangpp := shared.GetCompilerExecName("clang++") + if eclangpp != clangpp { + t.Errorf("C++ compiler not correct: %v\n", eclangpp) + } + if verbose { + fmt.Printf("\nParseSwitches: %v\nclang = %v\nclang++ = %v\n", ea, clang, clangpp) + } +} + +func Test_env_and_args(t *testing.T) { + + args := []string{"get-bc", "-v", "../data/hello"} + + ea := shared.ParseSwitches(args) + if !ea.Verbose { + t.Errorf("ParseSwitches: -v flag not working\n") + } + if ea.WriteManifest || ea.SortBitcodeFiles || ea.BuildBitcodeModule || ea.KeepTemp { + t.Errorf("ParseSwitches: defaults not correct\n") + } + if ea.InputFile != "../data/hello" { + t.Errorf("ParseSwitches: InputFile incorrect: %v\n", ea.InputFile) + } + + checkExecutables(t, ea, "llvm-link", "llvm-ar", "ar", "clang", "clang++") + + os.Setenv("LLVM_COMPILER_PATH", "/the_future_is_here") + os.Setenv("LLVM_CC_NAME", "clang-666") + os.Setenv("LLVM_CXX_NAME", "clang++-666") + os.Setenv("LLVM_LINK_NAME", "llvm-link-666") + os.Setenv("LLVM_AR_NAME", "llvm-ar-666") + + shared.FetchEnvironment() + + ea = shared.ParseSwitches(args) + + checkExecutables(t, ea, + "/the_future_is_here/llvm-link-666", + "/the_future_is_here/llvm-ar-666", + "ar", + "/the_future_is_here/clang-666", + "/the_future_is_here/clang++-666") + + args = []string{"get-bc", "-a", "llvm-ar-665", "-l", "llvm-link-665", "../data/hello"} + + ea = shared.ParseSwitches(args) + + checkExecutables(t, ea, + "llvm-link-665", + "llvm-ar-665", + "ar", + "/the_future_is_here/clang-666", + "/the_future_is_here/clang++-666") + + + +}