aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/dump_symbols.cc
diff options
context:
space:
mode:
authorted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-22 13:36:39 +0000
committerted.mielczarek@gmail.com <ted.mielczarek@gmail.com@4c0a9323-5329-0410-9bdc-e9ce6186880e>2013-01-22 13:36:39 +0000
commitc6f6d9ef308b7651b9dc8f4027fc9705cd9a93b7 (patch)
treeec8c3c1e1b22e4e62e4baf1630e98f14e061b338 /src/common/linux/dump_symbols.cc
parentRemove <(library) usage from gyp files. (diff)
downloadbreakpad-c6f6d9ef308b7651b9dc8f4027fc9705cd9a93b7.tar.xz
Make DumpSymbols methods take a vector of debug_dirs
r=thestig at https://breakpad.appspot.com/512002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1102 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/linux/dump_symbols.cc')
-rw-r--r--src/common/linux/dump_symbols.cc56
1 files changed, 35 insertions, 21 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index bcb39ca7..4a85ab8f 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -387,7 +387,7 @@ template<typename ElfClass>
string ReadDebugLink(const char* debuglink,
size_t debuglink_size,
const string& obj_file,
- const string& debug_dir) {
+ const std::vector<string>& debug_dirs) {
size_t debuglink_len = strlen(debuglink) + 5; // '\0' + CRC32.
debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round to nearest 4 bytes.
@@ -398,13 +398,26 @@ string ReadDebugLink(const char* debuglink,
return "";
}
- string debuglink_path = debug_dir + "/" + debuglink;
- int debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
- if (debuglink_fd < 0) {
+ bool found = false;
+ int debuglink_fd = -1;
+ string debuglink_path;
+ std::vector<string>::const_iterator it;
+ for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
+ const string& debug_dir = *it;
+ debuglink_path = debug_dir + "/" + debuglink;
+ debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
+ if (debuglink_fd >= 0) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
fprintf(stderr, "Failed to open debug ELF file '%s' for '%s': %s\n",
debuglink_path.c_str(), obj_file.c_str(), strerror(errno));
return "";
}
+
FDWrapper debuglink_fd_wrapper(debuglink_fd);
// TODO(thestig) check the CRC-32 at the end of the .gnu_debuglink
// section.
@@ -424,8 +437,8 @@ class LoadSymbolsInfo {
public:
typedef typename ElfClass::Addr Addr;
- explicit LoadSymbolsInfo(const string &dbg_dir) :
- debug_dir_(dbg_dir),
+ explicit LoadSymbolsInfo(const std::vector<string>& dbg_dirs) :
+ debug_dirs_(dbg_dirs),
has_loading_addr_(false) {}
// Keeps track of which sections have been loaded so sections don't
@@ -458,8 +471,8 @@ class LoadSymbolsInfo {
}
// Setters and getters
- const string &debug_dir() const {
- return debug_dir_;
+ const std::vector<string>& debug_dirs() const {
+ return debug_dirs_;
}
string debuglink_file() const {
@@ -470,7 +483,8 @@ class LoadSymbolsInfo {
}
private:
- const string &debug_dir_; // Directory with the debug ELF file.
+ const std::vector<string>& debug_dirs_; // Directories in which to
+ // search for the debug ELF file.
string debuglink_file_; // Full path to the debug ELF file.
@@ -601,14 +615,14 @@ bool LoadSymbols(const string& obj_file,
sections, names,
names_end, elf_header->e_shnum);
if (gnu_debuglink_section) {
- if (!info->debug_dir().empty()) {
+ if (!info->debug_dirs().empty()) {
const char* debuglink_contents =
GetOffset<ElfClass, char>(elf_header,
gnu_debuglink_section->sh_offset);
string debuglink_file
= ReadDebugLink<ElfClass>(debuglink_contents,
gnu_debuglink_section->sh_size,
- obj_file, info->debug_dir());
+ obj_file, info->debug_dirs());
info->set_debuglink_file(debuglink_file);
} else {
fprintf(stderr, ".gnu_debuglink section found in '%s', "
@@ -712,7 +726,7 @@ string BaseFileName(const string &filename) {
template<typename ElfClass>
bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
const string& obj_filename,
- const string& debug_dir,
+ const std::vector<string>& debug_dirs,
bool cfi,
Module** out_module) {
typedef typename ElfClass::Ehdr Ehdr;
@@ -744,10 +758,10 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
string os = "Linux";
string id = FormatIdentifier(identifier);
- LoadSymbolsInfo<ElfClass> info(debug_dir);
+ LoadSymbolsInfo<ElfClass> info(debug_dirs);
scoped_ptr<Module> module(new Module(name, os, architecture, id));
if (!LoadSymbols<ElfClass>(obj_filename, big_endian, elf_header,
- !debug_dir.empty(), &info, module.get())) {
+ !debug_dirs.empty(), &info, module.get())) {
const string debuglink_file = info.debuglink_file();
if (debuglink_file.empty())
return false;
@@ -801,7 +815,7 @@ namespace google_breakpad {
// Not explicitly exported, but not static so it can be used in unit tests.
bool ReadSymbolDataInternal(const uint8_t* obj_file,
const string& obj_filename,
- const string& debug_dir,
+ const std::vector<string>& debug_dirs,
bool cfi,
Module** module) {
@@ -813,12 +827,12 @@ 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_dir,
+ reinterpret_cast<const Elf32_Ehdr*>(obj_file), obj_filename, debug_dirs,
cfi, module);
}
if (elfclass == ELFCLASS64) {
return ReadSymbolDataElfClass<ElfClass64>(
- reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dir,
+ reinterpret_cast<const Elf64_Ehdr*>(obj_file), obj_filename, debug_dirs,
cfi, module);
}
@@ -826,11 +840,11 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file,
}
bool WriteSymbolFile(const string &obj_file,
- const string &debug_dir,
+ const std::vector<string>& debug_dirs,
bool cfi,
std::ostream &sym_stream) {
Module* module;
- if (!ReadSymbolData(obj_file, debug_dir, cfi, &module))
+ if (!ReadSymbolData(obj_file, debug_dirs, cfi, &module))
return false;
bool result = module->Write(sym_stream, cfi);
@@ -839,7 +853,7 @@ bool WriteSymbolFile(const string &obj_file,
}
bool ReadSymbolData(const string& obj_file,
- const string& debug_dir,
+ const std::vector<string>& debug_dirs,
bool cfi,
Module** module) {
MmapWrapper map_wrapper;
@@ -848,7 +862,7 @@ bool ReadSymbolData(const string& obj_file,
return false;
return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header),
- obj_file, debug_dir, cfi, module);
+ obj_file, debug_dirs, cfi, module);
}
} // namespace google_breakpad