1 /*
2  * Copyright (C) 2015 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 #ifndef COREDUMP_WRITER_H_
18 #define COREDUMP_WRITER_H_
19 
20 #include <map>
21 #include <string>
22 #include <vector>
23 
24 #include <elf.h>
25 #include <link.h>
26 
27 #include <android-base/macros.h>
28 
29 class CoredumpWriter {
30  public:
31   // Coredump will be read from |fd_src|, and will be written to
32   // |coredump_filename|. Additional files which are necessary to generate
33   // minidump will be generated under |proc_files_dir|.
34   CoredumpWriter(int fd_src,
35                  const std::string& coredump_filename,
36                  const std::string& proc_files_dir);
37   ~CoredumpWriter();
38 
39   // Writes coredump and returns the number of bytes written, or -1 on errors.
40   ssize_t WriteCoredump();
41 
coredump_size_limit()42   size_t coredump_size_limit() const { return coredump_size_limit_; }
expected_coredump_size()43   size_t expected_coredump_size() const { return expected_coredump_size_; }
44 
45  private:
46   using Ehdr = ElfW(Ehdr);
47   using Phdr = ElfW(Phdr);
48 
49   // Virtual address occupied by a mapped file.
50   using FileRange = std::pair<long, long>;
51   struct FileInfo {
52     long offset;
53     std::string path;
54   };
55   using FileMappings = std::map<FileRange, FileInfo>;
56 
57   class FdReader;
58 
59   ssize_t WriteCoredumpToFD(int fd_dest);
60 
61   // Reads ELF header, all program headers, and NOTE segment from fd_src.
62   bool ReadUntilNote(FdReader* reader,
63                      Ehdr* elf_header,
64                      std::vector<Phdr>* program_headers,
65                      std::vector<char>* note_buf);
66 
67   // Extracts a set of address ranges occupied by mapped files from NOTE segment.
68   bool GetFileMappings(const std::vector<char>& note_buf,
69                        FileMappings* file_mappings);
70 
71   // Filters out unneeded segments.
72   void FilterSegments(const std::vector<Phdr>& program_headers,
73                       const FileMappings& file_mappings,
74                       std::vector<Phdr>* program_headers_filtered);
75 
76   // Writes the contents of NT_AUXV note to a file.
77   bool WriteAuxv(const std::vector<char>& note_buf,
78                  const std::string& output_path);
79 
80   // Writes mapping info to a file in the same format as /proc/PID/maps.
81   // (cf. "man proc")
82   bool WriteMaps(const std::vector<Phdr>& program_headers,
83                  const FileMappings& file_mappings,
84                  const std::string& output_path);
85 
86   const int fd_src_;
87   const std::string coredump_filename_;
88   const std::string proc_files_dir_;
89   size_t coredump_size_limit_ = 0;
90   size_t expected_coredump_size_ = 0;
91 
92   DISALLOW_COPY_AND_ASSIGN(CoredumpWriter);
93 };
94 
95 #endif  // COREDUMP_WRITER_H_
96