1 //===- ExtractRanges.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/DebugInfo/GSYM/ExtractRanges.h"
10 #include "llvm/DebugInfo/GSYM/FileWriter.h"
11 #include "llvm/Support/DataExtractor.h"
12 #include <algorithm>
13 #include <inttypes.h>
14 
15 namespace llvm {
16 namespace gsym {
17 
18 void encodeRange(const AddressRange &Range, FileWriter &O, uint64_t BaseAddr) {
19   assert(Range.start() >= BaseAddr);
20   O.writeULEB(Range.start() - BaseAddr);
21   O.writeULEB(Range.size());
22 }
23 
24 AddressRange decodeRange(DataExtractor &Data, uint64_t BaseAddr,
25                          uint64_t &Offset) {
26   const uint64_t AddrOffset = Data.getULEB128(&Offset);
27   const uint64_t Size = Data.getULEB128(&Offset);
28   const uint64_t StartAddr = BaseAddr + AddrOffset;
29 
30   return {StartAddr, StartAddr + Size};
31 }
32 
33 void encodeRanges(const AddressRanges &Ranges, FileWriter &O,
34                   uint64_t BaseAddr) {
35   O.writeULEB(Ranges.size());
36   if (Ranges.empty())
37     return;
38   for (auto Range : Ranges)
39     encodeRange(Range, O, BaseAddr);
40 }
41 
42 void decodeRanges(AddressRanges &Ranges, DataExtractor &Data, uint64_t BaseAddr,
43                   uint64_t &Offset) {
44   Ranges.clear();
45   uint64_t NumRanges = Data.getULEB128(&Offset);
46   Ranges.reserve(NumRanges);
47   for (uint64_t RangeIdx = 0; RangeIdx < NumRanges; RangeIdx++)
48     Ranges.insert(decodeRange(Data, BaseAddr, Offset));
49 }
50 
51 void skipRange(DataExtractor &Data, uint64_t &Offset) {
52   Data.getULEB128(&Offset);
53   Data.getULEB128(&Offset);
54 }
55 
56 uint64_t skipRanges(DataExtractor &Data, uint64_t &Offset) {
57   uint64_t NumRanges = Data.getULEB128(&Offset);
58   for (uint64_t I = 0; I < NumRanges; ++I)
59     skipRange(Data, Offset);
60   return NumRanges;
61 }
62 
63 } // namespace gsym
64 
65 raw_ostream &operator<<(raw_ostream &OS, const AddressRange &R) {
66   return OS << '[' << HEX64(R.start()) << " - " << HEX64(R.end()) << ")";
67 }
68 
69 raw_ostream &operator<<(raw_ostream &OS, const AddressRanges &AR) {
70   size_t Size = AR.size();
71   for (size_t I = 0; I < Size; ++I) {
72     if (I)
73       OS << ' ';
74     OS << AR[I];
75   }
76   return OS;
77 }
78 
79 } // namespace llvm
80