elf_writer_quick.cc revision 53bee42d0f8b454ff4fe5b7e42bdb070c786e3eb
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 "base/logging.h"
20#include "base/unix_file/fd_file.h"
21#include "buffered_output_stream.h"
22#include "driver/compiler_driver.h"
23#include "elf_utils.h"
24#include "file_output_stream.h"
25#include "globals.h"
26#include "oat.h"
27#include "oat_writer.h"
28#include "utils.h"
29
30namespace art {
31
32bool ElfWriterQuick::Create(File* elf_file,
33                            OatWriter* oat_writer,
34                            const std::vector<const DexFile*>& dex_files,
35                            const std::string& android_root,
36                            bool is_host,
37                            const CompilerDriver& driver) {
38  ElfWriterQuick elf_writer(driver, elf_file);
39  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
40}
41
42bool ElfWriterQuick::Write(OatWriter* oat_writer,
43                           const std::vector<const DexFile*>& dex_files_unused,
44                           const std::string& android_root_unused,
45                           bool is_host_unused) {
46  const bool debug = false;
47  // +-------------------------+
48  // | Elf32_Ehdr              |
49  // +-------------------------+
50  // | Elf32_Phdr PHDR         |
51  // | Elf32_Phdr LOAD R       | .dynsym .dynstr .hash .rodata
52  // | Elf32_Phdr LOAD R X     | .text
53  // | Elf32_Phdr LOAD RW      | .dynamic
54  // | Elf32_Phdr DYNAMIC      | .dynamic
55  // +-------------------------+
56  // | .dynsym                 |
57  // | Elf32_Sym  STN_UNDEF    |
58  // | Elf32_Sym  oatdata      |
59  // | Elf32_Sym  oatexec      |
60  // | Elf32_Sym  oatlastword  |
61  // +-------------------------+
62  // | .dynstr                 |
63  // | \0                      |
64  // | oatdata\0               |
65  // | oatexec\0               |
66  // | oatlastword\0           |
67  // | boot.oat\0              |
68  // +-------------------------+
69  // | .hash                   |
70  // | Elf32_Word nbucket = 1  |
71  // | Elf32_Word nchain  = 3  |
72  // | Elf32_Word bucket[0] = 0|
73  // | Elf32_Word chain[0]  = 1|
74  // | Elf32_Word chain[1]  = 2|
75  // | Elf32_Word chain[2]  = 3|
76  // +-------------------------+
77  // | .rodata                 |
78  // | oatdata..oatexec-4      |
79  // +-------------------------+
80  // | .text                   |
81  // | oatexec..oatlastword    |
82  // +-------------------------+
83  // | .dynamic                |
84  // | Elf32_Dyn DT_SONAME     |
85  // | Elf32_Dyn DT_HASH       |
86  // | Elf32_Dyn DT_SYMTAB     |
87  // | Elf32_Dyn DT_SYMENT     |
88  // | Elf32_Dyn DT_STRTAB     |
89  // | Elf32_Dyn DT_STRSZ      |
90  // | Elf32_Dyn DT_NULL       |
91  // +-------------------------+
92  // | .shstrtab               |
93  // | \0                      |
94  // | .dynamic\0              |
95  // | .dynsym\0               |
96  // | .dynstr\0               |
97  // | .hash\0                 |
98  // | .rodata\0               |
99  // | .text\0                 |
100  // | .shstrtab\0             |
101  // | .debug_frame\0          |
102  // +-------------------------+
103  // | Elf32_Shdr NULL         |
104  // | Elf32_Shdr .dynsym      |
105  // | Elf32_Shdr .dynstr      |
106  // | Elf32_Shdr .hash        |
107  // | Elf32_Shdr .text        |
108  // | Elf32_Shdr .rodata      |
109  // | Elf32_Shdr .dynamic     |
110  // | Elf32_Shdr .shstrtab    |
111  // | Elf32_Shdr .debug_info  |  (Optional)
112  // | Elf32_Shdr .debug_abbrev|  (Optional)
113  // | Elf32_Shdr .debug_frame |  (Optional)
114  // +-------------------------+
115
116  // phase 1: computing offsets
117  uint32_t expected_offset = 0;
118
119  // Elf32_Ehdr
120  expected_offset += sizeof(Elf32_Ehdr);
121
122  // PHDR
123  uint32_t phdr_alignment = sizeof(Elf32_Word);
124  uint32_t phdr_offset = expected_offset;
125  const uint8_t PH_PHDR     = 0;
126  const uint8_t PH_LOAD_R__ = 1;
127  const uint8_t PH_LOAD_R_X = 2;
128  const uint8_t PH_LOAD_RW_ = 3;
129  const uint8_t PH_DYNAMIC  = 4;
130  const uint8_t PH_NUM      = 5;
131  uint32_t phdr_size = sizeof(Elf32_Phdr) * PH_NUM;
132  expected_offset += phdr_size;
133  if (debug) {
134    LOG(INFO) << "phdr_offset=" << phdr_offset << std::hex << " " << phdr_offset;
135    LOG(INFO) << "phdr_size=" << phdr_size << std::hex << " " << phdr_size;
136  }
137
138  // .dynsym
139  uint32_t dynsym_alignment = sizeof(Elf32_Word);
140  uint32_t dynsym_offset = expected_offset = RoundUp(expected_offset, dynsym_alignment);
141  const uint8_t SYM_UNDEF       = 0;  // aka STN_UNDEF
142  const uint8_t SYM_OATDATA     = 1;
143  const uint8_t SYM_OATEXEC     = 2;
144  const uint8_t SYM_OATLASTWORD = 3;
145  const uint8_t SYM_NUM         = 4;
146  uint32_t dynsym_size = sizeof(Elf32_Sym) * SYM_NUM;
147  expected_offset += dynsym_size;
148  if (debug) {
149    LOG(INFO) << "dynsym_offset=" << dynsym_offset << std::hex << " " << dynsym_offset;
150    LOG(INFO) << "dynsym_size=" << dynsym_size << std::hex << " " << dynsym_size;
151  }
152
153  // .dynstr
154  uint32_t dynstr_alignment = 1;
155  uint32_t dynstr_offset = expected_offset = RoundUp(expected_offset, dynstr_alignment);
156  std::string dynstr;
157  dynstr += '\0';
158  uint32_t dynstr_oatdata_offset = dynstr.size();
159  dynstr += "oatdata";
160  dynstr += '\0';
161  uint32_t dynstr_oatexec_offset = dynstr.size();
162  dynstr += "oatexec";
163  dynstr += '\0';
164  uint32_t dynstr_oatlastword_offset = dynstr.size();
165  dynstr += "oatlastword";
166  dynstr += '\0';
167  uint32_t dynstr_soname_offset = dynstr.size();
168  std::string file_name(elf_file_->GetPath());
169  size_t directory_separator_pos = file_name.rfind('/');
170  if (directory_separator_pos != std::string::npos) {
171    file_name = file_name.substr(directory_separator_pos + 1);
172  }
173  dynstr += file_name;
174  dynstr += '\0';
175  uint32_t dynstr_size = dynstr.size();
176  expected_offset += dynstr_size;
177  if (debug) {
178    LOG(INFO) << "dynstr_offset=" << dynstr_offset << std::hex << " " << dynstr_offset;
179    LOG(INFO) << "dynstr_size=" << dynstr_size << std::hex << " " << dynstr_size;
180  }
181
182  // .hash
183  uint32_t hash_alignment = sizeof(Elf32_Word);  // Even for 64-bit
184  uint32_t hash_offset = expected_offset = RoundUp(expected_offset, hash_alignment);
185  const uint8_t HASH_NBUCKET = 0;
186  const uint8_t HASH_NCHAIN  = 1;
187  const uint8_t HASH_BUCKET0 = 2;
188  const uint8_t HASH_NUM     = HASH_BUCKET0 + 1 + SYM_NUM;
189  uint32_t hash_size = sizeof(Elf32_Word) * HASH_NUM;
190  expected_offset += hash_size;
191  if (debug) {
192    LOG(INFO) << "hash_offset=" << hash_offset << std::hex << " " << hash_offset;
193    LOG(INFO) << "hash_size=" << hash_size << std::hex << " " << hash_size;
194  }
195
196  // .rodata
197  uint32_t oat_data_alignment = kPageSize;
198  uint32_t oat_data_offset = expected_offset = RoundUp(expected_offset, oat_data_alignment);
199  const OatHeader& oat_header = oat_writer->GetOatHeader();
200  CHECK(oat_header.IsValid());
201  uint32_t oat_data_size = oat_header.GetExecutableOffset();
202  expected_offset += oat_data_size;
203  if (debug) {
204    LOG(INFO) << "oat_data_offset=" << oat_data_offset << std::hex << " " << oat_data_offset;
205    LOG(INFO) << "oat_data_size=" << oat_data_size << std::hex << " " << oat_data_size;
206  }
207
208  // .text
209  uint32_t oat_exec_alignment = kPageSize;
210  CHECK_ALIGNED(expected_offset, kPageSize);
211  uint32_t oat_exec_offset = expected_offset = RoundUp(expected_offset, oat_exec_alignment);
212  uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
213  expected_offset += oat_exec_size;
214  CHECK_EQ(oat_data_offset + oat_writer->GetSize(), expected_offset);
215  if (debug) {
216    LOG(INFO) << "oat_exec_offset=" << oat_exec_offset << std::hex << " " << oat_exec_offset;
217    LOG(INFO) << "oat_exec_size=" << oat_exec_size << std::hex << " " << oat_exec_size;
218  }
219
220  // .dynamic
221  // alignment would naturally be sizeof(Elf32_Word), but we want this in a new segment
222  uint32_t dynamic_alignment = kPageSize;
223  uint32_t dynamic_offset = expected_offset = RoundUp(expected_offset, dynamic_alignment);
224  const uint8_t DH_SONAME = 0;
225  const uint8_t DH_HASH   = 1;
226  const uint8_t DH_SYMTAB = 2;
227  const uint8_t DH_SYMENT = 3;
228  const uint8_t DH_STRTAB = 4;
229  const uint8_t DH_STRSZ  = 5;
230  const uint8_t DH_NULL   = 6;
231  const uint8_t DH_NUM    = 7;
232  uint32_t dynamic_size = sizeof(Elf32_Dyn) * DH_NUM;
233  expected_offset += dynamic_size;
234  if (debug) {
235    LOG(INFO) << "dynamic_offset=" << dynamic_offset << std::hex << " " << dynamic_offset;
236    LOG(INFO) << "dynamic_size=" << dynamic_size << std::hex << " " << dynamic_size;
237  }
238
239  // .shstrtab
240  uint32_t shstrtab_alignment = 1;
241  uint32_t shstrtab_offset = expected_offset = RoundUp(expected_offset, shstrtab_alignment);
242  std::string shstrtab;
243  shstrtab += '\0';
244  uint32_t shstrtab_dynamic_offset = shstrtab.size();
245  CHECK_EQ(1U, shstrtab_dynamic_offset);
246  shstrtab += ".dynamic";
247  shstrtab += '\0';
248  uint32_t shstrtab_dynsym_offset = shstrtab.size();
249  shstrtab += ".dynsym";
250  shstrtab += '\0';
251  uint32_t shstrtab_dynstr_offset = shstrtab.size();
252  shstrtab += ".dynstr";
253  shstrtab += '\0';
254  uint32_t shstrtab_hash_offset = shstrtab.size();
255  shstrtab += ".hash";
256  shstrtab += '\0';
257  uint32_t shstrtab_rodata_offset = shstrtab.size();
258  shstrtab += ".rodata";
259  shstrtab += '\0';
260  uint32_t shstrtab_text_offset = shstrtab.size();
261  shstrtab += ".text";
262  shstrtab += '\0';
263  uint32_t shstrtab_shstrtab_offset = shstrtab.size();
264  shstrtab += ".shstrtab";
265  shstrtab += '\0';
266  uint32_t shstrtab_debug_info_offset = shstrtab.size();
267  shstrtab += ".debug_info";
268  shstrtab += '\0';
269  uint32_t shstrtab_debug_abbrev_offset = shstrtab.size();
270  shstrtab += ".debug_abbrev";
271  shstrtab += '\0';
272  uint32_t shstrtab_debug_str_offset = shstrtab.size();
273  shstrtab += ".debug_str";
274  shstrtab += '\0';
275  uint32_t shstrtab_debug_frame_offset = shstrtab.size();
276  shstrtab += ".debug_frame";
277  shstrtab += '\0';
278  uint32_t shstrtab_size = shstrtab.size();
279  expected_offset += shstrtab_size;
280  if (debug) {
281    LOG(INFO) << "shstrtab_offset=" << shstrtab_offset << std::hex << " " << shstrtab_offset;
282    LOG(INFO) << "shstrtab_size=" << shstrtab_size << std::hex << " " << shstrtab_size;
283  }
284
285  // Create debug informatin, if we have it.
286  bool generateDebugInformation = compiler_driver_->GetCallFrameInformation() != nullptr;
287  std::vector<uint8_t> dbg_info;
288  std::vector<uint8_t> dbg_abbrev;
289  std::vector<uint8_t> dbg_str;
290  if (generateDebugInformation) {
291    FillInCFIInformation(oat_writer, &dbg_info, &dbg_abbrev, &dbg_str);
292  }
293
294  uint32_t shdbg_info_alignment = 1;
295  uint32_t shdbg_info_offset = expected_offset;
296  uint32_t shdbg_info_size = dbg_info.size();
297  expected_offset += shdbg_info_size;
298  if (debug) {
299    LOG(INFO) << "shdbg_info_offset=" << shdbg_info_offset << std::hex << " " << shdbg_info_offset;
300    LOG(INFO) << "shdbg_info_size=" << shdbg_info_size << std::hex << " " << shdbg_info_size;
301  }
302
303  uint32_t shdbg_abbrev_alignment = 1;
304  uint32_t shdbg_abbrev_offset = expected_offset;
305  uint32_t shdbg_abbrev_size = dbg_abbrev.size();
306  expected_offset += shdbg_abbrev_size;
307  if (debug) {
308    LOG(INFO) << "shdbg_abbrev_offset=" << shdbg_abbrev_offset << std::hex << " " << shdbg_abbrev_offset;
309    LOG(INFO) << "shdbg_abbrev_size=" << shdbg_abbrev_size << std::hex << " " << shdbg_abbrev_size;
310  }
311
312  uint32_t shdbg_frm_alignment = 4;
313  uint32_t shdbg_frm_offset = expected_offset = RoundUp(expected_offset, shdbg_frm_alignment);
314  uint32_t shdbg_frm_size =
315    generateDebugInformation ? compiler_driver_->GetCallFrameInformation()->size() : 0;
316  expected_offset += shdbg_frm_size;
317  if (debug) {
318    LOG(INFO) << "shdbg_frm_offset=" << shdbg_frm_offset << std::hex << " " << shdbg_frm_offset;
319    LOG(INFO) << "shdbg_frm_size=" << shdbg_frm_size << std::hex << " " << shdbg_frm_size;
320  }
321
322  uint32_t shdbg_str_alignment = 1;
323  uint32_t shdbg_str_offset = expected_offset;
324  uint32_t shdbg_str_size = dbg_str.size();
325  expected_offset += shdbg_str_size;
326  if (debug) {
327    LOG(INFO) << "shdbg_str_offset=" << shdbg_str_offset << std::hex << " " << shdbg_str_offset;
328    LOG(INFO) << "shdbg_str_size=" << shdbg_str_size << std::hex << " " << shdbg_str_size;
329  }
330
331  // section headers (after all sections)
332  uint32_t shdr_alignment = sizeof(Elf32_Word);
333  uint32_t shdr_offset = expected_offset = RoundUp(expected_offset, shdr_alignment);
334  const uint8_t SH_NULL     = 0;
335  const uint8_t SH_DYNSYM   = 1;
336  const uint8_t SH_DYNSTR   = 2;
337  const uint8_t SH_HASH     = 3;
338  const uint8_t SH_RODATA   = 4;
339  const uint8_t SH_TEXT     = 5;
340  const uint8_t SH_DYNAMIC  = 6;
341  const uint8_t SH_SHSTRTAB = 7;
342  const uint8_t SH_DBG_INFO = 8;
343  const uint8_t SH_DBG_ABRV = 9;
344  const uint8_t SH_DBG_FRM  = 10;
345  const uint8_t SH_DBG_STR  = 11;
346  const uint8_t SH_NUM      = generateDebugInformation ? 12 : 8;
347  uint32_t shdr_size = sizeof(Elf32_Shdr) * SH_NUM;
348  expected_offset += shdr_size;
349  if (debug) {
350    LOG(INFO) << "shdr_offset=" << shdr_offset << std::hex << " " << shdr_offset;
351    LOG(INFO) << "shdr_size=" << shdr_size << std::hex << " " << shdr_size;
352  }
353
354  // phase 2: initializing data
355
356  // Elf32_Ehdr
357  Elf32_Ehdr elf_header;
358  memset(&elf_header, 0, sizeof(elf_header));
359  elf_header.e_ident[EI_MAG0]       = ELFMAG0;
360  elf_header.e_ident[EI_MAG1]       = ELFMAG1;
361  elf_header.e_ident[EI_MAG2]       = ELFMAG2;
362  elf_header.e_ident[EI_MAG3]       = ELFMAG3;
363  elf_header.e_ident[EI_CLASS]      = ELFCLASS32;
364  elf_header.e_ident[EI_DATA]       = ELFDATA2LSB;
365  elf_header.e_ident[EI_VERSION]    = EV_CURRENT;
366  elf_header.e_ident[EI_OSABI]      = ELFOSABI_LINUX;
367  elf_header.e_ident[EI_ABIVERSION] = 0;
368  elf_header.e_type = ET_DYN;
369  switch (compiler_driver_->GetInstructionSet()) {
370    case kArm:
371      // Fall through.
372    case kThumb2: {
373      elf_header.e_machine = EM_ARM;
374      elf_header.e_flags = EF_ARM_EABI_VER5;
375      break;
376    }
377    case kArm64: {
378      elf_header.e_machine = EM_AARCH64;
379      elf_header.e_flags = 0;
380      break;
381    }
382    case kX86: {
383      elf_header.e_machine = EM_386;
384      elf_header.e_flags = 0;
385      break;
386    }
387    case kX86_64: {
388      elf_header.e_machine = EM_X86_64;
389      elf_header.e_flags = 0;
390      break;
391    }
392    case kMips: {
393      elf_header.e_machine = EM_MIPS;
394      elf_header.e_flags = (EF_MIPS_NOREORDER |
395                            EF_MIPS_PIC       |
396                            EF_MIPS_CPIC      |
397                            EF_MIPS_ABI_O32   |
398                            EF_MIPS_ARCH_32R2);
399      break;
400    }
401    default: {
402      LOG(FATAL) << "Unknown instruction set: " << compiler_driver_->GetInstructionSet();
403      break;
404    }
405  }
406  elf_header.e_version = 1;
407  elf_header.e_entry = 0;
408  elf_header.e_phoff = phdr_offset;
409  elf_header.e_shoff = shdr_offset;
410  elf_header.e_ehsize = sizeof(Elf32_Ehdr);
411  elf_header.e_phentsize = sizeof(Elf32_Phdr);
412  elf_header.e_phnum = PH_NUM;
413  elf_header.e_shentsize = sizeof(Elf32_Shdr);
414  elf_header.e_shnum = SH_NUM;
415  elf_header.e_shstrndx = SH_SHSTRTAB;
416
417  // PHDR
418  Elf32_Phdr program_headers[PH_NUM];
419  memset(&program_headers, 0, sizeof(program_headers));
420
421  program_headers[PH_PHDR].p_type    = PT_PHDR;
422  program_headers[PH_PHDR].p_offset  = phdr_offset;
423  program_headers[PH_PHDR].p_vaddr   = phdr_offset;
424  program_headers[PH_PHDR].p_paddr   = phdr_offset;
425  program_headers[PH_PHDR].p_filesz  = sizeof(program_headers);
426  program_headers[PH_PHDR].p_memsz   = sizeof(program_headers);
427  program_headers[PH_PHDR].p_flags   = PF_R;
428  program_headers[PH_PHDR].p_align   = phdr_alignment;
429
430  program_headers[PH_LOAD_R__].p_type    = PT_LOAD;
431  program_headers[PH_LOAD_R__].p_offset  = 0;
432  program_headers[PH_LOAD_R__].p_vaddr   = 0;
433  program_headers[PH_LOAD_R__].p_paddr   = 0;
434  program_headers[PH_LOAD_R__].p_filesz  = oat_data_offset + oat_data_size;
435  program_headers[PH_LOAD_R__].p_memsz   = oat_data_offset + oat_data_size;
436  program_headers[PH_LOAD_R__].p_flags   = PF_R;
437  program_headers[PH_LOAD_R__].p_align   = oat_data_alignment;
438
439  program_headers[PH_LOAD_R_X].p_type    = PT_LOAD;
440  program_headers[PH_LOAD_R_X].p_offset  = oat_exec_offset;
441  program_headers[PH_LOAD_R_X].p_vaddr   = oat_exec_offset;
442  program_headers[PH_LOAD_R_X].p_paddr   = oat_exec_offset;
443  program_headers[PH_LOAD_R_X].p_filesz  = oat_exec_size;
444  program_headers[PH_LOAD_R_X].p_memsz   = oat_exec_size;
445  program_headers[PH_LOAD_R_X].p_flags   = PF_R | PF_X;
446  program_headers[PH_LOAD_R_X].p_align   = oat_exec_alignment;
447
448  // TODO: PF_W for DYNAMIC is considered processor specific, do we need it?
449  program_headers[PH_LOAD_RW_].p_type    = PT_LOAD;
450  program_headers[PH_LOAD_RW_].p_offset  = dynamic_offset;
451  program_headers[PH_LOAD_RW_].p_vaddr   = dynamic_offset;
452  program_headers[PH_LOAD_RW_].p_paddr   = dynamic_offset;
453  program_headers[PH_LOAD_RW_].p_filesz  = dynamic_size;
454  program_headers[PH_LOAD_RW_].p_memsz   = dynamic_size;
455  program_headers[PH_LOAD_RW_].p_flags   = PF_R | PF_W;
456  program_headers[PH_LOAD_RW_].p_align   = dynamic_alignment;
457
458  // TODO: PF_W for DYNAMIC is considered processor specific, do we need it?
459  program_headers[PH_DYNAMIC].p_type    = PT_DYNAMIC;
460  program_headers[PH_DYNAMIC].p_offset  = dynamic_offset;
461  program_headers[PH_DYNAMIC].p_vaddr   = dynamic_offset;
462  program_headers[PH_DYNAMIC].p_paddr   = dynamic_offset;
463  program_headers[PH_DYNAMIC].p_filesz  = dynamic_size;
464  program_headers[PH_DYNAMIC].p_memsz   = dynamic_size;
465  program_headers[PH_DYNAMIC].p_flags   = PF_R | PF_W;
466  program_headers[PH_DYNAMIC].p_align   = dynamic_alignment;
467
468  // .dynsym
469  Elf32_Sym dynsym[SYM_NUM];
470  memset(&dynsym, 0, sizeof(dynsym));
471
472  dynsym[SYM_UNDEF].st_name  = 0;
473  dynsym[SYM_UNDEF].st_value = 0;
474  dynsym[SYM_UNDEF].st_size  = 0;
475  dynsym[SYM_UNDEF].st_info  = 0;
476  dynsym[SYM_UNDEF].st_other = 0;
477  dynsym[SYM_UNDEF].st_shndx = 0;
478
479  dynsym[SYM_OATDATA].st_name  = dynstr_oatdata_offset;
480  dynsym[SYM_OATDATA].st_value = oat_data_offset;
481  dynsym[SYM_OATDATA].st_size  = oat_data_size;
482  SetBindingAndType(&dynsym[SYM_OATDATA], STB_GLOBAL, STT_OBJECT);
483  dynsym[SYM_OATDATA].st_other = STV_DEFAULT;
484  dynsym[SYM_OATDATA].st_shndx = SH_RODATA;
485
486  dynsym[SYM_OATEXEC].st_name  = dynstr_oatexec_offset;
487  dynsym[SYM_OATEXEC].st_value = oat_exec_offset;
488  dynsym[SYM_OATEXEC].st_size  = oat_exec_size;
489  SetBindingAndType(&dynsym[SYM_OATEXEC], STB_GLOBAL, STT_OBJECT);
490  dynsym[SYM_OATEXEC].st_other = STV_DEFAULT;
491  dynsym[SYM_OATEXEC].st_shndx = SH_TEXT;
492
493  dynsym[SYM_OATLASTWORD].st_name  = dynstr_oatlastword_offset;
494  dynsym[SYM_OATLASTWORD].st_value = oat_exec_offset + oat_exec_size - 4;
495  dynsym[SYM_OATLASTWORD].st_size  = 4;
496  SetBindingAndType(&dynsym[SYM_OATLASTWORD], STB_GLOBAL, STT_OBJECT);
497  dynsym[SYM_OATLASTWORD].st_other = STV_DEFAULT;
498  dynsym[SYM_OATLASTWORD].st_shndx = SH_TEXT;
499
500  // .dynstr initialized above as dynstr
501
502  // .hash
503  Elf32_Word hash[HASH_NUM];  // Note this is Elf32_Word even on 64-bit
504  hash[HASH_NBUCKET] = 1;
505  hash[HASH_NCHAIN]  = SYM_NUM;
506  hash[HASH_BUCKET0] = SYM_OATDATA;
507  hash[HASH_BUCKET0 + 1 + SYM_UNDEF]       = SYM_UNDEF;
508  hash[HASH_BUCKET0 + 1 + SYM_OATDATA]     = SYM_OATEXEC;
509  hash[HASH_BUCKET0 + 1 + SYM_OATEXEC]     = SYM_OATLASTWORD;
510  hash[HASH_BUCKET0 + 1 + SYM_OATLASTWORD] = SYM_UNDEF;
511
512  // .rodata and .text content come from oat_contents
513
514  // .dynamic
515  Elf32_Dyn dynamic_headers[DH_NUM];
516  memset(&dynamic_headers, 0, sizeof(dynamic_headers));
517
518  dynamic_headers[DH_SONAME].d_tag = DT_SONAME;
519  dynamic_headers[DH_SONAME].d_un.d_val = dynstr_soname_offset;
520
521  dynamic_headers[DH_HASH].d_tag = DT_HASH;
522  dynamic_headers[DH_HASH].d_un.d_ptr = hash_offset;
523
524  dynamic_headers[DH_SYMTAB].d_tag = DT_SYMTAB;
525  dynamic_headers[DH_SYMTAB].d_un.d_ptr = dynsym_offset;
526
527  dynamic_headers[DH_SYMENT].d_tag = DT_SYMENT;
528  dynamic_headers[DH_SYMENT].d_un.d_val = sizeof(Elf32_Sym);
529
530  dynamic_headers[DH_STRTAB].d_tag = DT_STRTAB;
531  dynamic_headers[DH_STRTAB].d_un.d_ptr = dynstr_offset;
532
533  dynamic_headers[DH_STRSZ].d_tag = DT_STRSZ;
534  dynamic_headers[DH_STRSZ].d_un.d_val = dynstr_size;
535
536  dynamic_headers[DH_NULL].d_tag = DT_NULL;
537  dynamic_headers[DH_NULL].d_un.d_val = 0;
538
539  // .shstrtab initialized above as shstrtab
540
541  // section headers (after all sections)
542  Elf32_Shdr section_headers[SH_NUM];
543  memset(&section_headers, 0, sizeof(section_headers));
544
545  section_headers[SH_NULL].sh_name      = 0;
546  section_headers[SH_NULL].sh_type      = SHT_NULL;
547  section_headers[SH_NULL].sh_flags     = 0;
548  section_headers[SH_NULL].sh_addr      = 0;
549  section_headers[SH_NULL].sh_offset    = 0;
550  section_headers[SH_NULL].sh_size      = 0;
551  section_headers[SH_NULL].sh_link      = 0;
552  section_headers[SH_NULL].sh_info      = 0;
553  section_headers[SH_NULL].sh_addralign = 0;
554  section_headers[SH_NULL].sh_entsize   = 0;
555
556  section_headers[SH_DYNSYM].sh_name      = shstrtab_dynsym_offset;
557  section_headers[SH_DYNSYM].sh_type      = SHT_DYNSYM;
558  section_headers[SH_DYNSYM].sh_flags     = SHF_ALLOC;
559  section_headers[SH_DYNSYM].sh_addr      = dynsym_offset;
560  section_headers[SH_DYNSYM].sh_offset    = dynsym_offset;
561  section_headers[SH_DYNSYM].sh_size      = dynsym_size;
562  section_headers[SH_DYNSYM].sh_link      = SH_DYNSTR;
563  section_headers[SH_DYNSYM].sh_info      = 1;  // 1 because we have not STB_LOCAL symbols
564  section_headers[SH_DYNSYM].sh_addralign = dynsym_alignment;
565  section_headers[SH_DYNSYM].sh_entsize   = sizeof(Elf32_Sym);
566
567  section_headers[SH_DYNSTR].sh_name      = shstrtab_dynstr_offset;
568  section_headers[SH_DYNSTR].sh_type      = SHT_STRTAB;
569  section_headers[SH_DYNSTR].sh_flags     = SHF_ALLOC;
570  section_headers[SH_DYNSTR].sh_addr      = dynstr_offset;
571  section_headers[SH_DYNSTR].sh_offset    = dynstr_offset;
572  section_headers[SH_DYNSTR].sh_size      = dynstr_size;
573  section_headers[SH_DYNSTR].sh_link      = 0;
574  section_headers[SH_DYNSTR].sh_info      = 0;
575  section_headers[SH_DYNSTR].sh_addralign = dynstr_alignment;
576  section_headers[SH_DYNSTR].sh_entsize   = 0;
577
578  section_headers[SH_HASH].sh_name      = shstrtab_hash_offset;
579  section_headers[SH_HASH].sh_type      = SHT_HASH;
580  section_headers[SH_HASH].sh_flags     = SHF_ALLOC;
581  section_headers[SH_HASH].sh_addr      = hash_offset;
582  section_headers[SH_HASH].sh_offset    = hash_offset;
583  section_headers[SH_HASH].sh_size      = hash_size;
584  section_headers[SH_HASH].sh_link      = SH_DYNSYM;
585  section_headers[SH_HASH].sh_info      = 0;
586  section_headers[SH_HASH].sh_addralign = hash_alignment;
587  section_headers[SH_HASH].sh_entsize   = sizeof(Elf32_Word);  // This is Elf32_Word even on 64-bit
588
589  section_headers[SH_RODATA].sh_name      = shstrtab_rodata_offset;
590  section_headers[SH_RODATA].sh_type      = SHT_PROGBITS;
591  section_headers[SH_RODATA].sh_flags     = SHF_ALLOC;
592  section_headers[SH_RODATA].sh_addr      = oat_data_offset;
593  section_headers[SH_RODATA].sh_offset    = oat_data_offset;
594  section_headers[SH_RODATA].sh_size      = oat_data_size;
595  section_headers[SH_RODATA].sh_link      = 0;
596  section_headers[SH_RODATA].sh_info      = 0;
597  section_headers[SH_RODATA].sh_addralign = oat_data_alignment;
598  section_headers[SH_RODATA].sh_entsize   = 0;
599
600  section_headers[SH_TEXT].sh_name      = shstrtab_text_offset;
601  section_headers[SH_TEXT].sh_type      = SHT_PROGBITS;
602  section_headers[SH_TEXT].sh_flags     = SHF_ALLOC | SHF_EXECINSTR;
603  section_headers[SH_TEXT].sh_addr      = oat_exec_offset;
604  section_headers[SH_TEXT].sh_offset    = oat_exec_offset;
605  section_headers[SH_TEXT].sh_size      = oat_exec_size;
606  section_headers[SH_TEXT].sh_link      = 0;
607  section_headers[SH_TEXT].sh_info      = 0;
608  section_headers[SH_TEXT].sh_addralign = oat_exec_alignment;
609  section_headers[SH_TEXT].sh_entsize   = 0;
610
611  // TODO: SHF_WRITE for .dynamic is considered processor specific, do we need it?
612  section_headers[SH_DYNAMIC].sh_name      = shstrtab_dynamic_offset;
613  section_headers[SH_DYNAMIC].sh_type      = SHT_DYNAMIC;
614  section_headers[SH_DYNAMIC].sh_flags     = SHF_WRITE | SHF_ALLOC;
615  section_headers[SH_DYNAMIC].sh_addr      = dynamic_offset;
616  section_headers[SH_DYNAMIC].sh_offset    = dynamic_offset;
617  section_headers[SH_DYNAMIC].sh_size      = dynamic_size;
618  section_headers[SH_DYNAMIC].sh_link      = SH_DYNSTR;
619  section_headers[SH_DYNAMIC].sh_info      = 0;
620  section_headers[SH_DYNAMIC].sh_addralign = dynamic_alignment;
621  section_headers[SH_DYNAMIC].sh_entsize   = sizeof(Elf32_Dyn);
622
623  section_headers[SH_SHSTRTAB].sh_name      = shstrtab_shstrtab_offset;
624  section_headers[SH_SHSTRTAB].sh_type      = SHT_STRTAB;
625  section_headers[SH_SHSTRTAB].sh_flags     = 0;
626  section_headers[SH_SHSTRTAB].sh_addr      = shstrtab_offset;
627  section_headers[SH_SHSTRTAB].sh_offset    = shstrtab_offset;
628  section_headers[SH_SHSTRTAB].sh_size      = shstrtab_size;
629  section_headers[SH_SHSTRTAB].sh_link      = 0;
630  section_headers[SH_SHSTRTAB].sh_info      = 0;
631  section_headers[SH_SHSTRTAB].sh_addralign = shstrtab_alignment;
632  section_headers[SH_SHSTRTAB].sh_entsize   = 0;
633
634  if (generateDebugInformation) {
635    section_headers[SH_DBG_INFO].sh_name      = shstrtab_debug_info_offset;
636    section_headers[SH_DBG_INFO].sh_type      = SHT_PROGBITS;
637    section_headers[SH_DBG_INFO].sh_flags     = 0;
638    section_headers[SH_DBG_INFO].sh_addr      = 0;
639    section_headers[SH_DBG_INFO].sh_offset    = shdbg_info_offset;
640    section_headers[SH_DBG_INFO].sh_size      = shdbg_info_size;
641    section_headers[SH_DBG_INFO].sh_link      = 0;
642    section_headers[SH_DBG_INFO].sh_info      = 0;
643    section_headers[SH_DBG_INFO].sh_addralign = shdbg_info_alignment;
644    section_headers[SH_DBG_INFO].sh_entsize   = 0;
645
646    section_headers[SH_DBG_ABRV].sh_name      = shstrtab_debug_abbrev_offset;
647    section_headers[SH_DBG_ABRV].sh_type      = SHT_PROGBITS;
648    section_headers[SH_DBG_ABRV].sh_flags     = 0;
649    section_headers[SH_DBG_ABRV].sh_addr      = 0;
650    section_headers[SH_DBG_ABRV].sh_offset    = shdbg_abbrev_offset;
651    section_headers[SH_DBG_ABRV].sh_size      = shdbg_abbrev_size;
652    section_headers[SH_DBG_ABRV].sh_link      = 0;
653    section_headers[SH_DBG_ABRV].sh_info      = 0;
654    section_headers[SH_DBG_ABRV].sh_addralign = shdbg_abbrev_alignment;
655    section_headers[SH_DBG_ABRV].sh_entsize   = 0;
656
657    section_headers[SH_DBG_FRM].sh_name      = shstrtab_debug_frame_offset;
658    section_headers[SH_DBG_FRM].sh_type      = SHT_PROGBITS;
659    section_headers[SH_DBG_FRM].sh_flags     = 0;
660    section_headers[SH_DBG_FRM].sh_addr      = 0;
661    section_headers[SH_DBG_FRM].sh_offset    = shdbg_frm_offset;
662    section_headers[SH_DBG_FRM].sh_size      = shdbg_frm_size;
663    section_headers[SH_DBG_FRM].sh_link      = 0;
664    section_headers[SH_DBG_FRM].sh_info      = 0;
665    section_headers[SH_DBG_FRM].sh_addralign = shdbg_frm_alignment;
666    section_headers[SH_DBG_FRM].sh_entsize   = 0;
667
668    section_headers[SH_DBG_STR].sh_name      = shstrtab_debug_str_offset;
669    section_headers[SH_DBG_STR].sh_type      = SHT_PROGBITS;
670    section_headers[SH_DBG_STR].sh_flags     = 0;
671    section_headers[SH_DBG_STR].sh_addr      = 0;
672    section_headers[SH_DBG_STR].sh_offset    = shdbg_str_offset;
673    section_headers[SH_DBG_STR].sh_size      = shdbg_str_size;
674    section_headers[SH_DBG_STR].sh_link      = 0;
675    section_headers[SH_DBG_STR].sh_info      = 0;
676    section_headers[SH_DBG_STR].sh_addralign = shdbg_str_alignment;
677    section_headers[SH_DBG_STR].sh_entsize   = 0;
678  }
679
680  // phase 3: writing file
681
682  // Elf32_Ehdr
683  if (!elf_file_->WriteFully(&elf_header, sizeof(elf_header))) {
684    PLOG(ERROR) << "Failed to write ELF header for " << elf_file_->GetPath();
685    return false;
686  }
687
688  // PHDR
689  if (static_cast<off_t>(phdr_offset) != lseek(elf_file_->Fd(), 0, SEEK_CUR)) {
690    PLOG(ERROR) << "Failed to be at expected ELF program header offset phdr_offset "
691                << " for " << elf_file_->GetPath();
692    return false;
693  }
694  if (!elf_file_->WriteFully(program_headers, sizeof(program_headers))) {
695    PLOG(ERROR) << "Failed to write ELF program headers for " << elf_file_->GetPath();
696    return false;
697  }
698
699  // .dynsym
700  DCHECK_LE(phdr_offset + phdr_size, dynsym_offset);
701  if (static_cast<off_t>(dynsym_offset) != lseek(elf_file_->Fd(), dynsym_offset, SEEK_SET)) {
702    PLOG(ERROR) << "Failed to seek to .dynsym offset location " << dynsym_offset
703                << " for " << elf_file_->GetPath();
704    return false;
705  }
706  if (!elf_file_->WriteFully(dynsym, sizeof(dynsym))) {
707    PLOG(ERROR) << "Failed to write .dynsym for " << elf_file_->GetPath();
708    return false;
709  }
710
711  // .dynstr
712  DCHECK_LE(dynsym_offset + dynsym_size, dynstr_offset);
713  if (static_cast<off_t>(dynstr_offset) != lseek(elf_file_->Fd(), dynstr_offset, SEEK_SET)) {
714    PLOG(ERROR) << "Failed to seek to .dynstr offset " << dynstr_offset
715                << " for " << elf_file_->GetPath();
716    return false;
717  }
718  if (!elf_file_->WriteFully(&dynstr[0], dynstr_size)) {
719    PLOG(ERROR) << "Failed to write .dynsym for " << elf_file_->GetPath();
720    return false;
721  }
722
723  // .hash
724  DCHECK_LE(dynstr_offset + dynstr_size, hash_offset);
725  if (static_cast<off_t>(hash_offset) != lseek(elf_file_->Fd(), hash_offset, SEEK_SET)) {
726    PLOG(ERROR) << "Failed to seek to .hash offset " << hash_offset
727                << " for " << elf_file_->GetPath();
728    return false;
729  }
730  if (!elf_file_->WriteFully(hash, sizeof(hash))) {
731    PLOG(ERROR) << "Failed to write .dynsym for " << elf_file_->GetPath();
732    return false;
733  }
734
735  // .rodata .text
736  DCHECK_LE(hash_offset + hash_size, oat_data_offset);
737  if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) {
738    PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset
739                << " for " << elf_file_->GetPath();
740    return false;
741  }
742  BufferedOutputStream output_stream(new FileOutputStream(elf_file_));
743  if (!oat_writer->Write(&output_stream)) {
744    PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath();
745    return false;
746  }
747
748  // .dynamic
749  DCHECK_LE(oat_data_offset + oat_writer->GetSize(), dynamic_offset);
750  if (static_cast<off_t>(dynamic_offset) != lseek(elf_file_->Fd(), dynamic_offset, SEEK_SET)) {
751    PLOG(ERROR) << "Failed to seek to .dynamic offset " << dynamic_offset
752                << " for " << elf_file_->GetPath();
753    return false;
754  }
755  if (!elf_file_->WriteFully(&dynamic_headers[0], dynamic_size)) {
756    PLOG(ERROR) << "Failed to write .dynamic for " << elf_file_->GetPath();
757    return false;
758  }
759
760  // .shstrtab
761  DCHECK_LE(dynamic_offset + dynamic_size, shstrtab_offset);
762  if (static_cast<off_t>(shstrtab_offset) != lseek(elf_file_->Fd(), shstrtab_offset, SEEK_SET)) {
763    PLOG(ERROR) << "Failed to seek to .shstrtab offset " << shstrtab_offset
764                << " for " << elf_file_->GetPath();
765    return false;
766  }
767  if (!elf_file_->WriteFully(&shstrtab[0], shstrtab_size)) {
768    PLOG(ERROR) << "Failed to write .shstrtab for " << elf_file_->GetPath();
769    return false;
770  }
771
772  if (generateDebugInformation) {
773    // .debug_info
774    DCHECK_LE(shstrtab_offset + shstrtab_size, shdbg_info_offset);
775    if (static_cast<off_t>(shdbg_info_offset) != lseek(elf_file_->Fd(), shdbg_info_offset, SEEK_SET)) {
776      PLOG(ERROR) << "Failed to seek to .shdbg_info offset " << shdbg_info_offset
777                  << " for " << elf_file_->GetPath();
778      return false;
779    }
780    if (!elf_file_->WriteFully(&dbg_info[0], shdbg_info_size)) {
781      PLOG(ERROR) << "Failed to write .debug_info for " << elf_file_->GetPath();
782      return false;
783    }
784
785    // .debug_abbrev
786    DCHECK_LE(shdbg_info_offset + shdbg_info_size, shdbg_abbrev_offset);
787    if (static_cast<off_t>(shdbg_abbrev_offset) != lseek(elf_file_->Fd(), shdbg_abbrev_offset, SEEK_SET)) {
788      PLOG(ERROR) << "Failed to seek to .shdbg_abbrev offset " << shdbg_abbrev_offset
789                  << " for " << elf_file_->GetPath();
790      return false;
791    }
792    if (!elf_file_->WriteFully(&dbg_abbrev[0], shdbg_abbrev_size)) {
793      PLOG(ERROR) << "Failed to write .debug_abbrev for " << elf_file_->GetPath();
794      return false;
795    }
796
797    // .debug_frame
798    DCHECK_LE(shdbg_abbrev_offset + shdbg_abbrev_size, shdbg_frm_offset);
799    if (static_cast<off_t>(shdbg_frm_offset) != lseek(elf_file_->Fd(), shdbg_frm_offset, SEEK_SET)) {
800      PLOG(ERROR) << "Failed to seek to .shdbg_frm offset " << shdbg_frm_offset
801                  << " for " << elf_file_->GetPath();
802      return false;
803    }
804    if (!elf_file_->WriteFully(&((*compiler_driver_->GetCallFrameInformation())[0]), shdbg_frm_size)) {
805      PLOG(ERROR) << "Failed to write .debug_frame for " << elf_file_->GetPath();
806      return false;
807    }
808
809    // .debug_str
810    DCHECK_LE(shdbg_frm_offset + shdbg_frm_size, shdbg_str_offset);
811    if (static_cast<off_t>(shdbg_str_offset) != lseek(elf_file_->Fd(), shdbg_str_offset, SEEK_SET)) {
812      PLOG(ERROR) << "Failed to seek to .shdbg_str offset " << shdbg_str_offset
813                  << " for " << elf_file_->GetPath();
814      return false;
815    }
816    if (!elf_file_->WriteFully(&dbg_str[0], shdbg_str_size)) {
817      PLOG(ERROR) << "Failed to write .debug_frame for " << elf_file_->GetPath();
818      return false;
819    }
820  }
821
822  // section headers (after all sections)
823  if (generateDebugInformation) {
824    DCHECK_LE(shdbg_str_offset + shdbg_str_size, shdr_offset);
825  } else {
826    DCHECK_LE(shstrtab_offset + shstrtab_size, shdr_offset);
827  }
828  if (static_cast<off_t>(shdr_offset) != lseek(elf_file_->Fd(), shdr_offset, SEEK_SET)) {
829    PLOG(ERROR) << "Failed to seek to ELF section headers offset " << shdr_offset
830                << " for " << elf_file_->GetPath();
831    return false;
832  }
833  if (!elf_file_->WriteFully(section_headers, sizeof(section_headers))) {
834    PLOG(ERROR) << "Failed to write ELF section headers for " << elf_file_->GetPath();
835    return false;
836  }
837
838  VLOG(compiler) << "ELF file written successfully: " << elf_file_->GetPath();
839  return true;
840}  // NOLINT(readability/fn_size)
841
842static void UpdateWord(std::vector<uint8_t>*buf, int offset, int data) {
843  (*buf)[offset+0] = data;
844  (*buf)[offset+1] = data >> 8;
845  (*buf)[offset+2] = data >> 16;
846  (*buf)[offset+3] = data >> 24;
847}
848
849static void PushWord(std::vector<uint8_t>*buf, int data) {
850  buf->push_back(data & 0xff);
851  buf->push_back((data >> 8) & 0xff);
852  buf->push_back((data >> 16) & 0xff);
853  buf->push_back((data >> 24) & 0xff);
854}
855
856static void PushHalf(std::vector<uint8_t>*buf, int data) {
857  buf->push_back(data & 0xff);
858  buf->push_back((data >> 8) & 0xff);
859}
860
861// DWARF constants needed to generate CFI information.
862enum {
863  // Tag encodings.
864  DW_TAG_compile_unit = 0x11,
865  DW_TAG_subprogram = 0X2e,
866
867  // Attribute encodings.
868  DW_AT_name = 0x03,
869  DW_AT_low_pc = 0x11,
870  DW_AT_high_pc = 0x12,
871  DW_AT_language = 0x13,
872
873  // Constant encoding.
874  DW_CHILDREN_no = 0x00,
875  DW_CHILDREN_yes = 0x01,
876
877  // Attribute form encodings.
878  DW_FORM_addr = 0x01,
879  DW_FORM_data1 = 0x0b,
880  DW_FORM_strp = 0x0e,
881
882  // Language encoding.
883  DW_LANG_Java = 0x000b
884};
885
886void ElfWriterQuick::FillInCFIInformation(OatWriter* oat_writer,
887                                          std::vector<uint8_t>* dbg_info,
888                                          std::vector<uint8_t>* dbg_abbrev,
889                                          std::vector<uint8_t>* dbg_str) {
890  // Create the debug_abbrev section with boilerplate information.
891  // We only care about low_pc and high_pc right now for the compilation
892  // unit and methods.
893
894  // Tag 1: Compilation unit: DW_TAG_compile_unit.
895  dbg_abbrev->push_back(1);
896  dbg_abbrev->push_back(DW_TAG_compile_unit);
897
898  // There are children (the methods).
899  dbg_abbrev->push_back(DW_CHILDREN_yes);
900
901  // DW_LANG_Java DW_FORM_data1.
902  dbg_abbrev->push_back(DW_AT_language);
903  dbg_abbrev->push_back(DW_FORM_data1);
904
905  // DW_AT_low_pc DW_FORM_addr.
906  dbg_abbrev->push_back(DW_AT_low_pc);
907  dbg_abbrev->push_back(DW_FORM_addr);
908
909  // DW_AT_high_pc DW_FORM_addr.
910  dbg_abbrev->push_back(DW_AT_high_pc);
911  dbg_abbrev->push_back(DW_FORM_addr);
912
913  // End of DW_TAG_compile_unit.
914  PushHalf(dbg_abbrev, 0);
915
916  // Tag 2: Compilation unit: DW_TAG_subprogram.
917  dbg_abbrev->push_back(2);
918  dbg_abbrev->push_back(DW_TAG_subprogram);
919
920  // There are no children.
921  dbg_abbrev->push_back(DW_CHILDREN_no);
922
923  // Name of the method.
924  dbg_abbrev->push_back(DW_AT_name);
925  dbg_abbrev->push_back(DW_FORM_strp);
926
927  // DW_AT_low_pc DW_FORM_addr.
928  dbg_abbrev->push_back(DW_AT_low_pc);
929  dbg_abbrev->push_back(DW_FORM_addr);
930
931  // DW_AT_high_pc DW_FORM_addr.
932  dbg_abbrev->push_back(DW_AT_high_pc);
933  dbg_abbrev->push_back(DW_FORM_addr);
934
935  // End of DW_TAG_subprogram.
936  PushHalf(dbg_abbrev, 0);
937
938  // Start the debug_info section with the header information
939  // 'unit_length' will be filled in later.
940  PushWord(dbg_info, 0);
941
942  // 'version' - 3.
943  PushHalf(dbg_info, 3);
944
945  // Offset into .debug_abbrev section (always 0).
946  PushWord(dbg_info, 0);
947
948  // Address size: 4.
949  dbg_info->push_back(4);
950
951  // Start the description for the compilation unit.
952  // This uses tag 1.
953  dbg_info->push_back(1);
954
955  // The language is Java.
956  dbg_info->push_back(DW_LANG_Java);
957
958  // Leave space for low_pc and high_pc.
959  int low_pc_offset = dbg_info->size();
960  PushWord(dbg_info, 0);
961  PushWord(dbg_info, 0);
962
963  // Walk through the information in the method table, and enter into dbg_info.
964  const std::vector<OatWriter::DebugInfo>& dbg = oat_writer->GetCFIMethodInfo();
965  uint32_t low_pc = 0xFFFFFFFFU;
966  uint32_t high_pc = 0;
967
968  for (uint32_t i = 0; i < dbg.size(); i++) {
969    const OatWriter::DebugInfo& info = dbg[i];
970    if (info.low_pc_ < low_pc) {
971      low_pc = info.low_pc_;
972    }
973    if (info.high_pc_ > high_pc) {
974      high_pc = info.high_pc_;
975    }
976
977    // Start a new TAG: subroutine (2).
978    dbg_info->push_back(2);
979
980    // Enter the name into the string table (and NUL terminate).
981    uint32_t str_offset = dbg_str->size();
982    dbg_str->insert(dbg_str->end(), info.method_name_.begin(), info.method_name_.end());
983    dbg_str->push_back('\0');
984
985    // Enter name, low_pc, high_pc.
986    PushWord(dbg_info, str_offset);
987    PushWord(dbg_info, info.low_pc_);
988    PushWord(dbg_info, info.high_pc_);
989  }
990
991  // One byte terminator
992  dbg_info->push_back(0);
993
994  // We have now walked all the methods.  Fill in lengths and low/high PCs.
995  UpdateWord(dbg_info, 0, dbg_info->size() - 4);
996  UpdateWord(dbg_info, low_pc_offset, low_pc);
997  UpdateWord(dbg_info, low_pc_offset + 4, high_pc);
998}
999
1000}  // namespace art
1001