Line 1... |
Line 1... |
// dwarf_reader.cc -- parse dwarf2/3 debug information
|
// dwarf_reader.cc -- parse dwarf2/3 debug information
|
|
|
// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
// Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
|
|
// This file is part of gold.
|
// This file is part of gold.
|
|
|
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
Line 60... |
Line 60... |
lsm->basic_block = false;
|
lsm->basic_block = false;
|
lsm->end_sequence = false;
|
lsm->end_sequence = false;
|
}
|
}
|
|
|
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
Sized_dwarf_line_info<size, big_endian>::Sized_dwarf_line_info(Object* object,
|
Sized_dwarf_line_info<size, big_endian>::Sized_dwarf_line_info(
|
|
Object* object,
|
unsigned int read_shndx)
|
unsigned int read_shndx)
|
: data_valid_(false), buffer_(NULL), symtab_buffer_(NULL),
|
: data_valid_(false), buffer_(NULL), buffer_start_(NULL),
|
directories_(), files_(), current_header_index_(-1)
|
symtab_buffer_(NULL), directories_(), files_(), current_header_index_(-1)
|
{
|
{
|
unsigned int debug_shndx;
|
unsigned int debug_shndx;
|
|
|
for (debug_shndx = 1; debug_shndx < object->shnum(); ++debug_shndx)
|
for (debug_shndx = 1; debug_shndx < object->shnum(); ++debug_shndx)
|
{
|
{
|
// FIXME: do this more efficiently: section_name() isn't super-fast
|
// FIXME: do this more efficiently: section_name() isn't super-fast
|
std::string name = object->section_name(debug_shndx);
|
std::string name = object->section_name(debug_shndx);
|
if (name == ".debug_line" || name == ".zdebug_line")
|
if (name == ".debug_line" || name == ".zdebug_line")
|
{
|
{
|
section_size_type buffer_size;
|
section_size_type buffer_size;
|
this->buffer_ = object->section_contents(debug_shndx, &buffer_size,
|
bool is_new = false;
|
false);
|
this->buffer_ = object->decompressed_section_contents(debug_shndx,
|
|
&buffer_size,
|
|
&is_new);
|
|
if (is_new)
|
|
this->buffer_start_ = this->buffer_;
|
this->buffer_end_ = this->buffer_ + buffer_size;
|
this->buffer_end_ = this->buffer_ + buffer_size;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
if (this->buffer_ == NULL)
|
if (this->buffer_ == NULL)
|
return;
|
return;
|
|
|
section_size_type uncompressed_size = 0;
|
|
unsigned char* uncompressed_data = NULL;
|
|
if (object->section_is_compressed(debug_shndx, &uncompressed_size))
|
|
{
|
|
uncompressed_data = new unsigned char[uncompressed_size];
|
|
if (!decompress_input_section(this->buffer_,
|
|
this->buffer_end_ - this->buffer_,
|
|
uncompressed_data,
|
|
uncompressed_size))
|
|
object->error(_("could not decompress section %s"),
|
|
object->section_name(debug_shndx).c_str());
|
|
this->buffer_ = uncompressed_data;
|
|
this->buffer_end_ = this->buffer_ + uncompressed_size;
|
|
}
|
|
|
|
// Find the relocation section for ".debug_line".
|
// Find the relocation section for ".debug_line".
|
// We expect these for relobjs (.o's) but not dynobjs (.so's).
|
// We expect these for relobjs (.o's) but not dynobjs (.so's).
|
bool got_relocs = false;
|
bool got_relocs = false;
|
for (unsigned int reloc_shndx = 0;
|
for (unsigned int reloc_shndx = 0;
|
reloc_shndx < object->shnum();
|
reloc_shndx < object->shnum();
|
Line 489... |
Line 480... |
bool add_line = this->process_one_opcode(lineptr, &lsm, &oplength);
|
bool add_line = this->process_one_opcode(lineptr, &lsm, &oplength);
|
if (add_line
|
if (add_line
|
&& (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx))
|
&& (shndx == -1U || lsm.shndx == -1U || shndx == lsm.shndx))
|
{
|
{
|
Offset_to_lineno_entry entry
|
Offset_to_lineno_entry entry
|
= { lsm.address, this->current_header_index_,
|
= { static_cast<off_t>(lsm.address),
|
lsm.file_num, true, lsm.line_num };
|
this->current_header_index_,
|
|
static_cast<unsigned int>(lsm.file_num),
|
|
true, lsm.line_num };
|
std::vector<Offset_to_lineno_entry>&
|
std::vector<Offset_to_lineno_entry>&
|
map(this->line_number_map_[lsm.shndx]);
|
map(this->line_number_map_[lsm.shndx]);
|
// If we see two consecutive entries with the same
|
// If we see two consecutive entries with the same
|
// offset and a real line number, then mark the first
|
// offset and a real line number, then mark the first
|
// one as non-canonical.
|
// one as non-canonical.
|