Two fallbacks in place in case we do not recognize the file extension of an object file

This commit is contained in:
Ian A Mason 2020-10-30 22:04:23 +00:00
parent 9f0092874f
commit 62c0620028
6 changed files with 132 additions and 13 deletions

View File

@ -149,8 +149,27 @@ func attachBitcodePathToObject(bcFile, objFile string) (success bool) {
".po": //iam: profiled object ".po": //iam: profiled object
LogDebug("attachBitcodePathToObject recognized %v as something it can inject into.\n", extension) LogDebug("attachBitcodePathToObject recognized %v as something it can inject into.\n", extension)
success = injectPath(extension, bcFile, objFile) success = injectPath(extension, bcFile, objFile)
return
default: default:
LogWarning("attachBitcodePathToObject ignoring unrecognized extension: %v\n", extension) //OK we have to work harder here
ok, err := injectableViaFileType(objFile)
if ok {
success = injectPath(extension, bcFile, objFile)
return
}
if err != nil {
// OK we have to work EVEN harder here (the file utility is not installed - probably)
// N.B. this will probably fail if we are cross compiling.
ok, err = injectableViaDebug(objFile)
if ok {
success = injectPath(extension, bcFile, objFile)
return
}
if err != nil {
LogWarning("attachBitcodePathToObject: injectableViaDebug failed %v", err)
}
}
LogWarning("attachBitcodePathToObject ignoring unrecognized extension %v of file %v of unknown type\n", extension, objFile)
} }
return return
} }

View File

@ -56,7 +56,8 @@ package shared
// //
// 1.2.8 October 13 2020 Wensheng Tang's (@legendtang) requests and fixes to the -flto issues (issue #39). // 1.2.8 October 13 2020 Wensheng Tang's (@legendtang) requests and fixes to the -flto issues (issue #39).
// Added support for the LTO_LINKING_FLAGS environment variable. // Added support for the LTO_LINKING_FLAGS environment variable.
// 1.2.9 October 30 2020 FreeBSD bug fixes (@arrowd) (issue #41) // 1.2.9 October 30 2020 Gleb Popov's FreeBSD bug fixes (@arrowd) (issue #41), plus some more improvements
// to the command line parsing (a never ending saga).
const gllvmVersion = "1.2.9" const gllvmVersion = "1.2.9"
const gllvmReleaseDate = "October 30 2020" const gllvmReleaseDate = "October 30 2020"

View File

@ -138,7 +138,7 @@ func ParseSwitches(args []string) (ea ExtractionArgs) {
return return
} }
ea.InputFile = realPath ea.InputFile = realPath
ea.InputType = getFileType(realPath) ea.InputType, _ = getFileType(realPath)
LogInfo("%v", ea) LogInfo("%v", ea)

View File

@ -34,7 +34,11 @@
package shared package shared
import ( import (
"debug/elf"
"debug/macho"
"os"
"os/exec" "os/exec"
"runtime"
"strings" "strings"
) )
@ -56,13 +60,15 @@ const (
//iam: //iam:
// this is not that robust, because it depends on the file utility "file" which is // this is not that robust, because it depends on the file utility "file" which is
// often missing on docker images (the klee doker file had this problem) // often missing on docker images (the klee doker file had this problem)
func getFileType(realPath string) (fileType int) { func getFileType(realPath string) (fileType int, err error) {
// We need the file command to guess the file type // We need the file command to guess the file type
fileType = fileTypeERROR
err = nil
cmd := exec.Command("file", realPath) cmd := exec.Command("file", realPath)
out, err := cmd.Output() out, err := cmd.Output()
if err != nil { if err != nil {
LogError("There was an error getting the type of %s. Make sure that the 'file' command is installed.", realPath) LogError("There was an error getting the type of %s. Make sure that the 'file' command is installed.", realPath)
fileType = fileTypeERROR
return return
} }
@ -101,3 +107,71 @@ func getFileType(realPath string) (fileType int) {
} }
return return
} }
// isPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
func isPlainFile(objectFile string) (ok bool) {
ok = false
info, err := os.Stat(objectFile)
if os.IsNotExist(err) || info.IsDir() {
return
}
if err != nil {
return
}
ok = true
return
}
func injectableViaFileType(objectFile string) (ok bool, err error) {
ok = false
err = nil
plain := isPlainFile(objectFile)
if !plain {
return
}
fileType, err := getFileType(objectFile)
if err != nil {
return
}
ok = (fileType == fileTypeELFOBJECT) || (fileType == fileTypeELFOBJECT)
return
}
func injectableViaDebug(objectFile string) (ok bool, err error) {
ok = false
err = nil
// I guess we are not doing cross compiling. Otherwise we are fucking up here.
ok, err = IsObjectFileForOS(objectFile, runtime.GOOS)
return
}
//IsObjectFileForOS returns true if the given file is an object file for the given OS, using the debug/elf and debug/macho packages.
func IsObjectFileForOS(objectFile string, operatingSys string) (ok bool, err error) {
plain := isPlainFile(objectFile)
if !plain {
return
}
switch operatingSys {
case "linux", "freebsd":
var lbinFile *elf.File
lbinFile, err = elf.Open(objectFile)
if err != nil {
return
}
dfileType := lbinFile.FileHeader.Type
ok = (dfileType == elf.ET_REL)
return
case "darwin":
var dbinFile *macho.File
dbinFile, err = macho.Open(objectFile)
if err != nil {
return
}
dfileType := dbinFile.FileHeader.Type
ok = (dfileType == macho.TypeObj)
return
}
return
}

