Skip to content

Commit 24dc445

Browse files
committed
New version. Trick or treat.
1 parent 34edd90 commit 24dc445

File tree

2 files changed

+134
-77
lines changed

2 files changed

+134
-77
lines changed

shared/constants.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,12 @@ package shared
5656
//
5757
// 1.2.8 October 13 2020 Wensheng Tang's (@legendtang) requests and fixes to the -flto issues (issue #39).
5858
// Added support for the LTO_LINKING_FLAGS environment variable.
59-
// 1.2.9 October 30 2020 Gleb Popov's FreeBSD bug fixes (@arrowd) (issue #41), plus some more improvements
59+
// 1.2.9 October 31 2020 Gleb Popov's FreeBSD bug fixes (@arrowd) (issue #41), plus some more improvements
6060
// to the command line parsing (a never ending saga), including the golang packages
61-
// debug/elf and debug/macho to spot object files..
61+
// debug/elf and debug/macho to spot object files...
6262

6363
const gllvmVersion = "1.2.9"
64-
const gllvmReleaseDate = "October 30 2020"
64+
const gllvmReleaseDate = "October 31 (Halloween) 2020"
6565

6666
const osDARWIN = "darwin"
6767
const osLINUX = "linux"

shared/filetypes.go

Lines changed: 131 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,134 @@ import (
4242
"strings"
4343
)
4444

