Skip to content

Commit 5511366

Browse files
committed
libexec: split path resolver from dynamic linker
1 parent 5d2c03b commit 5511366

File tree

13 files changed

+459
-522
lines changed

13 files changed

+459
-522
lines changed

source/intercept-library/library/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ add_library(exec_a OBJECT
99
source/Buffer.cc
1010
source/Environment.cc
1111
source/Executor.cc
12+
source/Linker.cc
1213
source/Logger.cc
1314
source/Paths.cc
14-
source/PathResolver.cc
1515
source/Resolver.cc
1616
source/Session.cc
1717
)

source/intercept-library/library/lib.cc

Lines changed: 55 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@
2323
#include <cstdarg>
2424

2525
#include "Executor.h"
26+
#include "Linker.h"
2627
#include "Logger.h"
2728
#include "Resolver.h"
2829
#include "Session.h"
2930

31+
#if defined HAVE_NSGETENVIRON
32+
#include <crt_externs.h>
33+
#else
34+
#include <unistd.h>
35+
36+
#endif
37+
3038
namespace {
3139

3240
size_t va_length(va_list& args)
@@ -42,6 +50,24 @@ namespace {
4250
for (size_t idx = 0; idx < argc; ++idx)
4351
argv[idx] = va_arg(args, char*);
4452
}
53+
54+
/**
55+
* Abstraction to get the current environment.
56+
*
57+
* When the dynamic linker loads the library the `environ` variable
58+
* might not be available. (This is the case for OSX.) This method
59+
* makes it uniform to access the current environment on all platform.
60+
*
61+
* @return the current environment.
62+
*/
63+
const char** environment() noexcept
64+
{
65+
#ifdef HAVE_NSGETENVIRON
66+
return const_cast<const char**>(*_NSGetEnviron());
67+
#else
68+
return const_cast<const char**>(environ);
69+
#endif
70+
}
4571
}
4672

