| 53 | |
| 54 | |
| 55 | BNSymbolDisplayResult PseudoCFunction::AppendPointerTextToken(const HighLevelILInstruction& instr, int64_t val, |
| 56 | vector<InstructionTextToken>& tokens, DisassemblySettings* settings, BNSymbolDisplayType symbolDisplay, BNOperatorPrecedence precedence) |
| 57 | { |
| 58 | Confidence<Ref<Type>> type = instr.GetType(); |
| 59 | if (type && (type->GetClass() == PointerTypeClass) && type->IsConst()) |
| 60 | { |
| 61 | string stringValue; |
| 62 | size_t childWidth = 0; |
| 63 | if (auto child = type->GetChildType(); child) |
| 64 | childWidth = child->GetWidth(); |
| 65 | if (auto strType = GetFunction()->GetView()->CheckForStringAnnotationType(val, stringValue, false, false, childWidth); strType.has_value()) |
| 66 | { |
| 67 | if (symbolDisplay == DereferenceNonDataSymbols) |
| 68 | { |
| 69 | if (precedence > UnaryOperatorPrecedence) |
| 70 | tokens.emplace_back(BraceToken, "("); |
| 71 | tokens.emplace_back(OperationToken, "*"); |
| 72 | } |
| 73 | tokens.emplace_back(BraceToken, DisassemblyTextRenderer::GetStringLiteralPrefix(strType.value()) + string("\"")); |
| 74 | tokens.emplace_back(StringToken, StringReferenceTokenContext, stringValue, instr.address, strType.value()); |
| 75 | tokens.emplace_back(BraceToken, "\""); |
| 76 | if (symbolDisplay == DereferenceNonDataSymbols && precedence > UnaryOperatorPrecedence) |
| 77 | tokens.emplace_back(BraceToken, ")"); |
| 78 | return OtherSymbolResult; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | if (GetFunction()) |
| 83 | { |
| 84 | // If the pointer has a value of 0, check if it points to a valid address by |
| 85 | // 1. If the binary is relocatable, assign the pointer as nullptr |
| 86 | // 2. else, check if the constant zero which being referenced is a pointer(display as symbol) or not(display as nullptr) |
| 87 | if(val == 0x0 && type && (type->GetClass() == PointerTypeClass)) |
| 88 | { |
| 89 | if (GetFunction()->GetView()->IsRelocatable()) |
| 90 | { |
| 91 | if (symbolDisplay == DereferenceNonDataSymbols) |
| 92 | { |
| 93 | if (precedence > UnaryOperatorPrecedence) |
| 94 | tokens.emplace_back(BraceToken, "("); |
| 95 | tokens.emplace_back(OperationToken, "*"); |
| 96 | } |
| 97 | tokens.emplace_back(CodeSymbolToken, InstructionAddressTokenContext, "nullptr", instr.address, val); |
| 98 | if (symbolDisplay == DereferenceNonDataSymbols && precedence > UnaryOperatorPrecedence) |
| 99 | tokens.emplace_back(BraceToken, ")"); |
| 100 | return OtherSymbolResult; |
| 101 | } |
| 102 | |
| 103 | auto arch = GetHighLevelILFunction()->GetArchitecture(); |
| 104 | auto refs = GetHighLevelILFunction()->GetFunction()->GetConstantsReferencedByInstructionIfAvailable( |
| 105 | arch, instr.address); |
| 106 | bool constantZeroBeingReferencedIsPointer = false; |
| 107 | |
| 108 | for (const BNConstantReference& ref : refs) |
| 109 | if (ref.value == 0x0 && ref.pointer) |
| 110 | constantZeroBeingReferencedIsPointer = true; |
| 111 | if (!constantZeroBeingReferencedIsPointer) |
| 112 | { |
no test coverage detected