elf_writer_quick.cc revision 3470ab4011b5e18d590d5375e2f13a1e3bd69222
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 "dwarf.h"
24#include "elf_utils.h"
25#include "file_output_stream.h"
26#include "globals.h"
27#include "oat.h"
28#include "oat_writer.h"
29#include "utils.h"
30
31namespace art {
32
33static constexpr Elf32_Word NextOffset(const Elf32_Shdr& cur, const Elf32_Shdr& prev) {
34  return RoundUp(prev.sh_size + prev.sh_offset, cur.sh_addralign);
35}
36
37static uint8_t MakeStInfo(uint8_t binding, uint8_t type) {
38  return ((binding) << 4) + ((type) & 0xf);
39}
40
41bool ElfWriterQuick::ElfBuilder::Write() {
42  // The basic layout of the elf file. Order may be different in final output.
43  // +-------------------------+
44  // | Elf32_Ehdr              |
45  // +-------------------------+
46  // | Elf32_Phdr PHDR         |
47  // | Elf32_Phdr LOAD R       | .dynsym .dynstr .hash .rodata
48  // | Elf32_Phdr LOAD R X     | .text
49  // | Elf32_Phdr LOAD RW      | .dynamic
50  // | Elf32_Phdr DYNAMIC      | .dynamic
51  // +-------------------------+
52  // | .dynsym                 |
53  // | Elf32_Sym  STN_UNDEF    |
54  // | Elf32_Sym  oatdata      |
55  // | Elf32_Sym  oatexec      |
56  // | Elf32_Sym  oatlastword  |
57  // +-------------------------+
58  // | .dynstr                 |
59  // | \0                      |
60  // | oatdata\0               |
61  // | oatexec\0               |
62  // | oatlastword\0           |
63  // | boot.oat\0              |
64  // +-------------------------+
65  // | .hash                   |
66  // | Elf32_Word nbucket = b  |
67  // | Elf32_Word nchain  = c  |
68  // | Elf32_Word bucket[0]    |
69  // |         ...             |
70  // | Elf32_Word bucket[b - 1]|
71  // | Elf32_Word chain[0]     |
72  // |         ...             |
73  // | Elf32_Word chain[c - 1] |
74  // +-------------------------+
75  // | .rodata                 |
76  // | oatdata..oatexec-4      |
77  // +-------------------------+
78  // | .text                   |
79  // | oatexec..oatlastword    |
80  // +-------------------------+
81  // | .dynamic                |
82  // | Elf32_Dyn DT_SONAME     |
83  // | Elf32_Dyn DT_HASH       |
84  // | Elf32_Dyn DT_SYMTAB     |
85  // | Elf32_Dyn DT_SYMENT     |
86  // | Elf32_Dyn DT_STRTAB     |
87  // | Elf32_Dyn DT_STRSZ      |
88  // | Elf32_Dyn DT_NULL       |
89  // +-------------------------+  (Optional)
90  // | .strtab                 |  (Optional)
91  // | program symbol names    |  (Optional)
92  // +-------------------------+  (Optional)
93  // | .symtab                 |  (Optional)
94  // | program symbols         |  (Optional)
95  // +-------------------------+
96  // | .shstrtab               |
97  // | \0                      |
98  // | .dynamic\0              |
99  // | .dynsym\0               |
100  // | .dynstr\0               |
101  // | .hash\0                 |
102  // | .rodata\0               |
103  // | .text\0                 |
104  // | .shstrtab\0             |
105  // | .symtab\0               |  (Optional)
106  // | .strtab\0               |  (Optional)
107  // | .debug_str\0            |  (Optional)
108  // | .debug_info\0           |  (Optional)
109  // | .debug_frame\0          |  (Optional)
110  // | .debug_abbrev\0         |  (Optional)
111  // +-------------------------+  (Optional)
112  // | .debug_str              |  (Optional)
113  // +-------------------------+  (Optional)
114  // | .debug_info             |  (Optional)
115  // +-------------------------+  (Optional)
116  // | .debug_frame            |  (Optional)
117  // +-------------------------+  (Optional)
118  // | .debug_abbrev           |  (Optional)
119  // +-------------------------+
120  // | Elf32_Shdr NULL         |
121  // | Elf32_Shdr .dynsym      |
122  // | Elf32_Shdr .dynstr      |
123  // | Elf32_Shdr .hash        |
124  // | Elf32_Shdr .text        |
125  // | Elf32_Shdr .rodata      |
126  // | Elf32_Shdr .dynamic     |
127  // | Elf32_Shdr .shstrtab    |
128  // | Elf32_Shdr .debug_str   |  (Optional)
129  // | Elf32_Shdr .debug_info  |  (Optional)
130  // | Elf32_Shdr .debug_frame |  (Optional)
131  // | Elf32_Shdr .debug_abbrev|  (Optional)
132  // +-------------------------+
133
134
135  if (fatal_error_) {
136    return false;
137  }
138  // Step 1. Figure out all the offsets.
139
140  // What phdr is.
141  uint32_t phdr_offset = sizeof(Elf32_Ehdr);
142  const uint8_t PH_PHDR     = 0;
143  const uint8_t PH_LOAD_R__ = 1;
144  const uint8_t PH_LOAD_R_X = 2;
145  const uint8_t PH_LOAD_RW_ = 3;
146  const uint8_t PH_DYNAMIC  = 4;
147  const uint8_t PH_NUM      = 5;
148  uint32_t phdr_size = sizeof(Elf32_Phdr) * PH_NUM;
149  if (debug_logging_) {
150    LOG(INFO) << "phdr_offset=" << phdr_offset << std::hex << " " << phdr_offset;
151    LOG(INFO) << "phdr_size=" << phdr_size << std::hex << " " << phdr_size;
152  }
153  Elf32_Phdr program_headers[PH_NUM];
154  memset(&program_headers, 0, sizeof(program_headers));
155  program_headers[PH_PHDR].p_type    = PT_PHDR;
156  program_headers[PH_PHDR].p_offset  = phdr_offset;
157  program_headers[PH_PHDR].p_vaddr   = phdr_offset;
158  program_headers[PH_PHDR].p_paddr   = phdr_offset;
159  program_headers[PH_PHDR].p_filesz  = sizeof(program_headers);
160  program_headers[PH_PHDR].p_memsz   = sizeof(program_headers);
161  program_headers[PH_PHDR].p_flags   = PF_R;
162  program_headers[PH_PHDR].p_align   = sizeof(Elf32_Word);
163
164  program_headers[PH_LOAD_R__].p_type    = PT_LOAD;
165  program_headers[PH_LOAD_R__].p_offset  = 0;
166  program_headers[PH_LOAD_R__].p_vaddr   = 0;
167  program_headers[PH_LOAD_R__].p_paddr   = 0;
168  program_headers[PH_LOAD_R__].p_flags   = PF_R;
169
170  program_headers[PH_LOAD_R_X].p_type    = PT_LOAD;
171  program_headers[PH_LOAD_R_X].p_flags   = PF_R | PF_X;
172
173  program_headers[PH_LOAD_RW_].p_type    = PT_LOAD;
174  program_headers[PH_LOAD_RW_].p_flags   = PF_R | PF_W;
175
176  program_headers[PH_DYNAMIC].p_type    = PT_DYNAMIC;
177  program_headers[PH_DYNAMIC].p_flags   = PF_R | PF_W;
178
179  // Get the dynstr string.
180  std::string dynstr(dynsym_builder_.GenerateStrtab());
181
182  // Add the SONAME to the dynstr.
183  uint32_t dynstr_soname_offset = dynstr.size();
184  std::string file_name(elf_file_->GetPath());
185  size_t directory_separator_pos = file_name.rfind('/');
186  if (directory_separator_pos != std::string::npos) {
187    file_name = file_name.substr(directory_separator_pos + 1);
188  }
189  dynstr += file_name;
190  dynstr += '\0';
191  if (debug_logging_) {
192    LOG(INFO) << "dynstr size (bytes)   =" << dynstr.size()
193              << std::hex << " " << dynstr.size();
194    LOG(INFO) << "dynsym size (elements)=" << dynsym_builder_.GetSize()
195              << std::hex << " " << dynsym_builder_.GetSize();
196  }
197
198  // get the strtab
199  std::string strtab;
200  if (IncludingDebugSymbols()) {
201    strtab = symtab_builder_.GenerateStrtab();
202    if (debug_logging_) {
203      LOG(INFO) << "strtab size (bytes)    =" << strtab.size()
204                << std::hex << " " << strtab.size();
205      LOG(INFO) << "symtab size (elements) =" << symtab_builder_.GetSize()
206                << std::hex << " " << symtab_builder_.GetSize();
207    }
208  }
209
210  // Get the section header string table.
211  std::vector<Elf32_Shdr*> section_ptrs;
212  std::string shstrtab;
213  shstrtab += '\0';
214
215  // Setup sym_undef
216  Elf32_Shdr null_hdr;
217  memset(&null_hdr, 0, sizeof(null_hdr));
218  null_hdr.sh_type = SHT_NULL;
219  null_hdr.sh_link = SHN_UNDEF;
220  section_ptrs.push_back(&null_hdr);
221
222  uint32_t section_index = 1;
223
224  // setup .dynsym
225  section_ptrs.push_back(&dynsym_builder_.section_);
226  AssignSectionStr(&dynsym_builder_, &shstrtab);
227  dynsym_builder_.section_index_ = section_index++;
228
229  // Setup .dynstr
230  section_ptrs.push_back(&dynsym_builder_.strtab_.section_);
231  AssignSectionStr(&dynsym_builder_.strtab_, &shstrtab);
232  dynsym_builder_.strtab_.section_index_ = section_index++;
233
234  // Setup .hash
235  section_ptrs.push_back(&hash_builder_.section_);
236  AssignSectionStr(&hash_builder_, &shstrtab);
237  hash_builder_.section_index_ = section_index++;
238
239  // Setup .rodata
240  section_ptrs.push_back(&rodata_builder_.section_);
241  AssignSectionStr(&rodata_builder_, &shstrtab);
242  rodata_builder_.section_index_ = section_index++;
243
244  // Setup .text
245  section_ptrs.push_back(&text_builder_.section_);
246  AssignSectionStr(&text_builder_, &shstrtab);
247  text_builder_.section_index_ = section_index++;
248
249  // Setup .dynamic
250  section_ptrs.push_back(&dynamic_builder_.section_);
251  AssignSectionStr(&dynamic_builder_, &shstrtab);
252  dynamic_builder_.section_index_ = section_index++;
253
254  if (IncludingDebugSymbols()) {
255    // Setup .symtab
256    section_ptrs.push_back(&symtab_builder_.section_);
257    AssignSectionStr(&symtab_builder_, &shstrtab);
258    symtab_builder_.section_index_ = section_index++;
259
260    // Setup .strtab
261    section_ptrs.push_back(&symtab_builder_.strtab_.section_);
262    AssignSectionStr(&symtab_builder_.strtab_, &shstrtab);
263    symtab_builder_.strtab_.section_index_ = section_index++;
264  }
265  ElfRawSectionBuilder* it = other_builders_.data();
266  for (uint32_t cnt = 0; cnt < other_builders_.size(); ++it, ++cnt) {
267    // Setup all the other sections.
268    section_ptrs.push_back(&it->section_);
269    AssignSectionStr(it, &shstrtab);
270    it->section_index_ = section_index++;
271  }
272
273  // Setup shstrtab
274  section_ptrs.push_back(&shstrtab_builder_.section_);
275  AssignSectionStr(&shstrtab_builder_, &shstrtab);
276  shstrtab_builder_.section_index_ = section_index++;
277
278  if (debug_logging_) {
279    LOG(INFO) << ".shstrtab size    (bytes)   =" << shstrtab.size()
280              << std::hex << " " << shstrtab.size();
281    LOG(INFO) << "section list size (elements)=" << section_ptrs.size()
282              << std::hex << " " << section_ptrs.size();
283  }
284
285  // Fill in the hash section.
286  std::vector<Elf32_Word> hash = dynsym_builder_.GenerateHashContents();
287
288  if (debug_logging_) {
289    LOG(INFO) << ".hash size (bytes)=" << hash.size() * sizeof(Elf32_Word)
290              << std::hex << " " << hash.size() * sizeof(Elf32_Word);
291  }
292
293  Elf32_Word base_offset = sizeof(Elf32_Ehdr) + sizeof(program_headers);
294  std::vector<ElfFilePiece> pieces;
295
296  // Get the layout in the sections.
297  //
298  // Get the layout of the dynsym section.
299  dynsym_builder_.section_.sh_offset = RoundUp(base_offset, dynsym_builder_.section_.sh_addralign);
300  dynsym_builder_.section_.sh_addr = dynsym_builder_.section_.sh_offset;
301  dynsym_builder_.section_.sh_size = dynsym_builder_.GetSize() * sizeof(Elf32_Sym);
302  dynsym_builder_.section_.sh_link = dynsym_builder_.GetLink();
303
304  // Get the layout of the dynstr section.
305  dynsym_builder_.strtab_.section_.sh_offset = NextOffset(dynsym_builder_.strtab_.section_,
306                                                          dynsym_builder_.section_);
307  dynsym_builder_.strtab_.section_.sh_addr = dynsym_builder_.strtab_.section_.sh_offset;
308  dynsym_builder_.strtab_.section_.sh_size = dynstr.size();
309  dynsym_builder_.strtab_.section_.sh_link = dynsym_builder_.strtab_.GetLink();
310
311  // Get the layout of the hash section
312  hash_builder_.section_.sh_offset = NextOffset(hash_builder_.section_,
313                                                dynsym_builder_.strtab_.section_);
314  hash_builder_.section_.sh_addr = hash_builder_.section_.sh_offset;
315  hash_builder_.section_.sh_size = hash.size() * sizeof(Elf32_Word);
316  hash_builder_.section_.sh_link = hash_builder_.GetLink();
317
318  // Get the layout of the rodata section.
319  rodata_builder_.section_.sh_offset = NextOffset(rodata_builder_.section_,
320                                                  hash_builder_.section_);
321  rodata_builder_.section_.sh_addr = rodata_builder_.section_.sh_offset;
322  rodata_builder_.section_.sh_size = rodata_builder_.size_;
323  rodata_builder_.section_.sh_link = rodata_builder_.GetLink();
324
325  // Get the layout of the text section.
326  text_builder_.section_.sh_offset = NextOffset(text_builder_.section_, rodata_builder_.section_);
327  text_builder_.section_.sh_addr = text_builder_.section_.sh_offset;
328  text_builder_.section_.sh_size = text_builder_.size_;
329  text_builder_.section_.sh_link = text_builder_.GetLink();
330  CHECK_ALIGNED(rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size, kPageSize);
331
332  // Get the layout of the dynamic section.
333  dynamic_builder_.section_.sh_offset = NextOffset(dynamic_builder_.section_,
334                                                   text_builder_.section_);
335  dynamic_builder_.section_.sh_addr = dynamic_builder_.section_.sh_offset;
336  dynamic_builder_.section_.sh_size = dynamic_builder_.GetSize() * sizeof(Elf32_Dyn);
337  dynamic_builder_.section_.sh_link = dynamic_builder_.GetLink();
338
339  Elf32_Shdr prev = dynamic_builder_.section_;
340  if (IncludingDebugSymbols()) {
341    // Get the layout of the symtab section.
342    symtab_builder_.section_.sh_offset = NextOffset(symtab_builder_.section_,
343                                                    dynamic_builder_.section_);
344    symtab_builder_.section_.sh_addr = 0;
345    // Add to leave space for the null symbol.
346    symtab_builder_.section_.sh_size = symtab_builder_.GetSize() * sizeof(Elf32_Sym);
347    symtab_builder_.section_.sh_link = symtab_builder_.GetLink();
348
349    // Get the layout of the dynstr section.
350    symtab_builder_.strtab_.section_.sh_offset = NextOffset(symtab_builder_.strtab_.section_,
351                                                            symtab_builder_.section_);
352    symtab_builder_.strtab_.section_.sh_addr = 0;
353    symtab_builder_.strtab_.section_.sh_size = strtab.size();
354    symtab_builder_.strtab_.section_.sh_link = symtab_builder_.strtab_.GetLink();
355
356    prev = symtab_builder_.strtab_.section_;
357  }
358  if (debug_logging_) {
359    LOG(INFO) << "dynsym off=" << dynsym_builder_.section_.sh_offset
360              << " dynsym size=" << dynsym_builder_.section_.sh_size;
361    LOG(INFO) << "dynstr off=" << dynsym_builder_.strtab_.section_.sh_offset
362              << " dynstr size=" << dynsym_builder_.strtab_.section_.sh_size;
363    LOG(INFO) << "hash off=" << hash_builder_.section_.sh_offset
364              << " hash size=" << hash_builder_.section_.sh_size;
365    LOG(INFO) << "rodata off=" << rodata_builder_.section_.sh_offset
366              << " rodata size=" << rodata_builder_.section_.sh_size;
367    LOG(INFO) << "text off=" << text_builder_.section_.sh_offset
368              << " text size=" << text_builder_.section_.sh_size;
369    LOG(INFO) << "dynamic off=" << dynamic_builder_.section_.sh_offset
370              << " dynamic size=" << dynamic_builder_.section_.sh_size;
371    if (IncludingDebugSymbols()) {
372      LOG(INFO) << "symtab off=" << symtab_builder_.section_.sh_offset
373                << " symtab size=" << symtab_builder_.section_.sh_size;
374      LOG(INFO) << "strtab off=" << symtab_builder_.strtab_.section_.sh_offset
375                << " strtab size=" << symtab_builder_.strtab_.section_.sh_size;
376    }
377  }
378  // Get the layout of the extra sections. (This will deal with the debug
379  // sections if they are there)
380  for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
381    it->section_.sh_offset = NextOffset(it->section_, prev);
382    it->section_.sh_addr = 0;
383    it->section_.sh_size = it->GetBuffer()->size();
384    it->section_.sh_link = it->GetLink();
385    pieces.push_back(ElfFilePiece(it->name_, it->section_.sh_offset,
386                                  it->GetBuffer()->data(), it->GetBuffer()->size()));
387    prev = it->section_;
388    if (debug_logging_) {
389      LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
390                << " " << it->name_ << " size=" << it->section_.sh_size;
391    }
392  }
393  // Get the layout of the shstrtab section
394  shstrtab_builder_.section_.sh_offset = NextOffset(shstrtab_builder_.section_, prev);
395  shstrtab_builder_.section_.sh_addr = 0;
396  shstrtab_builder_.section_.sh_size = shstrtab.size();
397  shstrtab_builder_.section_.sh_link = shstrtab_builder_.GetLink();
398  if (debug_logging_) {
399      LOG(INFO) << "shstrtab off=" << shstrtab_builder_.section_.sh_offset
400                << " shstrtab size=" << shstrtab_builder_.section_.sh_size;
401  }
402
403  // The section list comes after come after.
404  Elf32_Word sections_offset = RoundUp(
405      shstrtab_builder_.section_.sh_offset + shstrtab_builder_.section_.sh_size,
406      sizeof(Elf32_Word));
407
408  // Setup the actual symbol arrays.
409  std::vector<Elf32_Sym> dynsym = dynsym_builder_.GenerateSymtab();
410  CHECK_EQ(dynsym.size() * sizeof(Elf32_Sym), dynsym_builder_.section_.sh_size);
411  std::vector<Elf32_Sym> symtab;
412  if (IncludingDebugSymbols()) {
413    symtab = symtab_builder_.GenerateSymtab();
414    CHECK_EQ(symtab.size() * sizeof(Elf32_Sym), symtab_builder_.section_.sh_size);
415  }
416
417  // Setup the dynamic section.
418  // This will add the 2 values we cannot know until now time, namely the size
419  // and the soname_offset.
420  std::vector<Elf32_Dyn> dynamic = dynamic_builder_.GetDynamics(dynstr.size(),
421                                                                dynstr_soname_offset);
422  CHECK_EQ(dynamic.size() * sizeof(Elf32_Dyn), dynamic_builder_.section_.sh_size);
423
424  // Finish setup of the program headers now that we know the layout of the
425  // whole file.
426  Elf32_Word load_r_size = rodata_builder_.section_.sh_offset + rodata_builder_.section_.sh_size;
427  program_headers[PH_LOAD_R__].p_filesz = load_r_size;
428  program_headers[PH_LOAD_R__].p_memsz =  load_r_size;
429  program_headers[PH_LOAD_R__].p_align =  rodata_builder_.section_.sh_addralign;
430
431  Elf32_Word load_rx_size = text_builder_.section_.sh_size;
432  program_headers[PH_LOAD_R_X].p_offset = text_builder_.section_.sh_offset;
433  program_headers[PH_LOAD_R_X].p_vaddr  = text_builder_.section_.sh_offset;
434  program_headers[PH_LOAD_R_X].p_paddr  = text_builder_.section_.sh_offset;
435  program_headers[PH_LOAD_R_X].p_filesz = load_rx_size;
436  program_headers[PH_LOAD_R_X].p_memsz  = load_rx_size;
437  program_headers[PH_LOAD_R_X].p_align  = text_builder_.section_.sh_addralign;
438
439  program_headers[PH_LOAD_RW_].p_offset = dynamic_builder_.section_.sh_offset;
440  program_headers[PH_LOAD_RW_].p_vaddr  = dynamic_builder_.section_.sh_offset;
441  program_headers[PH_LOAD_RW_].p_paddr  = dynamic_builder_.section_.sh_offset;
442  program_headers[PH_LOAD_RW_].p_filesz = dynamic_builder_.section_.sh_size;
443  program_headers[PH_LOAD_RW_].p_memsz  = dynamic_builder_.section_.sh_size;
444  program_headers[PH_LOAD_RW_].p_align  = dynamic_builder_.section_.sh_addralign;
445
446  program_headers[PH_DYNAMIC].p_offset = dynamic_builder_.section_.sh_offset;
447  program_headers[PH_DYNAMIC].p_vaddr  = dynamic_builder_.section_.sh_offset;
448  program_headers[PH_DYNAMIC].p_paddr  = dynamic_builder_.section_.sh_offset;
449  program_headers[PH_DYNAMIC].p_filesz = dynamic_builder_.section_.sh_size;
450  program_headers[PH_DYNAMIC].p_memsz  = dynamic_builder_.section_.sh_size;
451  program_headers[PH_DYNAMIC].p_align  = dynamic_builder_.section_.sh_addralign;
452
453  // Finish setup of the Ehdr values.
454  elf_header_.e_phoff = phdr_offset;
455  elf_header_.e_shoff = sections_offset;
456  elf_header_.e_phnum = PH_NUM;
457  elf_header_.e_shnum = section_ptrs.size();
458  elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
459
460  // Add the rest of the pieces to the list.
461  pieces.push_back(ElfFilePiece("Elf Header", 0, &elf_header_, sizeof(elf_header_)));
462  pieces.push_back(ElfFilePiece("Program headers", phdr_offset,
463                                &program_headers, sizeof(program_headers)));
464  pieces.push_back(ElfFilePiece(".dynamic", dynamic_builder_.section_.sh_offset,
465                                dynamic.data(), dynamic_builder_.section_.sh_size));
466  pieces.push_back(ElfFilePiece(".dynsym", dynsym_builder_.section_.sh_offset,
467                                dynsym.data(), dynsym.size() * sizeof(Elf32_Sym)));
468  pieces.push_back(ElfFilePiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset,
469                                dynstr.c_str(), dynstr.size()));
470  pieces.push_back(ElfFilePiece(".hash", hash_builder_.section_.sh_offset,
471                                hash.data(), hash.size() * sizeof(Elf32_Word)));
472  pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset,
473                                nullptr, rodata_builder_.section_.sh_size));
474  pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset,
475                                nullptr, text_builder_.section_.sh_size));
476  if (IncludingDebugSymbols()) {
477    pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset,
478                                  symtab.data(), symtab.size() * sizeof(Elf32_Sym)));
479    pieces.push_back(ElfFilePiece(".strtab", symtab_builder_.strtab_.section_.sh_offset,
480                                  strtab.c_str(), strtab.size()));
481  }
482  pieces.push_back(ElfFilePiece(".shstrtab", shstrtab_builder_.section_.sh_offset,
483                                &shstrtab[0], shstrtab.size()));
484  for (uint32_t i = 0; i < section_ptrs.size(); ++i) {
485    // Just add all the sections in induvidually since they are all over the
486    // place on the heap/stack.
487    Elf32_Word cur_off = sections_offset + i * sizeof(Elf32_Shdr);
488    pieces.push_back(ElfFilePiece("section table piece", cur_off,
489                                  section_ptrs[i], sizeof(Elf32_Shdr)));
490  }
491
492  if (!WriteOutFile(pieces)) {
493    LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();
494    return false;
495  }
496  // write out the actual oat file data.
497  Elf32_Word oat_data_offset = rodata_builder_.section_.sh_offset;
498  if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) {
499    PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset
500                << " for " << elf_file_->GetPath();
501    return false;
502  }
503  std::unique_ptr<BufferedOutputStream> output_stream(
504      new BufferedOutputStream(new FileOutputStream(elf_file_)));
505  if (!oat_writer_->Write(output_stream.get())) {
506    PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath();
507    return false;
508  }
509
510  return true;
511}
512
513bool ElfWriterQuick::ElfBuilder::WriteOutFile(const std::vector<ElfFilePiece>& pieces) {
514  // TODO It would be nice if this checked for overlap.
515  for (auto it = pieces.begin(); it != pieces.end(); ++it) {
516    if (it->data_) {
517      if (static_cast<off_t>(it->offset_) != lseek(elf_file_->Fd(), it->offset_, SEEK_SET)) {
518        PLOG(ERROR) << "Failed to seek to " << it->dbg_name_ << " offset location "
519                    << it->offset_ << " for " << elf_file_->GetPath();
520        return false;
521      }
522      if (!elf_file_->WriteFully(it->data_, it->size_)) {
523        PLOG(ERROR) << "Failed to write " << it->dbg_name_ << " for " << elf_file_->GetPath();
524        return false;
525      }
526    }
527  }
528  return true;
529}
530
531void ElfWriterQuick::ElfBuilder::SetupDynamic() {
532  dynamic_builder_.AddDynamicTag(DT_HASH, 0, &hash_builder_);
533  dynamic_builder_.AddDynamicTag(DT_STRTAB, 0, &dynsym_builder_.strtab_);
534  dynamic_builder_.AddDynamicTag(DT_SYMTAB, 0, &dynsym_builder_);
535  dynamic_builder_.AddDynamicTag(DT_SYMENT, sizeof(Elf32_Sym));
536}
537
538void ElfWriterQuick::ElfBuilder::SetupRequiredSymbols() {
539  dynsym_builder_.AddSymbol("oatdata", &rodata_builder_, 0, true,
540                            rodata_builder_.size_, STB_GLOBAL, STT_OBJECT);
541  dynsym_builder_.AddSymbol("oatexec", &text_builder_, 0, true,
542                            text_builder_.size_, STB_GLOBAL, STT_OBJECT);
543  dynsym_builder_.AddSymbol("oatlastword", &text_builder_, text_builder_.size_ - 4,
544                            true, 4, STB_GLOBAL, STT_OBJECT);
545}
546
547void ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un) {
548  if (tag == DT_NULL) {
549    return;
550  }
551  dynamics_.push_back({nullptr, tag, d_un});
552}
553
554void ElfWriterQuick::ElfDynamicBuilder::AddDynamicTag(Elf32_Sword tag, Elf32_Word d_un,
555                                                      ElfSectionBuilder* section) {
556  if (tag == DT_NULL) {
557    return;
558  }
559  dynamics_.push_back({section, tag, d_un});
560}
561
562std::vector<Elf32_Dyn> ElfWriterQuick::ElfDynamicBuilder::GetDynamics(Elf32_Word strsz,
563                                                                      Elf32_Word soname) {
564  std::vector<Elf32_Dyn> ret;
565  for (auto it = dynamics_.cbegin(); it != dynamics_.cend(); ++it) {
566    if (it->section_) {
567      // We are adding an address relative to a section.
568      ret.push_back(
569          {it->tag_, {it->off_ + it->section_->section_.sh_addr}});
570    } else {
571      ret.push_back({it->tag_, {it->off_}});
572    }
573  }
574  ret.push_back({DT_STRSZ, {strsz}});
575  ret.push_back({DT_SONAME, {soname}});
576  ret.push_back({DT_NULL, {0}});
577  return ret;
578}
579
580std::vector<Elf32_Sym> ElfWriterQuick::ElfSymtabBuilder::GenerateSymtab() {
581  std::vector<Elf32_Sym> ret;
582  Elf32_Sym undef_sym;
583  memset(&undef_sym, 0, sizeof(undef_sym));
584  undef_sym.st_shndx = SHN_UNDEF;
585  ret.push_back(undef_sym);
586
587  for (auto it = symbols_.cbegin(); it != symbols_.cend(); ++it) {
588    Elf32_Sym sym;
589    memset(&sym, 0, sizeof(sym));
590    sym.st_name = it->name_idx_;
591    if (it->is_relative_) {
592      sym.st_value = it->addr_ + it->section_->section_.sh_offset;
593    } else {
594      sym.st_value = it->addr_;
595    }
596    sym.st_size = it->size_;
597    sym.st_other = it->other_;
598    sym.st_shndx = it->section_->section_index_;
599    sym.st_info = it->info_;
600
601    ret.push_back(sym);
602  }
603  return ret;
604}
605
606std::string ElfWriterQuick::ElfSymtabBuilder::GenerateStrtab() {
607  std::string tab;
608  tab += '\0';
609  for (auto it = symbols_.begin(); it != symbols_.end(); ++it) {
610    it->name_idx_ = tab.size();
611    tab += it->name_;
612    tab += '\0';
613  }
614  strtab_.section_.sh_size = tab.size();
615  return tab;
616}
617
618void ElfWriterQuick::ElfBuilder::AssignSectionStr(
619    ElfSectionBuilder* builder, std::string* strtab) {
620  builder->section_.sh_name = strtab->size();
621  *strtab += builder->name_;
622  *strtab += '\0';
623  if (debug_logging_) {
624    LOG(INFO) << "adding section name \"" << builder->name_ << "\" "
625              << "to shstrtab at offset " << builder->section_.sh_name;
626  }
627}
628
629// from bionic
630static unsigned elfhash(const char *_name) {
631  const unsigned char *name = (const unsigned char *) _name;
632  unsigned h = 0, g;
633
634  while (*name) {
635    h = (h << 4) + *name++;
636    g = h & 0xf0000000;
637    h ^= g;
638    h ^= g >> 24;
639  }
640  return h;
641}
642
643
644std::vector<Elf32_Word> ElfWriterQuick::ElfSymtabBuilder::GenerateHashContents() {
645  // Here is how The ELF hash table works.
646  // There are 3 arrays to worry about.
647  // * The symbol table where the symbol information is.
648  // * The bucket array which is an array of indexes into the symtab and chain.
649  // * The chain array which is also an array of indexes into the symtab and chain.
650  //
651  // Lets say the state is something like this.
652  // +--------+       +--------+      +-----------+
653  // | symtab |       | bucket |      |   chain   |
654  // |  nullptr  |       | 1      |      | STN_UNDEF |
655  // | <sym1> |       | 4      |      | 2         |
656  // | <sym2> |       |        |      | 5         |
657  // | <sym3> |       |        |      | STN_UNDEF |
658  // | <sym4> |       |        |      | 3         |
659  // | <sym5> |       |        |      | STN_UNDEF |
660  // +--------+       +--------+      +-----------+
661  //
662  // The lookup process (in python psudocode) is
663  //
664  // def GetSym(name):
665  //     # NB STN_UNDEF == 0
666  //     indx = bucket[elfhash(name) % num_buckets]
667  //     while indx != STN_UNDEF:
668  //         if GetSymbolName(symtab[indx]) == name:
669  //             return symtab[indx]
670  //         indx = chain[indx]
671  //     return SYMBOL_NOT_FOUND
672  //
673  // Between bucket and chain arrays every symtab index must be present exactly
674  // once (except for STN_UNDEF, which must be present 1 + num_bucket times).
675
676  // Select number of buckets.
677  // This is essentially arbitrary.
678  Elf32_Word nbuckets;
679  Elf32_Word chain_size = GetSize();
680  if (symbols_.size() < 8) {
681    nbuckets = 2;
682  } else if (symbols_.size() < 32) {
683    nbuckets = 4;
684  } else if (symbols_.size() < 256) {
685    nbuckets = 16;
686  } else {
687    // Have about 32 ids per bucket.
688    nbuckets = RoundUp(symbols_.size()/32, 2);
689  }
690  std::vector<Elf32_Word> hash;
691  hash.push_back(nbuckets);
692  hash.push_back(chain_size);
693  uint32_t bucket_offset = hash.size();
694  uint32_t chain_offset = bucket_offset + nbuckets;
695  hash.resize(hash.size() + nbuckets + chain_size, 0);
696
697  Elf32_Word* buckets = hash.data() + bucket_offset;
698  Elf32_Word* chain   = hash.data() + chain_offset;
699
700  // Set up the actual hash table.
701  for (Elf32_Word i = 0; i < symbols_.size(); i++) {
702    // Add 1 since we need to have the null symbol that is not in the symbols
703    // list.
704    Elf32_Word index = i + 1;
705    Elf32_Word hash_val = static_cast<Elf32_Word>(elfhash(symbols_[i].name_.c_str())) % nbuckets;
706    if (buckets[hash_val] == 0) {
707      buckets[hash_val] = index;
708    } else {
709      hash_val = buckets[hash_val];
710      CHECK_LT(hash_val, chain_size);
711      while (chain[hash_val] != 0) {
712        hash_val = chain[hash_val];
713        CHECK_LT(hash_val, chain_size);
714      }
715      chain[hash_val] = index;
716      // Check for loops. Works because if this is non-empty then there must be
717      // another cell which already contains the same symbol index as this one,
718      // which means some symbol has more then one name, which isn't allowed.
719      CHECK_EQ(chain[index], static_cast<Elf32_Word>(0));
720    }
721  }
722
723  return hash;
724}
725
726void ElfWriterQuick::ElfBuilder::SetupEhdr() {
727  memset(&elf_header_, 0, sizeof(elf_header_));
728  elf_header_.e_ident[EI_MAG0]       = ELFMAG0;
729  elf_header_.e_ident[EI_MAG1]       = ELFMAG1;
730  elf_header_.e_ident[EI_MAG2]       = ELFMAG2;
731  elf_header_.e_ident[EI_MAG3]       = ELFMAG3;
732  elf_header_.e_ident[EI_CLASS]      = ELFCLASS32;
733  elf_header_.e_ident[EI_DATA]       = ELFDATA2LSB;
734  elf_header_.e_ident[EI_VERSION]    = EV_CURRENT;
735  elf_header_.e_ident[EI_OSABI]      = ELFOSABI_LINUX;
736  elf_header_.e_ident[EI_ABIVERSION] = 0;
737  elf_header_.e_type = ET_DYN;
738  elf_header_.e_version = 1;
739  elf_header_.e_entry = 0;
740  elf_header_.e_ehsize = sizeof(Elf32_Ehdr);
741  elf_header_.e_phentsize = sizeof(Elf32_Phdr);
742  elf_header_.e_shentsize = sizeof(Elf32_Shdr);
743  elf_header_.e_phoff = sizeof(Elf32_Ehdr);
744}
745
746void ElfWriterQuick::ElfBuilder::SetISA(InstructionSet isa) {
747  switch (isa) {
748    case kArm:
749      // Fall through.
750    case kThumb2: {
751      elf_header_.e_machine = EM_ARM;
752      elf_header_.e_flags = EF_ARM_EABI_VER5;
753      break;
754    }
755    case kArm64: {
756      elf_header_.e_machine = EM_AARCH64;
757      elf_header_.e_flags = 0;
758      break;
759    }
760    case kX86: {
761      elf_header_.e_machine = EM_386;
762      elf_header_.e_flags = 0;
763      break;
764    }
765    case kX86_64: {
766      elf_header_.e_machine = EM_X86_64;
767      elf_header_.e_flags = 0;
768      break;
769    }
770    case kMips: {
771      elf_header_.e_machine = EM_MIPS;
772      elf_header_.e_flags = (EF_MIPS_NOREORDER |
773                             EF_MIPS_PIC       |
774                             EF_MIPS_CPIC      |
775                             EF_MIPS_ABI_O32   |
776                             EF_MIPS_ARCH_32R2);
777      break;
778    }
779    default: {
780      fatal_error_ = true;
781      LOG(FATAL) << "Unknown instruction set: " << isa;
782      break;
783    }
784  }
785}
786
787void ElfWriterQuick::ElfSymtabBuilder::AddSymbol(
788    const std::string& name, const ElfSectionBuilder* section, Elf32_Addr addr,
789    bool is_relative, Elf32_Word size, uint8_t binding, uint8_t type, uint8_t other) {
790  CHECK(section);
791  ElfSymtabBuilder::ElfSymbolState state {name, section, addr, size, is_relative,
792                                          MakeStInfo(binding, type), other, 0};
793  symbols_.push_back(state);
794}
795
796bool ElfWriterQuick::Create(File* elf_file,
797                            OatWriter* oat_writer,
798                            const std::vector<const DexFile*>& dex_files,
799                            const std::string& android_root,
800                            bool is_host,
801                            const CompilerDriver& driver) {
802  ElfWriterQuick elf_writer(driver, elf_file);
803  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
804}
805
806bool ElfWriterQuick::Write(OatWriter* oat_writer,
807                           const std::vector<const DexFile*>& dex_files_unused,
808                           const std::string& android_root_unused,
809                           bool is_host_unused) {
810  const bool debug = false;
811  const bool add_symbols = oat_writer->DidAddSymbols();
812  const OatHeader& oat_header = oat_writer->GetOatHeader();
813  Elf32_Word oat_data_size = oat_header.GetExecutableOffset();
814  uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
815
816  ElfBuilder builder(oat_writer, elf_file_, compiler_driver_->GetInstructionSet(), 0,
817                     oat_data_size, oat_data_size, oat_exec_size, add_symbols, debug);
818
819  if (add_symbols) {
820    AddDebugSymbols(builder, oat_writer, debug);
821  }
822
823  bool generateDebugInformation = compiler_driver_->GetCallFrameInformation() != nullptr;
824  if (generateDebugInformation) {
825    ElfRawSectionBuilder debug_info(".debug_info",   SHT_PROGBITS, 0, nullptr, 0, 1, 0);
826    ElfRawSectionBuilder debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
827    ElfRawSectionBuilder debug_str(".debug_str",    SHT_PROGBITS, 0, nullptr, 0, 1, 0);
828    ElfRawSectionBuilder debug_frame(".debug_frame",  SHT_PROGBITS, 0, nullptr, 0, 4, 0);
829    debug_frame.SetBuffer(*compiler_driver_->GetCallFrameInformation());
830
831    FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
832                         debug_abbrev.GetBuffer(), debug_str.GetBuffer());
833    builder.RegisterRawSection(debug_info);
834    builder.RegisterRawSection(debug_abbrev);
835    builder.RegisterRawSection(debug_frame);
836    builder.RegisterRawSection(debug_str);
837  }
838
839  return builder.Write();
840}
841
842void ElfWriterQuick::AddDebugSymbols(ElfBuilder& builder, OatWriter* oat_writer, bool debug) {
843  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
844  ElfSymtabBuilder* symtab = &builder.symtab_builder_;
845  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
846    symtab->AddSymbol(it->method_name_, &builder.text_builder_, it->low_pc_, true,
847                      it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
848  }
849}
850
851static void UpdateWord(std::vector<uint8_t>*buf, int offset, int data) {
852  (*buf)[offset+0] = data;
853  (*buf)[offset+1] = data >> 8;
854  (*buf)[offset+2] = data >> 16;
855  (*buf)[offset+3] = data >> 24;
856}
857
858static void PushWord(std::vector<uint8_t>*buf, int data) {
859  buf->push_back(data & 0xff);
860  buf->push_back((data >> 8) & 0xff);
861  buf->push_back((data >> 16) & 0xff);
862  buf->push_back((data >> 24) & 0xff);
863}
864
865static void PushHalf(std::vector<uint8_t>*buf, int data) {
866  buf->push_back(data & 0xff);
867  buf->push_back((data >> 8) & 0xff);
868}
869
870void ElfWriterQuick::FillInCFIInformation(OatWriter* oat_writer,
871                                          std::vector<uint8_t>* dbg_info,
872                                          std::vector<uint8_t>* dbg_abbrev,
873                                          std::vector<uint8_t>* dbg_str) {
874  // Create the debug_abbrev section with boilerplate information.
875  // We only care about low_pc and high_pc right now for the compilation
876  // unit and methods.
877
878  // Tag 1: Compilation unit: DW_TAG_compile_unit.
879  dbg_abbrev->push_back(1);
880  dbg_abbrev->push_back(DW_TAG_compile_unit);
881
882  // There are children (the methods).
883  dbg_abbrev->push_back(DW_CHILDREN_yes);
884
885  // DW_LANG_Java DW_FORM_data1.
886  dbg_abbrev->push_back(DW_AT_language);
887  dbg_abbrev->push_back(DW_FORM_data1);
888
889  // DW_AT_low_pc DW_FORM_addr.
890  dbg_abbrev->push_back(DW_AT_low_pc);
891  dbg_abbrev->push_back(DW_FORM_addr);
892
893  // DW_AT_high_pc DW_FORM_addr.
894  dbg_abbrev->push_back(DW_AT_high_pc);
895  dbg_abbrev->push_back(DW_FORM_addr);
896
897  // End of DW_TAG_compile_unit.
898  PushHalf(dbg_abbrev, 0);
899
900  // Tag 2: Compilation unit: DW_TAG_subprogram.
901  dbg_abbrev->push_back(2);
902  dbg_abbrev->push_back(DW_TAG_subprogram);
903
904  // There are no children.
905  dbg_abbrev->push_back(DW_CHILDREN_no);
906
907  // Name of the method.
908  dbg_abbrev->push_back(DW_AT_name);
909  dbg_abbrev->push_back(DW_FORM_strp);
910
911  // DW_AT_low_pc DW_FORM_addr.
912  dbg_abbrev->push_back(DW_AT_low_pc);
913  dbg_abbrev->push_back(DW_FORM_addr);
914
915  // DW_AT_high_pc DW_FORM_addr.
916  dbg_abbrev->push_back(DW_AT_high_pc);
917  dbg_abbrev->push_back(DW_FORM_addr);
918
919  // End of DW_TAG_subprogram.
920  PushHalf(dbg_abbrev, 0);
921
922  // Start the debug_info section with the header information
923  // 'unit_length' will be filled in later.
924  PushWord(dbg_info, 0);
925
926  // 'version' - 3.
927  PushHalf(dbg_info, 3);
928
929  // Offset into .debug_abbrev section (always 0).
930  PushWord(dbg_info, 0);
931
932  // Address size: 4.
933  dbg_info->push_back(4);
934
935  // Start the description for the compilation unit.
936  // This uses tag 1.
937  dbg_info->push_back(1);
938
939  // The language is Java.
940  dbg_info->push_back(DW_LANG_Java);
941
942  // Leave space for low_pc and high_pc.
943  int low_pc_offset = dbg_info->size();
944  PushWord(dbg_info, 0);
945  PushWord(dbg_info, 0);
946
947  // Walk through the information in the method table, and enter into dbg_info.
948  const std::vector<OatWriter::DebugInfo>& dbg = oat_writer->GetCFIMethodInfo();
949  uint32_t low_pc = 0xFFFFFFFFU;
950  uint32_t high_pc = 0;
951
952  for (uint32_t i = 0; i < dbg.size(); i++) {
953    const OatWriter::DebugInfo& info = dbg[i];
954    if (info.low_pc_ < low_pc) {
955      low_pc = info.low_pc_;
956    }
957    if (info.high_pc_ > high_pc) {
958      high_pc = info.high_pc_;
959    }
960
961    // Start a new TAG: subroutine (2).
962    dbg_info->push_back(2);
963
964    // Enter the name into the string table (and NUL terminate).
965    uint32_t str_offset = dbg_str->size();
966    dbg_str->insert(dbg_str->end(), info.method_name_.begin(), info.method_name_.end());
967    dbg_str->push_back('\0');
968
969    // Enter name, low_pc, high_pc.
970    PushWord(dbg_info, str_offset);
971    PushWord(dbg_info, info.low_pc_);
972    PushWord(dbg_info, info.high_pc_);
973  }
974
975  // One byte terminator
976  dbg_info->push_back(0);
977
978  // We have now walked all the methods.  Fill in lengths and low/high PCs.
979  UpdateWord(dbg_info, 0, dbg_info->size() - 4);
980  UpdateWord(dbg_info, low_pc_offset, low_pc);
981  UpdateWord(dbg_info, low_pc_offset + 4, high_pc);
982}
983
984}  // namespace art
985