1 //===- FileWriter.h ---------------------------------------------*- 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 #ifndef LLVM_DEBUGINFO_GSYM_FILEWRITER_H
10 #define LLVM_DEBUGINFO_GSYM_FILEWRITER_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/Support/Endian.h"
14 
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <sys/types.h>
18 
19 namespace llvm {
20 class raw_pwrite_stream;
21 
22 namespace gsym {
23 
24 /// A simplified binary data writer class that doesn't require targets, target
25 /// definitions, architectures, or require any other optional compile time
26 /// libraries to be enabled via the build process. This class needs the ability
27 /// to seek to different spots in the binary stream that is produces to fixup
28 /// offsets and sizes.
29 class FileWriter {
30   llvm::raw_pwrite_stream &OS;
31   llvm::endianness ByteOrder;
32 
33 public:
34   FileWriter(llvm::raw_pwrite_stream &S, llvm::endianness B)
35       : OS(S), ByteOrder(B) {}
36   ~FileWriter();
37   /// Write a single uint8_t value into the stream at the current file
38   /// position.
39   ///
40   /// \param   Value The value to write into the stream.
41   void writeU8(uint8_t Value);
42 
43   /// Write a single uint16_t value into the stream at the current file
44   /// position. The value will be byte swapped if needed to match the byte
45   /// order specified during construction.
46   ///
47   /// \param   Value The value to write into the stream.
48   void writeU16(uint16_t Value);
49 
50   /// Write a single uint32_t value into the stream at the current file
51   /// position. The value will be byte swapped if needed to match the byte
52   /// order specified during construction.
53   ///
54   /// \param   Value The value to write into the stream.
55   void writeU32(uint32_t Value);
56 
57   /// Write a single uint64_t value into the stream at the current file
58   /// position. The value will be byte swapped if needed to match the byte
59   /// order specified during construction.
60   ///
61   /// \param   Value The value to write into the stream.
62   void writeU64(uint64_t Value);
63 
64   /// Write the value into the stream encoded using signed LEB128 at the
65   /// current file position.
66   ///
67   /// \param   Value The value to write into the stream.
68   void writeSLEB(int64_t Value);
69 
70   /// Write the value into the stream encoded using unsigned LEB128 at the
71   /// current file position.
72   ///
73   /// \param   Value The value to write into the stream.
74   void writeULEB(uint64_t Value);
75 
76   /// Write an array of uint8_t values into the stream at the current file
77   /// position.
78   ///
79   /// \param   Data An array of values to write into the stream.
80   void writeData(llvm::ArrayRef<uint8_t> Data);
81 
82   /// Write a NULL terminated C string into the stream at the current file
83   /// position. The entire contents of Str will be written into the steam at
84   /// the current file position and then an extra NULL termation byte will be
85   /// written. It is up to the user to ensure that Str doesn't contain any NULL
86   /// characters unless the additional NULL characters are desired.
87   ///
88   /// \param   Str The value to write into the stream.
89   void writeNullTerminated(llvm::StringRef Str);
90 
91   /// Fixup a uint32_t value at the specified offset in the stream. This
92   /// function will save the current file position, seek to the specified
93   /// offset, overwrite the data using Value, and then restore the file
94   /// position to the previous file position.
95   ///
96   /// \param   Value The value to write into the stream.
97   /// \param   Offset The offset at which to write the Value within the stream.
98   void fixup32(uint32_t Value, uint64_t Offset);
99 
100   /// Pad with zeroes at the current file position until the current file
101   /// position matches the specified alignment.
102   ///
103   /// \param  Align An integer speciying the desired alignment. This does not
104   ///         need to be a power of two.
105   void alignTo(size_t Align);
106 
107   /// Return the current offset within the file.
108   ///
109   /// \return The unsigned offset from the start of the file of the current
110   ///         file position.
111   uint64_t tell();
112 
113   llvm::raw_pwrite_stream &get_stream() {
114     return OS;
115   }
116 
117   llvm::endianness getByteOrder() const { return ByteOrder; }
118 
119 private:
120   FileWriter(const FileWriter &rhs) = delete;
121   void operator=(const FileWriter &rhs) = delete;
122 };
123 
124 } // namespace gsym
125 } // namespace llvm
126 
127 #endif // LLVM_DEBUGINFO_GSYM_FILEWRITER_H
128