blob: ca5ec663817de14b8241703ea12a9527e170302e [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "elf_writer_quick.h"
18
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070019#include <unordered_map>
20
Brian Carlstrom7940e442013-07-12 13:46:57 -070021#include "base/logging.h"
22#include "base/unix_file/fd_file.h"
Brian Carlstromc6dfdac2013-08-26 18:57:31 -070023#include "buffered_output_stream.h"
Vladimir Marko20f85592015-03-19 10:07:02 +000024#include "compiled_method.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070025#include "driver/compiler_driver.h"
Vladimir Marko20f85592015-03-19 10:07:02 +000026#include "driver/compiler_options.h"
Alex Light3470ab42014-06-18 10:35:45 -070027#include "dwarf.h"
Andreas Gampe54fc26c2014-09-04 21:47:42 -070028#include "elf_builder.h"
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070029#include "elf_file.h"
Nicolas Geoffray50cfe742014-02-19 13:27:42 +000030#include "elf_utils.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070031#include "file_output_stream.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070032#include "globals.h"
Andreas Gampe79273802014-08-05 20:21:05 -070033#include "leb128.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070034#include "oat.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070035#include "oat_writer.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070036#include "utils.h"
37
38namespace art {
39
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070040static void PushByte(std::vector<uint8_t>* buf, int data) {
41 buf->push_back(data & 0xff);
42}
43
44static uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) {
45 if (str == nullptr) {
46 str = def;
47 }
48
49 uint32_t offset = buf->size();
50 for (size_t i = 0; str[i] != '\0'; ++i) {
51 buf->push_back(str[i]);
52 }
53 buf->push_back('\0');
54 return offset;
55}
56
57static uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) {
58 uint32_t offset = buf->size();
59 buf->insert(buf->end(), str.begin(), str.end());
60 buf->push_back('\0');
61 return offset;
62}
63
Andreas Gampe79273802014-08-05 20:21:05 -070064static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) {
65 (*buf)[offset+0] = data;
66 (*buf)[offset+1] = data >> 8;
67 (*buf)[offset+2] = data >> 16;
68 (*buf)[offset+3] = data >> 24;
69}
70
Andreas Gampe79273802014-08-05 20:21:05 -070071static void PushHalf(std::vector<uint8_t>* buf, int data) {
72 buf->push_back(data & 0xff);
73 buf->push_back((data >> 8) & 0xff);
74}
75
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000076template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
77 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
78 typename Elf_Phdr, typename Elf_Shdr>
79bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000080 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
Brian Carlstromb12f3472014-06-11 14:54:46 -070081 OatWriter* oat_writer,
82 const std::vector<const DexFile*>& dex_files,
83 const std::string& android_root,
84 bool is_host,
85 const CompilerDriver& driver) {
86 ElfWriterQuick elf_writer(driver, elf_file);
87 return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
88}
89
Andreas Gampe79273802014-08-05 20:21:05 -070090std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070091 std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>;
Andreas Gampe79273802014-08-05 20:21:05 -070092
93 // Length (will be filled in later in this routine).
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070094 if (is_x86_64) {
Vladimir Marko80b96d12015-02-19 15:50:28 +000095 Push32(cfi_info, 0xffffffff); // Indicates 64bit
96 Push32(cfi_info, 0);
97 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070098 } else {
Vladimir Marko80b96d12015-02-19 15:50:28 +000099 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700100 }
Andreas Gampe79273802014-08-05 20:21:05 -0700101
102 // CIE id: always 0.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700103 if (is_x86_64) {
Vladimir Marko80b96d12015-02-19 15:50:28 +0000104 Push32(cfi_info, 0);
105 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700106 } else {
Vladimir Marko80b96d12015-02-19 15:50:28 +0000107 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700108 }
Andreas Gampe79273802014-08-05 20:21:05 -0700109
110 // Version: always 1.
111 cfi_info->push_back(0x01);
112
113 // Augmentation: 'zR\0'
114 cfi_info->push_back(0x7a);
115 cfi_info->push_back(0x52);
116 cfi_info->push_back(0x0);
117
118 // Code alignment: 1.
119 EncodeUnsignedLeb128(1, cfi_info);
120
121 // Data alignment.
122 if (is_x86_64) {
123 EncodeSignedLeb128(-8, cfi_info);
124 } else {
125 EncodeSignedLeb128(-4, cfi_info);
126 }
127
128 // Return address register.
129 if (is_x86_64) {
130 // R16(RIP)
131 cfi_info->push_back(0x10);
132 } else {
133 // R8(EIP)
134 cfi_info->push_back(0x08);
135 }
136
137 // Augmentation length: 1.
138 cfi_info->push_back(1);
139
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700140 // Augmentation data.
141 if (is_x86_64) {
142 // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8).
143 cfi_info->push_back(0x04);
144 } else {
145 // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4).
146 cfi_info->push_back(0x03);
147 }
Andreas Gampe79273802014-08-05 20:21:05 -0700148
149 // Initial instructions.
150 if (is_x86_64) {
151 // DW_CFA_def_cfa R7(RSP) 8.
152 cfi_info->push_back(0x0c);
153 cfi_info->push_back(0x07);
154 cfi_info->push_back(0x08);
155
156 // DW_CFA_offset R16(RIP) 1 (* -8).
157 cfi_info->push_back(0x90);
158 cfi_info->push_back(0x01);
159 } else {
160 // DW_CFA_def_cfa R4(ESP) 4.
161 cfi_info->push_back(0x0c);
162 cfi_info->push_back(0x04);
163 cfi_info->push_back(0x04);
164
165 // DW_CFA_offset R8(EIP) 1 (* -4).
166 cfi_info->push_back(0x88);
167 cfi_info->push_back(0x01);
168 }
169
170 // Padding to a multiple of 4
171 while ((cfi_info->size() & 3) != 0) {
172 // DW_CFA_nop is encoded as 0.
173 cfi_info->push_back(0);
174 }
175
176 // Set the length of the CIE inside the generated bytes.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700177 if (is_x86_64) {
178 uint32_t length = cfi_info->size() - 12;
179 UpdateWord(cfi_info, 4, length);
180 } else {
181 uint32_t length = cfi_info->size() - 4;
182 UpdateWord(cfi_info, 0, length);
183 }
Andreas Gampe79273802014-08-05 20:21:05 -0700184 return cfi_info;
185}
186
187std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
188 switch (isa) {
189 case kX86:
190 return ConstructCIEFrameX86(false);
191 case kX86_64:
192 return ConstructCIEFrameX86(true);
193
194 default:
195 // Not implemented.
196 return nullptr;
197 }
198}
199
Ian Rogers0279ebb2014-10-08 17:27:48 -0700200class OatWriterWrapper FINAL : public CodeOutput {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700201 public:
202 explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
203
Vladimir Markof4da6752014-08-01 19:04:18 +0100204 void SetCodeOffset(size_t offset) {
205 oat_writer_->SetOatDataOffset(offset);
206 }
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700207 bool Write(OutputStream* out) OVERRIDE {
208 return oat_writer_->Write(out);
209 }
210 private:
Ian Rogers0279ebb2014-10-08 17:27:48 -0700211 OatWriter* const oat_writer_;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700212};
213
214template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
215 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
216 typename Elf_Phdr, typename Elf_Shdr>
217static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
218 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
219 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
220 OatWriter* oat_writer);
221
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000222template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
223 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
224 typename Elf_Phdr, typename Elf_Shdr>
225bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
226 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700227 const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
228 const std::string& android_root_unused ATTRIBUTE_UNUSED,
229 bool is_host_unused ATTRIBUTE_UNUSED) {
Andreas Gampe79273802014-08-05 20:21:05 -0700230 constexpr bool debug = false;
Brian Carlstromb12f3472014-06-11 14:54:46 -0700231 const OatHeader& oat_header = oat_writer->GetOatHeader();
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000232 Elf_Word oat_data_size = oat_header.GetExecutableOffset();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700233 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
Vladimir Marko5c42c292015-02-25 12:02:49 +0000234 uint32_t oat_bss_size = oat_writer->GetBssSize();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700235
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700236 OatWriterWrapper wrapper(oat_writer);
237
238 std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
239 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
240 new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
241 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
242 &wrapper,
243 elf_file_,
244 compiler_driver_->GetInstructionSet(),
245 0,
246 oat_data_size,
247 oat_data_size,
248 oat_exec_size,
Vladimir Marko5c42c292015-02-25 12:02:49 +0000249 RoundUp(oat_data_size + oat_exec_size, kPageSize),
250 oat_bss_size,
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700251 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
252 debug));
Alex Light78382fa2014-06-06 15:45:32 -0700253
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700254 if (!builder->Init()) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700255 return false;
256 }
257
Andreas Gampe79273802014-08-05 20:21:05 -0700258 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700259 WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
Brian Carlstromb12f3472014-06-11 14:54:46 -0700260 }
261
Alex Light53cb16b2014-06-12 11:26:29 -0700262 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700263 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
264 ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
Vladimir Markof4da6752014-08-01 19:04:18 +0100265 const std::vector<uintptr_t>& locations = oat_writer->GetAbsolutePatchLocations();
266 const uint8_t* begin = reinterpret_cast<const uint8_t*>(&locations[0]);
267 const uint8_t* end = begin + locations.size() * sizeof(locations[0]);
268 oat_patches.GetBuffer()->assign(begin, end);
269 if (debug) {
270 LOG(INFO) << "Prepared .oat_patches for " << locations.size() << " patches.";
271 }
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700272 builder->RegisterRawSection(oat_patches);
Alex Light53cb16b2014-06-12 11:26:29 -0700273 }
274
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700275 return builder->Write();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700276}
Mark Mendellae9fd932014-02-10 16:14:35 -0800277
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700278class LineTableGenerator FINAL : public Leb128Encoder {
279 public:
280 LineTableGenerator(int line_base, int line_range, int opcode_base,
281 std::vector<uint8_t>* data, uintptr_t current_address,
282 size_t current_line)
283 : Leb128Encoder(data), line_base_(line_base), line_range_(line_range),
284 opcode_base_(opcode_base), current_address_(current_address),
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700285 current_line_(current_line), current_file_index_(0) {}
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700286
287 void PutDelta(unsigned delta_addr, int delta_line) {
288 current_line_ += delta_line;
289 current_address_ += delta_addr;
290
291 if (delta_line >= line_base_ && delta_line < line_base_ + line_range_) {
292 unsigned special_opcode = (delta_line - line_base_) +
293 (line_range_ * delta_addr) + opcode_base_;
294 if (special_opcode <= 255) {
295 PushByte(data_, special_opcode);
296 return;
297 }
298 }
299
300 // generate standart opcode for address advance
301 if (delta_addr != 0) {
302 PushByte(data_, DW_LNS_advance_pc);
303 PushBackUnsigned(delta_addr);
304 }
305
306 // generate standart opcode for line delta
307 if (delta_line != 0) {
308 PushByte(data_, DW_LNS_advance_line);
309 PushBackSigned(delta_line);
310 }
311
312 // generate standart opcode for new LTN entry
313 PushByte(data_, DW_LNS_copy);
314 }
315
316 void SetAddr(uintptr_t addr) {
317 if (current_address_ == addr) {
318 return;
319 }
320
321 current_address_ = addr;
322
323 PushByte(data_, 0); // extended opcode:
324 PushByte(data_, 1 + 4); // length: opcode_size + address_size
325 PushByte(data_, DW_LNE_set_address);
Vladimir Marko80b96d12015-02-19 15:50:28 +0000326 Push32(data_, addr);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700327 }
328
329 void SetLine(unsigned line) {
330 int delta_line = line - current_line_;
331 if (delta_line) {
332 current_line_ = line;
333 PushByte(data_, DW_LNS_advance_line);
334 PushBackSigned(delta_line);
335 }
336 }
337
338 void SetFile(unsigned file_index) {
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700339 if (current_file_index_ != file_index) {
340 current_file_index_ = file_index;
341 PushByte(data_, DW_LNS_set_file);
342 PushBackUnsigned(file_index);
343 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700344 }
345
346 void EndSequence() {
347 // End of Line Table Program
348 // 0(=ext), 1(len), DW_LNE_end_sequence
349 PushByte(data_, 0);
350 PushByte(data_, 1);
351 PushByte(data_, DW_LNE_end_sequence);
352 }
353
354 private:
355 const int line_base_;
356 const int line_range_;
357 const int opcode_base_;
358 uintptr_t current_address_;
359 size_t current_line_;
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700360 unsigned current_file_index_;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700361
362 DISALLOW_COPY_AND_ASSIGN(LineTableGenerator);
363};
364
365// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800366static void GetLineInfoForJava(const uint8_t* dbgstream, const SwapSrcMap& pc2dex,
367 DefaultSrcMap* result, uint32_t start_pc = 0) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700368 if (dbgstream == nullptr) {
369 return;
370 }
371
372 int adjopcode;
373 uint32_t dex_offset = 0;
374 uint32_t java_line = DecodeUnsignedLeb128(&dbgstream);
375
376 // skip parameters
377 for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) {
378 DecodeUnsignedLeb128(&dbgstream);
379 }
380
381 for (bool is_end = false; is_end == false; ) {
382 uint8_t opcode = *dbgstream;
383 dbgstream++;
384 switch (opcode) {
385 case DexFile::DBG_END_SEQUENCE:
386 is_end = true;
387 break;
388
389 case DexFile::DBG_ADVANCE_PC:
390 dex_offset += DecodeUnsignedLeb128(&dbgstream);
391 break;
392
393 case DexFile::DBG_ADVANCE_LINE:
394 java_line += DecodeSignedLeb128(&dbgstream);
395 break;
396
397 case DexFile::DBG_START_LOCAL:
398 case DexFile::DBG_START_LOCAL_EXTENDED:
399 DecodeUnsignedLeb128(&dbgstream);
400 DecodeUnsignedLeb128(&dbgstream);
401 DecodeUnsignedLeb128(&dbgstream);
402
403 if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) {
404 DecodeUnsignedLeb128(&dbgstream);
405 }
406 break;
407
408 case DexFile::DBG_END_LOCAL:
409 case DexFile::DBG_RESTART_LOCAL:
410 DecodeUnsignedLeb128(&dbgstream);
411 break;
412
413 case DexFile::DBG_SET_PROLOGUE_END:
414 case DexFile::DBG_SET_EPILOGUE_BEGIN:
415 case DexFile::DBG_SET_FILE:
416 break;
417
418 default:
419 adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
420 dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
421 java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
422
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800423 for (SwapSrcMap::const_iterator found = pc2dex.FindByTo(dex_offset);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700424 found != pc2dex.end() && found->to_ == static_cast<int32_t>(dex_offset);
425 found++) {
426 result->push_back({found->from_ + start_pc, static_cast<int32_t>(java_line)});
427 }
428 break;
429 }
Andreas Gampe79273802014-08-05 20:21:05 -0700430 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800431}
432
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700433/*
434 * @brief Generate the DWARF debug_info and debug_abbrev sections
435 * @param oat_writer The Oat file Writer.
436 * @param dbg_info Compilation unit information.
437 * @param dbg_abbrev Abbreviations used to generate dbg_info.
438 * @param dbg_str Debug strings.
439 */
440static void FillInCFIInformation(OatWriter* oat_writer,
441 std::vector<uint8_t>* dbg_info,
442 std::vector<uint8_t>* dbg_abbrev,
443 std::vector<uint8_t>* dbg_str,
444 std::vector<uint8_t>* dbg_line,
445 uint32_t text_section_offset) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700446 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
447
448 uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
449
Mark Mendellae9fd932014-02-10 16:14:35 -0800450 // Create the debug_abbrev section with boilerplate information.
451 // We only care about low_pc and high_pc right now for the compilation
452 // unit and methods.
453
454 // Tag 1: Compilation unit: DW_TAG_compile_unit.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700455 PushByte(dbg_abbrev, 1);
456 PushByte(dbg_abbrev, DW_TAG_compile_unit);
Mark Mendellae9fd932014-02-10 16:14:35 -0800457
458 // There are children (the methods).
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700459 PushByte(dbg_abbrev, DW_CHILDREN_yes);
460
461 // DW_AT_producer DW_FORM_data1.
462 // REVIEW: we can get rid of dbg_str section if
463 // DW_FORM_string (immediate string) was used everywhere instead of
464 // DW_FORM_strp (ref to string from .debug_str section).
465 // DW_FORM_strp makes sense only if we reuse the strings.
466 PushByte(dbg_abbrev, DW_AT_producer);
467 PushByte(dbg_abbrev, DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800468
469 // DW_LANG_Java DW_FORM_data1.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700470 PushByte(dbg_abbrev, DW_AT_language);
471 PushByte(dbg_abbrev, DW_FORM_data1);
Mark Mendellae9fd932014-02-10 16:14:35 -0800472
473 // DW_AT_low_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700474 PushByte(dbg_abbrev, DW_AT_low_pc);
475 PushByte(dbg_abbrev, DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800476
477 // DW_AT_high_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700478 PushByte(dbg_abbrev, DW_AT_high_pc);
479 PushByte(dbg_abbrev, DW_FORM_addr);
480
481 if (dbg_line != nullptr) {
482 // DW_AT_stmt_list DW_FORM_sec_offset.
483 PushByte(dbg_abbrev, DW_AT_stmt_list);
484 PushByte(dbg_abbrev, DW_FORM_sec_offset);
485 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800486
487 // End of DW_TAG_compile_unit.
488 PushHalf(dbg_abbrev, 0);
489
490 // Tag 2: Compilation unit: DW_TAG_subprogram.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700491 PushByte(dbg_abbrev, 2);
492 PushByte(dbg_abbrev, DW_TAG_subprogram);
Mark Mendellae9fd932014-02-10 16:14:35 -0800493
494 // There are no children.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700495 PushByte(dbg_abbrev, DW_CHILDREN_no);
Mark Mendellae9fd932014-02-10 16:14:35 -0800496
497 // Name of the method.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700498 PushByte(dbg_abbrev, DW_AT_name);
499 PushByte(dbg_abbrev, DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800500
501 // DW_AT_low_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700502 PushByte(dbg_abbrev, DW_AT_low_pc);
503 PushByte(dbg_abbrev, DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800504
505 // DW_AT_high_pc DW_FORM_addr.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700506 PushByte(dbg_abbrev, DW_AT_high_pc);
507 PushByte(dbg_abbrev, DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800508
509 // End of DW_TAG_subprogram.
510 PushHalf(dbg_abbrev, 0);
511
512 // Start the debug_info section with the header information
513 // 'unit_length' will be filled in later.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700514 int cunit_length = dbg_info->size();
Vladimir Marko80b96d12015-02-19 15:50:28 +0000515 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800516
517 // 'version' - 3.
518 PushHalf(dbg_info, 3);
519
520 // Offset into .debug_abbrev section (always 0).
Vladimir Marko80b96d12015-02-19 15:50:28 +0000521 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800522
523 // Address size: 4.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700524 PushByte(dbg_info, 4);
Mark Mendellae9fd932014-02-10 16:14:35 -0800525
526 // Start the description for the compilation unit.
527 // This uses tag 1.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700528 PushByte(dbg_info, 1);
529
530 // The producer is Android dex2oat.
Vladimir Marko80b96d12015-02-19 15:50:28 +0000531 Push32(dbg_info, producer_str_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800532
533 // The language is Java.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700534 PushByte(dbg_info, DW_LANG_Java);
Mark Mendellae9fd932014-02-10 16:14:35 -0800535
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700536 // low_pc and high_pc.
537 uint32_t cunit_low_pc = 0 - 1;
538 uint32_t cunit_high_pc = 0;
539 int cunit_low_pc_pos = dbg_info->size();
Vladimir Marko80b96d12015-02-19 15:50:28 +0000540 Push32(dbg_info, 0);
541 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800542
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700543 if (dbg_line == nullptr) {
544 for (size_t i = 0; i < method_info.size(); ++i) {
545 const OatWriter::DebugInfo &dbg = method_info[i];
Mark Mendellae9fd932014-02-10 16:14:35 -0800546
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700547 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
548 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
549
550 // Start a new TAG: subroutine (2).
551 PushByte(dbg_info, 2);
552
553 // Enter name, low_pc, high_pc.
Vladimir Marko80b96d12015-02-19 15:50:28 +0000554 Push32(dbg_info, PushStr(dbg_str, dbg.method_name_));
555 Push32(dbg_info, dbg.low_pc_ + text_section_offset);
556 Push32(dbg_info, dbg.high_pc_ + text_section_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800557 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700558 } else {
559 // TODO: in gdb info functions <regexp> - reports Java functions, but
560 // source file is <unknown> because .debug_line is formed as one
561 // compilation unit. To fix this it is possible to generate
562 // a separate compilation unit for every distinct Java source.
563 // Each of the these compilation units can have several non-adjacent
564 // method ranges.
565
566 // Line number table offset
Vladimir Marko80b96d12015-02-19 15:50:28 +0000567 Push32(dbg_info, dbg_line->size());
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700568
569 size_t lnt_length = dbg_line->size();
Vladimir Marko80b96d12015-02-19 15:50:28 +0000570 Push32(dbg_line, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700571
572 PushHalf(dbg_line, 4); // LNT Version DWARF v4 => 4
573
574 size_t lnt_hdr_length = dbg_line->size();
Vladimir Marko80b96d12015-02-19 15:50:28 +0000575 Push32(dbg_line, 0); // TODO: 64-bit uses 8-byte here
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700576
577 PushByte(dbg_line, 1); // minimum_instruction_length (ubyte)
578 PushByte(dbg_line, 1); // maximum_operations_per_instruction (ubyte) = always 1
579 PushByte(dbg_line, 1); // default_is_stmt (ubyte)
580
581 const int8_t LINE_BASE = -5;
582 PushByte(dbg_line, LINE_BASE); // line_base (sbyte)
583
584 const uint8_t LINE_RANGE = 14;
585 PushByte(dbg_line, LINE_RANGE); // line_range (ubyte)
586
587 const uint8_t OPCODE_BASE = 13;
588 PushByte(dbg_line, OPCODE_BASE); // opcode_base (ubyte)
589
590 // Standard_opcode_lengths (array of ubyte).
591 PushByte(dbg_line, 0); PushByte(dbg_line, 1); PushByte(dbg_line, 1);
592 PushByte(dbg_line, 1); PushByte(dbg_line, 1); PushByte(dbg_line, 0);
593 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
594 PushByte(dbg_line, 0); PushByte(dbg_line, 0); PushByte(dbg_line, 1);
595
596 PushByte(dbg_line, 0); // include_directories (sequence of path names) = EMPTY
597
598 // File_names (sequence of file entries).
599 std::unordered_map<const char*, size_t> files;
600 for (size_t i = 0; i < method_info.size(); ++i) {
601 const OatWriter::DebugInfo &dbg = method_info[i];
602 // TODO: add package directory to the file name
603 const char* file_name = dbg.src_file_name_ == nullptr ? "null" : dbg.src_file_name_;
604 auto found = files.find(file_name);
605 if (found == files.end()) {
606 size_t file_index = 1 + files.size();
607 files[file_name] = file_index;
608 PushStr(dbg_line, file_name);
609 PushByte(dbg_line, 0); // include directory index = LEB128(0) - no directory
610 PushByte(dbg_line, 0); // modification time = LEB128(0) - NA
611 PushByte(dbg_line, 0); // file length = LEB128(0) - NA
612 }
613 }
614 PushByte(dbg_line, 0); // End of file_names.
615
616 // Set lnt header length.
617 UpdateWord(dbg_line, lnt_hdr_length, dbg_line->size() - lnt_hdr_length - 4);
618
619 // Generate Line Number Program code, one long program for all methods.
620 LineTableGenerator line_table_generator(LINE_BASE, LINE_RANGE, OPCODE_BASE,
621 dbg_line, 0, 1);
622
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800623 DefaultSrcMap pc2java_map;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700624 for (size_t i = 0; i < method_info.size(); ++i) {
625 const OatWriter::DebugInfo &dbg = method_info[i];
626 const char* file_name = (dbg.src_file_name_ == nullptr) ? "null" : dbg.src_file_name_;
627 size_t file_index = files[file_name];
628 DCHECK_NE(file_index, 0U) << file_name;
629
630 cunit_low_pc = std::min(cunit_low_pc, dbg.low_pc_);
631 cunit_high_pc = std::max(cunit_high_pc, dbg.high_pc_);
632
633 // Start a new TAG: subroutine (2).
634 PushByte(dbg_info, 2);
635
636 // Enter name, low_pc, high_pc.
Vladimir Marko80b96d12015-02-19 15:50:28 +0000637 Push32(dbg_info, PushStr(dbg_str, dbg.method_name_));
638 Push32(dbg_info, dbg.low_pc_ + text_section_offset);
639 Push32(dbg_info, dbg.high_pc_ + text_section_offset);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700640
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700641 GetLineInfoForJava(dbg.dbgstream_, dbg.compiled_method_->GetSrcMappingTable(),
642 &pc2java_map, dbg.low_pc_);
643 pc2java_map.DeltaFormat({dbg.low_pc_, 1}, dbg.high_pc_);
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700644 if (!pc2java_map.empty()) {
645 line_table_generator.SetFile(file_index);
646 line_table_generator.SetAddr(dbg.low_pc_ + text_section_offset);
647 line_table_generator.SetLine(1);
648 for (auto& src_map_elem : pc2java_map) {
649 line_table_generator.PutDelta(src_map_elem.from_, src_map_elem.to_);
650 }
651 pc2java_map.clear();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700652 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800653 }
654
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700655 // End Sequence should have the highest address set.
656 line_table_generator.SetAddr(cunit_high_pc + text_section_offset);
657 line_table_generator.EndSequence();
Mark Mendellae9fd932014-02-10 16:14:35 -0800658
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700659 // set lnt length
660 UpdateWord(dbg_line, lnt_length, dbg_line->size() - lnt_length - 4);
Mark Mendellae9fd932014-02-10 16:14:35 -0800661 }
662
663 // One byte terminator
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700664 PushByte(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800665
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700666 // Fill in cunit's low_pc and high_pc.
667 UpdateWord(dbg_info, cunit_low_pc_pos, cunit_low_pc + text_section_offset);
668 UpdateWord(dbg_info, cunit_low_pc_pos + 4, cunit_high_pc + text_section_offset);
669
670 // We have now walked all the methods. Fill in lengths.
671 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700672}
673
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700674template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
675 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
676 typename Elf_Phdr, typename Elf_Shdr>
Andreas Gampe86830382014-12-12 21:41:29 -0800677// Do not inline to avoid Clang stack frame problems. b/18738594
678NO_INLINE
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700679static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
680 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
681 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
682 OatWriter* oat_writer) {
683 std::unique_ptr<std::vector<uint8_t>> cfi_info(
684 ConstructCIEFrame(compiler_driver->GetInstructionSet()));
685
Ian Rogers0279ebb2014-10-08 17:27:48 -0700686 Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700687
688 // Iterate over the compiled methods.
689 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
Ian Rogers0279ebb2014-10-08 17:27:48 -0700690 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
691 builder->GetSymtabBuilder();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700692 for (auto it = method_info.begin(); it != method_info.end(); ++it) {
Ian Rogers0279ebb2014-10-08 17:27:48 -0700693 symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), it->low_pc_, true,
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700694 it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
695
Ningsheng Jianf9734552014-10-27 14:56:34 +0800696 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
697 // instructions, so that disassembler tools can correctly disassemble.
698 if (it->compiled_method_->GetInstructionSet() == kThumb2) {
699 symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true,
700 0, STB_LOCAL, STT_NOTYPE);
701 }
702
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700703 // Include CFI for compiled method, if possible.
704 if (cfi_info.get() != nullptr) {
705 DCHECK(it->compiled_method_ != nullptr);
706
707 // Copy in the FDE, if present
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800708 const SwapVector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700709 if (fde != nullptr) {
710 // Copy the information into cfi_info and then fix the address in the new copy.
711 int cur_offset = cfi_info->size();
712 cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
713
714 bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
715
716 // Set the 'CIE_pointer' field.
717 uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
718 uint64_t offset_to_update = CIE_pointer;
719 if (is_64bit) {
720 (*cfi_info)[offset_to_update+0] = CIE_pointer;
721 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
722 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
723 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
724 (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
725 (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
726 (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
727 (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
728 } else {
729 (*cfi_info)[offset_to_update+0] = CIE_pointer;
730 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
731 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
732 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
733 }
734
735 // Set the 'initial_location' field.
736 offset_to_update += is_64bit ? 8 : 4;
737 if (is_64bit) {
738 const uint64_t quick_code_start = it->low_pc_ + text_section_address;
739 (*cfi_info)[offset_to_update+0] = quick_code_start;
740 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
741 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
742 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
743 (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
744 (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
745 (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
746 (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
747 } else {
748 const uint32_t quick_code_start = it->low_pc_ + text_section_address;
749 (*cfi_info)[offset_to_update+0] = quick_code_start;
750 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
751 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
752 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
753 }
754 }
755 }
756 }
757
758 bool hasCFI = (cfi_info.get() != nullptr);
759 bool hasLineInfo = false;
760 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
761 if (dbg_info.dbgstream_ != nullptr &&
762 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
763 hasLineInfo = true;
764 break;
765 }
766 }
767
768 if (hasLineInfo || hasCFI) {
769 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
770 SHT_PROGBITS,
771 0, nullptr, 0, 1, 0);
772 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
773 SHT_PROGBITS,
774 0, nullptr, 0, 1, 0);
775 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
776 SHT_PROGBITS,
777 0, nullptr, 0, 1, 0);
778 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
779 SHT_PROGBITS,
780 0, nullptr, 0, 1, 0);
781
782 FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
783 debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
784 hasLineInfo ? debug_line.GetBuffer() : nullptr,
785 text_section_address);
786
787 builder->RegisterRawSection(debug_info);
788 builder->RegisterRawSection(debug_abbrev);
789
790 if (hasCFI) {
791 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
792 SHT_PROGBITS,
793 SHF_ALLOC,
794 nullptr, 0, 4, 0);
795 eh_frame.SetBuffer(std::move(*cfi_info.get()));
796 builder->RegisterRawSection(eh_frame);
797 }
798
799 if (hasLineInfo) {
800 builder->RegisterRawSection(debug_line);
801 }
802
803 builder->RegisterRawSection(debug_str);
804 }
805}
806
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000807// Explicit instantiations
808template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
809 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
810template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
811 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
812
Brian Carlstrom7940e442013-07-12 13:46:57 -0700813} // namespace art