mirror of
https://github.com/danog/gllvm.git
synced 2024-11-30 05:59:02 +01:00
Two fallbacks in place in case we do not recognize the file extension of an object file
This commit is contained in:
parent
9f0092874f
commit
62c0620028
@ -149,8 +149,27 @@ func attachBitcodePathToObject(bcFile, objFile string) (success bool) {
|
||||
".po": //iam: profiled object
|
||||
LogDebug("attachBitcodePathToObject recognized %v as something it can inject into.\n", extension)
|
||||
success = injectPath(extension, bcFile, objFile)
|
||||
return
|
||||
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
|
||||
}
|
||||
|
@ -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).
|
||||
// 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 gllvmReleaseDate = "October 30 2020"
|
||||
|
@ -138,7 +138,7 @@ func ParseSwitches(args []string) (ea ExtractionArgs) {
|
||||
return
|
||||
}
|
||||
ea.InputFile = realPath
|
||||
ea.InputType = getFileType(realPath)
|
||||
ea.InputType, _ = getFileType(realPath)
|
||||
|
||||
LogInfo("%v", ea)
|
||||
|
||||
|
@ -34,7 +34,11 @@
|
||||
package shared
|
||||
|
||||
import (
|
||||
"debug/elf"
|
||||
"debug/macho"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -56,13 +60,15 @@ const (
|
||||
//iam:
|
||||
// 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)
|
||||
func getFileType(realPath string) (fileType int) {
|
||||
func getFileType(realPath string) (fileType int, err error) {
|
||||
|
||||
// We need the file command to guess the file type
|
||||
fileType = fileTypeERROR
|
||||
err = nil
|
||||
cmd := exec.Command("file", realPath)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
LogError("There was an error getting the type of %s. Make sure that the 'file' command is installed.", realPath)
|
||||
fileType = fileTypeERROR
|
||||
return
|
||||
}
|
||||
|
||||
@ -101,3 +107,71 @@ func getFileType(realPath string) (fileType int) {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -381,8 +381,7 @@ func Parse(argList []string) ParserResult {
|
||||
{`^-stdlib=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}},
|
||||
{`^-mtune=.+$`, flagInfo{0, pr.compileUnaryCallback}},
|
||||
{`^--sysroot=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}}, //both compile and link time
|
||||
{`^-print-prog-name=.*$`, flagInfo{0, pr.compileUnaryCallback}},
|
||||
{`^-print-file-name=.*$`, flagInfo{0, pr.compileUnaryCallback}},
|
||||
{`^-print-.*$`, flagInfo{0, pr.compileUnaryCallback}}, // generic catch all for the print commands
|
||||
{`^-mmacosx-version-min=.+$`, flagInfo{0, pr.compileLinkUnaryCallback}},
|
||||
{`^-mstack-alignment=.+$`, flagInfo{0, pr.compileUnaryCallback}}, //iam, linux kernel stuff
|
||||
{`^-march=.+$`, flagInfo{0, pr.compileUnaryCallback}}, //iam: linux kernel stuff
|
||||
|
@ -4,27 +4,53 @@ import (
|
||||
"fmt"
|
||||
"github.com/SRI-CSL/gllvm/shared"
|
||||
"testing"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func Test_basic_functionality(t *testing.T) {
|
||||
args := []string{"../data/helloworld.c", "-o", "../data/hello"}
|
||||
|
||||
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/hello"}
|
||||
|
||||
exitCode = shared.Extract(args)
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Errorf("Extraction of %v returned %v\n", args, exitCode)
|
||||
} else {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user