Bug Summary

File:build/source/bolt/lib/Core/JumpTable.cpp
Warning:line 122, column 36
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name JumpTable.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-17/lib/clang/17 -D _DEBUG -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D _LIBCPP_ENABLE_ASSERTIONS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/bolt/lib/Core -I /build/source/bolt/lib/Core -I include -I /build/source/llvm/include -I /build/source/bolt/include -I tools/bolt/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-17/lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/source/= -fcoverage-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/source/= -source-date-epoch 1683717183 -O2 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-misleading-indentation -std=c++17 -fdeprecated-macro -fdebug-compilation-dir=/build/source/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/source/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-05-10-133810-16478-1 -x c++ /build/source/bolt/lib/Core/JumpTable.cpp
1//===- bolt/Core/JumpTable.cpp - Jump table at low-level IR ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the JumpTable class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "bolt/Core/JumpTable.h"
14#include "bolt/Core/BinaryFunction.h"
15#include "bolt/Core/BinarySection.h"
16#include "llvm/Support/CommandLine.h"
17
18#define DEBUG_TYPE"bolt" "bolt"
19
20using namespace llvm;
21using namespace bolt;
22
23using JumpTable = bolt::JumpTable;
24
25namespace opts {
26extern cl::opt<JumpTableSupportLevel> JumpTables;
27extern cl::opt<unsigned> Verbosity;
28} // namespace opts
29
30bolt::JumpTable::JumpTable(MCSymbol &Symbol, uint64_t Address, size_t EntrySize,
31 JumpTableType Type, LabelMapType &&Labels,
32 BinarySection &Section)
33 : BinaryData(Symbol, Address, 0, EntrySize, Section), EntrySize(EntrySize),
34 OutputEntrySize(EntrySize), Type(Type), Labels(Labels) {}
35
36std::pair<size_t, size_t>
37bolt::JumpTable::getEntriesForAddress(const uint64_t Addr) const {
38 // Check if this is not an address, but a cloned JT id
39 if ((int64_t)Addr < 0ll)
40 return std::make_pair(0, Entries.size());
41
42 const uint64_t InstOffset = Addr - getAddress();
43 size_t StartIndex = 0, EndIndex = 0;
44 uint64_t Offset = 0;
45
46 for (size_t I = 0; I < Entries.size(); ++I) {
47 auto LI = Labels.find(Offset);
48 if (LI != Labels.end()) {
49 const auto NextLI = std::next(LI);
50 const uint64_t NextOffset =
51 NextLI == Labels.end() ? getSize() : NextLI->first;
52 if (InstOffset >= LI->first && InstOffset < NextOffset) {
53 StartIndex = I;
54 EndIndex = I;
55 while (Offset < NextOffset) {
56 ++EndIndex;
57 Offset += EntrySize;
58 }
59 break;
60 }
61 }
62 Offset += EntrySize;
63 }
64
65 return std::make_pair(StartIndex, EndIndex);
66}
67
68bool bolt::JumpTable::replaceDestination(uint64_t JTAddress,
69 const MCSymbol *OldDest,
70 MCSymbol *NewDest) {
71 bool Patched = false;
72 const std::pair<size_t, size_t> Range = getEntriesForAddress(JTAddress);
73 for (auto I = Range.first; I != Range.second; ++I) {
74 if (Entries[I] == OldDest) {
75 Patched = true;
76 Entries[I] = NewDest;
77 }
78 }
79 return Patched;
80}
81
82void bolt::JumpTable::updateOriginal() {
83 BinaryContext &BC = getSection().getBinaryContext();
84 const uint64_t BaseOffset = getAddress() - getSection().getAddress();
85 uint64_t EntryOffset = BaseOffset;
86 for (MCSymbol *Entry : Entries) {
87 const uint64_t RelType =
88 Type == JTT_NORMAL ? ELF::R_X86_64_64 : ELF::R_X86_64_PC32;
89 const uint64_t RelAddend =
90 Type == JTT_NORMAL ? 0 : EntryOffset - BaseOffset;
91 // Replace existing relocation with the new one to allow any modifications
92 // to the original jump table.
93 if (BC.HasRelocations)
94 getOutputSection().removeRelocationAt(EntryOffset);
95 getOutputSection().addRelocation(EntryOffset, Entry, RelType, RelAddend);
96 EntryOffset += EntrySize;
97 }
98}
99
100void bolt::JumpTable::print(raw_ostream &OS) const {
101 uint64_t Offset = 0;
102 if (Type == JTT_PIC)
1
Assuming field 'Type' is not equal to JTT_PIC
2
Taking false branch
103 OS << "PIC ";
104 ListSeparator LS;
105
106 OS << "Jump table " << getName() << " for function ";
107 for (BinaryFunction *Frag : Parents)
3
Assuming '__begin1' is equal to '__end1'
108 OS << LS << *Frag;
109 OS << " at 0x" << Twine::utohexstr(getAddress()) << " with a total count of "
110 << Count << ":\n";
111 for (const uint64_t EntryAddress : EntriesAsAddress)
112 OS << " absolute offset: 0x" << Twine::utohexstr(EntryAddress) << '\n';
113 for (const MCSymbol *Entry : Entries) {
114 auto LI = Labels.find(Offset);
115 if (Offset
3.1
'Offset' is 0
&& LI != Labels.end()) {
4
Taking false branch
7
Assuming 'Offset' is 0
8
Taking false branch
116 OS << "Jump Table " << LI->second->getName() << " at 0x"
117 << Twine::utohexstr(getAddress() + Offset)
118 << " (possibly part of larger jump table):\n";
119 }
120 OS << format(" 0x%04" PRIx64"l" "x" " : ", Offset) << Entry->getName();
121 if (!Counts.empty()) {
5
Assuming the condition is false
6
Taking false branch
9
Assuming the condition is true
10
Taking true branch
122 OS << " : " << Counts[Offset / EntrySize].Mispreds << "/"
11
Division by zero
123 << Counts[Offset / EntrySize].Count;
124 }
125 OS << '\n';
126 Offset += EntrySize;
127 }
128 OS << "\n\n";
129}