| 316 | } |
| 317 | |
| 318 | static Ref<Symbol> DetectPotentialCopyRelocatedVTable(BinaryView* view, uint64_t address) |
| 319 | { |
| 320 | // 32-bit ELF binaries that are dynamically linked to the C++ runtime may use a |
| 321 | // copy relocation for the vtable. The vtable itself will be defined in the .bss |
| 322 | // section, and the copy relocation will cause the dynamic linker to populate it |
| 323 | // at load time from the C++ runtime library. |
| 324 | // |
| 325 | // Detect this by looking for a symbol pointing to the start of the vtable data, |
| 326 | // two pointers before the vtable address. |
| 327 | |
| 328 | int64_t vtableSymbolOffset = -(view->GetAddressSize() * 2); |
| 329 | if (!view->IsValidOffset(address) || !view->IsValidOffset(address + vtableSymbolOffset)) |
| 330 | return nullptr; |
| 331 | |
| 332 | // ELFView does not add a relocation record for RELOC_COPY so we use hueristics here. |
| 333 | if (view->IsOffsetBackedByFile(address)) |
| 334 | return nullptr; |
| 335 | if (!view->IsOffsetWritableSemantics(address)) |
| 336 | return nullptr; |
| 337 | |
| 338 | auto sym = view->GetSymbolByAddress(address + vtableSymbolOffset); |
| 339 | if (!sym || sym->GetShortName().find("__cxxabiv1") == std::string::npos) |
| 340 | return nullptr; |
| 341 | |
| 342 | return sym; |
| 343 | } |
| 344 | |
| 345 | std::optional<TypeInfoVariant> ReadTypeInfoVariant(BinaryView *view, uint64_t objectAddr) |
| 346 | { |
no test coverage detected