OLD | NEW |
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 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 } | 1549 } |
1550 | 1550 |
1551 CodeDescription* desc_; | 1551 CodeDescription* desc_; |
1552 }; | 1552 }; |
1553 | 1553 |
1554 | 1554 |
1555 #ifdef V8_TARGET_ARCH_X64 | 1555 #ifdef V8_TARGET_ARCH_X64 |
1556 | 1556 |
1557 class UnwindInfoSection : public DebugSection { | 1557 class UnwindInfoSection : public DebugSection { |
1558 public: | 1558 public: |
1559 explicit UnwindInfoSection(CodeDescription *desc); | 1559 explicit UnwindInfoSection(CodeDescription* desc); |
1560 virtual bool WriteBody(Writer *w); | 1560 virtual bool WriteBody(Writer* w); |
1561 | 1561 |
1562 int WriteCIE(Writer *w); | 1562 int WriteCIE(Writer* w); |
1563 void WriteFDE(Writer *w, int); | 1563 void WriteFDE(Writer* w, int); |
1564 | 1564 |
1565 void WriteFDEStateOnEntry(Writer *w); | 1565 void WriteFDEStateOnEntry(Writer* w); |
1566 void WriteFDEStateAfterRBPPush(Writer *w); | 1566 void WriteFDEStateAfterRBPPush(Writer* w); |
1567 void WriteFDEStateAfterRBPSet(Writer *w); | 1567 void WriteFDEStateAfterRBPSet(Writer* w); |
1568 void WriteFDEStateAfterRBPPop(Writer *w); | 1568 void WriteFDEStateAfterRBPPop(Writer* w); |
1569 | 1569 |
1570 void WriteLength(Writer *w, | 1570 void WriteLength(Writer* w, |
1571 Writer::Slot<uint32_t>* length_slot, | 1571 Writer::Slot<uint32_t>* length_slot, |
1572 int initial_position); | 1572 int initial_position); |
1573 | 1573 |
1574 private: | 1574 private: |
1575 CodeDescription *desc_; | 1575 CodeDescription* desc_; |
1576 | 1576 |
1577 // DWARF3 Specification, Table 7.23 | 1577 // DWARF3 Specification, Table 7.23 |
1578 enum CFIInstructions { | 1578 enum CFIInstructions { |
1579 DW_CFA_ADVANCE_LOC = 0x40, | 1579 DW_CFA_ADVANCE_LOC = 0x40, |
1580 DW_CFA_OFFSET = 0x80, | 1580 DW_CFA_OFFSET = 0x80, |
1581 DW_CFA_RESTORE = 0xC0, | 1581 DW_CFA_RESTORE = 0xC0, |
1582 DW_CFA_NOP = 0x00, | 1582 DW_CFA_NOP = 0x00, |
1583 DW_CFA_SET_LOC = 0x01, | 1583 DW_CFA_SET_LOC = 0x01, |
1584 DW_CFA_ADVANCE_LOC1 = 0x02, | 1584 DW_CFA_ADVANCE_LOC1 = 0x02, |
1585 DW_CFA_ADVANCE_LOC2 = 0x03, | 1585 DW_CFA_ADVANCE_LOC2 = 0x03, |
(...skipping 30 matching lines...) Expand all Loading... |
1616 enum CFIConstants { | 1616 enum CFIConstants { |
1617 CIE_ID = 0, | 1617 CIE_ID = 0, |
1618 CIE_VERSION = 1, | 1618 CIE_VERSION = 1, |
1619 CODE_ALIGN_FACTOR = 1, | 1619 CODE_ALIGN_FACTOR = 1, |
1620 DATA_ALIGN_FACTOR = 1, | 1620 DATA_ALIGN_FACTOR = 1, |
1621 RETURN_ADDRESS_REGISTER = AMD64_RA | 1621 RETURN_ADDRESS_REGISTER = AMD64_RA |
1622 }; | 1622 }; |
1623 }; | 1623 }; |
1624 | 1624 |
1625 | 1625 |
1626 void UnwindInfoSection::WriteLength(Writer *w, | 1626 void UnwindInfoSection::WriteLength(Writer* w, |
1627 Writer::Slot<uint32_t>* length_slot, | 1627 Writer::Slot<uint32_t>* length_slot, |
1628 int initial_position) { | 1628 int initial_position) { |
1629 uint32_t align = (w->position() - initial_position) % kPointerSize; | 1629 uint32_t align = (w->position() - initial_position) % kPointerSize; |
1630 | 1630 |
1631 if (align != 0) { | 1631 if (align != 0) { |
1632 for (uint32_t i = 0; i < (kPointerSize - align); i++) { | 1632 for (uint32_t i = 0; i < (kPointerSize - align); i++) { |
1633 w->Write<uint8_t>(DW_CFA_NOP); | 1633 w->Write<uint8_t>(DW_CFA_NOP); |
1634 } | 1634 } |
1635 } | 1635 } |
1636 | 1636 |
1637 ASSERT((w->position() - initial_position) % kPointerSize == 0); | 1637 ASSERT((w->position() - initial_position) % kPointerSize == 0); |
1638 length_slot->set(w->position() - initial_position); | 1638 length_slot->set(w->position() - initial_position); |
1639 } | 1639 } |
1640 | 1640 |
1641 | 1641 |
1642 UnwindInfoSection::UnwindInfoSection(CodeDescription *desc) | 1642 UnwindInfoSection::UnwindInfoSection(CodeDescription* desc) |
1643 #ifdef __ELF | 1643 #ifdef __ELF |
1644 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), | 1644 : ELFSection(".eh_frame", TYPE_X86_64_UNWIND, 1), |
1645 #else | 1645 #else |
1646 : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t), | 1646 : MachOSection("__eh_frame", "__TEXT", sizeof(uintptr_t), |
1647 MachOSection::S_REGULAR), | 1647 MachOSection::S_REGULAR), |
1648 #endif | 1648 #endif |
1649 desc_(desc) { } | 1649 desc_(desc) { } |
1650 | 1650 |
1651 int UnwindInfoSection::WriteCIE(Writer *w) { | 1651 int UnwindInfoSection::WriteCIE(Writer* w) { |
1652 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); | 1652 Writer::Slot<uint32_t> cie_length_slot = w->CreateSlotHere<uint32_t>(); |
1653 uint32_t cie_position = w->position(); | 1653 uint32_t cie_position = w->position(); |
1654 | 1654 |
1655 // Write out the CIE header. Currently no 'common instructions' are | 1655 // Write out the CIE header. Currently no 'common instructions' are |
1656 // emitted onto the CIE; every FDE has its own set of instructions. | 1656 // emitted onto the CIE; every FDE has its own set of instructions. |
1657 | 1657 |
1658 w->Write<uint32_t>(CIE_ID); | 1658 w->Write<uint32_t>(CIE_ID); |
1659 w->Write<uint8_t>(CIE_VERSION); | 1659 w->Write<uint8_t>(CIE_VERSION); |
1660 w->Write<uint8_t>(0); // Null augmentation string. | 1660 w->Write<uint8_t>(0); // Null augmentation string. |
1661 w->WriteSLEB128(CODE_ALIGN_FACTOR); | 1661 w->WriteSLEB128(CODE_ALIGN_FACTOR); |
1662 w->WriteSLEB128(DATA_ALIGN_FACTOR); | 1662 w->WriteSLEB128(DATA_ALIGN_FACTOR); |
1663 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); | 1663 w->Write<uint8_t>(RETURN_ADDRESS_REGISTER); |
1664 | 1664 |
1665 WriteLength(w, &cie_length_slot, cie_position); | 1665 WriteLength(w, &cie_length_slot, cie_position); |
1666 | 1666 |
1667 return cie_position; | 1667 return cie_position; |
1668 } | 1668 } |
1669 | 1669 |
1670 | 1670 |
1671 void UnwindInfoSection::WriteFDE(Writer *w, int cie_position) { | 1671 void UnwindInfoSection::WriteFDE(Writer* w, int cie_position) { |
1672 // The only FDE for this function. The CFA is the current RBP. | 1672 // The only FDE for this function. The CFA is the current RBP. |
1673 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); | 1673 Writer::Slot<uint32_t> fde_length_slot = w->CreateSlotHere<uint32_t>(); |
1674 int fde_position = w->position(); | 1674 int fde_position = w->position(); |
1675 w->Write<int32_t>(fde_position - cie_position + 4); | 1675 w->Write<int32_t>(fde_position - cie_position + 4); |
1676 | 1676 |
1677 w->Write<uintptr_t>(desc_->CodeStart()); | 1677 w->Write<uintptr_t>(desc_->CodeStart()); |
1678 w->Write<uintptr_t>(desc_->CodeSize()); | 1678 w->Write<uintptr_t>(desc_->CodeSize()); |
1679 | 1679 |
1680 WriteFDEStateOnEntry(w); | 1680 WriteFDEStateOnEntry(w); |
1681 WriteFDEStateAfterRBPPush(w); | 1681 WriteFDEStateAfterRBPPush(w); |
1682 WriteFDEStateAfterRBPSet(w); | 1682 WriteFDEStateAfterRBPSet(w); |
1683 WriteFDEStateAfterRBPPop(w); | 1683 WriteFDEStateAfterRBPPop(w); |
1684 | 1684 |
1685 WriteLength(w, &fde_length_slot, fde_position); | 1685 WriteLength(w, &fde_length_slot, fde_position); |
1686 } | 1686 } |
1687 | 1687 |
1688 | 1688 |
1689 void UnwindInfoSection::WriteFDEStateOnEntry(Writer *w) { | 1689 void UnwindInfoSection::WriteFDEStateOnEntry(Writer* w) { |
1690 // The first state, just after the control has been transferred to the the | 1690 // The first state, just after the control has been transferred to the the |
1691 // function. | 1691 // function. |
1692 | 1692 |
1693 // RBP for this function will be the value of RSP after pushing the RBP | 1693 // RBP for this function will be the value of RSP after pushing the RBP |
1694 // for the previous function. The previous RBP has not been pushed yet. | 1694 // for the previous function. The previous RBP has not been pushed yet. |
1695 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); | 1695 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); |
1696 w->WriteULEB128(AMD64_RSP); | 1696 w->WriteULEB128(AMD64_RSP); |
1697 w->WriteSLEB128(-kPointerSize); | 1697 w->WriteSLEB128(-kPointerSize); |
1698 | 1698 |
1699 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, | 1699 // The RA is stored at location CFA + kCallerPCOffset. This is an invariant, |
1700 // and hence omitted from the next states. | 1700 // and hence omitted from the next states. |
1701 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); | 1701 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); |
1702 w->WriteULEB128(AMD64_RA); | 1702 w->WriteULEB128(AMD64_RA); |
1703 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); | 1703 w->WriteSLEB128(StandardFrameConstants::kCallerPCOffset); |
1704 | 1704 |
1705 // The RBP of the previous function is still in RBP. | 1705 // The RBP of the previous function is still in RBP. |
1706 w->Write<uint8_t>(DW_CFA_SAME_VALUE); | 1706 w->Write<uint8_t>(DW_CFA_SAME_VALUE); |
1707 w->WriteULEB128(AMD64_RBP); | 1707 w->WriteULEB128(AMD64_RBP); |
1708 | 1708 |
1709 // Last location described by this entry. | 1709 // Last location described by this entry. |
1710 w->Write<uint8_t>(DW_CFA_SET_LOC); | 1710 w->Write<uint8_t>(DW_CFA_SET_LOC); |
1711 w->Write<uint64_t>( | 1711 w->Write<uint64_t>( |
1712 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH)); | 1712 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_PUSH)); |
1713 } | 1713 } |
1714 | 1714 |
1715 | 1715 |
1716 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer *w) { | 1716 void UnwindInfoSection::WriteFDEStateAfterRBPPush(Writer* w) { |
1717 // The second state, just after RBP has been pushed. | 1717 // The second state, just after RBP has been pushed. |
1718 | 1718 |
1719 // RBP / CFA for this function is now the current RSP, so just set the | 1719 // RBP / CFA for this function is now the current RSP, so just set the |
1720 // offset from the previous rule (from -8) to 0. | 1720 // offset from the previous rule (from -8) to 0. |
1721 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); | 1721 w->Write<uint8_t>(DW_CFA_DEF_CFA_OFFSET); |
1722 w->WriteULEB128(0); | 1722 w->WriteULEB128(0); |
1723 | 1723 |
1724 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant | 1724 // The previous RBP is stored at CFA + kCallerFPOffset. This is an invariant |
1725 // in this and the next state, and hence omitted in the next state. | 1725 // in this and the next state, and hence omitted in the next state. |
1726 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); | 1726 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); |
1727 w->WriteULEB128(AMD64_RBP); | 1727 w->WriteULEB128(AMD64_RBP); |
1728 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); | 1728 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); |
1729 | 1729 |
1730 // Last location described by this entry. | 1730 // Last location described by this entry. |
1731 w->Write<uint8_t>(DW_CFA_SET_LOC); | 1731 w->Write<uint8_t>(DW_CFA_SET_LOC); |
1732 w->Write<uint64_t>( | 1732 w->Write<uint64_t>( |
1733 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET)); | 1733 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_SET)); |
1734 } | 1734 } |
1735 | 1735 |
1736 | 1736 |
1737 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer *w) { | 1737 void UnwindInfoSection::WriteFDEStateAfterRBPSet(Writer* w) { |
1738 // The third state, after the RBP has been set. | 1738 // The third state, after the RBP has been set. |
1739 | 1739 |
1740 // The CFA can now directly be set to RBP. | 1740 // The CFA can now directly be set to RBP. |
1741 w->Write<uint8_t>(DW_CFA_DEF_CFA); | 1741 w->Write<uint8_t>(DW_CFA_DEF_CFA); |
1742 w->WriteULEB128(AMD64_RBP); | 1742 w->WriteULEB128(AMD64_RBP); |
1743 w->WriteULEB128(0); | 1743 w->WriteULEB128(0); |
1744 | 1744 |
1745 // Last location described by this entry. | 1745 // Last location described by this entry. |
1746 w->Write<uint8_t>(DW_CFA_SET_LOC); | 1746 w->Write<uint8_t>(DW_CFA_SET_LOC); |
1747 w->Write<uint64_t>( | 1747 w->Write<uint64_t>( |
1748 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP)); | 1748 desc_->GetStackStateStartAddress(CodeDescription::POST_RBP_POP)); |
1749 } | 1749 } |
1750 | 1750 |
1751 | 1751 |
1752 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer *w) { | 1752 void UnwindInfoSection::WriteFDEStateAfterRBPPop(Writer* w) { |
1753 // The fourth (final) state. The RBP has been popped (just before issuing a | 1753 // The fourth (final) state. The RBP has been popped (just before issuing a |
1754 // return). | 1754 // return). |
1755 | 1755 |
1756 // The CFA can is now calculated in the same way as in the first state. | 1756 // The CFA can is now calculated in the same way as in the first state. |
1757 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); | 1757 w->Write<uint8_t>(DW_CFA_DEF_CFA_SF); |
1758 w->WriteULEB128(AMD64_RSP); | 1758 w->WriteULEB128(AMD64_RSP); |
1759 w->WriteSLEB128(-kPointerSize); | 1759 w->WriteSLEB128(-kPointerSize); |
1760 | 1760 |
1761 // The RBP | 1761 // The RBP |
1762 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); | 1762 w->Write<uint8_t>(DW_CFA_OFFSET_EXTENDED); |
1763 w->WriteULEB128(AMD64_RBP); | 1763 w->WriteULEB128(AMD64_RBP); |
1764 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); | 1764 w->WriteSLEB128(StandardFrameConstants::kCallerFPOffset); |
1765 | 1765 |
1766 // Last location described by this entry. | 1766 // Last location described by this entry. |
1767 w->Write<uint8_t>(DW_CFA_SET_LOC); | 1767 w->Write<uint8_t>(DW_CFA_SET_LOC); |
1768 w->Write<uint64_t>(desc_->CodeEnd()); | 1768 w->Write<uint64_t>(desc_->CodeEnd()); |
1769 } | 1769 } |
1770 | 1770 |
1771 | 1771 |
1772 bool UnwindInfoSection::WriteBody(Writer *w) { | 1772 bool UnwindInfoSection::WriteBody(Writer* w) { |
1773 uint32_t cie_position = WriteCIE(w); | 1773 uint32_t cie_position = WriteCIE(w); |
1774 WriteFDE(w, cie_position); | 1774 WriteFDE(w, cie_position); |
1775 return true; | 1775 return true; |
1776 } | 1776 } |
1777 | 1777 |
1778 | 1778 |
1779 #endif // V8_TARGET_ARCH_X64 | 1779 #endif // V8_TARGET_ARCH_X64 |
1780 | 1780 |
1781 static void CreateDWARFSections(CodeDescription* desc, DebugObject* obj) { | 1781 static void CreateDWARFSections(CodeDescription* desc, DebugObject* obj) { |
1782 if (desc->IsLineInfoAvailable()) { | 1782 if (desc->IsLineInfoAvailable()) { |
(...skipping 20 matching lines...) Expand all Loading... |
1803 struct JITCodeEntry { | 1803 struct JITCodeEntry { |
1804 JITCodeEntry* next_; | 1804 JITCodeEntry* next_; |
1805 JITCodeEntry* prev_; | 1805 JITCodeEntry* prev_; |
1806 Address symfile_addr_; | 1806 Address symfile_addr_; |
1807 uint64_t symfile_size_; | 1807 uint64_t symfile_size_; |
1808 }; | 1808 }; |
1809 | 1809 |
1810 struct JITDescriptor { | 1810 struct JITDescriptor { |
1811 uint32_t version_; | 1811 uint32_t version_; |
1812 uint32_t action_flag_; | 1812 uint32_t action_flag_; |
1813 JITCodeEntry *relevant_entry_; | 1813 JITCodeEntry* relevant_entry_; |
1814 JITCodeEntry *first_entry_; | 1814 JITCodeEntry* first_entry_; |
1815 }; | 1815 }; |
1816 | 1816 |
1817 // GDB will place breakpoint into this function. | 1817 // GDB will place breakpoint into this function. |
1818 // To prevent GCC from inlining or removing it we place noinline attribute | 1818 // To prevent GCC from inlining or removing it we place noinline attribute |
1819 // and inline assembler statement inside. | 1819 // and inline assembler statement inside. |
1820 void __attribute__((noinline)) __jit_debug_register_code() { | 1820 void __attribute__((noinline)) __jit_debug_register_code() { |
1821 __asm__(""); | 1821 __asm__(""); |
1822 } | 1822 } |
1823 | 1823 |
1824 // GDB will inspect contents of this descriptor. | 1824 // GDB will inspect contents of this descriptor. |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1991 GetScriptLineNumber(script, 0); | 1991 GetScriptLineNumber(script, 0); |
1992 | 1992 |
1993 if (!name.is_null()) { | 1993 if (!name.is_null()) { |
1994 SmartArrayPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); | 1994 SmartArrayPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); |
1995 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); | 1995 AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); |
1996 } else { | 1996 } else { |
1997 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); | 1997 AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); |
1998 } | 1998 } |
1999 } | 1999 } |
2000 | 2000 |
2001 static void AddUnwindInfo(CodeDescription *desc) { | 2001 static void AddUnwindInfo(CodeDescription* desc) { |
2002 #ifdef V8_TARGET_ARCH_X64 | 2002 #ifdef V8_TARGET_ARCH_X64 |
2003 if (desc->tag() == GDBJITInterface::FUNCTION) { | 2003 if (desc->tag() == GDBJITInterface::FUNCTION) { |
2004 // To avoid propagating unwinding information through | 2004 // To avoid propagating unwinding information through |
2005 // compilation pipeline we use an approximation. | 2005 // compilation pipeline we use an approximation. |
2006 // For most use cases this should not affect usability. | 2006 // For most use cases this should not affect usability. |
2007 static const int kFramePointerPushOffset = 1; | 2007 static const int kFramePointerPushOffset = 1; |
2008 static const int kFramePointerSetOffset = 4; | 2008 static const int kFramePointerSetOffset = 4; |
2009 static const int kFramePointerPopOffset = -3; | 2009 static const int kFramePointerPopOffset = -3; |
2010 | 2010 |
2011 uintptr_t frame_pointer_push_address = | 2011 uintptr_t frame_pointer_push_address = |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2149 ScopedLock lock(mutex_); | 2149 ScopedLock lock(mutex_); |
2150 ASSERT(!IsLineInfoTagged(line_info)); | 2150 ASSERT(!IsLineInfoTagged(line_info)); |
2151 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); | 2151 HashMap::Entry* e = GetEntries()->Lookup(code, HashForCodeObject(code), true); |
2152 ASSERT(e->value == NULL); | 2152 ASSERT(e->value == NULL); |
2153 e->value = TagLineInfo(line_info); | 2153 e->value = TagLineInfo(line_info); |
2154 } | 2154 } |
2155 | 2155 |
2156 | 2156 |
2157 } } // namespace v8::internal | 2157 } } // namespace v8::internal |
2158 #endif | 2158 #endif |
OLD | NEW |