mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 14:47:00 +00:00
29400a2fb2
When type streams with forward references were merged using GHashes, cycles were introduced in the debug info. This was caused by GlobalTypeTableBuilder::insertRecordAs() not inserting the record on the second pass, thus yielding an empty ArrayRef at that record slot. Later on, upon PDB emission, TpiStreamBuilder::commit() would skip that empty record, thus offseting all indices that came after in the stream. This solution comes in two steps: 1. Fix the hash calculation, by doing a multiple-step resolution, iff there are forward references in the input stream. 2. Fix merge by resolving with multiple passes, therefore moving records with forward references at the end of the stream. This patch also adds support for llvm-readoj --codeview-ghash. Finally, fix dumpCodeViewMergedTypes() which previously could reference deleted memory. Fixes PR40221 Differential Revision: https://reviews.llvm.org/D57790 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353412 91177308-0d34-0410-b5e6-96231b3b80d8
146 lines
4.8 KiB
C++
146 lines
4.8 KiB
C++
//===-- ObjDumper.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H
|
|
#define LLVM_TOOLS_LLVM_READOBJ_OBJDUMPER_H
|
|
|
|
#include <memory>
|
|
#include <system_error>
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Object/ObjectFile.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
namespace llvm {
|
|
namespace object {
|
|
class COFFImportFile;
|
|
class ObjectFile;
|
|
}
|
|
namespace codeview {
|
|
class GlobalTypeTableBuilder;
|
|
class MergingTypeTableBuilder;
|
|
} // namespace codeview
|
|
|
|
class ScopedPrinter;
|
|
|
|
class ObjDumper {
|
|
public:
|
|
ObjDumper(ScopedPrinter &Writer);
|
|
virtual ~ObjDumper();
|
|
|
|
virtual void printFileHeaders() = 0;
|
|
virtual void printSectionHeaders() = 0;
|
|
virtual void printRelocations() = 0;
|
|
virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) {
|
|
if (PrintSymbols)
|
|
printSymbols();
|
|
if (PrintDynamicSymbols)
|
|
printDynamicSymbols();
|
|
}
|
|
virtual void printProgramHeaders(bool PrintProgramHeaders,
|
|
cl::boolOrDefault PrintSectionMapping) {
|
|
if (PrintProgramHeaders)
|
|
printProgramHeaders();
|
|
if (PrintSectionMapping == cl::BOU_TRUE)
|
|
printSectionMapping();
|
|
}
|
|
|
|
virtual void printUnwindInfo() = 0;
|
|
|
|
// Only implemented for ELF at this time.
|
|
virtual void printDynamicRelocations() { }
|
|
virtual void printDynamicTable() { }
|
|
virtual void printNeededLibraries() { }
|
|
virtual void printSectionAsHex(StringRef SectionName) {}
|
|
virtual void printHashTable() { }
|
|
virtual void printGnuHashTable() { }
|
|
virtual void printHashSymbols() {}
|
|
virtual void printLoadName() {}
|
|
virtual void printVersionInfo() {}
|
|
virtual void printGroupSections() {}
|
|
virtual void printHashHistogram() {}
|
|
virtual void printCGProfile() {}
|
|
virtual void printAddrsig() {}
|
|
virtual void printNotes() {}
|
|
virtual void printELFLinkerOptions() {}
|
|
|
|
// Only implemented for ARM ELF at this time.
|
|
virtual void printAttributes() { }
|
|
|
|
// Only implemented for MIPS ELF at this time.
|
|
virtual void printMipsPLTGOT() { }
|
|
virtual void printMipsABIFlags() { }
|
|
virtual void printMipsReginfo() { }
|
|
virtual void printMipsOptions() { }
|
|
|
|
// Only implemented for PE/COFF.
|
|
virtual void printCOFFImports() { }
|
|
virtual void printCOFFExports() { }
|
|
virtual void printCOFFDirectives() { }
|
|
virtual void printCOFFBaseReloc() { }
|
|
virtual void printCOFFDebugDirectory() { }
|
|
virtual void printCOFFResources() {}
|
|
virtual void printCOFFLoadConfig() { }
|
|
virtual void printCodeViewDebugInfo() { }
|
|
virtual void
|
|
mergeCodeViewTypes(llvm::codeview::MergingTypeTableBuilder &CVIDs,
|
|
llvm::codeview::MergingTypeTableBuilder &CVTypes,
|
|
llvm::codeview::GlobalTypeTableBuilder &GlobalCVIDs,
|
|
llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes,
|
|
bool GHash) {}
|
|
|
|
// Only implemented for MachO.
|
|
virtual void printMachODataInCode() { }
|
|
virtual void printMachOVersionMin() { }
|
|
virtual void printMachODysymtab() { }
|
|
virtual void printMachOSegment() { }
|
|
virtual void printMachOIndirectSymbols() { }
|
|
virtual void printMachOLinkerOptions() { }
|
|
|
|
virtual void printStackMap() const = 0;
|
|
|
|
void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName);
|
|
void printSectionAsHex(const object::ObjectFile *Obj, StringRef SecName);
|
|
|
|
protected:
|
|
ScopedPrinter &W;
|
|
|
|
private:
|
|
virtual void printSymbols() {}
|
|
virtual void printDynamicSymbols() {}
|
|
virtual void printProgramHeaders() {}
|
|
virtual void printSectionMapping() {}
|
|
};
|
|
|
|
std::error_code createCOFFDumper(const object::ObjectFile *Obj,
|
|
ScopedPrinter &Writer,
|
|
std::unique_ptr<ObjDumper> &Result);
|
|
|
|
std::error_code createELFDumper(const object::ObjectFile *Obj,
|
|
ScopedPrinter &Writer,
|
|
std::unique_ptr<ObjDumper> &Result);
|
|
|
|
std::error_code createMachODumper(const object::ObjectFile *Obj,
|
|
ScopedPrinter &Writer,
|
|
std::unique_ptr<ObjDumper> &Result);
|
|
|
|
std::error_code createWasmDumper(const object::ObjectFile *Obj,
|
|
ScopedPrinter &Writer,
|
|
std::unique_ptr<ObjDumper> &Result);
|
|
|
|
void dumpCOFFImportFile(const object::COFFImportFile *File,
|
|
ScopedPrinter &Writer);
|
|
|
|
void dumpCodeViewMergedTypes(ScopedPrinter &Writer,
|
|
ArrayRef<ArrayRef<uint8_t>> IpiRecords,
|
|
ArrayRef<ArrayRef<uint8_t>> TpiRecords);
|
|
|
|
} // namespace llvm
|
|
|
|
#endif
|