4773
/**
@@ -57,7 +83,7 @@ namespace {
5783
std::atomic<bool> LOADED(false);
5884
// These are related to the functionality of this library.
5985
el::Session SESSION = el::session::init();
60-
el::Resolver RESOLVER;
86+
el::Linker LINKER;
6187

6288
constexpr el::log::Logger LOGGER("lib.cc");
6389
}
@@ -74,7 +100,7 @@ extern "C" void on_load()
74100
if (LOADED.exchange(true))
75101
return;
76102

77-
el::session::from(SESSION, RESOLVER.environment());
103+
el::session::from(SESSION, environment());
78104
el::session::persist(SESSION, BUFFER, BUFFER + BUFFER_SIZE);
79105

80106
el::log::Level level = SESSION.verbose ? el::log::VERBOSE : el::log::SILENT;
@@ -102,7 +128,8 @@ extern "C" int execve(const char* path, char* const argv[], char* const envp[])
102128
{
103129
LOGGER.debug("execve path: ", path);
104130

105-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execve(path, argv, envp);
131+
el::Resolver resolver;
132+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execve(path, argv, envp);
106133
errno = result.error_code;
107134
return result.return_value;
108135
}
@@ -111,8 +138,9 @@ extern "C" int execv(const char* path, char* const argv[])
111138
{
112139
LOGGER.debug("execv path: ", path);
113140

114-
auto envp = const_cast<char* const*>(RESOLVER.environment());
115-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execve(path, argv, envp);
141+
auto envp = const_cast<char* const*>(environment());
142+
el::Resolver resolver;
143+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execve(path, argv, envp);
116144
errno = result.error_code;
117145
return result.return_value;
118146
}
@@ -121,7 +149,8 @@ extern "C" int execvpe(const char* file, char* const argv[], char* const envp[])
121149
{
122150
LOGGER.debug("execvpe file: ", file);
123151

124-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execvpe(file, argv, envp);
152+
el::Resolver resolver;
153+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execvpe(file, argv, envp);
125154
errno = result.error_code;
126155
return result.return_value;
127156
}
@@ -130,8 +159,9 @@ extern "C" int execvp(const char* file, char* const argv[])
130159
{
131160
LOGGER.debug("execvp file: ", file);
132161

133-
auto envp = const_cast<char* const*>(RESOLVER.environment());
134-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execvpe(file, argv, envp);
162+
auto envp = const_cast<char* const*>(environment());
163+
el::Resolver resolver;
164+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execvpe(file, argv, envp);
135165
errno = result.error_code;
136166
return result.return_value;
137167
}
@@ -140,8 +170,9 @@ extern "C" int execvP(const char* file, const char* search_path, char* const arg
140170
{
141171
LOGGER.debug("execvP file: ", file);
142172

143-
auto envp = const_cast<char* const*>(RESOLVER.environment());
144-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execvP(file, search_path, argv, envp);
173+
auto envp = const_cast<char* const*>(environment());
174+
el::Resolver resolver;
175+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execvP(file, search_path, argv, envp);
145176
errno = result.error_code;
146177
return result.return_value;
147178
}
@@ -150,7 +181,8 @@ extern "C" int exect(const char* path, char* const argv[], char* const envp[])
150181
{
151182
LOGGER.debug("exect path: ", path);
152183

153-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execve(path, argv, envp);
184+
el::Resolver resolver;
185+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execve(path, argv, envp);
154186
errno = result.error_code;
155187
return result.return_value;
156188
}
@@ -174,8 +206,9 @@ extern "C" int execl(const char* path, const char* arg, ...)
174206
va_copy_n(ap, &argv[1], argc + 1);
175207
va_end(ap);
176208

177-
auto envp = const_cast<char* const*>(RESOLVER.environment());
178-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execve(path, argv, envp);
209+
auto envp = const_cast<char* const*>(environment());
210+
el::Resolver resolver;
211+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execve(path, argv, envp);
179212
errno = result.error_code;
180213
return result.return_value;
181214
}
@@ -196,8 +229,9 @@ extern "C" int execlp(const char* file, const char* arg, ...)
196229
va_copy_n(ap, &argv[1], argc + 1);
197230
va_end(ap);
198231

199-
auto envp = const_cast<char* const*>(RESOLVER.environment());
200-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execvpe(file, argv, envp);
232+
auto envp = const_cast<char* const*>(environment());
233+
el::Resolver resolver;
234+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execvpe(file, argv, envp);
201235
errno = result.error_code;
202236
return result.return_value;
203237
}
@@ -220,7 +254,8 @@ extern "C" int execle(const char* path, const char* arg, ...)
220254
char** envp = va_arg(ap, char**);
221255
va_end(ap);
222256

223-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).execve(path, argv, envp);
257+
el::Resolver resolver;
258+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).execve(path, argv, envp);
224259
errno = result.error_code;
225260
return result.return_value;
226261
}
@@ -234,7 +269,8 @@ extern "C" int posix_spawn(pid_t* pid, const char* path,
234269
{
235270
LOGGER.debug("posix_spawn path:", path);
236271

237-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).posix_spawn(pid, path, file_actions, attrp, argv, envp);
272+
el::Resolver resolver;
273+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).posix_spawn(pid, path, file_actions, attrp, argv, envp);
238274
errno = result.error_code;
239275
return result.return_value;
240276
}
@@ -246,7 +282,8 @@ extern "C" int posix_spawnp(pid_t* pid, const char* file,
246282
{
247283
LOGGER.debug("posix_spawnp file:", file);
248284

249-
const el::Executor::Result result = el::Executor(RESOLVER, SESSION).posix_spawnp(pid, file, file_actions, attrp, argv, envp);
285+
el::Resolver resolver;
286+
const el::Executor::Result result = el::Executor(LINKER, SESSION, resolver).posix_spawnp(pid, file, file_actions, attrp, argv, envp);
250287
errno = result.error_code;
251288
return result.return_value;
252289
}

source/intercept-library/library/source/Executor.cc

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424
#include "Array.h"
2525
#include "Logger.h"
26-
#include "PathResolver.h"
2726
#include "Resolver.h"
27+
#include "Linker.h"
2828
#include "Session.h"
2929

3030
#include <algorithm>
@@ -105,24 +105,24 @@ namespace {
105105

106106
namespace el {
107107

108-
Executor::Executor(el::Resolver const& resolver, el::Session const& session) noexcept
109-
: resolver_(resolver)
108+
Executor::Executor(el::Linker const& linker, el::Session const& session, el::Resolver &resolver) noexcept
109+
: linker_(linker)
110110
, session_(session)
111+
, resolver_(resolver)
111112
{ }
112113

113114
Executor::Result Executor::execve(const char* path, char* const* argv, char* const* envp) const
114115
{
115116
CHECK_SESSION(session_);
116117
CHECK_POINTER(path);
117118

118-
PathResolver resolver(resolver_);
119-
if (auto executable = resolver.from_current_directory(path); executable) {
119+
if (auto executable = resolver_.from_current_directory(path); executable) {
120120
const CommandBuilder cmd(session_, executable.return_value, argv);
121121
const char* dst[cmd.length()];
122122
cmd.assemble(dst);
123123

124-
auto return_value = resolver_.execve(cmd.file(), const_cast<char* const*>(dst), envp);
125-
return Executor::Result { return_value, resolver_.error_code() };
124+
auto return_value = linker_.execve(cmd.file(), const_cast<char* const*>(dst), envp);
125+
return Executor::Result {return_value, linker_.error_code() };
126126
} else {
127127
return Executor::Result { -1, executable.error_code };
128128
}
@@ -133,14 +133,13 @@ namespace el {
133133
CHECK_SESSION(session_);
134134
CHECK_POINTER(file);
135135

136-
PathResolver resolver(resolver_);
137-
if (auto executable = resolver.from_path(file, envp); executable) {
136+
if (auto executable = resolver_.from_path(file, envp); executable) {
138137
const CommandBuilder cmd(session_, executable.return_value, argv);
139138
const char* dst[cmd.length()];
140139
cmd.assemble(dst);
141140

142-
auto return_value = resolver_.execve(cmd.file(), const_cast<char* const*>(dst), envp);
143-
return Executor::Result { return_value, resolver_.error_code() };
141+
auto return_value = linker_.execve(cmd.file(), const_cast<char* const*>(dst), envp);
142+
return Executor::Result {return_value, linker_.error_code() };
144143
} else {
145144
return Executor::Result { -1, executable.error_code };
146145
}
@@ -151,14 +150,13 @@ namespace el {
151150
CHECK_SESSION(session_);
152151
CHECK_POINTER(file);
153152

154-
PathResolver resolver(resolver_);
155-
if (auto executable = resolver.from_search_path(file, search_path); executable) {
153+
if (auto executable = resolver_.from_search_path(file, search_path); executable) {
156154
const CommandBuilder cmd(session_, executable.return_value, argv);
157155
const char* dst[cmd.length()];
158156
cmd.assemble(dst);
159157

160-
auto return_value = resolver_.execve(cmd.file(), const_cast<char* const*>(dst), envp);
161-
return Executor::Result { return_value, resolver_.error_code() };
158+
auto return_value = linker_.execve(cmd.file(), const_cast<char* const*>(dst), envp);
159+
return Executor::Result {return_value, linker_.error_code() };
162160
} else {
163161
return Executor::Result { -1, executable.error_code };
164162
}
@@ -171,14 +169,13 @@ namespace el {
171169
CHECK_SESSION(session_);
172170
CHECK_POINTER(path);
173171

174-
PathResolver resolver(resolver_);
175-
if (auto executable = resolver.from_current_directory(path); executable) {
172+
if (auto executable = resolver_.from_current_directory(path); executable) {
176173
const CommandBuilder cmd(session_, executable.return_value, argv);
177174
const char* dst[cmd.length()];
178175
cmd.assemble(dst);
179176

180-
auto return_value = resolver_.posix_spawn(pid, cmd.file(), file_actions, attrp, const_cast<char* const*>(dst), envp);
181-
return Executor::Result { return_value, resolver_.error_code() };
177+
auto return_value = linker_.posix_spawn(pid, cmd.file(), file_actions, attrp, const_cast<char* const*>(dst), envp);
178+
return Executor::Result {return_value, linker_.error_code() };
182179
} else {
183180
return Executor::Result { -1, executable.error_code };
184181
}
@@ -191,14 +188,13 @@ namespace el {
191188
CHECK_SESSION(session_);
192189
CHECK_POINTER(file);
193190

194-
PathResolver resolver(resolver_);
195-
if (auto executable = resolver.from_path(file, envp); executable) {
191+
if (auto executable = resolver_.from_path(file, envp); executable) {
196192
const CommandBuilder cmd(session_, executable.return_value, argv);
197193
const char* dst[cmd.length()];
198194
cmd.assemble(dst);
199195

200-
auto return_value = resolver_.posix_spawn(pid, cmd.file(), file_actions, attrp, const_cast<char* const*>(dst), envp);
201-
return Executor::Result { return_value, resolver_.error_code() };
196+
auto return_value = linker_.posix_spawn(pid, cmd.file(), file_actions, attrp, const_cast<char* const*>(dst), envp);
197+
return Executor::Result {return_value, linker_.error_code() };
202198
} else {
203199
return Executor::Result { -1, executable.error_code };
204200
}

source/intercept-library/library/source/Executor.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323

2424
namespace el {
2525

26-
class Resolver;
26+
class Linker;
2727
struct Session;
28+
class Resolver;
2829

2930
/**
3031
* This class implements the process execution logic.
@@ -51,7 +52,7 @@ namespace el {
5152
};
5253

5354
public:
54-
Executor(el::Resolver const& resolver, el::Session const& session) noexcept;
55+
Executor(el::Linker const& linker, el::Session const& session, el::Resolver &resolver) noexcept;
5556

5657
~Executor() noexcept = default;
5758

@@ -75,7 +76,8 @@ namespace el {
7576
char* const envp[]) const;
7677

7778
private:
78-
el::Resolver const& resolver_;
79-
el::Session const& session_;
79+
el::Linker const &linker_;
80+
el::Session const &session_;
81+
el::Resolver &resolver_;
8082
};
8183
}

0 commit comments

Comments
 (0)