elf_writer_quick.cc revision 8683038c1f59bea790d8c7691e40eed7f6250e4a
1/*
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
19#include <unordered_map>
20
21#include "base/logging.h"
22#include "base/unix_file/fd_file.h"
23#include "buffered_output_stream.h"
24#include "driver/compiler_driver.h"
25#include "dwarf.h"
26#include "elf_builder.h"
27#include "elf_file.h"
28#include "elf_utils.h"
29#include "file_output_stream.h"
30#include "globals.h"
31#include "leb128.h"
32#include "oat.h"
33#include "oat_writer.h"
34#include "utils.h"
35
36namespace art {
37
38static 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
62static 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
69static void PushHalf(std::vector<uint8_t>* buf, int data) {
70  buf->push_back(data & 0xff);
71  buf->push_back((data >> 8) & 0xff);
72}
73
74template <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,
78  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
79                            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
88std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) {
89  std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>;
90
91  // Length (will be filled in later in this routine).
92  if (is_x86_64) {
93    PushWord(cfi_info, 0xffffffff);  // Indicates 64bit
94    PushWord(cfi_info, 0);
95    PushWord(cfi_info, 0);
96  } else {
97    PushWord(cfi_info, 0);
98  }
99
100  // CIE id: always 0.
101  if (is_x86_64) {
102    PushWord(cfi_info, 0);
103    PushWord(cfi_info, 0);
104  } else {
105    PushWord(cfi_info, 0);
106  }
107
108  // Version: always 1.
109  cfi_info->push_back(0x01);
110
111  // Augmentation: 'zR\0'
112  cfi_info->push_back(0x7a);
113  cfi_info->push_back(0x52);
114  cfi_info->push_back(0x0);
115
116  // Code alignment: 1.
117  EncodeUnsignedLeb128(1, cfi_info);
118
119  // Data alignment.
120  if (is_x86_64) {
121    EncodeSignedLeb128(-8, cfi_info);
122  } else {
123    EncodeSignedLeb128(-4, cfi_info);
124  }
125
126  // Return address register.
127  if (is_x86_64) {
128    // R16(RIP)
129    cfi_info->push_back(0x10);
130  } else {
131    // R8(EIP)
132    cfi_info->push_back(0x08);
133  }
134
135  // Augmentation length: 1.
136  cfi_info->push_back(1);
137
138  // Augmentation data.
139  if (is_x86_64) {
140    // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8).
141    cfi_info->push_back(0x04);
142  } else {
143    // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4).
144    cfi_info->push_back(0x03);
145  }
146
147  // Initial instructions.
148  if (is_x86_64) {
149    // DW_CFA_def_cfa R7(RSP) 8.
150    cfi_info->push_back(0x0c);
151    cfi_info->push_back(0x07);
152    cfi_info->push_back(0x08);
153
154    // DW_CFA_offset R16(RIP) 1 (* -8).
155    cfi_info->push_back(0x90);
156    cfi_info->push_back(0x01);
157  } else {
158    // DW_CFA_def_cfa R4(ESP) 4.
159    cfi_info->push_back(0x0c);
160    cfi_info->push_back(0x04);
161    cfi_info->push_back(0x04);
162
163    // DW_CFA_offset R8(EIP) 1 (* -4).
164    cfi_info->push_back(0x88);
165    cfi_info->push_back(0x01);
166  }
167
168  // Padding to a multiple of 4
169  while ((cfi_info->size() & 3) != 0) {
170    // DW_CFA_nop is encoded as 0.
171    cfi_info->push_back(0);
172  }
173
174  // Set the length of the CIE inside the generated bytes.
175  if (is_x86_64) {
176    uint32_t length = cfi_info->size() - 12;
177    UpdateWord(cfi_info, 4, length);
178  } else {
179    uint32_t length = cfi_info->size() - 4;
180    UpdateWord(cfi_info, 0, length);
181  }
182  return cfi_info;
183}
184
185std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
186  switch (isa) {
187    case kX86:
188      return ConstructCIEFrameX86(false);
189    case kX86_64:
190      return ConstructCIEFrameX86(true);
191
192    default:
193      // Not implemented.
194      return nullptr;
195  }
196}
197
198class OatWriterWrapper FINAL : public CodeOutput {
199 public:
200  explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
201
202  void SetCodeOffset(size_t offset) {
203    oat_writer_->SetOatDataOffset(offset);
204  }
205  bool Write(OutputStream* out) OVERRIDE {
206    return oat_writer_->Write(out);
207  }
208 private:
209  OatWriter* const oat_writer_;
210};
211
212template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
213          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
214          typename Elf_Phdr, typename Elf_Shdr>
215static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
216                              ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
217                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
218                              OatWriter* oat_writer);
219
220template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
221          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
222          typename Elf_Phdr, typename Elf_Shdr>
223bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
224  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
225                           const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
226                           const std::string& android_root_unused ATTRIBUTE_UNUSED,
227                           bool is_host_unused ATTRIBUTE_UNUSED) {
228  constexpr bool debug = false;
229  const OatHeader& oat_header = oat_writer->GetOatHeader();
230  Elf_Word oat_data_size = oat_header.GetExecutableOffset();
231  uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
232
233  OatWriterWrapper wrapper(oat_writer);
234
235  std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
236                             Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
237      new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
238                     Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
239          &wrapper,
240          elf_file_,
241          compiler_driver_->GetInstructionSet(),
242          0,
243          oat_data_size,
244          oat_data_size,
245          oat_exec_size,
246          compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
247          debug));
248
249  if (!builder->Init()) {
250    return false;
251  }
252
253  if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
254    WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
255  }
256
257  if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
258    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
259        ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
260    const std::vector<uintptr_t>& locations = oat_writer->GetAbsolutePatchLocations();
261    const uint8_t* begin = reinterpret_cast<const uint8_t*>(&locations[0]);
262    const uint8_t* end = begin + locations.size() * sizeof(locations[0]);
263    oat_patches.GetBuffer()->assign(begin, end);
264    if (debug) {
265      LOG(INFO) << "Prepared .oat_patches for " << locations.size() << " patches.";
266    }
267    builder->RegisterRawSection(oat_patches);
268  }
269
270  return builder->Write();
271}
272
273class LineTableGenerator FINAL : public Leb128Encoder {
274 public:
275  LineTableGenerator(int line_base, int line_range, int opcode_base,
276                     std::vector<uint8_t>* data, uintptr_t current_address,
277                     size_t current_line)
278    : Leb128Encoder(data), line_base_(line_base), line_range_(line_range),
279      opcode_base_(opcode_base), current_address_(current_address),
280      current_line_(current_line), current_file_index_(0) {}
281
282  void PutDelta(unsigned delta_addr, int delta_line) {
283    current_line_ += delta_line;
284    current_address_ += delta_addr;
285
286    if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) {
287      unsigned special_opcode = (delta_line - line_base_) +
288                                (line_range_ * delta_addr) + opcode_base_;
289      if (special_opcode <= 255) {
290        PushByte(data_, special_opcode);
291        return;
292      }
293    }
294
295    // generate standart opcode for address advance
296    if (delta_addr != 0) {
297      PushByte(data_, DW_LNS_advance_pc);
298      PushBackUnsigned(delta_addr);
299    }
300
301    // generate standart opcode for line delta
302    if (delta_line != 0) {
303      PushByte(data_, DW_LNS_advance_line);
304      PushBackSigned(delta_line);
305    }
306
307    // generate standart opcode for new LTN entry
308    PushByte(data_, DW_LNS_copy);
309  }
310
311  void SetAddr(uintptr_t addr) {
312    if (current_address_ == addr) {
313      return;
314    }
315
316    current_address_ = addr;
317
318    PushByte(data_, 0);  // extended opcode:
319    PushByte(data_, 1 + 4);  // length: opcode_size + address_size
320    PushByte(data_, DW_LNE_set_address);
321    PushWord(data_, addr);
322  }
323
324  void SetLine(unsigned line) {
325    int delta_line = line - current_line_;
326    if (delta_line) {
327      current_line_ = line;
328      PushByte(data_, DW_LNS_advance_line);
329      PushBackSigned(delta_line);
330    }
331  }
332
333  void SetFile(unsigned file_index) {
334    if (current_file_index_ != file_index) {
335      current_file_index_ = file_index;
336      PushByte(data_, DW_LNS_set_file);
337      PushBackUnsigned(file_index);
338    }
339  }
340
341  void EndSequence() {
342    // End of Line Table Program
343    // 0(=ext), 1(len), DW_LNE_end_sequence
344    PushByte(data_, 0);
345    PushByte(data_, 1);
346    PushByte(data_, DW_LNE_end_sequence);
347  }
348
349 private:
350  const int line_base_;
351  const int line_range_;
352  const int opcode_base_;
353  uintptr_t current_address_;
354  size_t current_line_;
355  unsigned current_file_index_;
356
357  DISALLOW_COPY_AND_ASSIGN(LineTableGenerator);
358};
359
360// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
361static void GetLineInfoForJava(const uint8_t* dbgstream, const SrcMap& pc2dex,
362                               SrcMap* result, uint32_t start_pc = 0) {
363  if (dbgstream == nullptr) {
364    return;
365  }
366
367  int adjopcode;
368  uint32_t dex_offset = 0;
369  uint32_t java_line = DecodeUnsignedLeb128(&dbgstream);
370
371  // skip parameters
372  for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) {
373    DecodeUnsignedLeb128(&dbgstream);
374  }
375
376  for (bool is_end = false; is_end == false; ) {
377    uint8_t opcode = *dbgstream;
378    dbgstream++;
379    switch (opcode) {
380    case DexFile::DBG_END_SEQUENCE:
381      is_end = true;
382      break;
383
384    case DexFile::DBG_ADVANCE_PC:
385      dex_offset += DecodeUnsignedLeb128(&dbgstream);
386      break;
387
388    case DexFile::DBG_ADVANCE_LINE:
389      java_line += DecodeSignedLeb128(&dbgstream);
390      break;
391
392    case DexFile::DBG_START_LOCAL:
393    case DexFile::DBG_START_LOCAL_EXTENDED:
394      DecodeUnsignedLeb128(&dbgstream);
395      DecodeUnsignedLeb128(&dbgstream);
396      DecodeUnsignedLeb128(&dbgstream);
397
398      if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) {
399        DecodeUnsignedLeb128(&dbgstream);
400      }
401      break;
402
403    case DexFile::DBG_END_LOCAL:
404    case DexFile::DBG_RESTART_LOCAL:
405      DecodeUnsignedLeb128(&dbgstream);
406      break;
407
408    case DexFile::DBG_SET_PROLOGUE_END:
409    case DexFile::DBG_SET_EPILOGUE_BEGIN:
410    case DexFile::DBG_SET_FILE:
411      break;
412
413    default:
414      adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
415      dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
416      java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
417
418      for (SrcMap::const_iterator found = pc2dex.FindByTo(dex_offset);
419          found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset);
420          found++) {
421        result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)});
422      }
423      break;
424    }
425  }
426}
427
428/*
429 * @brief Generate the DWARF debug_info and debug_abbrev sections
430 * @param oat_writer The Oat file Writer.
431 * @param dbg_info Compilation unit information.
432 * @param dbg_abbrev Abbreviations used to generate dbg_info.
433 * @param dbg_str Debug strings.
434 */
435static void FillInCFIInformation(OatWriter* oat_writer,
436                                 std::vector<uint8_t>* dbg_info,
437                                 std::vector<uint8_t>* dbg_abbrev,
438                                 std::vector<uint8_t>* dbg_str,
439                                 std::vector<uint8_t>* dbg_line,
440                                 uint32_t text_section_offset) {
441  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
442
443  uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
444
445  // Create the debug_abbrev section with boilerplate information.
446  // We only care about low_pc and high_pc right now for the compilation
447  // unit and methods.
448
449  // Tag 1: Compilation unit: DW_TAG_compile_unit.
450  PushByte(dbg_abbrev, 1);
451  PushByte(dbg_abbrev, DW_TAG_compile_unit);
452
453  // There are children (the methods).
454  PushByte(dbg_abbrev, DW_CHILDREN_yes);
455
456  // DW_AT_producer DW_FORM_data1.
457  // REVIEW: we can get rid of dbg_str section if
458  // DW_FORM_string (immediate string) was used everywhere instead of
459  // DW_FORM_strp (ref to string from .debug_str section).
460  // DW_FORM_strp makes sense only if we reuse the strings.
461  PushByte(dbg_abbrev, DW_AT_producer);
462  PushByte(dbg_abbrev, DW_FORM_strp);
463
464  // DW_LANG_Java DW_FORM_data1.
465  PushByte(dbg_abbrev, DW_AT_language);
466  PushByte(dbg_abbrev, DW_FORM_data1);
467
468  // DW_AT_low_pc DW_FORM_addr.
469  PushByte(dbg_abbrev, DW_AT_low_pc);
470  PushByte(dbg_abbrev, DW_FORM_addr);
471
472  // DW_AT_high_pc DW_FORM_addr.
473  PushByte(dbg_abbrev, DW_AT_high_pc);
474  PushByte(dbg_abbrev, DW_FORM_addr);
475
476  if (dbg_line != nullptr) {
477    // DW_AT_stmt_list DW_FORM_sec_offset.
478    PushByte(dbg_abbrev, DW_AT_stmt_list);
479    PushByte(dbg_abbrev, DW_FORM_sec_offset);
480  }
481
482  // End of DW_TAG_compile_unit.
483  PushHalf(dbg_abbrev, 0);
484
485  // Tag 2: Compilation unit: DW_TAG_subprogram.
486  PushByte(dbg_abbrev, 2);
487  PushByte(dbg_abbrev, DW_TAG_subprogram);
488
489  // There are no children.
490  PushByte(dbg_abbrev, DW_CHILDREN_no);
491
492  // Name of the method.
493  PushByte(dbg_abbrev, DW_AT_name);
494  PushByte(dbg_abbrev, DW_FORM_strp);
495
496  // DW_AT_low_pc DW_FORM_addr.
497  PushByte(dbg_abbrev, DW_AT_low_pc);
498  PushByte(dbg_abbrev, DW_FORM_addr);
499
500  // DW_AT_high_pc DW_FORM_addr.
501  PushByte(dbg_abbrev, DW_AT_high_pc);
502  PushByte(dbg_abbrev, DW_FORM_addr);
503
504  // End of DW_TAG_subprogram.
505  PushHalf(dbg_abbrev, 0);
506
507  // Start the debug_info section with the header information
508  // 'unit_length' will be filled in later.
509  int cunit_length = dbg_info->size();
510  PushWord(dbg_info, 0);
511
512  // 'version' - 3.
513  PushHalf(dbg_info, 3);
514
515  // Offset into .debug_abbrev section (always 0).
516  PushWord(dbg_info, 0);
517
518  // Address size: 4.
519  PushByte(dbg_info, 4);
520
521  // Start the description for the compilation unit.
522  // This uses tag 1.
523  PushByte(dbg_info, 1);
524
525  // The producer is Android dex2oat.
526  PushWord(dbg_info, producer_str_offset);
527
528  // The language is Java.
529  PushByte(dbg_info, DW_LANG_Java);
530
531  // low_pc and high_pc.
532  uint32_t cunit_low_pc = 0 - 1;
533  uint32_t cunit_high_pc = 0;
534  int cunit_low_pc_pos = dbg_info->size();
535  PushWord(dbg_info, 0);
536  PushWord(dbg_info, 0);
537
538  if (dbg_line == nullptr) {
539    for (size_t i = 0; i < method_info.size(); ++i) {
540      const OatWriter::DebugInfo &dbg = method_info[i];
541
542      cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
543      cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
544
545      // Start a new TAG: subroutine (2).
546      PushByte(dbg_info, 2);
547
548      // Enter name, low_pc, high_pc.
549      PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
550      PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
551      PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
552    }
553  } else {
554    // TODO: in gdb info functions <regexp> - reports Java functions, but
555    // source file is <unknown> because .debug_line is formed as one
556    // compilation unit. To fix this it is possible to generate
557    // a separate compilation unit for every distinct Java source.
558    // Each of the these compilation units can have several non-adjacent
559    // method ranges.
560
561    // Line number table offset
562    PushWord(dbg_info, dbg_line->size());
563
564    size_t lnt_length = dbg_line->size();
565    PushWord(dbg_line, 0);
566
567    PushHalf(dbg_line, 4);  // LNT Version DWARF v4 => 4
568
569    size_t lnt_hdr_length = dbg_line->size();
570    PushWord(dbg_line, 0);  // TODO: 64-bit uses 8-byte here
571
572    PushByte(dbg_line, 1);  // minimum_instruction_length (ubyte)
573    PushByte(dbg_line, 1);  // maximum_operations_per_instruction (ubyte) = always 1
574    PushByte(dbg_line, 1);  // default_is_stmt (ubyte)
575
576    const int8_t LINE_BASE = -5;
577    PushByte(dbg_line, LINE_BASE);  // line_base (sbyte)
578
579    const uint8_t LINE_RANGE = 14;
580    PushByte(dbg_line, LINE_RANGE);  // line_range (ubyte)
581
582    const uint8_t OPCODE_BASE = 13;
583    PushByte(dbg_line, OPCODE_BASE);  // opcode_base (ubyte)
584
585    // Standard_opcode_lengths (array of ubyte).
586    PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1);
587    PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0);
588    PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
589    PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
590
591    PushByte(dbg_line, 0);  // include_directories (sequence of path names) = EMPTY
592
593    // File_names (sequence of file entries).
594    std::unordered_map<const char*, size_t> files;
595    for (size_t i = 0; i < method_info.size(); ++i) {
596      const OatWriter::DebugInfo &dbg = method_info[i];
597      // TODO: add package directory to the file name
598      const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_;
599      auto found = files.find(file_name);
600      if (found == files.end()) {
601        size_t file_index = 1 + files.size();
602        files[file_name] = file_index;
603        PushStr(dbg_line, file_name);
604        PushByte(dbg_line, 0);  // include directory index = LEB128(0) - no directory
605        PushByte(dbg_line, 0);  // modification time = LEB128(0) - NA
606        PushByte(dbg_line, 0);  // file length = LEB128(0) - NA
607      }
608    }
609    PushByte(dbg_line, 0);  // End of file_names.
610
611    // Set lnt header length.
612    UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4);
613
614    // Generate Line Number Program code, one long program for all methods.
615    LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE,
616                                            dbg_line, 0, 1);
617
618    SrcMap pc2java_map;
619    for (size_t i = 0; i < method_info.size(); ++i) {
620      const OatWriter::DebugInfo &dbg = method_info[i];
621      const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_;
622      size_t file_index = files[file_name];
623      DCHECK_NE(file_index, 0U) << file_name;
624
625      cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
626      cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
627
628      // Start a new TAG: subroutine (2).
629      PushByte(dbg_info, 2);
630
631      // Enter name, low_pc, high_pc.
632      PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
633      PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
634      PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
635
636      GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(),
637                         &pc2java_map, dbg.low_pc_);
638      pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_);
639      if (!pc2java_map.empty()) {
640        line_table_generator.SetFile(file_index);
641        line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset);
642        line_table_generator.SetLine(1);
643        for (auto& src_map_elem : pc2java_map) {
644          line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_);
645        }
646        pc2java_map.clear();
647      }
648    }
649
650    // End Sequence should have the highest address set.
651    line_table_generator.SetAddr(cunit_high_pc + text_section_offset);
652    line_table_generator.EndSequence();
653
654    // set lnt length
655    UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4);
656  }
657
658  // One byte terminator
659  PushByte(dbg_info, 0);
660
661  // Fill in cunit's low_pc and high_pc.
662  UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset);
663  UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset);
664
665  // We have now walked all the methods.  Fill in lengths.
666  UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
667}
668
669template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
670          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
671          typename Elf_Phdr, typename Elf_Shdr>
672// Do not inline to avoid Clang stack frame problems. b/18738594
673NO_INLINE
674static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
675                              ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
676                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
677                              OatWriter* oat_writer) {
678  std::unique_ptr<std::vector<uint8_t>> cfi_info(
679      ConstructCIEFrame(compiler_driver->GetInstructionSet()));
680
681  Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
682
683  // Iterate over the compiled methods.
684  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
685  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
686      builder->GetSymtabBuilder();
687  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
688    symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), it->low_pc_, true,
689                      it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
690
691    // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
692    // instructions, so that disassembler tools can correctly disassemble.
693    if (it->compiled_method_->GetInstructionSet() == kThumb2) {
694      symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true,
695                        0, STB_LOCAL, STT_NOTYPE);
696    }
697
698    // Include CFI for compiled method, if possible.
699    if (cfi_info.get() != nullptr) {
700      DCHECK(it->compiled_method_ != nullptr);
701
702      // Copy in the FDE, if present
703      const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
704      if (fde != nullptr) {
705        // Copy the information into cfi_info and then fix the address in the new copy.
706        int cur_offset = cfi_info->size();
707        cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
708
709        bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
710
711        // Set the 'CIE_pointer' field.
712        uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
713        uint64_t offset_to_update = CIE_pointer;
714        if (is_64bit) {
715          (*cfi_info)[offset_to_update+0] = CIE_pointer;
716          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
717          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
718          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
719          (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
720          (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
721          (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
722          (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
723        } else {
724          (*cfi_info)[offset_to_update+0] = CIE_pointer;
725          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
726          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
727          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
728        }
729
730        // Set the 'initial_location' field.
731        offset_to_update += is_64bit ? 8 : 4;
732        if (is_64bit) {
733          const uint64_t quick_code_start = it->low_pc_ + text_section_address;
734          (*cfi_info)[offset_to_update+0] = quick_code_start;
735          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
736          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
737          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
738          (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
739          (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
740          (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
741          (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
742        } else {
743          const uint32_t quick_code_start = it->low_pc_ + text_section_address;
744          (*cfi_info)[offset_to_update+0] = quick_code_start;
745          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
746          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
747          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
748        }
749      }
750    }
751  }
752
753  bool hasCFI = (cfi_info.get() != nullptr);
754  bool hasLineInfo = false;
755  for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
756    if (dbg_info.dbgstream_ != nullptr &&
757        !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
758      hasLineInfo = true;
759      break;
760    }
761  }
762
763  if (hasLineInfo || hasCFI) {
764    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
765                                                                   SHT_PROGBITS,
766                                                                   0, nullptr, 0, 1, 0);
767    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
768                                                                     SHT_PROGBITS,
769                                                                     0, nullptr, 0, 1, 0);
770    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
771                                                                  SHT_PROGBITS,
772                                                                  0, nullptr, 0, 1, 0);
773    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
774                                                                   SHT_PROGBITS,
775                                                                   0, nullptr, 0, 1, 0);
776
777    FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
778                         debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
779                         hasLineInfo ? debug_line.GetBuffer() : nullptr,
780                         text_section_address);
781
782    builder->RegisterRawSection(debug_info);
783    builder->RegisterRawSection(debug_abbrev);
784
785    if (hasCFI) {
786      ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
787                                                                   SHT_PROGBITS,
788                                                                   SHF_ALLOC,
789                                                                   nullptr, 0, 4, 0);
790      eh_frame.SetBuffer(std::move(*cfi_info.get()));
791      builder->RegisterRawSection(eh_frame);
792    }
793
794    if (hasLineInfo) {
795      builder->RegisterRawSection(debug_line);
796    }
797
798    builder->RegisterRawSection(debug_str);
799  }
800}
801
802// Explicit instantiations
803template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
804                              Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
805template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
806                              Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
807
808}  // namespace art
809