From 363fd7a30f25fa50277620276f10c021379d8acf Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 11 Aug 2017 20:46:28 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310754 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-pdbutil/DumpOutputStyle.cpp | 68 ----------------- tools/llvm-pdbutil/FormatUtil.cpp | 85 ++++++++++++++++++++++ tools/llvm-pdbutil/FormatUtil.h | 9 +++ tools/llvm-pdbutil/MinimalSymbolDumper.cpp | 19 +++-- 4 files changed, 108 insertions(+), 73 deletions(-) diff --git a/tools/llvm-pdbutil/DumpOutputStyle.cpp b/tools/llvm-pdbutil/DumpOutputStyle.cpp index bc0bb0830d9..1e3e8e419a8 100644 --- a/tools/llvm-pdbutil/DumpOutputStyle.cpp +++ b/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 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 Opts; diff --git a/tools/llvm-pdbutil/FormatUtil.cpp b/tools/llvm-pdbutil/FormatUtil.cpp index 02030272dd4..039b1b900f3 100644 --- a/tools/llvm-pdbutil/FormatUtil.cpp +++ b/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 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/tools/llvm-pdbutil/FormatUtil.h b/tools/llvm-pdbutil/FormatUtil.h index df32ed9360f..34fe4ee455c 100644 --- a/tools/llvm-pdbutil/FormatUtil.h +++ b/tools/llvm-pdbutil/FormatUtil.h @@ -49,6 +49,15 @@ template 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 Opts, uint32_t IndentLevel, uint32_t GroupSize, StringRef Sep); diff --git a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/tools/llvm-pdbutil/MinimalSymbolDumper.cpp index cc592b724df..678376b5957 100644 --- a/tools/llvm-pdbutil/MinimalSymbolDumper.cpp +++ b/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(); } -- 2.50.1