blob: f0ed81b6e9c0ebf784baccbd4bdc669297043ab5 [file] [log] [blame]
// Copyright 2016 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CRASH_REPORTER_CORE_COLLECTOR_COREDUMP_WRITER_H_
#define CRASH_REPORTER_CORE_COLLECTOR_COREDUMP_WRITER_H_
#include <functional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <elf.h>
#include <link.h>
#include <common/basictypes.h>
// Reads a core dump from an input stream, writes a stripped version thereof to
// disk, and generates files needed for minidump conversion.
class CoredumpWriter {
public:
// Virtual address range occupied by a mapped file.
using FileRange = std::pair<ElfW(Addr), ElfW(Addr)>;
// Core dump is read from |fd|, and written to |coredump_path|. Files needed
// for minidump conversion are stored in |container_dir|.
CoredumpWriter(int fd,
const char *coredump_path,
const char *container_dir);
// Returns sysexits.h exit code.
int WriteCoredump();
private:
using Ehdr = ElfW(Ehdr);
using Phdr = ElfW(Phdr);
struct FileInfo {
ElfW(Off) offset;
std::string path;
};
using FileMappings = std::unordered_map<FileRange, FileInfo>;
class Reader;
// Reads ELF header, all program headers, and PT_NOTE segment.
int ReadUntilNote(Reader *reader,
Ehdr *elf_header,
std::vector<Phdr> *program_headers,
std::vector<char> *note_buf);
// Extracts address ranges occupied by mapped files from PT_NOTE segment.
bool GetFileMappings(const std::vector<char> &note_buf,
FileMappings *file_mappings);
// Strips unnecessary segments by setting their size to zero.
static void StripSegments(const std::vector<Phdr> &program_headers,
const FileMappings &file_mappings,
std::vector<Phdr> *stripped_program_headers);
// Writes file in |container_dir_| in the format of /proc/[pid]/auxv.
int WriteAuxv(const std::vector<char> &note_buf);
// Writes file in |container_dir_| in the format of /proc/[pid]/maps.
int WriteMaps(const std::vector<Phdr> &program_headers,
const FileMappings &file_mappings);
const int fd_; // Source stream.
const char * const coredump_path_;
const char * const container_dir_;
DISALLOW_COPY_AND_ASSIGN(CoredumpWriter);
};
namespace std {
template <>
struct hash<CoredumpWriter::FileRange> {
std::size_t operator ()(const CoredumpWriter::FileRange &range) const {
// Hashing either address is sufficient, since collisions due to duplicate
// addresses are impossible.
return std::hash<ElfW(Addr)>()(range.first);
}
};
} // namespace std
#endif // CRASH_REPORTER_CORE_COLLECTOR_COREDUMP_WRITER_H_