diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/linux/dump_symbols.cc | 2 | ||||
-rw-r--r-- | src/common/linux/file_id.cc | 2 | ||||
-rw-r--r-- | src/common/md5.c (renamed from src/common/linux/md5.c) | 2 | ||||
-rw-r--r-- | src/common/md5.h (renamed from src/common/linux/md5.h) | 6 | ||||
-rw-r--r-- | src/common/solaris/dump_symbols.cc | 587 | ||||
-rw-r--r-- | src/common/solaris/dump_symbols.h | 49 | ||||
-rw-r--r-- | src/common/solaris/file_id.cc | 13 |
7 files changed, 648 insertions, 13 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 8c211579..bb3f81e9 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -494,7 +494,7 @@ bool WriteModuleInfo(int fd, ElfW(Half) arch, const std::string &obj_file) { size_t slash_pos = obj_file.find_last_of("/"); if (slash_pos != std::string::npos) filename = obj_file.substr(slash_pos + 1); - return WriteFormat(fd, "MODULE Linux %s %s %s\n", arch_name, + return WriteFormat(fd, "MODULE linux %s %s %s\n", arch_name, id_no_dash, filename.c_str()); } return false; diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index f8bb586e..d69d45a9 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -42,7 +42,7 @@ #include <unistd.h> #include "common/linux/file_id.h" -#include "common/linux/md5.h" +#include "common/md5.h" namespace google_breakpad { diff --git a/src/common/linux/md5.c b/src/common/md5.c index 60c1a782..7fc198af 100644 --- a/src/common/linux/md5.c +++ b/src/common/md5.c @@ -15,7 +15,7 @@ #include <string.h> -#include "common/linux/md5.h" +#include "common/md5.h" #ifndef WORDS_BIGENDIAN #define byteReverse(buf, len) /* Nothing */ diff --git a/src/common/linux/md5.h b/src/common/md5.h index 03a13d6f..dbf4893c 100644 --- a/src/common/linux/md5.h +++ b/src/common/md5.h @@ -1,7 +1,7 @@ // Copyright 2007 Google Inc. All Rights Reserved. // Author: liuli@google.com (Liu Li) -#ifndef COMMON_LINUX_MD5_H__ -#define COMMON_LINUX_MD5_H__ +#ifndef COMMON_MD5_H__ +#define COMMON_MD5_H__ #include <stdint.h> @@ -28,4 +28,4 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx); } #endif -#endif // COMMON_LINUX_MD5_H__ +#endif // COMMON_MD5_H__ diff --git a/src/common/solaris/dump_symbols.cc b/src/common/solaris/dump_symbols.cc new file mode 100644 index 00000000..b9fc74f6 --- /dev/null +++ b/src/common/solaris/dump_symbols.cc @@ -0,0 +1,587 @@ +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: Alfred Peng + +#include <demangle.h> +#include <fcntl.h> +#include <gelf.h> +#include <link.h> +#include <sys/mman.h> +#include <stab.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <functional> +#include <vector> + +#include "common/solaris/dump_symbols.h" +#include "common/solaris/file_id.h" +#include "common/solaris/guid_creator.h" +#include "processor/scoped_ptr.h" + +// This namespace contains helper functions. +namespace { + +// Symbol table entry for stabs. Sun CC specific. +struct slist { + // String table index. + unsigned int n_strx; + // Stab type. + unsigned char n_type; + char n_other; + short n_desc; + unsigned long n_value; +}; + +// Infomation of a line. +struct LineInfo { + // Offset from start of the function. + // Load from stab symbol. + GElf_Off rva_to_func; + // Offset from base of the loading binary. + GElf_Off rva_to_base; + // Size of the line. + // The first line: equals to rva_to_func. + // The other lines: the difference of rva_to_func of the line and + // rva_to_func of the previous N_SLINE. + uint32_t size; + // Line number. + uint32_t line_num; +}; + +// Information of a function. +struct FuncInfo { + // Name of the function. + const char *name; + // Offset from the base of the loading address. + GElf_Off rva_to_base; + // Virtual address of the function. + // Load from stab symbol. + GElf_Addr addr; + // Size of the function. + // Equal to rva_to_func of the last function line. + uint32_t size; + // Total size of stack parameters. + uint32_t stack_param_size; + // Line information array. + std::vector<struct LineInfo> line_info; +}; + +// Information of a source file. +struct SourceFileInfo { + // Name of the source file. + const char *name; + // Starting address of the source file. + GElf_Addr addr; + // Id of the source file. + int source_id; + // Functions information. + std::vector<struct FuncInfo> func_info; +}; + +// Information of a symbol table. +// This is the root of all types of symbol. +struct SymbolInfo { + std::vector<struct SourceFileInfo> source_file_info; +}; + +// Stab section name. +const char *kStabName = ".stab"; + +// Stab str section name. +const char *kStabStrName = ".stabstr"; + +// Default buffer lenght for demangle. +const int demangleLen = 2000; + +// Demangle using demangle library on Solaris. +std::string Demangle(const char *mangled) { + int status = 0; + char *demangled = (char *)malloc(demangleLen); + if (!demangled) { + fprintf(stderr, "no enough memory.\n"); + goto out; + } + + if ((status = cplus_demangle(mangled, demangled, demangleLen)) == + DEMANGLE_ESPACE) { + fprintf(stderr, "incorrect demangle.\n"); + goto out; + } + + std::string str(demangled); + free(demangled); + return str; + +out: + return std::string(mangled); +} + +// Find the prefered loading address of the binary. +GElf_Addr GetLoadingAddress(const GElf_Phdr *program_headers, int nheader) { + for (int i = 0; i < nheader; ++i) { + const GElf_Phdr &header = program_headers[i]; + // For executable, it is the PT_LOAD segment with offset to zero. + if (header.p_type == PT_LOAD && header.p_offset == 0) + return header.p_vaddr; + } + // For other types of ELF, return 0. + return 0; +} + +bool WriteFormat(int fd, const char *fmt, ...) { + va_list list; + char buffer[4096]; + ssize_t expected, written; + va_start(list, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, list); + expected = strlen(buffer); + written = write(fd, buffer, strlen(buffer)); + va_end(list); + return expected == written; +} + +bool IsValidElf(const GElf_Ehdr *elf_header) { + return memcmp(elf_header, ELFMAG, SELFMAG) == 0; +} + +static bool FindSectionByName(Elf *elf, const char *name, + int shstrndx, + GElf_Shdr *shdr) { + assert(name != NULL); + + if (strlen(name) == 0) + return false; + + Elf_Scn *scn = NULL; + + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if (gelf_getshdr(scn, shdr) == (GElf_Shdr *)0) { + fprintf(stderr, "failed to read section header: %s\n", elf_errmsg(0)); + return false; + } + + const char *section_name = elf_strptr(elf, shstrndx, shdr->sh_name); + if (!section_name) { + fprintf(stderr, "Section name error: %s\n", elf_errmsg(-1)); + continue; + } + + if (strcmp(section_name, name) == 0) + return true; + } + + return false; +} + +// The parameter size is used for FPO-optimized code, and +// this is all tied up with the debugging data for Windows x86. +// Set it to 0 on Solaris. +int LoadStackParamSize(struct slist *list, + struct slist *list_end, + struct FuncInfo *func_info) { + struct slist *cur_list = list; + int step = 1; + while (cur_list < list_end && cur_list->n_type == N_PSYM) { + ++cur_list; + ++step; + } + + func_info->stack_param_size = 0; + return step; +} + +int LoadLineInfo(struct slist *list, + struct slist *list_end, + struct FuncInfo *func_info) { + struct slist *cur_list = list; + do { + // Skip non line information. + while (cur_list < list_end && cur_list->n_type != N_SLINE) { + // Only exit when got another function, or source file. + if (cur_list->n_type == N_FUN || cur_list->n_type == N_SO) + return cur_list - list; + ++cur_list; + } + struct LineInfo line; + while (cur_list < list_end && cur_list->n_type == N_SLINE) { + line.rva_to_func = cur_list->n_value; + // n_desc is a signed short + line.line_num = (unsigned short)cur_list->n_desc; + func_info->line_info.push_back(line); + ++cur_list; + } + if (cur_list == list_end && cur_list->n_type == N_ENDM) + break; + } while (list < list_end); + + return cur_list - list; +} + +int LoadFuncSymbols(struct slist *list, + struct slist *list_end, + const GElf_Shdr *stabstr_section, + GElf_Word base, + struct SourceFileInfo *source_file_info) { + struct slist *cur_list = list; + assert(cur_list->n_type == N_SO); + ++cur_list; + + source_file_info->func_info.clear(); + while (cur_list < list_end) { + // Go until the function symbol. + while (cur_list < list_end && cur_list->n_type != N_FUN) { + if (cur_list->n_type == N_SO) { + return cur_list - list; + } + ++cur_list; + continue; + } + while (cur_list->n_type == N_FUN) { + struct FuncInfo func_info; + memset(&func_info, 0, sizeof(func_info)); + func_info.name = + reinterpret_cast<char *>(cur_list->n_strx + + stabstr_section->sh_offset + base); + // The n_value field is always 0 from stab generated by Sun CC. + // TODO(Alfred): Find the correct value. + func_info.addr = cur_list->n_value; + ++cur_list; + if (cur_list->n_type != N_ESYM && cur_list->n_type != N_ISYM && + cur_list->n_type != N_FUN) { + // Stack parameter size. + cur_list += LoadStackParamSize(cur_list, list_end, &func_info); + // Line info. + cur_list += LoadLineInfo(cur_list, list_end, &func_info); + } + // Functions in this module should have address bigger than the module + // starting address. + // + // These two values are always 0 with Sun CC. + // TODO(Alfred): Get the correct value or remove the condition statement. + if (func_info.addr >= source_file_info->addr) { + source_file_info->func_info.push_back(func_info); + } + } + } + return cur_list - list; +} + +// Compute size and rva information based on symbols loaded from stab section. +bool ComputeSizeAndRVA(GElf_Addr loading_addr, struct SymbolInfo *symbols) { + std::vector<struct SourceFileInfo> *sorted_files = + &(symbols->source_file_info); + for (size_t i = 0; i < sorted_files->size(); ++i) { + struct SourceFileInfo &source_file = (*sorted_files)[i]; + std::vector<struct FuncInfo> *sorted_functions = &(source_file.func_info); + for (size_t j = 0; j < sorted_functions->size(); ++j) { + struct FuncInfo &func_info = (*sorted_functions)[j]; + assert(func_info.addr >= loading_addr); + func_info.rva_to_base = func_info.addr - loading_addr; + int line_count = func_info.line_info.size(); + func_info.size = + (line_count == 0) ? 0 : + func_info.line_info[line_count - 1].rva_to_func; + // Compute function and line size. + for (size_t k = 0; k < line_count; ++k) { + struct LineInfo &line_info = func_info.line_info[k]; + if (k == 0) { + line_info.size = line_info.rva_to_func; + } else { + line_info.size = + line_info.rva_to_func - func_info.line_info[k - 1].rva_to_func; + } + line_info.rva_to_base = line_info.rva_to_func + func_info.rva_to_base; + } // for each line. + } // for each function. + } // for each source file. + return true; +} + +bool LoadAllSymbols(const GElf_Shdr *stab_section, + const GElf_Shdr *stabstr_section, + GElf_Addr loading_addr, + GElf_Word base, + struct SymbolInfo *symbols) { + if (stab_section == NULL || stabstr_section == NULL) + return false; + + struct slist *lists = + reinterpret_cast<struct slist *>(stab_section->sh_offset + base); + int nstab = stab_section->sh_size / sizeof(struct slist); + int source_id = 0; + // First pass, load all symbols from the object file. + for (int i = 0; i < nstab; ) { + int step = 1; + struct slist *cur_list = lists + i; + if (cur_list->n_type == N_SO) { + // FUNC <address> <size> <param_stack_size> <function> + struct SourceFileInfo source_file_info; + source_file_info.name = + reinterpret_cast<char *>(cur_list->n_strx + + stabstr_section->sh_offset + base); + // The n_value field is always 0 from stab generated by Sun CC. + // TODO(Alfred): Find the correct value. + source_file_info.addr = cur_list->n_value; + if (strchr(source_file_info.name, '.')) + source_file_info.source_id = source_id++; + else + source_file_info.source_id = -1; + step = LoadFuncSymbols(cur_list, lists + nstab - 1, + stabstr_section, base, &source_file_info); + symbols->source_file_info.push_back(source_file_info); + } + i += step; + } + // Second pass, compute the size of functions and lines. + return ComputeSizeAndRVA(loading_addr, symbols); +} + +bool LoadSymbols(Elf *elf, GElf_Ehdr *elf_header, struct SymbolInfo *symbols, + void *obj_base) { + GElf_Word base = reinterpret_cast<GElf_Word>(obj_base); + GElf_Addr loading_addr = GetLoadingAddress( + reinterpret_cast<GElf_Phdr *>(elf_header->e_phoff + base), + elf_header->e_phnum); + + const GElf_Shdr *sections = + reinterpret_cast<GElf_Shdr *>(elf_header->e_shoff + base); + GElf_Shdr stab_section; + if (!FindSectionByName(elf, kStabName, elf_header->e_shstrndx, + &stab_section)) { + fprintf(stderr, "Stab section not found.\n"); + return false; + } + GElf_Shdr stabstr_section; + if (!FindSectionByName(elf, kStabStrName, elf_header->e_shstrndx, + &stabstr_section)) { + fprintf(stderr, "Stabstr section not found.\n"); + return false; + } + + // Load symbols. + return LoadAllSymbols(&stab_section, &stabstr_section, loading_addr, base, symbols); +} + +bool WriteModuleInfo(int fd, GElf_Half arch, const std::string &obj_file) { + const char *arch_name = NULL; + if (arch == EM_386) + arch_name = "x86"; + else if (arch == EM_X86_64) + arch_name = "x86_64"; + else + return false; + + unsigned char identifier[16]; + google_breakpad::FileID file_id(obj_file.c_str()); + if (file_id.ElfFileIdentifier(identifier)) { + char identifier_str[40]; + file_id.ConvertIdentifierToString(identifier, + identifier_str, sizeof(identifier_str)); + std::string filename = obj_file; + size_t slash_pos = obj_file.find_last_of("/"); + if (slash_pos != std::string::npos) + filename = obj_file.substr(slash_pos + 1); + return WriteFormat(fd, "MODULE solaris %s %s %s\n", arch_name, + identifier_str, filename.c_str()); + } + return false; +} + +bool WriteSourceFileInfo(int fd, const struct SymbolInfo &symbols) { + for (size_t i = 0; i < symbols.source_file_info.size(); ++i) { + if (symbols.source_file_info[i].source_id != -1) { + const char *name = symbols.source_file_info[i].name; + if (!WriteFormat(fd, "FILE %d %s\n", + symbols.source_file_info[i].source_id, name)) + return false; + } + } + return true; +} + +bool WriteOneFunction(int fd, int source_id, + const struct FuncInfo &func_info){ + // Discard the ending part of the name. + std::string func_name(func_info.name); + std::string::size_type last_colon = func_name.find_last_of(':'); + if (last_colon != std::string::npos) + func_name = func_name.substr(0, last_colon); + func_name = Demangle(func_name.c_str()); + + if (func_info.size < 0) + return true; + + // rva_to_base could be unsigned long(32 bit) or unsigned long long(64 bit). + if (WriteFormat(fd, "FUNC %llx %d %d %s\n", + (long long)func_info.rva_to_base, + func_info.size, + func_info.stack_param_size, + func_name.c_str())) { + for (size_t i = 0; i < func_info.line_info.size(); ++i) { + const struct LineInfo &line_info = func_info.line_info[i]; + if (!WriteFormat(fd, "%llx %d %d %d\n", + (long long)line_info.rva_to_base, + line_info.size, + line_info.line_num, + source_id)) + return false; + } + return true; + } + return false; +} + +bool WriteFunctionInfo(int fd, const struct SymbolInfo &symbols) { + for (size_t i = 0; i < symbols.source_file_info.size(); ++i) { + const struct SourceFileInfo &file_info = symbols.source_file_info[i]; + for (size_t j = 0; j < file_info.func_info.size(); ++j) { + const struct FuncInfo &func_info = file_info.func_info[j]; + if (!WriteOneFunction(fd, file_info.source_id, func_info)) + return false; + } + } + return true; +} + +bool DumpStabSymbols(int fd, const struct SymbolInfo &symbols) { + return WriteSourceFileInfo(fd, symbols) && + WriteFunctionInfo(fd, symbols); +} + +// +// FDWrapper +// +// Wrapper class to make sure opened file is closed. +// +class FDWrapper { + public: + explicit FDWrapper(int fd) : + fd_(fd) { + } + ~FDWrapper() { + if (fd_ != -1) + close(fd_); + } + int get() { + return fd_; + } + int release() { + int fd = fd_; + fd_ = -1; + return fd; + } + private: + int fd_; +}; + +// +// MmapWrapper +// +// Wrapper class to make sure mapped regions are unmapped. +// +class MmapWrapper { + public: + MmapWrapper(void *mapped_address, size_t mapped_size) : + base_(mapped_address), size_(mapped_size) { + } + ~MmapWrapper() { + if (base_ != NULL) { + assert(size_ > 0); + munmap((char *)base_, size_); + } + } + void release() { + base_ = NULL; + size_ = 0; + } + + private: + void *base_; + size_t size_; +}; + +} // namespace + +namespace google_breakpad { + +class AutoElfEnder { + public: + AutoElfEnder(Elf *elf) : elf_(elf) {} + ~AutoElfEnder() { if (elf_) elf_end(elf_); } + private: + Elf *elf_; +}; + + +bool DumpSymbols::WriteSymbolFile(const std::string &obj_file, int sym_fd) { + if (elf_version(EV_CURRENT) == EV_NONE) { + fprintf(stderr, "elf_version() failed: %s\n", elf_errmsg(0)); + return false; + } + + int obj_fd = open(obj_file.c_str(), O_RDONLY); + if (obj_fd < 0) + return false; + FDWrapper obj_fd_wrapper(obj_fd); + struct stat st; + if (fstat(obj_fd, &st) != 0 && st.st_size <= 0) + return false; + void *obj_base = mmap(NULL, st.st_size, + PROT_READ, MAP_PRIVATE, obj_fd, 0); + if (!obj_base) + return false; + MmapWrapper map_wrapper(obj_base, st.st_size); + GElf_Ehdr elf_header; + Elf *elf = elf_begin(obj_fd, ELF_C_READ, NULL); + AutoElfEnder elfEnder(elf); + + if (gelf_getehdr(elf, &elf_header) == (GElf_Ehdr *)NULL) { + fprintf(stderr, "failed to read elf header: %s\n", elf_errmsg(-1)); + return false; + } + + if (!IsValidElf(&elf_header)) { + fprintf(stderr, "header magic doesn't match\n"); + return false; + } + struct SymbolInfo symbols; + if (!LoadSymbols(elf, &elf_header, &symbols, obj_base)) + return false; + // Write to symbol file. + if (WriteModuleInfo(sym_fd, elf_header.e_machine, obj_file) && + DumpStabSymbols(sym_fd, symbols)) + return true; + + return false; +} + +} // namespace google_breakpad diff --git a/src/common/solaris/dump_symbols.h b/src/common/solaris/dump_symbols.h new file mode 100644 index 00000000..7f4baadc --- /dev/null +++ b/src/common/solaris/dump_symbols.h @@ -0,0 +1,49 @@ +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// dump_symbols.cc: Implements a Solaris stab debugging format dumper. +// +// Author: Alfred Peng + +#ifndef COMMON_SOLARIS_DUMP_SYMBOLS_H__ +#define COMMON_SOLARIS_DUMP_SYMBOLS_H__ + +#include <string> + +namespace google_breakpad { + +class DumpSymbols { + public: + bool WriteSymbolFile(const std::string &obj_file, + int sym_fd); +}; + +} // namespace google_breakpad + +#endif // COMMON_SOLARIS_DUMP_SYMBOLS_H__ diff --git a/src/common/solaris/file_id.cc b/src/common/solaris/file_id.cc index 4bec3ed8..92e7f71f 100644 --- a/src/common/solaris/file_id.cc +++ b/src/common/solaris/file_id.cc @@ -36,8 +36,6 @@ #include <elf.h> #include <fcntl.h> #include <gelf.h> -#include <gnutls/openssl.h> -#include <link.h> #include <sys/mman.h> #include <sys/ksyms.h> #include <stdio.h> @@ -47,6 +45,7 @@ #include <cassert> #include <cstdio> +#include "common/md5.h" #include "common/solaris/file_id.h" #include "common/solaris/message_output.h" #include "google_breakpad/common/minidump_format.h" @@ -130,7 +129,7 @@ static bool FindElfTextSection(int fd, const void *elf_base, } FileID::FileID(const char *path) { - strncpy(path_, path, strlen(path)); + strcpy(path_, path); } class AutoCloser { @@ -160,10 +159,10 @@ bool FileID::ElfFileIdentifier(unsigned char identifier[16]) { int text_size = 0; if (FindElfTextSection(fd, base, &text_section, &text_size)) { - MD5_CTX md5; - MD5_Init(&md5); - MD5_Update(&md5, text_section, text_size); - MD5_Final(identifier, &md5); + MD5Context md5; + MD5Init(&md5); + MD5Update(&md5, (const unsigned char *)text_section, text_size); + MD5Final(identifier, &md5); success = true; } |