| 2500 | |
| 2501 | |
| 2502 | bool MachoView::AddExportTerminalSymbol( |
| 2503 | const std::string& symbolName, uint64_t symbolFlags, uint64_t imageOffset) |
| 2504 | { |
| 2505 | if (symbolFlags & EXPORT_SYMBOL_FLAGS_REEXPORT) |
| 2506 | { |
| 2507 | m_logger->LogTrace("Export symbol is a re-export, not supported: %s", symbolName.c_str()); |
| 2508 | return false; |
| 2509 | } |
| 2510 | |
| 2511 | uint64_t symbolAddress = GetStart() + imageOffset; |
| 2512 | if (symbolName.empty() || symbolAddress == 0) |
| 2513 | { |
| 2514 | m_logger->LogTrace("Export symbol is malformed: %s", symbolName.c_str()); |
| 2515 | return false; |
| 2516 | } |
| 2517 | |
| 2518 | // Tries to get the symbol type based off the section containing it. |
| 2519 | auto sectionSymbolType = [&]() -> BNSymbolType { |
| 2520 | uint32_t sectionFlags = 0; |
| 2521 | for (const auto& section : m_allSections) |
| 2522 | { |
| 2523 | if (symbolAddress >= section.addr && symbolAddress < section.addr + section.size) |
| 2524 | { |
| 2525 | // Take the flags from the first containing section. |
| 2526 | sectionFlags = section.flags; |
| 2527 | break; |
| 2528 | } |
| 2529 | } |
| 2530 | |
| 2531 | // TODO: Is this enough to determine a function symbol? |
| 2532 | // TODO: Might be the cause of https://github.com/Vector35/binaryninja-api/issues/6526 |
| 2533 | // Check the sections flags to see if we actually have a function symbol instead. |
| 2534 | if (sectionFlags & S_ATTR_PURE_INSTRUCTIONS || sectionFlags & S_ATTR_SOME_INSTRUCTIONS) |
| 2535 | return FunctionSymbol; |
| 2536 | |
| 2537 | // FIXME: See above, no it is not. Fallback on old logic here to avoid breaking export symbols in __text on regular Mach-Os. |
| 2538 | auto symbolType = GetAnalysisFunctionsForAddress(GetStart() + imageOffset).size() ? FunctionSymbol : DataSymbol; |
| 2539 | return symbolType; |
| 2540 | }; |
| 2541 | |
| 2542 | switch (symbolFlags & EXPORT_SYMBOL_FLAGS_KIND_MASK) |
| 2543 | { |
| 2544 | case EXPORT_SYMBOL_FLAGS_KIND_REGULAR: |
| 2545 | case EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: |
| 2546 | m_logger->LogTrace("Export symbol is a regular or thread local symbol: %d %s", sectionSymbolType(), symbolName.c_str()); |
| 2547 | DefineMachoSymbol(sectionSymbolType(), symbolName, symbolAddress, GlobalBinding, false); |
| 2548 | break; |
| 2549 | case EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: |
| 2550 | m_logger->LogTrace("Export symbol is an absolute symbol: %s", symbolName.c_str()); |
| 2551 | DefineMachoSymbol(DataSymbol, symbolName, symbolAddress, GlobalBinding, false); |
| 2552 | break; |
| 2553 | default: |
| 2554 | m_logger->LogWarn("Unhandled export symbol kind: %llx", symbolFlags & EXPORT_SYMBOL_FLAGS_KIND_MASK); |
| 2555 | return false; |
| 2556 | } |
| 2557 | |
| 2558 | m_logger->LogTrace("Successfully added export symbol: %s", symbolName.c_str()); |
| 2559 | |