DWARFFormValue.h revision 321369
1321369Sdim//===- DWARFFormValue.h -----------------------------------------*- C++ -*-===//
2283625Sdim//
3283625Sdim//                     The LLVM Compiler Infrastructure
4283625Sdim//
5283625Sdim// This file is distributed under the University of Illinois Open Source
6283625Sdim// License. See LICENSE.TXT for details.
7283625Sdim//
8283625Sdim//===----------------------------------------------------------------------===//
9283625Sdim
10283625Sdim#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H
11283625Sdim#define LLVM_DEBUGINFO_DWARFFORMVALUE_H
12283625Sdim
13321369Sdim#include "llvm/ADT/ArrayRef.h"
14321369Sdim#include "llvm/ADT/None.h"
15283625Sdim#include "llvm/ADT/Optional.h"
16321369Sdim#include "llvm/BinaryFormat/Dwarf.h"
17321369Sdim#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
18321369Sdim#include <cstdint>
19283625Sdim
20283625Sdimnamespace llvm {
21283625Sdim
22283625Sdimclass DWARFUnit;
23283625Sdimclass raw_ostream;
24283625Sdim
25321369Sdim/// A helper struct for DWARFFormValue methods, providing information that
26321369Sdim/// allows it to know the byte size of DW_FORM values that vary in size
27321369Sdim/// depending on the DWARF version, address byte size, or DWARF32/DWARF64.
28321369Sdimstruct DWARFFormParams {
29321369Sdim  uint16_t Version;
30321369Sdim  uint8_t AddrSize;
31321369Sdim  dwarf::DwarfFormat Format;
32321369Sdim
33321369Sdim  /// The definition of the size of form DW_FORM_ref_addr depends on the
34321369Sdim  /// version. In DWARF v2 it's the size of an address; after that, it's the
35321369Sdim  /// size of a reference.
36321369Sdim  uint8_t getRefAddrByteSize() const {
37321369Sdim    if (Version == 2)
38321369Sdim      return AddrSize;
39321369Sdim    return getDwarfOffsetByteSize();
40321369Sdim  }
41321369Sdim
42321369Sdim  /// The size of a reference is determined by the DWARF 32/64-bit format.
43321369Sdim  uint8_t getDwarfOffsetByteSize() const {
44321369Sdim    switch (Format) {
45321369Sdim    case dwarf::DwarfFormat::DWARF32:
46321369Sdim      return 4;
47321369Sdim    case dwarf::DwarfFormat::DWARF64:
48321369Sdim      return 8;
49321369Sdim    }
50321369Sdim    llvm_unreachable("Invalid Format value");
51321369Sdim  }
52321369Sdim};
53321369Sdim
54283625Sdimclass DWARFFormValue {
55283625Sdimpublic:
56283625Sdim  enum FormClass {
57283625Sdim    FC_Unknown,
58283625Sdim    FC_Address,
59283625Sdim    FC_Block,
60283625Sdim    FC_Constant,
61283625Sdim    FC_String,
62283625Sdim    FC_Flag,
63283625Sdim    FC_Reference,
64283625Sdim    FC_Indirect,
65283625Sdim    FC_SectionOffset,
66283625Sdim    FC_Exprloc
67283625Sdim  };
68283625Sdim
69283625Sdimprivate:
70283625Sdim  struct ValueType {
71321369Sdim    ValueType() { uval = 0; }
72283625Sdim
73283625Sdim    union {
74283625Sdim      uint64_t uval;
75283625Sdim      int64_t sval;
76321369Sdim      const char *cstr;
77283625Sdim    };
78321369Sdim    const uint8_t *data = nullptr;
79321369Sdim    uint64_t SectionIndex;      /// Section index for reference forms.
80283625Sdim  };
81283625Sdim
82321369Sdim  dwarf::Form Form;             /// Form for this value.
83321369Sdim  ValueType Value;              /// Contains all data for the form.
84321369Sdim  const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
85283625Sdim
86283625Sdimpublic:
87321369Sdim  DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
88321369Sdim
89314564Sdim  dwarf::Form getForm() const { return Form; }
90321369Sdim  uint64_t getRawUValue() const { return Value.uval; }
91321369Sdim  uint64_t getSectionIndex() const { return Value.SectionIndex; }
92314564Sdim  void setForm(dwarf::Form F) { Form = F; }
93314564Sdim  void setUValue(uint64_t V) { Value.uval = V; }
94314564Sdim  void setSValue(int64_t V) { Value.sval = V; }
95314564Sdim  void setPValue(const char *V) { Value.cstr = V; }
96321369Sdim
97321369Sdim  void setBlockValue(const ArrayRef<uint8_t> &Data) {
98321369Sdim    Value.data = Data.data();
99321369Sdim    setUValue(Data.size());
100321369Sdim  }
101321369Sdim
102283625Sdim  bool isFormClass(FormClass FC) const;
103314564Sdim  const DWARFUnit *getUnit() const { return U; }
104314564Sdim  void dump(raw_ostream &OS) const;
105283625Sdim
106321369Sdim  /// Extracts a value in \p Data at offset \p *OffsetPtr.
107283625Sdim  ///
108321369Sdim  /// The passed DWARFUnit is allowed to be nullptr, in which case some
109283625Sdim  /// kind of forms that depend on Unit information are disallowed.
110321369Sdim  /// \param Data The DWARFDataExtractor to use.
111321369Sdim  /// \param OffsetPtr The offset within \p Data where the data starts.
112321369Sdim  /// \param U The optional DWARFUnit supplying information for some forms.
113283625Sdim  /// \returns whether the extraction succeeded.
114321369Sdim  bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr,
115314564Sdim                    const DWARFUnit *U);
116321369Sdim
117283625Sdim  bool isInlinedCStr() const {
118321369Sdim    return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr;
119283625Sdim  }
120283625Sdim
121283625Sdim  /// getAsFoo functions below return the extracted value as Foo if only
122283625Sdim  /// DWARFFormValue has form class is suitable for representing Foo.
123314564Sdim  Optional<uint64_t> getAsReference() const;
124283625Sdim  Optional<uint64_t> getAsUnsignedConstant() const;
125283625Sdim  Optional<int64_t> getAsSignedConstant() const;
126314564Sdim  Optional<const char *> getAsCString() const;
127314564Sdim  Optional<uint64_t> getAsAddress() const;
128283625Sdim  Optional<uint64_t> getAsSectionOffset() const;
129283625Sdim  Optional<ArrayRef<uint8_t>> getAsBlock() const;
130314564Sdim  Optional<uint64_t> getAsCStringOffset() const;
131314564Sdim  Optional<uint64_t> getAsReferenceUVal() const;
132321369Sdim
133314564Sdim  /// Get the fixed byte size for a given form.
134314564Sdim  ///
135321369Sdim  /// If the form has a fixed byte size, then an Optional with a value will be
136321369Sdim  /// returned. If the form is always encoded using a variable length storage
137321369Sdim  /// format (ULEB or SLEB numbers or blocks) then None will be returned.
138314564Sdim  ///
139321369Sdim  /// \param Form DWARF form to get the fixed byte size for.
140321369Sdim  /// \param FormParams DWARF parameters to help interpret forms.
141314564Sdim  /// \returns Optional<uint8_t> value with the fixed byte size or None if
142321369Sdim  /// \p Form doesn't have a fixed byte size.
143314564Sdim  static Optional<uint8_t> getFixedByteSize(dwarf::Form Form,
144321369Sdim                                            const DWARFFormParams FormParams);
145283625Sdim
146321369Sdim  /// Skip a form's value in \p DebugInfoData at the offset specified by
147321369Sdim  /// \p OffsetPtr.
148314564Sdim  ///
149321369Sdim  /// Skips the bytes for the current form and updates the offset.
150314564Sdim  ///
151321369Sdim  /// \param DebugInfoData The data where we want to skip the value.
152321369Sdim  /// \param OffsetPtr A reference to the offset that will be updated.
153321369Sdim  /// \param Params DWARF parameters to help interpret forms.
154314564Sdim  /// \returns true on success, false if the form was not skipped.
155321369Sdim  bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
156321369Sdim                 const DWARFFormParams Params) const {
157321369Sdim    return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
158321369Sdim  }
159321369Sdim
160321369Sdim  /// Skip a form's value in \p DebugInfoData at the offset specified by
161321369Sdim  /// \p OffsetPtr.
162314564Sdim  ///
163321369Sdim  /// Skips the bytes for the specified form and updates the offset.
164314564Sdim  ///
165321369Sdim  /// \param Form The DW_FORM enumeration that indicates the form to skip.
166321369Sdim  /// \param DebugInfoData The data where we want to skip the value.
167321369Sdim  /// \param OffsetPtr A reference to the offset that will be updated.
168321369Sdim  /// \param FormParams DWARF parameters to help interpret forms.
169314564Sdim  /// \returns true on success, false if the form was not skipped.
170321369Sdim  static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
171321369Sdim                        uint32_t *OffsetPtr, const DWARFFormParams FormParams);
172283625Sdim
173283625Sdimprivate:
174314564Sdim  void dumpString(raw_ostream &OS) const;
175283625Sdim};
176283625Sdim
177321369Sdimnamespace dwarf {
178321369Sdim
179321369Sdim/// Take an optional DWARFFormValue and try to extract a string value from it.
180321369Sdim///
181321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
182321369Sdim/// \returns an optional value that contains a value if the form value
183321369Sdim/// was valid and was a string.
184321369Sdiminline Optional<const char *> toString(const Optional<DWARFFormValue> &V) {
185321369Sdim  if (V)
186321369Sdim    return V->getAsCString();
187321369Sdim  return None;
188285181Sdim}
189283625Sdim
190321369Sdim/// Take an optional DWARFFormValue and extract a string value from it.
191321369Sdim///
192321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
193321369Sdim/// \param Default the default value to return in case of failure.
194321369Sdim/// \returns the string value or Default if the V doesn't have a value or the
195321369Sdim/// form value's encoding wasn't a string.
196321369Sdiminline const char *toString(const Optional<DWARFFormValue> &V,
197321369Sdim                            const char *Default) {
198321369Sdim  return toString(V).getValueOr(Default);
199321369Sdim}
200321369Sdim
201321369Sdim/// Take an optional DWARFFormValue and try to extract an unsigned constant.
202321369Sdim///
203321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
204321369Sdim/// \returns an optional value that contains a value if the form value
205321369Sdim/// was valid and has a unsigned constant form.
206321369Sdiminline Optional<uint64_t> toUnsigned(const Optional<DWARFFormValue> &V) {
207321369Sdim  if (V)
208321369Sdim    return V->getAsUnsignedConstant();
209321369Sdim  return None;
210321369Sdim}
211321369Sdim
212321369Sdim/// Take an optional DWARFFormValue and extract a unsigned constant.
213321369Sdim///
214321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
215321369Sdim/// \param Default the default value to return in case of failure.
216321369Sdim/// \returns the extracted unsigned value or Default if the V doesn't have a
217321369Sdim/// value or the form value's encoding wasn't an unsigned constant form.
218321369Sdiminline uint64_t toUnsigned(const Optional<DWARFFormValue> &V,
219321369Sdim                           uint64_t Default) {
220321369Sdim  return toUnsigned(V).getValueOr(Default);
221321369Sdim}
222321369Sdim
223321369Sdim/// Take an optional DWARFFormValue and try to extract an reference.
224321369Sdim///
225321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
226321369Sdim/// \returns an optional value that contains a value if the form value
227321369Sdim/// was valid and has a reference form.
228321369Sdiminline Optional<uint64_t> toReference(const Optional<DWARFFormValue> &V) {
229321369Sdim  if (V)
230321369Sdim    return V->getAsReference();
231321369Sdim  return None;
232321369Sdim}
233321369Sdim
234321369Sdim/// Take an optional DWARFFormValue and extract a reference.
235321369Sdim///
236321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
237321369Sdim/// \param Default the default value to return in case of failure.
238321369Sdim/// \returns the extracted reference value or Default if the V doesn't have a
239321369Sdim/// value or the form value's encoding wasn't a reference form.
240321369Sdiminline uint64_t toReference(const Optional<DWARFFormValue> &V,
241321369Sdim                            uint64_t Default) {
242321369Sdim  return toReference(V).getValueOr(Default);
243321369Sdim}
244321369Sdim
245321369Sdim/// Take an optional DWARFFormValue and try to extract an signed constant.
246321369Sdim///
247321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
248321369Sdim/// \returns an optional value that contains a value if the form value
249321369Sdim/// was valid and has a signed constant form.
250321369Sdiminline Optional<int64_t> toSigned(const Optional<DWARFFormValue> &V) {
251321369Sdim  if (V)
252321369Sdim    return V->getAsSignedConstant();
253321369Sdim  return None;
254321369Sdim}
255321369Sdim
256321369Sdim/// Take an optional DWARFFormValue and extract a signed integer.
257321369Sdim///
258321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
259321369Sdim/// \param Default the default value to return in case of failure.
260321369Sdim/// \returns the extracted signed integer value or Default if the V doesn't
261321369Sdim/// have a value or the form value's encoding wasn't a signed integer form.
262321369Sdiminline int64_t toSigned(const Optional<DWARFFormValue> &V, int64_t Default) {
263321369Sdim  return toSigned(V).getValueOr(Default);
264321369Sdim}
265321369Sdim
266321369Sdim/// Take an optional DWARFFormValue and try to extract an address.
267321369Sdim///
268321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
269321369Sdim/// \returns an optional value that contains a value if the form value
270321369Sdim/// was valid and has a address form.
271321369Sdiminline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) {
272321369Sdim  if (V)
273321369Sdim    return V->getAsAddress();
274321369Sdim  return None;
275321369Sdim}
276321369Sdim
277321369Sdim/// Take an optional DWARFFormValue and extract a address.
278321369Sdim///
279321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
280321369Sdim/// \param Default the default value to return in case of failure.
281321369Sdim/// \returns the extracted address value or Default if the V doesn't have a
282321369Sdim/// value or the form value's encoding wasn't an address form.
283321369Sdiminline uint64_t toAddress(const Optional<DWARFFormValue> &V, uint64_t Default) {
284321369Sdim  return toAddress(V).getValueOr(Default);
285321369Sdim}
286321369Sdim
287321369Sdim/// Take an optional DWARFFormValue and try to extract an section offset.
288321369Sdim///
289321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
290321369Sdim/// \returns an optional value that contains a value if the form value
291321369Sdim/// was valid and has a section offset form.
292321369Sdiminline Optional<uint64_t> toSectionOffset(const Optional<DWARFFormValue> &V) {
293321369Sdim  if (V)
294321369Sdim    return V->getAsSectionOffset();
295321369Sdim  return None;
296321369Sdim}
297321369Sdim
298321369Sdim/// Take an optional DWARFFormValue and extract a section offset.
299321369Sdim///
300321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
301321369Sdim/// \param Default the default value to return in case of failure.
302321369Sdim/// \returns the extracted section offset value or Default if the V doesn't
303321369Sdim/// have a value or the form value's encoding wasn't a section offset form.
304321369Sdiminline uint64_t toSectionOffset(const Optional<DWARFFormValue> &V,
305321369Sdim                                uint64_t Default) {
306321369Sdim  return toSectionOffset(V).getValueOr(Default);
307321369Sdim}
308321369Sdim
309321369Sdim/// Take an optional DWARFFormValue and try to extract block data.
310321369Sdim///
311321369Sdim/// \param V and optional DWARFFormValue to attempt to extract the value from.
312321369Sdim/// \returns an optional value that contains a value if the form value
313321369Sdim/// was valid and has a block form.
314321369Sdiminline Optional<ArrayRef<uint8_t>> toBlock(const Optional<DWARFFormValue> &V) {
315321369Sdim  if (V)
316321369Sdim    return V->getAsBlock();
317321369Sdim  return None;
318321369Sdim}
319321369Sdim
320321369Sdim} // end namespace dwarf
321321369Sdim
322321369Sdim} // end namespace llvm
323321369Sdim
324321369Sdim#endif // LLVM_DEBUGINFO_DWARFFORMVALUE_H
325