Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: src/gdb-jit.cc

Issue 6371011: Ensures that GDB prints stacktraces correctly for x64 builds when debugging t... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 TYPE_STRTAB = 3, 194 TYPE_STRTAB = 3,
195 TYPE_RELA = 4, 195 TYPE_RELA = 4,
196 TYPE_HASH = 5, 196 TYPE_HASH = 5,
197 TYPE_DYNAMIC = 6, 197 TYPE_DYNAMIC = 6,
198 TYPE_NOTE = 7, 198 TYPE_NOTE = 7,
199 TYPE_NOBITS = 8, 199 TYPE_NOBITS = 8,
200 TYPE_REL = 9, 200 TYPE_REL = 9,
201 TYPE_SHLIB = 10, 201 TYPE_SHLIB = 10,
202 TYPE_DYNSYM = 11, 202 TYPE_DYNSYM = 11,
203 TYPE_LOPROC = 0x70000000, 203 TYPE_LOPROC = 0x70000000,
204 TYPE_X86_64_UNWIND = 0x70000001,
204 TYPE_HIPROC = 0x7fffffff, 205 TYPE_HIPROC = 0x7fffffff,
205 TYPE_LOUSER = 0x80000000, 206 TYPE_LOUSER = 0x80000000,
206 TYPE_HIUSER = 0xffffffff 207 TYPE_HIUSER = 0xffffffff
207 }; 208 };
208 209
209 enum Flags { 210 enum Flags {
210 FLAG_WRITE = 1, 211 FLAG_WRITE = 1,
211 FLAG_ALLOC = 2, 212 FLAG_ALLOC = 2,
212 FLAG_EXEC = 4 213 FLAG_EXEC = 4
213 }; 214 };
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after
1159 1160
1160 void GDBJITInterface::RegisterDetailedLineInfo(Code* code, 1161 void GDBJITInterface::RegisterDetailedLineInfo(Code* code,
1161 GDBJITLineInfo* line_info) { 1162 GDBJITLineInfo* line_info) {
1162 ASSERT(!IsLineInfoTagged(line_info)); 1163 ASSERT(!IsLineInfoTagged(line_info));
1163 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true); 1164 HashMap::Entry* e = entries.Lookup(code, HashForCodeObject(code), true);
1164 ASSERT(e->value == NULL); 1165 ASSERT(e->value == NULL);
1165 e->value = TagLineInfo(line_info); 1166 e->value = TagLineInfo(line_info);
1166 } 1167 }
1167 1168
1168 1169
1170 #ifdef V8_TARGET_ARCH_X64
1171
1172
1173 class UnwindInfoSection : public ELFSection {
1174 public:
1175 explicit UnwindInfoSection(UnwindInfoInterface::UnwindInformation *);
1176 explicit UnwindInfoSection(uintptr_t begin, uintptr_t end);
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 2 argument constructors don't need explicit.
1177 virtual bool WriteBody(Writer *w);
1178
1179 private:
1180 UnwindInfoInterface::UnwindInformation *info_;
1181 uintptr_t begin_, length_;
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 uintptr_t begin_; uintptr_t length_;
1182 bool is_code_stub_;
1183
1184 // DWARF3 Specification, Table 7.23
1185 enum CFIInstructions {
1186 DW_CFA_ADVANCE_LOC = 0X40,
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 style nit: 0X -> 0x
1187 DW_CFA_OFFSET = 0X80,
1188 DW_CFA_RESTORE = 0XC0,
1189 DW_CFA_NOP = 0X00,
1190 DW_CFA_SET_LOC = 0X01,
1191 DW_CFA_ADVANCE_LOC1 = 0X02,
1192 DW_CFA_ADVANCE_LOC2 = 0X03,
1193 DW_CFA_ADVANCE_LOC4 = 0X04,
1194 DW_CFA_OFFSET_EXTENDED = 0X05,
1195 DW_CFA_RESTORE_EXTENDED = 0X06,
1196 DW_CFA_UNDEFINED = 0X07,
1197 DW_CFA_SAME_VALUE = 0X08,
1198 DW_CFA_REGISTER = 0X09,
1199 DW_CFA_REMEMBER_STATE = 0X0A,
1200 DW_CFA_RESTORE_STATE = 0X0B,
1201 DW_CFA_DEF_CFA = 0X0C,
1202 DW_CFA_DEF_CFA_REGISTER = 0X0D,
1203 DW_CFA_DEF_CFA_OFFSET = 0X0E,
1204
1205 DW_CFA_DEF_CFA_EXPRESSION = 0X0F,
1206 DW_CFA_EXPRESSION = 0X10,
1207 DW_CFA_OFFSET_EXTENDED_SF = 0X11,
1208 DW_CFA_DEF_CFA_SF = 0X12,
1209 DW_CFA_DEF_CFA_OFFSET_SF = 0X13,
1210 DW_CFA_VAL_OFFSET = 0X14,
1211 DW_CFA_VAL_OFFSET_SF = 0X15,
1212 DW_CFA_VAL_EXPRESSION = 0X16
1213 };
1214
1215 // System V ABI, AMD64 Supplement, Version 0.99.5, Figure 3.36
1216 enum RegisterMapping {
1217 // Only the relevant ones have been added to reduce clutter.
1218 AMD64_RBP = 6,
1219 AMD64_RSP = 7,
1220 AMD64_RA = 16
1221 };
1222
1223 enum CFIConstants {
1224 CIE_ID = 0,
1225 CIE_VERSION = 1,
1226 CODE_ALIGN_FACTOR = 1,
1227 DATA_ALIGN_FACTOR = 1,
1228 RETURN_ADDRESS_REGISTER = AMD64_RA
1229 };
1230 };
1231
1232
1233 UnwindInfoSection::UnwindInfoSection(UnwindInfoInterface::UnwindInformation
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 I think the right way to format this will be Unw
1234 *info)
1235 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), info_(info),
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 either all on a single line or each initializer on
1236 is_code_stub_(false) { }
1237
1238
1239 UnwindInfoSection::UnwindInfoSection(uintptr_t begin, uintptr_t length)
1240 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), begin_(begin),
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 ditto
1241 length_(length), is_code_stub_(true) { }
1242
1243
1244 bool UnwindInfoSection::WriteBody(Writer *w) {
1245 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>();
1246 uint32_t cie_position = w->position(), align;
1247
1248 // Write out the CIE header. Currently no 'common instructions' are
1249 // emitted onto the CIE; every FDE has its own set of instructions.
1250
1251 w->Write<uint32_t>(CIE_ID);
1252 w->Write<uint8_t>(CIE_VERSION);
1253 w->Write<uint8_t>(0); // Augmentation string.
1254 w->WriteSLEB128(CODE_ALIGN_FACTOR);
1255 w->WriteSLEB128(DATA_ALIGN_FACTOR);
1256 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER);
1257
1258 align = (w->position() - cie_position) % kPointerSize;
1259 if (align) {
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 We don't rely on implicit int->bool convertions, s
1260 for (uint32_t i = 0; i < (kPointerSize - align); i++) {
1261 w->Write<uint8_t>(DW_CFA_NOP);
1262 }
1263 }
1264 ASSERT((w->position() - cie_position) % kPointerSize == 0);
1265 cie_length_slot.set(w->position() - cie_position);
1266
1267 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>();
1268 int fde_position = w->position();
1269 w->Write<int32_t>(fde_position - cie_position + 4); // Pointer to CIE
1270
1271 // The (only) FDE for this function
1272
1273 if (!is_code_stub_) {
1274 w->Write<uintptr_t>(info_->begin_);
1275 w->Write<uintptr_t>
1276 (info_->state_offsets_[UnwindInfoInterface::UNWIND_STATE_AFTER_RETURN]);
1277
1278 // The CFA is the frame-pointer of the current function. This seemed the
1279 // most straightforward since (it seems) both the full-codegen and the
1280 // classic codegen maintain the frame-pointer.
1281
1282 // -- The first state, just after the control has been transferred to the
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 Can you split this into four different functions f
1283 // -- the function.
1284
1285 // RBP for this function will be the value of RSP after pushing the RBP
1286 // for the previous function. The previous RBP has not been pushed yet.
1287 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1288 w->WriteULEB128(AMD64_RSP);
1289 w->WriteSLEB128(-kPointerSize);
1290
1291 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant,
1292 // and hence omitted from the next states.
1293 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1294 w->WriteULEB128(AMD64_RA);
1295 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset);
1296
1297 // The RBP of the previous function is still in RBP.
1298 w->Write<uint8_t>(DW_CFA_SAME_VALUE);
1299 w->WriteULEB128(AMD64_RBP);
1300
1301 // Last location described by this entry.
1302 w->Write<uint8_t>(DW_CFA_SET_LOC);
1303 w->Write<uint64_t>
1304 (info_->begin_ + info_->state_offsets_
1305 [UnwindInfoInterface::UNWIND_STATE_AFTER_RBP_PUSH]);
1306
1307 // -- The second state, just after RBP has been pushed.
1308
1309 // RBP / CFA for this function is now the current RSP, so just set the
1310 // offset from the previous rule (from -8) to 0.
1311 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET);
1312 w->WriteULEB128(0);
1313
1314 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant
1315 // in this and the next state, and hence omitted in the next state.
1316 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1317 w->WriteULEB128(AMD64_RBP);
1318 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1319
1320 // Last location described by this entry.
1321 w->Write<uint8_t>(DW_CFA_SET_LOC);
1322 w->Write<uint64_t>
1323 (info_->begin_ + info_->state_offsets_
1324 [UnwindInfoInterface::UNWIND_STATE_AFTER_RBP_SET]);
1325
1326 // -- The third state, after the RBP has been set.
1327
1328 // The CFA can now directly be set to RBP.
1329 w->Write<uint8_t>(DW_CFA_DEF_CFA);
1330 w->WriteULEB128(AMD64_RBP);
1331 w->WriteULEB128(0);
1332
1333 // Last location described by this entry.
1334 w->Write<uint8_t>(DW_CFA_SET_LOC);
1335 w->Write<uint64_t>
1336 (info_->begin_ + info_->state_offsets_
1337 [UnwindInfoInterface::UNWIND_STATE_AFTER_RBP_POP]);
1338
1339 // -- The fourth (final) state. The RBP has been popped (just before issuing
1340 // a return.
1341
1342 // The CFA can is now calculated in the same way as in the first state.
1343 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF);
1344 w->WriteULEB128(AMD64_RSP);
1345 w->WriteSLEB128(-kPointerSize);
1346
1347 // The RBP
1348 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1349 w->WriteULEB128(AMD64_RBP);
1350 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1351
1352 // Last location described by this entry.
1353 w->Write<uint8_t>(DW_CFA_SET_LOC);
1354 w->Write<uint64_t>
1355 (info_->begin_ +
1356 info_->state_offsets_[UnwindInfoInterface::UNWIND_STATE_AFTER_RETURN]);
1357 } else {
1358 // This is a code-stub. Unwind information for code-stubs is not divided
1359 // into stages, we just tell GDB to unwind using the frame pointer.
1360 w->Write<uintptr_t>(begin_);
1361 w->Write<uintptr_t>(length_);
1362
1363 // The CFA is the current function's RBP
1364 w->Write<uint8_t>(DW_CFA_DEF_CFA);
1365 w->WriteULEB128(AMD64_RBP);
1366 w->WriteULEB128(0);
1367
1368 // These assumptions are not true at the code-stub entry and exit. However,
1369 // we are assuming that the debugger will halt code-stubs only at their
1370 // call sites.
1371 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1372 w->WriteULEB128(AMD64_RA);
1373 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset);
1374
1375 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED);
1376 w->WriteULEB128(AMD64_RBP);
1377 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset);
1378
1379 // The last location described by this entry.
1380 w->Write<uint8_t>(DW_CFA_SET_LOC);
1381 w->Write<uint64_t>(begin_ + length_);
1382 }
1383
1384 if ((align = (w->position() - fde_position) % kPointerSize)) {
Vyacheslav Egorov (Chromium) 2011/01/25 12:50:11 I think we usually avoid assignments in expression
1385 for (uint32_t i = 0; i < (kPointerSize - align); i++)
1386 w->Write<uint8_t>(DW_CFA_NOP);
1387 }
1388
1389 ASSERT((w->position() - fde_position) % kPointerSize == 0);
1390 fde_length_slot.set(w->position() - fde_position);
1391
1392 return true;
1393 }
1394
1395
1396 UnwindInfoInterface::UnwindInformationList *UnwindInfoInterface::info_ = NULL;
1397
1398
1399 static void SaveUnwindInfo(UnwindInfoSection *section) {
1400 ELF elf;
1401 elf.AddSection(section);
1402 Writer w(&elf);
1403 elf.Write(&w);
1404 JITCodeEntry *entry = CreateCodeEntry(w.buffer(), w.position());
1405 RegisterCodeEntry(entry);
1406 }
1407
1408
1409 UnwindInfoInterface::~UnwindInfoInterface() {
1410 ASSERT(info_ != NULL);
1411
1412 UnwindInfoSection unwind_section(&info_->data_);
1413 SaveUnwindInfo(&unwind_section);
1414 UnwindInformationList *tmp = info_->next_;
1415 delete info_;
1416 info_ = tmp;
1417 }
1418
1419
1420 void UnwindInfoInterface::SetCodeStub(uintptr_t b, uintptr_t l) {
1421 UnwindInfoSection unwind_section(b, l);
1422 SaveUnwindInfo(&unwind_section);
1423 }
1424
1425
1426 #endif // V8_TARGET_ARCH_X64
1427
1428
1169 } } // namespace v8::internal 1429 } } // namespace v8::internal
1170 #endif 1430 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698