@@ -14,60 +14,36 @@ import Foundation
14
14
import LinuxSystemHeaders
15
15
16
16
internal class AuxVec {
17
- enum Error : Swift . Error { case FileReadFailure( _ filePath: String ) }
18
-
19
- // enum values must match the constants defined in usr/include/linux/auxv.h
20
- enum Tag : UInt64 {
21
- case AT_NULL = 0
22
- case AT_IGNORE = 1
23
- case AT_EXECFD = 2
24
- case AT_PHDR = 3
25
- case AT_PHENT = 4
26
- case AT_PHNUM = 5
27
- case AT_PAGESZ = 6
28
- case AT_BASE = 7
29
- case AT_FLAGS = 8
30
- case AT_ENTRY = 9
31
- case AT_NOTELF = 10
32
- case AT_UID = 11
33
- case AT_EUID = 12
34
- case AT_GID = 13
35
- case AT_EGID = 14
36
- case AT_PLATFORM = 15
37
- case AT_HWCAP = 16
38
- case AT_CLKTCK = 17
39
- case AT_SECURE = 23
40
- case AT_BASE_PLATFORM = 24
41
- case AT_RANDOM = 25
42
- case AT_HWCAP2 = 26
43
- case AT_RSEQ_FEATURE_SIZE = 27
44
- case AT_RSEQ_ALIGN = 28
45
- case AT_EXECFN = 31
46
- case AT_SYSINFO_EHDR = 33
47
- case AT_MINSIGSTKSZ = 51
48
- }
49
-
50
- static func load( for process: Process ) throws -> [ Tag : UInt64 ] {
17
+ // loads the auxiliary vector for a process
18
+ public static func load( for process: Process ) -> [ Int32 : UInt64 ] ? {
51
19
let filePath = " /proc/ \( process. pid) /auxv "
52
-
53
- let fileHandle = try FileHandle ( forReadingFrom: URL ( fileURLWithPath: filePath) )
20
+ guard let fileHandle = FileHandle ( forReadingAtPath: filePath) else { return nil }
54
21
defer { fileHandle. closeFile ( ) }
55
22
56
- guard let data = try fileHandle. readToEnd ( ) else { throw Error . FileReadFailure ( filePath ) }
23
+ guard let data = try ? fileHandle. readToEnd ( ) , data . count > 0 else { return nil }
57
24
58
- // aux vector is an array of 8-byte pairs in a 64-bit process
59
- assert ( process . elfFile . isElf64 , " only 64-bit processes are supported " )
60
- let auxVec : [ ( UInt64 , UInt64 ) ] = data . withUnsafeBytes {
61
- let count = $0. count / MemoryLayout < ( UInt64 , UInt64 ) > . stride
62
- return Array ( $0 . bindMemory ( to : ( UInt64 , UInt64 ) . self ) [ ..< count ] )
25
+ func fromData < T : UnsignedInteger > ( _ data : Data ) -> [ ( T , T ) ] {
26
+ return data . withUnsafeBytes {
27
+ let count = $0 . count / MemoryLayout < ( T , T ) > . stride
28
+ return Array ( $0. bindMemory ( to : ( T , T ) . self ) [ ..< count ] )
29
+ }
63
30
}
64
31
65
- var entries : [ Tag : UInt64 ] = [ : ]
66
- for (rawTag, value) in auxVec {
67
- guard let tag = Tag ( rawValue: rawTag) else { continue }
68
- entries [ tag] = value
32
+ func fromArray< T: UnsignedInteger > ( _ array: [ ( T , T ) ] ) -> [ Int32 : UInt64 ] {
33
+ var entries : [ Int32 : UInt64 ] = [ : ]
34
+ for (rawTag, value) in array {
35
+ // the AT_ constants defined in linux/auxv.h are imported as Int32
36
+ guard let tag = Int32 ( exactly: rawTag) else { continue }
37
+ entries [ tag] = UInt64 ( value)
38
+ }
39
+ return entries
69
40
}
70
41
71
- return entries
42
+ // in a 32-bit process, aux vector is an array of 4-byte pairs
43
+ // in a 64-bit process, aux vector is an array of 8-byte pairs
44
+ return process. elfFile. isElf64
45
+ ? fromArray ( fromData ( data) as [ ( UInt64 , UInt64 ) ] )
46
+ : fromArray ( fromData ( data) as [ ( UInt32 , UInt32 ) ] )
72
47
}
48
+
73
49
}
0 commit comments