blob: 4b7d8d9d92df2149910f6a31255872226451fd76 [file] [log] [blame]
David Srbecky15c19752015-03-31 14:53:55 +00001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_DWARF_DEBUG_LINE_WRITER_H_
18#define ART_COMPILER_DWARF_DEBUG_LINE_WRITER_H_
19
20#include "debug_line_opcode_writer.h"
21#include "dwarf.h"
22#include "writer.h"
23#include <string>
24
25namespace art {
26namespace dwarf {
27
28// Writer for the .debug_line section (DWARF-3).
29template<typename Allocator = std::allocator<uint8_t>>
30class DebugLineWriter FINAL : private Writer<Allocator> {
31 public:
32 struct FileEntry {
33 std::string file_name;
34 int directory_index;
35 int modification_time;
36 int file_size;
37 };
38
39 void WriteTable(const std::vector<std::string>& include_directories,
40 const std::vector<FileEntry>& files,
41 const DebugLineOpCodeWriter<Allocator>& opcodes) {
42 size_t header_start = this->data()->size();
43 this->PushUint32(0); // Section-length placeholder.
44 // Claim DWARF-2 version even though we use some DWARF-3 features.
45 // DWARF-2 consumers will ignore the unknown opcodes.
46 // This is what clang currently does.
47 this->PushUint16(2); // .debug_line version.
48 size_t header_length_pos = this->data()->size();
49 this->PushUint32(0); // Header-length placeholder.
50 this->PushUint8(1 << opcodes.GetCodeFactorBits());
51 this->PushUint8(DebugLineOpCodeWriter<Allocator>::kDefaultIsStmt ? 1 : 0);
52 this->PushInt8(DebugLineOpCodeWriter<Allocator>::kLineBase);
53 this->PushUint8(DebugLineOpCodeWriter<Allocator>::kLineRange);
54 this->PushUint8(DebugLineOpCodeWriter<Allocator>::kOpcodeBase);
55 static const int opcode_lengths[DebugLineOpCodeWriter<Allocator>::kOpcodeBase] = {
56 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 };
57 for (int i = 1; i < DebugLineOpCodeWriter<Allocator>::kOpcodeBase; i++) {
58 this->PushUint8(opcode_lengths[i]);
59 }
60 for (const std::string& directory : include_directories) {
61 this->PushData(directory.data(), directory.size() + 1);
62 }
63 this->PushUint8(0); // Terminate include_directories list.
64 for (const FileEntry& file : files) {
65 this->PushData(file.file_name.data(), file.file_name.size() + 1);
66 this->PushUleb128(file.directory_index);
67 this->PushUleb128(file.modification_time);
68 this->PushUleb128(file.file_size);
69 }
70 this->PushUint8(0); // Terminate file list.
71 this->UpdateUint32(header_length_pos, this->data()->size() - header_length_pos - 4);
72 this->PushData(opcodes.data()->data(), opcodes.data()->size());
73 this->UpdateUint32(header_start, this->data()->size() - header_start - 4);
74 }
75
76 explicit DebugLineWriter(std::vector<uint8_t, Allocator>* buffer)
77 : Writer<Allocator>(buffer) {
78 }
79
80 private:
81 DISALLOW_COPY_AND_ASSIGN(DebugLineWriter);
82};
83
84} // namespace dwarf
85} // namespace art
86
87#endif // ART_COMPILER_DWARF_DEBUG_LINE_WRITER_H_