blob: 354c71ec125aeefdf3802a6fbfdd8193fc7ef242 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
2 * Copyright (C) 2012 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#include "elf_writer_quick.h"
18
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070019#include <unordered_map>
20
Brian Carlstrom7940e442013-07-12 13:46:57 -070021#include "base/logging.h"
22#include "base/unix_file/fd_file.h"
Brian Carlstromc6dfdac2013-08-26 18:57:31 -070023#include "buffered_output_stream.h"
Vladimir Marko20f85592015-03-19 10:07:02 +000024#include "compiled_method.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070025#include "driver/compiler_driver.h"
Vladimir Marko20f85592015-03-19 10:07:02 +000026#include "driver/compiler_options.h"
Alex Light3470ab42014-06-18 10:35:45 -070027#include "dwarf.h"
David Srbecky6f715892015-03-30 14:21:42 +010028#include "dwarf/debug_frame_writer.h"
29#include "dwarf/debug_line_writer.h"
Andreas Gampe54fc26c2014-09-04 21:47:42 -070030#include "elf_builder.h"
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070031#include "elf_file.h"
Nicolas Geoffray50cfe742014-02-19 13:27:42 +000032#include "elf_utils.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070033#include "file_output_stream.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070034#include "globals.h"
Andreas Gampe79273802014-08-05 20:21:05 -070035#include "leb128.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070036#include "oat.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070037#include "oat_writer.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070038#include "utils.h"
39
40namespace art {
41
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070042static void PushByte(std::vector<uint8_t>* buf, int data) {
43 buf->push_back(data & 0xff);
44}
45
46static uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) {
47 if (str == nullptr) {
48 str = def;
49 }
50
51 uint32_t offset = buf->size();
52 for (size_t i = 0; str[i] != '\0'; ++i) {
53 buf->push_back(str[i]);
54 }
55 buf->push_back('\0');
56 return offset;
57}
58
59static uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) {
60 uint32_t offset = buf->size();
61 buf->insert(buf->end(), str.begin(), str.end());
62 buf->push_back('\0');
63 return offset;
64}
65
Andreas Gampe79273802014-08-05 20:21:05 -070066static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) {
67 (*buf)[offset+0] = data;
68 (*buf)[offset+1] = data >> 8;
69 (*buf)[offset+2] = data >> 16;
70 (*buf)[offset+3] = data >> 24;
71}
72
Andreas Gampe79273802014-08-05 20:21:05 -070073static void PushHalf(std::vector<uint8_t>* buf, int data) {
74 buf->push_back(data & 0xff);
75 buf->push_back((data >> 8) & 0xff);
76}
77
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000078template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
79 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
80 typename Elf_Phdr, typename Elf_Shdr>
81bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000082 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
Brian Carlstromb12f3472014-06-11 14:54:46 -070083 OatWriter* oat_writer,
84 const std::vector<const DexFile*>& dex_files,
85 const std::string& android_root,
86 bool is_host,
87 const CompilerDriver& driver) {
88 ElfWriterQuick elf_writer(driver, elf_file);
89 return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
90}
91
David Srbecky1109fb32015-04-07 20:21:06 +010092void WriteCIE(dwarf::DebugFrameWriter<>* cfi, InstructionSet isa) {
93 // Scratch registers should be marked as undefined. This tells the
94 // debugger that its value in the previous frame is not recoverable.
95 switch (isa) {
96 case kArm:
97 case kThumb2: {
98 dwarf::DebugFrameOpCodeWriter<> opcodes;
99 opcodes.DefCFA(dwarf::Reg::ArmCore(13), 0); // R13(SP).
100 // core registers.
101 for (int reg = 0; reg < 13; reg++) {
102 if (reg < 4 || reg == 12) {
103 opcodes.Undefined(dwarf::Reg::ArmCore(reg));
104 } else {
105 opcodes.SameValue(dwarf::Reg::ArmCore(reg));
106 }
107 }
108 // fp registers.
109 for (int reg = 0; reg < 32; reg++) {
110 if (reg < 16) {
111 opcodes.Undefined(dwarf::Reg::ArmFp(reg));
112 } else {
113 opcodes.SameValue(dwarf::Reg::ArmFp(reg));
114 }
115 }
116 auto return_address_reg = dwarf::Reg::ArmCore(14); // R14(LR).
117 cfi->WriteCIE(return_address_reg, opcodes);
118 return;
119 }
120 case kArm64: {
121 dwarf::DebugFrameOpCodeWriter<> opcodes;
122 opcodes.DefCFA(dwarf::Reg::Arm64Core(31), 0); // R31(SP).
123 // core registers.
124 for (int reg = 0; reg < 30; reg++) {
125 if (reg < 8 || reg == 16 || reg == 17) {
126 opcodes.Undefined(dwarf::Reg::Arm64Core(reg));
127 } else {
128 opcodes.SameValue(dwarf::Reg::Arm64Core(reg));
129 }
130 }
131 // fp registers.
132 for (int reg = 0; reg < 32; reg++) {
133 if (reg < 8 || reg >= 16) {
134 opcodes.Undefined(dwarf::Reg::Arm64Fp(reg));
135 } else {
136 opcodes.SameValue(dwarf::Reg::Arm64Fp(reg));
137 }
138 }
139 auto return_address_reg = dwarf::Reg::Arm64Core(30); // R30(LR).
140 cfi->WriteCIE(return_address_reg, opcodes);
141 return;
142 }
143 case kMips:
144 case kMips64: {
145 dwarf::DebugFrameOpCodeWriter<> opcodes;
146 opcodes.DefCFA(dwarf::Reg::MipsCore(29), 0); // R29(SP).
147 // core registers.
148 for (int reg = 1; reg < 26; reg++) {
149 if (reg < 16 || reg == 24 || reg == 25) { // AT, V*, A*, T*.
150 opcodes.Undefined(dwarf::Reg::MipsCore(reg));
151 } else {
152 opcodes.SameValue(dwarf::Reg::MipsCore(reg));
153 }
154 }
155 auto return_address_reg = dwarf::Reg::MipsCore(31); // R31(RA).
156 cfi->WriteCIE(return_address_reg, opcodes);
157 return;
158 }
159 case kX86: {
160 dwarf::DebugFrameOpCodeWriter<> opcodes;
161 opcodes.DefCFA(dwarf::Reg::X86Core(4), 4); // R4(ESP).
162 opcodes.Offset(dwarf::Reg::X86Core(8), -4); // R8(EIP).
163 // core registers.
164 for (int reg = 0; reg < 8; reg++) {
165 if (reg <= 3) {
166 opcodes.Undefined(dwarf::Reg::X86Core(reg));
167 } else if (reg == 4) {
168 // Stack pointer.
169 } else {
170 opcodes.SameValue(dwarf::Reg::X86Core(reg));
171 }
172 }
173 // fp registers.
174 for (int reg = 0; reg < 8; reg++) {
175 opcodes.Undefined(dwarf::Reg::X86Fp(reg));
176 }
177 auto return_address_reg = dwarf::Reg::X86Core(8); // R8(EIP).
178 cfi->WriteCIE(return_address_reg, opcodes);
179 return;
180 }
181 case kX86_64: {
182 dwarf::DebugFrameOpCodeWriter<> opcodes;
183 opcodes.DefCFA(dwarf::Reg::X86_64Core(4), 8); // R4(RSP).
184 opcodes.Offset(dwarf::Reg::X86_64Core(16), -8); // R16(RIP).
185 // core registers.
186 for (int reg = 0; reg < 16; reg++) {
187 if (reg == 4) {
188 // Stack pointer.
189 } else if (reg < 12 && reg != 3 && reg != 5) { // except EBX and EBP.
190 opcodes.Undefined(dwarf::Reg::X86_64Core(reg));
191 } else {
192 opcodes.SameValue(dwarf::Reg::X86_64Core(reg));
193 }
194 }
195 // fp registers.
196 for (int reg = 0; reg < 16; reg++) {
197 if (reg < 12) {
198 opcodes.Undefined(dwarf::Reg::X86_64Fp(reg));
199 } else {
200 opcodes.SameValue(dwarf::Reg::X86_64Fp(reg));
201 }
202 }
203 auto return_address_reg = dwarf::Reg::X86_64Core(16); // R16(RIP).
204 cfi->WriteCIE(return_address_reg, opcodes);
205 return;
206 }
207 case kNone:
208 break;
209 }
210 LOG(FATAL) << "Can not write CIE frame for ISA " << isa;
211 UNREACHABLE();
212}
213
Ian Rogers0279ebb2014-10-08 17:27:48 -0700214class OatWriterWrapper FINAL : public CodeOutput {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700215 public:
216 explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
217
Vladimir Markof4da6752014-08-01 19:04:18 +0100218 void SetCodeOffset(size_t offset) {
219 oat_writer_->SetOatDataOffset(offset);
220 }
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700221 bool Write(OutputStream* out) OVERRIDE {
222 return oat_writer_->Write(out);
223 }
224 private:
Ian Rogers0279ebb2014-10-08 17:27:48 -0700225 OatWriter* const oat_writer_;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700226};
227
228template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
229 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
230 typename Elf_Phdr, typename Elf_Shdr>
231static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
232 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
233 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
234 OatWriter* oat_writer);
235
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000236template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
237 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
238 typename Elf_Phdr, typename Elf_Shdr>
239bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
240 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700241 const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
242 const std::string& android_root_unused ATTRIBUTE_UNUSED,
243 bool is_host_unused ATTRIBUTE_UNUSED) {
Andreas Gampe79273802014-08-05 20:21:05 -0700244 constexpr bool debug = false;
Brian Carlstromb12f3472014-06-11 14:54:46 -0700245 const OatHeader& oat_header = oat_writer->GetOatHeader();
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000246 Elf_Word oat_data_size = oat_header.GetExecutableOffset();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700247 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
Vladimir Marko5c42c292015-02-25 12:02:49 +0000248 uint32_t oat_bss_size = oat_writer->GetBssSize();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700249
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700250 OatWriterWrapper wrapper(oat_writer);
251
252 std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
253 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
254 new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
255 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
256 &wrapper,
257 elf_file_,
258 compiler_driver_->GetInstructionSet(),
259 0,
260 oat_data_size,
261 oat_data_size,
262 oat_exec_size,
Vladimir Marko5c42c292015-02-25 12:02:49 +0000263 RoundUp(oat_data_size + oat_exec_size, kPageSize),
264 oat_bss_size,
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700265 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
266 debug));
Alex Light78382fa2014-06-06 15:45:32 -0700267
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700268 if (!builder->Init()) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700269 return false;
270 }
271
Andreas Gampe79273802014-08-05 20:21:05 -0700272 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700273 WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
Brian Carlstromb12f3472014-06-11 14:54:46 -0700274 }
275
Alex Light53cb16b2014-06-12 11:26:29 -0700276 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700277 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
278 ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
Vladimir Markof4da6752014-08-01 19:04:18 +0100279 const std::vector<uintptr_t>& locations = oat_writer->GetAbsolutePatchLocations();
280 const uint8_t* begin = reinterpret_cast<const uint8_t*>(&locations[0]);
281 const uint8_t* end = begin + locations.size() * sizeof(locations[0]);
282 oat_patches.GetBuffer()->assign(begin, end);
283 if (debug) {
284 LOG(INFO) << "Prepared .oat_patches for " << locations.size() << " patches.";
285 }
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700286 builder->RegisterRawSection(oat_patches);
Alex Light53cb16b2014-06-12 11:26:29 -0700287 }
288
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700289 return builder->Write();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700290}
Mark Mendellae9fd932014-02-10 16:14:35 -0800291
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700292// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
David Srbecky6f715892015-03-30 14:21:42 +0100293static void GetLineInfoForJava(const uint8_t* dbgstream, DefaultSrcMap* dex2line) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700294 if (dbgstream == nullptr) {
295 return;
296 }
297
298 int adjopcode;
299 uint32_t dex_offset = 0;
300 uint32_t java_line = DecodeUnsignedLeb128(&dbgstream);
301
302 // skip parameters
303 for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) {
304 DecodeUnsignedLeb128(&dbgstream);
305 }
306
307 for (bool is_end = false; is_end == false; ) {
308 uint8_t opcode = *dbgstream;
309 dbgstream++;
310 switch (opcode) {
311 case DexFile::DBG_END_SEQUENCE:
312 is_end = true;
313 break;
314
315 case DexFile::DBG_ADVANCE_PC:
316 dex_offset += DecodeUnsignedLeb128(&dbgstream);
317 break;
318
319 case DexFile::DBG_ADVANCE_LINE:
320 java_line += DecodeSignedLeb128(&dbgstream);
321 break;
322
323 case DexFile::DBG_START_LOCAL:
324 case DexFile::DBG_START_LOCAL_EXTENDED:
325 DecodeUnsignedLeb128(&dbgstream);
326 DecodeUnsignedLeb128(&dbgstream);
327 DecodeUnsignedLeb128(&dbgstream);
328
329 if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) {
330 DecodeUnsignedLeb128(&dbgstream);
331 }
332 break;
333
334 case DexFile::DBG_END_LOCAL:
335 case DexFile::DBG_RESTART_LOCAL:
336 DecodeUnsignedLeb128(&dbgstream);
337 break;
338
339 case DexFile::DBG_SET_PROLOGUE_END:
340 case DexFile::DBG_SET_EPILOGUE_BEGIN:
341 case DexFile::DBG_SET_FILE:
342 break;
343
344 default:
345 adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
346 dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
347 java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
David Srbecky6f715892015-03-30 14:21:42 +0100348 dex2line->push_back({dex_offset, static_cast<int32_t>(java_line)});
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700349 break;
350 }
Andreas Gampe79273802014-08-05 20:21:05 -0700351 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800352}
353
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700354/*
355 * @brief Generate the DWARF debug_info and debug_abbrev sections
356 * @param oat_writer The Oat file Writer.
357 * @param dbg_info Compilation unit information.
358 * @param dbg_abbrev Abbreviations used to generate dbg_info.
359 * @param dbg_str Debug strings.
360 */
361static void FillInCFIInformation(OatWriter* oat_writer,
362 std::vector<uint8_t>* dbg_info,
363 std::vector<uint8_t>* dbg_abbrev,
364 std::vector<uint8_t>* dbg_str,
365 std::vector<uint8_t>* dbg_line,
366 uint32_t text_section_offset) {
David Srbecky6f715892015-03-30 14:21:42 +0100367 const std::vector<OatWriter::DebugInfo>& method_infos = oat_writer->GetCFIMethodInfo();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700368
369 uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
370
David Srbecky6f715892015-03-30 14:21:42 +0100371 constexpr bool use_64bit_addresses = false;
372
Mark Mendellae9fd932014-02-10 16:14:35 -0800373 // Create the debug_abbrev section with boilerplate information.
374 // We only care about low_pc and high_pc right now for the compilation
375 // unit and methods.
376
377 // Tag 1: Compilation unit: DW_TAG_compile_unit.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700378 PushByte(dbg_abbrev, 1);
David Srbecky6f715892015-03-30 14:21:42 +0100379 PushByte(dbg_abbrev, dwarf::DW_TAG_compile_unit);
Mark Mendellae9fd932014-02-10 16:14:35 -0800380
381 // There are children (the methods).
David Srbecky6f715892015-03-30 14:21:42 +0100382 PushByte(dbg_abbrev, dwarf::DW_CHILDREN_yes);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700383
384 // DW_AT_producer DW_FORM_data1.
385 // REVIEW: we can get rid of dbg_str section if
386 // DW_FORM_string (immediate string) was used everywhere instead of
387 // DW_FORM_strp (ref to string from .debug_str section).
388 // DW_FORM_strp makes sense only if we reuse the strings.
David Srbecky6f715892015-03-30 14:21:42 +0100389 PushByte(dbg_abbrev, dwarf::DW_AT_producer);
390 PushByte(dbg_abbrev, dwarf::DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800391
392 // DW_LANG_Java DW_FORM_data1.
David Srbecky6f715892015-03-30 14:21:42 +0100393 PushByte(dbg_abbrev, dwarf::DW_AT_language);
394 PushByte(dbg_abbrev, dwarf::DW_FORM_data1);
Mark Mendellae9fd932014-02-10 16:14:35 -0800395
396 // DW_AT_low_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100397 PushByte(dbg_abbrev, dwarf::DW_AT_low_pc);
398 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800399
400 // DW_AT_high_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100401 PushByte(dbg_abbrev, dwarf::DW_AT_high_pc);
402 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700403
404 if (dbg_line != nullptr) {
405 // DW_AT_stmt_list DW_FORM_sec_offset.
David Srbecky6f715892015-03-30 14:21:42 +0100406 PushByte(dbg_abbrev, dwarf::DW_AT_stmt_list);
407 PushByte(dbg_abbrev, dwarf::DW_FORM_data4);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700408 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800409
410 // End of DW_TAG_compile_unit.
David Srbecky6f715892015-03-30 14:21:42 +0100411 PushByte(dbg_abbrev, 0); // DW_AT.
412 PushByte(dbg_abbrev, 0); // DW_FORM.
Mark Mendellae9fd932014-02-10 16:14:35 -0800413
414 // Tag 2: Compilation unit: DW_TAG_subprogram.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700415 PushByte(dbg_abbrev, 2);
David Srbecky6f715892015-03-30 14:21:42 +0100416 PushByte(dbg_abbrev, dwarf::DW_TAG_subprogram);
Mark Mendellae9fd932014-02-10 16:14:35 -0800417
418 // There are no children.
David Srbecky6f715892015-03-30 14:21:42 +0100419 PushByte(dbg_abbrev, dwarf::DW_CHILDREN_no);
Mark Mendellae9fd932014-02-10 16:14:35 -0800420
421 // Name of the method.
David Srbecky6f715892015-03-30 14:21:42 +0100422 PushByte(dbg_abbrev, dwarf::DW_AT_name);
423 PushByte(dbg_abbrev, dwarf::DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800424
425 // DW_AT_low_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100426 PushByte(dbg_abbrev, dwarf::DW_AT_low_pc);
427 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800428
429 // DW_AT_high_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100430 PushByte(dbg_abbrev, dwarf::DW_AT_high_pc);
431 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800432
433 // End of DW_TAG_subprogram.
David Srbecky6f715892015-03-30 14:21:42 +0100434 PushByte(dbg_abbrev, 0); // DW_AT.
435 PushByte(dbg_abbrev, 0); // DW_FORM.
436
437 // End of abbrevs for compilation unit
438 PushByte(dbg_abbrev, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800439
440 // Start the debug_info section with the header information
441 // 'unit_length' will be filled in later.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700442 int cunit_length = dbg_info->size();
Vladimir Marko80b96d12015-02-19 15:50:28 +0000443 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800444
445 // 'version' - 3.
446 PushHalf(dbg_info, 3);
447
448 // Offset into .debug_abbrev section (always 0).
Vladimir Marko80b96d12015-02-19 15:50:28 +0000449 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800450
David Srbecky6f715892015-03-30 14:21:42 +0100451 // Address size: 4 or 8.
452 PushByte(dbg_info, use_64bit_addresses ? 8 : 4);
Mark Mendellae9fd932014-02-10 16:14:35 -0800453
454 // Start the description for the compilation unit.
455 // This uses tag 1.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700456 PushByte(dbg_info, 1);
457
458 // The producer is Android dex2oat.
Vladimir Marko80b96d12015-02-19 15:50:28 +0000459 Push32(dbg_info, producer_str_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800460
461 // The language is Java.
David Srbecky6f715892015-03-30 14:21:42 +0100462 PushByte(dbg_info, dwarf::DW_LANG_Java);
Mark Mendellae9fd932014-02-10 16:14:35 -0800463
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700464 // low_pc and high_pc.
David Srbecky6f715892015-03-30 14:21:42 +0100465 uint32_t cunit_low_pc = static_cast<uint32_t>(-1);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700466 uint32_t cunit_high_pc = 0;
David Srbecky6f715892015-03-30 14:21:42 +0100467 for (auto method_info : method_infos) {
468 cunit_low_pc = std::min(cunit_low_pc, method_info.low_pc_);
469 cunit_high_pc = std::max(cunit_high_pc, method_info.high_pc_);
470 }
471 Push32(dbg_info, cunit_low_pc + text_section_offset);
472 Push32(dbg_info, cunit_high_pc + text_section_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800473
David Srbecky6f715892015-03-30 14:21:42 +0100474 if (dbg_line != nullptr) {
475 // Line number table offset.
476 Push32(dbg_info, dbg_line->size());
477 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800478
David Srbecky6f715892015-03-30 14:21:42 +0100479 for (auto method_info : method_infos) {
480 // Start a new TAG: subroutine (2).
481 PushByte(dbg_info, 2);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700482
David Srbecky6f715892015-03-30 14:21:42 +0100483 // Enter name, low_pc, high_pc.
484 Push32(dbg_info, PushStr(dbg_str, method_info.method_name_));
485 Push32(dbg_info, method_info.low_pc_ + text_section_offset);
486 Push32(dbg_info, method_info.high_pc_ + text_section_offset);
487 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700488
David Srbecky6f715892015-03-30 14:21:42 +0100489 if (dbg_line != nullptr) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700490 // TODO: in gdb info functions <regexp> - reports Java functions, but
491 // source file is <unknown> because .debug_line is formed as one
492 // compilation unit. To fix this it is possible to generate
493 // a separate compilation unit for every distinct Java source.
494 // Each of the these compilation units can have several non-adjacent
495 // method ranges.
496
David Srbecky6f715892015-03-30 14:21:42 +0100497 std::vector<dwarf::DebugLineWriter<>::FileEntry> files;
498 std::unordered_map<std::string, size_t> files_map;
499 std::vector<std::string> directories;
500 std::unordered_map<std::string, size_t> directories_map;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700501
David Srbecky6f715892015-03-30 14:21:42 +0100502 int code_factor_bits_ = 0;
503 int isa = -1;
504 switch (oat_writer->GetOatHeader().GetInstructionSet()) {
David Srbecky189ae822015-04-04 10:15:17 +0100505 case kArm: // arm actually means thumb2.
David Srbecky6f715892015-03-30 14:21:42 +0100506 case kThumb2:
507 code_factor_bits_ = 1; // 16-bit instuctions
508 isa = 1; // DW_ISA_ARM_thumb.
509 break;
David Srbecky6f715892015-03-30 14:21:42 +0100510 case kArm64:
511 case kMips:
512 case kMips64:
513 code_factor_bits_ = 2; // 32-bit instructions
514 break;
515 case kNone:
516 case kX86:
517 case kX86_64:
518 break;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700519 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700520
David Srbecky6f715892015-03-30 14:21:42 +0100521 dwarf::DebugLineOpCodeWriter<> opcodes(use_64bit_addresses, code_factor_bits_);
522 opcodes.SetAddress(text_section_offset + cunit_low_pc);
523 if (isa != -1) {
524 opcodes.SetISA(isa);
525 }
526 DefaultSrcMap dex2line_map;
527 for (size_t i = 0; i < method_infos.size(); i++) {
528 const OatWriter::DebugInfo& method_info = method_infos[i];
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700529
David Srbecky6f715892015-03-30 14:21:42 +0100530 // Addresses in the line table should be unique and increasing.
531 if (method_info.deduped_) {
532 continue;
533 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700534
David Srbecky6f715892015-03-30 14:21:42 +0100535 // Get and deduplicate directory and filename.
536 int file_index = 0; // 0 - primary source file of the compilation.
537 if (method_info.src_file_name_ != nullptr) {
538 std::string file_name(method_info.src_file_name_);
539 size_t file_name_slash = file_name.find_last_of('/');
540 std::string class_name(method_info.class_descriptor_);
541 size_t class_name_slash = class_name.find_last_of('/');
542 std::string full_path(file_name);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700543
David Srbecky6f715892015-03-30 14:21:42 +0100544 // Guess directory from package name.
545 int directory_index = 0; // 0 - current directory of the compilation.
546 if (file_name_slash == std::string::npos && // Just filename.
547 class_name.front() == 'L' && // Type descriptor for a class.
548 class_name_slash != std::string::npos) { // Has package name.
549 std::string package_name = class_name.substr(1, class_name_slash - 1);
550 auto it = directories_map.find(package_name);
551 if (it == directories_map.end()) {
552 directory_index = 1 + directories.size();
553 directories_map.emplace(package_name, directory_index);
554 directories.push_back(package_name);
555 } else {
556 directory_index = it->second;
557 }
558 full_path = package_name + "/" + file_name;
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700559 }
David Srbecky6f715892015-03-30 14:21:42 +0100560
561 // Add file entry.
562 auto it2 = files_map.find(full_path);
563 if (it2 == files_map.end()) {
564 file_index = 1 + files.size();
565 files_map.emplace(full_path, file_index);
566 files.push_back(dwarf::DebugLineWriter<>::FileEntry {
567 file_name,
568 directory_index,
569 0, // Modification time - NA.
570 0, // File size - NA.
571 });
572 } else {
573 file_index = it2->second;
574 }
575 }
576 opcodes.SetFile(file_index);
577
578 // Generate mapping opcodes from PC to Java lines.
579 dex2line_map.clear();
580 GetLineInfoForJava(method_info.dbgstream_, &dex2line_map);
581 uint32_t low_pc = text_section_offset + method_info.low_pc_;
582 if (file_index != 0 && !dex2line_map.empty()) {
583 bool first = true;
584 for (SrcMapElem pc2dex : method_info.compiled_method_->GetSrcMappingTable()) {
585 uint32_t pc = pc2dex.from_;
586 int dex = pc2dex.to_;
587 auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex));
588 if (dex2line.first) {
589 int line = dex2line.second;
590 if (first) {
591 first = false;
592 if (pc > 0) {
593 // Assume that any preceding code is prologue.
594 int first_line = dex2line_map.front().to_;
595 // Prologue is not a sensible place for a breakpoint.
596 opcodes.NegateStmt();
597 opcodes.AddRow(low_pc, first_line);
598 opcodes.NegateStmt();
599 opcodes.SetPrologueEnd();
600 }
601 opcodes.AddRow(low_pc + pc, line);
602 } else if (line != opcodes.CurrentLine()) {
603 opcodes.AddRow(low_pc + pc, line);
604 }
605 }
606 }
607 } else {
608 // line 0 - instruction cannot be attributed to any source line.
609 opcodes.AddRow(low_pc, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700610 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800611 }
612
David Srbecky6f715892015-03-30 14:21:42 +0100613 opcodes.AdvancePC(text_section_offset + cunit_high_pc);
614 opcodes.EndSequence();
Mark Mendellae9fd932014-02-10 16:14:35 -0800615
David Srbecky6f715892015-03-30 14:21:42 +0100616 dwarf::DebugLineWriter<> dbg_line_writer(dbg_line);
617 dbg_line_writer.WriteTable(directories, files, opcodes);
Mark Mendellae9fd932014-02-10 16:14:35 -0800618 }
619
David Srbecky6f715892015-03-30 14:21:42 +0100620 // One byte terminator.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700621 PushByte(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800622
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700623 // We have now walked all the methods. Fill in lengths.
624 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700625}
626
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700627template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
628 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
629 typename Elf_Phdr, typename Elf_Shdr>
Andreas Gampe86830382014-12-12 21:41:29 -0800630// Do not inline to avoid Clang stack frame problems. b/18738594
631NO_INLINE
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700632static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
633 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
634 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
635 OatWriter* oat_writer) {
David Srbecky1109fb32015-04-07 20:21:06 +0100636 std::vector<uint8_t> cfi_data;
637 bool is_64bit = Is64BitInstructionSet(compiler_driver->GetInstructionSet());
638 dwarf::DebugFrameWriter<> cfi(&cfi_data, is_64bit);
639 WriteCIE(&cfi, compiler_driver->GetInstructionSet());
640
Ian Rogers0279ebb2014-10-08 17:27:48 -0700641 Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700642
643 // Iterate over the compiled methods.
644 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
Ian Rogers0279ebb2014-10-08 17:27:48 -0700645 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
646 builder->GetSymtabBuilder();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700647 for (auto it = method_info.begin(); it != method_info.end(); ++it) {
David Srbecky6f715892015-03-30 14:21:42 +0100648 uint32_t low_pc = it->low_pc_;
649 // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
650 low_pc += it->compiled_method_->CodeDelta();
651 symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), low_pc,
652 true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700653
Ningsheng Jianf9734552014-10-27 14:56:34 +0800654 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
655 // instructions, so that disassembler tools can correctly disassemble.
656 if (it->compiled_method_->GetInstructionSet() == kThumb2) {
657 symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true,
658 0, STB_LOCAL, STT_NOTYPE);
659 }
David Srbecky1109fb32015-04-07 20:21:06 +0100660
661 // Include FDE for compiled method, if possible.
662 DCHECK(it->compiled_method_ != nullptr);
663 const SwapVector<uint8_t>* unwind_opcodes = it->compiled_method_->GetCFIInfo();
664 if (unwind_opcodes != nullptr) {
665 // TUNING: The headers take a lot of space. Can we have 1 FDE per file?
666 // TUNING: Some tools support compressed DWARF sections (.zdebug_*).
667 cfi.WriteFDE(text_section_address + it->low_pc_, it->high_pc_ - it->low_pc_,
668 unwind_opcodes->data(), unwind_opcodes->size());
669 }
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700670 }
671
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700672 bool hasLineInfo = false;
673 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
674 if (dbg_info.dbgstream_ != nullptr &&
675 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
676 hasLineInfo = true;
677 break;
678 }
679 }
680
David Srbecky1109fb32015-04-07 20:21:06 +0100681 if (!method_info.empty() &&
682 compiler_driver->GetCompilerOptions().GetGenerateGDBInformation()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700683 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
684 SHT_PROGBITS,
685 0, nullptr, 0, 1, 0);
686 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
687 SHT_PROGBITS,
688 0, nullptr, 0, 1, 0);
689 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
690 SHT_PROGBITS,
691 0, nullptr, 0, 1, 0);
692 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
693 SHT_PROGBITS,
694 0, nullptr, 0, 1, 0);
695
696 FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
697 debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
698 hasLineInfo ? debug_line.GetBuffer() : nullptr,
699 text_section_address);
700
701 builder->RegisterRawSection(debug_info);
702 builder->RegisterRawSection(debug_abbrev);
703
David Srbecky1109fb32015-04-07 20:21:06 +0100704 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
705 SHT_PROGBITS,
706 SHF_ALLOC,
707 nullptr, 0, 4, 0);
708 eh_frame.SetBuffer(std::move(cfi_data));
709 builder->RegisterRawSection(eh_frame);
710
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700711 if (hasLineInfo) {
712 builder->RegisterRawSection(debug_line);
713 }
714
715 builder->RegisterRawSection(debug_str);
716 }
717}
718
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000719// Explicit instantiations
720template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
721 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
722template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
723 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
724
Brian Carlstrom7940e442013-07-12 13:46:57 -0700725} // namespace art