blob: ca5781805ec9ba13f5c6dc6bd81bf756054924eb [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_DWARFSTRINGPATCHER_H_
#define POST_PROCESSOR_DWARFSTRINGPATCHER_H_
#include <sys/types.h>
#include <list>
#include <map>
#include <string>
#include <vector>
#include "patcher_base.h"
namespace post_processor {
class DWARFBufferReader;
class MachOFile;
/// Provides utilities to patch DWARF string table entries.
class DWARFStringPatcher : public PatcherBase {
public:
DWARFStringPatcher(const std::string &old_prefix,
const std::string &new_prefix,
bool verbose = false) :
PatcherBase(old_prefix, new_prefix, verbose) {
}
virtual ReturnCode Patch(MachOFile *f);
private:
// DWARF attributes consist of a "name" value and a form type.
typedef std::pair<uint64_t, uint64_t> Attribute;
struct Abbreviation {
uint64_t abbreviation_code;
uint64_t tag;
bool has_children;
std::vector<Attribute> attributes;
};
typedef std::map<uint64_t, Abbreviation> AbbreviationTable;
/// Encapsulates the set of information needed to patch a since compilation
/// unit's line info.
struct LineInfoPatch {
uint64_t compilation_unit_length;
/// The original offset of the unit_length field.
size_t compilation_unit_length_offset;
uint64_t header_length;
/// The original offset of the header_length field.
size_t header_length_offset;
// The original offset of the string table.
size_t string_table_start_offset;
// The length in bytes of the unmodified string table, including the null
// delimiter.
size_t string_table_length;
std::unique_ptr<uint8_t[]> new_string_table;
// The updated length of the string table.
size_t new_string_table_length;
};
private:
void UpdateStringSectionInPlace(char *data,
size_t data_length,
bool *data_was_modified);
std::unique_ptr<uint8_t[]> RewriteStringSection(
char *data,
size_t data_length,
std::map<size_t, size_t> *relocation_table,
size_t *new_data_length,
bool *data_was_modified);
ReturnCode ProcessAbbrevSection(
const MachOFile &f,
std::map<size_t, AbbreviationTable> *abbreviation_table) const;
ReturnCode ProcessAbbreviation(DWARFBufferReader *reader,
Abbreviation *out,
bool *end_of_table) const;
ReturnCode PatchInfoSection(
MachOFile *f,
const std::map<size_t, size_t> &string_relocation_table,
const std::map<size_t, AbbreviationTable> &abbreviation_table_map) const;
ReturnCode PatchLineInfoSection(MachOFile *f);
ReturnCode ProcessLineInfoData(uint8_t *data,
size_t data_length,
bool swap_byte_ordering,
std::list<LineInfoPatch> *patch_actions,
size_t *patched_section_size_increase);
ReturnCode ApplyLineInfoPatchesInPlace(
MachOFile *f,
std::unique_ptr<uint8_t[]> data,
size_t data_length,
const std::list<LineInfoPatch> &patch_actions) const;
ReturnCode ApplyLineInfoPatches(
MachOFile *f,
std::unique_ptr<uint8_t[]> existing_data,
size_t data_length,
size_t new_data_length,
const std::list<LineInfoPatch> &patch_actions) const;
};
} // namespace post_processor
#endif // POST_PROCESSOR_DWARFSTRINGPATCHER_H_