Skip to content

Commit

Permalink
Update obj2yaml and yaml2obj for .debug$H section.
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D40842

llvm-svn: 319925
  • Loading branch information
Zachary Turner committed Dec 6, 2017
1 parent c8dfde2 commit c221dc7
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 64 deletions.
1 change: 1 addition & 0 deletions llvm/include/llvm/BinaryFormat/COFF.h
Expand Up @@ -707,6 +707,7 @@ struct ImportHeader {

enum CodeViewIdentifiers {
DEBUG_SECTION_MAGIC = 0x4,
DEBUG_HASHES_SECTION_MAGIC = 0x133C9C5
};

inline bool isReservedSectionNumber(int32_t SectionNumber) {
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/ObjectYAML/COFFYAML.h
Expand Up @@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h"
#include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h"
#include "llvm/ObjectYAML/CodeViewYAMLTypes.h"
#include "llvm/ObjectYAML/YAML.h"
#include <cstdint>
Expand Down Expand Up @@ -66,6 +67,7 @@ struct Section {
yaml::BinaryRef SectionData;
std::vector<CodeViewYAML::YAMLDebugSubsection> DebugS;
std::vector<CodeViewYAML::LeafRecord> DebugT;
Optional<CodeViewYAML::DebugHSection> DebugH;
std::vector<Relocation> Relocations;
StringRef Name;

Expand Down
62 changes: 62 additions & 0 deletions llvm/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h
@@ -0,0 +1,62 @@
//==- CodeViewYAMLTypeHashing.h - CodeView YAMLIO Type hashing ----*- C++-*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines classes for handling the YAML representation of CodeView
// Debug Info.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_OBJECTYAML_CODEVIEWYAMLTYPEHASHING_H
#define LLVM_OBJECTYAML_CODEVIEWYAMLTYPEHASHING_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/TypeHashing.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/YAMLTraits.h"
#include <cstdint>
#include <memory>
#include <vector>

namespace llvm {

namespace CodeViewYAML {

struct GlobalHash {
GlobalHash() = default;
explicit GlobalHash(StringRef S) : Hash(S) {
assert(S.size() == 20 && "Invalid hash size!");
}
explicit GlobalHash(ArrayRef<uint8_t> S) : Hash(S) {
assert(S.size() == 20 && "Invalid hash size!");
}
yaml::BinaryRef Hash;
};

struct DebugHSection {
uint32_t Magic;
uint16_t Version;
uint16_t HashAlgorithm;
std::vector<GlobalHash> Hashes;
};

DebugHSection fromDebugH(ArrayRef<uint8_t> DebugT);
ArrayRef<uint8_t> toDebugH(const DebugHSection &DebugH,
BumpPtrAllocator &Alloc);

} // end namespace CodeViewYAML

} // end namespace llvm

LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::DebugHSection)
LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::GlobalHash, false)
LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::GlobalHash)

#endif // LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H
5 changes: 3 additions & 2 deletions llvm/lib/ObjectYAML/CMakeLists.txt
@@ -1,7 +1,8 @@
add_llvm_library(LLVMObjectYAML
CodeViewYAMLTypes.cpp
CodeViewYAMLSymbols.cpp
CodeViewYAMLDebugSections.cpp
CodeViewYAMLSymbols.cpp
CodeViewYAMLTypeHashing.cpp
CodeViewYAMLTypes.cpp
COFFYAML.cpp
DWARFEmitter.cpp
DWARFVisitor.cpp
Expand Down
8 changes: 5 additions & 3 deletions llvm/lib/ObjectYAML/COFFYAML.cpp
Expand Up @@ -562,14 +562,16 @@ void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U);
IO.mapOptional("Alignment", Sec.Alignment, 0U);

// If this is a .debug$S or .debug$T section parse the semantic representation
// of the symbols/types. If it is any other kind of section, just deal in raw
// bytes.
// If this is a .debug$S .debug$T, or .debug$H section parse the semantic
// representation of the symbols/types. If it is any other kind of section,
// just deal in raw bytes.
IO.mapOptional("SectionData", Sec.SectionData);
if (Sec.Name == ".debug$S")
IO.mapOptional("Subsections", Sec.DebugS);
else if (Sec.Name == ".debug$T")
IO.mapOptional("Types", Sec.DebugT);
else if (Sec.Name == ".debug$H")
IO.mapOptional("GlobalHashes", Sec.DebugH);

