|
1 | 1 | /* |
2 | | - * Copyright 2016 Andrei Pangin |
3 | | - * |
4 | | - * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | - * you may not use this file except in compliance with the License. |
6 | | - * You may obtain a copy of the License at |
7 | | - * |
8 | | - * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | - * |
10 | | - * Unless required by applicable law or agreed to in writing, software |
11 | | - * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | - * See the License for the specific language governing permissions and |
14 | | - * limitations under the License. |
| 2 | + * Copyright The async-profiler authors |
| 3 | + * SPDX-License-Identifier: Apache-2.0 |
15 | 4 | */ |
16 | 5 |
|
17 | 6 | #include "codeCache.h" |
@@ -274,48 +263,88 @@ void CodeCache::findSymbolsByPrefix(std::vector<const char *> &prefixes, |
274 | 263 | } |
275 | 264 | } |
276 | 265 |
|
277 | | -void CodeCache::addImport(void **entry, const char *name) { |
278 | | - switch (name[0]) { |
279 | | - case 'd': |
280 | | - if (strcmp(name, "dlopen") == 0) { |
281 | | - _imports[im_dlopen] = entry; |
| 266 | +void CodeCache::saveImport(ImportId id, void** entry) { |
| 267 | + for (int ty = 0; ty < NUM_IMPORT_TYPES; ty++) { |
| 268 | + if (_imports[id][ty] == nullptr) { |
| 269 | + _imports[id][ty] = entry; |
| 270 | + return; |
| 271 | + } |
282 | 272 | } |
283 | | - break; |
284 | | - case 'p': |
285 | | - if (strcmp(name, "pthread_create") == 0) { |
286 | | - _imports[im_pthread_create] = entry; |
287 | | - } else if (strcmp(name, "pthread_exit") == 0) { |
288 | | - _imports[im_pthread_exit] = entry; |
289 | | - } else if (strcmp(name, "pthread_setspecific") == 0) { |
290 | | - _imports[im_pthread_setspecific] = entry; |
| 273 | +} |
| 274 | + |
| 275 | +void CodeCache::addImport(void **entry, const char *name) { |
| 276 | + switch (name[0]) { |
| 277 | + case 'c': |
| 278 | + if (strcmp(name, "calloc") == 0) { |
| 279 | + saveImport(im_calloc, entry); |
| 280 | + } |
| 281 | + break; |
| 282 | + case 'd': |
| 283 | + if (strcmp(name, "dlopen") == 0) { |
| 284 | + saveImport(im_dlopen, entry); |
| 285 | + } |
| 286 | + break; |
| 287 | + case 'f': |
| 288 | + if (strcmp(name, "free") == 0) { |
| 289 | + saveImport(im_free, entry); |
| 290 | + } |
| 291 | + break; |
| 292 | + case 'm': |
| 293 | + if (strcmp(name, "malloc") == 0) { |
| 294 | + saveImport(im_malloc, entry); |
| 295 | + } |
| 296 | + break; |
| 297 | + case 'p': |
| 298 | + if (strcmp(name, "pthread_create") == 0) { |
| 299 | + saveImport(im_pthread_create, entry); |
| 300 | + } else if (strcmp(name, "pthread_exit") == 0) { |
| 301 | + saveImport(im_pthread_exit, entry); |
| 302 | + } else if (strcmp(name, "pthread_setspecific") == 0) { |
| 303 | + saveImport(im_pthread_setspecific, entry); |
| 304 | + } else if (strcmp(name, "poll") == 0) { |
| 305 | + saveImport(im_poll, entry); |
| 306 | + } |
| 307 | + break; |
| 308 | + case 'r': |
| 309 | + if (strcmp(name, "realloc") == 0) { |
| 310 | + saveImport(im_realloc, entry); |
| 311 | + } |
| 312 | + break; |
291 | 313 | } |
292 | | - break; |
293 | | - } |
294 | 314 | } |
295 | 315 |
|
296 | 316 | void **CodeCache::findImport(ImportId id) { |
297 | 317 | if (!_imports_patchable) { |
298 | 318 | makeImportsPatchable(); |
299 | 319 | _imports_patchable = true; |
300 | 320 | } |
301 | | - return _imports[id]; |
| 321 | + return _imports[id][PRIMARY]; |
302 | 322 | } |
303 | 323 |
|
304 | 324 | void CodeCache::patchImport(ImportId id, void *hook_func) { |
305 | | - void **entry = findImport(id); |
| 325 | + if (!_imports_patchable) { |
| 326 | + makeImportsPatchable(); |
| 327 | + _imports_patchable = true; |
| 328 | + } |
| 329 | + |
| 330 | + for (int ty = 0; ty < NUM_IMPORT_TYPES; ty++) {void **entry = _imports[id][ty]; |
306 | 331 | if (entry != NULL) { |
307 | 332 | *entry = hook_func; |
308 | | - } |
| 333 | + }} |
309 | 334 | } |
310 | 335 |
|
311 | 336 | void CodeCache::makeImportsPatchable() { |
312 | 337 | void **min_import = (void **)-1; |
313 | 338 | void **max_import = NULL; |
314 | 339 | for (int i = 0; i < NUM_IMPORTS; i++) { |
315 | | - if (_imports[i] != NULL && _imports[i] < min_import) |
316 | | - min_import = _imports[i]; |
317 | | - if (_imports[i] != NULL && _imports[i] > max_import) |
318 | | - max_import = _imports[i]; |
| 340 | + for (int j = 0; j < NUM_IMPORT_TYPES; j++) { |
| 341 | + void** entry = _imports[i][j]; |
| 342 | + if (entry == NULL) continue; |
| 343 | + if (entry < min_import) |
| 344 | + min_import = entry; |
| 345 | + if (entry > max_import) |
| 346 | + max_import = entry; |
| 347 | + } |
319 | 348 | } |
320 | 349 |
|
321 | 350 | if (max_import != NULL) { |
|
0 commit comments