| 776 | } |
| 777 | |
| 778 | void Symbols::parseLibraries(CodeCacheArray* array, bool kernel_symbols) { |
| 779 | MutexLocker ml(_parse_lock); |
| 780 | |
| 781 | if (_in_parse_libraries || array->count() >= MAX_NATIVE_LIBS) { |
| 782 | return; |
| 783 | } |
| 784 | _in_parse_libraries = true; |
| 785 | |
| 786 | if (kernel_symbols && !haveKernelSymbols()) { |
| 787 | CodeCache* cc = new CodeCache("[kernel]"); |
| 788 | parseKernelSymbols(cc); |
| 789 | |
| 790 | if (haveKernelSymbols()) { |
| 791 | cc->sort(); |
| 792 | array->add(cc); |
| 793 | } else { |
| 794 | delete cc; |
| 795 | } |
| 796 | } |
| 797 | |
| 798 | std::unordered_map<u64, SharedLibrary> libs; |
| 799 | collectSharedLibraries(libs, MAX_NATIVE_LIBS - array->count()); |
| 800 | |
| 801 | for (auto& it : libs) { |
| 802 | u64 inode = it.first; |
| 803 | _parsed_inodes.insert(inode); |
| 804 | |
| 805 | SharedLibrary& lib = it.second; |
| 806 | CodeCache* cc = new CodeCache(lib.file, array->count(), lib.map_start, lib.map_end, lib.image_base); |
| 807 | |
| 808 | if (strchr(lib.file, ':') != NULL) { |
| 809 | // Do not try to parse pseudofiles like anon_inode:name, /memfd:name |
| 810 | } else if (strcmp(lib.file, "[vdso]") == 0) { |
| 811 | ElfParser::parseProgramHeaders(cc, lib.map_start, lib.map_end, true); |
| 812 | } else if (lib.image_base == NULL) { |
| 813 | // Unlikely case when image base has not been found: not safe to access program headers. |
| 814 | // Be careful: executable file is not always ELF, e.g. classes.jsa |
| 815 | ElfParser::parseFile(cc, lib.map_start, lib.file, true); |
| 816 | } else { |
| 817 | // Parse debug symbols first |
| 818 | ElfParser::parseFile(cc, lib.image_base, lib.file, true); |
| 819 | |
| 820 | UnloadProtection handle(cc); |
| 821 | if (handle.isValid()) { |
| 822 | ElfParser::parseProgramHeaders(cc, lib.image_base, lib.map_end, OS::isMusl()); |
| 823 | } |
| 824 | } |
| 825 | |
| 826 | free(lib.file); |
| 827 | |
| 828 | cc->sort(); |
| 829 | applyPatch(cc); |
| 830 | array->add(cc); |
| 831 | } |
| 832 | |
| 833 | if (array->count() >= MAX_NATIVE_LIBS && !_libs_limit_reported) { |
| 834 | Log::warn("Number of parsed libraries reached the limit of %d", MAX_NATIVE_LIBS); |
| 835 | _libs_limit_reported = true; |
nothing calls this directly
no test coverage detected