blob: 24cb364d080fe261e1c5cfeab009fd07d6f3e217 [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()) {
David Srbecky189ae822015-04-04 10:15:17 +0100493 case kArm: // arm actually means thumb2.
David Srbecky6f715892015-03-30 14:21:42 +0100494 case kThumb2:
495 code_factor_bits_ = 1; // 16-bit instuctions
496 isa = 1; // DW_ISA_ARM_thumb.
497 break;
David Srbecky6f715892015-03-30 14:21:42 +0100498 case kArm64:
499 case kMips:
500 case kMips64:
501 code_factor_bits_ = 2; // 32-bit instructions
502 break;
503 case kNone:
504 case kX86:
505 case kX86_64:
506 break;
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700507 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700508
David Srbecky6f715892015-03-30 14:21:42 +0100509 dwarf::DebugLineOpCodeWriter<> opcodes(use_64bit_addresses, code_factor_bits_);
510 opcodes.SetAddress(text_section_offset + cunit_low_pc);
511 if (isa != -1) {
512 opcodes.SetISA(isa);
513 }
514 DefaultSrcMap dex2line_map;
515 for (size_t i = 0; i < method_infos.size(); i++) {
516 const OatWriter::DebugInfo& method_info = method_infos[i];
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700517
David Srbecky6f715892015-03-30 14:21:42 +0100518 // Addresses in the line table should be unique and increasing.
519 if (method_info.deduped_) {
520 continue;
521 }
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700522
David Srbecky6f715892015-03-30 14:21:42 +0100523 // Get and deduplicate directory and filename.
524 int file_index = 0; // 0 - primary source file of the compilation.
525 if (method_info.src_file_name_ != nullptr) {
526 std::string file_name(method_info.src_file_name_);
527 size_t file_name_slash = file_name.find_last_of('/');
528 std::string class_name(method_info.class_descriptor_);
529 size_t class_name_slash = class_name.find_last_of('/');
530 std::string full_path(file_name);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700531
David Srbecky6f715892015-03-30 14:21:42 +0100532 // Guess directory from package name.
533 int directory_index = 0; // 0 - current directory of the compilation.
534 if (file_name_slash == std::string::npos && // Just filename.
535 class_name.front() == 'L' && // Type descriptor for a class.
536 class_name_slash != std::string::npos) { // Has package name.
537 std::string package_name = class_name.substr(1, class_name_slash - 1);
538 auto it = directories_map.find(package_name);
539 if (it == directories_map.end()) {
540 directory_index = 1 + directories.size();
541 directories_map.emplace(package_name, directory_index);
542 directories.push_back(package_name);
543 } else {
544 directory_index = it->second;
545 }
546 full_path = package_name + "/" + file_name;
Yevgeny Rouban33ac8192014-08-19 18:39:57 +0700547 }
David Srbecky6f715892015-03-30 14:21:42 +0100548
549 // Add file entry.
550 auto it2 = files_map.find(full_path);
551 if (it2 == files_map.end()) {
552 file_index = 1 + files.size();
553 files_map.emplace(full_path, file_index);
554 files.push_back(dwarf::DebugLineWriter<>::FileEntry {
555 file_name,
556 directory_index,
557 0, // Modification time - NA.
558 0, // File size - NA.
559 });
560 } else {
561 file_index = it2->second;
562 }
563 }
564 opcodes.SetFile(file_index);
565
566 // Generate mapping opcodes from PC to Java lines.
567 dex2line_map.clear();
568 GetLineInfoForJava(method_info.dbgstream_, &dex2line_map);
569 uint32_t low_pc = text_section_offset + method_info.low_pc_;
570 if (file_index != 0 && !dex2line_map.empty()) {
571 bool first = true;
572 for (SrcMapElem pc2dex : method_info.compiled_method_->GetSrcMappingTable()) {
573 uint32_t pc = pc2dex.from_;
574 int dex = pc2dex.to_;
575 auto dex2line = dex2line_map.Find(static_cast<uint32_t>(dex));
576 if (dex2line.first) {
577 int line = dex2line.second;
578 if (first) {
579 first = false;
580 if (pc > 0) {
581 // Assume that any preceding code is prologue.
582 int first_line = dex2line_map.front().to_;
583 // Prologue is not a sensible place for a breakpoint.
584 opcodes.NegateStmt();
585 opcodes.AddRow(low_pc, first_line);
586 opcodes.NegateStmt();
587 opcodes.SetPrologueEnd();
588 }
589 opcodes.AddRow(low_pc + pc, line);
590 } else if (line != opcodes.CurrentLine()) {
591 opcodes.AddRow(low_pc + pc, line);
592 }
593 }
594 }
595 } else {
596 // line 0 - instruction cannot be attributed to any source line.
597 opcodes.AddRow(low_pc, 0);
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700598 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800599 }
600
David Srbecky6f715892015-03-30 14:21:42 +0100601 opcodes.AdvancePC(text_section_offset + cunit_high_pc);
602 opcodes.EndSequence();
Mark Mendellae9fd932014-02-10 16:14:35 -0800603
David Srbecky6f715892015-03-30 14:21:42 +0100604 dwarf::DebugLineWriter<> dbg_line_writer(dbg_line);
605 dbg_line_writer.WriteTable(directories, files, opcodes);
Mark Mendellae9fd932014-02-10 16:14:35 -0800606 }
607
David Srbecky6f715892015-03-30 14:21:42 +0100608 // One byte terminator.
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700609 PushByte(dbg_info, 0);
Mark Mendellae9fd932014-02-10 16:14:35 -0800610
Yevgeny Roubane3ea8382014-08-08 16:29:38 +0700611 // We have now walked all the methods. Fill in lengths.
612 UpdateWord(dbg_info, cunit_length, dbg_info->size() - cunit_length - 4);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700613}
614
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700615template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
616 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
617 typename Elf_Phdr, typename Elf_Shdr>
Andreas Gampe86830382014-12-12 21:41:29 -0800618// Do not inline to avoid Clang stack frame problems. b/18738594
619NO_INLINE
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700620static void WriteDebugSymbols(const CompilerDriver* compiler_driver,
621 ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn,
622 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
623 OatWriter* oat_writer) {
624 std::unique_ptr<std::vector<uint8_t>> cfi_info(
625 ConstructCIEFrame(compiler_driver->GetInstructionSet()));
626
Ian Rogers0279ebb2014-10-08 17:27:48 -0700627 Elf_Addr text_section_address = builder->GetTextBuilder().GetSection()->sh_addr;
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700628
629 // Iterate over the compiled methods.
630 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetCFIMethodInfo();
Ian Rogers0279ebb2014-10-08 17:27:48 -0700631 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab =
632 builder->GetSymtabBuilder();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700633 for (auto it = method_info.begin(); it != method_info.end(); ++it) {
David Srbecky6f715892015-03-30 14:21:42 +0100634 uint32_t low_pc = it->low_pc_;
635 // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
636 low_pc += it->compiled_method_->CodeDelta();
637 symtab->AddSymbol(it->method_name_, &builder->GetTextBuilder(), low_pc,
638 true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700639
Ningsheng Jianf9734552014-10-27 14:56:34 +0800640 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
641 // instructions, so that disassembler tools can correctly disassemble.
642 if (it->compiled_method_->GetInstructionSet() == kThumb2) {
643 symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true,
644 0, STB_LOCAL, STT_NOTYPE);
645 }
646
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700647 // Include CFI for compiled method, if possible.
648 if (cfi_info.get() != nullptr) {
649 DCHECK(it->compiled_method_ != nullptr);
650
651 // Copy in the FDE, if present
Andreas Gampee21dc3d2014-12-08 16:59:43 -0800652 const SwapVector<uint8_t>* fde = it->compiled_method_->GetCFIInfo();
Andreas Gampe54fc26c2014-09-04 21:47:42 -0700653 if (fde != nullptr) {
654 // Copy the information into cfi_info and then fix the address in the new copy.
655 int cur_offset = cfi_info->size();
656 cfi_info->insert(cfi_info->end(), fde->begin(), fde->end());
657
658 bool is_64bit = *(reinterpret_cast<const uint32_t*>(fde->data())) == 0xffffffff;
659
660 // Set the 'CIE_pointer' field.
661 uint64_t CIE_pointer = cur_offset + (is_64bit ? 12 : 4);
662 uint64_t offset_to_update = CIE_pointer;
663 if (is_64bit) {
664 (*cfi_info)[offset_to_update+0] = CIE_pointer;
665 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
666 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
667 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
668 (*cfi_info)[offset_to_update+4] = CIE_pointer >> 32;
669 (*cfi_info)[offset_to_update+5] = CIE_pointer >> 40;
670 (*cfi_info)[offset_to_update+6] = CIE_pointer >> 48;
671 (*cfi_info)[offset_to_update+7] = CIE_pointer >> 56;
672 } else {
673 (*cfi_info)[offset_to_update+0] = CIE_pointer;
674 (*cfi_info)[offset_to_update+1] = CIE_pointer >> 8;
675 (*cfi_info)[offset_to_update+2] = CIE_pointer >> 16;
676 (*cfi_info)[offset_to_update+3] = CIE_pointer >> 24;
677 }
678
679 // Set the 'initial_location' field.
680 offset_to_update += is_64bit ? 8 : 4;
681 if (is_64bit) {
682 const uint64_t quick_code_start = it->low_pc_ + text_section_address;
683 (*cfi_info)[offset_to_update+0] = quick_code_start;
684 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
685 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
686 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
687 (*cfi_info)[offset_to_update+4] = quick_code_start >> 32;
688 (*cfi_info)[offset_to_update+5] = quick_code_start >> 40;
689 (*cfi_info)[offset_to_update+6] = quick_code_start >> 48;
690 (*cfi_info)[offset_to_update+7] = quick_code_start >> 56;
691 } else {
692 const uint32_t quick_code_start = it->low_pc_ + text_section_address;
693 (*cfi_info)[offset_to_update+0] = quick_code_start;
694 (*cfi_info)[offset_to_update+1] = quick_code_start >> 8;
695 (*cfi_info)[offset_to_update+2] = quick_code_start >> 16;
696 (*cfi_info)[offset_to_update+3] = quick_code_start >> 24;
697 }
698 }
699 }
700 }
701
702 bool hasCFI = (cfi_info.get() != nullptr);
703 bool hasLineInfo = false;
704 for (auto& dbg_info : oat_writer->GetCFIMethodInfo()) {
705 if (dbg_info.dbgstream_ != nullptr &&
706 !dbg_info.compiled_method_->GetSrcMappingTable().empty()) {
707 hasLineInfo = true;
708 break;
709 }
710 }
711
712 if (hasLineInfo || hasCFI) {
713 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_info(".debug_info",
714 SHT_PROGBITS,
715 0, nullptr, 0, 1, 0);
716 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_abbrev(".debug_abbrev",
717 SHT_PROGBITS,
718 0, nullptr, 0, 1, 0);
719 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_str(".debug_str",
720 SHT_PROGBITS,
721 0, nullptr, 0, 1, 0);
722 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> debug_line(".debug_line",
723 SHT_PROGBITS,
724 0, nullptr, 0, 1, 0);
725
726 FillInCFIInformation(oat_writer, debug_info.GetBuffer(),
727 debug_abbrev.GetBuffer(), debug_str.GetBuffer(),
728 hasLineInfo ? debug_line.GetBuffer() : nullptr,
729 text_section_address);
730
731 builder->RegisterRawSection(debug_info);
732 builder->RegisterRawSection(debug_abbrev);
733
734 if (hasCFI) {
735 ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> eh_frame(".eh_frame",
736 SHT_PROGBITS,
737 SHF_ALLOC,
738 nullptr, 0, 4, 0);
739 eh_frame.SetBuffer(std::move(*cfi_info.get()));
740 builder->RegisterRawSection(eh_frame);
741 }
742
743 if (hasLineInfo) {
744 builder->RegisterRawSection(debug_line);
745 }
746
747 builder->RegisterRawSection(debug_str);
748 }
749}
750
Nicolas Geoffrayf9b87b12014-09-02 08:12:09 +0000751// Explicit instantiations
752template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
753 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>;
754template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn,
755 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>;
756
Brian Carlstrom7940e442013-07-12 13:46:57 -0700757} // namespace art