summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-08-11 20:46:28 +0000
committerZachary Turner <zturner@google.com>2017-08-11 20:46:28 +0000
commit28e31ee45e63d7c195e7980c811a15f0b26118cb (patch)
tree4a76001bb0f8b1d3d87d1c95fbcddf12087d4a09
parent71bcbd451ff7460f12c77b97ecdc29c7dbd19bf0 (diff)
downloadbcm5719-llvm-28e31ee45e63d7c195e7980c811a15f0b26118cb.tar.gz
bcm5719-llvm-28e31ee45e63d7c195e7980c811a15f0b26118cb.zip
Output S_SECTION symbols to the Linker module.
PDBs need to contain 1 module for each object file/compiland, and a special one synthesized by the linker. This one contains a symbol record for each output section in the executable with its address information. This patch adds such symbols to the linker module. Note that we also are supposed to add an S_COFFGROUP symbol for what appears to be each input section that contributes to each output section, but it's not entirely clear how to generate these yet, so I'm leaving that for a separate patch. llvm-svn: 310754
-rw-r--r--lld/COFF/PDB.cpp41
-rw-r--r--llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp68
-rw-r--r--llvm/tools/llvm-pdbutil/FormatUtil.cpp85
-rw-r--r--llvm/tools/llvm-pdbutil/FormatUtil.h9
-rw-r--r--llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp19
5 files changed, 140 insertions, 82 deletions
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 6f9f21a7917..ca044ca3b9c 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -727,13 +727,13 @@ void PDBLinker::addObjectsToPDB() {
}
}
-static void addLinkerModuleSymbols(StringRef Path,
- pdb::DbiModuleDescriptorBuilder &Mod,
- BumpPtrAllocator &Allocator) {
- codeview::SymbolSerializer Serializer(Allocator, CodeViewContainer::Pdb);
- codeview::ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
- codeview::Compile3Sym CS(SymbolRecordKind::Compile3Sym);
- codeview::EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym);
+static void addCommonLinkerModuleSymbols(StringRef Path,
+ pdb::DbiModuleDescriptorBuilder &Mod,
+ BumpPtrAllocator &Allocator) {
+ SymbolSerializer Serializer(Allocator, CodeViewContainer::Pdb);
+ ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
+ Compile3Sym CS(SymbolRecordKind::Compile3Sym);
+ EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym);
ONS.Name = "* Linker *";
ONS.Signature = 0;
@@ -771,6 +771,27 @@ static void addLinkerModuleSymbols(StringRef Path,
EBS, Allocator, CodeViewContainer::Pdb));
}
+static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
+ OutputSection &OS,
+ BumpPtrAllocator &Allocator) {
+ SectionSym Sym(SymbolRecordKind::SectionSym);
+ Sym.Alignment = 0;
+ // We store log_2(Align), not the alignment itself.
+ auto Max = std::max_element(OS.getChunks().begin(), OS.getChunks().end(),
+ [](const Chunk *C, const Chunk *D) {
+ return C->getAlign() < D->getAlign();
+ });
+ if (Max != OS.getChunks().end())
+ Sym.Alignment = Log2_32((*Max)->getAlign());
+ Sym.Characteristics = OS.getCharacteristics();
+ Sym.Length = OS.getVirtualSize();
+ Sym.Name = OS.getName();
+ Sym.Rva = OS.getRVA();
+ Sym.SectionNumber = OS.SectionIndex;
+ Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
+ Sym, Allocator, CodeViewContainer::Pdb));
+}
+
// Creates a PDB file.
void coff::createPDB(SymbolTable *Symtab,
ArrayRef<OutputSection *> OutputSections,
@@ -843,12 +864,14 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
LinkerModule.setPdbFilePathNI(PdbFilePathNI);
- addLinkerModuleSymbols(NativePath, LinkerModule, Alloc);
+ addCommonLinkerModuleSymbols(NativePath, LinkerModule, Alloc);
// Add section contributions. They must be ordered by ascending RVA.
- for (OutputSection *OS : OutputSections)
+ for (OutputSection *OS : OutputSections) {
+ addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc);
for (Chunk *C : OS->getChunks())
addSectionContrib(LinkerModule, OS, C);
+ }
// Add Section Map stream.
ArrayRef<object::coff_section> Sections = {
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
index bc0bb0830d9..1e3e8e419a8 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -1003,74 +1003,6 @@ Error DumpOutputStyle::dumpSymbolsFromGSI(const GSIHashTable &Table,
return Error::success();
}
-static std::string formatSectionCharacteristics(uint32_t IndentLevel,
- uint32_t C,
- uint32_t FlagsPerLine,
- StringRef Separator) {
- using SC = COFF::SectionCharacteristics;
- std::vector<std::string> Opts;
- if (C == COFF::SC_Invalid)
- return "invalid";
- if (C == 0)
- return "none";
-
- PUSH_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, "IMAGE_SCN_TYPE_NOLOAD");
- PUSH_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, "IMAGE_SCN_TYPE_NO_PAD");
- PUSH_FLAG(SC, IMAGE_SCN_CNT_CODE, C, "IMAGE_SCN_CNT_CODE");
- PUSH_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C,
- "IMAGE_SCN_CNT_INITIALIZED_DATA");
- PUSH_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C,
- "IMAGE_SCN_CNT_UNINITIALIZED_DATA");
- PUSH_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, "IMAGE_SCN_LNK_OTHER");
- PUSH_FLAG(SC, IMAGE_SCN_LNK_INFO, C, "IMAGE_SCN_LNK_INFO");
- PUSH_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, "IMAGE_SCN_LNK_REMOVE");
- PUSH_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, "IMAGE_SCN_LNK_COMDAT");
- PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, "IMAGE_SCN_MEM_PURGEABLE");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, "IMAGE_SCN_MEM_16BIT");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, "IMAGE_SCN_MEM_LOCKED");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, "IMAGE_SCN_MEM_PRELOAD");
- PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
- PUSH_FLAG(SC, IMAGE_SCN_GPREL, C, "IMAGE_SCN_GPREL");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C,
- "IMAGE_SCN_ALIGN_1BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C,
- "IMAGE_SCN_ALIGN_2BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C,
- "IMAGE_SCN_ALIGN_4BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C,
- "IMAGE_SCN_ALIGN_8BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C,
- "IMAGE_SCN_ALIGN_16BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C,
- "IMAGE_SCN_ALIGN_32BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C,
- "IMAGE_SCN_ALIGN_64BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C,
- "IMAGE_SCN_ALIGN_128BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C,
- "IMAGE_SCN_ALIGN_256BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C,
- "IMAGE_SCN_ALIGN_512BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C,
- "IMAGE_SCN_ALIGN_1024BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C,
- "IMAGE_SCN_ALIGN_2048BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C,
- "IMAGE_SCN_ALIGN_4096BYTES");
- PUSH_MASKED_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C,
- "IMAGE_SCN_ALIGN_8192BYTES");
- PUSH_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, "IMAGE_SCN_LNK_NRELOC_OVFL");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, "IMAGE_SCN_MEM_DISCARDABLE");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, "IMAGE_SCN_MEM_NOT_CACHED");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, "IMAGE_SCN_MEM_NOT_PAGED");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, "IMAGE_SCN_MEM_SHARED");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, "IMAGE_SCN_MEM_EXECUTE");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_READ, C, "IMAGE_SCN_MEM_READ");
- PUSH_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, "IMAGE_SCN_MEM_WRITE");
- return typesetItemList(Opts, IndentLevel, FlagsPerLine, Separator);
-}
-
static std::string formatSegMapDescriptorFlag(uint32_t IndentLevel,
OMFSegDescFlags Flags) {
std::vector<std::string> Opts;
diff --git a/llvm/tools/llvm-pdbutil/FormatUtil.cpp b/llvm/tools/llvm-pdbutil/FormatUtil.cpp
index 02030272dd4..039b1b900f3 100644
--- a/llvm/tools/llvm-pdbutil/FormatUtil.cpp
+++ b/llvm/tools/llvm-pdbutil/FormatUtil.cpp
@@ -10,6 +10,7 @@
#include "FormatUtil.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/BinaryFormat/COFF.h"
#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
@@ -99,3 +100,87 @@ std::string llvm::pdb::typesetStringList(uint32_t IndentLevel,
std::string llvm::pdb::formatSegmentOffset(uint16_t Segment, uint32_t Offset) {
return formatv("{0:4}:{1:4}", Segment, Offset);
}
+
+#define PUSH_CHARACTERISTIC_FLAG(Enum, TheOpt, Value, Style, Descriptive) \
+ PUSH_FLAG(Enum, TheOpt, Value, \
+ ((Style == CharacteristicStyle::HeaderDefinition) ? #TheOpt \
+ : Descriptive))
+
+#define PUSH_MASKED_CHARACTERISTIC_FLAG(Enum, Mask, TheOpt, Value, Style, \
+ Descriptive) \
+ PUSH_MASKED_FLAG(Enum, Mask, TheOpt, Value, \
+ ((Style == CharacteristicStyle::HeaderDefinition) \
+ ? #TheOpt \
+ : Descriptive))
+
+std::string llvm::pdb::formatSectionCharacteristics(uint32_t IndentLevel,
+ uint32_t C,
+ uint32_t FlagsPerLine,
+ StringRef Separator,
+ CharacteristicStyle Style) {
+ using SC = COFF::SectionCharacteristics;
+ std::vector<std::string> Opts;
+ if (C == COFF::SC_Invalid)
+ return "invalid";
+ if (C == 0)
+ return "none";
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NOLOAD, C, Style, "noload");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_TYPE_NO_PAD, C, Style, "no padding");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_CODE, C, Style, "code");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_INITIALIZED_DATA, C, Style,
+ "initialized data");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_CNT_UNINITIALIZED_DATA, C, Style,
+ "uninitialized data");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_OTHER, C, Style, "other");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_INFO, C, Style, "info");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_REMOVE, C, Style, "remove");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_COMDAT, C, Style, "comdat");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_GPREL, C, Style, "gp rel");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PURGEABLE, C, Style, "purgeable");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_16BIT, C, Style, "16-bit");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_LOCKED, C, Style, "locked");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_PRELOAD, C, Style, "preload");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1BYTES, C,
+ Style, "1 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2BYTES, C,
+ Style, "2 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4BYTES, C,
+ Style, "4 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8BYTES, C,
+ Style, "8 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_16BYTES, C,
+ Style, "16 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_32BYTES, C,
+ Style, "32 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_64BYTES, C,
+ Style, "64 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_128BYTES, C,
+ Style, "128 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_256BYTES, C,
+ Style, "256 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_512BYTES, C,
+ Style, "512 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_1024BYTES, C,
+ Style, "1024 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_2048BYTES, C,
+ Style, "2048 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_4096BYTES, C,
+ Style, "4096 byte align");
+ PUSH_MASKED_CHARACTERISTIC_FLAG(SC, 0xF00000, IMAGE_SCN_ALIGN_8192BYTES, C,
+ Style, "8192 byte align");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_LNK_NRELOC_OVFL, C, Style,
+ "noreloc overflow");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_DISCARDABLE, C, Style,
+ "discardable");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_CACHED, C, Style,
+ "not cached");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_NOT_PAGED, C, Style, "not paged");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_SHARED, C, Style, "shared");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_EXECUTE, C, Style,
+ "execute permissions");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_READ, C, Style,
+ "read permissions");
+ PUSH_CHARACTERISTIC_FLAG(SC, IMAGE_SCN_MEM_WRITE, C, Style,
+ "write permissions");
+ return typesetItemList(Opts, IndentLevel, FlagsPerLine, Separator);
+}
diff --git a/llvm/tools/llvm-pdbutil/FormatUtil.h b/llvm/tools/llvm-pdbutil/FormatUtil.h
index df32ed9360f..34fe4ee455c 100644
--- a/llvm/tools/llvm-pdbutil/FormatUtil.h
+++ b/llvm/tools/llvm-pdbutil/FormatUtil.h
@@ -49,6 +49,15 @@ template <typename T> std::string formatUnknownEnum(T Value) {
std::string formatSegmentOffset(uint16_t Segment, uint32_t Offset);
+enum class CharacteristicStyle {
+ HeaderDefinition, // format as windows header definition
+ Descriptive, // format as human readable words
+};
+std::string formatSectionCharacteristics(
+ uint32_t IndentLevel, uint32_t C, uint32_t FlagsPerLine,
+ StringRef Separator,
+ CharacteristicStyle Style = CharacteristicStyle::HeaderDefinition);
+
std::string typesetItemList(ArrayRef<std::string> Opts, uint32_t IndentLevel,
uint32_t GroupSize, StringRef Sep);
diff --git a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index cc592b724df..678376b5957 100644
--- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
@@ -446,18 +446,27 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
SectionSym &Section) {
P.format(" `{0}`", Section.Name);
AutoIndent Indent(P, 7);
- P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}, "
- "characteristics = {4}",
+ P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}",
Section.Length, Section.Alignment, Section.Rva,
- Section.SectionNumber, Section.Characteristics);
+ Section.SectionNumber);
+ P.printLine("characteristics =");
+ AutoIndent Indent2(P, 2);
+ P.printLine(formatSectionCharacteristics(P.getIndentLevel(),
+ Section.Characteristics, 1, "",
+ CharacteristicStyle::Descriptive));
return Error::success();
}
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CoffGroupSym &CG) {
P.format(" `{0}`", CG.Name);
AutoIndent Indent(P, 7);
- P.formatLine("length = {0}, addr = {1}, characteristics = {2}", CG.Size,
- formatSegmentOffset(CG.Segment, CG.Offset), CG.Characteristics);
+ P.formatLine("length = {0}, addr = {1}", CG.Size,
+ formatSegmentOffset(CG.Segment, CG.Offset));
+ P.printLine("characteristics =");
+ AutoIndent Indent2(P, 2);
+ P.printLine(formatSectionCharacteristics(P.getIndentLevel(),
+ CG.Characteristics, 1, "",
+ CharacteristicStyle::Descriptive));
return Error::success();
}
OpenPOWER on IntegriCloud