namespace coff {
SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
- : Chunk(SectionKind), Repl(this), File(F), Header(H),
+ : Chunk(SectionKind), Repl(this), Header(H), File(F),
Relocs(File->getCOFFObj()->getRelocations(Header)),
NumRelocs(std::distance(Relocs.begin(), Relocs.end())) {
// Initialize SectionName.
// Auxiliary Format 5: Section Definitions. Used for ICF.
uint32_t Checksum = 0;
+ const coff_section *Header;
+
private:
// A file this chunk was created from.
ObjectFile *File;
- const coff_section *Header;
StringRef SectionName;
std::vector<SectionChunk *> AssocChildren;
llvm::iterator_range<const coff_relocation *> Relocs;
//===----------------------------------------------------------------------===//
#include "PDB.h"
+#include "Chunks.h"
#include "Error.h"
+#include "SymbolTable.h"
+#include "Symbols.h"
#include "llvm/DebugInfo/MSF/MSFBuilder.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include <memory>
using namespace lld;
+using namespace lld::coff;
using namespace llvm;
using namespace llvm::support;
using namespace llvm::support::endian;
+using llvm::object::coff_section;
+
static ExitOnError ExitOnErr;
-void coff::createPDB(StringRef Path, ArrayRef<uint8_t> SectionTable) {
+// Returns a list of all SectionChunks.
+static std::vector<coff_section> getInputSections(SymbolTable *Symtab) {
+ std::vector<coff_section> V;
+ for (Chunk *C : Symtab->getChunks())
+ if (auto *SC = dyn_cast<SectionChunk>(C))
+ V.push_back(*SC->Header);
+ return V;
+}
+
+// Creates a PDB file.
+void coff::createPDB(StringRef Path, SymbolTable *Symtab,
+ ArrayRef<uint8_t> SectionTable) {
BumpPtrAllocator Alloc;
pdb::PDBFileBuilder Builder(Alloc);
ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
auto &IpiBuilder = Builder.getIpiBuilder();
IpiBuilder.setVersionHeader(pdb::PdbTpiV80);
+ // Add Section Contributions.
+ ArrayRef<coff_section> InputSections = getInputSections(Symtab);
+ std::vector<pdb::SectionContrib> Contribs =
+ pdb::DbiStreamBuilder::createSectionContribs(InputSections);
+ DbiBuilder.setSectionContribs(Contribs);
+
// Add Section Map stream.
ArrayRef<object::coff_section> Sections = {
(const object::coff_section *)SectionTable.data(),
namespace lld {
namespace coff {
-void createPDB(llvm::StringRef Path, llvm::ArrayRef<uint8_t> SectionTable);
+class SymbolTable;
+
+void createPDB(llvm::StringRef Path, SymbolTable *Symtab,
+ llvm::ArrayRef<uint8_t> SectionTable);
}
}
writeBuildId();
if (!Config->PDBPath.empty())
- createPDB(Config->PDBPath, SectionTable);
+ createPDB(Config->PDBPath, Symtab, SectionTable);
if (auto EC = Buffer->commit())
fatal(EC, "failed to write the output file");
# RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream \
# RUN: -dbi-stream -ipi-stream %t.pdb | FileCheck %s
-# RUN: llvm-pdbdump raw -section-map -section-headers %t.pdb | \
-# RUN: FileCheck -check-prefix RAW %s
+# RUN: llvm-pdbdump raw -section-map -section-headers -section-contribs %t.pdb \
+# RUN: | FileCheck -check-prefix RAW %s
# CHECK: MSF:
# CHECK-NEXT: SuperBlock:
# CHECK-NEXT: DirectoryBlocks: [ 9 ]
# CHECK-NEXT: NumStreams: 6
# CHECK-NEXT: FileSize: 40960
-# CHECK-NEXT: StreamSizes: [ 0, 48, 56, 154, 56, 80 ]
+# CHECK-NEXT: StreamSizes: [ 0, 48, 56, 242, 56, 80 ]
# CHECK-NEXT: StreamMap:
# CHECK-NEXT: - Stream: [ ]
# CHECK-NEXT: - Stream: [ 5 ]
# CHECK-NEXT: Version: VC80
# CHECK-NEXT: Records:
-# RAW: Section Map [
-# RAW-NEXT: Entry {
-# RAW-NEXT: Flags [ (0x10D)
-# RAW-NEXT: AddressIs32Bit (0x8)
+# RAW: Section Contributions [
+# RAW-NEXT: Contribution {
+# RAW-NEXT: ISect: 0
+# RAW-NEXT: Off: 140
+# RAW-NEXT: Size: 3
+# RAW-NEXT: Characteristics [ (0x60300020)
+# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
+# RAW-NEXT: IMAGE_SCN_CNT_CODE (0x20)
+# RAW-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
+# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
+# RAW-NEXT: ]
+# RAW-NEXT: Module {
+# RAW-NEXT: Index: 0
+# RAW-NEXT: }
+# RAW-NEXT: Data CRC: 0
+# RAW-NEXT: Reloc CRC: 0
+# RAW-NEXT: }
+# RAW-NEXT: Contribution {
+# RAW-NEXT: ISect: 0
+# RAW-NEXT: Off: 0
+# RAW-NEXT: Size: 0
+# RAW-NEXT: Characteristics [ (0xC0300040)
+# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
+# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
+# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
+# RAW-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
+# RAW-NEXT: ]
+# RAW-NEXT: Module {
+# RAW-NEXT: Index: 0
+# RAW-NEXT: }
+# RAW-NEXT: Data CRC: 0
+# RAW-NEXT: Reloc CRC: 0
+# RAW-NEXT: }
+# RAW-NEXT: Contribution {
+# RAW-NEXT: ISect: 0
+# RAW-NEXT: Off: 0
+# RAW-NEXT: Size: 0
+# RAW-NEXT: Characteristics [ (0xC0300080)
+# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
+# RAW-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80)
+# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
+# RAW-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
+# RAW-NEXT: ]
+# RAW-NEXT: Module {
+# RAW-NEXT: Index: 0
+# RAW-NEXT: }
+# RAW-NEXT: Data CRC: 0
+# RAW-NEXT: Reloc CRC: 0
+# RAW-NEXT: }
+# RAW-NEXT: ]
+# RAW-NEXT: Section Map [
+# RAW-NEXT: Entry {
+# RAW-NEXT: Flags [ (0x10D)
+# RAW-NEXT: AddressIs32Bit (0x8)
# RAW-NEXT: Execute (0x4)
# RAW-NEXT: IsSelector (0x100)
# RAW-NEXT: Read (0x1)