Home | History | Annotate | Download | only in crash_collector
      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 
     42   size_t coredump_size_limit() const { return coredump_size_limit_; }
     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