View File

@ -381,8 +381,7 @@ func Parse(argList []string) ParserResult {
{`^-stdlib=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}}, {`^-stdlib=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}},
{`^-mtune=.+$`, flagInfo{0, pr.compileUnaryCallback}}, {`^-mtune=.+$`, flagInfo{0, pr.compileUnaryCallback}},
{`^--sysroot=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}}, //both compile and link time {`^--sysroot=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}}, //both compile and link time
{`^-print-prog-name=.*$`, flagInfo{0, pr.compileUnaryCallback}}, {`^-print-.*$`, flagInfo{0, pr.compileUnaryCallback}}, // generic catch all for the print commands
{`^-print-file-name=.*$`, flagInfo{0, pr.compileUnaryCallback}},
{`^-mmacosx-version-min=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}}, {`^-mmacosx-version-min=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}},
{`^-mstack-alignment=.+$`, flagInfo{0, pr.compileUnaryCallback}}, //iam, linux kernel stuff {`^-mstack-alignment=.+$`, flagInfo{0, pr.compileUnaryCallback}}, //iam, linux kernel stuff
{`^-march=.+$`, flagInfo{0, pr.compileUnaryCallback}}, //iam: linux kernel stuff {`^-march=.+$`, flagInfo{0, pr.compileUnaryCallback}}, //iam: linux kernel stuff

View File

@ -4,27 +4,53 @@ import (
"fmt" "fmt"
"github.com/SRI-CSL/gllvm/shared" "github.com/SRI-CSL/gllvm/shared"
"testing" "testing"
"runtime"
) )
func Test_basic_functionality(t *testing.T) { func Test_basic_functionality(t *testing.T) {
args := []string{"../data/helloworld.c", "-o", "../data/hello"} args := []string{"../data/helloworld.c", "-o", "../data/hello"}
exitCode := shared.Compile(args, "clang") exitCode := shared.Compile(args, "clang")
if exitCode != 0 { if exitCode != 0 {
t.Errorf("Compile of %v returned %v\n", args, exitCode) t.Errorf("Compile of %v returned %v\n", args, exitCode)
} else { } else {
fmt.Println("Compiled OK") fmt.Println("Compiled OK")
} }
args = []string{"get-bc", "-v", "../data/hello"} args = []string{"get-bc", "-v", "../data/hello"}
exitCode = shared.Extract(args) exitCode = shared.Extract(args)
if exitCode != 0 { if exitCode != 0 {
t.Errorf("Extraction of %v returned %v\n", args, exitCode) t.Errorf("Extraction of %v returned %v\n", args, exitCode)
} else { } else {
fmt.Println("Extraction OK") fmt.Println("Extraction OK")
} }
}
func Test_more_functionality(t *testing.T) {
objectFile := "../data/bhello.o"
args := []string{"../data/helloworld.c", "-c", "-o", objectFile}
exitCode := shared.Compile(args, "clang")
if exitCode != 0 {
t.Errorf("Compile of %v returned %v\n", args, exitCode)
} else {
fmt.Println("Compiled OK")
}
ok, err := shared.IsObjectFileForOS(objectFile, runtime.GOOS)
if !ok {
t.Errorf("isObjectFileForOS(%v, %v) = %v (err = %v)\n", objectFile, runtime.GOOS, ok, err)
} else {
fmt.Printf("isObjectFileForOS(%v, %v) = %v\n", objectFile, runtime.GOOS, ok)
}
args = []string{objectFile, "-o", "../data/bhello"}
exitCode = shared.Compile(args, "clang")
if exitCode != 0 {
t.Errorf("Compile of %v returned %v\n", args, exitCode)
} else {
fmt.Println("Compiled OK")
}
args = []string{"get-bc", "-v", "../data/bhello"}
exitCode = shared.Extract(args)
if exitCode != 0 {
t.Errorf("Extraction of %v returned %v\n", args, exitCode)
} else {
fmt.Println("Extraction OK")
}
} }