mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-12-23 00:55:41 +00:00
Enable reading DWARF4 CIEs with 32 bit addresses.
- Reading DWARF4 CIEs was added in https://chromium-review.googlesource.com/c/breakpad/breakpad/+/406012 but it was only enabled for 64bit builds, since it would error out if the CIE address size was not 8 bytes. - Added a unit test to ensure that 32bit continues to work. Change-Id: I824bb40cdf12056d39da335adb55ed315970fb88 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1941034 Reviewed-by: Ivan Penkov <ivanpe@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
5bc3092b30
commit
f32b83eb08
|
@ -2330,21 +2330,15 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
|
|||
}
|
||||
|
||||
if (cie->version >= 4) {
|
||||
uint8_t address_size = *cursor++;
|
||||
if (address_size != 8) {
|
||||
// TODO(scottmg): Only supporting x64 for now.
|
||||
reporter_->UnexpectedAddressSize(cie->offset, address_size);
|
||||
cie->address_size = *cursor++;
|
||||
if (cie->address_size != 8 && cie->address_size != 4) {
|
||||
reporter_->UnexpectedAddressSize(cie->offset, cie->address_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t segment_size = *cursor++;
|
||||
if (segment_size != 0) {
|
||||
// TODO(scottmg): Only supporting x64 for now.
|
||||
// I would have perhaps expected 4 here, but LLVM emits a 0, near
|
||||
// http://llvm.org/docs/doxygen/html/MCDwarf_8cpp_source.html#l00606. As
|
||||
// we are not using the value, only succeed for now if it's the expected
|
||||
// 0.
|
||||
reporter_->UnexpectedSegmentSize(cie->offset, segment_size);
|
||||
cie->segment_size = *cursor++;
|
||||
if (cie->segment_size != 0) {
|
||||
reporter_->UnexpectedSegmentSize(cie->offset, cie->segment_size);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2606,6 +2600,15 @@ bool CallFrameInfo::Start() {
|
|||
if (!ReadCIEFields(&cie))
|
||||
continue;
|
||||
|
||||
// TODO(nbilling): This could lead to strange behavior if a single buffer
|
||||
// contained a mixture of DWARF versions as well as address sizes. Not
|
||||
// sure if it's worth handling such a case.
|
||||
|
||||
// DWARF4 CIE specifies address_size, so use it for this call frame.
|
||||
if (cie.version >= 4) {
|
||||
reader_->SetAddressSize(cie.address_size);
|
||||
}
|
||||
|
||||
// We now have the values that govern both the CIE and the FDE.
|
||||
cie.cie = &cie;
|
||||
fde.cie = &cie;
|
||||
|
|
|
@ -999,6 +999,11 @@ class CallFrameInfo {
|
|||
// or not we saw a 'z' augmentation string; its default value is
|
||||
// DW_EH_PE_absptr, which is what normal DWARF CFI uses.
|
||||
DwarfPointerEncoding pointer_encoding;
|
||||
|
||||
// These were only introduced in DWARF4, so will not be set in older
|
||||
// versions.
|
||||
uint8 address_size;
|
||||
uint8 segment_size;
|
||||
};
|
||||
|
||||
// A frame description entry (FDE).
|
||||
|
|
|
@ -608,11 +608,11 @@ TEST_F(CFI, CIEVersion3ReturnColumn) {
|
|||
}
|
||||
|
||||
TEST_F(CFI, CIEVersion4AdditionalFields) {
|
||||
CFISection section(kBigEndian, 4);
|
||||
CFISection section(kBigEndian, 8);
|
||||
Label cie;
|
||||
section
|
||||
.Mark(&cie)
|
||||
// CIE version 4 with expected address and segment size.
|
||||
// CIE version 4 with expected address (64bit) and segment size.
|
||||
.CIEHeader(0x0ab4758d, 0xc010fdf7, 0x89, 4, "", true, 8, 0)
|
||||
.FinishEntry()
|
||||
// FDE, citing that CIE.
|
||||
|
@ -631,7 +631,36 @@ TEST_F(CFI, CIEVersion4AdditionalFields) {
|
|||
string contents;
|
||||
EXPECT_TRUE(section.GetContents(&contents));
|
||||
ByteReader byte_reader(ENDIANNESS_BIG);
|
||||
byte_reader.SetAddressSize(4);
|
||||
CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
|
||||
contents.size(),
|
||||
&byte_reader, &handler, &reporter);
|
||||
EXPECT_TRUE(parser.Start());
|
||||
}
|
||||
|
||||
TEST_F(CFI, CIEVersion4AdditionalFields32BitAddress) {
|
||||
CFISection section(kBigEndian, 4);
|
||||
Label cie;
|
||||
section
|
||||
.Mark(&cie)
|
||||
// CIE version 4 with expected address (32bit) and segment size.
|
||||
.CIEHeader(0x0ab4758d, 0xc010fdf7, 0x89, 4, "", true, 4, 0)
|
||||
.FinishEntry()
|
||||
// FDE, citing that CIE.
|
||||
.FDEHeader(cie, 0x86763f2b, 0x2a66dc23)
|
||||
.FinishEntry();
|
||||
|
||||
PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion3ReturnColumn", section);
|
||||
|
||||
{
|
||||
InSequence s;
|
||||
EXPECT_CALL(handler, Entry(_, 0x86763f2b, 0x2a66dc23, 4, "", 0x89))
|
||||
.WillOnce(Return(true));
|
||||
EXPECT_CALL(handler, End()).WillOnce(Return(true));
|
||||
}
|
||||
|
||||
string contents;
|
||||
EXPECT_TRUE(section.GetContents(&contents));
|
||||
ByteReader byte_reader(ENDIANNESS_BIG);
|
||||
CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
|
||||
contents.size(),
|
||||
&byte_reader, &handler, &reporter);
|
||||
|
@ -659,7 +688,6 @@ TEST_F(CFI, CIEVersion4AdditionalFieldsUnexpectedAddressSize) {
|
|||
string contents;
|
||||
EXPECT_TRUE(section.GetContents(&contents));
|
||||
ByteReader byte_reader(ENDIANNESS_BIG);
|
||||
byte_reader.SetAddressSize(8);
|
||||
CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
|
||||
contents.size(),
|
||||
&byte_reader, &handler, &reporter);
|
||||
|
@ -667,7 +695,7 @@ TEST_F(CFI, CIEVersion4AdditionalFieldsUnexpectedAddressSize) {
|
|||
}
|
||||
|
||||
TEST_F(CFI, CIEVersion4AdditionalFieldsUnexpectedSegmentSize) {
|
||||
CFISection section(kBigEndian, 4);
|
||||
CFISection section(kBigEndian, 8);
|
||||
Label cie;
|
||||
|
||||
section
|
||||
|
@ -685,7 +713,6 @@ TEST_F(CFI, CIEVersion4AdditionalFieldsUnexpectedSegmentSize) {
|
|||
string contents;
|
||||
EXPECT_TRUE(section.GetContents(&contents));
|
||||
ByteReader byte_reader(ENDIANNESS_BIG);
|
||||
byte_reader.SetAddressSize(8);
|
||||
CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
|
||||
contents.size(),
|
||||
&byte_reader, &handler, &reporter);
|
||||
|
|
Loading…
Reference in a new issue