1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <sys/types.h>
20 
21 #include <string>
22 #include <string_view>
23 #include <vector>
24 
25 #include "rangeset.h"
26 
27 // This class holds the content of a block map file.
28 class BlockMapData {
29  public:
30   // A "block map" which looks like this (from uncrypt/uncrypt.cpp):
31   //
32   //   /dev/block/platform/msm_sdcc.1/by-name/userdata     # block device
33   //   49652 4096                                          # file size in bytes, block size
34   //   3                                                   # count of block ranges
35   //   1000 1008                                           # block range 0
36   //   2100 2102                                           # ... block range 1
37   //   30 33                                               # ... block range 2
38   //
39   // Each block range represents a half-open interval; the line "30 33" reprents the blocks
40   // [30, 31, 32].
41   static BlockMapData ParseBlockMapFile(const std::string& block_map_path);
42 
43   explicit operator bool() const {
44     return !path_.empty();
45   }
46 
path()47   std::string path() const {
48     return path_;
49   }
file_size()50   uint64_t file_size() const {
51     return file_size_;
52   }
block_size()53   uint32_t block_size() const {
54     return block_size_;
55   }
block_ranges()56   RangeSet block_ranges() const {
57     return block_ranges_;
58   }
59 
60  private:
61   BlockMapData() = default;
62 
BlockMapData(const std::string & path,uint64_t file_size,uint32_t block_size,RangeSet block_ranges)63   BlockMapData(const std::string& path, uint64_t file_size, uint32_t block_size,
64                RangeSet block_ranges)
65       : path_(path),
66         file_size_(file_size),
67         block_size_(block_size),
68         block_ranges_(std::move(block_ranges)) {}
69 
70   std::string path_;
71   uint64_t file_size_ = 0;
72   uint32_t block_size_ = 0;
73   RangeSet block_ranges_;
74 };
75 
76 /*
77  * Use this to keep track of mapped segments.
78  */
79 class MemMapping {
80  public:
81   ~MemMapping();
82   // Map a file into a private, read-only memory segment. If 'filename' begins with an '@'
83   // character, it is a map of blocks to be mapped, otherwise it is treated as an ordinary file.
84   bool MapFile(const std::string& filename);
ranges()85   size_t ranges() const {
86     return ranges_.size();
87   };
88 
89   unsigned char* addr;  // start of data
90   size_t length;        // length of data
91 
92  private:
93   struct MappedRange {
94     void* addr;
95     size_t length;
96   };
97 
98   bool MapBlockFile(const std::string& filename);
99   bool MapFD(int fd);
100 
101   std::vector<MappedRange> ranges_;
102 };
103 
104 // Reboots the device into the specified target, by additionally handling quiescent reboot mode.
105 // All unknown targets reboot into Android.
106 [[noreturn]] void Reboot(std::string_view target);
107 
108 // Triggers a shutdown.
109 bool Shutdown(std::string_view target);
110 
111 // Returns a null-terminated char* array, where the elements point to the C-strings in the given
112 // vector, plus an additional nullptr at the end. This is a helper function that facilitates
113 // calling C functions (such as getopt(3)) that expect an array of C-strings.
114 std::vector<char*> StringVectorToNullTerminatedArray(const std::vector<std::string>& args);
115