From 2d12117cfb1f7bccb53af00e1133a5795b5f7d23 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Sun, 7 Apr 2024 09:09:54 +0000 Subject: [PATCH] fix cursor crash --- 3party/libelfin/dwarf/cursor.cc | 285 ++++++++++++++++---------------- 1 file changed, 140 insertions(+), 145 deletions(-) diff --git a/3party/libelfin/dwarf/cursor.cc b/3party/libelfin/dwarf/cursor.cc index 22b28b1..e06c084 100644 --- a/3party/libelfin/dwarf/cursor.cc +++ b/3party/libelfin/dwarf/cursor.cc @@ -4,8 +4,8 @@ #include "internal.hh" -#include #include +#include using namespace std; @@ -14,57 +14,56 @@ DWARFPP_BEGIN_NAMESPACE int64_t cursor::sleb128() { - // Appendix C - uint64_t result = 0; - unsigned shift = 0; - while (pos < sec->end) { - uint8_t byte = *(uint8_t*)(pos++); - result |= (uint64_t)(byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) { - if (shift < sizeof(result)*8 && (byte & 0x40)) - result |= -((uint64_t)1 << shift); - return result; - } + // Appendix C + uint64_t result = 0; + unsigned shift = 0; + while (pos < sec->end) { + uint8_t byte = *(uint8_t *) (pos++); + result |= (uint64_t) (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) { + if (shift < sizeof(result) * 8 && (byte & 0x40)) result |= -((uint64_t) 1 << shift); + return result; } - underflow(); - return 0; + } + underflow(); + return 0; } shared_ptr
cursor::subsection() { - // Section 7.4 - const char *begin = pos; - section_length length = fixed(); - format fmt; - if (length < 0xfffffff0) { - fmt = format::dwarf32; - length += sizeof(uword); - } else if (length == 0xffffffff) { - length = fixed(); - fmt = format::dwarf64; - length += sizeof(uword) + sizeof(uint64_t); - } else { - throw format_error("initial length has reserved value"); - } - pos = begin + length; - return make_shared
(sec->type, begin, length, sec->ord, fmt); + // Section 7.4 + const char *begin = pos; + section_length length = fixed(); + format fmt; + if (length < 0xfffffff0) { + fmt = format::dwarf32; + length += sizeof(uword); + } else if (length == 0xffffffff) { + length = fixed(); + fmt = format::dwarf64; + length += sizeof(uword) + sizeof(uint64_t); + } else { + throw format_error("initial length has reserved value"); + } + pos = begin + length; + return make_shared
(sec->type, begin, length, sec->ord, fmt); } void cursor::skip_initial_length() { - switch (sec->fmt) { - case format::dwarf32: - pos += sizeof(uword); - break; - case format::dwarf64: - pos += sizeof(uword) + sizeof(uint64_t); - break; - default: - throw logic_error("cannot skip initial length with unknown format"); - } + switch (sec->fmt) { + case format::dwarf32: + pos += sizeof(uword); + break; + case format::dwarf64: + pos += sizeof(uword) + sizeof(uint64_t); + break; + default: + throw logic_error("cannot skip initial length with unknown format"); + } } void @@ -76,132 +75,128 @@ cursor::skip_unit_type() section_offset cursor::offset() { - switch (sec->fmt) { - case format::dwarf32: - return fixed(); - case format::dwarf64: - return fixed(); - default: - throw logic_error("cannot read offset with unknown format"); - } + switch (sec->fmt) { + case format::dwarf32: + return fixed(); + case format::dwarf64: + return fixed(); + default: + throw logic_error("cannot read offset with unknown format"); + } } void cursor::string(std::string &out) { - size_t size; - const char *p = this->cstr(&size); - out.resize(size); - memmove(&out.front(), p, size); + size_t size; + const char *p = this->cstr(&size); + // out.resize(size); + // memmove(&out.front(), p, size); + out = std::string(p, p + size); } const char * cursor::cstr(size_t *size_out) { - // Scan string size - const char *p = pos; - while (pos < sec->end && *pos) - pos++; - if (pos == sec->end) - throw format_error("unterminated string"); - if (size_out) - *size_out = pos - p; - pos++; - return p; + // Scan string size + const char *p = pos; + while (pos < sec->end && *pos) pos++; + if (pos == sec->end) throw format_error("unterminated string"); + if (size_out) *size_out = pos - p; + pos++; + return p; } void cursor::skip_form(DW_FORM form) { - section_offset tmp; + section_offset tmp; - // Section 7.5.4 - switch (form) { - case DW_FORM::addr: - pos += sec->addr_size; - break; - case DW_FORM::sec_offset: - case DW_FORM::ref_addr: - case DW_FORM::strp: - switch (sec->fmt) { - case format::dwarf32: - pos += 4; - break; - case format::dwarf64: - pos += 8; - break; - case format::unknown: - throw logic_error("cannot read form with unknown format"); - } - break; - - // size+data forms - case DW_FORM::block1: - tmp = fixed(); - pos += tmp; - break; - case DW_FORM::block2: - tmp = fixed(); - pos += tmp; - break; - case DW_FORM::block4: - tmp = fixed(); - pos += tmp; - break; - case DW_FORM::block: - case DW_FORM::exprloc: - tmp = uleb128(); - pos += tmp; - break; - - // fixed-length forms - case DW_FORM::flag_present: - break; - case DW_FORM::flag: - case DW_FORM::data1: - case DW_FORM::ref1: - pos += 1; - break; - case DW_FORM::data2: - case DW_FORM::ref2: - pos += 2; - break; - case DW_FORM::data4: - case DW_FORM::ref4: - pos += 4; - break; - case DW_FORM::data8: - case DW_FORM::ref_sig8: - pos += 8; - break; - - // variable-length forms - case DW_FORM::sdata: - case DW_FORM::udata: - case DW_FORM::ref_udata: - while (pos < sec->end && (*(uint8_t*)pos & 0x80)) - pos++; - pos++; - break; - case DW_FORM::string: - while (pos < sec->end && *pos) - pos++; - pos++; - break; - - case DW_FORM::indirect: - skip_form((DW_FORM)uleb128()); - break; - - default: - throw format_error("unknown form " + to_string(form)); + // Section 7.5.4 + switch (form) { + case DW_FORM::addr: + pos += sec->addr_size; + break; + case DW_FORM::sec_offset: + case DW_FORM::ref_addr: + case DW_FORM::strp: + switch (sec->fmt) { + case format::dwarf32: + pos += 4; + break; + case format::dwarf64: + pos += 8; + break; + case format::unknown: + throw logic_error("cannot read form with unknown format"); } + break; + + // size+data forms + case DW_FORM::block1: + tmp = fixed(); + pos += tmp; + break; + case DW_FORM::block2: + tmp = fixed(); + pos += tmp; + break; + case DW_FORM::block4: + tmp = fixed(); + pos += tmp; + break; + case DW_FORM::block: + case DW_FORM::exprloc: + tmp = uleb128(); + pos += tmp; + break; + + // fixed-length forms + case DW_FORM::flag_present: + break; + case DW_FORM::flag: + case DW_FORM::data1: + case DW_FORM::ref1: + pos += 1; + break; + case DW_FORM::data2: + case DW_FORM::ref2: + pos += 2; + break; + case DW_FORM::data4: + case DW_FORM::ref4: + pos += 4; + break; + case DW_FORM::data8: + case DW_FORM::ref_sig8: + pos += 8; + break; + + // variable-length forms + case DW_FORM::sdata: + case DW_FORM::udata: + case DW_FORM::ref_udata: + while (pos < sec->end && (*(uint8_t *) pos & 0x80)) pos++; + pos++; + break; + case DW_FORM::string: + while (pos < sec->end && *pos) pos++; + pos++; + break; + + case DW_FORM::indirect: + skip_form((DW_FORM) uleb128()); + break; + + default: + throw format_error("unknown form " + to_string(form)); + } } void cursor::underflow() { - throw underflow_error("cannot read past end of DWARF section"); + throw underflow_error("cannot read past end of DWARF section"); } DWARFPP_END_NAMESPACE