15b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// Copyright (c) 2010 Google Inc. 25b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// All rights reserved. 35b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// 45b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// Redistribution and use in source and binary forms, with or without 55b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// modification, are permitted provided that the following conditions are 65b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// met: 75b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// 85b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// * Redistributions of source code must retain the above copyright 95b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// notice, this list of conditions and the following disclaimer. 105b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// * Redistributions in binary form must reproduce the above 115b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// copyright notice, this list of conditions and the following disclaimer 125b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// in the documentation and/or other materials provided with the 135b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// distribution. 145b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// * Neither the name of Google Inc. nor the names of its 155b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// contributors may be used to endorse or promote products derived from 165b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// this software without specific prior written permission. 175b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// 185b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// 305b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// source_line_resolver_base.cc: Implementation of SourceLineResolverBase. 315b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// 325b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// See source_line_resolver_base.h and source_line_resolver_base_types.h for 335b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// more documentation. 345b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// 355b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com// Author: Siyang Xie (lambxsy@google.com) 365b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 375b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include <stdio.h> 385b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include <string.h> 395b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include <sys/stat.h> 405b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 415b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include <map> 425b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include <utility> 435b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 445b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include "google_breakpad/processor/source_line_resolver_base.h" 455b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include "processor/source_line_resolver_base_types.h" 465b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com#include "processor/module_factory.h" 475b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 485b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comusing std::map; 495b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comusing std::make_pair; 505b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 515b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comnamespace google_breakpad { 525b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 535b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comSourceLineResolverBase::SourceLineResolverBase( 545b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ModuleFactory *module_factory) 555b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com : modules_(new ModuleMap), 562d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com corrupt_modules_(new ModuleSet), 57a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com memory_buffers_(new MemoryMap), 585b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com module_factory_(module_factory) { 595b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 605b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 615b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comSourceLineResolverBase::~SourceLineResolverBase() { 625b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ModuleMap::iterator it; 635b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Iterate through ModuleMap and delete all loaded modules. 645b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com for (it = modules_->begin(); it != modules_->end(); ++it) { 655b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Delete individual module. 665b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com delete it->second; 675b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 685b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Delete the map of modules. 695b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com delete modules_; 702d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com modules_ = NULL; 712d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com 722d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com // Delete the set of corrupt modules. 732d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com delete corrupt_modules_; 742d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com corrupt_modules_ = NULL; 755b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 76a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com MemoryMap::iterator iter = memory_buffers_->begin(); 77a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com for (; iter != memory_buffers_->end(); ++iter) { 78a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete [] iter->second; 79a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 80a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com // Delete the map of memory buffers. 81a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete memory_buffers_; 822d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com memory_buffers_ = NULL; 835b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 84a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete module_factory_; 852d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com module_factory_ = NULL; 86a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com} 875b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 882d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.combool SourceLineResolverBase::ReadSymbolFile(const string &map_file, 892d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com char **symbol_data, 902d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com size_t *symbol_data_size) { 912d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (symbol_data == NULL || symbol_data_size == NULL) { 925b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(ERROR) << "Could not Read file into Null memory pointer"; 935b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 945b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 955b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 965b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com struct stat buf; 975b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com int error_code = stat(map_file.c_str(), &buf); 985b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (error_code == -1) { 995b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com string error_string; 1004fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org error_code = ErrnoString(&error_string); 1015b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(ERROR) << "Could not open " << map_file << 1025b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ", error " << error_code << ": " << error_string; 1035b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1045b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 1055b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1065b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com off_t file_size = buf.st_size; 1075b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1085b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Allocate memory for file contents, plus a null terminator 1095b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // since we may use strtok() on the contents. 1102d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com *symbol_data_size = file_size + 1; 111a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com *symbol_data = new char[file_size + 1]; 1125b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1135b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (*symbol_data == NULL) { 1145b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(ERROR) << "Could not allocate memory for " << map_file; 1155b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1165b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 1175b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1185b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(INFO) << "Opening " << map_file; 1195b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1205b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com FILE *f = fopen(map_file.c_str(), "rt"); 1215b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (!f) { 1225b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com string error_string; 1234fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org error_code = ErrnoString(&error_string); 1245b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(ERROR) << "Could not open " << map_file << 1255b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ", error " << error_code << ": " << error_string; 126a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete [] (*symbol_data); 1275b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com *symbol_data = NULL; 1285b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1295b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 1305b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1315b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com AutoFileCloser closer(f); 1325b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1335b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com int items_read = 0; 1345b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1355b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com items_read = fread(*symbol_data, 1, file_size, f); 1365b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1375b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (items_read != file_size) { 1385b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com string error_string; 1394fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org error_code = ErrnoString(&error_string); 1405b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(ERROR) << "Could not slurp " << map_file << 1415b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ", error " << error_code << ": " << error_string; 142a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete [] (*symbol_data); 1435b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com *symbol_data = NULL; 1445b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1455b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 1465b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1475b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com (*symbol_data)[file_size] = '\0'; 1485b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return true; 1495b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 1505b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1515b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.combool SourceLineResolverBase::LoadModule(const CodeModule *module, 1525b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com const string &map_file) { 1535b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (module == NULL) 1545b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1555b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1565b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Make sure we don't already have a module with the given name. 1575b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (modules_->find(module->code_file()) != modules_->end()) { 1585b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(INFO) << "Symbols for module " << module->code_file() 1595b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com << " already loaded"; 1605b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1615b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 1625b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1635b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(INFO) << "Loading symbols for module " << module->code_file() 1645b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com << " from " << map_file; 1655b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1665b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com char *memory_buffer; 1672d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com size_t memory_buffer_size; 1682d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (!ReadSymbolFile(map_file, &memory_buffer, &memory_buffer_size)) 1695b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 1705b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1715b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(INFO) << "Read symbol file " << map_file << " succeeded"; 1725b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1732d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com bool load_result = LoadModuleUsingMemoryBuffer(module, memory_buffer, 1742d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com memory_buffer_size); 175a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com 176a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (load_result && !ShouldDeleteMemoryBufferAfterLoadModule()) { 177a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com // memory_buffer has to stay alive as long as the module. 178a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com memory_buffers_->insert(make_pair(module->code_file(), memory_buffer)); 179a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } else { 180a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete [] memory_buffer; 181a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 1825b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 183a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com return load_result; 1845b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 1855b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 1865b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.combool SourceLineResolverBase::LoadModuleUsingMapBuffer( 1875b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com const CodeModule *module, const string &map_buffer) { 188a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (module == NULL) 189a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com return false; 190a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com 191a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com // Make sure we don't already have a module with the given name. 192a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (modules_->find(module->code_file()) != modules_->end()) { 193a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com BPLOG(INFO) << "Symbols for module " << module->code_file() 194a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com << " already loaded"; 1955b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 196a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 197a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com 1982d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com size_t memory_buffer_size = map_buffer.size() + 1; 1992d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com char *memory_buffer = new char[memory_buffer_size]; 200a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (memory_buffer == NULL) { 201a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com BPLOG(ERROR) << "Could not allocate memory for " << module->code_file(); 202a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com return false; 203a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 2045b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2055b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Can't use strcpy, as the data may contain '\0's before the end. 2065b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com memcpy(memory_buffer, map_buffer.c_str(), map_buffer.size()); 2075b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com memory_buffer[map_buffer.size()] = '\0'; 2085b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2092d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com bool load_result = LoadModuleUsingMemoryBuffer(module, memory_buffer, 2102d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com memory_buffer_size); 211a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com 212a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (load_result && !ShouldDeleteMemoryBufferAfterLoadModule()) { 213a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com // memory_buffer has to stay alive as long as the module. 214a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com memory_buffers_->insert(make_pair(module->code_file(), memory_buffer)); 215a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } else { 216a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete [] memory_buffer; 217a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 2185b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 219a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com return load_result; 2205b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 2215b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2225b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.combool SourceLineResolverBase::LoadModuleUsingMemoryBuffer( 2232d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com const CodeModule *module, 2242d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com char *memory_buffer, 2252d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com size_t memory_buffer_size) { 226a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (!module) 2275b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 2285b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2295b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Make sure we don't already have a module with the given name. 2305b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (modules_->find(module->code_file()) != modules_->end()) { 2315b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(INFO) << "Symbols for module " << module->code_file() 2325b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com << " already loaded"; 2335b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 2345b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 2355b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2365b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com BPLOG(INFO) << "Loading symbols for module " << module->code_file() 237a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com << " from memory buffer"; 2385b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2395b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com Module *basic_module = module_factory_->CreateModule(module->code_file()); 2405b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2415b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com // Ownership of memory is NOT transfered to Module::LoadMapFromMemory(). 2422d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (!basic_module->LoadMapFromMemory(memory_buffer, memory_buffer_size)) { 2432d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com BPLOG(ERROR) << "Too many error while parsing symbol data for module " 2442d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com << module->code_file(); 2452d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com // Returning false from here would be an indication that the symbols for 2462d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com // this module are missing which would be wrong. Intentionally fall through 2472d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com // and add the module to both the modules_ and the corrupt_modules_ lists. 2482d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com assert(basic_module->IsCorrupt()); 2495b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 2505b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2515b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com modules_->insert(make_pair(module->code_file(), basic_module)); 2522d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (basic_module->IsCorrupt()) { 2532d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com corrupt_modules_->insert(module->code_file()); 2542d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com } 255a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com return true; 256a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com} 257a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com 258a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.combool SourceLineResolverBase::ShouldDeleteMemoryBufferAfterLoadModule() { 2595b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return true; 2605b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 2615b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2625b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comvoid SourceLineResolverBase::UnloadModule(const CodeModule *code_module) { 2635b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (!code_module) 2645b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return; 2655b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2664fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org ModuleMap::iterator mod_iter = modules_->find(code_module->code_file()); 2674fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org if (mod_iter != modules_->end()) { 2684fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org Module *symbol_module = mod_iter->second; 2695b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com delete symbol_module; 2702d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com corrupt_modules_->erase(mod_iter->first); 2714fd4efe1c615da174abe42f3ca40662bb50763bfthestig@chromium.org modules_->erase(mod_iter); 2725b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 2735b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 274a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (ShouldDeleteMemoryBufferAfterLoadModule()) { 275a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com // No-op. Because we never store any memory buffers. 276a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } else { 277a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com // There may be a buffer stored locally, we need to find and delete it. 278a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com MemoryMap::iterator iter = memory_buffers_->find(code_module->code_file()); 279a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com if (iter != memory_buffers_->end()) { 280a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com delete [] iter->second; 281a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com memory_buffers_->erase(iter); 282a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 283a8c1c466a16ad4c85bfd1ca20ab8fc056d669abeSiyangXie@gmail.com } 2845b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 2855b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2865b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.combool SourceLineResolverBase::HasModule(const CodeModule *module) { 2875b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (!module) 2885b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return false; 2895b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return modules_->find(module->code_file()) != modules_->end(); 2905b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 2915b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 2922d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.combool SourceLineResolverBase::IsModuleCorrupt(const CodeModule *module) { 2932d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com if (!module) 2942d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com return false; 2952d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com return corrupt_modules_->find(module->code_file()) != corrupt_modules_->end(); 2962d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com} 2972d460c37d16a99fd4bcdac045298e87b6b5735b0ivan.penkov@gmail.com 2985b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comvoid SourceLineResolverBase::FillSourceLineInfo(StackFrame *frame) { 2995b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (frame->module) { 3005b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); 3015b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (it != modules_->end()) { 3025b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com it->second->LookupAddress(frame); 3035b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 3045b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 3055b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 3065b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 3075b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comWindowsFrameInfo *SourceLineResolverBase::FindWindowsFrameInfo( 3085b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com const StackFrame *frame) { 3095b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (frame->module) { 3105b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); 3115b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (it != modules_->end()) { 3125b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return it->second->FindWindowsFrameInfo(frame); 3135b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 3145b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 3155b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return NULL; 3165b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 3175b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 3185b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.comCFIFrameInfo *SourceLineResolverBase::FindCFIFrameInfo( 3195b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com const StackFrame *frame) { 3205b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (frame->module) { 3215b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com ModuleMap::const_iterator it = modules_->find(frame->module->code_file()); 3225b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com if (it != modules_->end()) { 3235b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return it->second->FindCFIFrameInfo(frame); 3245b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 3255b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com } 3265b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return NULL; 3275b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 3285b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 3295b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.combool SourceLineResolverBase::CompareString::operator()( 3305b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com const string &s1, const string &s2) const { 3315b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return strcmp(s1.c_str(), s2.c_str()) < 0; 3325b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 3335b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 3345b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.combool SourceLineResolverBase::Module::ParseCFIRuleSet( 3355b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com const string &rule_set, CFIFrameInfo *frame_info) const { 3365b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com CFIFrameInfoParseHandler handler(frame_info); 3375b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com CFIRuleParser parser(&handler); 3385b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com return parser.Parse(rule_set); 3395b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} 3405b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com 3415b117cf53af46f357d28761ced3a1d94aeb5df91SiyangXie@gmail.com} // namespace google_breakpad 342