OSDN Git Service

525c44ce7abcb1663b5456495beb4bf49d5304b8
[android-x86/external-llvm.git] / tools / yaml2obj / yaml2dwarf.cpp
1 //===- yaml2dwarf - Convert YAML to DWARF binary data ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief The DWARF component of yaml2obj.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/ObjectYAML/DWARFYAML.h"
16 #include "llvm/Support/Error.h"
17 #include "llvm/Support/LEB128.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include "llvm/Support/SwapByteOrder.h"
20
21 using namespace llvm;
22
23 template <typename T>
24 void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
25   if (IsLittleEndian != sys::IsLittleEndianHost)
26     sys::swapByteOrder(Integer);
27   OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
28 }
29
30 void writeVariableSizedInteger(uint64_t Integer, size_t Size, raw_ostream &OS,
31                                bool IsLittleEndian) {
32   if (8 == Size)
33     writeInteger((uint64_t)Integer, OS, IsLittleEndian);
34   else if (4 == Size)
35     writeInteger((uint32_t)Integer, OS, IsLittleEndian);
36   else if (2 == Size)
37     writeInteger((uint16_t)Integer, OS, IsLittleEndian);
38   else if (1 == Size)
39     writeInteger((uint8_t)Integer, OS, IsLittleEndian);
40   else
41     assert(false && "Invalid integer write size.");
42 }
43
44 void ZeroFillBytes(raw_ostream &OS, size_t Size) {
45   std::vector<uint8_t> FillData;
46   FillData.insert(FillData.begin(), Size, 0);
47   OS.write(reinterpret_cast<char *>(FillData.data()), Size);
48 }
49
50 void yaml2debug_str(raw_ostream &OS, const DWARFYAML::Data &DI) {
51   for (auto Str : DI.DebugStrings) {
52     OS.write(Str.data(), Str.size());
53     OS.write('\0');
54   }
55 }
56
57 void yaml2debug_abbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
58   for (auto AbbrevDecl : DI.AbbrevDecls) {
59     encodeULEB128(AbbrevDecl.Code, OS);
60     encodeULEB128(AbbrevDecl.Tag, OS);
61     OS.write(AbbrevDecl.Children);
62     for (auto Attr : AbbrevDecl.Attributes) {
63       encodeULEB128(Attr.Attribute, OS);
64       encodeULEB128(Attr.Form, OS);
65     }
66     encodeULEB128(0, OS);
67     encodeULEB128(0, OS);
68   }
69 }
70
71 void yaml2debug_aranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
72   for (auto Range : DI.ARanges) {
73     auto HeaderStart = OS.tell();
74     writeInteger((uint32_t)Range.Length, OS, DI.IsLittleEndian);
75     writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
76     writeInteger((uint32_t)Range.CuOffset, OS, DI.IsLittleEndian);
77     writeInteger((uint8_t)Range.AddrSize, OS, DI.IsLittleEndian);
78     writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
79
80     auto HeaderSize = OS.tell() - HeaderStart;
81     auto FirstDescriptor = alignTo(HeaderSize, Range.AddrSize * 2);
82     ZeroFillBytes(OS, FirstDescriptor - HeaderSize);
83
84     for (auto Descriptor : Range.Descriptors) {
85       writeVariableSizedInteger(Descriptor.Address, Range.AddrSize, OS,
86                                 DI.IsLittleEndian);
87       writeVariableSizedInteger(Descriptor.Length, Range.AddrSize, OS,
88                                 DI.IsLittleEndian);
89     }
90     ZeroFillBytes(OS, Range.AddrSize * 2);
91   }
92 }
93
94 void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
95                      bool IsLittleEndian) {
96   writeInteger((uint32_t)Sect.Length, OS, IsLittleEndian);
97   writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
98   writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
99   writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
100   for (auto Entry : Sect.Entries) {
101     writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
102     if (Sect.IsGNUStyle)
103       writeInteger((uint32_t)Entry.Descriptor, OS, IsLittleEndian);
104     OS.write(Entry.Name.data(), Entry.Name.size());
105     OS.write('\0');
106   }
107 }