45+
//BinaryType is the 'intersection' of elf.Type and macho.Type and partitions
46+
// the binary world into categories we are most interested in. Missing is
47+
// ARCHIVE but that is because it is not an elf format, so we cannot entirely
48+
// eliminate the use of the 'file' utility (cf getFileType below).
49+
type BinaryType uint32
50+
51+
const (
52+
//BinaryUnknown signals that the file does not fit into our three simple minded categories
53+
BinaryUnknown BinaryType = 0
54+
//BinaryObject is the type of an object file, the output unit of compilation
55+
BinaryObject BinaryType = 1
56+
//BinaryExecutable is the type of an executable file
57+
BinaryExecutable BinaryType = 2
58+
//BinaryShared is the type of a shared or dynamic library
59+
BinaryShared BinaryType = 3
60+
)
61+
62+
func elfType2BinaryType(et elf.Type) (bt BinaryType) {
63+
bt = BinaryUnknown
64+
switch et {
65+
case elf.ET_NONE:
66+
bt = BinaryUnknown
67+
case elf.ET_REL:
68+
bt = BinaryObject
69+
case elf.ET_EXEC:
70+
bt = BinaryExecutable
71+
case elf.ET_DYN:
72+
bt = BinaryShared
73+
case elf.ET_CORE, elf.ET_LOOS, elf.ET_HIOS, elf.ET_LOPROC, elf.ET_HIPROC:
74+
bt = BinaryUnknown
75+
default:
76+
bt = BinaryUnknown
77+
}
78+
return
79+
}
80+
81+
func machoType2BinaryType(mt macho.Type) (bt BinaryType) {
82+
bt = BinaryUnknown
83+
switch mt {
84+
case macho.TypeObj:
85+
bt = BinaryObject
86+
case macho.TypeExec:
87+
bt = BinaryExecutable
88+
case macho.TypeDylib:
89+
bt = BinaryShared
90+
case macho.TypeBundle:
91+
bt = BinaryUnknown
92+
default:
93+
bt = BinaryUnknown
94+
}
95+
return
96+
}
97+
98+
// isPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
99+
func isPlainFile(objectFile string) (ok bool) {
100+
info, err := os.Stat(objectFile)
101+
if os.IsNotExist(err) || info.IsDir() {
102+
return
103+
}
104+
if err != nil {
105+
return
106+
}
107+
ok = true
108+
return
109+
}
110+
111+
func injectableViaFileType(objectFile string) (ok bool, err error) {
112+
plain := isPlainFile(objectFile)
113+
if !plain {
114+
return
115+
}
116+
fileType, err := getFileType(objectFile)
117+
if err != nil {
118+
return
119+
}
120+
ok = (fileType == fileTypeELFOBJECT) || (fileType == fileTypeELFOBJECT)
121+
return
122+
}
123+
124+
func injectableViaDebug(objectFile string) (ok bool, err error) {
125+
// I guess we are not doing cross compiling. Otherwise we are fucking up here.
126+
ok, err = IsObjectFileForOS(objectFile, runtime.GOOS)
127+
return
128+
}
129+
130+
// ElfFileType returns the elf.Type of the given file name
131+
func ElfFileType(objectFile string) (code BinaryType, err error) {
132+
var lbinFile *elf.File
133+
lbinFile, err = elf.Open(objectFile)
134+
if err != nil {
135+
return
136+
}
137+
code = elfType2BinaryType(lbinFile.FileHeader.Type)
138+
return
139+
}
140+
141+
// MachoFileType returns the macho.Type of the given file name
142+
func MachoFileType(objectFile string) (code BinaryType, err error) {
143+
var dbinFile *macho.File
144+
dbinFile, err = macho.Open(objectFile)
145+
if err != nil {
146+
return
147+
}
148+
code = machoType2BinaryType(dbinFile.FileHeader.Type)
149+
return
150+
}
151+
152+
//IsObjectFileForOS returns true if the given file is an object file for the given OS, using the debug/elf and debug/macho packages.
153+
func IsObjectFileForOS(objectFile string, operatingSys string) (ok bool, err error) {
154+
plain := isPlainFile(objectFile)
155+
if !plain {
156+
return
157+
}
158+
var binaryType BinaryType
159+
switch operatingSys {
160+
case "linux", "freebsd":
161+
binaryType, err = ElfFileType(objectFile)
162+
case "darwin":
163+
binaryType, err = MachoFileType(objectFile)
164+
}
165+
if err != nil {
166+
return
167+
}
168+
ok = (binaryType == BinaryObject)
169+
return
170+
}
171+
172+
// file types via the unix 'file' utility
45173
const (
46174
// File types
47175
fileTypeUNDEFINED = iota
@@ -57,23 +185,19 @@ const (
57185
fileTypeERROR
58186
)
59187

60-
//iam:
61-
// this is not that robust, because it depends on the file utility "file" which is
62-
// often missing on docker images (the klee doker file had this problem)
188+
//iam: this is not that robust, because it depends on the file utility "file" which is
189+
// often missing on docker images (the klee docker file had this problem)
190+
// this is only used in extraction, not in compilation.
63191
func getFileType(realPath string) (fileType int, err error) {
64-
65192
// We need the file command to guess the file type
66193
fileType = fileTypeERROR
67-
err = nil
68194
cmd := exec.Command("file", realPath)
69195
out, err := cmd.Output()
70196
if err != nil {
71197
LogError("There was an error getting the type of %s. Make sure that the 'file' command is installed.", realPath)
72198
return
73199
}
74-
75200
fo := string(out)
76-
77201
if strings.Contains(fo, "ELF") {
78202

79203
if strings.Contains(fo, "executable") {
@@ -107,70 +231,3 @@ func getFileType(realPath string) (fileType int, err error) {
107231
}
108232
return
109233
}
110-
111-
// isPlainFile returns true if the file is stat-able (i.e. exists etc), and is not a directory, else it returns false.
112-
func isPlainFile(objectFile string) (ok bool) {
113-
ok = false
114-
info, err := os.Stat(objectFile)
115-
if os.IsNotExist(err) || info.IsDir() {
116-
return
117-
}
118-
if err != nil {
119-
return
120-
}
121-
ok = true
122-
return
123-
}
124-
125-
func injectableViaFileType(objectFile string) (ok bool, err error) {
126-
ok = false
127-
err = nil
128-
plain := isPlainFile(objectFile)
129-
if !plain {
130-
return
131-
}
132-
fileType, err := getFileType(objectFile)
133-
if err != nil {
134-
return
135-
}
136-
ok = (fileType == fileTypeELFOBJECT) || (fileType == fileTypeELFOBJECT)
137-
return
138-
}
139-
140-
func injectableViaDebug(objectFile string) (ok bool, err error) {
141-
ok = false
142-
err = nil
143-
// I guess we are not doing cross compiling. Otherwise we are fucking up here.
144-
ok, err = IsObjectFileForOS(objectFile, runtime.GOOS)
145-
return
146-
}
147-
148-
//IsObjectFileForOS returns true if the given file is an object file for the given OS, using the debug/elf and debug/macho packages.
149-
func IsObjectFileForOS(objectFile string, operatingSys string) (ok bool, err error) {
150-
plain := isPlainFile(objectFile)
151-
if !plain {
152-
return
153-
}
154-
switch operatingSys {
155-
case "linux", "freebsd":
156-
var lbinFile *elf.File
157-
lbinFile, err = elf.Open(objectFile)
158-
if err != nil {
159-
return
160-
}
161-
dfileType := lbinFile.FileHeader.Type
162-
ok = (dfileType == elf.ET_REL)
163-
return
164-
case "darwin":
165-
var dbinFile *macho.File
166-
dbinFile, err = macho.Open(objectFile)
167-
if err != nil {
168-
return
169-
}
170-
dfileType := dbinFile.FileHeader.Type
171-
ok = (dfileType == macho.TypeObj)
172-
173-
return
174-
}
175-
return
176-
}

0 commit comments

Comments
 (0)