1 // Copyright 2024 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 17 #include <cstring> 18 #include <memory> 19 #include <optional> 20 #include <string_view> 21 #include <variant> 22 #include <vector> 23 24 #include "pw_bytes/span.h" 25 #include "pw_elf/internal/reader_impl.h" 26 #include "pw_result/result.h" 27 #include "pw_status/status.h" 28 #include "pw_status/try.h" 29 #include "pw_stream/stream.h" 30 31 namespace pw::elf { 32 33 /// A basic reader for ELF files. 34 class ElfReader { 35 public: 36 /// Creates an ElfReader from a stream. 37 /// 38 /// @returns @rst 39 /// 40 /// .. pw-status-codes:: 41 /// 42 /// OK: The reader was initialized successfully. 43 /// 44 /// DATA_LOSS: The input file was invalid. 45 /// 46 /// OUT_OF_RANGE: Input stream exhausted (EOF). 47 /// 48 /// UNIMPLEMENTED: Some aspect of the ELF file is not (yet) supported by 49 /// this class, e.g., non-native endianness, or 64-bit ELF on a 32-bit 50 /// host. 51 /// 52 /// May return other error codes from the underlying stream. 53 /// 54 /// @endrst 55 static Result<ElfReader> FromStream(stream::SeekableReader& stream); 56 57 /// Gets the associated stream. stream()58 stream::SeekableReader& stream() const { 59 return std::visit([](auto&& impl) -> auto& { return impl.stream(); }, 60 impl_); 61 } 62 63 /// Seeks the associated stream to the beginning of the data of the section 64 /// with the given name. 65 /// 66 /// @param[in] name The name of the desired section. 67 /// 68 /// @returns @rst 69 /// 70 /// .. pw-status-codes:: 71 /// 72 /// OK: Successfully found the desired section and seeked the stream to 73 /// it. The associated size is the size of the associated section. 74 /// 75 /// NOT_FOUND: No section was found with the desired name. 76 /// 77 /// May return other error codes from the underlying stream. 78 /// 79 /// @endrst SeekToSection(std::string_view name)80 StatusWithSize SeekToSection(std::string_view name) { 81 return std::visit([name](auto&& impl) { return impl.SeekToSection(name); }, 82 impl_); 83 } 84 85 /// Reads a section with the given name. 86 /// 87 /// @param[in] name The name of the desired section. 88 /// 89 /// @returns @rst 90 /// 91 /// .. pw-status-codes:: 92 /// 93 /// OK: Successfully read the desired section. 94 /// The result value is a vector of the section data. 95 /// 96 /// NOT_FOUND: No section was found with the desired name. 97 /// 98 /// May return other error codes from the underlying stream. 99 /// 100 /// @endrst 101 Result<std::vector<std::byte>> ReadSection(std::string_view name); 102 103 private: 104 internal::ElfReaderImpls impl_; 105 ElfReader(internal::ElfReaderImpls && impl)106 ElfReader(internal::ElfReaderImpls&& impl) : impl_(std::move(impl)) {} 107 }; 108 109 } // namespace pw::elf 110