blob: dbd3a37dbb0762a948d8997042d733ed42e7f60b [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"
Brian Carlstrom7940e442013-07-12 13:46:57 -070024#include "driver/compiler_driver.h"
Alex Light3470ab42014-06-18 10:35:45 -070025#include "dwarf.h"
Andreas Gampe54fc26c2014-09-04 21:47:42 -070026#include "elf_builder.h"
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070027#include "elf_file.h"
Nicolas Geoffray50cfe742014-02-19 13:27:42 +000028#include "elf_utils.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070029#include "file_output_stream.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070030#include "globals.h"
Andreas Gampe79273802014-08-05 20:21:05 -070031#include "leb128.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070032#include "oat.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070033#include "oat_writer.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070034#include "utils.h"
35
36namespace art {
37
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070038static void PushByte(std::vector<uint8_t>* buf, int data) {
39 buf->push_back(data & 0xff);
40}
41
42static uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) {
43 if (str == nullptr) {
44 str = def;
45 }
46
47 uint32_t offset = buf->size();
48 for (size_t i = 0; str[i] != '\0'; ++i) {
49 buf->push_back(str[i]);
50 }
51 buf->push_back('\0');
52 return offset;
53}
54
55static uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) {
56 uint32_t offset = buf->size();
57 buf->insert(buf->end(), str.begin(), str.end());
58 buf->push_back('\0');
59 return offset;
60}
61
Andreas Gampe79273802014-08-05 20:21:05 -070062static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) {
63 (*buf)[offset+0] = data;
64 (*buf)[offset+1] = data >> 8;
65 (*buf)[offset+2] = data >> 16;
66 (*buf)[offset+3] = data >> 24;
67}
68
Andreas Gampe79273802014-08-05 20:21:05 -070069static void PushHalf(std::vector<uint8_t>* buf, int data) {
70 buf->push_back(data & 0xff);
71 buf->push_back((data >> 8) & 0xff);
72}
73
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000074template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
75 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
76 typename Elf_Phdr, typename Elf_Shdr>
77bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000078 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
Brian Carlstromb12f3472014-06-11 14:54:46 -070079 OatWriter* oat_writer,
80 const std::vector<const DexFile*>& dex_files,
81 const std::string& android_root,
82 bool is_host,
83 const CompilerDriver& driver) {
84 ElfWriterQuick elf_writer(driver, elf_file);
85 return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
86}
87
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000088// Add patch information to this section. Each patch is a Elf_Word that
Alex Light53cb16b2014-06-12 11:26:29 -070089// identifies an offset from the start of the text section
Andreas Gampe54fc26c2014-09-04 21:47:42 -070090static void ReservePatchSpace(const CompilerDriver* compiler_driver, std::vector<uint8_t>* buffer,
91 bool debug) {
Alex Light53cb16b2014-06-12 11:26:29 -070092 size_t size =
Andreas Gampe54fc26c2014-09-04 21:47:42 -070093 compiler_driver->GetCodeToPatch().size() +
94 compiler_driver->GetMethodsToPatch().size() +
95 compiler_driver->GetClassesToPatch().size();
Alex Light53cb16b2014-06-12 11:26:29 -070096 if (size == 0) {
97 if (debug) {
98 LOG(INFO) << "No patches to record";
99 }
100 return;
101 }
102 buffer->resize(size * sizeof(uintptr_t));
103 if (debug) {
104 LOG(INFO) << "Patches reserved for " << size;
105 }
106}
107
Andreas Gampe79273802014-08-05 20:21:05 -0700108std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700109 std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>;
Andreas Gampe79273802014-08-05 20:21:05 -0700110
111 // Length (will be filled in later in this routine).
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700112 if (is_x86_64) {
113 PushWord(cfi_info, 0xffffffff); // Indicates 64bit
114 PushWord(cfi_info, 0);
115 PushWord(cfi_info, 0);
116 } else {
117 PushWord(cfi_info, 0);
118 }
Andreas Gampe79273802014-08-05 20:21:05 -0700119
120 // CIE id: always 0.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700121 if (is_x86_64) {
122 PushWord(cfi_info, 0);
123 PushWord(cfi_info, 0);
124 } else {
125 PushWord(cfi_info, 0);
126 }
Andreas Gampe79273802014-08-05 20:21:05 -0700127
128 // Version: always 1.
129 cfi_info->push_back(0x01);
130
131 // Augmentation: 'zR\0'
132 cfi_info->push_back(0x7a);
133 cfi_info->push_back(0x52);
134 cfi_info->push_back(0x0);
135
136 // Code alignment: 1.
137 EncodeUnsignedLeb128(1, cfi_info);
138
139 // Data alignment.
140 if (is_x86_64) {
141 EncodeSignedLeb128(-8, cfi_info);
142 } else {
143 EncodeSignedLeb128(-4, cfi_info);
144 }
145
146 // Return address register.
147 if (is_x86_64) {
148 // R16(RIP)
149 cfi_info->push_back(0x10);
150 } else {
151 // R8(EIP)
152 cfi_info->push_back(0x08);
153 }
154
155 // Augmentation length: 1.
156 cfi_info->push_back(1);
157
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700158 // Augmentation data.
159 if (is_x86_64) {
160 // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8).
161 cfi_info->push_back(0x04);
162 } else {
163 // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4).
164 cfi_info->push_back(0x03);
165 }
Andreas Gampe79273802014-08-05 20:21:05 -0700166
167 // Initial instructions.
168 if (is_x86_64) {
169 // DW_CFA_def_cfa R7(RSP) 8.
170 cfi_info->push_back(0x0c);
171 cfi_info->push_back(0x07);
172 cfi_info->push_back(0x08);
173
174 // DW_CFA_offset R16(RIP) 1 (* -8).
175 cfi_info->push_back(0x90);
176 cfi_info->push_back(0x01);
177 } else {
178 // DW_CFA_def_cfa R4(ESP) 4.
179 cfi_info->push_back(0x0c);
180 cfi_info->push_back(0x04);
181 cfi_info->push_back(0x04);
182
183 // DW_CFA_offset R8(EIP) 1 (* -4).
184 cfi_info->push_back(0x88);
185 cfi_info->push_back(0x01);
186 }
187
188 // Padding to a multiple of 4
189 while ((cfi_info->size() & 3) != 0) {
190 // DW_CFA_nop is encoded as 0.
191 cfi_info->push_back(0);
192 }
193
194 // Set the length of the CIE inside the generated bytes.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700195 if (is_x86_64) {
196 uint32_t length = cfi_info->size() - 12;
197 UpdateWord(cfi_info, 4, length);
198 } else {
199 uint32_t length = cfi_info->size() - 4;
200 UpdateWord(cfi_info, 0, length);
201 }
Andreas Gampe79273802014-08-05 20:21:05 -0700202 return cfi_info;
203}
204
205std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
206 switch (isa) {
207 case kX86:
208 return ConstructCIEFrameX86(false);
209 case kX86_64:
210 return ConstructCIEFrameX86(true);
211
212 default:
213 // Not implemented.
214 return nullptr;
215 }
216}
217
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700218class OatWriterWrapper : public CodeOutput {
219 public:
220 explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
221
222 bool Write(OutputStream* out) OVERRIDE {
223 return oat_writer_->Write(out);
224 }
225 private:
226 OatWriter* oat_writer_;
227};
228
229template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
230 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
231 typename Elf_Phdr, typename Elf_Shdr>
232static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
233 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
234 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
235 OatWriter* oat_writer);
236
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000237template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
238 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
239 typename Elf_Phdr, typename Elf_Shdr>
240bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
241 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
Brian Carlstromb12f3472014-06-11 14:54:46 -0700242 const std::vector<const DexFile*>& dex_files_unused,
243 const std::string& android_root_unused,
244 bool is_host_unused) {
Andreas Gampe79273802014-08-05 20:21:05 -0700245 constexpr bool debug = false;
Brian Carlstromb12f3472014-06-11 14:54:46 -0700246 const OatHeader& oat_header = oat_writer->GetOatHeader();
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000247 Elf_Word oat_data_size = oat_header.GetExecutableOffset();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700248 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
249
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,
263 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
264 debug));
Alex Light78382fa2014-06-06 15:45:32 -0700265
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700266 if (!builder->Init()) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700267 return false;
268 }
269
Andreas Gampe79273802014-08-05 20:21:05 -0700270 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700271 WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
Brian Carlstromb12f3472014-06-11 14:54:46 -0700272 }
273
Alex Light53cb16b2014-06-12 11:26:29 -0700274 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700275 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
276 ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
277 ReservePatchSpace(compiler_driver_, oat_patches.GetBuffer(), debug);
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700278 builder->RegisterRawSection(oat_patches);
Alex Light53cb16b2014-06-12 11:26:29 -0700279 }
280
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700281 return builder->Write();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700282}
Mark Mendellae9fd932014-02-10 16:14:35 -0800283
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700284class LineTableGenerator FINAL : public Leb128Encoder {
285 public:
286 LineTableGenerator(int line_base, int line_range, int opcode_base,
287 std::vector<uint8_t>* data, uintptr_t current_address,
288 size_t current_line)
289 : Leb128Encoder(data), line_base_(line_base), line_range_(line_range),
290 opcode_base_(opcode_base), current_address_(current_address),
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700291 current_line_(current_line), current_file_index_(0) {}
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700292
293 void PutDelta(unsigned delta_addr, int delta_line) {
294 current_line_ += delta_line;
295 current_address_ += delta_addr;
296
297 if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) {
298 unsigned special_opcode = (delta_line - line_base_) +
299 (line_range_ * delta_addr) + opcode_base_;
300 if (special_opcode <= 255) {
301 PushByte(data_, special_opcode);
302 return;
303 }
304 }
305
306 // generate standart opcode for address advance
307 if (delta_addr != 0) {
308 PushByte(data_, DW_LNS_advance_pc);
309 PushBackUnsigned(delta_addr);
310 }
311
312 // generate standart opcode for line delta
313 if (delta_line != 0) {
314 PushByte(data_, DW_LNS_advance_line);
315 PushBackSigned(delta_line);
316 }
317
318 // generate standart opcode for new LTN entry
319 PushByte(data_, DW_LNS_copy);
320 }
321
322 void SetAddr(uintptr_t addr) {
323 if (current_address_ == addr) {
324 return;
325 }
326
327 current_address_ = addr;
328
329 PushByte(data_, 0); // extended opcode:
330 PushByte(data_, 1 + 4); // length: opcode_size + address_size
331 PushByte(data_, DW_LNE_set_address);
332 PushWord(data_, addr);
333 }
334
335 void SetLine(unsigned line) {
336 int delta_line = line - current_line_;
337 if (delta_line) {
338 current_line_ = line;
339 PushByte(data_, DW_LNS_advance_line);
340 PushBackSigned(delta_line);
341 }
342 }
343
344 void SetFile(unsigned file_index) {
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700345 if (current_file_index_ != file_index) {
346 current_file_index_ = file_index;
347 PushByte(data_, DW_LNS_set_file);
348 PushBackUnsigned(file_index);
349 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700350 }
351
352 void EndSequence() {
353 // End of Line Table Program
354 // 0(=ext), 1(len), DW_LNE_end_sequence
355 PushByte(data_, 0);
356 PushByte(data_, 1);
357 PushByte(data_, DW_LNE_end_sequence);
358 }
359
360 private:
361 const int line_base_;
362 const int line_range_;
363 const int opcode_base_;
364 uintptr_t current_address_;
365 size_t current_line_;
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700366 unsigned current_file_index_;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700367
368 DISALLOW_COPY_AND_ASSIGN(LineTableGenerator);
369};
370
371// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
372static void GetLineInfoForJava(const uint8_t* dbgstream, const SrcMap& pc2dex,
373 SrcMap* result, uint32_t start_pc = 0) {
374 if (dbgstream == nullptr) {
375 return;
376 }
377
378 int adjopcode;
379 uint32_t dex_offset = 0;
380 uint32_t java_line = DecodeUnsignedLeb128(&dbgstream);
381
382 // skip parameters
383 for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) {
384 DecodeUnsignedLeb128(&dbgstream);
385 }
386
387 for (bool is_end = false; is_end == false; ) {
388 uint8_t opcode = *dbgstream;
389 dbgstream++;
390 switch (opcode) {
391 case DexFile::DBG_END_SEQUENCE:
392 is_end = true;
393 break;
394
395 case DexFile::DBG_ADVANCE_PC:
396 dex_offset += DecodeUnsignedLeb128(&dbgstream);
397 break;
398
399 case DexFile::DBG_ADVANCE_LINE:
400 java_line += DecodeSignedLeb128(&dbgstream);
401 break;
402
403 case DexFile::DBG_START_LOCAL:
404 case DexFile::DBG_START_LOCAL_EXTENDED:
405 DecodeUnsignedLeb128(&dbgstream);
406 DecodeUnsignedLeb128(&dbgstream);
407 DecodeUnsignedLeb128(&dbgstream);
408
409 if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) {
410 DecodeUnsignedLeb128(&dbgstream);
411 }
412 break;
413
414 case DexFile::DBG_END_LOCAL:
415 case DexFile::DBG_RESTART_LOCAL:
416 DecodeUnsignedLeb128(&dbgstream);
417 break;
418
419 case DexFile::DBG_SET_PROLOGUE_END:
420 case DexFile::DBG_SET_EPILOGUE_BEGIN:
421 case DexFile::DBG_SET_FILE:
422 break;
423
424 default:
425 adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
426 dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
427 java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
428
429 for (SrcMap::const_iterator found = pc2dex.FindByTo(dex_offset);
430 found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset);
431 found++) {
432 result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)});
433 }
434 break;
435 }
Andreas Gampe79273802014-08-05 20:21:05 -0700436 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800437}
438
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700439/*
440 * @brief Generate the DWARF debug_info and debug_abbrev sections
441 * @param oat_writer The Oat file Writer.
442 * @param dbg_info Compilation unit information.
443 * @param dbg_abbrev Abbreviations used to generate dbg_info.
444 * @param dbg_str Debug strings.
445 */
446static void FillInCFIInformation(OatWriter* oat_writer,
447 std::vector<uint8_t>* dbg_info,
448 std::vector<uint8_t>* dbg_abbrev,
449 std::vector<uint8_t>* dbg_str,
450 std::vector<uint8_t>* dbg_line,
451 uint32_t text_section_offset) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700452 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
453
454 uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
455
Mark Mendellae9fd932014-02-10 16:14:35 -0800456 // Create the debug_abbrev section with boilerplate information.
457 // We only care about low_pc and high_pc right now for the compilation
458 // unit and methods.
459
460 // Tag 1: Compilation unit: DW_TAG_compile_unit.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700461 PushByte(dbg_abbrev, 1);
462 PushByte(dbg_abbrev, DW_TAG_compile_unit);
Mark Mendellae9fd932014-02-10 16:14:35 -0800463
464 // There are children (the methods).
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700465 PushByte(dbg_abbrev, DW_CHILDREN_yes);
466
467 // DW_AT_producer DW_FORM_data1.
468 // REVIEW: we can get rid of dbg_str section if
469 // DW_FORM_string (immediate string) was used everywhere instead of
470 // DW_FORM_strp (ref to string from .debug_str section).
471 // DW_FORM_strp makes sense only if we reuse the strings.
472 PushByte(dbg_abbrev, DW_AT_producer);
473 PushByte(dbg_abbrev, DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800474
475 // DW_LANG_Java DW_FORM_data1.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700476 PushByte(dbg_abbrev, DW_AT_language);
477 PushByte(dbg_abbrev, DW_FORM_data1);
Mark Mendellae9fd932014-02-10 16:14:35 -0800478
479 // DW_AT_low_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700480 PushByte(dbg_abbrev, DW_AT_low_pc);
481 PushByte(dbg_abbrev, DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800482
483 // DW_AT_high_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700484 PushByte(dbg_abbrev, DW_AT_high_pc);
485 PushByte(dbg_abbrev, DW_FORM_addr);
486
487 if (dbg_line != nullptr) {
488 // DW_AT_stmt_list DW_FORM_sec_offset.
489 PushByte(dbg_abbrev, DW_AT_stmt_list);
490 PushByte(dbg_abbrev, DW_FORM_sec_offset);
491 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800492
493 // End of DW_TAG_compile_unit.
494 PushHalf(dbg_abbrev, 0);
495
496 // Tag 2: Compilation unit: DW_TAG_subprogram.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700497 PushByte(dbg_abbrev, 2);
498 PushByte(dbg_abbrev, DW_TAG_subprogram);
Mark Mendellae9fd932014-02-10 16:14:35 -0800499
500 // There are no children.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700501 PushByte(dbg_abbrev, DW_CHILDREN_no);
Mark Mendellae9fd932014-02-10 16:14:35 -0800502
503 // Name of the method.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700504 PushByte(dbg_abbrev, DW_AT_name);
505 PushByte(dbg_abbrev, DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800506
507 // DW_AT_low_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700508 PushByte(dbg_abbrev, DW_AT_low_pc);
509 PushByte(dbg_abbrev, DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800510
511 // DW_AT_high_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700512 PushByte(dbg_abbrev, DW_AT_high_pc);
513 PushByte(dbg_abbrev, DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800514
515 // End of DW_TAG_subprogram.
516 PushHalf(dbg_abbrev, 0);
517
518 // Start the debug_info section with the header information
519 // 'unit_length' will be filled in later.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700520 int cunit_length = dbg_info->size();
Mark Mendellae9fd932014-02-10 16:14:35 -0800521 PushWord(dbg_info, 0);
522
523 // 'version' - 3.
524 PushHalf(dbg_info, 3);
525
526 // Offset into .debug_abbrev section (always 0).
527 PushWord(dbg_info, 0);
528
529 // Address size: 4.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700530 PushByte(dbg_info, 4);
Mark Mendellae9fd932014-02-10 16:14:35 -0800531
532 // Start the description for the compilation unit.
533 // This uses tag 1.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700534 PushByte(dbg_info, 1);
535
536 // The producer is Android dex2oat.
537 PushWord(dbg_info, producer_str_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800538
539 // The language is Java.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700540 PushByte(dbg_info, DW_LANG_Java);
Mark Mendellae9fd932014-02-10 16:14:35 -0800541
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700542 // low_pc and high_pc.
543 uint32_t cunit_low_pc = 0 - 1;
544 uint32_t cunit_high_pc = 0;
545 int cunit_low_pc_pos = dbg_info->size();
Mark Mendellae9fd932014-02-10 16:14:35 -0800546 PushWord(dbg_info, 0);
547 PushWord(dbg_info, 0);
548
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700549 if (dbg_line == nullptr) {
550 for (size_t i = 0; i < method_info.size(); ++i) {
551 const OatWriter::DebugInfo &dbg = method_info[i];
Mark Mendellae9fd932014-02-10 16:14:35 -0800552
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700553 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
554 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
555
556 // Start a new TAG: subroutine (2).
557 PushByte(dbg_info, 2);
558
559 // Enter name, low_pc, high_pc.
560 PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
561 PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
562 PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800563 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700564 } else {
565 // TODO: in gdb info functions <regexp> - reports Java functions, but
566 // source file is <unknown> because .debug_line is formed as one
567 // compilation unit. To fix this it is possible to generate
568 // a separate compilation unit for every distinct Java source.
569 // Each of the these compilation units can have several non-adjacent
570 // method ranges.
571
572 // Line number table offset
573 PushWord(dbg_info, dbg_line->size());
574
575 size_t lnt_length = dbg_line->size();
576 PushWord(dbg_line, 0);
577
578 PushHalf(dbg_line, 4); // LNT Version DWARF v4 => 4
579
580 size_t lnt_hdr_length = dbg_line->size();
581 PushWord(dbg_line, 0); // TODO: 64-bit uses 8-byte here
582
583 PushByte(dbg_line, 1); // minimum_instruction_length (ubyte)
584 PushByte(dbg_line, 1); // maximum_operations_per_instruction (ubyte) = always 1
585 PushByte(dbg_line, 1); // default_is_stmt (ubyte)
586
587 const int8_t LINE_BASE = -5;
588 PushByte(dbg_line, LINE_BASE); // line_base (sbyte)
589
590 const uint8_t LINE_RANGE = 14;
591 PushByte(dbg_line, LINE_RANGE); // line_range (ubyte)
592
593 const uint8_t OPCODE_BASE = 13;
594 PushByte(dbg_line, OPCODE_BASE); // opcode_base (ubyte)
595
596 // Standard_opcode_lengths (array of ubyte).
597 PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1);
598 PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0);
599 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
600 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
601
602 PushByte(dbg_line, 0); // include_directories (sequence of path names) = EMPTY
603
604 // File_names (sequence of file entries).
605 std::unordered_map<const char*, size_t> files;
606 for (size_t i = 0; i < method_info.size(); ++i) {
607 const OatWriter::DebugInfo &dbg = method_info[i];
608 // TODO: add package directory to the file name
609 const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_;
610 auto found = files.find(file_name);
611 if (found == files.end()) {
612 size_t file_index = 1 + files.size();
613 files[file_name] = file_index;
614 PushStr(dbg_line, file_name);
615 PushByte(dbg_line, 0); // include directory index = LEB128(0) - no directory
616 PushByte(dbg_line, 0); // modification time = LEB128(0) - NA
617 PushByte(dbg_line, 0); // file length = LEB128(0) - NA
618 }
619 }
620 PushByte(dbg_line, 0); // End of file_names.
621
622 // Set lnt header length.
623 UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4);
624
625 // Generate Line Number Program code, one long program for all methods.
626 LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE,
627 dbg_line, 0, 1);
628
629 SrcMap pc2java_map;
630 for (size_t i = 0; i < method_info.size(); ++i) {
631 const OatWriter::DebugInfo &dbg = method_info[i];
632 const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_;
633 size_t file_index = files[file_name];
634 DCHECK_NE(file_index, 0U) << file_name;
635
636 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
637 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
638
639 // Start a new TAG: subroutine (2).
640 PushByte(dbg_info, 2);
641
642 // Enter name, low_pc, high_pc.
643 PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
644 PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
645 PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
646
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700647 GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(),
648 &pc2java_map, dbg.low_pc_);
649 pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_);
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700650 if (!pc2java_map.empty()) {
651 line_table_generator.SetFile(file_index);
652 line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset);
653 line_table_generator.SetLine(1);
654 for (auto& src_map_elem : pc2java_map) {
655 line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_);
656 }
657 pc2java_map.clear();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700658 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800659 }
660
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700661 // End Sequence should have the highest address set.
662 line_table_generator.SetAddr(cunit_high_pc + text_section_offset);
663 line_table_generator.EndSequence();
Mark Mendellae9fd932014-02-10 16:14:35 -0800664
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700665 // set lnt length
666 UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4);
Mark Mendellae9fd932014-02-10 16:14:35 -0800667 }
668
669 // One byte terminator
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700670 PushByte(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800671
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700672 // Fill in cunit's low_pc and high_pc.
673 UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset);
674 UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset);
675
676 // We have now walked all the methods. Fill in lengths.
677 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700678}
679
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700680template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
681 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
682 typename Elf_Phdr, typename Elf_Shdr>
683static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
684 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
685 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
686 OatWriter* oat_writer) {
687 std::unique_ptr<std::vector<uint8_t>> cfi_info(
688 ConstructCIEFrame(compiler_driver->GetInstructionSet()));
689
690 Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr;
691
692 // Iterate over the compiled methods.
693 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
694 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr,
695 Elf_Sym, Elf_Shdr>* symtab = &builder->symtab_builder_;
696 for (auto it = method_info.begin(); it != method_info.end(); ++it) {
697 symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true,
698 it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
699
700 // Include CFI for compiled method, if possible.
701 if (cfi_info.get() != nullptr) {
702 DCHECK(it->compiled_method_ != nullptr);
703
704 // Copy in the FDE, if present
705 const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
706 if (fde != nullptr) {
707 // Copy the information into cfi_info and then fix the address in the new copy.
708 int cur_offset = cfi_info->size();
709 cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
710
711 bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
712
713 // Set the 'CIE_pointer' field.
714 uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
715 uint64_t offset_to_update = CIE_pointer;
716 if (is_64bit) {
717 (*cfi_info)[offset_to_update+0] = CIE_pointer;
718 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
719 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
720 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
721 (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
722 (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
723 (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
724 (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
725 } else {
726 (*cfi_info)[offset_to_update+0] = CIE_pointer;
727 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
728 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
729 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
730 }
731
732 // Set the 'initial_location' field.
733 offset_to_update += is_64bit ? 8 : 4;
734 if (is_64bit) {
735 const uint64_t quick_code_start = it->low_pc_ + text_section_address;
736 (*cfi_info)[offset_to_update+0] = quick_code_start;
737 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
738 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
739 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
740 (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
741 (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
742 (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
743 (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
744 } else {
745 const uint32_t quick_code_start = it->low_pc_ + text_section_address;
746 (*cfi_info)[offset_to_update+0] = quick_code_start;
747 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
748 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
749 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
750 }
751 }
752 }
753 }
754
755 bool hasCFI = (cfi_info.get() != nullptr);
756 bool hasLineInfo = false;
757 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
758 if (dbg_info.dbgstream_ != nullptr &&
759 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
760 hasLineInfo = true;
761 break;
762 }
763 }
764
765 if (hasLineInfo || hasCFI) {
766 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
767 SHT_PROGBITS,
768 0, nullptr, 0, 1, 0);
769 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
770 SHT_PROGBITS,
771 0, nullptr, 0, 1, 0);
772 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
773 SHT_PROGBITS,
774 0, nullptr, 0, 1, 0);
775 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
776 SHT_PROGBITS,
777 0, nullptr, 0, 1, 0);
778
779 FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
780 debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
781 hasLineInfo ? debug_line.GetBuffer() : nullptr,
782 text_section_address);
783
784 builder->RegisterRawSection(debug_info);
785 builder->RegisterRawSection(debug_abbrev);
786
787 if (hasCFI) {
788 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
789 SHT_PROGBITS,
790 SHF_ALLOC,
791 nullptr, 0, 4, 0);
792 eh_frame.SetBuffer(std::move(*cfi_info.get()));
793 builder->RegisterRawSection(eh_frame);
794 }
795
796 if (hasLineInfo) {
797 builder->RegisterRawSection(debug_line);
798 }
799
800 builder->RegisterRawSection(debug_str);
801 }
802}
803
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000804// Explicit instantiations
805template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
806 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
807template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
808 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
809
Brian Carlstrom7940e442013-07-12 13:46:57 -0700810} // namespace art