elf_writer_quick.cc revision 54fc26c7350beb782d042ba61cb06284b3a367e4
16a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom/*
26a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Copyright (C) 2012 The Android Open Source Project
36a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *
46a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
56a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * you may not use this file except in compliance with the License.
66a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * You may obtain a copy of the License at
76a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *
86a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
96a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *
106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * See the License for the specific language governing permissions and
146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * limitations under the License.
156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom */
166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "elf_writer_quick.h"
186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
19e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban#include <unordered_map>
20e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/logging.h"
226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/unix_file/fd_file.h"
23c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom#include "buffered_output_stream.h"
247940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h"
253470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light#include "dwarf.h"
2654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe#include "elf_builder.h"
27e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban#include "elf_file.h"
2850cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#include "elf_utils.h"
29c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "file_output_stream.h"
306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "globals.h"
3179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe#include "leb128.h"
326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "oat.h"
33c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "oat_writer.h"
346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "utils.h"
356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art {
376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
38e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanstatic void PushByte(std::vector<uint8_t>* buf, int data) {
39e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  buf->push_back(data & 0xff);
40e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban}
41e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
42e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanstatic uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) {
43e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (str == nullptr) {
44e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    str = def;
45e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
46e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
47e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t offset = buf->size();
48e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  for (size_t i = 0; str[i] != '\0'; ++i) {
49e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    buf->push_back(str[i]);
50e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
51e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  buf->push_back('\0');
52e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  return offset;
53e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban}
54e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
55e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanstatic uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) {
56e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t offset = buf->size();
57e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  buf->insert(buf->end(), str.begin(), str.end());
58e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  buf->push_back('\0');
59e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  return offset;
60e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban}
61e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
6279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampestatic void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) {
6379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  (*buf)[offset+0] = data;
6479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  (*buf)[offset+1] = data >> 8;
6579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  (*buf)[offset+2] = data >> 16;
6679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  (*buf)[offset+3] = data >> 24;
6779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe}
6879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
6979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampestatic void PushHalf(std::vector<uint8_t>* buf, int data) {
7079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  buf->push_back(data & 0xff);
7179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  buf->push_back((data >> 8) & 0xff);
7279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe}
7379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
74f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffraytemplate <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
75f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
76f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray          typename Elf_Phdr, typename Elf_Shdr>
77f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffraybool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
78f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
79b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            OatWriter* oat_writer,
80b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            const std::vector<const DexFile*>& dex_files,
81b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            const std::string& android_root,
82b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            bool is_host,
83b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                            const CompilerDriver& driver) {
84b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  ElfWriterQuick elf_writer(driver, elf_file);
85b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
86b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom}
87b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
88f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray// Add patch information to this section. Each patch is a Elf_Word that
8953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light// identifies an offset from the start of the text section
9054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampestatic void ReservePatchSpace(const CompilerDriver* compiler_driver, std::vector<uint8_t>* buffer,
9154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                              bool debug) {
9253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  size_t size =
9354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      compiler_driver->GetCodeToPatch().size() +
9454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      compiler_driver->GetMethodsToPatch().size() +
9554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      compiler_driver->GetClassesToPatch().size();
9653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (size == 0) {
9753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    if (debug) {
9853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      LOG(INFO) << "No patches to record";
9953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    }
10053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    return;
10153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
10253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  buffer->resize(size * sizeof(uintptr_t));
10353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (debug) {
10453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    LOG(INFO) << "Patches reserved for " << size;
10553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
10653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light}
10753cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
10879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampestd::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) {
109e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>;
11079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
11179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Length (will be filled in later in this routine).
112e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (is_x86_64) {
113e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0xffffffff);  // Indicates 64bit
114e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0);
115e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0);
116e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  } else {
117e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0);
118e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
11979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
12079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // CIE id: always 0.
121e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (is_x86_64) {
122e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0);
123e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0);
124e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  } else {
125e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(cfi_info, 0);
126e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
12779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
12879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Version: always 1.
12979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  cfi_info->push_back(0x01);
13079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
13179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Augmentation: 'zR\0'
13279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  cfi_info->push_back(0x7a);
13379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  cfi_info->push_back(0x52);
13479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  cfi_info->push_back(0x0);
13579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
13679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Code alignment: 1.
13779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  EncodeUnsignedLeb128(1, cfi_info);
13879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
13979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Data alignment.
14079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  if (is_x86_64) {
14179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    EncodeSignedLeb128(-8, cfi_info);
14279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  } else {
14379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    EncodeSignedLeb128(-4, cfi_info);
14479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  }
14579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
14679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Return address register.
14779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  if (is_x86_64) {
14879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // R16(RIP)
14979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x10);
15079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  } else {
15179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // R8(EIP)
15279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x08);
15379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  }
15479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
15579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Augmentation length: 1.
15679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  cfi_info->push_back(1);
15779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
158e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // Augmentation data.
159e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (is_x86_64) {
160e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8).
161e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    cfi_info->push_back(0x04);
162e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  } else {
163e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4).
164e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    cfi_info->push_back(0x03);
165e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
16679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
16779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Initial instructions.
16879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  if (is_x86_64) {
16979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // DW_CFA_def_cfa R7(RSP) 8.
17079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x0c);
17179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x07);
17279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x08);
17379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
17479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // DW_CFA_offset R16(RIP) 1 (* -8).
17579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x90);
17679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x01);
17779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  } else {
17879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // DW_CFA_def_cfa R4(ESP) 4.
17979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x0c);
18079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x04);
18179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x04);
18279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
18379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // DW_CFA_offset R8(EIP) 1 (* -4).
18479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x88);
18579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0x01);
18679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  }
18779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
18879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Padding to a multiple of 4
18979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  while ((cfi_info->size() & 3) != 0) {
19079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    // DW_CFA_nop is encoded as 0.
19179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    cfi_info->push_back(0);
19279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  }
19379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
19479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  // Set the length of the CIE inside the generated bytes.
195e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (is_x86_64) {
196e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    uint32_t length = cfi_info->size() - 12;
197e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    UpdateWord(cfi_info, 4, length);
198e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  } else {
199e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    uint32_t length = cfi_info->size() - 4;
200e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    UpdateWord(cfi_info, 0, length);
201e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
20279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  return cfi_info;
20379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe}
20479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
20579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampestd::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
20679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  switch (isa) {
20779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    case kX86:
20879273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe      return ConstructCIEFrameX86(false);
20979273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    case kX86_64:
21079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe      return ConstructCIEFrameX86(true);
21179273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
21279273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe    default:
21379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe      // Not implemented.
21479273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe      return nullptr;
21579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  }
21679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe}
21779273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe
21854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampeclass OatWriterWrapper : public CodeOutput {
21954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe public:
22054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
22154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
22254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  bool Write(OutputStream* out) OVERRIDE {
22354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    return oat_writer_->Write(out);
22454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  }
22554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe private:
22654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  OatWriter* oat_writer_;
22754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe};
22854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
22954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampetemplate <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
23054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
23154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          typename Elf_Phdr, typename Elf_Shdr>
23254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampestatic void WriteDebugSymbols(const CompilerDriver* compiler_driver,
23354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                              ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
23454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
23554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                              OatWriter* oat_writer);
23654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
237f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffraytemplate <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
238f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
239f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray          typename Elf_Phdr, typename Elf_Shdr>
240f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffraybool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
241f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray  Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
242b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                           const std::vector<const DexFile*>& dex_files_unused,
243b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                           const std::string& android_root_unused,
244b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom                           bool is_host_unused) {
24579273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  constexpr bool debug = false;
246b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  const OatHeader& oat_header = oat_writer->GetOatHeader();
247f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray  Elf_Word oat_data_size = oat_header.GetExecutableOffset();
248b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
249b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
25054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  OatWriterWrapper wrapper(oat_writer);
25154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
25254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
25354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                             Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
25454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
25554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                     Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
25654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          &wrapper,
25754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          elf_file_,
25854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          compiler_driver_->GetInstructionSet(),
25954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          0,
26054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          oat_data_size,
26154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          oat_data_size,
26254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          oat_exec_size,
26354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
26454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          debug));
26518a49cc2f956dec648e0a13186d42374023d47a7Brian Carlstrom
26618a49cc2f956dec648e0a13186d42374023d47a7Brian Carlstrom  if (!builder->Init()) {
267e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    return false;
268e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
269e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
27079273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
27154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
2726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom  }
2736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
27453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
27554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
27654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
27754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    ReservePatchSpace(compiler_driver_, oat_patches.GetBuffer(), debug);
27818a49cc2f956dec648e0a13186d42374023d47a7Brian Carlstrom    builder->RegisterRawSection(oat_patches);
27953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
28053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
28118a49cc2f956dec648e0a13186d42374023d47a7Brian Carlstrom  return builder->Write();
282b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom}
283ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
284e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanclass LineTableGenerator FINAL : public Leb128Encoder {
285e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban public:
286e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  LineTableGenerator(int line_base, int line_range, int opcode_base,
287e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban                     std::vector<uint8_t>* data, uintptr_t current_address,
288e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban                     size_t current_line)
289e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    : Leb128Encoder(data), line_base_(line_base), line_range_(line_range),
290e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      opcode_base_(opcode_base), current_address_(current_address),
29133ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban      current_line_(current_line), current_file_index_(0) {}
292e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
293e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  void PutDelta(unsigned delta_addr, int delta_line) {
294e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    current_line_ += delta_line;
295e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    current_address_ += delta_addr;
296e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
297e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) {
298e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      unsigned special_opcode = (delta_line - line_base_) +
299e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban                                (line_range_ * delta_addr) + opcode_base_;
300e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      if (special_opcode <= 255) {
301e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        PushByte(data_, special_opcode);
302e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        return;
303e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      }
304e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
305e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
306e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // generate standart opcode for address advance
307e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    if (delta_addr != 0) {
308e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushByte(data_, DW_LNS_advance_pc);
309e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushBackUnsigned(delta_addr);
310e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
311e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
312e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // generate standart opcode for line delta
313e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    if (delta_line != 0) {
314e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushByte(data_, DW_LNS_advance_line);
315e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushBackSigned(delta_line);
316e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
317e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
318e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // generate standart opcode for new LTN entry
319e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, DW_LNS_copy);
320e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
321e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
322e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  void SetAddr(uintptr_t addr) {
323e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    if (current_address_ == addr) {
324e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      return;
325e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
326e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
327e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    current_address_ = addr;
328e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
329e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, 0);  // extended opcode:
330e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, 1 + 4);  // length: opcode_size + address_size
331e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, DW_LNE_set_address);
332e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(data_, addr);
333e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
334e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
335e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  void SetLine(unsigned line) {
336e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    int delta_line = line - current_line_;
337e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    if (delta_line) {
338e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      current_line_ = line;
339e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushByte(data_, DW_LNS_advance_line);
340e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushBackSigned(delta_line);
341e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
342e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
343e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
344e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  void SetFile(unsigned file_index) {
34533ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban    if (current_file_index_ != file_index) {
34633ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban      current_file_index_ = file_index;
34733ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban      PushByte(data_, DW_LNS_set_file);
34833ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban      PushBackUnsigned(file_index);
34933ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban    }
350e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
351e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
352e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  void EndSequence() {
353e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // End of Line Table Program
354e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // 0(=ext), 1(len), DW_LNE_end_sequence
355e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, 0);
356e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, 1);
357e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(data_, DW_LNE_end_sequence);
358e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
359e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
360e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban private:
361e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  const int line_base_;
362e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  const int line_range_;
363e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  const int opcode_base_;
364e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uintptr_t current_address_;
365e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  size_t current_line_;
36633ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban  unsigned current_file_index_;
367e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
368e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  DISALLOW_COPY_AND_ASSIGN(LineTableGenerator);
369e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban};
370e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
371e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
372e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Roubanstatic void GetLineInfoForJava(const uint8_t* dbgstream, const SrcMap& pc2dex,
373e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban                               SrcMap* result, uint32_t start_pc = 0) {
374e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (dbgstream == nullptr) {
375e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    return;
376e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
377e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
378e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  int adjopcode;
379e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t dex_offset = 0;
380e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t java_line = DecodeUnsignedLeb128(&dbgstream);
381e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
382e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // skip parameters
383e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) {
384e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    DecodeUnsignedLeb128(&dbgstream);
385e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
386e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
387e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  for (bool is_end = false; is_end == false; ) {
388e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    uint8_t opcode = *dbgstream;
389e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    dbgstream++;
390e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    switch (opcode) {
391e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_END_SEQUENCE:
392e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      is_end = true;
393e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
394e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
395e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_ADVANCE_PC:
396e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      dex_offset += DecodeUnsignedLeb128(&dbgstream);
397e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
398e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
399e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_ADVANCE_LINE:
400e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      java_line += DecodeSignedLeb128(&dbgstream);
401e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
402e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
403e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_START_LOCAL:
404e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_START_LOCAL_EXTENDED:
405e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      DecodeUnsignedLeb128(&dbgstream);
406e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      DecodeUnsignedLeb128(&dbgstream);
407e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      DecodeUnsignedLeb128(&dbgstream);
408e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
409e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) {
410e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        DecodeUnsignedLeb128(&dbgstream);
411e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      }
412e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
413e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
414e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_END_LOCAL:
415e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_RESTART_LOCAL:
416e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      DecodeUnsignedLeb128(&dbgstream);
417e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
418e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
419e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_SET_PROLOGUE_END:
420e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_SET_EPILOGUE_BEGIN:
421e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    case DexFile::DBG_SET_FILE:
422e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
423e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
424e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    default:
425e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
426e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
427e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
428e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
429e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      for (SrcMap::const_iterator found = pc2dex.FindByTo(dex_offset);
430e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban          found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset);
431e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban          found++) {
432e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)});
433e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      }
434e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      break;
435e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
43679273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe  }
437ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell}
438ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
43954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe/*
44054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe * @brief Generate the DWARF debug_info and debug_abbrev sections
44154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe * @param oat_writer The Oat file Writer.
44254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe * @param dbg_info Compilation unit information.
44354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe * @param dbg_abbrev Abbreviations used to generate dbg_info.
44454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe * @param dbg_str Debug strings.
44554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe */
44654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampestatic void FillInCFIInformation(OatWriter* oat_writer,
44754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                 std::vector<uint8_t>* dbg_info,
44854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                 std::vector<uint8_t>* dbg_abbrev,
44954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                 std::vector<uint8_t>* dbg_str,
45054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                 std::vector<uint8_t>* dbg_line,
45154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                 uint32_t text_section_offset) {
452e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
453e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
454e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
455e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
456ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Create the debug_abbrev section with boilerplate information.
457ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // We only care about low_pc and high_pc right now for the compilation
458ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // unit and methods.
459ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
460ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Tag 1: Compilation unit: DW_TAG_compile_unit.
461e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, 1);
462e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_TAG_compile_unit);
463ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
464ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // There are children (the methods).
465e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_CHILDREN_yes);
466e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
467e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // DW_AT_producer DW_FORM_data1.
468e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // REVIEW: we can get rid of dbg_str section if
469e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // DW_FORM_string (immediate string) was used everywhere instead of
470e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // DW_FORM_strp (ref to string from .debug_str section).
471e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // DW_FORM_strp makes sense only if we reuse the strings.
472e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_producer);
473e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_strp);
474ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
475ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // DW_LANG_Java DW_FORM_data1.
476e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_language);
477e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_data1);
478ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
479ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // DW_AT_low_pc DW_FORM_addr.
480e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_low_pc);
481e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_addr);
482ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
483ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // DW_AT_high_pc DW_FORM_addr.
484e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_high_pc);
485e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_addr);
486e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
487e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (dbg_line != nullptr) {
488e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // DW_AT_stmt_list DW_FORM_sec_offset.
489e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_abbrev, DW_AT_stmt_list);
490e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_abbrev, DW_FORM_sec_offset);
491e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  }
492ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
493ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // End of DW_TAG_compile_unit.
494ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushHalf(dbg_abbrev, 0);
495ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
496ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Tag 2: Compilation unit: DW_TAG_subprogram.
497e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, 2);
498e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_TAG_subprogram);
499ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
500ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // There are no children.
501e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_CHILDREN_no);
502ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
503ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Name of the method.
504e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_name);
505e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_strp);
506ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
507ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // DW_AT_low_pc DW_FORM_addr.
508e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_low_pc);
509e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_addr);
510ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
511ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // DW_AT_high_pc DW_FORM_addr.
512e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_AT_high_pc);
513e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_abbrev, DW_FORM_addr);
514ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
515ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // End of DW_TAG_subprogram.
516ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushHalf(dbg_abbrev, 0);
517ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
518ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Start the debug_info section with the header information
519ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // 'unit_length' will be filled in later.
520e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  int cunit_length = dbg_info->size();
521ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushWord(dbg_info, 0);
522ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
523ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // 'version' - 3.
524ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushHalf(dbg_info, 3);
525ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
526ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Offset into .debug_abbrev section (always 0).
527ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushWord(dbg_info, 0);
528ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
529ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Address size: 4.
530e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_info, 4);
531ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
532ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // Start the description for the compilation unit.
533ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // This uses tag 1.
534e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_info, 1);
535e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
536e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // The producer is Android dex2oat.
537e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushWord(dbg_info, producer_str_offset);
538ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
539ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // The language is Java.
540e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_info, DW_LANG_Java);
541ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
542e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // low_pc and high_pc.
543e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t cunit_low_pc = 0 - 1;
544e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  uint32_t cunit_high_pc = 0;
545e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  int cunit_low_pc_pos = dbg_info->size();
546ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushWord(dbg_info, 0);
547ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  PushWord(dbg_info, 0);
548ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
549e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  if (dbg_line == nullptr) {
550e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    for (size_t i = 0; i < method_info.size(); ++i) {
551e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      const OatWriter::DebugInfo &dbg = method_info[i];
552e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
553e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
554e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
555e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
556e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      // Start a new TAG: subroutine (2).
557e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushByte(dbg_info, 2);
558ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
559e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      // Enter name, low_pc, high_pc.
560e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
561e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
562e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
563ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    }
564e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  } else {
565e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // TODO: in gdb info functions <regexp> - reports Java functions, but
566e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // source file is <unknown> because .debug_line is formed as one
567e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // compilation unit. To fix this it is possible to generate
568e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // a separate compilation unit for every distinct Java source.
569e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // Each of the these compilation units can have several non-adjacent
570e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // method ranges.
571e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
572e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // Line number table offset
573e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(dbg_info, dbg_line->size());
574e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
575e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    size_t lnt_length = dbg_line->size();
576e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(dbg_line, 0);
577e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
578e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushHalf(dbg_line, 4);  // LNT Version DWARF v4 => 4
579e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
580e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    size_t lnt_hdr_length = dbg_line->size();
581e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushWord(dbg_line, 0);  // TODO: 64-bit uses 8-byte here
582e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
583e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 1);  // minimum_instruction_length (ubyte)
584e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 1);  // maximum_operations_per_instruction (ubyte) = always 1
585e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 1);  // default_is_stmt (ubyte)
586e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
587e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    const int8_t LINE_BASE = -5;
588e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, LINE_BASE);  // line_base (sbyte)
589e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
590e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    const uint8_t LINE_RANGE = 14;
591e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, LINE_RANGE);  // line_range (ubyte)
592e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
593e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    const uint8_t OPCODE_BASE = 13;
594e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, OPCODE_BASE);  // opcode_base (ubyte)
595e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
596e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // Standard_opcode_lengths (array of ubyte).
597e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1);
598e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0);
599e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
600e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
601e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
602e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 0);  // include_directories (sequence of path names) = EMPTY
603e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
604e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // File_names (sequence of file entries).
605e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    std::unordered_map<const char*, size_t> files;
606e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    for (size_t i = 0; i < method_info.size(); ++i) {
607e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      const OatWriter::DebugInfo &dbg = method_info[i];
608e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      // TODO: add package directory to the file name
609e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_;
610e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      auto found = files.find(file_name);
611e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      if (found == files.end()) {
612e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        size_t file_index = 1 + files.size();
613e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        files[file_name] = file_index;
614e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        PushStr(dbg_line, file_name);
615e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        PushByte(dbg_line, 0);  // include directory index = LEB128(0) - no directory
616e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        PushByte(dbg_line, 0);  // modification time = LEB128(0) - NA
617e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban        PushByte(dbg_line, 0);  // file length = LEB128(0) - NA
618e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      }
619e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    }
620e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    PushByte(dbg_line, 0);  // End of file_names.
621e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
622e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // Set lnt header length.
623e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4);
624e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
625e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // Generate Line Number Program code, one long program for all methods.
626e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE,
627e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban                                            dbg_line, 0, 1);
628e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
629e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    SrcMap pc2java_map;
630e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    for (size_t i = 0; i < method_info.size(); ++i) {
631e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      const OatWriter::DebugInfo &dbg = method_info[i];
632e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_;
633e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      size_t file_index = files[file_name];
634e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      DCHECK_NE(file_index, 0U) << file_name;
635e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
636e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
637e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
638e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
639e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      // Start a new TAG: subroutine (2).
640e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushByte(dbg_info, 2);
641e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
642e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      // Enter name, low_pc, high_pc.
643e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushWord(dbg_info, PushStr(dbg_str, dbg.method_name_));
644e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushWord(dbg_info, dbg.low_pc_ + text_section_offset);
645e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      PushWord(dbg_info, dbg.high_pc_ + text_section_offset);
646e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
647e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(),
648e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban                         &pc2java_map, dbg.low_pc_);
649e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_);
65033ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban      if (!pc2java_map.empty()) {
65133ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban        line_table_generator.SetFile(file_index);
65233ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban        line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset);
65333ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban        line_table_generator.SetLine(1);
65433ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban        for (auto& src_map_elem : pc2java_map) {
65533ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban          line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_);
65633ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban        }
65733ac819bd13c6e9d42b36ae8393c37cfb1bb4cdeYevgeny Rouban        pc2java_map.clear();
658e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban      }
659ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    }
660ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
661e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // End Sequence should have the highest address set.
662e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    line_table_generator.SetAddr(cunit_high_pc + text_section_offset);
663e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    line_table_generator.EndSequence();
664ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
665e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    // set lnt length
666e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban    UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4);
667ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  }
668ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
669ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  // One byte terminator
670e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  PushByte(dbg_info, 0);
671e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban
672e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // Fill in cunit's low_pc and high_pc.
673e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset);
674e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset);
675ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
676e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  // We have now walked all the methods.  Fill in lengths.
677e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban  UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
6786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom}
6796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
68054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampetemplate <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
68154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
68254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          typename Elf_Phdr, typename Elf_Shdr>
68354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampestatic void WriteDebugSymbols(const CompilerDriver* compiler_driver,
68454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                              ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
68554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                         Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
68654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                              OatWriter* oat_writer) {
68754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  std::unique_ptr<std::vector<uint8_t>> cfi_info(
68854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      ConstructCIEFrame(compiler_driver->GetInstructionSet()));
68954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
69054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  Elf_Addr text_section_address = builder->text_builder_.section_.sh_addr;
69154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
69254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  // Iterate over the compiled methods.
69354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
69454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr,
69554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                   Elf_Sym, Elf_Shdr>* symtab = &builder->symtab_builder_;
69654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
69754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    symtab->AddSymbol(it->method_name_, &builder->text_builder_, it->low_pc_, true,
69854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                      it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
69954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
70054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    // Include CFI for compiled method, if possible.
70154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    if (cfi_info.get() != nullptr) {
70254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      DCHECK(it->compiled_method_ != nullptr);
70354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
70454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      // Copy in the FDE, if present
70554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      const std::vector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
70654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      if (fde != nullptr) {
70754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        // Copy the information into cfi_info and then fix the address in the new copy.
70854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        int cur_offset = cfi_info->size();
70954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
71054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
71154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
71254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
71354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        // Set the 'CIE_pointer' field.
71454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
71554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        uint64_t offset_to_update = CIE_pointer;
71654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        if (is_64bit) {
71754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+0] = CIE_pointer;
71854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
71954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
72054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
72154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
72254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
72354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
72454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
72554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        } else {
72654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+0] = CIE_pointer;
72754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
72854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
72954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
73054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        }
73154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
73254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        // Set the 'initial_location' field.
73354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        offset_to_update += is_64bit ? 8 : 4;
73454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        if (is_64bit) {
73554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          const uint64_t quick_code_start = it->low_pc_ + text_section_address;
73654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+0] = quick_code_start;
73754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
73854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
73954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
74054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
74154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
74254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
74354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
74454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        } else {
74554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          const uint32_t quick_code_start = it->low_pc_ + text_section_address;
74654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+0] = quick_code_start;
74754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
74854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
74954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe          (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
75054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        }
75154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      }
75254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    }
75354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  }
75454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
75554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  bool hasCFI = (cfi_info.get() != nullptr);
75654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  bool hasLineInfo = false;
75754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
75854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    if (dbg_info.dbgstream_ != nullptr &&
75954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe        !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
76054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      hasLineInfo = true;
76154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      break;
76254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    }
76354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  }
76454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
76554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  if (hasLineInfo || hasCFI) {
76654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
76754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   SHT_PROGBITS,
76854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   0, nullptr, 0, 1, 0);
76954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
77054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                     SHT_PROGBITS,
77154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                     0, nullptr, 0, 1, 0);
77254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
77354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                  SHT_PROGBITS,
77454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                  0, nullptr, 0, 1, 0);
77554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
77654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   SHT_PROGBITS,
77754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   0, nullptr, 0, 1, 0);
77854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
77954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
78054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                         debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
78154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                         hasLineInfo ? debug_line.GetBuffer() : nullptr,
78254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                         text_section_address);
78354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
78454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    builder->RegisterRawSection(debug_info);
78554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    builder->RegisterRawSection(debug_abbrev);
78654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
78754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    if (hasCFI) {
78854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
78954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   SHT_PROGBITS,
79054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   SHF_ALLOC,
79154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe                                                                   nullptr, 0, 4, 0);
79254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      eh_frame.SetBuffer(std::move(*cfi_info.get()));
79354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      builder->RegisterRawSection(eh_frame);
79454fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    }
79554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
79654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    if (hasLineInfo) {
79754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe      builder->RegisterRawSection(debug_line);
79854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    }
79954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
80054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe    builder->RegisterRawSection(debug_str);
80154fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  }
80254fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe}
80354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
804f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray// Explicit instantiations
805f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffraytemplate class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
806f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray                              Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
807f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffraytemplate class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
808f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray                              Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
809f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray
8106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom}  // namespace art
811