llvm-project/llvm/lib/DebugInfo/GSYM/Range.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

125 lines
3.5 KiB
C++
Raw Normal View History

Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
//===- Range.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/GSYM/Range.h"
#include "llvm/DebugInfo/GSYM/FileWriter.h"
#include "llvm/Support/DataExtractor.h"
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
#include <algorithm>
#include <inttypes.h>
using namespace llvm;
using namespace gsym;
void AddressRanges::insert(AddressRange Range) {
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
if (Range.size() == 0)
return;
auto It = llvm::upper_bound(Ranges, Range);
auto It2 = It;
while (It2 != Ranges.end() && It2->Start < Range.End)
++It2;
if (It != It2) {
Range.End = std::max(Range.End, It2[-1].End);
It = Ranges.erase(It, It2);
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
}
if (It != Ranges.begin() && Range.Start < It[-1].End)
It[-1].End = std::max(It[-1].End, Range.End);
else
Ranges.insert(It, Range);
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
}
bool AddressRanges::contains(uint64_t Addr) const {
auto It = std::partition_point(
Ranges.begin(), Ranges.end(),
[=](const AddressRange &R) { return R.Start <= Addr; });
return It != Ranges.begin() && Addr < It[-1].End;
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
}
bool AddressRanges::contains(AddressRange Range) const {
if (Range.size() == 0)
return false;
auto It = std::partition_point(
Ranges.begin(), Ranges.end(),
[=](const AddressRange &R) { return R.Start <= Range.Start; });
if (It == Ranges.begin())
return false;
return Range.End <= It[-1].End;
}
Optional<AddressRange>
AddressRanges::getRangeThatContains(uint64_t Addr) const {
auto It = std::partition_point(
Ranges.begin(), Ranges.end(),
[=](const AddressRange &R) { return R.Start <= Addr; });
if (It != Ranges.begin() && Addr < It[-1].End)
return It[-1];
return llvm::None;
}
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) {
return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")";
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
}
raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) {
size_t Size = AR.size();
for (size_t I = 0; I < Size; ++I) {
Add GSYM utility files along with unit tests. The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
2019-06-26 22:09:09 +08:00
if (I)
OS << ' ';
OS << AR[I];
}
return OS;
}
void AddressRange::encode(FileWriter &O, uint64_t BaseAddr) const {
assert(Start >= BaseAddr);
O.writeULEB(Start - BaseAddr);
O.writeULEB(size());
}
void AddressRange::decode(DataExtractor &Data, uint64_t BaseAddr,
uint64_t &Offset) {
const uint64_t AddrOffset = Data.getULEB128(&Offset);
const uint64_t Size = Data.getULEB128(&Offset);
const uint64_t StartAddr = BaseAddr + AddrOffset;
Start = StartAddr;
End = StartAddr + Size;
}
void AddressRanges::encode(FileWriter &O, uint64_t BaseAddr) const {
O.writeULEB(Ranges.size());
if (Ranges.empty())
return;
for (auto Range : Ranges)
Range.encode(O, BaseAddr);
}
void AddressRanges::decode(DataExtractor &Data, uint64_t BaseAddr,
uint64_t &Offset) {
clear();
uint64_t NumRanges = Data.getULEB128(&Offset);
if (NumRanges == 0)
return;
Ranges.resize(NumRanges);
for (auto &Range : Ranges)
Range.decode(Data, BaseAddr, Offset);
}
void AddressRange::skip(DataExtractor &Data, uint64_t &Offset) {
Data.getULEB128(&Offset);
Data.getULEB128(&Offset);
}
uint64_t AddressRanges::skip(DataExtractor &Data, uint64_t &Offset) {
uint64_t NumRanges = Data.getULEB128(&Offset);
for (uint64_t I=0; I<NumRanges; ++I)
AddressRange::skip(Data, Offset);
return NumRanges;
}