convert to uint8_t* for binary data to fix -Wnarrowing build errors

Newer gcc versions default to -Werror=narrowing when using newer C++
standards (which we do).  This causes issues when we try to stuff a
value like 0xea into a char -- the value is out of range for signed
char bytes.  That's when gcc throws an error:
.../bytereader_unittest.cc: In member function 'virtual void Reader_DW_EH_PE_absptr4_Test::TestBody()':
.../bytereader_unittest.cc:400:55: error: narrowing conversion of '234' from 'int' to 'char' inside { } [-Wnarrowing]

BUG=chromium:579384
TEST=`make check` passes
R=mark@chromium.org

Review URL: https://codereview.chromium.org/1605153004 .
This commit is contained in:
Mike Frysinger 2016-01-26 15:38:19 -05:00
parent b16c640e09
commit bc44efdc27
16 changed files with 219 additions and 173 deletions

View file

@ -32,16 +32,15 @@
#include "common/dwarf/bytereader.h" #include "common/dwarf/bytereader.h"
#include <assert.h> #include <assert.h>
#include <stdint.h>
namespace dwarf2reader { namespace dwarf2reader {
inline uint8 ByteReader::ReadOneByte(const char* buffer) const { inline uint8 ByteReader::ReadOneByte(const uint8_t *buffer) const {
return buffer[0]; return buffer[0];
} }
inline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const { inline uint16 ByteReader::ReadTwoBytes(const uint8_t *buffer) const {
const unsigned char *buffer
= reinterpret_cast<const unsigned char *>(signed_buffer);
const uint16 buffer0 = buffer[0]; const uint16 buffer0 = buffer[0];
const uint16 buffer1 = buffer[1]; const uint16 buffer1 = buffer[1];
if (endian_ == ENDIANNESS_LITTLE) { if (endian_ == ENDIANNESS_LITTLE) {
@ -51,9 +50,7 @@ inline uint16 ByteReader::ReadTwoBytes(const char* signed_buffer) const {
} }
} }
inline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const { inline uint64 ByteReader::ReadFourBytes(const uint8_t *buffer) const {
const unsigned char *buffer
= reinterpret_cast<const unsigned char *>(signed_buffer);
const uint32 buffer0 = buffer[0]; const uint32 buffer0 = buffer[0];
const uint32 buffer1 = buffer[1]; const uint32 buffer1 = buffer[1];
const uint32 buffer2 = buffer[2]; const uint32 buffer2 = buffer[2];
@ -65,9 +62,7 @@ inline uint64 ByteReader::ReadFourBytes(const char* signed_buffer) const {
} }
} }
inline uint64 ByteReader::ReadEightBytes(const char* signed_buffer) const { inline uint64 ByteReader::ReadEightBytes(const uint8_t *buffer) const {
const unsigned char *buffer
= reinterpret_cast<const unsigned char *>(signed_buffer);
const uint64 buffer0 = buffer[0]; const uint64 buffer0 = buffer[0];
const uint64 buffer1 = buffer[1]; const uint64 buffer1 = buffer[1];
const uint64 buffer2 = buffer[2]; const uint64 buffer2 = buffer[2];
@ -89,12 +84,12 @@ inline uint64 ByteReader::ReadEightBytes(const char* signed_buffer) const {
// information, plus one bit saying whether the number continues or // information, plus one bit saying whether the number continues or
// not. // not.
inline uint64 ByteReader::ReadUnsignedLEB128(const char* buffer, inline uint64 ByteReader::ReadUnsignedLEB128(const uint8_t *buffer,
size_t* len) const { size_t* len) const {
uint64 result = 0; uint64 result = 0;
size_t num_read = 0; size_t num_read = 0;
unsigned int shift = 0; unsigned int shift = 0;
unsigned char byte; uint8_t byte;
do { do {
byte = *buffer++; byte = *buffer++;
@ -114,12 +109,12 @@ inline uint64 ByteReader::ReadUnsignedLEB128(const char* buffer,
// Read a signed LEB128 number. These are like regular LEB128 // Read a signed LEB128 number. These are like regular LEB128
// numbers, except the last byte may have a sign bit set. // numbers, except the last byte may have a sign bit set.
inline int64 ByteReader::ReadSignedLEB128(const char* buffer, inline int64 ByteReader::ReadSignedLEB128(const uint8_t *buffer,
size_t* len) const { size_t* len) const {
int64 result = 0; int64 result = 0;
unsigned int shift = 0; unsigned int shift = 0;
size_t num_read = 0; size_t num_read = 0;
unsigned char byte; uint8_t byte;
do { do {
byte = *buffer++; byte = *buffer++;
@ -134,18 +129,18 @@ inline int64 ByteReader::ReadSignedLEB128(const char* buffer,
return result; return result;
} }
inline uint64 ByteReader::ReadOffset(const char* buffer) const { inline uint64 ByteReader::ReadOffset(const uint8_t *buffer) const {
assert(this->offset_reader_); assert(this->offset_reader_);
return (this->*offset_reader_)(buffer); return (this->*offset_reader_)(buffer);
} }
inline uint64 ByteReader::ReadAddress(const char* buffer) const { inline uint64 ByteReader::ReadAddress(const uint8_t *buffer) const {
assert(this->address_reader_); assert(this->address_reader_);
return (this->*address_reader_)(buffer); return (this->*address_reader_)(buffer);
} }
inline void ByteReader::SetCFIDataBase(uint64 section_base, inline void ByteReader::SetCFIDataBase(uint64 section_base,
const char *buffer_base) { const uint8_t *buffer_base) {
section_base_ = section_base; section_base_ = section_base;
buffer_base_ = buffer_base; buffer_base_ = buffer_base;
have_section_base_ = true; have_section_base_ = true;

View file

@ -27,6 +27,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h> #include <assert.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "common/dwarf/bytereader-inl.h" #include "common/dwarf/bytereader-inl.h"
@ -62,7 +63,7 @@ void ByteReader::SetAddressSize(uint8 size) {
} }
} }
uint64 ByteReader::ReadInitialLength(const char* start, size_t* len) { uint64 ByteReader::ReadInitialLength(const uint8_t *start, size_t* len) {
const uint64 initial_length = ReadFourBytes(start); const uint64 initial_length = ReadFourBytes(start);
start += 4; start += 4;
@ -100,7 +101,7 @@ bool ByteReader::UsableEncoding(DwarfPointerEncoding encoding) const {
} }
} }
uint64 ByteReader::ReadEncodedPointer(const char *buffer, uint64 ByteReader::ReadEncodedPointer(const uint8_t *buffer,
DwarfPointerEncoding encoding, DwarfPointerEncoding encoding,
size_t *len) const { size_t *len) const {
// UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't // UsableEncoding doesn't approve of DW_EH_PE_omit, so we shouldn't
@ -129,7 +130,7 @@ uint64 ByteReader::ReadEncodedPointer(const char *buffer,
// Round up to the next boundary. // Round up to the next boundary.
uint64 aligned = (offset + AddressSize() - 1) & -AddressSize(); uint64 aligned = (offset + AddressSize() - 1) & -AddressSize();
// Convert back to a pointer. // Convert back to a pointer.
const char *aligned_buffer = buffer_base_ + (aligned - skew); const uint8_t *aligned_buffer = buffer_base_ + (aligned - skew);
// Finally, store the length and actually fetch the pointer. // Finally, store the length and actually fetch the pointer.
*len = aligned_buffer - buffer + AddressSize(); *len = aligned_buffer - buffer + AddressSize();
return ReadAddress(aligned_buffer); return ReadAddress(aligned_buffer);

View file

@ -31,7 +31,10 @@
#ifndef COMMON_DWARF_BYTEREADER_H__ #ifndef COMMON_DWARF_BYTEREADER_H__
#define COMMON_DWARF_BYTEREADER_H__ #define COMMON_DWARF_BYTEREADER_H__
#include <stdint.h>
#include <string> #include <string>
#include "common/dwarf/types.h" #include "common/dwarf/types.h"
#include "common/dwarf/dwarf2enums.h" #include "common/dwarf/dwarf2enums.h"
@ -59,22 +62,22 @@ class ByteReader {
// Read a single byte from BUFFER and return it as an unsigned 8 bit // Read a single byte from BUFFER and return it as an unsigned 8 bit
// number. // number.
uint8 ReadOneByte(const char* buffer) const; uint8 ReadOneByte(const uint8_t *buffer) const;
// Read two bytes from BUFFER and return them as an unsigned 16 bit // Read two bytes from BUFFER and return them as an unsigned 16 bit
// number, using this ByteReader's endianness. // number, using this ByteReader's endianness.
uint16 ReadTwoBytes(const char* buffer) const; uint16 ReadTwoBytes(const uint8_t *buffer) const;
// Read four bytes from BUFFER and return them as an unsigned 32 bit // Read four bytes from BUFFER and return them as an unsigned 32 bit
// number, using this ByteReader's endianness. This function returns // number, using this ByteReader's endianness. This function returns
// a uint64 so that it is compatible with ReadAddress and // a uint64 so that it is compatible with ReadAddress and
// ReadOffset. The number it returns will never be outside the range // ReadOffset. The number it returns will never be outside the range
// of an unsigned 32 bit integer. // of an unsigned 32 bit integer.
uint64 ReadFourBytes(const char* buffer) const; uint64 ReadFourBytes(const uint8_t *buffer) const;
// Read eight bytes from BUFFER and return them as an unsigned 64 // Read eight bytes from BUFFER and return them as an unsigned 64
// bit number, using this ByteReader's endianness. // bit number, using this ByteReader's endianness.
uint64 ReadEightBytes(const char* buffer) const; uint64 ReadEightBytes(const uint8_t *buffer) const;
// Read an unsigned LEB128 (Little Endian Base 128) number from // Read an unsigned LEB128 (Little Endian Base 128) number from
// BUFFER and return it as an unsigned 64 bit integer. Set LEN to // BUFFER and return it as an unsigned 64 bit integer. Set LEN to
@ -93,7 +96,7 @@ class ByteReader {
// In other words, we break VALUE into groups of seven bits, put // In other words, we break VALUE into groups of seven bits, put
// them in little-endian order, and then write them as eight-bit // them in little-endian order, and then write them as eight-bit
// bytes with the high bit on all but the last. // bytes with the high bit on all but the last.
uint64 ReadUnsignedLEB128(const char* buffer, size_t* len) const; uint64 ReadUnsignedLEB128(const uint8_t *buffer, size_t *len) const;
// Read a signed LEB128 number from BUFFER and return it as an // Read a signed LEB128 number from BUFFER and return it as an
// signed 64 bit integer. Set LEN to the number of bytes read. // signed 64 bit integer. Set LEN to the number of bytes read.
@ -112,7 +115,7 @@ class ByteReader {
// In other words, we break VALUE into groups of seven bits, put // In other words, we break VALUE into groups of seven bits, put
// them in little-endian order, and then write them as eight-bit // them in little-endian order, and then write them as eight-bit
// bytes with the high bit on all but the last. // bytes with the high bit on all but the last.
int64 ReadSignedLEB128(const char* buffer, size_t* len) const; int64 ReadSignedLEB128(const uint8_t *buffer, size_t *len) const;
// Indicate that addresses on this architecture are SIZE bytes long. SIZE // Indicate that addresses on this architecture are SIZE bytes long. SIZE
// must be either 4 or 8. (DWARF allows addresses to be any number of // must be either 4 or 8. (DWARF allows addresses to be any number of
@ -135,7 +138,7 @@ class ByteReader {
// Read an address from BUFFER and return it as an unsigned 64 bit // Read an address from BUFFER and return it as an unsigned 64 bit
// integer, respecting this ByteReader's endianness and address size. You // integer, respecting this ByteReader's endianness and address size. You
// must call SetAddressSize before calling this function. // must call SetAddressSize before calling this function.
uint64 ReadAddress(const char* buffer) const; uint64 ReadAddress(const uint8_t *buffer) const;
// DWARF actually defines two slightly different formats: 32-bit DWARF // DWARF actually defines two slightly different formats: 32-bit DWARF
// and 64-bit DWARF. This is *not* related to the size of registers or // and 64-bit DWARF. This is *not* related to the size of registers or
@ -172,14 +175,14 @@ class ByteReader {
// - The 32-bit value 0xffffffff, followed by a 64-bit byte count, // - The 32-bit value 0xffffffff, followed by a 64-bit byte count,
// indicating that the data whose length is being measured uses // indicating that the data whose length is being measured uses
// the 64-bit DWARF format. // the 64-bit DWARF format.
uint64 ReadInitialLength(const char* start, size_t* len); uint64 ReadInitialLength(const uint8_t *start, size_t *len);
// Read an offset from BUFFER and return it as an unsigned 64 bit // Read an offset from BUFFER and return it as an unsigned 64 bit
// integer, respecting the ByteReader's endianness. In 32-bit DWARF, the // integer, respecting the ByteReader's endianness. In 32-bit DWARF, the
// offset is 4 bytes long; in 64-bit DWARF, the offset is eight bytes // offset is 4 bytes long; in 64-bit DWARF, the offset is eight bytes
// long. You must call ReadInitialLength or SetOffsetSize before calling // long. You must call ReadInitialLength or SetOffsetSize before calling
// this function; see the comments above for details. // this function; see the comments above for details.
uint64 ReadOffset(const char* buffer) const; uint64 ReadOffset(const uint8_t *buffer) const;
// Return the current offset size, in bytes. // Return the current offset size, in bytes.
// A return value of 4 indicates that we are reading 32-bit DWARF. // A return value of 4 indicates that we are reading 32-bit DWARF.
@ -234,7 +237,7 @@ class ByteReader {
// is BUFFER_BASE. This allows us to find the address that a given // is BUFFER_BASE. This allows us to find the address that a given
// byte in our buffer would have when loaded into the program the // byte in our buffer would have when loaded into the program the
// data describes. We need this to resolve DW_EH_PE_pcrel pointers. // data describes. We need this to resolve DW_EH_PE_pcrel pointers.
void SetCFIDataBase(uint64 section_base, const char *buffer_base); void SetCFIDataBase(uint64 section_base, const uint8_t *buffer_base);
// Indicate that the base address of the program's ".text" section // Indicate that the base address of the program's ".text" section
// is TEXT_BASE. We need this to resolve DW_EH_PE_textrel pointers. // is TEXT_BASE. We need this to resolve DW_EH_PE_textrel pointers.
@ -273,13 +276,14 @@ class ByteReader {
// base address this reader hasn't been given, so you should check // base address this reader hasn't been given, so you should check
// with ValidEncoding and UsableEncoding first if you would rather // with ValidEncoding and UsableEncoding first if you would rather
// die in a more helpful way. // die in a more helpful way.
uint64 ReadEncodedPointer(const char *buffer, DwarfPointerEncoding encoding, uint64 ReadEncodedPointer(const uint8_t *buffer,
DwarfPointerEncoding encoding,
size_t *len) const; size_t *len) const;
private: private:
// Function pointer type for our address and offset readers. // Function pointer type for our address and offset readers.
typedef uint64 (ByteReader::*AddressReader)(const char*) const; typedef uint64 (ByteReader::*AddressReader)(const uint8_t *) const;
// Read an offset from BUFFER and return it as an unsigned 64 bit // Read an offset from BUFFER and return it as an unsigned 64 bit
// integer. DWARF2/3 define offsets as either 4 or 8 bytes, // integer. DWARF2/3 define offsets as either 4 or 8 bytes,
@ -302,7 +306,7 @@ class ByteReader {
bool have_section_base_, have_text_base_, have_data_base_; bool have_section_base_, have_text_base_, have_data_base_;
bool have_function_base_; bool have_function_base_;
uint64 section_base_, text_base_, data_base_, function_base_; uint64 section_base_, text_base_, data_base_, function_base_;
const char *buffer_base_; const uint8_t *buffer_base_;
}; };
} // namespace dwarf2reader } // namespace dwarf2reader

View file

@ -31,6 +31,8 @@
// bytereader_unittest.cc: Unit tests for dwarf2reader::ByteReader // bytereader_unittest.cc: Unit tests for dwarf2reader::ByteReader
#include <stdint.h>
#include <string> #include <string>
#include "breakpad_googletest_includes.h" #include "breakpad_googletest_includes.h"
@ -71,7 +73,7 @@ TEST_F(Reader, SimpleConstructor) {
.LEB128(-0x4f337badf4483f83LL) .LEB128(-0x4f337badf4483f83LL)
.D32(0xfec319c9); .D32(0xfec319c9);
ASSERT_TRUE(section.GetContents(&contents)); ASSERT_TRUE(section.GetContents(&contents));
const char *data = contents.data(); const uint8_t *data = reinterpret_cast<const uint8_t *>(contents.data());
EXPECT_EQ(0xc0U, reader.ReadOneByte(data)); EXPECT_EQ(0xc0U, reader.ReadOneByte(data));
EXPECT_EQ(0xcf0dU, reader.ReadTwoBytes(data + 1)); EXPECT_EQ(0xcf0dU, reader.ReadTwoBytes(data + 1));
EXPECT_EQ(0x96fdd219U, reader.ReadFourBytes(data + 3)); EXPECT_EQ(0x96fdd219U, reader.ReadFourBytes(data + 3));
@ -375,7 +377,7 @@ TEST_F(Reader, ValidEncodings) {
} }
TEST_F(ReaderDeathTest, DW_EH_PE_omit) { TEST_F(ReaderDeathTest, DW_EH_PE_omit) {
static const char data[1] = { 42 }; static const uint8_t data[] = { 42 };
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(4); reader.SetAddressSize(4);
EXPECT_DEATH(reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_omit, EXPECT_DEATH(reader.ReadEncodedPointer(data, dwarf2reader::DW_EH_PE_omit,
@ -384,7 +386,7 @@ TEST_F(ReaderDeathTest, DW_EH_PE_omit) {
} }
TEST_F(Reader, DW_EH_PE_absptr4) { TEST_F(Reader, DW_EH_PE_absptr4) {
static const char data[] = { 0x27, 0x57, 0xea, 0x40 }; static const uint8_t data[] = { 0x27, 0x57, 0xea, 0x40 };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
reader.SetAddressSize(4); reader.SetAddressSize(4);
EXPECT_EQ(0x40ea5727U, EXPECT_EQ(0x40ea5727U,
@ -394,7 +396,7 @@ TEST_F(Reader, DW_EH_PE_absptr4) {
} }
TEST_F(Reader, DW_EH_PE_absptr8) { TEST_F(Reader, DW_EH_PE_absptr8) {
static const char data[] = { static const uint8_t data[] = {
0x60, 0x27, 0x57, 0xea, 0x40, 0xc2, 0x98, 0x05, 0x01, 0x50 0x60, 0x27, 0x57, 0xea, 0x40, 0xc2, 0x98, 0x05, 0x01, 0x50
}; };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
@ -406,7 +408,7 @@ TEST_F(Reader, DW_EH_PE_absptr8) {
} }
TEST_F(Reader, DW_EH_PE_uleb128) { TEST_F(Reader, DW_EH_PE_uleb128) {
static const char data[] = { 0x81, 0x84, 0x4c }; static const uint8_t data[] = { 0x81, 0x84, 0x4c };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
reader.SetAddressSize(4); reader.SetAddressSize(4);
EXPECT_EQ(0x130201U, EXPECT_EQ(0x130201U,
@ -416,7 +418,7 @@ TEST_F(Reader, DW_EH_PE_uleb128) {
} }
TEST_F(Reader, DW_EH_PE_udata2) { TEST_F(Reader, DW_EH_PE_udata2) {
static const char data[] = { 0xf4, 0x8d }; static const uint8_t data[] = { 0xf4, 0x8d };
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(4); reader.SetAddressSize(4);
EXPECT_EQ(0xf48dU, EXPECT_EQ(0xf48dU,
@ -426,7 +428,7 @@ TEST_F(Reader, DW_EH_PE_udata2) {
} }
TEST_F(Reader, DW_EH_PE_udata4) { TEST_F(Reader, DW_EH_PE_udata4) {
static const char data[] = { 0xb2, 0x68, 0xa5, 0x62, 0x8f, 0x8b }; static const uint8_t data[] = { 0xb2, 0x68, 0xa5, 0x62, 0x8f, 0x8b };
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(8); reader.SetAddressSize(8);
EXPECT_EQ(0xa5628f8b, EXPECT_EQ(0xa5628f8b,
@ -436,7 +438,7 @@ TEST_F(Reader, DW_EH_PE_udata4) {
} }
TEST_F(Reader, DW_EH_PE_udata8Addr8) { TEST_F(Reader, DW_EH_PE_udata8Addr8) {
static const char data[] = { static const uint8_t data[] = {
0x27, 0x04, 0x73, 0x04, 0x69, 0x9f, 0x19, 0xed, 0x8f, 0xfe 0x27, 0x04, 0x73, 0x04, 0x69, 0x9f, 0x19, 0xed, 0x8f, 0xfe
}; };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
@ -448,7 +450,7 @@ TEST_F(Reader, DW_EH_PE_udata8Addr8) {
} }
TEST_F(Reader, DW_EH_PE_udata8Addr4) { TEST_F(Reader, DW_EH_PE_udata8Addr4) {
static const char data[] = { static const uint8_t data[] = {
0x27, 0x04, 0x73, 0x04, 0x69, 0x9f, 0x19, 0xed, 0x8f, 0xfe 0x27, 0x04, 0x73, 0x04, 0x69, 0x9f, 0x19, 0xed, 0x8f, 0xfe
}; };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
@ -460,7 +462,7 @@ TEST_F(Reader, DW_EH_PE_udata8Addr4) {
} }
TEST_F(Reader, DW_EH_PE_sleb128) { TEST_F(Reader, DW_EH_PE_sleb128) {
static const char data[] = { 0x42, 0xff, 0xfb, 0x73 }; static const uint8_t data[] = { 0x42, 0xff, 0xfb, 0x73 };
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(4); reader.SetAddressSize(4);
EXPECT_EQ(-0x030201U & 0xffffffff, EXPECT_EQ(-0x030201U & 0xffffffff,
@ -470,7 +472,7 @@ TEST_F(Reader, DW_EH_PE_sleb128) {
} }
TEST_F(Reader, DW_EH_PE_sdata2) { TEST_F(Reader, DW_EH_PE_sdata2) {
static const char data[] = { 0xb9, 0xbf }; static const uint8_t data[] = { 0xb9, 0xbf };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
reader.SetAddressSize(8); reader.SetAddressSize(8);
EXPECT_EQ(0xffffffffffffbfb9ULL, EXPECT_EQ(0xffffffffffffbfb9ULL,
@ -480,7 +482,7 @@ TEST_F(Reader, DW_EH_PE_sdata2) {
} }
TEST_F(Reader, DW_EH_PE_sdata4) { TEST_F(Reader, DW_EH_PE_sdata4) {
static const char data[] = { 0xa0, 0xca, 0xf2, 0xb8, 0xc2, 0xad }; static const uint8_t data[] = { 0xa0, 0xca, 0xf2, 0xb8, 0xc2, 0xad };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
reader.SetAddressSize(8); reader.SetAddressSize(8);
EXPECT_EQ(0xffffffffadc2b8f2ULL, EXPECT_EQ(0xffffffffadc2b8f2ULL,
@ -490,7 +492,7 @@ TEST_F(Reader, DW_EH_PE_sdata4) {
} }
TEST_F(Reader, DW_EH_PE_sdata8) { TEST_F(Reader, DW_EH_PE_sdata8) {
static const char data[] = { static const uint8_t data[] = {
0xf6, 0x66, 0x57, 0x79, 0xe0, 0x0c, 0x9b, 0x26, 0x87 0xf6, 0x66, 0x57, 0x79, 0xe0, 0x0c, 0x9b, 0x26, 0x87
}; };
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
@ -502,7 +504,9 @@ TEST_F(Reader, DW_EH_PE_sdata8) {
} }
TEST_F(Reader, DW_EH_PE_pcrel) { TEST_F(Reader, DW_EH_PE_pcrel) {
static const char data[] = { 0x4a, 0x8b, 0x1b, 0x14, 0xc8, 0xc4, 0x02, 0xce }; static const uint8_t data[] = {
0x4a, 0x8b, 0x1b, 0x14, 0xc8, 0xc4, 0x02, 0xce
};
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(4); reader.SetAddressSize(4);
DwarfPointerEncoding encoding = DwarfPointerEncoding encoding =
@ -515,7 +519,9 @@ TEST_F(Reader, DW_EH_PE_pcrel) {
} }
TEST_F(Reader, DW_EH_PE_textrel) { TEST_F(Reader, DW_EH_PE_textrel) {
static const char data[] = { 0xd9, 0x0d, 0x05, 0x17, 0xc9, 0x7a, 0x42, 0x1e }; static const uint8_t data[] = {
0xd9, 0x0d, 0x05, 0x17, 0xc9, 0x7a, 0x42, 0x1e
};
ByteReader reader(ENDIANNESS_LITTLE); ByteReader reader(ENDIANNESS_LITTLE);
reader.SetAddressSize(4); reader.SetAddressSize(4);
reader.SetTextBase(0xb91beaf0); reader.SetTextBase(0xb91beaf0);
@ -528,7 +534,9 @@ TEST_F(Reader, DW_EH_PE_textrel) {
} }
TEST_F(Reader, DW_EH_PE_datarel) { TEST_F(Reader, DW_EH_PE_datarel) {
static const char data[] = { 0x16, 0xf2, 0xbb, 0x82, 0x68, 0xa7, 0xbc, 0x39 }; static const uint8_t data[] = {
0x16, 0xf2, 0xbb, 0x82, 0x68, 0xa7, 0xbc, 0x39
};
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(8); reader.SetAddressSize(8);
reader.SetDataBase(0xbef308bd25ce74f0ULL); reader.SetDataBase(0xbef308bd25ce74f0ULL);
@ -541,7 +549,9 @@ TEST_F(Reader, DW_EH_PE_datarel) {
} }
TEST_F(Reader, DW_EH_PE_funcrel) { TEST_F(Reader, DW_EH_PE_funcrel) {
static const char data[] = { 0x84, 0xf8, 0x14, 0x01, 0x61, 0xd1, 0x48, 0xc9 }; static const uint8_t data[] = {
0x84, 0xf8, 0x14, 0x01, 0x61, 0xd1, 0x48, 0xc9
};
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetAddressSize(4); reader.SetAddressSize(4);
reader.SetFunctionBase(0x823c3520); reader.SetFunctionBase(0x823c3520);
@ -554,7 +564,7 @@ TEST_F(Reader, DW_EH_PE_funcrel) {
} }
TEST(UsableBase, CFI) { TEST(UsableBase, CFI) {
static const char data[1] = { 0x42 }; static const uint8_t data[] = { 0x42 };
ByteReader reader(ENDIANNESS_BIG); ByteReader reader(ENDIANNESS_BIG);
reader.SetCFIDataBase(0xb31cbd20, data); reader.SetCFIDataBase(0xb31cbd20, data);
EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr)); EXPECT_TRUE(reader.UsableEncoding(dwarf2reader::DW_EH_PE_absptr));
@ -617,12 +627,12 @@ TEST(UsableBase, ClearFunction) {
struct AlignedFixture { struct AlignedFixture {
AlignedFixture() : reader(ENDIANNESS_BIG) { reader.SetAddressSize(4); } AlignedFixture() : reader(ENDIANNESS_BIG) { reader.SetAddressSize(4); }
static const char data[10]; static const uint8_t data[10];
ByteReader reader; ByteReader reader;
size_t pointer_size; size_t pointer_size;
}; };
const char AlignedFixture::data[10] = { const uint8_t AlignedFixture::data[10] = {
0xfe, 0x6e, 0x93, 0xd8, 0x34, 0xd5, 0x1c, 0xd3, 0xac, 0x2b 0xfe, 0x6e, 0x93, 0xd8, 0x34, 0xd5, 0x1c, 0xd3, 0xac, 0x2b
}; };

View file

@ -32,6 +32,7 @@
// See dwarf2diehandler.h for details. // See dwarf2diehandler.h for details.
#include <assert.h> #include <assert.h>
#include <stdint.h>
#include <string> #include <string>
@ -167,7 +168,7 @@ void DIEDispatcher::ProcessAttributeReference(uint64 offset,
void DIEDispatcher::ProcessAttributeBuffer(uint64 offset, void DIEDispatcher::ProcessAttributeBuffer(uint64 offset,
enum DwarfAttribute attr, enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
const char* data, const uint8_t *data,
uint64 len) { uint64 len) {
HandlerStack &current = die_handlers_.top(); HandlerStack &current = die_handlers_.top();
// This had better be an attribute of the DIE we were meant to handle. // This had better be an attribute of the DIE we were meant to handle.

View file

@ -156,6 +156,8 @@
#ifndef COMMON_DWARF_DWARF2DIEHANDLER_H__ #ifndef COMMON_DWARF_DWARF2DIEHANDLER_H__
#define COMMON_DWARF_DWARF2DIEHANDLER_H__ #define COMMON_DWARF_DWARF2DIEHANDLER_H__
#include <stdint.h>
#include <stack> #include <stack>
#include <string> #include <string>
@ -206,7 +208,7 @@ class DIEHandler {
uint64 data) { } uint64 data) { }
virtual void ProcessAttributeBuffer(enum DwarfAttribute attr, virtual void ProcessAttributeBuffer(enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
const char* data, const uint8_t *data,
uint64 len) { } uint64 len) { }
virtual void ProcessAttributeString(enum DwarfAttribute attr, virtual void ProcessAttributeString(enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
@ -309,7 +311,7 @@ class DIEDispatcher: public Dwarf2Handler {
void ProcessAttributeBuffer(uint64 offset, void ProcessAttributeBuffer(uint64 offset,
enum DwarfAttribute attr, enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
const char* data, const uint8_t *data,
uint64 len); uint64 len);
void ProcessAttributeString(uint64 offset, void ProcessAttributeString(uint64 offset,
enum DwarfAttribute attr, enum DwarfAttribute attr,

View file

@ -32,6 +32,8 @@
// dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher. // dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher.
#include <stdint.h>
#include <string> #include <string>
#include <utility> #include <utility>
@ -67,7 +69,7 @@ class MockDIEHandler: public DIEHandler {
MOCK_METHOD3(ProcessAttributeReference, MOCK_METHOD3(ProcessAttributeReference,
void(DwarfAttribute, DwarfForm, uint64)); void(DwarfAttribute, DwarfForm, uint64));
MOCK_METHOD4(ProcessAttributeBuffer, MOCK_METHOD4(ProcessAttributeBuffer,
void(DwarfAttribute, DwarfForm, const char *, uint64)); void(DwarfAttribute, DwarfForm, const uint8_t *, uint64));
MOCK_METHOD3(ProcessAttributeString, MOCK_METHOD3(ProcessAttributeString,
void(DwarfAttribute, DwarfForm, const string &)); void(DwarfAttribute, DwarfForm, const string &));
MOCK_METHOD3(ProcessAttributeSignature, MOCK_METHOD3(ProcessAttributeSignature,
@ -86,7 +88,7 @@ class MockRootDIEHandler: public RootDIEHandler {
MOCK_METHOD3(ProcessAttributeReference, MOCK_METHOD3(ProcessAttributeReference,
void(DwarfAttribute, DwarfForm, uint64)); void(DwarfAttribute, DwarfForm, uint64));
MOCK_METHOD4(ProcessAttributeBuffer, MOCK_METHOD4(ProcessAttributeBuffer,
void(DwarfAttribute, DwarfForm, const char *, uint64)); void(DwarfAttribute, DwarfForm, const uint8_t *, uint64));
MOCK_METHOD3(ProcessAttributeString, MOCK_METHOD3(ProcessAttributeString,
void(DwarfAttribute, DwarfForm, const string &)); void(DwarfAttribute, DwarfForm, const string &));
MOCK_METHOD3(ProcessAttributeSignature, MOCK_METHOD3(ProcessAttributeSignature,
@ -185,8 +187,9 @@ TEST(Dwarf2DIEHandler, PassAttributeValues) {
MockRootDIEHandler mock_root_handler; MockRootDIEHandler mock_root_handler;
DIEDispatcher die_dispatcher(&mock_root_handler); DIEDispatcher die_dispatcher(&mock_root_handler);
const char buffer[10] = { 0x24, 0x24, 0x35, 0x9a, 0xca, const uint8_t buffer[10] = {
0xcf, 0xa8, 0x84, 0xa7, 0x18 }; 0x24, 0x24, 0x35, 0x9a, 0xca, 0xcf, 0xa8, 0x84, 0xa7, 0x18
};
string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d"; string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d";
// Set expectations. // Set expectations.

View file

@ -83,9 +83,9 @@ void CompilationUnit::ReadAbbrevs() {
// The only way to check whether we are reading over the end of the // The only way to check whether we are reading over the end of the
// buffer would be to first compute the size of the leb128 data by // buffer would be to first compute the size of the leb128 data by
// reading it, then go back and read it again. // reading it, then go back and read it again.
const char* abbrev_start = iter->second.first + const uint8_t *abbrev_start = iter->second.first +
header_.abbrev_offset; header_.abbrev_offset;
const char* abbrevptr = abbrev_start; const uint8_t *abbrevptr = abbrev_start;
#ifndef NDEBUG #ifndef NDEBUG
const uint64 abbrev_length = iter->second.second - header_.abbrev_offset; const uint64 abbrev_length = iter->second.second - header_.abbrev_offset;
#endif #endif
@ -132,7 +132,7 @@ void CompilationUnit::ReadAbbrevs() {
} }
// Skips a single DIE's attributes. // Skips a single DIE's attributes.
const char* CompilationUnit::SkipDIE(const char* start, const uint8_t *CompilationUnit::SkipDIE(const uint8_t* start,
const Abbrev& abbrev) { const Abbrev& abbrev) {
for (AttributeList::const_iterator i = abbrev.attributes.begin(); for (AttributeList::const_iterator i = abbrev.attributes.begin();
i != abbrev.attributes.end(); i != abbrev.attributes.end();
@ -143,7 +143,7 @@ const char* CompilationUnit::SkipDIE(const char* start,
} }
// Skips a single attribute form's data. // Skips a single attribute form's data.
const char* CompilationUnit::SkipAttribute(const char* start, const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
enum DwarfForm form) { enum DwarfForm form) {
size_t len; size_t len;
@ -171,7 +171,7 @@ const char* CompilationUnit::SkipAttribute(const char* start,
case DW_FORM_ref_sig8: case DW_FORM_ref_sig8:
return start + 8; return start + 8;
case DW_FORM_string: case DW_FORM_string:
return start + strlen(start) + 1; return start + strlen(reinterpret_cast<const char *>(start)) + 1;
case DW_FORM_udata: case DW_FORM_udata:
case DW_FORM_ref_udata: case DW_FORM_ref_udata:
reader_->ReadUnsignedLEB128(start, &len); reader_->ReadUnsignedLEB128(start, &len);
@ -218,7 +218,7 @@ const char* CompilationUnit::SkipAttribute(const char* start,
// the offset in the .debug_abbrev section for our abbrevs, and an // the offset in the .debug_abbrev section for our abbrevs, and an
// address size. // address size.
void CompilationUnit::ReadHeader() { void CompilationUnit::ReadHeader() {
const char* headerptr = buffer_; const uint8_t *headerptr = buffer_;
size_t initial_length_size; size_t initial_length_size;
assert(headerptr + 4 < buffer_ + buffer_length_); assert(headerptr + 4 < buffer_ + buffer_length_);
@ -305,8 +305,8 @@ uint64 CompilationUnit::Start() {
// If one really wanted, you could merge SkipAttribute and // If one really wanted, you could merge SkipAttribute and
// ProcessAttribute // ProcessAttribute
// This is all boring data manipulation and calling of the handler. // This is all boring data manipulation and calling of the handler.
const char* CompilationUnit::ProcessAttribute( const uint8_t *CompilationUnit::ProcessAttribute(
uint64 dieoffset, const char* start, enum DwarfAttribute attr, uint64 dieoffset, const uint8_t *start, enum DwarfAttribute attr,
enum DwarfForm form) { enum DwarfForm form) {
size_t len; size_t len;
@ -340,7 +340,7 @@ const char* CompilationUnit::ProcessAttribute(
reader_->ReadEightBytes(start)); reader_->ReadEightBytes(start));
return start + 8; return start + 8;
case DW_FORM_string: { case DW_FORM_string: {
const char* str = start; const char *str = reinterpret_cast<const char *>(start);
handler_->ProcessAttributeString(dieoffset, attr, form, handler_->ProcessAttributeString(dieoffset, attr, form,
str); str);
return start + strlen(str) + 1; return start + strlen(str) + 1;
@ -440,7 +440,7 @@ const char* CompilationUnit::ProcessAttribute(
const uint64 offset = reader_->ReadOffset(start); const uint64 offset = reader_->ReadOffset(start);
assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_); assert(string_buffer_ + offset < string_buffer_ + string_buffer_length_);
const char* str = string_buffer_ + offset; const char *str = reinterpret_cast<const char *>(string_buffer_ + offset);
handler_->ProcessAttributeString(dieoffset, attr, form, handler_->ProcessAttributeString(dieoffset, attr, form,
str); str);
return start + reader_->OffsetSize(); return start + reader_->OffsetSize();
@ -450,8 +450,8 @@ const char* CompilationUnit::ProcessAttribute(
return NULL; return NULL;
} }
const char* CompilationUnit::ProcessDIE(uint64 dieoffset, const uint8_t *CompilationUnit::ProcessDIE(uint64 dieoffset,
const char* start, const uint8_t *start,
const Abbrev& abbrev) { const Abbrev& abbrev) {
for (AttributeList::const_iterator i = abbrev.attributes.begin(); for (AttributeList::const_iterator i = abbrev.attributes.begin();
i != abbrev.attributes.end(); i != abbrev.attributes.end();
@ -462,12 +462,12 @@ const char* CompilationUnit::ProcessDIE(uint64 dieoffset,
} }
void CompilationUnit::ProcessDIEs() { void CompilationUnit::ProcessDIEs() {
const char* dieptr = after_header_; const uint8_t *dieptr = after_header_;
size_t len; size_t len;
// lengthstart is the place the length field is based on. // lengthstart is the place the length field is based on.
// It is the point in the header after the initial length field // It is the point in the header after the initial length field
const char* lengthstart = buffer_; const uint8_t *lengthstart = buffer_;
// In 64 bit dwarf, the initial length is 12 bytes, because of the // In 64 bit dwarf, the initial length is 12 bytes, because of the
// 0xffffffff at the start. // 0xffffffff at the start.
@ -515,7 +515,7 @@ void CompilationUnit::ProcessDIEs() {
} }
} }
LineInfo::LineInfo(const char* buffer, uint64 buffer_length, LineInfo::LineInfo(const uint8_t *buffer, uint64 buffer_length,
ByteReader* reader, LineInfoHandler* handler): ByteReader* reader, LineInfoHandler* handler):
handler_(handler), reader_(reader), buffer_(buffer) { handler_(handler), reader_(reader), buffer_(buffer) {
#ifndef NDEBUG #ifndef NDEBUG
@ -533,7 +533,7 @@ uint64 LineInfo::Start() {
// The header for a debug_line section is mildly complicated, because // The header for a debug_line section is mildly complicated, because
// the line info is very tightly encoded. // the line info is very tightly encoded.
void LineInfo::ReadHeader() { void LineInfo::ReadHeader() {
const char* lineptr = buffer_; const uint8_t *lineptr = buffer_;
size_t initial_length_size; size_t initial_length_size;
const uint64 initial_length const uint64 initial_length
@ -580,7 +580,7 @@ void LineInfo::ReadHeader() {
if (*lineptr) { if (*lineptr) {
uint32 dirindex = 1; uint32 dirindex = 1;
while (*lineptr) { while (*lineptr) {
const char* dirname = lineptr; const char *dirname = reinterpret_cast<const char *>(lineptr);
handler_->DefineDir(dirname, dirindex); handler_->DefineDir(dirname, dirindex);
lineptr += strlen(dirname) + 1; lineptr += strlen(dirname) + 1;
dirindex++; dirindex++;
@ -593,7 +593,7 @@ void LineInfo::ReadHeader() {
uint32 fileindex = 1; uint32 fileindex = 1;
size_t len; size_t len;
while (*lineptr) { while (*lineptr) {
const char* filename = lineptr; const char *filename = reinterpret_cast<const char *>(lineptr);
lineptr += strlen(filename) + 1; lineptr += strlen(filename) + 1;
uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len); uint64 dirindex = reader_->ReadUnsignedLEB128(lineptr, &len);
@ -618,7 +618,7 @@ void LineInfo::ReadHeader() {
bool LineInfo::ProcessOneOpcode(ByteReader* reader, bool LineInfo::ProcessOneOpcode(ByteReader* reader,
LineInfoHandler* handler, LineInfoHandler* handler,
const struct LineInfoHeader &header, const struct LineInfoHeader &header,
const char* start, const uint8_t *start,
struct LineStateMachine* lsm, struct LineStateMachine* lsm,
size_t* len, size_t* len,
uintptr pc, uintptr pc,
@ -759,7 +759,7 @@ bool LineInfo::ProcessOneOpcode(ByteReader* reader,
} }
break; break;
case DW_LNE_define_file: { case DW_LNE_define_file: {
const char* filename = start; const char *filename = reinterpret_cast<const char *>(start);
templen = strlen(filename) + 1; templen = strlen(filename) + 1;
start += templen; start += templen;
@ -806,7 +806,7 @@ void LineInfo::ReadLines() {
// lengthstart is the place the length field is based on. // lengthstart is the place the length field is based on.
// It is the point in the header after the initial length field // It is the point in the header after the initial length field
const char* lengthstart = buffer_; const uint8_t *lengthstart = buffer_;
// In 64 bit dwarf, the initial length is 12 bytes, because of the // In 64 bit dwarf, the initial length is 12 bytes, because of the
// 0xffffffff at the start. // 0xffffffff at the start.
@ -815,7 +815,7 @@ void LineInfo::ReadLines() {
else else
lengthstart += 4; lengthstart += 4;
const char* lineptr = after_header_; const uint8_t *lineptr = after_header_;
lsm.Reset(header_.default_is_stmt); lsm.Reset(header_.default_is_stmt);
// The LineInfoHandler interface expects each line's length along // The LineInfoHandler interface expects each line's length along
@ -1314,7 +1314,7 @@ class CallFrameInfo::State {
const Entry *entry_; const Entry *entry_;
// The next instruction to process. // The next instruction to process.
const char *cursor_; const uint8_t *cursor_;
// The current set of rules. // The current set of rules.
RuleMap rules_; RuleMap rules_;
@ -1412,7 +1412,8 @@ bool CallFrameInfo::State::ParseOperands(const char *format,
if (len > bytes_left || expression_length > bytes_left - len) if (len > bytes_left || expression_length > bytes_left - len)
return ReportIncomplete(); return ReportIncomplete();
cursor_ += len; cursor_ += len;
operands->expression = string(cursor_, expression_length); operands->expression = string(reinterpret_cast<const char *>(cursor_),
expression_length);
cursor_ += expression_length; cursor_ += expression_length;
break; break;
} }
@ -1765,8 +1766,8 @@ bool CallFrameInfo::State::DoRestore(unsigned reg) {
return DoRule(reg, rule); return DoRule(reg, rule);
} }
bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) { bool CallFrameInfo::ReadEntryPrologue(const uint8_t *cursor, Entry *entry) {
const char *buffer_end = buffer_ + buffer_length_; const uint8_t *buffer_end = buffer_ + buffer_length_;
// Initialize enough of ENTRY for use in error reporting. // Initialize enough of ENTRY for use in error reporting.
entry->offset = cursor - buffer_; entry->offset = cursor - buffer_;
@ -1844,7 +1845,7 @@ bool CallFrameInfo::ReadEntryPrologue(const char *cursor, Entry *entry) {
} }
bool CallFrameInfo::ReadCIEFields(CIE *cie) { bool CallFrameInfo::ReadCIEFields(CIE *cie) {
const char *cursor = cie->fields; const uint8_t *cursor = cie->fields;
size_t len; size_t len;
assert(cie->kind == kCIE); assert(cie->kind == kCIE);
@ -1875,12 +1876,13 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
return false; return false;
} }
const char *augmentation_start = cursor; const uint8_t *augmentation_start = cursor;
const void *augmentation_end = const uint8_t *augmentation_end =
memchr(augmentation_start, '\0', cie->end - augmentation_start); reinterpret_cast<const uint8_t *>(memchr(augmentation_start, '\0',
cie->end - augmentation_start));
if (! augmentation_end) return ReportIncomplete(cie); if (! augmentation_end) return ReportIncomplete(cie);
cursor = static_cast<const char *>(augmentation_end); cursor = augmentation_end;
cie->augmentation = string(augmentation_start, cie->augmentation = string(reinterpret_cast<const char *>(augmentation_start),
cursor - augmentation_start); cursor - augmentation_start);
// Skip the terminating '\0'. // Skip the terminating '\0'.
cursor++; cursor++;
@ -1927,9 +1929,9 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
if (size_t(cie->end - cursor) < len + data_size) if (size_t(cie->end - cursor) < len + data_size)
return ReportIncomplete(cie); return ReportIncomplete(cie);
cursor += len; cursor += len;
const char *data = cursor; const uint8_t *data = cursor;
cursor += data_size; cursor += data_size;
const char *data_end = cursor; const uint8_t *data_end = cursor;
cie->has_z_lsda = false; cie->has_z_lsda = false;
cie->has_z_personality = false; cie->has_z_personality = false;
@ -2021,7 +2023,7 @@ bool CallFrameInfo::ReadCIEFields(CIE *cie) {
} }
bool CallFrameInfo::ReadFDEFields(FDE *fde) { bool CallFrameInfo::ReadFDEFields(FDE *fde) {
const char *cursor = fde->fields; const uint8_t *cursor = fde->fields;
size_t size; size_t size;
fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding, fde->address = reader_->ReadEncodedPointer(cursor, fde->cie->pointer_encoding,
@ -2087,10 +2089,10 @@ bool CallFrameInfo::ReadFDEFields(FDE *fde) {
} }
bool CallFrameInfo::Start() { bool CallFrameInfo::Start() {
const char *buffer_end = buffer_ + buffer_length_; const uint8_t *buffer_end = buffer_ + buffer_length_;
const char *cursor; const uint8_t *cursor;
bool all_ok = true; bool all_ok = true;
const char *entry_end; const uint8_t *entry_end;
bool ok; bool ok;
// Traverse all the entries in buffer_, skipping CIEs and offering // Traverse all the entries in buffer_, skipping CIEs and offering

View file

@ -40,6 +40,8 @@
#ifndef COMMON_DWARF_DWARF2READER_H__ #ifndef COMMON_DWARF_DWARF2READER_H__
#define COMMON_DWARF_DWARF2READER_H__ #define COMMON_DWARF_DWARF2READER_H__
#include <stdint.h>
#include <list> #include <list>
#include <map> #include <map>
#include <string> #include <string>
@ -58,7 +60,7 @@ class LineInfoHandler;
// This maps from a string naming a section to a pair containing a // This maps from a string naming a section to a pair containing a
// the data for the section, and the size of the section. // the data for the section, and the size of the section.
typedef std::map<string, std::pair<const char*, uint64> > SectionMap; typedef std::map<string, std::pair<const uint8_t *, uint64> > SectionMap;
typedef std::list<std::pair<enum DwarfAttribute, enum DwarfForm> > typedef std::list<std::pair<enum DwarfAttribute, enum DwarfForm> >
AttributeList; AttributeList;
typedef AttributeList::iterator AttributeIterator; typedef AttributeList::iterator AttributeIterator;
@ -85,7 +87,7 @@ class LineInfo {
// to the beginning and length of the line information to read. // to the beginning and length of the line information to read.
// Reader is a ByteReader class that has the endianness set // Reader is a ByteReader class that has the endianness set
// properly. // properly.
LineInfo(const char* buffer_, uint64 buffer_length, LineInfo(const uint8_t *buffer_, uint64 buffer_length,
ByteReader* reader, LineInfoHandler* handler); ByteReader* reader, LineInfoHandler* handler);
virtual ~LineInfo() { virtual ~LineInfo() {
@ -111,7 +113,7 @@ class LineInfo {
static bool ProcessOneOpcode(ByteReader* reader, static bool ProcessOneOpcode(ByteReader* reader,
LineInfoHandler* handler, LineInfoHandler* handler,
const struct LineInfoHeader &header, const struct LineInfoHeader &header,
const char* start, const uint8_t *start,
struct LineStateMachine* lsm, struct LineStateMachine* lsm,
size_t* len, size_t* len,
uintptr pc, uintptr pc,
@ -139,11 +141,11 @@ class LineInfo {
// buffer is the buffer for our line info, starting at exactly where // buffer is the buffer for our line info, starting at exactly where
// the line info to read is. after_header is the place right after // the line info to read is. after_header is the place right after
// the end of the line information header. // the end of the line information header.
const char* buffer_; const uint8_t *buffer_;
#ifndef NDEBUG #ifndef NDEBUG
uint64 buffer_length_; uint64 buffer_length_;
#endif #endif
const char* after_header_; const uint8_t *after_header_;
}; };
// This class is the main interface between the line info reader and // This class is the main interface between the line info reader and
@ -268,14 +270,14 @@ class CompilationUnit {
// Processes a single DIE for this compilation unit and return a new // Processes a single DIE for this compilation unit and return a new
// pointer just past the end of it // pointer just past the end of it
const char* ProcessDIE(uint64 dieoffset, const uint8_t *ProcessDIE(uint64 dieoffset,
const char* start, const uint8_t *start,
const Abbrev& abbrev); const Abbrev& abbrev);
// Processes a single attribute and return a new pointer just past the // Processes a single attribute and return a new pointer just past the
// end of it // end of it
const char* ProcessAttribute(uint64 dieoffset, const uint8_t *ProcessAttribute(uint64 dieoffset,
const char* start, const uint8_t *start,
enum DwarfAttribute attr, enum DwarfAttribute attr,
enum DwarfForm form); enum DwarfForm form);
@ -284,13 +286,11 @@ class CompilationUnit {
// Skips the die with attributes specified in ABBREV starting at // Skips the die with attributes specified in ABBREV starting at
// START, and return the new place to position the stream to. // START, and return the new place to position the stream to.
const char* SkipDIE(const char* start, const uint8_t *SkipDIE(const uint8_t *start, const Abbrev& abbrev);
const Abbrev& abbrev);
// Skips the attribute starting at START, with FORM, and return the // Skips the attribute starting at START, with FORM, and return the
// new place to position the stream to. // new place to position the stream to.
const char* SkipAttribute(const char* start, const uint8_t *SkipAttribute(const uint8_t *start, enum DwarfForm form);
enum DwarfForm form);
// Offset from section start is the offset of this compilation unit // Offset from section start is the offset of this compilation unit
// from the beginning of the .debug_info section. // from the beginning of the .debug_info section.
@ -299,9 +299,9 @@ class CompilationUnit {
// buffer is the buffer for our CU, starting at .debug_info + offset // buffer is the buffer for our CU, starting at .debug_info + offset
// passed in from constructor. // passed in from constructor.
// after_header points to right after the compilation unit header. // after_header points to right after the compilation unit header.
const char* buffer_; const uint8_t *buffer_;
uint64 buffer_length_; uint64 buffer_length_;
const char* after_header_; const uint8_t *after_header_;
// The associated ByteReader that handles endianness issues for us // The associated ByteReader that handles endianness issues for us
ByteReader* reader_; ByteReader* reader_;
@ -320,7 +320,7 @@ class CompilationUnit {
// String section buffer and length, if we have a string section. // String section buffer and length, if we have a string section.
// This is here to avoid doing a section lookup for strings in // This is here to avoid doing a section lookup for strings in
// ProcessAttribute, which is in the hot path for DWARF2 reading. // ProcessAttribute, which is in the hot path for DWARF2 reading.
const char* string_buffer_; const uint8_t *string_buffer_;
uint64 string_buffer_length_; uint64 string_buffer_length_;
}; };
@ -383,7 +383,7 @@ class Dwarf2Handler {
virtual void ProcessAttributeBuffer(uint64 offset, virtual void ProcessAttributeBuffer(uint64 offset,
enum DwarfAttribute attr, enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
const char* data, const uint8_t *data,
uint64 len) { } uint64 len) { }
// Called when we have an attribute with string data to give to our handler. // Called when we have an attribute with string data to give to our handler.
@ -639,7 +639,7 @@ class CallFrameInfo {
// The mechanics of C++ exception handling, personality routines, // The mechanics of C++ exception handling, personality routines,
// and language-specific data areas are described here, rather nicely: // and language-specific data areas are described here, rather nicely:
// http://www.codesourcery.com/public/cxx-abi/abi-eh.html // http://www.codesourcery.com/public/cxx-abi/abi-eh.html
CallFrameInfo(const char *buffer, size_t buffer_length, CallFrameInfo(const uint8_t *buffer, size_t buffer_length,
ByteReader *reader, Handler *handler, Reporter *reporter, ByteReader *reader, Handler *handler, Reporter *reporter,
bool eh_frame = false) bool eh_frame = false)
: buffer_(buffer), buffer_length_(buffer_length), : buffer_(buffer), buffer_length_(buffer_length),
@ -667,7 +667,7 @@ class CallFrameInfo {
size_t offset; size_t offset;
// The start of this entry in the buffer. // The start of this entry in the buffer.
const char *start; const uint8_t *start;
// Which kind of entry this is. // Which kind of entry this is.
// //
@ -678,16 +678,16 @@ class CallFrameInfo {
// The end of this entry's common prologue (initial length and id), and // The end of this entry's common prologue (initial length and id), and
// the start of this entry's kind-specific fields. // the start of this entry's kind-specific fields.
const char *fields; const uint8_t *fields;
// The start of this entry's instructions. // The start of this entry's instructions.
const char *instructions; const uint8_t *instructions;
// The address past the entry's last byte in the buffer. (Note that // The address past the entry's last byte in the buffer. (Note that
// since offset points to the entry's initial length field, and the // since offset points to the entry's initial length field, and the
// length field is the number of bytes after that field, this is not // length field is the number of bytes after that field, this is not
// simply buffer_ + offset + length.) // simply buffer_ + offset + length.)
const char *end; const uint8_t *end;
// For both DWARF CFI and .eh_frame sections, this is the CIE id in a // For both DWARF CFI and .eh_frame sections, this is the CIE id in a
// CIE, and the offset of the associated CIE in an FDE. // CIE, and the offset of the associated CIE in an FDE.
@ -764,7 +764,7 @@ class CallFrameInfo {
// true. On failure, report the problem, and return false. Even if we // true. On failure, report the problem, and return false. Even if we
// return false, set ENTRY->end to the first byte after the entry if we // return false, set ENTRY->end to the first byte after the entry if we
// were able to figure that out, or NULL if we weren't. // were able to figure that out, or NULL if we weren't.
bool ReadEntryPrologue(const char *cursor, Entry *entry); bool ReadEntryPrologue(const uint8_t *cursor, Entry *entry);
// Parse the fields of a CIE after the entry prologue, including any 'z' // Parse the fields of a CIE after the entry prologue, including any 'z'
// augmentation data. Assume that the 'Entry' fields of CIE are // augmentation data. Assume that the 'Entry' fields of CIE are
@ -792,7 +792,7 @@ class CallFrameInfo {
} }
// The contents of the DWARF .debug_info section we're parsing. // The contents of the DWARF .debug_info section we're parsing.
const char *buffer_; const uint8_t *buffer_;
size_t buffer_length_; size_t buffer_length_;
// For reading multi-byte values with the appropriate endianness. // For reading multi-byte values with the appropriate endianness.

View file

@ -31,6 +31,7 @@
// dwarf2reader_cfi_unittest.cc: Unit tests for dwarf2reader::CallFrameInfo // dwarf2reader_cfi_unittest.cc: Unit tests for dwarf2reader::CallFrameInfo
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string> #include <string>
@ -186,7 +187,7 @@ class CFI: public CFIFixture, public Test { };
TEST_F(CFI, EmptyRegion) { TEST_F(CFI, EmptyRegion) {
EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0); EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
EXPECT_CALL(handler, End()).Times(0); EXPECT_CALL(handler, End()).Times(0);
static const char data[1] = { 42 }; static const uint8_t data[] = { 42 };
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
CallFrameInfo parser(data, 0, &byte_reader, &handler, &reporter); CallFrameInfo parser(data, 0, &byte_reader, &handler, &reporter);
@ -213,7 +214,8 @@ TEST_F(CFI, IncompleteLength32) {
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(8); byte_reader.SetAddressSize(8);
CallFrameInfo parser(contents.data(), contents.size() - 2, CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size() - 2,
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_FALSE(parser.Start()); EXPECT_FALSE(parser.Start());
} }
@ -238,7 +240,8 @@ TEST_F(CFI, IncompleteLength64) {
ByteReader byte_reader(ENDIANNESS_LITTLE); ByteReader byte_reader(ENDIANNESS_LITTLE);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size() - 4, CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size() - 4,
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_FALSE(parser.Start()); EXPECT_FALSE(parser.Start());
} }
@ -262,7 +265,8 @@ TEST_F(CFI, IncompleteId32) {
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(8); byte_reader.SetAddressSize(8);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_FALSE(parser.Start()); EXPECT_FALSE(parser.Start());
} }
@ -288,7 +292,8 @@ TEST_F(CFI, BadId32) {
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(8); byte_reader.SetAddressSize(8);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_FALSE(parser.Start()); EXPECT_FALSE(parser.Start());
} }
@ -309,7 +314,8 @@ TEST_F(CFI, SingleCIE) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_LITTLE); ByteReader byte_reader(ENDIANNESS_LITTLE);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
} }
@ -339,7 +345,8 @@ TEST_F(CFI, OneFDE) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
} }
@ -382,7 +389,8 @@ TEST_F(CFI, TwoFDEsOneCIE) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
} }
@ -431,7 +439,8 @@ TEST_F(CFI, TwoFDEsTwoCIEs) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_LITTLE); ByteReader byte_reader(ENDIANNESS_LITTLE);
byte_reader.SetAddressSize(8); byte_reader.SetAddressSize(8);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
} }
@ -475,7 +484,8 @@ TEST_F(CFI, BadVersion) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_FALSE(parser.Start()); EXPECT_FALSE(parser.Start());
} }
@ -519,7 +529,8 @@ TEST_F(CFI, BadAugmentation) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_FALSE(parser.Start()); EXPECT_FALSE(parser.Start());
} }
@ -553,7 +564,8 @@ TEST_F(CFI, CIEVersion1ReturnColumn) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
} }
@ -587,7 +599,8 @@ TEST_F(CFI, CIEVersion3ReturnColumn) {
EXPECT_TRUE(section.GetContents(&contents)); EXPECT_TRUE(section.GetContents(&contents));
ByteReader byte_reader(ENDIANNESS_BIG); ByteReader byte_reader(ENDIANNESS_BIG);
byte_reader.SetAddressSize(4); byte_reader.SetAddressSize(4);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
} }
@ -668,7 +681,8 @@ struct CFIInsnFixture: public CFIFixture {
} }
ByteReader byte_reader(endianness); ByteReader byte_reader(endianness);
byte_reader.SetAddressSize(section->AddressSize()); byte_reader.SetAddressSize(section->AddressSize());
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter); &byte_reader, &handler, &reporter);
if (succeeds) if (succeeds)
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());
@ -1989,10 +2003,12 @@ struct EHFrameFixture: public CFIInsnFixture {
} }
ByteReader byte_reader(endianness); ByteReader byte_reader(endianness);
byte_reader.SetAddressSize(section->AddressSize()); byte_reader.SetAddressSize(section->AddressSize());
byte_reader.SetCFIDataBase(encoded_pointer_bases.cfi, contents.data()); byte_reader.SetCFIDataBase(encoded_pointer_bases.cfi,
reinterpret_cast<const uint8_t *>(contents.data()));
byte_reader.SetTextBase(encoded_pointer_bases.text); byte_reader.SetTextBase(encoded_pointer_bases.text);
byte_reader.SetDataBase(encoded_pointer_bases.data); byte_reader.SetDataBase(encoded_pointer_bases.data);
CallFrameInfo parser(contents.data(), contents.size(), CallFrameInfo parser(reinterpret_cast<const uint8_t *>(contents.data()),
contents.size(),
&byte_reader, &handler, &reporter, true); &byte_reader, &handler, &reporter, true);
if (succeeds) if (succeeds)
EXPECT_TRUE(parser.Start()); EXPECT_TRUE(parser.Start());

View file

@ -31,6 +31,7 @@
// dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit // dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <iostream> #include <iostream>
@ -91,7 +92,7 @@ class MockDwarf2Handler: public Dwarf2Handler {
MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset, MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset,
enum DwarfAttribute attr, enum DwarfAttribute attr,
enum DwarfForm form, enum DwarfForm form,
const char* data, const uint8_t *data,
uint64 len)); uint64 len));
MOCK_METHOD4(ProcessAttributeString, void(uint64 offset, MOCK_METHOD4(ProcessAttributeString, void(uint64 offset,
enum DwarfAttribute attr, enum DwarfAttribute attr,
@ -132,9 +133,11 @@ struct DIEFixture {
assert(info.GetContents(&info_contents)); assert(info.GetContents(&info_contents));
assert(abbrevs.GetContents(&abbrevs_contents)); assert(abbrevs.GetContents(&abbrevs_contents));
section_map.clear(); section_map.clear();
section_map[".debug_info"].first = info_contents.data(); section_map[".debug_info"].first
= reinterpret_cast<const uint8_t *>(info_contents.data());
section_map[".debug_info"].second = info_contents.size(); section_map[".debug_info"].second = info_contents.size();
section_map[".debug_abbrev"].first = abbrevs_contents.data(); section_map[".debug_abbrev"].first
= reinterpret_cast<const uint8_t *>(abbrevs_contents.data());
section_map[".debug_abbrev"].second = abbrevs_contents.size(); section_map[".debug_abbrev"].second = abbrevs_contents.size();
return section_map; return section_map;
} }

View file

@ -43,6 +43,7 @@
#include <cxxabi.h> #include <cxxabi.h>
#endif #endif
#include <inttypes.h> #include <inttypes.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <algorithm> #include <algorithm>
@ -140,7 +141,7 @@ DwarfCUToModule::FileContext::~FileContext() {
} }
void DwarfCUToModule::FileContext::AddSectionToSectionMap( void DwarfCUToModule::FileContext::AddSectionToSectionMap(
const string& name, const char* contents, uint64 length) { const string& name, const uint8_t *contents, uint64 length) {
section_map_[name] = std::make_pair(contents, length); section_map_[name] = std::make_pair(contents, length);
} }
@ -814,7 +815,7 @@ void DwarfCUToModule::ReadSourceLines(uint64 offset) {
cu_context_->reporter->MissingSection(".debug_line"); cu_context_->reporter->MissingSection(".debug_line");
return; return;
} }
const char *section_start = map_entry->second.first; const uint8_t *section_start = map_entry->second.first;
uint64 section_length = map_entry->second.second; uint64 section_length = map_entry->second.second;
if (offset >= section_length) { if (offset >= section_length) {
cu_context_->reporter->BadLineInfoOffset(offset); cu_context_->reporter->BadLineInfoOffset(offset);

View file

@ -39,6 +39,8 @@
#ifndef COMMON_LINUX_DWARF_CU_TO_MODULE_H__ #ifndef COMMON_LINUX_DWARF_CU_TO_MODULE_H__
#define COMMON_LINUX_DWARF_CU_TO_MODULE_H__ #define COMMON_LINUX_DWARF_CU_TO_MODULE_H__
#include <stdint.h>
#include <string> #include <string>
#include "common/language.h" #include "common/language.h"
@ -84,7 +86,7 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
// Add CONTENTS of size LENGTH to the section map as NAME. // Add CONTENTS of size LENGTH to the section map as NAME.
void AddSectionToSectionMap(const string& name, void AddSectionToSectionMap(const string& name,
const char* contents, const uint8_t *contents,
uint64 length); uint64 length);
// Clear the section map for testing. // Clear the section map for testing.
@ -140,7 +142,7 @@ class DwarfCUToModule: public dwarf2reader::RootDIEHandler {
// mappings, given a pointer to some DWARF line number data // mappings, given a pointer to some DWARF line number data
// PROGRAM, and an overestimate of its size. Add no zero-length // PROGRAM, and an overestimate of its size. Add no zero-length
// lines to LINES. // lines to LINES.
virtual void ReadProgram(const char *program, uint64 length, virtual void ReadProgram(const uint8_t *program, uint64 length,
Module *module, vector<Module::Line> *lines) = 0; Module *module, vector<Module::Line> *lines) = 0;
}; };

View file

@ -31,6 +31,8 @@
// dwarf_cu_to_module.cc: Unit tests for google_breakpad::DwarfCUToModule. // dwarf_cu_to_module.cc: Unit tests for google_breakpad::DwarfCUToModule.
#include <stdint.h>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -65,7 +67,7 @@ using ::testing::ValuesIn;
class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler { class MockLineToModuleHandler: public DwarfCUToModule::LineToModuleHandler {
public: public:
MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir)); MOCK_METHOD1(StartCompilationUnit, void(const string& compilation_dir));
MOCK_METHOD4(ReadProgram, void(const char* program, uint64 length, MOCK_METHOD4(ReadProgram, void(const uint8_t *program, uint64 length,
Module *module, vector<Module::Line> *lines)); Module *module, vector<Module::Line> *lines));
}; };
@ -111,7 +113,7 @@ class CUFixtureBase {
public: public:
explicit AppendLinesFunctor( explicit AppendLinesFunctor(
const vector<Module::Line> *lines) : lines_(lines) { } const vector<Module::Line> *lines) : lines_(lines) { }
void operator()(const char *program, uint64 length, void operator()(const uint8_t *program, uint64 length,
Module *module, vector<Module::Line> *lines) { Module *module, vector<Module::Line> *lines) {
lines->insert(lines->end(), lines_->begin(), lines_->end()); lines->insert(lines->end(), lines_->begin(), lines_->end());
} }
@ -285,7 +287,7 @@ class CUFixtureBase {
// Mock line program reader. // Mock line program reader.
MockLineToModuleHandler line_reader_; MockLineToModuleHandler line_reader_;
AppendLinesFunctor appender_; AppendLinesFunctor appender_;
static const char dummy_line_program_[]; static const uint8_t dummy_line_program_[];
static const size_t dummy_line_size_; static const size_t dummy_line_size_;
MockWarningReporter reporter_; MockWarningReporter reporter_;
@ -302,7 +304,7 @@ class CUFixtureBase {
bool functions_filled_; bool functions_filled_;
}; };
const char CUFixtureBase::dummy_line_program_[] = "lots of fun data"; const uint8_t CUFixtureBase::dummy_line_program_[] = "lots of fun data";
const size_t CUFixtureBase::dummy_line_size_ = const size_t CUFixtureBase::dummy_line_size_ =
sizeof(CUFixtureBase::dummy_line_program_); sizeof(CUFixtureBase::dummy_line_program_);
@ -375,7 +377,7 @@ void CUFixtureBase::ProcessStrangeAttributes(
handler->ProcessAttributeReference((DwarfAttribute) 0xf7f7480f, handler->ProcessAttributeReference((DwarfAttribute) 0xf7f7480f,
(DwarfForm) 0x829e038a, (DwarfForm) 0x829e038a,
0x50fddef44734fdecULL); 0x50fddef44734fdecULL);
static const char buffer[10] = "frobynode"; static const uint8_t buffer[10] = "frobynode";
handler->ProcessAttributeBuffer((DwarfAttribute) 0xa55ffb51, handler->ProcessAttributeBuffer((DwarfAttribute) 0xa55ffb51,
(DwarfForm) 0x2f43b041, (DwarfForm) 0x2f43b041,
buffer, sizeof(buffer)); buffer, sizeof(buffer));

View file

@ -39,6 +39,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <link.h> #include <link.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -220,7 +221,7 @@ class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler {
void StartCompilationUnit(const string& compilation_dir) { void StartCompilationUnit(const string& compilation_dir) {
compilation_dir_ = compilation_dir; compilation_dir_ = compilation_dir;
} }
void ReadProgram(const char* program, uint64 length, void ReadProgram(const uint8_t *program, uint64 length,
Module* module, std::vector<Module::Line>* lines) { Module* module, std::vector<Module::Line>* lines) {
DwarfLineToModule handler(module, compilation_dir_, lines); DwarfLineToModule handler(module, compilation_dir_, lines);
dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
@ -258,7 +259,7 @@ bool LoadDwarf(const string& dwarf_filename,
string name = GetOffset<ElfClass, char>(elf_header, string name = GetOffset<ElfClass, char>(elf_header,
section_names->sh_offset) + section_names->sh_offset) +
section->sh_name; section->sh_name;
const char* contents = GetOffset<ElfClass, char>(elf_header, const uint8_t *contents = GetOffset<ElfClass, uint8_t>(elf_header,
section->sh_offset); section->sh_offset);
file_context.AddSectionToSectionMap(name, contents, section->sh_size); file_context.AddSectionToSectionMap(name, contents, section->sh_size);
} }
@ -268,7 +269,7 @@ bool LoadDwarf(const string& dwarf_filename,
dwarf2reader::SectionMap::const_iterator debug_info_entry = dwarf2reader::SectionMap::const_iterator debug_info_entry =
file_context.section_map().find(".debug_info"); file_context.section_map().find(".debug_info");
assert(debug_info_entry != file_context.section_map().end()); assert(debug_info_entry != file_context.section_map().end());
const std::pair<const char*, uint64>& debug_info_section = const std::pair<const uint8_t *, uint64>& debug_info_section =
debug_info_entry->second; debug_info_entry->second;
// This should never have been called if the file doesn't have a // This should never have been called if the file doesn't have a
// .debug_info section. // .debug_info section.
@ -345,8 +346,8 @@ bool LoadDwarfCFI(const string& dwarf_filename,
dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE; dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE;
// Find the call frame information and its size. // Find the call frame information and its size.
const char* cfi = const uint8_t *cfi =
GetOffset<ElfClass, char>(elf_header, section->sh_offset); GetOffset<ElfClass, uint8_t>(elf_header, section->sh_offset);
size_t cfi_size = section->sh_size; size_t cfi_size = section->sh_size;
// Plug together the parser, handler, and their entourages. // Plug together the parser, handler, and their entourages.
@ -433,12 +434,13 @@ bool IsSameFile(const char* left_abspath, const string& right_path) {
// Read the .gnu_debuglink and get the debug file name. If anything goes // Read the .gnu_debuglink and get the debug file name. If anything goes
// wrong, return an empty string. // wrong, return an empty string.
string ReadDebugLink(const char* debuglink, string ReadDebugLink(const uint8_t *debuglink,
const size_t debuglink_size, const size_t debuglink_size,
const bool big_endian, const bool big_endian,
const string& obj_file, const string& obj_file,
const std::vector<string>& debug_dirs) { const std::vector<string>& debug_dirs) {
size_t debuglink_len = strlen(debuglink) + 5; // Include '\0' + CRC32. // Include '\0' + CRC32 (4 bytes).
size_t debuglink_len = strlen(reinterpret_cast<const char *>(debuglink)) + 5;
debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round up to 4 bytes. debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round up to 4 bytes.
// Sanity check. // Sanity check.
@ -459,7 +461,8 @@ string ReadDebugLink(const char* debuglink,
std::vector<string>::const_iterator it; std::vector<string>::const_iterator it;
for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) { for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
const string& debug_dir = *it; const string& debug_dir = *it;
debuglink_path = debug_dir + "/" + debuglink; debuglink_path = debug_dir + "/" +
reinterpret_cast<const char *>(debuglink);
// There is the annoying case of /path/to/foo.so having foo.so as the // There is the annoying case of /path/to/foo.so having foo.so as the
// debug link file name. Thus this may end up opening /path/to/foo.so again, // debug link file name. Thus this may end up opening /path/to/foo.so again,
@ -769,8 +772,8 @@ bool LoadSymbols(const string& obj_file,
names_end, elf_header->e_shnum); names_end, elf_header->e_shnum);
if (gnu_debuglink_section) { if (gnu_debuglink_section) {
if (!info->debug_dirs().empty()) { if (!info->debug_dirs().empty()) {
const char* debuglink_contents = const uint8_t *debuglink_contents =
GetOffset<ElfClass, char>(elf_header, GetOffset<ElfClass, uint8_t>(elf_header,
gnu_debuglink_section->sh_offset); gnu_debuglink_section->sh_offset);
string debuglink_file = string debuglink_file =
ReadDebugLink(debuglink_contents, ReadDebugLink(debuglink_contents,

View file

@ -41,6 +41,7 @@
#include <libgen.h> #include <libgen.h>
#include <mach-o/arch.h> #include <mach-o/arch.h>
#include <mach-o/fat.h> #include <mach-o/fat.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -316,7 +317,7 @@ class DumpSymbols::DumperLineToModule:
compilation_dir_ = compilation_dir; compilation_dir_ = compilation_dir;
} }
void ReadProgram(const char *program, uint64 length, void ReadProgram(const uint8_t *program, uint64 length,
Module *module, vector<Module::Line> *lines) { Module *module, vector<Module::Line> *lines) {
DwarfLineToModule handler(module, compilation_dir_, lines); DwarfLineToModule handler(module, compilation_dir_, lines);
dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
@ -346,7 +347,7 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
it != dwarf_sections.end(); ++it) { it != dwarf_sections.end(); ++it) {
file_context.AddSectionToSectionMap( file_context.AddSectionToSectionMap(
it->first, it->first,
reinterpret_cast<const char *>(it->second.contents.start), it->second.contents.start,
it->second.contents.Size()); it->second.contents.Size());
} }
@ -354,7 +355,7 @@ bool DumpSymbols::ReadDwarf(google_breakpad::Module *module,
dwarf2reader::SectionMap::const_iterator debug_info_entry = dwarf2reader::SectionMap::const_iterator debug_info_entry =
file_context.section_map().find("__debug_info"); file_context.section_map().find("__debug_info");
assert(debug_info_entry != file_context.section_map().end()); assert(debug_info_entry != file_context.section_map().end());
const std::pair<const char*, uint64>& debug_info_section = const std::pair<const uint8_t *, uint64>& debug_info_section =
debug_info_entry->second; debug_info_entry->second;
// There had better be a __debug_info section! // There had better be a __debug_info section!
if (!debug_info_section.first) { if (!debug_info_section.first) {
@ -424,7 +425,7 @@ bool DumpSymbols::ReadCFI(google_breakpad::Module *module,
} }
// Find the call frame information and its size. // Find the call frame information and its size.
const char *cfi = reinterpret_cast<const char *>(section.contents.start); const uint8_t *cfi = section.contents.start;
size_t cfi_size = section.contents.Size(); size_t cfi_size = section.contents.Size();
// Plug together the parser, handler, and their entourages. // Plug together the parser, handler, and their entourages.