Index: src/common/linux/dump_symbols.cc |
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc |
index 517edee3be42b3c5d344c618572dd6defa9e2841..59d59ccade0e5dafdac575aae71bce3499001de9 100644 |
--- a/src/common/linux/dump_symbols.cc |
+++ b/src/common/linux/dump_symbols.cc |
@@ -61,6 +61,7 @@ |
#include "common/linux/elfutils-inl.h" |
#include "common/linux/elf_symbols_to_module.h" |
#include "common/linux/file_id.h" |
+#include "common/memory_range.h" |
#include "common/module.h" |
#include "common/scoped_ptr.h" |
#ifndef NO_STABS_SUPPORT |
@@ -82,6 +83,7 @@ using google_breakpad::ElfClass64; |
using google_breakpad::FindElfSectionByName; |
using google_breakpad::GetOffset; |
using google_breakpad::IsValidElf; |
+using google_breakpad::MemoryRange; |
using google_breakpad::Module; |
#ifndef NO_STABS_SUPPORT |
using google_breakpad::StabsToModule; |
@@ -118,31 +120,27 @@ class FDWrapper { |
// |
// Wrapper class to make sure mapped regions are unmapped. |
// |
-class MmapWrapper { |
+class MmapWrapper: public MemoryRange { |
public: |
MmapWrapper() : is_set_(false) {} |
~MmapWrapper() { |
- if (is_set_ && base_ != NULL) { |
- assert(size_ > 0); |
- munmap(base_, size_); |
+ if (is_set_ && data() != NULL) { |
+ assert(length() > 0); |
+ munmap(const_cast<uint8_t*>(data()), length()); |
} |
} |
- void set(void *mapped_address, size_t mapped_size) { |
+ void Set(void* mapped_address, size_t mapped_size) { |
is_set_ = true; |
- base_ = mapped_address; |
- size_ = mapped_size; |
+ MemoryRange::Set(mapped_address, mapped_size); |
} |
- void release() { |
+ void Reset() { |
assert(is_set_); |
is_set_ = false; |
- base_ = NULL; |
- size_ = 0; |
+ MemoryRange::Reset(); |
} |
private: |
bool is_set_; |
- void *base_; |
- size_t size_; |
}; |
// Find the preferred loading address of the binary. |
@@ -349,8 +347,7 @@ bool LoadDwarfCFI(const string& dwarf_filename, |
return true; |
} |
-bool LoadELF(const string& obj_file, MmapWrapper* map_wrapper, |
- void** elf_header) { |
+bool LoadELF(const string& obj_file, MmapWrapper* map_wrapper) { |
int obj_fd = open(obj_file.c_str(), O_RDONLY); |
if (obj_fd < 0) { |
fprintf(stderr, "Failed to open ELF file '%s': %s\n", |
@@ -371,9 +368,8 @@ bool LoadELF(const string& obj_file, MmapWrapper* map_wrapper, |
obj_file.c_str(), strerror(errno)); |
return false; |
} |
- map_wrapper->set(obj_base, st.st_size); |
- *elf_header = obj_base; |
- if (!IsValidElf(*elf_header)) { |
+ map_wrapper->Set(obj_base, st.st_size); |
+ if (!IsValidElf(*map_wrapper)) { |
fprintf(stderr, "Not a valid ELF file: %s\n", obj_file.c_str()); |
return false; |
} |
@@ -542,9 +538,9 @@ bool LoadSymbols(const string& obj_file, |
const Shdr* sections = |
GetOffset<ElfClass, Shdr>(elf_header, elf_header->e_shoff); |
const Shdr* section_names = sections + elf_header->e_shstrndx; |
- const char* names = |
- GetOffset<ElfClass, char>(elf_header, section_names->sh_offset); |
- const char *names_end = names + section_names->sh_size; |
+ MemoryRange names( |
+ GetOffset<ElfClass, char>(elf_header, section_names->sh_offset), |
+ section_names->sh_size); |
bool found_debug_info_section = false; |
bool found_usable_info = false; |
@@ -553,8 +549,7 @@ bool LoadSymbols(const string& obj_file, |
// Look for STABS debugging information, and load it if present. |
const Shdr* stab_section = |
FindElfSectionByName<ElfClass>(".stab", SHT_PROGBITS, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
if (stab_section) { |
const Shdr* stabstr_section = stab_section->sh_link + sections; |
if (stabstr_section) { |
@@ -573,8 +568,7 @@ bool LoadSymbols(const string& obj_file, |
// Look for DWARF debugging information, and load it if present. |
const Shdr* dwarf_section = |
FindElfSectionByName<ElfClass>(".debug_info", SHT_PROGBITS, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
if (dwarf_section) { |
found_debug_info_section = true; |
found_usable_info = true; |
@@ -592,8 +586,7 @@ bool LoadSymbols(const string& obj_file, |
// the other DWARF debugging information, and can be used alone. |
const Shdr* dwarf_cfi_section = |
FindElfSectionByName<ElfClass>(".debug_frame", SHT_PROGBITS, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
if (dwarf_cfi_section) { |
// Ignore the return value of this function; even without call frame |
// information, the other debugging information could be perfectly |
@@ -610,19 +603,16 @@ bool LoadSymbols(const string& obj_file, |
// unwinding data. |
const Shdr* eh_frame_section = |
FindElfSectionByName<ElfClass>(".eh_frame", SHT_PROGBITS, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
if (eh_frame_section) { |
// Pointers in .eh_frame data may be relative to the base addresses of |
// certain sections. Provide those sections if present. |
const Shdr* got_section = |
FindElfSectionByName<ElfClass>(".got", SHT_PROGBITS, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
const Shdr* text_section = |
FindElfSectionByName<ElfClass>(".text", SHT_PROGBITS, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
info->LoadedSection(".eh_frame"); |
// As above, ignore the return value of this function. |
bool result = |
@@ -643,7 +633,7 @@ bool LoadSymbols(const string& obj_file, |
const Shdr* gnu_debuglink_section |
= FindElfSectionByName<ElfClass>(".gnu_debuglink", SHT_PROGBITS, |
sections, names, |
- names_end, elf_header->e_shnum); |
+ elf_header->e_shnum); |
if (gnu_debuglink_section) { |
if (!info->debug_dirs().empty()) { |
const char* debuglink_contents = |
@@ -668,12 +658,10 @@ bool LoadSymbols(const string& obj_file, |
// See if there are export symbols available. |
const Shdr* dynsym_section = |
FindElfSectionByName<ElfClass>(".dynsym", SHT_DYNSYM, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
const Shdr* dynstr_section = |
FindElfSectionByName<ElfClass>(".dynstr", SHT_STRTAB, |
- sections, names, names_end, |
- elf_header->e_shnum); |
+ sections, names, elf_header->e_shnum); |
if (dynsym_section && dynstr_section) { |
info->LoadedSection(".dynsym"); |
@@ -758,7 +746,7 @@ string BaseFileName(const string &filename) { |
} |
template<typename ElfClass> |
-bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, |
+bool ReadSymbolDataElfClass(const MemoryRange& obj_file, |
const string& obj_filename, |
const std::vector<string>& debug_dirs, |
const DumpOptions& options, |
@@ -766,10 +754,12 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, |
typedef typename ElfClass::Ehdr Ehdr; |
typedef typename ElfClass::Shdr Shdr; |
+ const Ehdr* elf_header = obj_file.GetData<Ehdr>(0); |
+ |
*out_module = NULL; |
unsigned char identifier[16]; |
- if (!google_breakpad::FileID::ElfFileIdentifierFromMappedFile(elf_header, |
+ if (!google_breakpad::FileID::ElfFileIdentifierFromMappedFile(obj_file, |
identifier)) { |
fprintf(stderr, "%s: unable to generate file identifier\n", |
obj_filename.c_str()); |
@@ -804,10 +794,9 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, |
// Load debuglink ELF file. |
fprintf(stderr, "Found debugging info in %s\n", debuglink_file.c_str()); |
MmapWrapper debug_map_wrapper; |
- Ehdr* debug_elf_header = NULL; |
- if (!LoadELF(debuglink_file, &debug_map_wrapper, |
- reinterpret_cast<void**>(&debug_elf_header))) |
+ if (!LoadELF(debuglink_file, &debug_map_wrapper)) |
return false; |
+ const Ehdr* debug_elf_header = debug_map_wrapper.GetData<Ehdr>(0); |
// Sanity checks to make sure everything matches up. |
const char *debug_architecture = |
ElfArchitecture<ElfClass>(debug_elf_header); |
@@ -849,7 +838,7 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, |
namespace google_breakpad { |
// Not explicitly exported, but not static so it can be used in unit tests. |
-bool ReadSymbolDataInternal(const uint8_t* obj_file, |
+bool ReadSymbolDataInternal(const MemoryRange& obj_file, |
const string& obj_filename, |
const std::vector<string>& debug_dirs, |
const DumpOptions& options, |
@@ -861,13 +850,11 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file, |
int elfclass = ElfClass(obj_file); |
if (elfclass == ELFCLASS32) { |
- return ReadSymbolDataElfClass<ElfClass32>( |
- reinterpret_cast<const Elf32_Ehdr*>(obj_file), obj_filename, debug_dirs, |
+ return ReadSymbolDataElfClass<ElfClass32>(obj_file, obj_filename, debug_dirs, |
options, module); |
} |
if (elfclass == ELFCLASS64) { |
- return ReadSymbolDataElfClass<ElfClass64>( |
- reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dirs, |
+ return ReadSymbolDataElfClass<ElfClass64>(obj_file, obj_filename, debug_dirs, |
options, module); |
} |
@@ -892,11 +879,10 @@ bool ReadSymbolData(const string& obj_file, |
const DumpOptions& options, |
Module** module) { |
MmapWrapper map_wrapper; |
- void* elf_header = NULL; |
- if (!LoadELF(obj_file, &map_wrapper, &elf_header)) |
+ if (!LoadELF(obj_file, &map_wrapper)) |
return false; |
- return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header), |
+ return ReadSymbolDataInternal(map_wrapper, |
obj_file, debug_dirs, options, module); |
} |