@@ -34,19 +34,6 @@ extern "C" {
34
34
35
35
namespace ObjectIntrospection {
36
36
37
- /* *
38
- * We need a way to identify the BLOB/Object file, but we don't have access
39
- * to the function's name or the introspected type's name without
40
- * initialising drgn.
41
- * Exclusively to OIL, we won't use the type's name, but the templated
42
- * function address. We assume the address of the templated function
43
- * changes at every compilation, so we don't re-use object files that
44
- * are for an older version of the binary.
45
- */
46
- const std::string function_identifier (uintptr_t functionAddress) {
47
- return (boost::format (" %x" ) % (uint32_t )(functionAddress % UINT32_MAX)).str ();
48
- }
49
-
50
37
OILibraryImpl::OILibraryImpl (OILibrary *self, void *TemplateFunc)
51
38
: _self(self), _TemplateFunc(TemplateFunc) {
52
39
if (_self->opts .debugLevel != 0 ) {
@@ -122,14 +109,6 @@ void close_file(std::FILE *fp) {
122
109
std::fclose (fp);
123
110
}
124
111
125
- static inline void logElfError (const char *message) {
126
- const char *elf_error_message = elf_errmsg (0 );
127
- if (elf_error_message)
128
- LOG (ERROR) << message << " : " << elf_error_message;
129
- else
130
- LOG (ERROR) << message;
131
- }
132
-
133
112
int OILibraryImpl::compileCode () {
134
113
OICompiler compiler{symbols, compilerConfig};
135
114
@@ -152,114 +131,54 @@ int OILibraryImpl::compileCode() {
152
131
auto objectPath =
153
132
fs::path ((boost::format (" /dev/fd/%1%" ) % objectMemfd).str ());
154
133
155
- if (_self->opts .forceJIT ) {
156
- struct drgn_program *prog = symbols->getDrgnProgram ();
157
- if (!prog) {
158
- return Response::OIL_COMPILATION_FAILURE;
159
- }
160
- struct drgn_symbol *sym;
161
- if (auto err = drgn_program_find_symbol_by_address (
162
- prog, (uintptr_t )_TemplateFunc, &sym)) {
163
- LOG (ERROR) << " Error when finding symbol by address " << err->code << " "
164
- << err->message ;
165
- drgn_error_destroy (err);
166
- return Response::OIL_COMPILATION_FAILURE;
167
- }
168
- const char *name = drgn_symbol_name (sym);
169
- drgn_symbol_destroy (sym);
134
+ struct drgn_program *prog = symbols->getDrgnProgram ();
135
+ if (!prog) {
136
+ return Response::OIL_COMPILATION_FAILURE;
137
+ }
138
+ struct drgn_symbol *sym;
139
+ if (auto err = drgn_program_find_symbol_by_address (
140
+ prog, (uintptr_t )_TemplateFunc, &sym)) {
141
+ LOG (ERROR) << " Error when finding symbol by address " << err->code << " "
142
+ << err->message ;
143
+ drgn_error_destroy (err);
144
+ return Response::OIL_COMPILATION_FAILURE;
145
+ }
146
+ const char *name = drgn_symbol_name (sym);
147
+ drgn_symbol_destroy (sym);
170
148
171
- auto rootType = symbols->getRootType (irequest{" entry" , name, " arg0" });
172
- if (!rootType.has_value ()) {
173
- LOG (ERROR) << " Failed to get type of probe argument" ;
174
- return Response::OIL_COMPILATION_FAILURE;
175
- }
149
+ // TODO: change this to the new drgn interface from symbol -> type
150
+ auto rootType = symbols->getRootType (irequest{" entry" , name, " arg0" });
151
+ if (!rootType.has_value ()) {
152
+ LOG (ERROR) << " Failed to get type of probe argument" ;
153
+ return Response::OIL_COMPILATION_FAILURE;
154
+ }
176
155
177
- std::string code =
156
+ std::string code =
178
157
#include " OITraceCode.cpp"
179
- ;
180
-
181
- auto codegen = OICodeGen::buildFromConfig (generatorConfig, *symbols);
182
- if (!codegen) {
183
- return OIL_COMPILATION_FAILURE;
184
- }
158
+ ;
185
159
186
- codegen-> setRootType (rootType-> type );
187
- if (!codegen-> generate (code) ) {
188
- return Response:: OIL_COMPILATION_FAILURE;
189
- }
160
+ auto codegen = OICodeGen::buildFromConfig (generatorConfig, *symbols );
161
+ if (!codegen) {
162
+ return OIL_COMPILATION_FAILURE;
163
+ }
190
164
191
- std::string sourcePath = _self->opts .sourceFileDumpPath ;
192
- if (_self->opts .sourceFileDumpPath .empty ()) {
193
- // This is the path Clang acts as if it has compiled from e.g. for debug
194
- // information. It does not need to exist.
195
- sourcePath = " oil_jit.cpp" ;
196
- } else {
197
- std::ofstream outputFile (sourcePath);
198
- outputFile << code;
199
- }
165
+ codegen->setRootType (rootType->type );
166
+ if (!codegen->generate (code)) {
167
+ return Response::OIL_COMPILATION_FAILURE;
168
+ }
200
169
201
- if (!compiler.compile (code, sourcePath, objectPath)) {
202
- return Response::OIL_COMPILATION_FAILURE;
203
- }
170
+ std::string sourcePath = _self->opts .sourceFileDumpPath ;
171
+ if (_self->opts .sourceFileDumpPath .empty ()) {
172
+ // This is the path Clang acts as if it has compiled from e.g. for debug
173
+ // information. It does not need to exist.
174
+ sourcePath = " oil_jit.cpp" ;
204
175
} else {
205
- auto executable =
206
- open (fs::read_symlink (" /proc/self/exe" ).c_str (), O_RDONLY);
207
- if (executable == -1 ) {
208
- PLOG (ERROR) << " Failed to open executable file" ;
209
- return Response::OIL_COMPILATION_FAILURE;
210
- }
211
- auto __executable_cleanup = Cleanup (executable, close);
212
- elf_version (EV_CURRENT);
213
- auto elf = elf_begin (executable, ELF_C_READ, NULL );
214
- auto __elf_cleanup = Cleanup (elf, elf_end);
215
- GElf_Ehdr ehdr;
216
- if (!gelf_getehdr (elf, &ehdr)) {
217
- logElfError (" Failed to get ELF object file header" );
218
- return Response::OIL_COMPILATION_FAILURE;
219
- }
220
- size_t string_table_index;
221
- if (elf_getshdrstrndx (elf, &string_table_index) != 0 ) {
222
- logElfError (" Failed to get index of the section header string table" );
223
- return Response::OIL_COMPILATION_FAILURE;
224
- }
176
+ std::ofstream outputFile (sourcePath);
177
+ outputFile << code;
178
+ }
225
179
226
- Elf_Scn *section = NULL ;
227
- bool done = false ;
228
- const auto identifier = function_identifier ((uintptr_t )_TemplateFunc);
229
- const auto section_name = OI_SECTION_PREFIX.data () + identifier;
230
- while ((section = elf_nextscn (elf, section))) {
231
- GElf_Shdr section_header;
232
- GElf_Shdr *header = gelf_getshdr (section, §ion_header);
233
- if (!header)
234
- continue ;
235
- const char *name = elf_strptr (elf, string_table_index, header->sh_name );
236
- if (name && strcmp (name, section_name.c_str ()) == 0 ) {
237
- Elf_Data *section_data;
238
- if (!(section_data = elf_getdata (section, NULL ))) {
239
- LOG (ERROR) << " Failed to get data from section '" << name
240
- << " ': " << elf_errmsg (0 );
241
- return Response::OIL_COMPILATION_FAILURE;
242
- }
243
- if (section_data->d_size == 0 ) {
244
- LOG (ERROR) << " Section '" << name << " ' is empty" ;
245
- return Response::OIL_COMPILATION_FAILURE;
246
- }
247
- if (fwrite (section_data->d_buf , 1 , section_data->d_size ,
248
- objectStream.get ()) < section_data->d_size ) {
249
- PLOG (ERROR)
250
- << " Failed to write object file contents to temporary file" ;
251
- return Response::OIL_COMPILATION_FAILURE;
252
- }
253
- done = true ;
254
- break ;
255
- }
256
- }
257
- if (!done) {
258
- LOG (ERROR) << " Did not find section '" << section_name
259
- << " ' in the executable" ;
260
- return Response::OIL_COMPILATION_FAILURE;
261
- }
262
- fflush (objectStream.get ());
180
+ if (!compiler.compile (code, sourcePath, objectPath)) {
181
+ return Response::OIL_COMPILATION_FAILURE;
263
182
}
264
183
265
184
auto relocRes = compiler.applyRelocs (
@@ -278,8 +197,9 @@ int OILibraryImpl::compileCode() {
278
197
break ;
279
198
}
280
199
}
281
- if (!_self->fp )
200
+ if (!_self->fp ) {
282
201
return Response::OIL_RELOCATION_FAILURE;
202
+ }
283
203
284
204
// Copy relocated segments in their final destination
285
205
for (const auto &[BaseAddr, RelocAddr, Size] : segments)
0 commit comments