blob: 8c3cce9286a3397f1d4d4ec962c22bd6714819c8 [file] [log] [blame]
//===-- LVBinaryReader.h ----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the LVBinaryReader class, which is used to describe a
// binary reader.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H
#define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H
#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/ObjectFile.h"
namespace llvm {
namespace logicalview {
constexpr bool UpdateHighAddress = false;
// Logical scope, Section address, Section index, IsComdat.
struct LVSymbolTableEntry final {
LVScope *Scope = nullptr;
LVAddress Address = 0;
LVSectionIndex SectionIndex = 0;
bool IsComdat = false;
LVSymbolTableEntry() = default;
LVSymbolTableEntry(LVScope *Scope, LVAddress Address,
LVSectionIndex SectionIndex, bool IsComdat)
: Scope(Scope), Address(Address), SectionIndex(SectionIndex),
IsComdat(IsComdat) {}
};
// Function names extracted from the object symbol table.
class LVSymbolTable final {
using LVSymbolNames = std::map<std::string, LVSymbolTableEntry>;
LVSymbolNames SymbolNames;
public:
LVSymbolTable() = default;
void add(StringRef Name, LVScope *Function, LVSectionIndex SectionIndex = 0);
void add(StringRef Name, LVAddress Address, LVSectionIndex SectionIndex,
bool IsComdat);
LVSectionIndex update(LVScope *Function);
const LVSymbolTableEntry &getEntry(StringRef Name);
LVAddress getAddress(StringRef Name);
LVSectionIndex getIndex(StringRef Name);
bool getIsComdat(StringRef Name);
void print(raw_ostream &OS);
};
class LVBinaryReader : public LVReader {
// Function names extracted from the object symbol table.
LVSymbolTable SymbolTable;
// Instruction lines for a logical scope. These instructions are fetched
// during its merge with the debug lines.
LVDoubleMap<LVSectionIndex, LVScope *, LVLines *> ScopeInstructions;
// Links the scope with its first assembler address line.
LVDoubleMap<LVSectionIndex, LVAddress, LVScope *> AssemblerMappings;
// Mapping from virtual address to section.
// The virtual address refers to the address where the section is loaded.
using LVSectionAddresses = std::map<LVSectionIndex, object::SectionRef>;
LVSectionAddresses SectionAddresses;
void addSectionAddress(const object::SectionRef &Section) {
if (SectionAddresses.find(Section.getAddress()) == SectionAddresses.end())
SectionAddresses.emplace(Section.getAddress(), Section);
}
// Scopes with ranges for current compile unit. It is used to find a line
// giving its exact or closest address. To support comdat functions, all
// addresses for the same section are recorded in the same map.
using LVSectionRanges = std::map<LVSectionIndex, LVRange *>;
LVSectionRanges SectionRanges;
// Image base and virtual address for Executable file.
uint64_t ImageBaseAddress = 0;
uint64_t VirtualAddress = 0;
// Object sections with machine code.
using LVSections = std::map<LVSectionIndex, object::SectionRef>;
LVSections Sections;
protected:
// It contains the LVLineDebug elements representing the logical lines for
// the current compile unit, created by parsing the debug line section.
LVLines CULines;
std::unique_ptr<const MCRegisterInfo> MRI;
std::unique_ptr<const MCAsmInfo> MAI;
std::unique_ptr<const MCSubtargetInfo> STI;
std::unique_ptr<const MCInstrInfo> MII;
std::unique_ptr<const MCDisassembler> MD;
std::unique_ptr<MCContext> MC;
std::unique_ptr<MCInstPrinter> MIP;
// Loads all info for the architecture of the provided object file.
Error loadGenericTargetInfo(StringRef TheTriple, StringRef TheFeatures);
virtual void mapRangeAddress(const object::ObjectFile &Obj) {}
virtual void mapRangeAddress(const object::ObjectFile &Obj,
const object::SectionRef &Section,
bool IsComdat) {}
// Create a mapping from virtual address to section.
void mapVirtualAddress(const object::ObjectFile &Obj);
void mapVirtualAddress(const object::COFFObjectFile &COFFObj);
Expected<std::pair<LVSectionIndex, object::SectionRef>>
getSection(LVScope *Scope, LVAddress Address, LVSectionIndex SectionIndex);
void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope);
void addSectionRange(LVSectionIndex SectionIndex, LVScope *Scope,
LVAddress LowerAddress, LVAddress UpperAddress);
LVRange *getSectionRanges(LVSectionIndex SectionIndex);
Error createInstructions();
Error createInstructions(LVScope *Function, LVSectionIndex SectionIndex);
Error createInstructions(LVScope *Function, LVSectionIndex SectionIndex,
const LVNameInfo &NameInfo);
void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex);
void processLines(LVLines *DebugLines, LVSectionIndex SectionIndex,
LVScope *Function);
public:
LVBinaryReader() = delete;
LVBinaryReader(StringRef Filename, StringRef FileFormatName, ScopedPrinter &W,
LVBinaryType BinaryType)
: LVReader(Filename, FileFormatName, W, BinaryType) {}
LVBinaryReader(const LVBinaryReader &) = delete;
LVBinaryReader &operator=(const LVBinaryReader &) = delete;
virtual ~LVBinaryReader();
void addToSymbolTable(StringRef Name, LVScope *Function,
LVSectionIndex SectionIndex = 0);
void addToSymbolTable(StringRef Name, LVAddress Address,
LVSectionIndex SectionIndex, bool IsComdat);
LVSectionIndex updateSymbolTable(LVScope *Function);
const LVSymbolTableEntry &getSymbolTableEntry(StringRef Name);
LVAddress getSymbolTableAddress(StringRef Name);
LVSectionIndex getSymbolTableIndex(StringRef Name);
bool getSymbolTableIsComdat(StringRef Name);
LVSectionIndex getSectionIndex(LVScope *Scope) override {
return Scope ? getSymbolTableIndex(Scope->getLinkageName())
: DotTextSectionIndex;
}
void print(raw_ostream &OS) const;
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void dump() const { print(dbgs()); }
#endif
};
} // end namespace logicalview
} // end namespace llvm
#endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVBINARYREADER_H