llvm.org GIT mirror llvm / a15cff1
[DebugInfo] add SectionedAddress to DebugInfo interfaces. That patch is the fix for https://bugs.llvm.org/show_bug.cgi?id=40703 "wrong line number info for obj file compiled with -ffunction-sections" bug. The problem happened with only .o files. If object file contains several .text sections then line number information showed incorrectly. The reason for this is that DwarfLineTable could not detect section which corresponds to specified address(because address is the local to the section). And as the result it could not select proper sequence in the line table. The fix is to pass SectionIndex with the address. So that it would be possible to differentiate addresses from various sections. With this fix llvm-objdump shows correct line numbers for disassembled code. Differential review: https://reviews.llvm.org/D58194 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354972 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Lapshin 7 months ago
44 changed file(s) with 785 addition(s) and 329 deletion(s). Raw diff Collapse all Expand all
202202 return true;
203203 }
204204
205 virtual DILineInfo getLineInfoForAddress(uint64_t Address,
205 virtual DILineInfo getLineInfoForAddress(
206 object::SectionedAddress Address,
206207 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
207 virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
208 uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
209 virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
208 virtual DILineInfoTable getLineInfoForAddressRange(
209 object::SectionedAddress Address, uint64_t Size,
210 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
211 virtual DIInliningInfo getInliningInfoForAddress(
212 object::SectionedAddress Address,
210213 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
211214
212215 private:
316316
317317 /// Get the compilation unit, the function DIE and lexical block DIE for the
318318 /// given address where applicable.
319 /// TODO: change input parameter from "uint64_t Address"
320 /// into "SectionedAddress Address"
319321 DIEsForAddress getDIEsForAddress(uint64_t Address);
320322
321 DILineInfo getLineInfoForAddress(uint64_t Address,
323 DILineInfo getLineInfoForAddress(
324 object::SectionedAddress Address,
322325 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
323 DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
326 DILineInfoTable getLineInfoForAddressRange(
327 object::SectionedAddress Address, uint64_t Size,
324328 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
325 DIInliningInfo getInliningInfoForAddress(uint64_t Address,
329 DIInliningInfo getInliningInfoForAddress(
330 object::SectionedAddress Address,
326331 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
327332
328333 bool isLittleEndian() const { return DObj->isLittleEndian(); }
365370 private:
366371 /// Return the compile unit which contains instruction with provided
367372 /// address.
373 /// TODO: change input parameter from "uint64_t Address"
374 /// into "SectionedAddress Address"
368375 DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
369376 };
370377
138138 static void dumpTableHeader(raw_ostream &OS);
139139
140140 static bool orderByAddress(const Row &LHS, const Row &RHS) {
141 return LHS.Address < RHS.Address;
141 return std::tie(LHS.Address.SectionIndex, LHS.Address.Address) <
142 std::tie(RHS.Address.SectionIndex, RHS.Address.Address);
142143 }
143144
144145 /// The program-counter value corresponding to a machine instruction
145 /// generated by the compiler.
146 uint64_t Address;
146 /// generated by the compiler and section index pointing to the section
147 /// containg this PC. If relocation information is present then section
148 /// index is the index of the section which contains above address.
149 /// Otherwise this is object::SectionedAddress::Undef value.
150 object::SectionedAddress Address;
147151 /// An unsigned integer indicating a source line number. Lines are numbered
148152 /// beginning at 1. The compiler may emit the value 0 in cases where an
149153 /// instruction cannot be attributed to any source line.
191195 /// and is described by line table rows [FirstRowIndex, LastRowIndex).
192196 uint64_t LowPC;
193197 uint64_t HighPC;
198 /// If relocation information is present then this is the index of the
199 /// section which contains above addresses. Otherwise this is
200 /// object::SectionedAddress::Undef value.
201 uint64_t SectionIndex;
194202 unsigned FirstRowIndex;
195203 unsigned LastRowIndex;
196204 bool Empty;
198206 void reset();
199207
200208 static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) {
201 return LHS.LowPC < RHS.LowPC;
209 return std::tie(LHS.SectionIndex, LHS.LowPC) <
210 std::tie(RHS.SectionIndex, RHS.LowPC);
202211 }
203212
204213 bool isValid() const {
205214 return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
206215 }
207216
208 bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); }
217 bool containsPC(object::SectionedAddress PC) const {
218 return SectionIndex == PC.SectionIndex &&
219 (LowPC <= PC.Address && PC.Address < HighPC);
220 }
209221 };
210222
211223 struct LineTable {
222234
223235 /// Returns the index of the row with file/line info for a given address,
224236 /// or UnknownRowIndex if there is no such row.
225 uint32_t lookupAddress(uint64_t Address) const;
226
227 bool lookupAddressRange(uint64_t Address, uint64_t Size,
237 uint32_t lookupAddress(object::SectionedAddress Address) const;
238
239 bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size,
228240 std::vector &Result) const;
229241
230242 bool hasFileAtIndex(uint64_t FileIndex) const;
237249
238250 /// Fills the Result argument with the file and line information
239251 /// corresponding to Address. Returns true on success.
240 bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir,
252 bool getFileLineInfoForAddress(object::SectionedAddress Address,
253 const char *CompDir,
241254 DILineInfoSpecifier::FileLineInfoKind Kind,
242255 DILineInfo &Result) const;
243256
262275
263276 private:
264277 uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
265 uint64_t Address) const;
278 object::SectionedAddress Address) const;
266279 Optional
267280 getSourceByIndex(uint64_t FileIndex,
268281 DILineInfoSpecifier::FileLineInfoKind Kind) const;
282
283 uint32_t lookupAddressImpl(object::SectionedAddress Address) const;
284
285 bool lookupAddressRangeImpl(object::SectionedAddress Address, uint64_t Size,
286 std::vector &Result) const;
269287 };
270288
271289 const LineTable *getLineTable(uint32_t Offset) const;
7575 /// list. Has to be passed base address of the compile unit referencing this
7676 /// range list.
7777 DWARFAddressRangesVector
78 getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;
78 getAbsoluteRanges(llvm::Optional<object::SectionedAddress> BaseAddr) const;
7979 };
8080
8181 } // end namespace llvm
3636 Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr);
3737 void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
3838 uint64_t &CurrentBase, DIDumpOptions DumpOpts,
39 llvm::function_refSectionedAddress>(uint32_t)>
39 llvm::function_refobject::SectionedAddress>(uint32_t)>
4040 LookupPooledAddress) const;
4141 bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; }
4242 };
4646 public:
4747 /// Build a DWARFAddressRangesVector from a rangelist.
4848 DWARFAddressRangesVector
49 getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
49 getAbsoluteRanges(llvm::Optional<object::SectionedAddress> BaseAddr,
5050 DWARFUnit &U) const;
5151 };
5252
7878 const DWARFUnit *getUnit() const { return U; }
7979 void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const;
8080 void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts,
81 SectionedAddress SA) const;
81 object::SectionedAddress SA) const;
8282 static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
8383 DIDumpOptions DumpOpts, uint64_t SectionIndex);
8484
107107 Optional getAsSignedConstant() const;
108108 Optional getAsCString() const;
109109 Optional getAsAddress() const;
110 Optional<SectionedAddress> getAsSectionedAddress() const;
110 Optional<object::SectionedAddress> getAsSectionedAddress() const;
111111 Optional getAsSectionOffset() const;
112112 Optional> getAsBlock() const;
113113 Optional getAsCStringOffset() const;
245245 return None;
246246 }
247247
248 inline Optional<SectionedAddress>
248 inline Optional<object::SectionedAddress>
249249 toSectionedAddress(const Optional &V) {
250250 if (V)
251251 return V->getAsSectionedAddress();
156156 uint8_t getAddrSize() const { return Header.getAddrSize(); }
157157
158158 void dump(raw_ostream &OS,
159 llvm::function_refSectionedAddress>(uint32_t)>
159 llvm::function_refobject::SectionedAddress>(uint32_t)>
160160 LookupPooledAddress,
161161 DIDumpOptions DumpOpts = {}) const;
162162
233233 template
234234 void DWARFListTableBase::dump(
235235 raw_ostream &OS,
236 llvm::function_refSectionedAddress>(uint32_t)>
236 llvm::function_refobject::SectionedAddress>(uint32_t)>
237237 LookupPooledAddress,
238238 DIDumpOptions DumpOpts) const {
239239 Header.dump(OS, DumpOpts);
2121 bool IsNameUnique;
2222 };
2323
24 struct SectionedAddress {
25 uint64_t Address;
26 uint64_t SectionIndex;
27 };
28
2924 } // end namespace llvm
3025
3126 #endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
216216 Optional RngListTable;
217217
218218 mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
219 llvm::Optional<SectionedAddress> BaseAddr;
219 llvm::Optional<object::SectionedAddress> BaseAddr;
220220 /// The compile unit debug information entry items.
221221 std::vector DieArray;
222222
303303 RangeSectionBase = Base;
304304 }
305305
306 Optional<SectionedAddress> getAddrOffsetSectionItem(uint32_t Index) const;
306 Optional<object::SectionedAddress>
307 getAddrOffsetSectionItem(uint32_t Index) const;
307308 Optional getStringOffsetSectionItem(uint32_t Index) const;
308309
309310 DWARFDataExtractor getDebugInfoExtractor() const;
374375 llvm_unreachable("Invalid UnitType.");
375376 }
376377
377 llvm::Optional<SectionedAddress> getBaseAddress();
378 llvm::Optional<object::SectionedAddress> getBaseAddress();
378379
379380 DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
380381 extractDIEsIfNeeded(ExtractUnitDIEOnly);
4242 void dump(raw_ostream &OS, DIDumpOptions DIDumpOpts) override;
4343
4444 DILineInfo getLineInfoForAddress(
45 uint64_t Address,
45 object::SectionedAddress Address,
4646 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
4747 DILineInfoTable getLineInfoForAddressRange(
48 uint64_t Address, uint64_t Size,
48 object::SectionedAddress Address, uint64_t Size,
4949 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
5050 DIInliningInfo getInliningInfoForAddress(
51 uint64_t Address,
51 object::SectionedAddress Address,
5252 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
5353
5454 private:
2323 public:
2424 virtual ~SymbolizableModule() = default;
2525
26 virtual DILineInfo symbolizeCode(uint64_t ModuleOffset,
26 virtual DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
2727 FunctionNameKind FNKind,
2828 bool UseSymbolTable) const = 0;
29 virtual DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset,
30 FunctionNameKind FNKind,
31 bool UseSymbolTable) const = 0;
32 virtual DIGlobal symbolizeData(uint64_t ModuleOffset) const = 0;
29 virtual DIInliningInfo
30 symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
31 FunctionNameKind FNKind, bool UseSymbolTable) const = 0;
32 virtual DIGlobal
33 symbolizeData(object::SectionedAddress ModuleOffset) const = 0;
3334
3435 // Return true if this is a 32-bit x86 PE COFF module.
3536 virtual bool isWin32Module() const = 0;
5959 }
6060
6161 Expected symbolizeCode(const std::string &ModuleName,
62 uint64_t ModuleOffset,
62 object::SectionedAddress ModuleOffset,
6363 StringRef DWPName = "");
64 Expected symbolizeInlinedCode(const std::string &ModuleName,
65 uint64_t ModuleOffset,
66 StringRef DWPName = "");
64 Expected
65 symbolizeInlinedCode(const std::string &ModuleName,
66 object::SectionedAddress ModuleOffset,
67 StringRef DWPName = "");
6768 Expected symbolizeData(const std::string &ModuleName,
68 uint64_t ModuleOffset);
69 object::SectionedAddress ModuleOffset);
6970 void flush();
7071
7172 static std::string
133133 DataRefImpl getRawDataRefImpl() const;
134134 const ObjectFile *getObject() const;
135135 };
136
137 struct SectionedAddress {
138 // TODO: constructors could be removed when C++14 would be adopted.
139 SectionedAddress() {}
140 SectionedAddress(uint64_t Addr, uint64_t SectIdx)
141 : Address(Addr), SectionIndex(SectIdx) {}
142
143 const static uint64_t UndefSection = UINT64_MAX;
144
145 uint64_t Address = 0;
146 uint64_t SectionIndex = UndefSection;
147 };
148
149 inline bool operator<(const SectionedAddress &LHS,
150 const SectionedAddress &RHS) {
151 return std::tie(LHS.SectionIndex, LHS.Address) <
152 std::tie(RHS.SectionIndex, RHS.Address);
153 }
154
155 inline bool operator==(const SectionedAddress &LHS,
156 const SectionedAddress &RHS) {
157 return std::tie(LHS.SectionIndex, LHS.Address) ==
158 std::tie(RHS.SectionIndex, RHS.Address);
159 }
136160
137161 /// This is a value type class that represents a single symbol in the list of
138162 /// symbols in the object file.
267267 }
268268
269269 // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
270 static void
271 dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,
272 llvm::function_ref(uint32_t)>
273 LookupPooledAddress,
274 DIDumpOptions DumpOpts) {
270 static void dumpRnglistsSection(
271 raw_ostream &OS, DWARFDataExtractor &rnglistData,
272 llvm::function_ref(uint32_t)>
273 LookupPooledAddress,
274 DIDumpOptions DumpOpts) {
275275 uint32_t Offset = 0;
276276 while (rnglistData.isValidOffset(Offset)) {
277277 llvm::DWARFDebugRnglistTable Rnglists;
937937 return Result;
938938 }
939939
940 /// TODO: change input parameter from "uint64_t Address"
941 /// into "SectionedAddress Address"
940942 static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
941943 uint64_t Address,
942944 FunctionNameKind Kind,
965967 return FoundResult;
966968 }
967969
968 DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address,
970 DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address,
969971 DILineInfoSpecifier Spec) {
970972 DILineInfo Result;
971973
972 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
974 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
973975 if (!CU)
974976 return Result;
975 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind,
976 Result.FunctionName,
977 Result.StartLine);
977
978 getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
979 Result.FunctionName, Result.StartLine);
978980 if (Spec.FLIKind != FileLineInfoKind::None) {
979 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU))
980 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
981 Spec.FLIKind, Result);
981 if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
982 LineTable->getFileLineInfoForAddress(
983 {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
984 Spec.FLIKind, Result);
985 }
982986 }
983987 return Result;
984988 }
985989
986 DILineInfoTable
987 DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
988 DILineInfoSpecifier Spec) {
990 DILineInfoTable DWARFContext::getLineInfoForAddressRange(
991 object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
989992 DILineInfoTable Lines;
990 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
993 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
991994 if (!CU)
992995 return Lines;
993996
994997 std::string FunctionName = "";
995998 uint32_t StartLine = 0;
996 getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName,
997 StartLine);
999 getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
1000 FunctionName, StartLine);
9981001
9991002 // If the Specifier says we don't need FileLineInfo, just
10001003 // return the top-most function at the starting address.
10021005 DILineInfo Result;
10031006 Result.FunctionName = FunctionName;
10041007 Result.StartLine = StartLine;
1005 Lines.push_back(std::make_pair(Address, Result));
1008 Lines.push_back(std::make_pair(Address.Address, Result));
10061009 return Lines;
10071010 }
10081011
10101013
10111014 // Get the index of row we're looking for in the line table.
10121015 std::vector RowVector;
1013 if (!LineTable->lookupAddressRange(Address, Size, RowVector))
1016 if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex},
1017 Size, RowVector)) {
10141018 return Lines;
1019 }
10151020
10161021 for (uint32_t RowIndex : RowVector) {
10171022 // Take file number and line/column from the row.
10231028 Result.Line = Row.Line;
10241029 Result.Column = Row.Column;
10251030 Result.StartLine = StartLine;
1026 Lines.push_back(std::make_pair(Row.Address, Result));
1031 Lines.push_back(std::make_pair(Row.Address.Address, Result));
10271032 }
10281033
10291034 return Lines;
10301035 }
10311036
10321037 DIInliningInfo
1033 DWARFContext::getInliningInfoForAddress(uint64_t Address,
1038 DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
10341039 DILineInfoSpecifier Spec) {
10351040 DIInliningInfo InliningInfo;
10361041
1037 DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
1042 DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
10381043 if (!CU)
10391044 return InliningInfo;
10401045
10411046 const DWARFLineTable *LineTable = nullptr;
10421047 SmallVector InlinedChain;
1043 CU->getInlinedChainForAddress(Address, InlinedChain);
1048 CU->getInlinedChainForAddress(Address.Address, InlinedChain);
10441049 if (InlinedChain.size() == 0) {
10451050 // If there is no DIE for address (e.g. it is in unavailable .dwo file),
10461051 // try to at least get file/line info from symbol table.
10471052 if (Spec.FLIKind != FileLineInfoKind::None) {
10481053 DILineInfo Frame;
10491054 LineTable = getLineTableForUnit(CU);
1050 if (LineTable &&
1051 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
1052 Spec.FLIKind, Frame))
1055 if (LineTable && LineTable->getFileLineInfoForAddress(
1056 {Address.Address, Address.SectionIndex},
1057 CU->getCompilationDir(), Spec.FLIKind, Frame))
10531058 InliningInfo.addFrame(Frame);
10541059 }
10551060 return InliningInfo;
10711076 LineTable = getLineTableForUnit(CU);
10721077 // For the topmost routine, get file/line info from line table.
10731078 if (LineTable)
1074 LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(),
1075 Spec.FLIKind, Frame);
1079 LineTable->getFileLineInfoForAddress(
1080 {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
1081 Spec.FLIKind, Frame);
10761082 } else {
10771083 // Otherwise, use call file, call line and call column from
10781084 // previous DIE in inlined chain.
1414 uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
1515 uint64_t *SecNdx) const {
1616 if (SecNdx)
17 *SecNdx = -1ULL;
17 *SecNdx = object::SectionedAddress::UndefSection;
1818 if (!Section)
1919 return getUnsigned(Off, Size);
2020 Optional Rel = Obj->find(*Section, *Off);
352352 }
353353
354354 void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
355 Address = 0;
355 Address.Address = 0;
356 Address.SectionIndex = object::SectionedAddress::UndefSection;
356357 Line = 1;
357358 Column = 0;
358359 File = 1;
372373 }
373374
374375 void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
375 OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
376 OS << format("0x%16.16" PRIx64 " %6u %6u", Address.Address, Line, Column)
376377 << format(" %6u %3u %13u ", File, Isa, Discriminator)
377378 << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
378379 << (PrologueEnd ? " prologue_end" : "")
385386 void DWARFDebugLine::Sequence::reset() {
386387 LowPC = 0;
387388 HighPC = 0;
389 SectionIndex = object::SectionedAddress::UndefSection;
388390 FirstRowIndex = 0;
389391 LastRowIndex = 0;
390392 Empty = true;
425427 if (Sequence.Empty) {
426428 // Record the beginning of instruction sequence.
427429 Sequence.Empty = false;
428 Sequence.LowPC = Row.Address;
430 Sequence.LowPC = Row.Address.Address;
429431 Sequence.FirstRowIndex = RowNumber;
430432 }
431433 ++RowNumber;
432434 LineTable->appendRow(Row);
433435 if (Row.EndSequence) {
434436 // Record the end of instruction sequence.
435 Sequence.HighPC = Row.Address;
437 Sequence.HighPC = Row.Address.Address;
436438 Sequence.LastRowIndex = RowNumber;
439 Sequence.SectionIndex = Row.Address.SectionIndex;
437440 if (Sequence.isValid())
438441 LineTable->appendSequence(Sequence);
439442 Sequence.reset();
564567 ExtOffset, DebugLineData.getAddressSize(),
565568 Len - 1);
566569 }
567 State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr);
570 State.Row.Address.Address = DebugLineData.getRelocatedAddress(
571 OffsetPtr, &State.Row.Address.SectionIndex);
568572 if (OS)
569 *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address);
573 *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address);
570574 break;
571575
572576 case DW_LNE_define_file:
653657 {
654658 uint64_t AddrOffset =
655659 DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
656 State.Row.Address += AddrOffset;
660 State.Row.Address.Address += AddrOffset;
657661 if (OS)
658662 *OS << " (" << AddrOffset << ")";
659663 }
711715 uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
712716 uint64_t AddrOffset =
713717 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
714 State.Row.Address += AddrOffset;
718 State.Row.Address.Address += AddrOffset;
715719 if (OS)
716720 *OS
717721 << format(" (0x%16.16" PRIx64 ")", AddrOffset);
730734 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
731735 {
732736 uint16_t PCOffset = DebugLineData.getU16(OffsetPtr);
733 State.Row.Address += PCOffset;
737 State.Row.Address.Address += PCOffset;
734738 if (OS)
735739 *OS
736740 << format(" (0x%16.16" PRIx64 ")", PCOffset);
813817 int32_t LineOffset =
814818 Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
815819 State.Row.Line += LineOffset;
816 State.Row.Address += AddrOffset;
820 State.Row.Address.Address += AddrOffset;
817821
818822 if (OS) {
819823 *OS << "address += " << AddrOffset << ", line += " << LineOffset
849853 return Error::success();
850854 }
851855
852 uint32_t
853 DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
854 uint64_t Address) const {
856 uint32_t DWARFDebugLine::LineTable::findRowInSeq(
857 const DWARFDebugLine::Sequence &Seq,
858 object::SectionedAddress Address) const {
855859 if (!Seq.containsPC(Address))
856860 return UnknownRowIndex;
861 assert(Seq.SectionIndex == Address.SectionIndex);
857862 // Search for instruction address in the rows describing the sequence.
858863 // Rows are stored in a vector, so we may use arithmetical operations with
859864 // iterators.
866871 if (RowPos == LastRow) {
867872 return Seq.LastRowIndex - 1;
868873 }
874 assert(Seq.SectionIndex == RowPos->Address.SectionIndex);
869875 uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
870 if (RowPos->Address > Address) {
876 if (RowPos->Address.Address > Address.Address) {
871877 if (RowPos == FirstRow)
872878 return UnknownRowIndex;
873879 else
876882 return Index;
877883 }
878884
879 uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
885 uint32_t DWARFDebugLine::LineTable::lookupAddress(
886 object::SectionedAddress Address) const {
887
888 // Search for relocatable addresses
889 uint32_t Result = lookupAddressImpl(Address);
890
891 if (Result != UnknownRowIndex ||
892 Address.SectionIndex == object::SectionedAddress::UndefSection)
893 return Result;
894
895 // Search for absolute addresses
896 Address.SectionIndex = object::SectionedAddress::UndefSection;
897 return lookupAddressImpl(Address);
898 }
899
900 uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
901 object::SectionedAddress Address) const {
880902 if (Sequences.empty())
881903 return UnknownRowIndex;
882904 // First, find an instruction sequence containing the given address.
883905 DWARFDebugLine::Sequence Sequence;
884 Sequence.LowPC = Address;
906 Sequence.SectionIndex = Address.SectionIndex;
907 Sequence.LowPC = Address.Address;
885908 SequenceIter FirstSeq = Sequences.begin();
886909 SequenceIter LastSeq = Sequences.end();
887910 SequenceIter SeqPos = std::lower_bound(
888911 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
889912 DWARFDebugLine::Sequence FoundSeq;
913
890914 if (SeqPos == LastSeq) {
891915 FoundSeq = Sequences.back();
892 } else if (SeqPos->LowPC == Address) {
916 } else if (SeqPos->LowPC == Address.Address &&
917 SeqPos->SectionIndex == Address.SectionIndex) {
893918 FoundSeq = *SeqPos;
894919 } else {
895920 if (SeqPos == FirstSeq)
896921 return UnknownRowIndex;
897922 FoundSeq = *(SeqPos - 1);
898923 }
924 if (FoundSeq.SectionIndex != Address.SectionIndex)
925 return UnknownRowIndex;
899926 return findRowInSeq(FoundSeq, Address);
900927 }
901928
902929 bool DWARFDebugLine::LineTable::lookupAddressRange(
903 uint64_t Address, uint64_t Size, std::vector &Result) const {
930 object::SectionedAddress Address, uint64_t Size,
931 std::vector &Result) const {
932
933 // Search for relocatable addresses
934 if (lookupAddressRangeImpl(Address, Size, Result))
935 return true;
936
937 if (Address.SectionIndex == object::SectionedAddress::UndefSection)
938 return false;
939
940 // Search for absolute addresses
941 Address.SectionIndex = object::SectionedAddress::UndefSection;
942 return lookupAddressRangeImpl(Address, Size, Result);
943 }
944
945 bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
946 object::SectionedAddress Address, uint64_t Size,
947 std::vector &Result) const {
904948 if (Sequences.empty())
905949 return false;
906 uint64_t EndAddr = Address + Size;
950 uint64_t EndAddr = Address.Address + Size;
907951 // First, find an instruction sequence containing the given address.
908952 DWARFDebugLine::Sequence Sequence;
909 Sequence.LowPC = Address;
953 Sequence.SectionIndex = Address.SectionIndex;
954 Sequence.LowPC = Address.Address;
910955 SequenceIter FirstSeq = Sequences.begin();
911956 SequenceIter LastSeq = Sequences.end();
912957 SequenceIter SeqPos = std::lower_bound(
913958 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
914 if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
959 if (SeqPos == LastSeq || !SeqPos->containsPC(Address)) {
915960 if (SeqPos == FirstSeq)
916961 return false;
917962 SeqPos--;
933978 FirstRowIndex = findRowInSeq(CurSeq, Address);
934979
935980 // Figure out the last row in the range.
936 uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
981 uint32_t LastRowIndex =
982 findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
937983 if (LastRowIndex == UnknownRowIndex)
938984 LastRowIndex = CurSeq.LastRowIndex - 1;
939985
10101056 }
10111057
10121058 bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
1013 uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
1014 DILineInfo &Result) const {
1059 object::SectionedAddress Address, const char *CompDir,
1060 FileLineInfoKind Kind, DILineInfo &Result) const {
10151061 // Get the index of row we're looking for in the line table.
10161062 uint32_t RowIndex = lookupAddress(Address);
10171063 if (RowIndex == -1U)
6767 }
6868
6969 DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
70 llvm::Optional<SectionedAddress> BaseAddr) const {
70 llvm::Optional<object::SectionedAddress> BaseAddr) const {
7171 DWARFAddressRangesVector Res;
7272 for (const RangeListEntry &RLE : Entries) {
7373 if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
111111 return Error::success();
112112 }
113113
114 DWARFAddressRangesVector
115 DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional BaseAddr,
116 DWARFUnit &U) const {
114 DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
115 llvm::Optional BaseAddr, DWARFUnit &U) const {
117116 DWARFAddressRangesVector Res;
118117 for (const RangeListEntry &RLE : Entries) {
119118 if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
173172 void RangeListEntry::dump(
174173 raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
175174 uint64_t &CurrentBase, DIDumpOptions DumpOpts,
176 llvm::function_refSectionedAddress>(uint32_t)>
175 llvm::function_refobject::SectionedAddress>(uint32_t)>
177176 LookupPooledAddress) const {
178177 auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,
179178 uint8_t AddrSize, DIDumpOptions DumpOpts) {
9999 auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
100100 if (LL) {
101101 uint64_t BaseAddr = 0;
102 if (Optional<SectionedAddress> BA = U->getBaseAddress())
102 if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
103103 BaseAddr = BA->Address;
104104 LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
105105 BaseAddr, Indent);
124124 Data, &Offset, UseLocLists ? U->getVersion() : 4);
125125
126126 uint64_t BaseAddr = 0;
127 if (Optional<SectionedAddress> BA = U->getBaseAddress())
127 if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
128128 BaseAddr = BA->Address;
129129
130130 if (LL)
359359
360360 void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
361361 DIDumpOptions DumpOpts,
362 SectionedAddress SA) const {
362 object::SectionedAddress SA) const {
363363 OS << format("0x%016" PRIx64, SA.Address);
364364 dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
365365 SA.SectionIndex);
396396 case DW_FORM_addrx3:
397397 case DW_FORM_addrx4:
398398 case DW_FORM_GNU_addr_index: {
399 Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
399 Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue);
400400 if (!A || DumpOpts.Verbose)
401401 AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue);
402402 if (U == nullptr)
617617 return SA->Address;
618618 return None;
619619 }
620 Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const {
620 Optional<object::SectionedAddress>
621 DWARFFormValue::getAsSectionedAddress() const {
621622 if (!isFormClass(FC_Address))
622623 return None;
623624 if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) {
624625 uint32_t Index = Value.uval;
625626 if (!U)
626627 return None;
627 Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
628 Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
628629 if (!SA)
629630 return None;
630631 return SA;
196196 getAddressByteSize());
197197 }
198198
199 Optional<SectionedAddress>
199 Optional<object::SectionedAddress>
200200 DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
201201 if (IsDWO) {
202202 auto R = Context.info_section_units();
743743 return Abbrevs;
744744 }
745745
746 llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() {
746 llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
747747 if (BaseAddr)
748748 return BaseAddr;
749749
771771 uint32_t RowIndex = 0;
772772 for (const auto &Row : LineTable->Rows) {
773773 // Verify row address.
774 if (Row.Address < PrevAddress) {
774 if (Row.Address.Address < PrevAddress) {
775775 ++NumDebugLineErrors;
776776 error() << ".debug_line["
777777 << format("0x%08" PRIx64,
801801 if (Row.EndSequence)
802802 PrevAddress = 0;
803803 else
804 PrevAddress = Row.Address;
804 PrevAddress = Row.Address.Address;
805805 ++RowIndex;
806806 }
807807 }
2929
3030 void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
3131
32 DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
32 DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
3333 DILineInfoSpecifier Specifier) {
3434 DILineInfo Result;
35 Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
35 Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind);
3636
3737 uint32_t Length = 1;
3838 std::unique_ptr Symbol =
39 Session->findSymbolByAddress(Address, PDB_SymType::None);
39 Session->findSymbolByAddress(Address.Address, PDB_SymType::None);
4040 if (auto Func = dyn_cast_or_null(Symbol.get())) {
4141 Length = Func->getLength();
4242 } else if (auto Data = dyn_cast_or_null(Symbol.get())) {
4545
4646 // If we couldn't find a symbol, then just assume 1 byte, so that we get
4747 // only the line number of the first instruction.
48 auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
48 auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Length);
4949 if (!LineNumbers || LineNumbers->getChildCount() == 0)
5050 return Result;
5151
6262 }
6363
6464 DILineInfoTable
65 PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
65 PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
66 uint64_t Size,
6667 DILineInfoSpecifier Specifier) {
6768 if (Size == 0)
6869 return DILineInfoTable();
6970
7071 DILineInfoTable Table;
71 auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
72 auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size);
7273 if (!LineNumbers || LineNumbers->getChildCount() == 0)
7374 return Table;
7475
7576 while (auto LineInfo = LineNumbers->getNext()) {
76 DILineInfo LineEntry =
77 getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
77 DILineInfo LineEntry = getLineInfoForAddress(
78 {LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier);
7879 Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
7980 }
8081 return Table;
8182 }
8283
8384 DIInliningInfo
84 PDBContext::getInliningInfoForAddress(uint64_t Address,
85 PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
8586 DILineInfoSpecifier Specifier) {
8687 DIInliningInfo InlineInfo;
8788 DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
221221 isa(DebugInfoContext.get());
222222 }
223223
224 DILineInfo SymbolizableObjectFile::symbolizeCode(uint64_t ModuleOffset,
225 FunctionNameKind FNKind,
226 bool UseSymbolTable) const {
224 DILineInfo
225 SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset,
226 FunctionNameKind FNKind,
227 bool UseSymbolTable) const {
227228 DILineInfo LineInfo;
228229 if (DebugInfoContext) {
229230 LineInfo = DebugInfoContext->getLineInfoForAddress(
233234 if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) {
234235 std::string FunctionName;
235236 uint64_t Start, Size;
236 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
237 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address,
237238 FunctionName, Start, Size)) {
238239 LineInfo.FunctionName = FunctionName;
239240 }
242243 }
243244
244245 DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
245 uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const {
246 object::SectionedAddress ModuleOffset, FunctionNameKind FNKind,
247 bool UseSymbolTable) const {
246248 DIInliningInfo InlinedContext;
247249
248250 if (DebugInfoContext)
256258 if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) {
257259 std::string FunctionName;
258260 uint64_t Start, Size;
259 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
261 if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address,
260262 FunctionName, Start, Size)) {
261263 InlinedContext.getMutableFrame(InlinedContext.getNumberOfFrames() - 1)
262264 ->FunctionName = FunctionName;
266268 return InlinedContext;
267269 }
268270
269 DIGlobal SymbolizableObjectFile::symbolizeData(uint64_t ModuleOffset) const {
271 DIGlobal SymbolizableObjectFile::symbolizeData(
272 object::SectionedAddress ModuleOffset) const {
270273 DIGlobal Res;
271 getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset, Res.Name, Res.Start,
272 Res.Size);
274 getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset.Address, Res.Name,
275 Res.Start, Res.Size);
273276 return Res;
274277 }
3232 static ErrorOr>
3333 create(object::ObjectFile *Obj, std::unique_ptr DICtx);
3434
35 DILineInfo symbolizeCode(uint64_t ModuleOffset, FunctionNameKind FNKind,
35 DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
36 FunctionNameKind FNKind,
3637 bool UseSymbolTable) const override;
37 DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset,
38 DIInliningInfo symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
3839 FunctionNameKind FNKind,
3940 bool UseSymbolTable) const override;
40 DIGlobal symbolizeData(uint64_t ModuleOffset) const override;
41 DIGlobal symbolizeData(object::SectionedAddress ModuleOffset) const override;
4142
4243 // Return true if this is a 32-bit x86 PE COFF module.
4344 bool isWin32Module() const override;
5151
5252 Expected
5353 LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
54 uint64_t ModuleOffset, StringRef DWPName) {
54 object::SectionedAddress ModuleOffset,
55 StringRef DWPName) {
5556 SymbolizableModule *Info;
5657 if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
5758 Info = InfoOrErr.get();
6667 // If the user is giving us relative addresses, add the preferred base of the
6768 // object to the offset before we do the query. It's what DIContext expects.
6869 if (Opts.RelativeAddresses)
69 ModuleOffset += Info->getModulePreferredBase();
70 ModuleOffset.Address += Info->getModulePreferredBase();
7071
7172 DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts.PrintFunctions,
7273 Opts.UseSymbolTable);
7778
7879 Expected
7980 LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
80 uint64_t ModuleOffset, StringRef DWPName) {
81 object::SectionedAddress ModuleOffset,
82 StringRef DWPName) {
8183 SymbolizableModule *Info;
8284 if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName))
8385 Info = InfoOrErr.get();
9294 // If the user is giving us relative addresses, add the preferred base of the
9395 // object to the offset before we do the query. It's what DIContext expects.
9496 if (Opts.RelativeAddresses)
95 ModuleOffset += Info->getModulePreferredBase();
97 ModuleOffset.Address += Info->getModulePreferredBase();
9698
9799 DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(
98100 ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable);
105107 return InlinedContext;
106108 }
107109
108 Expected LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
109 uint64_t ModuleOffset) {
110 Expected
111 LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
112 object::SectionedAddress ModuleOffset) {
110113 SymbolizableModule *Info;
111114 if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName))
112115 Info = InfoOrErr.get();
122125 // the object to the offset before we do the query. It's what DIContext
123126 // expects.
124127 if (Opts.RelativeAddresses)
125 ModuleOffset += Info->getModulePreferredBase();
128 ModuleOffset.Address += Info->getModulePreferredBase();
126129
127130 DIGlobal Global = Info->symbolizeData(ModuleOffset);
128131 if (Opts.Demangle)
0 # The code below is the reduced version of the output
1 # from the following invocation and source:
2 #
3 # // test.cpp:
4 #void f1() {}
5 #void f2() {}
6 #
7 # clang -gdwarf-5 -ffunction-sections test.cpp -o test.s -S
8
9 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -dwarf-version=5 %s -o %t.o
10 # RUN: llvm-objdump -disassemble -line-numbers -r -s -section-headers -t %t.o | FileCheck %s
11
12
13 # CHECK: 0000000000000000 _Z2f1v
14 # CHECK-NOT: test.cpp:2
15 # CHECK: test.cpp:1
16 # CHECK-NOT: test.cpp:2
17 # CHECK: 0000000000000000 _Z2f2v
18 # CHECK-NOT: test.cpp:1
19 # CHECK: test.cpp:2
20 # CHECK-NOT: test.cpp:1
21
22
23 .text
24 .file "test.cpp"
25 .section .text._Z2f1v,"ax",@progbits
26 .globl _Z2f1v # -- Begin function _Z2f1v
27 .p2align 4, 0x90
28 .type _Z2f1v,@function
29 _Z2f1v: # @_Z2f1v
30 .Lfunc_begin0:
31 .file 0 "/home/avl" "test.cpp" md5 0xefae234cc05b45384d782316d3a5d338
32 .file 1 "test.cpp" md5 0xefae234cc05b45384d782316d3a5d338
33 .loc 1 1 0 # test.cpp:1:0
34 .cfi_startproc
35 # %bb.0: # %entry
36 pushq %rbp
37 .cfi_def_cfa_offset 16
38 .cfi_offset %rbp, -16
39 movq %rsp, %rbp
40 .cfi_def_cfa_register %rbp
41 .Ltmp0:
42 .loc 1 1 12 prologue_end # test.cpp:1:12
43 popq %rbp
44 .cfi_def_cfa %rsp, 8
45 retq
46 .Ltmp1:
47 .Lfunc_end0:
48 .size _Z2f1v, .Lfunc_end0-_Z2f1v
49 .cfi_endproc
50 # -- End function
51 .section .text._Z2f2v,"ax",@progbits
52 .globl _Z2f2v # -- Begin function _Z2f2v
53 .p2align 4, 0x90
54 .type _Z2f2v,@function
55 _Z2f2v: # @_Z2f2v
56 .Lfunc_begin1:
57 .loc 1 2 0 # test.cpp:2:0
58 .cfi_startproc
59 # %bb.0: # %entry
60 pushq %rbp
61 .cfi_def_cfa_offset 16
62 .cfi_offset %rbp, -16
63 movq %rsp, %rbp
64 .cfi_def_cfa_register %rbp
65 .Ltmp2:
66 .loc 1 2 12 prologue_end # test.cpp:2:12
67 popq %rbp
68 .cfi_def_cfa %rsp, 8
69 retq
70 .Ltmp3:
71 .Lfunc_end1:
72 .size _Z2f2v, .Lfunc_end1-_Z2f2v
73 .cfi_endproc
74 # -- End function
75 .section .debug_str_offsets,"",@progbits
76 .long 32
77 .short 5
78 .short 0
79 .Lstr_offsets_base0:
80 .section .debug_str,"MS",@progbits,1
81 .Linfo_string0:
82 .asciz "clang version 9.0.0 (https://github.com/llvm/llvm-project.git ebfc1e5af7a65381d858612517e6414ef58df482)" # string offset=0
83 .Linfo_string1:
84 .asciz "test.cpp" # string offset=104
85 .Linfo_string2:
86 .asciz "/home/avl" # string offset=113
87 .Linfo_string3:
88 .asciz "_Z2f1v" # string offset=123
89 .Linfo_string4:
90 .asciz "f1" # string offset=130
91 .Linfo_string5:
92 .asciz "_Z2f2v" # string offset=133
93 .Linfo_string6:
94 .asciz "f2" # string offset=140
95 .section .debug_str_offsets,"",@progbits
96 .long .Linfo_string0
97 .long .Linfo_string1
98 .long .Linfo_string2
99 .long .Linfo_string3
100 .long .Linfo_string4
101 .long .Linfo_string5
102 .long .Linfo_string6
103 .section .debug_abbrev,"",@progbits
104 .byte 1 # Abbreviation Code
105 .byte 17 # DW_TAG_compile_unit
106 .byte 1 # DW_CHILDREN_yes
107 .byte 37 # DW_AT_producer
108 .byte 37 # DW_FORM_strx1
109 .byte 19 # DW_AT_language
110 .byte 5 # DW_FORM_data2
111 .byte 3 # DW_AT_name
112 .byte 37 # DW_FORM_strx1
113 .byte 114 # DW_AT_str_offsets_base
114 .byte 23 # DW_FORM_sec_offset
115 .byte 16 # DW_AT_stmt_list
116 .byte 23 # DW_FORM_sec_offset
117 .byte 27 # DW_AT_comp_dir
118 .byte 37 # DW_FORM_strx1
119 .byte 115 # DW_AT_addr_base
120 .byte 23 # DW_FORM_sec_offset
121 .byte 17 # DW_AT_low_pc
122 .byte 1 # DW_FORM_addr
123 .byte 85 # DW_AT_ranges
124 .byte 35 # DW_FORM_rnglistx
125 .byte 116 # DW_AT_rnglists_base
126 .byte 23 # DW_FORM_sec_offset
127 .byte 0 # EOM(1)
128 .byte 0 # EOM(2)
129 .byte 2 # Abbreviation Code
130 .byte 46 # DW_TAG_subprogram
131 .byte 0 # DW_CHILDREN_no
132 .byte 17 # DW_AT_low_pc
133 .byte 27 # DW_FORM_addrx
134 .byte 18 # DW_AT_high_pc
135 .byte 6 # DW_FORM_data4
136 .byte 64 # DW_AT_frame_base
137 .byte 24 # DW_FORM_exprloc
138 .byte 110 # DW_AT_linkage_name
139 .byte 37 # DW_FORM_strx1
140 .byte 3 # DW_AT_name
141 .byte 37 # DW_FORM_strx1
142 .byte 58 # DW_AT_decl_file
143 .byte 11 # DW_FORM_data1
144 .byte 59 # DW_AT_decl_line
145 .byte 11 # DW_FORM_data1
146 .byte 63 # DW_AT_external
147 .byte 25 # DW_FORM_flag_present
148 .byte 0 # EOM(1)
149 .byte 0 # EOM(2)
150 .byte 0 # EOM(3)
151 .section .debug_info,"",@progbits
152 .Lcu_begin0:
153 .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
154 .Ldebug_info_start0:
155 .short 5 # DWARF version number
156 .byte 1 # DWARF Unit Type
157 .byte 8 # Address Size (in bytes)
158 .long .debug_abbrev # Offset Into Abbrev. Section
159 .byte 1 # Abbrev [1] 0xc:0x38 DW_TAG_compile_unit
160 .byte 0 # DW_AT_producer
161 .short 4 # DW_AT_language
162 .byte 1 # DW_AT_name
163 .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
164 .long .Lline_table_start0 # DW_AT_stmt_list
165 .byte 2 # DW_AT_comp_dir
166 .long .Laddr_table_base0 # DW_AT_addr_base
167 .quad 0 # DW_AT_low_pc
168 .byte 0 # DW_AT_ranges
169 .long .Lrnglists_table_base0 # DW_AT_rnglists_base
170 .byte 2 # Abbrev [2] 0x2b:0xc DW_TAG_subprogram
171 .byte 0 # DW_AT_low_pc
172 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
173 .byte 1 # DW_AT_frame_base
174 .byte 86
175 .byte 3 # DW_AT_linkage_name
176 .byte 4 # DW_AT_name
177 .byte 1 # DW_AT_decl_file
178 .byte 1 # DW_AT_decl_line
179 # DW_AT_external
180 .byte 2 # Abbrev [2] 0x37:0xc DW_TAG_subprogram
181 .byte 1 # DW_AT_low_pc
182 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
183 .byte 1 # DW_AT_frame_base
184 .byte 86
185 .byte 5 # DW_AT_linkage_name
186 .byte 6 # DW_AT_name
187 .byte 1 # DW_AT_decl_file
188 .byte 2 # DW_AT_decl_line
189 # DW_AT_external
190 .byte 0 # End Of Children Mark
191 .Ldebug_info_end0:
192 .section .debug_rnglists,"",@progbits
193 .long .Ldebug_rnglist_table_end0-.Ldebug_rnglist_table_start0 # Length
194 .Ldebug_rnglist_table_start0:
195 .short 5 # Version
196 .byte 8 # Address size
197 .byte 0 # Segment selector size
198 .long 1 # Offset entry count
199 .Lrnglists_table_base0:
200 .long .Ldebug_ranges0-.Lrnglists_table_base0
201 .Ldebug_ranges0:
202 .byte 3 # DW_RLE_startx_length
203 .byte 0 # start index
204 .uleb128 .Lfunc_end0-.Lfunc_begin0 # length
205 .byte 3 # DW_RLE_startx_length
206 .byte 1 # start index
207 .uleb128 .Lfunc_end1-.Lfunc_begin1 # length
208 .byte 0 # DW_RLE_end_of_list
209 .Ldebug_rnglist_table_end0:
210 .Ldebug_addr_start0:
211 .short 5 # DWARF version number
212 .byte 8 # Address size
213 .byte 0 # Segment selector size
214 .Laddr_table_base0:
215 .quad .Lfunc_begin0
216 .quad .Lfunc_begin1
217 .Ldebug_addr_end0:
218
219 .section .debug_line,"",@progbits
220 .Lline_table_start0:
17331733 // it is marked as end_sequence in the input (because in that
17341734 // case, the relocation offset is accurate and that entry won't
17351735 // serve as the start of another function).
1736 if (CurrRange == InvalidRange || Row.Address < CurrRange.start() ||
1737 Row.Address > CurrRange.stop() ||
1738 (Row.Address == CurrRange.stop() && !Row.EndSequence)) {
1736 if (CurrRange == InvalidRange || Row.Address.Address < CurrRange.start() ||
1737 Row.Address.Address > CurrRange.stop() ||
1738 (Row.Address.Address == CurrRange.stop() && !Row.EndSequence)) {
17391739 // We just stepped out of a known range. Insert a end_sequence
17401740 // corresponding to the end of the range.
17411741 uint64_t StopAddress = CurrRange != InvalidRange
17421742 ? CurrRange.stop() + CurrRange.value()
17431743 : -1ULL;
1744 CurrRange = FunctionRanges.find(Row.Address);
1744 CurrRange = FunctionRanges.find(Row.Address.Address);
17451745 bool CurrRangeValid =
1746 CurrRange != InvalidRange && CurrRange.start() <= Row.Address;
1746 CurrRange != InvalidRange && CurrRange.start() <= Row.Address.Address;
17471747 if (!CurrRangeValid) {
17481748 CurrRange = InvalidRange;
17491749 if (StopAddress != -1ULL) {
17531753 // for now do as dsymutil.
17541754 // FIXME: Understand exactly what cases this addresses and
17551755 // potentially remove it along with the Ranges map.
1756 auto Range = Ranges.lower_bound(Row.Address);
1756 auto Range = Ranges.lower_bound(Row.Address.Address);
17571757 if (Range != Ranges.begin() && Range != Ranges.end())
17581758 --Range;
17591759
1760 if (Range != Ranges.end() && Range->first <= Row.Address &&
1761 Range->second.HighPC >= Row.Address) {
1762 StopAddress = Row.Address + Range->second.Offset;
1760 if (Range != Ranges.end() && Range->first <= Row.Address.Address &&
1761 Range->second.HighPC >= Row.Address.Address) {
1762 StopAddress = Row.Address.Address + Range->second.Offset;
17631763 }
17641764 }
17651765 }
17671767 // Insert end sequence row with the computed end address, but
17681768 // the same line as the previous one.
17691769 auto NextLine = Seq.back();
1770 NextLine.Address = StopAddress;
1770 NextLine.Address.Address = StopAddress;
17711771 NextLine.EndSequence = 1;
17721772 NextLine.PrologueEnd = 0;
17731773 NextLine.BasicBlock = 0;
17851785 continue;
17861786
17871787 // Relocate row address and add it to the current sequence.
1788 Row.Address += CurrRange.value();
1788 Row.Address.Address += CurrRange.value();
17891789 Seq.emplace_back(Row);
17901790
17911791 if (Row.EndSequence)
479479 MS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
480480 MS->EmitULEB128IntValue(PointerSize + 1);
481481 MS->EmitIntValue(dwarf::DW_LNE_set_address, 1);
482 MS->EmitIntValue(Row.Address, PointerSize);
482 MS->EmitIntValue(Row.Address.Address, PointerSize);
483483 LineSectionSize += 2 + PointerSize + getULEB128Size(PointerSize + 1);
484484 AddressDelta = 0;
485485 } else {
486 AddressDelta = (Row.Address - Address) / MinInstLength;
486 AddressDelta = (Row.Address.Address - Address) / MinInstLength;
487487 }
488488
489489 // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable.
539539 MS->EmitBytes(EncodingOS.str());
540540 LineSectionSize += EncodingBuffer.size();
541541 EncodingBuffer.resize(0);
542 Address = Row.Address;
542 Address = Row.Address.Address;
543543 LastLine = Row.Line;
544544 RowsSinceLastSequence++;
545545 } else {
253253 return CFCrossReferences;
254254 }
255255
256 const std::set<uint64_t> &FileAnalysis::getIndirectInstructions() const {
256 const std::set<object::SectionedAddress> &
257 FileAnalysis::getIndirectInstructions() const {
257258 return IndirectInstructions;
258259 }
259260
267268 return MIA.get();
268269 }
269270
270 Expected FileAnalysis::symbolizeInlinedCode(uint64_t Address) {
271 Expected
272 FileAnalysis::symbolizeInlinedCode(object::SectionedAddress Address) {
271273 assert(Symbolizer != nullptr && "Symbolizer is invalid.");
274
272275 return Symbolizer->symbolizeInlinedCode(Object->getFileName(), Address);
273276 }
274277
456459
457460 ArrayRef SectionBytes((const uint8_t *)SectionContents.data(),
458461 Section.getSize());
459 parseSectionContents(SectionBytes, Section.getAddress());
462 parseSectionContents(SectionBytes,
463 {Section.getAddress(), Section.getIndex()});
460464 }
461465 return Error::success();
462466 }
463467
464468 void FileAnalysis::parseSectionContents(ArrayRef SectionBytes,
465 uint64_t SectionAddress) {
469 object::SectionedAddress Address) {
466470 assert(Symbolizer && "Symbolizer is uninitialised.");
467471 MCInst Instruction;
468472 Instr InstrMeta;
476480
477481 Byte += InstructionSize;
478482
479 uint64_t VMAddress = SectionAddress + Byte - InstructionSize;
483 uint64_t VMAddress = Address.Address + Byte - InstructionSize;
480484 InstrMeta.Instruction = Instruction;
481485 InstrMeta.VMAddress = VMAddress;
482486 InstrMeta.InstructionSize = InstructionSize;
508512
509513 // Check if this instruction exists in the range of the DWARF metadata.
510514 if (!IgnoreDWARFFlag) {
511 auto LineInfo =
512 Symbolizer->symbolizeCode(Object->getFileName(), VMAddress);
515 auto LineInfo = Symbolizer->symbolizeCode(
516 Object->getFileName(), {VMAddress, Address.SectionIndex});
513517 if (!LineInfo) {
514518 handleAllErrors(LineInfo.takeError(), [](const ErrorInfoBase &E) {
515519 errs() << "Symbolizer failed to get line: " << E.message() << "\n";
521525 continue;
522526 }
523527
524 IndirectInstructions.insert(VMAddress);
528 IndirectInstructions.insert({VMAddress, Address.SectionIndex});
525529 }
526530 }
527531
138138 bool usesRegisterOperand(const Instr &InstrMeta) const;
139139
140140 // Returns the list of indirect instructions.
141 const std::set<uint64_t> &getIndirectInstructions() const;
141 const std::set<object::SectionedAddress> &getIndirectInstructions() const;
142142
143143 const MCRegisterInfo *getRegisterInfo() const;
144144 const MCInstrInfo *getMCInstrInfo() const;
145145 const MCInstrAnalysis *getMCInstrAnalysis() const;
146146
147147 // Returns the inlining information for the provided address.
148 Expected symbolizeInlinedCode(uint64_t Address);
148 Expected
149 symbolizeInlinedCode(object::SectionedAddress Address);
149150
150151 // Returns whether the provided Graph represents a protected indirect control
151152 // flow instruction in this file.
177178 // Disassemble and parse the provided bytes into this object. Instruction
178179 // address calculation is done relative to the provided SectionAddress.
179180 void parseSectionContents(ArrayRef SectionBytes,
180 uint64_t SectionAddress);
181 object::SectionedAddress Address);
181182
182183 // Constructs and initialises members required for disassembly.
183184 Error initialiseDisassemblyMembers();
224225 DenseMap> StaticBranchTargetings;
225226
226227 // A list of addresses of indirect control flow instructions.
227 std::set<uint64_t> IndirectInstructions;
228 std::set<object::SectionedAddress> IndirectInstructions;
228229
229230 // The addresses of functions that will trap on CFI violations.
230231 SmallSet TrapOnFailFunctionAddresses;
9292 }
9393
9494 GraphResult GraphBuilder::buildFlowGraph(const FileAnalysis &Analysis,
95 uint64_t Address) {
95 object::SectionedAddress Address) {
9696 GraphResult Result;
97 Result.BaseAddress = Address;
97 Result.BaseAddress = Address.Address;
9898 DenseSet OpenedNodes;
9999
100100 const auto &IndirectInstructions = Analysis.getIndirectInstructions();
101101
102 if (IndirectInstructions.find(Address) == IndirectInstructions.end())
102 // check that IndirectInstructions contains specified Address
103 if (IndirectInstructions.find(Address) == IndirectInstructions.end()) {
103104 return Result;
104
105 buildFlowGraphImpl(Analysis, OpenedNodes, Result, Address, 0);
105 }
106
107 buildFlowGraphImpl(Analysis, OpenedNodes, Result, Address.Address, 0);
106108 return Result;
107109 }
108110
101101 // (i.e. the upwards traversal did not make it to a branch node) flows to the
102102 // provided node in GraphResult::OrphanedNodes.
103103 static GraphResult buildFlowGraph(const FileAnalysis &Analysis,
104 uint64_t Address);
104 object::SectionedAddress Address);
105105
106106 private:
107107 // Implementation function that actually builds the flow graph. Retrieves a
129129
130130 std::map BlameCounter;
131131
132 for (uint64_t Address : Analysis.getIndirectInstructions()) {
133 const auto &InstrMeta = Analysis.getInstructionOrDie(Address);
132 for (object::SectionedAddress Address : Analysis.getIndirectInstructions()) {
133 const auto &InstrMeta = Analysis.getInstructionOrDie(Address.Address);
134134 GraphResult Graph = GraphBuilder::buildFlowGraph(Analysis, Address);
135135
136136 CFIProtectionStatus ProtectionStatus =
152152
153153 auto InliningInfo = Analysis.symbolizeInlinedCode(Address);
154154 if (!InliningInfo || InliningInfo->getNumberOfFrames() == 0) {
155 errs() << "Failed to symbolise " << format_hex(Address, 2)
155 errs() << "Failed to symbolise " << format_hex(Address.Address, 2)
156156 << " with line tables from " << InputFilename << "\n";
157157 exit(EXIT_FAILURE);
158158 }
163163 if (!Summarize) {
164164 for (uint32_t i = 0; i < InliningInfo->getNumberOfFrames(); ++i) {
165165 const auto &Line = InliningInfo->getFrame(i);
166 outs() << " " << format_hex(Address, 2) << " = " << Line.FileName
167 << ":" << Line.Line << ":" << Line.Column << " ("
168 << Line.FunctionName << ")\n";
166 outs() << " " << format_hex(Address.Address, 2) << " = "
167 << Line.FileName << ":" << Line.Line << ":" << Line.Column
168 << " (" << Line.FunctionName << ")\n";
169169 }
170170 }
171171
378378
379379 /// Handle the --lookup option and dump the DIEs and line info for the given
380380 /// address.
381 static bool lookup(DWARFContext &DICtx, uint64_t Address, raw_ostream &OS) {
381 /// TODO: specified Address for --lookup option could relate for several
382 /// different sections(in case not-linked object file). llvm-dwarfdump
383 /// need to do something with this: extend lookup option with section
384 /// information or probably display all matched entries, or something else...
385 static bool lookup(ObjectFile &Obj, DWARFContext &DICtx, uint64_t Address,
386 raw_ostream &OS) {
382387 auto DIEsForAddr = DICtx.getDIEsForAddress(Lookup);
383388
384389 if (!DIEsForAddr)
393398 DIEsForAddr.BlockDIE.dump(OS, 4, DumpOpts);
394399 }
395400
396 if (DILineInfo LineInfo = DICtx.getLineInfoForAddress(Lookup))
401 // TODO: it is neccessary to set proper SectionIndex here.
402 // object::SectionedAddress::UndefSection works for only absolute addresses.
403 if (DILineInfo LineInfo = DICtx.getLineInfoForAddress(
404 {Lookup, object::SectionedAddress::UndefSection}))
397405 LineInfo.dump(OS);
398406
399407 return true;
412420
413421 // Handle the --lookup option.
414422 if (Lookup)
415 return lookup(DICtx, Lookup, OS);
423 return lookup(Obj, DICtx, Lookup, OS);
416424
417425 // Handle the --name option.
418426 if (!Name.empty()) {
74997499
75007500 // Print debug info.
75017501 if (diContext) {
7502 DILineInfo dli = diContext->getLineInfoForAddress(PC);
7502 DILineInfo dli = diContext->getLineInfoForAddress({PC, SectIdx});
75037503 // Print valid line info if it changed.
75047504 if (dli != lastLine && dli.Line != 0)
75057505 outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
507507 Symbolizer.reset(new symbolize::LLVMSymbolizer(SymbolizerOpts));
508508 }
509509 virtual ~SourcePrinter() = default;
510 virtual void printSourceLine(raw_ostream &OS, uint64_t Address,
510 virtual void printSourceLine(raw_ostream &OS,
511 object::SectionedAddress Address,
511512 StringRef Delimiter = "; ");
512513 };
513514
537538 return true;
538539 }
539540
540 void SourcePrinter::printSourceLine(raw_ostream &OS, uint64_t Address,
541 void SourcePrinter::printSourceLine(raw_ostream &OS,
542 object::SectionedAddress Address,
541543 StringRef Delimiter) {
542544 if (!Symbolizer)
543545 return;
598600 public:
599601 virtual ~PrettyPrinter() = default;
600602 virtual void printInst(MCInstPrinter &IP, const MCInst *MI,
601 ArrayRef Bytes, uint64_t Address,
602 raw_ostream &OS, StringRef Annot,
603 MCSubtargetInfo const &STI, SourcePrinter *SP,
603 ArrayRef Bytes,
604 object::SectionedAddress Address, raw_ostream &OS,
605 StringRef Annot, MCSubtargetInfo const &STI,
606 SourcePrinter *SP,
604607 std::vector *Rels = nullptr) {
605608 if (SP && (PrintSource || PrintLines))
606609 SP->printSourceLine(OS, Address);
607610 if (!NoLeadingAddr)
608 OS << format("%8" PRIx64 ":", Address);
611 OS << format("%8" PRIx64 ":", Address.Address);
609612 if (!NoShowRawInsn) {
610613 OS << "\t";
611614 dumpBytes(Bytes, OS);
632635 }
633636 }
634637 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef Bytes,
635 uint64_t Address, raw_ostream &OS, StringRef Annot,
636 MCSubtargetInfo const &STI, SourcePrinter *SP,
638 object::SectionedAddress Address, raw_ostream &OS,
639 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
637640 std::vector *Rels) override {
638641 if (SP && (PrintSource || PrintLines))
639642 SP->printSourceLine(OS, Address, "");
640643 if (!MI) {
641 printLead(Bytes, Address, OS);
644 printLead(Bytes, Address.Address, OS);
642645 OS << " ";
643646 return;
644647 }
660663 std::vector::const_iterator RelCur = Rels->begin();
661664 std::vector::const_iterator RelEnd = Rels->end();
662665 auto PrintReloc = [&]() -> void {
663 while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address)) {
664 if (RelCur->getOffset() == Address) {
665 printRelocation(*RelCur, Address, 4);
666 while ((RelCur != RelEnd) && (RelCur->getOffset() <= Address.Address)) {
667 if (RelCur->getOffset() == Address.Address) {
668 printRelocation(*RelCur, Address.Address, 4);
666669 return;
667670 }
668671 ++RelCur;
674677 Separator = "\n";
675678 if (SP && (PrintSource || PrintLines))
676679 SP->printSourceLine(OS, Address, "");
677 printLead(Bytes, Address, OS);
680 printLead(Bytes, Address.Address, OS);
678681 OS << Preamble;
679682 Preamble = " ";
680683 StringRef Inst;
692695 OS << " } " << PacketBundle.second;
693696 PrintReloc();
694697 Bytes = Bytes.slice(4);
695 Address += 4;
698 Address.Address += 4;
696699 }
697700 }
698701 };
701704 class AMDGCNPrettyPrinter : public PrettyPrinter {
702705 public:
703706 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef Bytes,
704 uint64_t Address, raw_ostream &OS, StringRef Annot,
705 MCSubtargetInfo const &STI, SourcePrinter *SP,
707 object::SectionedAddress Address, raw_ostream &OS,
708 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
706709 std::vector *Rels) override {
707710 if (SP && (PrintSource || PrintLines))
708711 SP->printSourceLine(OS, Address);
732735 }
733736 }
734737
735 OS << format("// %012" PRIX64 ": ", Address);
738 OS << format("// %012" PRIX64 ": ", Address.Address);
736739 if (Bytes.size() >=4) {
737740 for (auto D : makeArrayRef(reinterpret_cast(Bytes.data()),
738741 Bytes.size() / sizeof(U32)))
753756 class BPFPrettyPrinter : public PrettyPrinter {
754757 public:
755758 void printInst(MCInstPrinter &IP, const MCInst *MI, ArrayRef Bytes,
756 uint64_t Address, raw_ostream &OS, StringRef Annot,
757 MCSubtargetInfo const &STI, SourcePrinter *SP,
759 object::SectionedAddress Address, raw_ostream &OS,
760 StringRef Annot, MCSubtargetInfo const &STI, SourcePrinter *SP,
758761 std::vector *Rels) override {
759762 if (SP && (PrintSource || PrintLines))
760763 SP->printSourceLine(OS, Address);
761764 if (!NoLeadingAddr)
762 OS << format("%8" PRId64 ":", Address / 8);
765 OS << format("%8" PRId64 ":", Address.Address / 8);
763766 if (!NoShowRawInsn) {
764767 OS << "\t";
765768 dumpBytes(Bytes, OS);
13221325 if (Size == 0)
13231326 Size = 1;
13241327
1325 PIP.printInst(
1326 *IP, Disassembled ? &Inst : nullptr, Bytes.slice(Index, Size),
1327 SectionAddr + Index + VMAAdjustment, outs(), "", *STI, &SP, &Rels);
1328 PIP.printInst(*IP, Disassembled ? &Inst : nullptr,
1329 Bytes.slice(Index, Size),
1330 {SectionAddr + Index + VMAAdjustment, Section.getIndex()},
1331 outs(), "", *STI, &SP, &Rels);
13281332 outs() << CommentStream.str();
13291333 Comments.clear();
13301334
366366 }
367367 uint64_t Addr = *AddrOrErr;
368368
369 object::SectionedAddress Address;
370
369371 uint64_t Size = P.second;
370372 // If we're not using the debug object, compute the address of the
371373 // symbol in memory (rather than that in the unrelocated object file)
380382 object::section_iterator Sec = *SecOrErr;
381383 StringRef SecName;
382384 Sec->getName(SecName);
385 Address.SectionIndex = Sec->getIndex();
383386 uint64_t SectionLoadAddress =
384387 LoadedObjInfo->getSectionLoadAddress(*Sec);
385388 if (SectionLoadAddress != 0)
386389 Addr += SectionLoadAddress - Sec->getAddress();
387 }
390 } else if (auto SecOrErr = Sym.getSection())
391 Address.SectionIndex = SecOrErr.get()->getIndex();
388392
389393 outs() << "Function: " << *Name << ", Size = " << Size
390394 << ", Addr = " << Addr << "\n";
391395
392 DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size);
396 Address.Address = Addr;
397 DILineInfoTable Lines =
398 Context->getLineInfoForAddressRange(Address, Size);
393399 for (auto &D : Lines) {
394400 outs() << " Line info @ " << D.first - Addr << ": "
395401 << D.second.FileName << ", line:" << D.second.Line << "\n";
193193 return !StringRef(pos, offset_length).getAsInteger(0, ModuleOffset);
194194 }
195195
196 // This routine returns section index for an address.
197 // Assumption: would work ambiguously for object files which have sections not
198 // assigned to an address(since the same address could belong to various
199 // sections).
200 static uint64_t getModuleSectionIndexForAddress(const std::string &ModuleName,
201 uint64_t Address) {
202
203 Expected> BinaryOrErr = createBinary(ModuleName);
204
205 if (error(BinaryOrErr))
206 return object::SectionedAddress::UndefSection;
207
208 Binary &Binary = *BinaryOrErr->getBinary();
209
210 if (ObjectFile *O = dyn_cast(&Binary)) {
211 for (SectionRef Sec : O->sections()) {
212 if (!Sec.isText() || Sec.isVirtual())
213 continue;
214
215 if (Address >= Sec.getAddress() &&
216 Address <= Sec.getAddress() + Sec.getSize()) {
217 return Sec.getIndex();
218 }
219 }
220 }
221
222 return object::SectionedAddress::UndefSection;
223 }
224
196225 static void symbolizeInput(StringRef InputString, LLVMSymbolizer &Symbolizer,
197226 DIPrinter &Printer) {
198227 bool IsData = false;
199228 std::string ModuleName;
200 uint64_t ModuleOffset = 0;
201 if (!parseCommand(StringRef(InputString), IsData, ModuleName, ModuleOffset)) {
229 uint64_t Offset = 0;
230 if (!parseCommand(StringRef(InputString), IsData, ModuleName, Offset)) {
202231 outs() << InputString;
203232 return;
204233 }
205234
206235 if (ClPrintAddress) {
207236 outs() << "0x";
208 outs().write_hex(ModuleOffset);
237 outs().write_hex(Offset);
209238 StringRef Delimiter = ClPrettyPrint ? ": " : "\n";
210239 outs() << Delimiter;
211240 }
212 ModuleOffset -= ClAdjustVMA;
241 Offset -= ClAdjustVMA;
242 object::SectionedAddress ModuleOffset = {
243 Offset, getModuleSectionIndexForAddress(ModuleName, Offset)};
213244 if (IsData) {
214245 auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset);
215246 Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get());
2828 return F.str();
2929 }
3030
31 if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, It->second)) {
31 object::SectionedAddress ModuleAddress;
32 ModuleAddress.Address = It->second;
33 // TODO: set proper section index here.
34 // object::SectionedAddress::UndefSection works for only absolute addresses.
35 ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection;
36 if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) {
3237 auto &DI = *ResOrErr;
3338 if (DI.FunctionName == "")
3439 F << "@(" << std::hex << It->second << ")";
5055 return "(unknown)";
5156
5257 std::ostringstream F;
53 auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, It->second);
58 object::SectionedAddress ModuleAddress;
59 ModuleAddress.Address = It->second;
60 // TODO: set proper section index here.
61 // object::SectionedAddress::UndefSection works for only absolute addresses.
62 ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection;
63 auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress);
5464 if (!ResOrErr) {
5565 consumeError(ResOrErr.takeError());
5666 return "(unknown)";
620620 std::set CoveredFiles;
621621 if (ClSkipDeadFiles) {
622622 for (auto Addr : CoveredAddrs) {
623 auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
623 // TODO: it would be neccessary to set proper section index here.
624 // object::SectionedAddress::UndefSection works for only absolute
625 // addresses.
626 object::SectionedAddress ModuleAddress = {
627 Addr, object::SectionedAddress::UndefSection};
628
629 auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, ModuleAddress);
624630 failIfError(LineInfo);
625631 CoveredFiles.insert(LineInfo->FileName);
626 auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr);
632 auto InliningInfo =
633 Symbolizer->symbolizeInlinedCode(ObjectFile, ModuleAddress);
627634 failIfError(InliningInfo);
628635 for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) {
629636 auto FrameInfo = InliningInfo->getFrame(I);
635642 for (auto Addr : Addrs) {
636643 std::set Infos; // deduplicate debug info.
637644
638 auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
645 // TODO: it would be neccessary to set proper section index here.
646 // object::SectionedAddress::UndefSection works for only absolute addresses.
647 object::SectionedAddress ModuleAddress = {
648 Addr, object::SectionedAddress::UndefSection};
649
650 auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, ModuleAddress);
639651 failIfError(LineInfo);
640652 if (ClSkipDeadFiles &&
641653 CoveredFiles.find(LineInfo->FileName) == CoveredFiles.end())
649661 Infos.insert(*LineInfo);
650662 Point.Locs.push_back(*LineInfo);
651663
652 auto InliningInfo = Symbolizer->symbolizeInlinedCode(ObjectFile, Addr);
664 auto InliningInfo =
665 Symbolizer->symbolizeInlinedCode(ObjectFile, ModuleAddress);
653666 failIfError(InliningInfo);
654667 for (uint32_t I = 0; I < InliningInfo->getNumberOfFrames(); ++I) {
655668 auto FrameInfo = InliningInfo->getFrame(I);
956969 auto Symbolizer(createSymbolizer());
957970
958971 for (uint64_t Addr : *Data.Addrs) {
959 auto LineInfo = Symbolizer->symbolizeCode(ObjectFile, Addr);
972 // TODO: it would be neccessary to set proper section index here.
973 // object::SectionedAddress::UndefSection works for only absolute addresses.
974 auto LineInfo = Symbolizer->symbolizeCode(
975 ObjectFile, {Addr, object::SectionedAddress::UndefSection});
960976 failIfError(LineInfo);
961977 if (B.isBlacklisted(*LineInfo))
962978 continue;
8383 // As the instrumentation tracks the return address and not
8484 // the address of the call to `__sanitizer_stat_report` we
8585 // remove one from the address to get the correct DI.
86 if (Expected LineInfo =
87 Symbolizer.symbolizeCode(Filename, Addr - 1)) {
86 // TODO: it would be neccessary to set proper section index here.
87 // object::SectionedAddress::UndefSection works for only absolute addresses.
88 if (Expected LineInfo = Symbolizer.symbolizeCode(
89 Filename, {Addr - 1, object::SectionedAddress::UndefSection})) {
8890 llvm::outs() << format_hex(Addr - 1, 18) << ' ' << LineInfo->FileName
8991 << ':' << LineInfo->Line << ' ' << LineInfo->FunctionName
9092 << ' ';
5050
5151 // Expose this method publicly for testing.
5252 void parseSectionContents(ArrayRef SectionBytes,
53 uint64_t SectionAddress) {
54 FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
53 object::SectionedAddress Address) {
54 FileAnalysis::parseSectionContents(SectionBytes, Address);
5555 }
5656
5757 Error initialiseDisassemblyMembers() {
105105 0x41, 0x0e, // 21: rex.B (bad)
106106 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
107107 },
108 0xDEADBEEF);
108 {0xDEADBEEF, 0x0});
109109
110110 EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));
111111 EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));
209209 0x2f, // 1: (bad)
210210 0x90 // 2: nop
211211 },
212 0xDEADBEEF);
212 {0xDEADBEEF, 0x0});
213213 const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);
214214 const auto *GoodInstrMeta =
215215 Analysis.getPrevInstructionSequential(BadInstrMeta);
239239 0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
240240 0x0f, 0x0b // 28: ud2
241241 },
242 0xDEADBEEF);
242 {0xDEADBEEF, 0x0});
243243
244244 EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));
245245 EXPECT_FALSE(
274274 0x75, 0x00, // 17: jne +0
275275 0xc3, // 19: retq
276276 },
277 0xDEADBEEF);
277 {0xDEADBEEF, 0x0});
278278
279279 EXPECT_TRUE(
280280 Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));
321321 0xeb, 0xdd, // 36: jmp 3 [-35]
322322 0xeb, 0xdc, // 38: jmp 4 [-36]
323323 },
324 0xDEADBEEF);
324 {0xDEADBEEF, 0x0});
325325
326326 const auto *Current = Analysis.getInstruction(0xDEADBEEF);
327327 const auto *Next = Analysis.getDefiniteNextInstruction(*Current);
411411 0xeb, 0xdd, // 36: jmp 3 [-35]
412412 0xeb, 0xdc, // 38: jmp 4 [-36]
413413 },
414 0xDEADBEEF);
414 {0xDEADBEEF, 0x0});
415415 const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);
416416 std::set XRefs =
417417 Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
502502 0x0f, 0x0b, // 1: ud2
503503 0x75, 0x00, // 3: jne 5 [+0]
504504 },
505 0xDEADBEEF);
506 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
505 {0xDEADBEEF, 0x0});
506 GraphResult Result =
507 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
507508 EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
508509 Analysis.validateCFIProtection(Result));
509 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
510 Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
510511 EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
511512 Analysis.validateCFIProtection(Result));
512 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
513 Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
513514 EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
514515 Analysis.validateCFIProtection(Result));
515 Result = GraphBuilder::buildFlowGraph(Analysis, 0x12345678);
516 Result = GraphBuilder::buildFlowGraph(Analysis, {0x12345678, 0x0});
516517 EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION,
517518 Analysis.validateCFIProtection(Result));
518519 }
526527 0x0f, 0x0b, // 2: ud2
527528 0xff, 0x10, // 4: callq *(%rax)
528529 },
529 0xDEADBEEF);
530 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
530 {0xDEADBEEF, 0x0});
531 GraphResult Result =
532 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
531533 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
532534 Analysis.validateCFIProtection(Result));
533535 }
541543 0xff, 0x10, // 2: callq *(%rax)
542544 0x0f, 0x0b, // 4: ud2
543545 },
544 0xDEADBEEF);
545 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
546 {0xDEADBEEF, 0x0});
547 GraphResult Result =
548 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
546549 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
547550 Analysis.validateCFIProtection(Result));
548551 }
559562 0x75, 0xf9, // 7: jne 2 [-7]
560563 0x0f, 0x0b, // 9: ud2
561564 },
562 0xDEADBEEF);
563 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
565 {0xDEADBEEF, 0x0});
566 GraphResult Result =
567 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
564568 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
565569 Analysis.validateCFIProtection(Result));
566570 }
576580 0x75, 0xfb, // 5: jne 2 [-5]
577581 0x0f, 0x0b, // 7: ud2
578582 },
579 0xDEADBEEF);
580 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
583 {0xDEADBEEF, 0x0});
584 GraphResult Result =
585 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
581586 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
582587 Analysis.validateCFIProtection(Result));
583588 }
595600 0xff, 0x10, // 6: callq *(%rax)
596601 0x0f, 0x0b, // 8: ud2
597602 },
598 0xDEADBEEF);
603 {0xDEADBEEF, 0x0});
599604 uint64_t PrevSearchLengthForConditionalBranch =
600605 SearchLengthForConditionalBranch;
601606 SearchLengthForConditionalBranch = 2;
602607
603 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
608 GraphResult Result =
609 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
604610 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
605611 Analysis.validateCFIProtection(Result));
606612
620626 0x90, // 7: nop
621627 0x0f, 0x0b, // 8: ud2
622628 },
623 0xDEADBEEF);
629 {0xDEADBEEF, 0x0});
624630 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
625631 SearchLengthForUndef = 2;
626632
627 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
633 GraphResult Result =
634 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
628635 EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
629636 Analysis.validateCFIProtection(Result));
630637
641648 0xff, 0x10, // 4: callq *(%rax)
642649 0x0f, 0x0b, // 6: ud2
643650 },
644 0xDEADBEEF);
645 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
651 {0xDEADBEEF, 0x0});
652 GraphResult Result =
653 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
646654 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
647655 Analysis.validateCFIProtection(Result));
648656 }
657665 0xff, 0x10, // 4: callq *(%rax)
658666 0x0f, 0x0b, // 6: ud2
659667 },
660 0xDEADBEEF);
661 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
668 {0xDEADBEEF, 0x0});
669 GraphResult Result =
670 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
662671 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
663672 Analysis.validateCFIProtection(Result));
664673 }
684693 0x90, // 21: nop
685694 0x0f, 0x0b, // 22: ud2
686695 },
687 0xDEADBEEF);
696 {0xDEADBEEF, 0x0});
688697 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
689698 SearchLengthForUndef = 5;
690 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
699 GraphResult Result =
700 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
691701 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
692702 Analysis.validateCFIProtection(Result));
693703 SearchLengthForUndef = PrevSearchLengthForUndef;
703713 0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130
704714 0x0f, 0x0b, // 0x688127: ud2
705715 },
706 0x688118);
716 {0x688118, 0x0});
707717 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
708718 SearchLengthForUndef = 1;
709 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x68811d);
719 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x68811d, 0x0});
710720 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
711721 Analysis.validateCFIProtection(Result));
712722 SearchLengthForUndef = PrevSearchLengthForUndef;
718728 0x74, 0x73, // 0x7759eb: je 0x775a60
719729 0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e
720730 },
721 0x7759eb);
731 {0x7759eb, 0x0});
722732
723733 Analysis.parseSectionContents(
724734 {
728738 0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi
729739 0xff, 0xd1, // 0x775a68: callq *%rcx
730740 },
731 0x775a56);
741 {0x775a56, 0x0});
732742
733743 Analysis.parseSectionContents(
734744 {
735745 0x0f, 0x0b, // 0x775e0e: ud2
736746 },
737 0x775e0e);
747 {0x775e0e, 0x0});
738748 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
739749 SearchLengthForUndef = 1;
740 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
750 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
741751 EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
742752 Analysis.validateCFIProtection(Result));
743753 SearchLengthForUndef = 2;
744 Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
754 Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
745755 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
746756 Analysis.validateCFIProtection(Result));
747757 SearchLengthForUndef = 3;
748 Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
758 Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});
749759 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
750760 Analysis.validateCFIProtection(Result));
751761 SearchLengthForUndef = PrevSearchLengthForUndef;
761771 0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax
762772 0xff, 0x10, // 10: callq *(%rax)
763773 },
764 0xDEADBEEF);
765 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10);
774 {0xDEADBEEF, 0x0});
775 GraphResult Result =
776 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0});
766777 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
767778 Analysis.validateCFIProtection(Result));
768779 }
777788 0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax
778789 0xff, 0x10, // 8: callq *(%rax)
779790 },
780 0xDEADBEEF);
781 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
791 {0xDEADBEEF, 0x0});
792 GraphResult Result =
793 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
782794 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
783795 Analysis.validateCFIProtection(Result));
784796 }
793805 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax
794806 0xff, 0x10, // 9: callq *(%rax)
795807 },
796 0xDEADBEEF);
797 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
808 {0xDEADBEEF, 0x0});
809 GraphResult Result =
810 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});
798811 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
799812 Analysis.validateCFIProtection(Result));
800813 }
811824 0x75, 0xf9, // 8: jne 2 [-7]
812825 0x0f, 0x0b, // 10: ud2
813826 },
814 0xDEADBEEF);
815 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
827 {0xDEADBEEF, 0x0});
828 GraphResult Result =
829 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
816830 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
817831 Analysis.validateCFIProtection(Result));
818832 }
824838 {
825839 0x00, 0x01, 0x3f, 0xd6, // 0: blr x8
826840 },
827 0xDEADBEEF);
828 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
841 {0xDEADBEEF, 0x0});
842 GraphResult Result =
843 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
829844 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
830845 Analysis.validateCFIProtection(Result));
831846 }
839854 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
840855 0x00, 0x01, 0x3f, 0xd6, // 8: blr x8
841856 },
842 0xDEADBEEF);
843 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
857 {0xDEADBEEF, 0x0});
858 GraphResult Result =
859 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});
844860 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
845861 Analysis.validateCFIProtection(Result));
846862 }
855871 0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1
856872 0x00, 0x01, 0x3f, 0xd6, // 12: blr x8
857873 },
858 0xDEADBEEF);
859 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
874 {0xDEADBEEF, 0x0});
875 GraphResult Result =
876 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
860877 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
861878 Analysis.validateCFIProtection(Result));
862879 }
871888 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
872889 0x20, 0x00, 0x1f, 0xd6, // 12: br x1
873890 },
874 0xDEADBEEF);
875 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
891 {0xDEADBEEF, 0x0});
892 GraphResult Result =
893 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
876894 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
877895 Analysis.validateCFIProtection(Result));
878896 }
888906 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
889907 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
890908 },
891 0xDEADBEEF);
892 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
909 {0xDEADBEEF, 0x0});
910 GraphResult Result =
911 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
893912 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
894913 Analysis.validateCFIProtection(Result));
895914 }
905924 0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1
906925 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
907926 },
908 0xDEADBEEF);
909 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
927 {0xDEADBEEF, 0x0});
928 GraphResult Result =
929 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
910930 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
911931 Analysis.validateCFIProtection(Result));
912932 }
922942 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
923943 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
924944 },
925 0xDEADBEEF);
926 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
945 {0xDEADBEEF, 0x0});
946 GraphResult Result =
947 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
927948 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
928949 Analysis.validateCFIProtection(Result));
929950 }
939960 0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]
940961 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
941962 },
942 0xDEADBEEF);
943 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
963 {0xDEADBEEF, 0x0});
964 GraphResult Result =
965 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
944966 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
945967 Analysis.validateCFIProtection(Result));
946968 }
956978 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
957979 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
958980 },
959 0xDEADBEEF);
960 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
981 {0xDEADBEEF, 0x0});
982 GraphResult Result =
983 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
961984 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
962985 Analysis.validateCFIProtection(Result));
963986 }
973996 0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]
974997 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
975998 },
976 0xDEADBEEF);
977 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
999 {0xDEADBEEF, 0x0});
1000 GraphResult Result =
1001 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});
9781002 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
9791003 Analysis.validateCFIProtection(Result));
9801004 }
9891013 0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1
9901014 0x20, 0x00, 0x1f, 0xd6, // 12: br x1
9911015 },
992 0xDEADBEEF);
993 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
1016 {0xDEADBEEF, 0x0});
1017 GraphResult Result =
1018 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});
9941019 EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
9951020 Analysis.validateCFIProtection(Result));
9961021 }
10081033 0x20, 0x00, 0x1f, 0xd6, // 20: br x1
10091034 0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1
10101035 },
1011 0xDEADBEEF);
1012 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 20);
1036 {0xDEADBEEF, 0x0});
1037 GraphResult Result =
1038 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0});
10131039 EXPECT_EQ(CFIProtectionStatus::PROTECTED,
10141040 Analysis.validateCFIProtection(Result));
10151041 }
10281054 0x20, 0x00, 0x1f, 0xd6, // 24: br x1
10291055 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
10301056 },
1031 0xDEADBEEF);
1032 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
1057 {0xDEADBEEF, 0x0});
1058 GraphResult Result =
1059 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
10331060 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
10341061 Analysis.validateCFIProtection(Result));
10351062 }
10481075 0x20, 0x00, 0x1f, 0xd6, // 24: br x1
10491076 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
10501077 },
1051 0xDEADBEEF);
1052 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
1078 {0xDEADBEEF, 0x0});
1079 GraphResult Result =
1080 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});
10531081 EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
10541082 Analysis.validateCFIProtection(Result));
10551083 }
112112
113113 // Expose this method publicly for testing.
114114 void parseSectionContents(ArrayRef SectionBytes,
115 uint64_t SectionAddress) {
116 FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
115 object::SectionedAddress Address) {
116 FileAnalysis::parseSectionContents(SectionBytes, Address);
117117 }
118118
119119 Error initialiseDisassemblyMembers() {
155155 0x0f, 0x0b, // 2: ud2
156156 0xff, 0x10, // 4: callq *(%rax)
157157 },
158 0xDEADBEEF);
159 const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
158 {0xDEADBEEF, 0x0});
159 const auto Result =
160 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
160161
161162 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
162163 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
181182 0xff, 0x10, // 2: callq *(%rax)
182183 0x0f, 0x0b, // 4: ud2
183184 },
184 0xDEADBEEF);
185 const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
185 {0xDEADBEEF, 0x0});
186 const auto Result =
187 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
186188
187189 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
188190 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
210212 0x75, 0xf9, // 7: jne 2 [-7]
211213 0x0f, 0x0b, // 9: ud2
212214 },
213 0xDEADBEEF);
214 const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
215 {0xDEADBEEF, 0x0});
216 const auto Result =
217 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
215218
216219 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
217220 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
248251 0x75, 0xfb, // 5: jne 2 [-5]
249252 0x0f, 0x0b, // 7: ud2
250253 },
251 0xDEADBEEF);
252 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
254 {0xDEADBEEF, 0x0});
255 GraphResult Result =
256 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
253257
254258 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
255259 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
283287 0x90, // 0: nop
284288 0x75, 0xfe, // 1: jne 1 [-2]
285289 },
286 0xDEADBEEF);
287 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
290 {0xDEADBEEF, 0x0});
291 GraphResult Result =
292 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});
288293 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
289294 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
290295
291 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
296 Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});
292297 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
293298 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
294299
295 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADC0DE);
300 Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADC0DE, 0x0});
296301 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
297302 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
298303 }
305310 0xeb, 0xfe, // 0: jmp 0 [-2]
306311 0xff, 0x10, // 2: callq *(%rax)
307312 },
308 0xDEADBEEF);
309 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
313 {0xDEADBEEF, 0x0});
314 GraphResult Result =
315 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
310316 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
311317 EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 2));
312318 EXPECT_THAT(Result.IntermediateNodes, IsEmpty());
320326 0x75, 0xfe, // 0: jne 0 [-2]
321327 0xff, 0x10, // 2: callq *(%rax)
322328 },
323 0xDEADBEEF);
324 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
329 {0xDEADBEEF, 0x0});
330 GraphResult Result =
331 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
325332 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
326333 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
327334 EXPECT_THAT(
343350 0xeb, 0xfc, // 2: jmp 0 [-4]
344351 0xff, 0x10, // 4: callq *(%rax)
345352 },
346 0xDEADBEEF);
347 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
353 {0xDEADBEEF, 0x0});
354 GraphResult Result =
355 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
348356 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
349357 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
350358 EXPECT_THAT(
367375 0xeb, 0xfc, // 2: jmp 0 [-4]
368376 0xff, 0x10, // 4: callq *(%rax)
369377 },
370 0xDEADBEEF);
371 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
378 {0xDEADBEEF, 0x0});
379 GraphResult Result =
380 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});
372381 EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 4));
373382 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
374383 }
386395 0xff, 0x10, // 6: callq *(%rax)
387396 0x0f, 0x0b, // 8: ud2
388397 },
389 0xDEADBEEF);
398 {0xDEADBEEF, 0x0});
390399 uint64_t PrevSearchLengthForConditionalBranch =
391400 SearchLengthForConditionalBranch;
392401 SearchLengthForConditionalBranch = 2;
393402
394 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
403 GraphResult Result =
404 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});
395405 EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
396406 EXPECT_THAT(Result.OrphanedNodes,
397407 Each(HasPath(Result, ElementsAre(0xDEADBEEF + 4, 0xDEADBEEF + 5,
415425 0x90, // 7: nop
416426 0x0f, 0x0b, // 8: ud2
417427 },
418 0xDEADBEEF);
428 {0xDEADBEEF, 0x0});
419429 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
420430 SearchLengthForUndef = 2;
421431
422 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
432 GraphResult Result =
433 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});
423434 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
424435 EXPECT_THAT(
425436 Result.ConditionalBranchNodes,
449460 0x75, 0xfb, // 5: jne 2 [-5]
450461 0x0f, 0x0b, // 7: ud2
451462 },
452 0xDEADBEEF);
453 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
463 {0xDEADBEEF, 0x0});
464 GraphResult Result =
465 GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});
454466 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
455467 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
456468 EXPECT_THAT(
528540 0x90, // 21: nop
529541 0x0f, 0x0b, // 22: ud2
530542 },
531 0x1000);
543 {0x1000, 0x0});
532544 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
533545 SearchLengthForUndef = 5;
534546
535 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x1000 + 9);
547 GraphResult Result =
548 GraphBuilder::buildFlowGraph(Analysis, {0x1000 + 9, 0x0});
536549
537550 EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
538551 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(3));