blob: 66e42737d37a4f56ce9f0ca07f6dfc5eeccb922a [file] [log] [blame]
// Copyright 2016 The Tulsi Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef POST_PROCESSOR_COVMAPSECTION_H_
#define POST_PROCESSOR_COVMAPSECTION_H_
#include <sys/types.h>
#include <string>
#include <vector>
#include "dwarf_buffer_reader.h"
#include "return_code.h"
namespace post_processor {
/// Provides utilities to read and manipulate __llvm_covmap sections in Mach
/// binaries.
/// WARNING: This class is not thread-safe.
class CovmapSection {
public:
/// Creates a CovmapSection that may be used to manipulate the given coverage
/// map data. If "swap_byte_ordering" is true, values read will be translated
/// to host byte order.
CovmapSection(std::unique_ptr<uint8_t[]> covmap_section,
size_t section_length,
bool swap_byte_ordering);
/// Parses the section data.
ReturnCode Parse();
/// Patches all filenames in the covmap data, replacing any paths that start
/// with "old_prefix" with "new_prefix".
/// WARNING: As an optimization, this method may move and invalidate this
/// CovmapSection's data member. It is unsafe to invoke any method on
/// this instance after this method returns.
std::unique_ptr<uint8_t[]> PatchFilenamesAndInvalidate(
const std::string &old_prefix,
const std::string &new_prefix,
size_t *section_length,
bool *data_was_modified);
inline const uint8_t *section_data() const { return section_data_.get(); }
inline size_t section_length() const { return section_length_; }
private:
/// Models an array of filenames associated with a given coverage mapping.
struct FilenameGroup {
void CalculateSize();
/// Appends the serialized form of this FilenameGroup to the given vector,
/// inserting additional empty filenames if necessary to pad to min_size.
bool Serialize(std::vector<uint8_t> *v, size_t min_size = 0) const;
size_t size; // Serialized size of this group in bytes.
off_t offset; // Offset of this FilenameGroup in the file.
std::vector<std::string> filenames;
};
private:
/// Reads an LLVM coverage mapping. has_more is set to true if additional
/// coverage mappings may be read from this covmap section.
ReturnCode ReadCoverageMapping(bool *has_more);
/// Reads function records within an LLVM coverage mapping.
ReturnCode ReadFunctionRecords(uint32_t count);
/// Reads function records within an LLVM v2 coverage mapping.
ReturnCode ReadV2FunctionRecords(uint32_t count);
/// Reads a filename array within an LLVM coverage mapping.
ReturnCode ReadFilenameGroup(FilenameGroup *);
private:
std::unique_ptr<uint8_t[]> section_data_;
size_t section_length_;
DWARFBufferReader reader_;
std::vector<FilenameGroup> filename_groups_;
};
} // namespace post_processor
#endif // POST_PROCESSOR_COVMAPSECTION_H_