IO.mapOptional("Relocations", Sec.Relocations);
}
Expand Down
84 changes: 84 additions & 0 deletions llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp
@@ -0,0 +1,84 @@
//===- CodeViewYAMLTypeHashing.cpp - CodeView YAMLIO type hashing ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines classes for handling the YAML representation of CodeView
// Debug Info.
//
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamWriter.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::CodeViewYAML;
using namespace llvm::yaml;

namespace llvm {
namespace yaml {

void MappingTraits<DebugHSection>::mapping(IO &io, DebugHSection &DebugH) {
io.mapRequired("Version", DebugH.Version);
io.mapRequired("HashAlgorithm", DebugH.HashAlgorithm);
io.mapOptional("HashValues", DebugH.Hashes);
}

void ScalarTraits<GlobalHash>::output(const GlobalHash &GH, void *Ctx,
raw_ostream &OS) {
ScalarTraits<BinaryRef>::output(GH.Hash, Ctx, OS);
}

StringRef ScalarTraits<GlobalHash>::input(StringRef Scalar, void *Ctx,
GlobalHash &GH) {
return ScalarTraits<BinaryRef>::input(Scalar, Ctx, GH.Hash);
}

} // end namespace yaml
} // end namespace llvm

DebugHSection llvm::CodeViewYAML::fromDebugH(ArrayRef<uint8_t> DebugT) {
assert(DebugT.size() >= 8);
assert((DebugT.size() - 8) % 20 == 0);

BinaryStreamReader Reader(DebugT, llvm::support::little);
DebugHSection DHS;
cantFail(Reader.readInteger(DHS.Magic));
cantFail(Reader.readInteger(DHS.Version));
cantFail(Reader.readInteger(DHS.HashAlgorithm));
while (Reader.bytesRemaining() != 0) {
ArrayRef<uint8_t> S;
cantFail(Reader.readBytes(S, 20));
DHS.Hashes.emplace_back(S);
}
assert(Reader.bytesRemaining() == 0);
return DHS;
}

ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugH(const DebugHSection &DebugH,
BumpPtrAllocator &Alloc) {
uint32_t Size = 8 + 20 * DebugH.Hashes.size();
uint8_t *Data = Alloc.Allocate<uint8_t>(Size);
MutableArrayRef<uint8_t> Buffer(Data, Size);
BinaryStreamWriter Writer(Buffer, llvm::support::little);
cantFail(Writer.writeInteger(DebugH.Magic));
cantFail(Writer.writeInteger(DebugH.Version));
cantFail(Writer.writeInteger(DebugH.HashAlgorithm));
SmallString<20> Hash;
for (const auto &H : DebugH.Hashes) {
Hash.clear();
raw_svector_ostream OS(Hash);
H.Hash.writeAsBinary(OS);
assert((Hash.size() == 20) && "Invalid hash size!");
cantFail(Writer.writeFixedString(Hash));
}
assert(Writer.bytesRemaining() == 0);
return Buffer;
}
59 changes: 0 additions & 59 deletions llvm/test/ObjectYAML/CodeView/guid.yaml

This file was deleted.

112 changes: 112 additions & 0 deletions llvm/test/ObjectYAML/CodeView/sections.yaml
@@ -0,0 +1,112 @@
# RUN: yaml2obj %s > %t.obj
# RUN: obj2yaml %t.obj | FileCheck --check-prefix=CHECK %s
# RUN: llvm-objdump -section-headers %t.obj | FileCheck --check-prefix=HEADERS %s

--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: [ ]
sections:
- Name: '.debug$T'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 1
Types:
- Kind: LF_TYPESERVER2
TypeServer2:
Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
Age: 24
Name: 'C:\src\llvm-project\build\vc140.pdb'
- Name: '.debug$H'
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
Alignment: 4
GlobalHashes:
Version: 0
HashAlgorithm: 0
HashValues:
- 1522A98D88FAF71B618D97BCAC2B89A424EC4805
- 8B2BA87CC27BF9D290A31A6070FA296AAA577E53
- EC11CE9F78D6BF61F8D913A9E2C98293782A7EB4
- 1088AD64CEBC88D9E015058A159516AF20B79286
- 457ABCB8AB70407594B5D72BF471B6BDECC99BC9
symbols:
- Name: '.debug$T'
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 64
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 0
Number: 0
- Name: '.debug$H'
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 108
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 2189213922
Number: 1
...

