@@ -32,25 +32,14 @@ getDataSlice(ArrayRef<uint8_t> Data, uint64_t Offset, uint64_t Size) {
3232}
3333
3434template <typename T>
35- static Expected<ArrayRef<T>>
36- getDataSliceAsArrayOf (ArrayRef< uint8_t > Data, uint64_t Offset, uint64_t Count ) {
35+ static Expected<const T &> getDataSliceAs ( ArrayRef<uint8_t > Data,
36+ uint64_t Offset ) {
3737 static_assert (std::is_trivial_v<T>);
38- Expected<ArrayRef<uint8_t >> Slice =
39- getDataSlice (Data, Offset, sizeof (T) * Count);
38+ Expected<ArrayRef<uint8_t >> Slice = getDataSlice (Data, Offset, sizeof (T));
4039 if (!Slice)
4140 return Slice.takeError ();
4241
43- return ArrayRef (reinterpret_cast <const T *>(Slice->data ()), Count);
44- }
45-
46- template <typename T>
47- static Expected<const T &> getDataSliceAs (ArrayRef<uint8_t > Data,
48- uint64_t Offset) {
49- Expected<ArrayRef<T>> Array = getDataSliceAsArrayOf<T>(Data, Offset, 1 );
50- if (!Array)
51- return Array.takeError ();
52-
53- return Array->front ();
42+ return *reinterpret_cast <const T *>(Slice->data ());
5443}
5544
5645template <endianness E>
@@ -111,119 +100,6 @@ uint64_t SFrameParser<E>::getAbsoluteStartAddress(
111100 return Result;
112101}
113102
114- template <typename EndianT>
115- static Error readArray (ArrayRef<uint8_t > Data, uint64_t Count, uint64_t &Offset,
116- SmallVectorImpl<int32_t > &Vec) {
117- Expected<ArrayRef<EndianT>> RawArray =
118- getDataSliceAsArrayOf<EndianT>(Data, Offset, Count);
119- if (!RawArray)
120- return RawArray.takeError ();
121- Offset += Count * sizeof (EndianT);
122- Vec.resize (Count);
123- llvm::copy (*RawArray, Vec.begin ());
124- return Error::success ();
125- }
126-
127- template <typename T, endianness E>
128- static Error readFRE (ArrayRef<uint8_t > Data, uint64_t &Offset,
129- typename SFrameParser<E>::FrameRowEntry &FRE) {
130- Expected<sframe::FrameRowEntry<T, E>> RawFRE =
131- getDataSliceAs<sframe::FrameRowEntry<T, E>>(Data, Offset);
132- if (!RawFRE)
133- return RawFRE.takeError ();
134-
135- Offset += sizeof (*RawFRE);
136- FRE.StartAddress = RawFRE->StartAddress ;
137- FRE.Info .Info = RawFRE->Info .Info ;
138-
139- switch (FRE.Info .getOffsetSize ()) {
140- case sframe::FREOffset::B1:
141- return readArray<sframe::detail::packed<int8_t , E>>(
142- Data, FRE.Info .getOffsetCount (), Offset, FRE.Offsets );
143- case sframe::FREOffset::B2:
144- return readArray<sframe::detail::packed<int16_t , E>>(
145- Data, FRE.Info .getOffsetCount (), Offset, FRE.Offsets );
146- case sframe::FREOffset::B4:
147- return readArray<sframe::detail::packed<int32_t , E>>(
148- Data, FRE.Info .getOffsetCount (), Offset, FRE.Offsets );
149- default :
150- return createError (" unsupported/unknown offset size" );
151- }
152- }
153-
154- template <endianness E> Error SFrameParser<E>::FallibleFREIterator::inc() {
155- if (++Idx == Size)
156- return Error::success ();
157-
158- switch (FREType) {
159- case sframe::FREType::Addr1:
160- return readFRE<uint8_t , E>(Data, Offset, FRE);
161- case sframe::FREType::Addr2:
162- return readFRE<uint16_t , E>(Data, Offset, FRE);
163- case sframe::FREType::Addr4:
164- return readFRE<uint32_t , E>(Data, Offset, FRE);
165- default :
166- return createError (" invalid/unsupported FRE type" );
167- }
168- }
169-
170- template <endianness E>
171- iterator_range<typename SFrameParser<E>::fre_iterator>
172- SFrameParser<E>::fres(const sframe::FuncDescEntry<E> &FDE, Error &Err) const {
173- uint64_t Offset = getFREBase () + FDE.StartFREOff ;
174- fre_iterator BeforeBegin = make_fallible_itr (
175- FallibleFREIterator (Data, FDE.getFREType (), -1 , FDE.NumFREs , Offset),
176- Err);
177- fre_iterator End = make_fallible_end (
178- FallibleFREIterator (Data, FDE.getFREType (), FDE.NumFREs , FDE.NumFREs ,
179- /* Offset=*/ 0 ));
180- return {++BeforeBegin, End};
181- }
182-
183- static std::optional<int32_t > getOffset (ArrayRef<int32_t > Offsets, size_t Idx) {
184- if (Offsets.size () > Idx)
185- return Offsets[Idx];
186- return std::nullopt ;
187- }
188-
189- // The interpretation of offsets is ABI-specific. The implementation of this and
190- // the following functions may need to be adjusted when adding support for a new
191- // ABI.
192- template <endianness E>
193- std::optional<int32_t >
194- SFrameParser<E>::getCFAOffset(const FrameRowEntry &FRE) const {
195- return getOffset (FRE.Offsets , 0 );
196- }
197-
198- template <endianness E>
199- std::optional<int32_t >
200- SFrameParser<E>::getRAOffset(const FrameRowEntry &FRE) const {
201- if (usesFixedRAOffset ())
202- return Header.CFAFixedRAOffset ;
203- return getOffset (FRE.Offsets , 1 );
204- }
205-
206- template <endianness E>
207- std::optional<int32_t >
208- SFrameParser<E>::getFPOffset(const FrameRowEntry &FRE) const {
209- if (usesFixedFPOffset ())
210- return Header.CFAFixedFPOffset ;
211- return getOffset (FRE.Offsets , usesFixedRAOffset () ? 1 : 2 );
212- }
213-
214- template <endianness E>
215- ArrayRef<int32_t >
216- SFrameParser<E>::getExtraOffsets(const FrameRowEntry &FRE) const {
217- size_t UsedOffsets = 1 ; // CFA
218- if (!usesFixedRAOffset ())
219- ++UsedOffsets;
220- if (!usesFixedFPOffset ())
221- ++UsedOffsets;
222- if (FRE.Offsets .size () > UsedOffsets)
223- return ArrayRef (FRE.Offsets ).drop_front (UsedOffsets);
224- return {};
225- }
226-
227103template class LLVM_EXPORT_TEMPLATE llvm::object::SFrameParser<endianness::big>;
228104template class LLVM_EXPORT_TEMPLATE
229105 llvm::object::SFrameParser<endianness::little>;
0 commit comments