blob: 3ce19ab0df88280069ac16bc21afc07097373851 [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"
David Srbecky6f715892015-03-30 14:21:42 +010028#include "dwarf/debug_frame_writer.h"
29#include "dwarf/debug_line_writer.h"
Andreas Gampe54fc26c2014-09-04 21:47:42 -070030#include "elf_builder.h"
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070031#include "elf_file.h"
Nicolas Geoffray50cfe742014-02-19 13:27:42 +000032#include "elf_utils.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070033#include "file_output_stream.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070034#include "globals.h"
Andreas Gampe79273802014-08-05 20:21:05 -070035#include "leb128.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070036#include "oat.h"
Brian Carlstromc50d8e12013-07-23 22:35:16 -070037#include "oat_writer.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070038#include "utils.h"
39
40namespace art {
41
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070042static void PushByte(std::vector<uint8_t>* buf, int data) {
43 buf->push_back(data & 0xff);
44}
45
46static uint32_t PushStr(std::vector<uint8_t>* buf, const char* str, const char* def = nullptr) {
47 if (str == nullptr) {
48 str = def;
49 }
50
51 uint32_t offset = buf->size();
52 for (size_t i = 0; str[i] != '\0'; ++i) {
53 buf->push_back(str[i]);
54 }
55 buf->push_back('\0');
56 return offset;
57}
58
59static uint32_t PushStr(std::vector<uint8_t>* buf, const std::string &str) {
60 uint32_t offset = buf->size();
61 buf->insert(buf->end(), str.begin(), str.end());
62 buf->push_back('\0');
63 return offset;
64}
65
Andreas Gampe79273802014-08-05 20:21:05 -070066static void UpdateWord(std::vector<uint8_t>* buf, int offset, int data) {
67 (*buf)[offset+0] = data;
68 (*buf)[offset+1] = data >> 8;
69 (*buf)[offset+2] = data >> 16;
70 (*buf)[offset+3] = data >> 24;
71}
72
Andreas Gampe79273802014-08-05 20:21:05 -070073static void PushHalf(std::vector<uint8_t>* buf, int data) {
74 buf->push_back(data & 0xff);
75 buf->push_back((data >> 8) & 0xff);
76}
77
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000078template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
79 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
80 typename Elf_Phdr, typename Elf_Shdr>
81bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +000082 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file,
Brian Carlstromb12f3472014-06-11 14:54:46 -070083 OatWriter* oat_writer,
84 const std::vector<const DexFile*>& dex_files,
85 const std::string& android_root,
86 bool is_host,
87 const CompilerDriver& driver) {
88 ElfWriterQuick elf_writer(driver, elf_file);
89 return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
90}
91
Andreas Gampe79273802014-08-05 20:21:05 -070092std::vector<uint8_t>* ConstructCIEFrameX86(bool is_x86_64) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070093 std::vector<uint8_t>* cfi_info = new std::vector<uint8_t>;
Andreas Gampe79273802014-08-05 20:21:05 -070094
95 // Length (will be filled in later in this routine).
Yevgeny Roubane3ea8382014-08-08 16:29:38 +070096 if (is_x86_64) {
Vladimir Marko80b96d12015-02-19 15:50:28 +000097 Push32(cfi_info, 0xffffffff); // Indicates 64bit
98 Push32(cfi_info, 0);
99 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700100 } else {
Vladimir Marko80b96d12015-02-19 15:50:28 +0000101 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700102 }
Andreas Gampe79273802014-08-05 20:21:05 -0700103
104 // CIE id: always 0.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700105 if (is_x86_64) {
Vladimir Marko80b96d12015-02-19 15:50:28 +0000106 Push32(cfi_info, 0);
107 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700108 } else {
Vladimir Marko80b96d12015-02-19 15:50:28 +0000109 Push32(cfi_info, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700110 }
Andreas Gampe79273802014-08-05 20:21:05 -0700111
112 // Version: always 1.
113 cfi_info->push_back(0x01);
114
115 // Augmentation: 'zR\0'
116 cfi_info->push_back(0x7a);
117 cfi_info->push_back(0x52);
118 cfi_info->push_back(0x0);
119
120 // Code alignment: 1.
121 EncodeUnsignedLeb128(1, cfi_info);
122
123 // Data alignment.
124 if (is_x86_64) {
125 EncodeSignedLeb128(-8, cfi_info);
126 } else {
127 EncodeSignedLeb128(-4, cfi_info);
128 }
129
130 // Return address register.
131 if (is_x86_64) {
132 // R16(RIP)
133 cfi_info->push_back(0x10);
134 } else {
135 // R8(EIP)
136 cfi_info->push_back(0x08);
137 }
138
139 // Augmentation length: 1.
140 cfi_info->push_back(1);
141
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700142 // Augmentation data.
143 if (is_x86_64) {
144 // 0x04 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata8).
145 cfi_info->push_back(0x04);
146 } else {
147 // 0x03 ((DW_EH_PE_absptr << 4) | DW_EH_PE_udata4).
148 cfi_info->push_back(0x03);
149 }
Andreas Gampe79273802014-08-05 20:21:05 -0700150
151 // Initial instructions.
152 if (is_x86_64) {
153 // DW_CFA_def_cfa R7(RSP) 8.
154 cfi_info->push_back(0x0c);
155 cfi_info->push_back(0x07);
156 cfi_info->push_back(0x08);
157
158 // DW_CFA_offset R16(RIP) 1 (* -8).
159 cfi_info->push_back(0x90);
160 cfi_info->push_back(0x01);
161 } else {
162 // DW_CFA_def_cfa R4(ESP) 4.
163 cfi_info->push_back(0x0c);
164 cfi_info->push_back(0x04);
165 cfi_info->push_back(0x04);
166
167 // DW_CFA_offset R8(EIP) 1 (* -4).
168 cfi_info->push_back(0x88);
169 cfi_info->push_back(0x01);
170 }
171
172 // Padding to a multiple of 4
173 while ((cfi_info->size() & 3) != 0) {
174 // DW_CFA_nop is encoded as 0.
175 cfi_info->push_back(0);
176 }
177
178 // Set the length of the CIE inside the generated bytes.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700179 if (is_x86_64) {
180 uint32_t length = cfi_info->size() - 12;
181 UpdateWord(cfi_info, 4, length);
182 } else {
183 uint32_t length = cfi_info->size() - 4;
184 UpdateWord(cfi_info, 0, length);
185 }
Andreas Gampe79273802014-08-05 20:21:05 -0700186 return cfi_info;
187}
188
189std::vector<uint8_t>* ConstructCIEFrame(InstructionSet isa) {
190 switch (isa) {
191 case kX86:
192 return ConstructCIEFrameX86(false);
193 case kX86_64:
194 return ConstructCIEFrameX86(true);
195
196 default:
197 // Not implemented.
198 return nullptr;
199 }
200}
201
Ian Rogers0279ebb2014-10-08 17:27:48 -0700202class OatWriterWrapper FINAL : public CodeOutput {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700203 public:
204 explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
205
Vladimir Markof4da6752014-08-01 19:04:18 +0100206 void SetCodeOffset(size_t offset) {
207 oat_writer_->SetOatDataOffset(offset);
208 }
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700209 bool Write(OutputStream* out) OVERRIDE {
210 return oat_writer_->Write(out);
211 }
212 private:
Ian Rogers0279ebb2014-10-08 17:27:48 -0700213 OatWriter* const oat_writer_;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700214};
215
216template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
217 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
218 typename Elf_Phdr, typename Elf_Shdr>
219static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
220 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
221 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
222 OatWriter* oat_writer);
223
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000224template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
225 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
226 typename Elf_Phdr, typename Elf_Shdr>
227bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
228 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer,
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700229 const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
230 const std::string& android_root_unused ATTRIBUTE_UNUSED,
231 bool is_host_unused ATTRIBUTE_UNUSED) {
Andreas Gampe79273802014-08-05 20:21:05 -0700232 constexpr bool debug = false;
Brian Carlstromb12f3472014-06-11 14:54:46 -0700233 const OatHeader& oat_header = oat_writer->GetOatHeader();
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000234 Elf_Word oat_data_size = oat_header.GetExecutableOffset();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700235 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size;
Vladimir Marko5c42c292015-02-25 12:02:49 +0000236 uint32_t oat_bss_size = oat_writer->GetBssSize();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700237
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700238 OatWriterWrapper wrapper(oat_writer);
239
240 std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
241 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder(
242 new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
243 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>(
244 &wrapper,
245 elf_file_,
246 compiler_driver_->GetInstructionSet(),
247 0,
248 oat_data_size,
249 oat_data_size,
250 oat_exec_size,
Vladimir Marko5c42c292015-02-25 12:02:49 +0000251 RoundUp(oat_data_size + oat_exec_size, kPageSize),
252 oat_bss_size,
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700253 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(),
254 debug));
Alex Light78382fa2014-06-06 15:45:32 -0700255
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700256 if (!builder->Init()) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700257 return false;
258 }
259
Andreas Gampe79273802014-08-05 20:21:05 -0700260 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700261 WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
Brian Carlstromb12f3472014-06-11 14:54:46 -0700262 }
263
Alex Light53cb16b2014-06-12 11:26:29 -0700264 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700265 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
266 ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
Vladimir Markof4da6752014-08-01 19:04:18 +0100267 const std::vector<uintptr_t>& locations = oat_writer->GetAbsolutePatchLocations();
268 const uint8_t* begin = reinterpret_cast<const uint8_t*>(&locations[0]);
269 const uint8_t* end = begin + locations.size() * sizeof(locations[0]);
270 oat_patches.GetBuffer()->assign(begin, end);
271 if (debug) {
272 LOG(INFO) << "Prepared .oat_patches for " << locations.size() << " patches.";
273 }
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700274 builder->RegisterRawSection(oat_patches);
Alex Light53cb16b2014-06-12 11:26:29 -0700275 }
276
Brian Carlstrom18a49cc2014-08-29 16:20:48 -0700277 return builder->Write();
Brian Carlstromb12f3472014-06-11 14:54:46 -0700278}
Mark Mendellae9fd932014-02-10 16:14:35 -0800279
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700280// TODO: rewriting it using DexFile::DecodeDebugInfo needs unneeded stuff.
David Srbecky6f715892015-03-30 14:21:42 +0100281static void GetLineInfoForJava(const uint8_t* dbgstream, DefaultSrcMap* dex2line) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700282 if (dbgstream == nullptr) {
283 return;
284 }
285
286 int adjopcode;
287 uint32_t dex_offset = 0;
288 uint32_t java_line = DecodeUnsignedLeb128(&dbgstream);
289
290 // skip parameters
291 for (uint32_t param_count = DecodeUnsignedLeb128(&dbgstream); param_count != 0; --param_count) {
292 DecodeUnsignedLeb128(&dbgstream);
293 }
294
295 for (bool is_end = false; is_end == false; ) {
296 uint8_t opcode = *dbgstream;
297 dbgstream++;
298 switch (opcode) {
299 case DexFile::DBG_END_SEQUENCE:
300 is_end = true;
301 break;
302
303 case DexFile::DBG_ADVANCE_PC:
304 dex_offset += DecodeUnsignedLeb128(&dbgstream);
305 break;
306
307 case DexFile::DBG_ADVANCE_LINE:
308 java_line += DecodeSignedLeb128(&dbgstream);
309 break;
310
311 case DexFile::DBG_START_LOCAL:
312 case DexFile::DBG_START_LOCAL_EXTENDED:
313 DecodeUnsignedLeb128(&dbgstream);
314 DecodeUnsignedLeb128(&dbgstream);
315 DecodeUnsignedLeb128(&dbgstream);
316
317 if (opcode == DexFile::DBG_START_LOCAL_EXTENDED) {
318 DecodeUnsignedLeb128(&dbgstream);
319 }
320 break;
321
322 case DexFile::DBG_END_LOCAL:
323 case DexFile::DBG_RESTART_LOCAL:
324 DecodeUnsignedLeb128(&dbgstream);
325 break;
326
327 case DexFile::DBG_SET_PROLOGUE_END:
328 case DexFile::DBG_SET_EPILOGUE_BEGIN:
329 case DexFile::DBG_SET_FILE:
330 break;
331
332 default:
333 adjopcode = opcode - DexFile::DBG_FIRST_SPECIAL;
334 dex_offset += adjopcode / DexFile::DBG_LINE_RANGE;
335 java_line += DexFile::DBG_LINE_BASE + (adjopcode % DexFile::DBG_LINE_RANGE);
David Srbecky6f715892015-03-30 14:21:42 +0100336 dex2line->push_back({dex_offset, static_cast<int32_t>(java_line)});
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700337 break;
338 }
Andreas Gampe79273802014-08-05 20:21:05 -0700339 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800340}
341
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700342/*
343 * @brief Generate the DWARF debug_info and debug_abbrev sections
344 * @param oat_writer The Oat file Writer.
345 * @param dbg_info Compilation unit information.
346 * @param dbg_abbrev Abbreviations used to generate dbg_info.
347 * @param dbg_str Debug strings.
348 */
349static void FillInCFIInformation(OatWriter* oat_writer,
350 std::vector<uint8_t>* dbg_info,
351 std::vector<uint8_t>* dbg_abbrev,
352 std::vector<uint8_t>* dbg_str,
353 std::vector<uint8_t>* dbg_line,
354 uint32_t text_section_offset) {
David Srbecky6f715892015-03-30 14:21:42 +0100355 const std::vector<OatWriter::DebugInfo>& method_infos = oat_writer->GetCFIMethodInfo();
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700356
357 uint32_t producer_str_offset = PushStr(dbg_str, "Android dex2oat");
358
David Srbecky6f715892015-03-30 14:21:42 +0100359 constexpr bool use_64bit_addresses = false;
360
Mark Mendellae9fd932014-02-10 16:14:35 -0800361 // Create the debug_abbrev section with boilerplate information.
362 // We only care about low_pc and high_pc right now for the compilation
363 // unit and methods.
364
365 // Tag 1: Compilation unit: DW_TAG_compile_unit.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700366 PushByte(dbg_abbrev, 1);
David Srbecky6f715892015-03-30 14:21:42 +0100367 PushByte(dbg_abbrev, dwarf::DW_TAG_compile_unit);
Mark Mendellae9fd932014-02-10 16:14:35 -0800368
369 // There are children (the methods).
David Srbecky6f715892015-03-30 14:21:42 +0100370 PushByte(dbg_abbrev, dwarf::DW_CHILDREN_yes);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700371
372 // DW_AT_producer DW_FORM_data1.
373 // REVIEW: we can get rid of dbg_str section if
374 // DW_FORM_string (immediate string) was used everywhere instead of
375 // DW_FORM_strp (ref to string from .debug_str section).
376 // DW_FORM_strp makes sense only if we reuse the strings.
David Srbecky6f715892015-03-30 14:21:42 +0100377 PushByte(dbg_abbrev, dwarf::DW_AT_producer);
378 PushByte(dbg_abbrev, dwarf::DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800379
380 // DW_LANG_Java DW_FORM_data1.
David Srbecky6f715892015-03-30 14:21:42 +0100381 PushByte(dbg_abbrev, dwarf::DW_AT_language);
382 PushByte(dbg_abbrev, dwarf::DW_FORM_data1);
Mark Mendellae9fd932014-02-10 16:14:35 -0800383
384 // DW_AT_low_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100385 PushByte(dbg_abbrev, dwarf::DW_AT_low_pc);
386 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800387
388 // DW_AT_high_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100389 PushByte(dbg_abbrev, dwarf::DW_AT_high_pc);
390 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700391
392 if (dbg_line != nullptr) {
393 // DW_AT_stmt_list DW_FORM_sec_offset.
David Srbecky6f715892015-03-30 14:21:42 +0100394 PushByte(dbg_abbrev, dwarf::DW_AT_stmt_list);
395 PushByte(dbg_abbrev, dwarf::DW_FORM_data4);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700396 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800397
398 // End of DW_TAG_compile_unit.
David Srbecky6f715892015-03-30 14:21:42 +0100399 PushByte(dbg_abbrev, 0); // DW_AT.
400 PushByte(dbg_abbrev, 0); // DW_FORM.
Mark Mendellae9fd932014-02-10 16:14:35 -0800401
402 // Tag 2: Compilation unit: DW_TAG_subprogram.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700403 PushByte(dbg_abbrev, 2);
David Srbecky6f715892015-03-30 14:21:42 +0100404 PushByte(dbg_abbrev, dwarf::DW_TAG_subprogram);
Mark Mendellae9fd932014-02-10 16:14:35 -0800405
406 // There are no children.
David Srbecky6f715892015-03-30 14:21:42 +0100407 PushByte(dbg_abbrev, dwarf::DW_CHILDREN_no);
Mark Mendellae9fd932014-02-10 16:14:35 -0800408
409 // Name of the method.
David Srbecky6f715892015-03-30 14:21:42 +0100410 PushByte(dbg_abbrev, dwarf::DW_AT_name);
411 PushByte(dbg_abbrev, dwarf::DW_FORM_strp);
Mark Mendellae9fd932014-02-10 16:14:35 -0800412
413 // DW_AT_low_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100414 PushByte(dbg_abbrev, dwarf::DW_AT_low_pc);
415 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800416
417 // DW_AT_high_pc DW_FORM_addr.
David Srbecky6f715892015-03-30 14:21:42 +0100418 PushByte(dbg_abbrev, dwarf::DW_AT_high_pc);
419 PushByte(dbg_abbrev, dwarf::DW_FORM_addr);
Mark Mendellae9fd932014-02-10 16:14:35 -0800420
421 // End of DW_TAG_subprogram.
David Srbecky6f715892015-03-30 14:21:42 +0100422 PushByte(dbg_abbrev, 0); // DW_AT.
423 PushByte(dbg_abbrev, 0); // DW_FORM.
424
425 // End of abbrevs for compilation unit
426 PushByte(dbg_abbrev, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800427
428 // Start the debug_info section with the header information
429 // 'unit_length' will be filled in later.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700430 int cunit_length = dbg_info->size();
Vladimir Marko80b96d12015-02-19 15:50:28 +0000431 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800432
433 // 'version' - 3.
434 PushHalf(dbg_info, 3);
435
436 // Offset into .debug_abbrev section (always 0).
Vladimir Marko80b96d12015-02-19 15:50:28 +0000437 Push32(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800438
David Srbecky6f715892015-03-30 14:21:42 +0100439 // Address size: 4 or 8.
440 PushByte(dbg_info, use_64bit_addresses ? 8 : 4);
Mark Mendellae9fd932014-02-10 16:14:35 -0800441
442 // Start the description for the compilation unit.
443 // This uses tag 1.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700444 PushByte(dbg_info, 1);
445
446 // The producer is Android dex2oat.
Vladimir Marko80b96d12015-02-19 15:50:28 +0000447 Push32(dbg_info, producer_str_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800448
449 // The language is Java.
David Srbecky6f715892015-03-30 14:21:42 +0100450 PushByte(dbg_info, dwarf::DW_LANG_Java);
Mark Mendellae9fd932014-02-10 16:14:35 -0800451
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700452 // low_pc and high_pc.
David Srbecky6f715892015-03-30 14:21:42 +0100453 uint32_t cunit_low_pc = static_cast<uint32_t>(-1);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700454 uint32_t cunit_high_pc = 0;
David Srbecky6f715892015-03-30 14:21:42 +0100455 for (auto method_info : method_infos) {
456 cunit_low_pc = std::min(cunit_low_pc, method_info.low_pc_);
457 cunit_high_pc = std::max(cunit_high_pc, method_info.high_pc_);
458 }
459 Push32(dbg_info, cunit_low_pc + text_section_offset);
460 Push32(dbg_info, cunit_high_pc + text_section_offset);
Mark Mendellae9fd932014-02-10 16:14:35 -0800461
David Srbecky6f715892015-03-30 14:21:42 +0100462 if (dbg_line != nullptr) {
463 // Line number table offset.
464 Push32(dbg_info, dbg_line->size());
465 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800466
David Srbecky6f715892015-03-30 14:21:42 +0100467 for (auto method_info : method_infos) {
468 // Start a new TAG: subroutine (2).
469 PushByte(dbg_info, 2);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700470
David Srbecky6f715892015-03-30 14:21:42 +0100471 // Enter name, low_pc, high_pc.
472 Push32(dbg_info, PushStr(dbg_str, method_info.method_name_));
473 Push32(dbg_info, method_info.low_pc_ + text_section_offset);
474 Push32(dbg_info, method_info.high_pc_ + text_section_offset);
475 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700476
David Srbecky6f715892015-03-30 14:21:42 +0100477 if (dbg_line != nullptr) {
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700478 // TODO: in gdb info functions <regexp> - reports Java functions, but
479 // source file is <unknown> because .debug_line is formed as one
480 // compilation unit. To fix this it is possible to generate
481 // a separate compilation unit for every distinct Java source.
482 // Each of the these compilation units can have several non-adjacent
483 // method ranges.
484
David Srbecky6f715892015-03-30 14:21:42 +0100485 std::vector<dwarf::DebugLineWriter<>::FileEntry> files;
486 std::unordered_map<std::string, size_t> files_map;
487 std::vector<std::string> directories;
488 std::unordered_map<std::string, size_t> directories_map;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700489
David Srbecky6f715892015-03-30 14:21:42 +0100490 int code_factor_bits_ = 0;
491 int isa = -1;
492 switch (oat_writer->GetOatHeader().GetInstructionSet()) {
493 case kThumb2:
494 code_factor_bits_ = 1; // 16-bit instuctions
495 isa = 1; // DW_ISA_ARM_thumb.
496 break;
497 case kArm:
David Srbecky934d7542015-04-02 20:38:40 +0100498 code_factor_bits_ = 1; // 16-bit instructions
David Srbecky6f715892015-03-30 14:21:42 +0100499 isa = 2; // DW_ISA_ARM_arm.
500 break;
501 case kArm64:
502 case kMips:
503 case kMips64:
504 code_factor_bits_ = 2; // 32-bit instructions
505 break;
506 case kNone:
507 case kX86:
508 case kX86_64:
509 break;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700510 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700511
David Srbecky6f715892015-03-30 14:21:42 +0100512 dwarf::DebugLineOpCodeWriter<> opcodes(use_64bit_addresses, code_factor_bits_);
513 opcodes.SetAddress(text_section_offset + cunit_low_pc);
514 if (isa != -1) {
515 opcodes.SetISA(isa);
516 }
517 DefaultSrcMap dex2line_map;
518 for (size_t i = 0; i < method_infos.size(); i++) {
519 const OatWriter::DebugInfo& method_info = method_infos[i];
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700520
David Srbecky6f715892015-03-30 14:21:42 +0100521 // Addresses in the line table should be unique and increasing.
522 if (method_info.deduped_) {
523 continue;
524 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700525
David Srbecky6f715892015-03-30 14:21:42 +0100526 // Get and deduplicate directory and filename.
527 int file_index = 0; // 0 - primary source file of the compilation.
528 if (method_info.src_file_name_ != nullptr) {
529 std::string file_name(method_info.src_file_name_);
530 size_t file_name_slash = file_name.find_last_of('/');
531 std::string class_name(method_info.class_descriptor_);
532 size_t class_name_slash = class_name.find_last_of('/');
533 std::string full_path(file_name);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700534
David Srbecky6f715892015-03-30 14:21:42 +0100535 // Guess directory from package name.
536 int directory_index = 0; // 0 - current directory of the compilation.
537 if (file_name_slash == std::string::npos && // Just filename.
538 class_name.front() == 'L' && // Type descriptor for a class.
539 class_name_slash != std::string::npos) { // Has package name.
540 std::string package_name = class_name.substr(1, class_name_slash - 1);
541 auto it = directories_map.find(package_name);
542 if (it == directories_map.end()) {
543 directory_index = 1 + directories.size();
544 directories_map.emplace(package_name, directory_index);
545 directories.push_back(package_name);
546 } else {
547 directory_index = it->second;
548 }
549 full_path = package_name + "/" + file_name;
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700550 }
David Srbecky6f715892015-03-30 14:21:42 +0100551
552 // Add file entry.
553 auto it2 = files_map.find(full_path);
554 if (it2 == files_map.end()) {
555 file_index = 1 + files.size();
556 files_map.emplace(full_path, file_index);
557 files.push_back(dwarf::DebugLineWriter<>::FileEntry {
558 file_name,
559 directory_index,
560 0, // Modification time - NA.
561 0, // File size - NA.
562 });
563 } else {
564 file_index = it2->second;
565 }
566 }
567 opcodes.SetFile(file_index);
568
569 // Generate mapping opcodes from PC to Java lines.
570 dex2line_map.clear();
571 GetLineInfoForJava(method_info.dbgstream_, &dex2line_map);
572 uint32_t low_pc = text_section_offset + method_info.low_pc_;
573 if (file_index != 0 && !dex2line_map.empty()) {
574 bool first = true;
575 for (SrcMapElem pc2dex : method_info.compiled_method_->GetSrcMappingTable()) {
576 uint32_t pc = pc2dex.from_;
577 int dex = pc2dex.to_;
578 auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex));
579 if (dex2line.first) {
580 int line = dex2line.second;
581 if (first) {
582 first = false;
583 if (pc > 0) {
584 // Assume that any preceding code is prologue.
585 int first_line = dex2line_map.front().to_;
586 // Prologue is not a sensible place for a breakpoint.
587 opcodes.NegateStmt();
588 opcodes.AddRow(low_pc, first_line);
589 opcodes.NegateStmt();
590 opcodes.SetPrologueEnd();
591 }
592 opcodes.AddRow(low_pc + pc, line);
593 } else if (line != opcodes.CurrentLine()) {
594 opcodes.AddRow(low_pc + pc, line);
595 }
596 }
597 }
598 } else {
599 // line 0 - instruction cannot be attributed to any source line.
600 opcodes.AddRow(low_pc, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700601 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800602 }
603
David Srbecky6f715892015-03-30 14:21:42 +0100604 opcodes.AdvancePC(text_section_offset + cunit_high_pc);
605 opcodes.EndSequence();
Mark Mendellae9fd932014-02-10 16:14:35 -0800606
David Srbecky6f715892015-03-30 14:21:42 +0100607 dwarf::DebugLineWriter<> dbg_line_writer(dbg_line);
608 dbg_line_writer.WriteTable(directories, files, opcodes);
Mark Mendellae9fd932014-02-10 16:14:35 -0800609 }
610
David Srbecky6f715892015-03-30 14:21:42 +0100611 // One byte terminator.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700612 PushByte(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800613
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700614 // We have now walked all the methods. Fill in lengths.
615 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700616}
617
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700618template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
619 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
620 typename Elf_Phdr, typename Elf_Shdr>
Andreas Gampe86830382014-12-12 21:41:29 -0800621// Do not inline to avoid Clang stack frame problems. b/18738594
622NO_INLINE
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700623static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
624 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
625 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
626 OatWriter* oat_writer) {
627 std::unique_ptr<std::vector<uint8_t>> cfi_info(
628 ConstructCIEFrame(compiler_driver->GetInstructionSet()));
629
Ian Rogers0279ebb2014-10-08 17:27:48 -0700630 Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700631
632 // Iterate over the compiled methods.
633 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
Ian Rogers0279ebb2014-10-08 17:27:48 -0700634 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
635 builder->GetSymtabBuilder();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700636 for (auto it = method_info.begin(); it != method_info.end(); ++it) {
David Srbecky6f715892015-03-30 14:21:42 +0100637 uint32_t low_pc = it->low_pc_;
638 // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
639 low_pc += it->compiled_method_->CodeDelta();
640 symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), low_pc,
641 true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700642
Ningsheng Jianf9734552014-10-27 14:56:34 +0800643 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
644 // instructions, so that disassembler tools can correctly disassemble.
645 if (it->compiled_method_->GetInstructionSet() == kThumb2) {
646 symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true,
647 0, STB_LOCAL, STT_NOTYPE);
648 }
649
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700650 // Include CFI for compiled method, if possible.
651 if (cfi_info.get() != nullptr) {
652 DCHECK(it->compiled_method_ != nullptr);
653
654 // Copy in the FDE, if present
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800655 const SwapVector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700656 if (fde != nullptr) {
657 // Copy the information into cfi_info and then fix the address in the new copy.
658 int cur_offset = cfi_info->size();
659 cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
660
661 bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
662
663 // Set the 'CIE_pointer' field.
664 uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
665 uint64_t offset_to_update = CIE_pointer;
666 if (is_64bit) {
667 (*cfi_info)[offset_to_update+0] = CIE_pointer;
668 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
669 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
670 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
671 (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
672 (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
673 (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
674 (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
675 } else {
676 (*cfi_info)[offset_to_update+0] = CIE_pointer;
677 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
678 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
679 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
680 }
681
682 // Set the 'initial_location' field.
683 offset_to_update += is_64bit ? 8 : 4;
684 if (is_64bit) {
685 const uint64_t quick_code_start = it->low_pc_ + text_section_address;
686 (*cfi_info)[offset_to_update+0] = quick_code_start;
687 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
688 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
689 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
690 (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
691 (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
692 (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
693 (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
694 } else {
695 const uint32_t quick_code_start = it->low_pc_ + text_section_address;
696 (*cfi_info)[offset_to_update+0] = quick_code_start;
697 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
698 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
699 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
700 }
701 }
702 }
703 }
704
705 bool hasCFI = (cfi_info.get() != nullptr);
706 bool hasLineInfo = false;
707 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
708 if (dbg_info.dbgstream_ != nullptr &&
709 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
710 hasLineInfo = true;
711 break;
712 }
713 }
714
715 if (hasLineInfo || hasCFI) {
716 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
717 SHT_PROGBITS,
718 0, nullptr, 0, 1, 0);
719 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
720 SHT_PROGBITS,
721 0, nullptr, 0, 1, 0);
722 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
723 SHT_PROGBITS,
724 0, nullptr, 0, 1, 0);
725 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
726 SHT_PROGBITS,
727 0, nullptr, 0, 1, 0);
728
729 FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
730 debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
731 hasLineInfo ? debug_line.GetBuffer() : nullptr,
732 text_section_address);
733
734 builder->RegisterRawSection(debug_info);
735 builder->RegisterRawSection(debug_abbrev);
736
737 if (hasCFI) {
738 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
739 SHT_PROGBITS,
740 SHF_ALLOC,
741 nullptr, 0, 4, 0);
742 eh_frame.SetBuffer(std::move(*cfi_info.get()));
743 builder->RegisterRawSection(eh_frame);
744 }
745
746 if (hasLineInfo) {
747 builder->RegisterRawSection(debug_line);
748 }
749
750 builder->RegisterRawSection(debug_str);
751 }
752}
753
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000754// Explicit instantiations
755template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
756 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
757template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
758 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
759
Brian Carlstrom7940e442013-07-12 13:46:57 -0700760} // namespace art