# CHECK: --- !COFF
# CHECK: header:
# CHECK: Machine: IMAGE_FILE_MACHINE_AMD64
# CHECK: Characteristics: [ ]
# CHECK: sections:
# CHECK: - Name: '.debug$T'
# CHECK: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
# CHECK: Alignment: 1
# CHECK: Types:
# CHECK: - Kind: LF_TYPESERVER2
# CHECK: TypeServer2:
# CHECK: Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
# CHECK: Age: 24
# CHECK: Name: 'C:\src\llvm-project\build\vc140.pdb'
# CHECK: - Name: '.debug$H'
# CHECK: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
# CHECK: Alignment: 4
# CHECK: GlobalHashes:
# CHECK: Version: 0
# CHECK: HashAlgorithm: 0
# CHECK: HashValues:
# CHECK: - 1522A98D88FAF71B618D97BCAC2B89A424EC4805
# CHECK: - 8B2BA87CC27BF9D290A31A6070FA296AAA577E53
# CHECK: - EC11CE9F78D6BF61F8D913A9E2C98293782A7EB4
# CHECK: - 1088AD64CEBC88D9E015058A159516AF20B79286
# CHECK: - 457ABCB8AB70407594B5D72BF471B6BDECC99BC9
# CHECK: symbols:
# CHECK: - Name: '.debug$T'
# CHECK: Value: 0
# CHECK: SectionNumber: 1
# CHECK: SimpleType: IMAGE_SYM_TYPE_NULL
# CHECK: ComplexType: IMAGE_SYM_DTYPE_NULL
# CHECK: StorageClass: IMAGE_SYM_CLASS_STATIC
# CHECK: SectionDefinition:
# CHECK: Length: 64
# CHECK: NumberOfRelocations: 0
# CHECK: NumberOfLinenumbers: 0
# CHECK: CheckSum: 0
# CHECK: Number: 0
# CHECK: - Name: '.debug$H'
# CHECK: Value: 0
# CHECK: SectionNumber: 2
# CHECK: SimpleType: IMAGE_SYM_TYPE_NULL
# CHECK: ComplexType: IMAGE_SYM_DTYPE_NULL
# CHECK: StorageClass: IMAGE_SYM_CLASS_STATIC
# CHECK: SectionDefinition:
# CHECK: Length: 108
# CHECK: NumberOfRelocations: 0
# CHECK: NumberOfLinenumbers: 0
# CHECK: CheckSum: 2189213922
# CHECK: Number: 1
# CHECK: ...

# HEADERS: 0 .debug$T 00000040 0000000000000000 DATA
# HEADERS: 1 .debug$H 0000006c 0000000000000000 DATA
2 changes: 2 additions & 0 deletions llvm/tools/obj2yaml/coff2yaml.cpp
Expand Up @@ -172,6 +172,8 @@ void COFFDumper::dumpSections(unsigned NumSections) {
NewYAMLSection.DebugS = CodeViewYAML::fromDebugS(sectionData, SC);
else if (NewYAMLSection.Name == ".debug$T")
NewYAMLSection.DebugT = CodeViewYAML::fromDebugT(sectionData);
else if (NewYAMLSection.Name == ".debug$H")
NewYAMLSection.DebugH = CodeViewYAML::fromDebugH(sectionData);

std::vector<COFFYAML::Relocation> Relocations;
for (const auto &Reloc : ObjSection.relocations()) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/tools/yaml2obj/yaml2coff.cpp
Expand Up @@ -234,6 +234,9 @@ static bool layoutCOFF(COFFParser &CP) {
} else if (S.Name == ".debug$T") {
if (S.SectionData.binary_size() == 0)
S.SectionData = CodeViewYAML::toDebugT(S.DebugT, CP.Allocator);
} else if (S.Name == ".debug$H") {
if (S.DebugH.hasValue() && S.SectionData.binary_size() == 0)
S.SectionData = CodeViewYAML::toDebugH(*S.DebugH, CP.Allocator);
}

if (S.SectionData.binary_size() > 0) {
Expand Down

0 comments on commit c221dc7

Please sign in to comment.