From 3d3264fd14088592f4baba91ac727db549e3bbb7 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Mon, 3 Aug 2020 16:41:28 -0400 Subject: [PATCH 1/7] extractor: Make extraction errors fatal --- shared/extractor.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/shared/extractor.go b/shared/extractor.go index c4b97db..8acd3d6 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -257,7 +257,10 @@ func resolveTool(defaultPath string, envPath string, usrPath string) (path strin func handleExecutable(ea ExtractionArgs) (success bool) { // get the list of bitcode paths - artifactPaths := ea.Extractor(ea.InputFile) + artifactPaths, success := ea.Extractor(ea.InputFile) + if !success { + return + } if len(artifactPaths) < 20 { // naert: to avoid saturating the log when dealing with big file lists @@ -671,40 +674,46 @@ func linkBitcodeFiles(ea ExtractionArgs, filesToLink []string) (success bool) { return } -func extractSectionDarwin(inputFile string) (contents []string) { +func extractSectionDarwin(inputFile string) (contents []string, success bool) { machoFile, err := macho.Open(inputFile) if err != nil { LogError("Mach-O file %s could not be read.", inputFile) + success = false return } section := machoFile.Section(DarwinSectionName) if section == nil { - LogWarning("The %s section of %s is missing!\n", DarwinSectionName, inputFile) + LogError("The %s section of %s is missing!\n", DarwinSectionName, inputFile) + success = false return } sectionContents, errContents := section.Data() if errContents != nil { - LogWarning("Error reading the %s section of Mach-O file %s.", DarwinSectionName, inputFile) + LogError("Error reading the %s section of Mach-O file %s.", DarwinSectionName, inputFile) + success = false return } contents = strings.Split(strings.TrimSuffix(string(sectionContents), "\n"), "\n") return } -func extractSectionUnix(inputFile string) (contents []string) { +func extractSectionUnix(inputFile string) (contents []string, success bool) { elfFile, err := elf.Open(inputFile) if err != nil { LogError("ELF file %s could not be read.", inputFile) + success = false return } section := elfFile.Section(ELFSectionName) if section == nil { - LogWarning("Error reading the %s section of ELF file %s.", ELFSectionName, inputFile) + LogError("Error reading the %s section of ELF file %s.", ELFSectionName, inputFile) + success = false return } sectionContents, errContents := section.Data() if errContents != nil { - LogWarning("Error reading the %s section of ELF file %s.", ELFSectionName, inputFile) + LogError("Error reading the %s section of ELF file %s.", ELFSectionName, inputFile) + success = false return } contents = strings.Split(strings.TrimSuffix(string(sectionContents), "\n"), "\n") From 6ca36df5db435d0290af890f81f92ccdce3f375c Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Mon, 3 Aug 2020 16:46:52 -0400 Subject: [PATCH 2/7] extractor: Fix Extractor signature --- shared/extractor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/extractor.go b/shared/extractor.go index 8acd3d6..6a96adb 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -67,7 +67,7 @@ type ExtractionArgs struct { LlvmArchiverName string ArchiverName string ArArgs []string - Extractor func(string) []string + Extractor func(string) ([]string, bool) } //for printing out the parsed arguments, some have been skipped. From eb5c783f2c0c44f0022d7ec55b31164f3f0a9e94 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Mon, 3 Aug 2020 16:55:38 -0400 Subject: [PATCH 3/7] extractor: Fix other assigns --- shared/extractor.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/shared/extractor.go b/shared/extractor.go index 6a96adb..d6dc2a2 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -307,7 +307,10 @@ func handleThinArchive(ea ExtractionArgs) (success bool) { for index, obj := range objectFiles { LogInfo("obj = '%v'\n", obj) if len(obj) > 0 { - artifacts := ea.Extractor(obj) + artifacts, success := ea.Extractor(obj) + if !success { + return + } LogInfo("\t%v\n", artifacts) artifactFiles = append(artifactFiles, artifacts...) for _, bc := range artifacts { @@ -460,7 +463,10 @@ func handleArchive(ea ExtractionArgs) (success bool) { if obj != "" && extractFile(ea, inputFile, obj, i) { - artifacts := ea.Extractor(obj) + artifacts, success := ea.Extractor(obj) + if !success { + return + } LogInfo("\t%v\n", artifacts) artifactFiles = append(artifactFiles, artifacts...) for _, bc := range artifacts { From 3a0cea8f371c6cf2b601a90243815c52263a23d7 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 4 Aug 2020 09:43:46 -0400 Subject: [PATCH 4/7] extractor: Fix success shadowing --- shared/extractor.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/shared/extractor.go b/shared/extractor.go index d6dc2a2..451f411 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -257,7 +257,8 @@ func resolveTool(defaultPath string, envPath string, usrPath string) (path strin func handleExecutable(ea ExtractionArgs) (success bool) { // get the list of bitcode paths - artifactPaths, success := ea.Extractor(ea.InputFile) + var artifactPaths []string + artifactPaths, success = ea.Extractor(ea.InputFile) if !success { return } @@ -307,7 +308,8 @@ func handleThinArchive(ea ExtractionArgs) (success bool) { for index, obj := range objectFiles { LogInfo("obj = '%v'\n", obj) if len(obj) > 0 { - artifacts, success := ea.Extractor(obj) + var artifacts []string + artifacts, success = ea.Extractor(obj) if !success { return } @@ -462,8 +464,8 @@ func handleArchive(ea ExtractionArgs) (success bool) { for i := 1; i <= instance; i++ { if obj != "" && extractFile(ea, inputFile, obj, i) { - - artifacts, success := ea.Extractor(obj) + var artifacts []string + artifacts, success = ea.Extractor(obj) if !success { return } From d235e663df35a651d8f13aef0cb762da252376ca Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 4 Aug 2020 10:22:40 -0400 Subject: [PATCH 5/7] get-bc: exit with Extract()'s exit code --- cmd/get-bc/main.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/get-bc/main.go b/cmd/get-bc/main.go index 23aca14..fa6203f 100644 --- a/cmd/get-bc/main.go +++ b/cmd/get-bc/main.go @@ -42,11 +42,9 @@ func main() { // Parse command line var args = os.Args - shared.Extract(args) + exitCode := shared.Extract(args) shared.LogInfo("Calling %v DID NOT TELL US WHAT HAPPENED\n", os.Args) - // could be more honest about our success here - os.Exit(0) - + os.Exit(exitCode) } From 3389f1fde6a3bec96d25edce5de5fa96e18075d7 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 4 Aug 2020 10:48:02 -0400 Subject: [PATCH 6/7] extractor: Fix success assignment Booleans are default-initialized to false, so we only need to assign to true in the success case. --- shared/extractor.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/shared/extractor.go b/shared/extractor.go index 451f411..2cb6de9 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -686,22 +686,20 @@ func extractSectionDarwin(inputFile string) (contents []string, success bool) { machoFile, err := macho.Open(inputFile) if err != nil { LogError("Mach-O file %s could not be read.", inputFile) - success = false return } section := machoFile.Section(DarwinSectionName) if section == nil { LogError("The %s section of %s is missing!\n", DarwinSectionName, inputFile) - success = false return } sectionContents, errContents := section.Data() if errContents != nil { LogError("Error reading the %s section of Mach-O file %s.", DarwinSectionName, inputFile) - success = false return } contents = strings.Split(strings.TrimSuffix(string(sectionContents), "\n"), "\n") + success = true return } @@ -709,22 +707,20 @@ func extractSectionUnix(inputFile string) (contents []string, success bool) { elfFile, err := elf.Open(inputFile) if err != nil { LogError("ELF file %s could not be read.", inputFile) - success = false return } section := elfFile.Section(ELFSectionName) if section == nil { LogError("Error reading the %s section of ELF file %s.", ELFSectionName, inputFile) - success = false return } sectionContents, errContents := section.Data() if errContents != nil { LogError("Error reading the %s section of ELF file %s.", ELFSectionName, inputFile) - success = false return } contents = strings.Split(strings.TrimSuffix(string(sectionContents), "\n"), "\n") + success = true return } From c14c8e6d736f9b3fb3aab2094b85f3a13472f3a3 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 4 Aug 2020 12:59:52 -0400 Subject: [PATCH 7/7] extractor: Add a "strict extraction" mode The more permissive current behavior remains the default. --- shared/extractor.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/shared/extractor.go b/shared/extractor.go index 2cb6de9..d15b634 100644 --- a/shared/extractor.go +++ b/shared/extractor.go @@ -58,6 +58,7 @@ type ExtractionArgs struct { SortBitcodeFiles bool // sort the arguments to linking and archiving (debugging too) BuildBitcodeModule bool // buld an archive rather than a module KeepTemp bool // keep temporary linking folder + StrictExtract bool // turn extraction failures into errors LinkArgSize int // maximum size of a llvm-link command line InputType int ObjectTypeInArchive int // Type of file that can be put into an archive @@ -85,10 +86,11 @@ ea.OutputFile: %v ea.LlvmArchiverName: %v ea.LlvmLinkerName: %v ea.ArchiverName: %v +ea.StrictExtract: %v ` return fmt.Sprintf(format, ea.Verbose, ea.WriteManifest, ea.SortBitcodeFiles, ea.BuildBitcodeModule, ea.KeepTemp, ea.LinkArgSize, ea.InputFile, ea.OutputFile, ea.LlvmArchiverName, - ea.LlvmLinkerName, ea.ArchiverName) + ea.LlvmLinkerName, ea.ArchiverName, ea.StrictExtract) } //ParseSwitches parses the command line into an ExtractionArgs object. @@ -106,6 +108,7 @@ func ParseSwitches(args []string) (ea ExtractionArgs) { flagSet.StringVar(&ea.LlvmLinkerName, "l", "llvm-link", "the llvm linker (i.e. llvm-link)") flagSet.IntVar(&ea.LinkArgSize, "n", 0, "maximum llvm-link command line size (in bytes)") flagSet.BoolVar(&ea.KeepTemp, "t", false, "keep temporary linking folder") + flagSet.BoolVar(&ea.StrictExtract, "S", false, "exit with an error if extraction fails") err := flagSet.Parse(args[1:]) @@ -259,7 +262,7 @@ func handleExecutable(ea ExtractionArgs) (success bool) { // get the list of bitcode paths var artifactPaths []string artifactPaths, success = ea.Extractor(ea.InputFile) - if !success { + if !success && ea.StrictExtract { return } @@ -310,7 +313,7 @@ func handleThinArchive(ea ExtractionArgs) (success bool) { if len(obj) > 0 { var artifacts []string artifacts, success = ea.Extractor(obj) - if !success { + if !success && ea.StrictExtract { return } LogInfo("\t%v\n", artifacts) @@ -466,7 +469,7 @@ func handleArchive(ea ExtractionArgs) (success bool) { if obj != "" && extractFile(ea, inputFile, obj, i) { var artifacts []string artifacts, success = ea.Extractor(obj) - if !success { + if !success && ea.StrictExtract { return } LogInfo("\t%v\n", artifacts)