@@ -14,10 +14,10 @@ import Foundation
1414import LinuxSystemHeaders
1515
1616class LinkMap {
17- public enum Error : Swift . Error {
18- case MalformedElf ( _ description : String )
19- case MissingAuxVecEntry ( _ description : String )
20- case ProcessReadMemoryFailure ( address : UInt , _ description: String = " " )
17+ public enum LinkMapError : Error {
18+ case failedLoadingAuxVec ( for : pid_t )
19+ case missingAuxVecEntry ( for : pid_t , _ tag : Int32 )
20+ case malformedELF ( for : pid_t , _ description: String )
2121 }
2222
2323 public struct Entry {
@@ -28,22 +28,21 @@ class LinkMap {
2828 public let entries : [ Entry ]
2929
3030 public init ( for process: Process ) throws {
31- guard let auxVec = Self . loadAuxVec ( for: process) else {
32- throw Error . MissingAuxVecEntry ( " failed reading auxvec for \( process) " )
31+ let auxVec = try Self . loadAuxVec ( for: process. pid)
32+ guard let phdrAddr = auxVec [ AT_PHDR] else {
33+ throw LinkMapError . missingAuxVecEntry ( for: process. pid, AT_PHDR)
3334 }
3435
35- guard let phdrAddr = auxVec [ AT_PHDR] else { throw Error . MissingAuxVecEntry ( " missing AT_PHDR " ) }
36-
3736 guard let phdrSize = auxVec [ AT_PHENT] else {
38- throw Error . MissingAuxVecEntry ( " missing AT_PHENT" )
37+ throw LinkMapError . missingAuxVecEntry ( for : process . pid , AT_PHENT)
3938 }
4039
4140 guard let phdrCount = auxVec [ AT_PHNUM] else {
42- throw Error . MissingAuxVecEntry ( " missing AT_PHNUM" )
41+ throw LinkMapError . missingAuxVecEntry ( for : process . pid , AT_PHNUM)
4342 }
4443
4544 guard phdrSize == MemoryLayout< Elf64_Phdr> . size else {
46- throw Error . MalformedElf ( " AT_PHENT invalid size: \( phdrSize) " )
45+ throw LinkMapError . malformedELF ( for : process . pid , " AT_PHENT invalid size: \( phdrSize) " )
4746 }
4847
4948 // determine the base load address for the executable file and locate the
@@ -66,7 +65,7 @@ class LinkMap {
6665
6766 case UInt32 ( PT_DYNAMIC) :
6867 guard dynamicSegment == nil else {
69- throw Error . MalformedElf ( " multiple PT_DYNAMIC segments found " )
68+ throw LinkMapError . malformedELF ( for : process . pid , " multiple PT_DYNAMIC segments found " )
7069 }
7170 dynamicSegment = phdr
7271
@@ -75,11 +74,11 @@ class LinkMap {
7574 }
7675
7776 guard let dynamicSegment = dynamicSegment else {
78- throw Error . MalformedElf ( " PT_DYNAMIC segment not found " )
77+ throw LinkMapError . malformedELF ( for : process . pid , " PT_DYNAMIC segment not found " )
7978 }
8079
8180 guard let baseLoadSegment = baseLoadSegment else {
82- throw Error . MalformedElf ( " PT_LOAD segment not found " )
81+ throw LinkMapError . malformedELF ( for : process . pid , " PT_LOAD segment not found " )
8382 }
8483
8584 let ehdrSize = MemoryLayout< Elf64_Ehdr> . size
@@ -101,7 +100,7 @@ class LinkMap {
101100 }
102101
103102 guard let rDebugEntry = rDebugEntry else {
104- throw Error . MalformedElf ( " DT_DEBUG not found in dynamic segment " )
103+ throw LinkMapError . malformedELF ( for : process . pid , " DT_DEBUG not found in dynamic segment " )
105104 }
106105
107106 let rDebugAddr : UInt64 = rDebugEntry. d_un. d_val
@@ -122,8 +121,11 @@ class LinkMap {
122121 }
123122
124123 // loads the auxiliary vector for a 64-bit process
125- static func loadAuxVec( for process: Process ) -> [ Int32 : UInt64 ] ? {
126- guard let data = ProcFS . loadFile ( for: process. pid, " auxv " ) else { return nil }
124+ static func loadAuxVec( for pid: pid_t ) throws -> [ Int32 : UInt64 ] {
125+ guard let data = ProcFS . loadFile ( for: pid, " auxv " ) else {
126+ throw LinkMapError . failedLoadingAuxVec ( for: pid)
127+ }
128+
127129 return data. withUnsafeBytes {
128130 // in a 64-bit process, aux vector is an array of 8-byte pairs
129131 let count = $0. count / MemoryLayout< ( UInt64, UInt64) > . stride
0 commit comments