Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: src/common/linux/dump_symbols.cc

Issue 1605153004: unittests: fix -Wnarrowing build errors (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: back to stdint.h Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/common/dwarf_cu_to_module_unittest.cc ('k') | src/common/mac/dump_syms.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 Google Inc. 1 // Copyright (c) 2011 Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 21 matching lines...) Expand all
32 // dump_symbols.cc: implement google_breakpad::WriteSymbolFile: 32 // dump_symbols.cc: implement google_breakpad::WriteSymbolFile:
33 // Find all the debugging info in a file and dump it as a Breakpad symbol file. 33 // Find all the debugging info in a file and dump it as a Breakpad symbol file.
34 34
35 #include "common/linux/dump_symbols.h" 35 #include "common/linux/dump_symbols.h"
36 36
37 #include <assert.h> 37 #include <assert.h>
38 #include <elf.h> 38 #include <elf.h>
39 #include <errno.h> 39 #include <errno.h>
40 #include <fcntl.h> 40 #include <fcntl.h>
41 #include <link.h> 41 #include <link.h>
42 #include <stdint.h>
42 #include <stdio.h> 43 #include <stdio.h>
43 #include <stdlib.h> 44 #include <stdlib.h>
44 #include <string.h> 45 #include <string.h>
45 #include <sys/mman.h> 46 #include <sys/mman.h>
46 #include <sys/stat.h> 47 #include <sys/stat.h>
47 #include <unistd.h> 48 #include <unistd.h>
48 49
49 #include <iostream> 50 #include <iostream>
50 #include <set> 51 #include <set>
51 #include <string> 52 #include <string>
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // dwarf2reader::LineInfo and populates a Module and a line vector 214 // dwarf2reader::LineInfo and populates a Module and a line vector
214 // with the results. 215 // with the results.
215 class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler { 216 class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler {
216 public: 217 public:
217 // Create a line-to-module converter using BYTE_READER. 218 // Create a line-to-module converter using BYTE_READER.
218 explicit DumperLineToModule(dwarf2reader::ByteReader *byte_reader) 219 explicit DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
219 : byte_reader_(byte_reader) { } 220 : byte_reader_(byte_reader) { }
220 void StartCompilationUnit(const string& compilation_dir) { 221 void StartCompilationUnit(const string& compilation_dir) {
221 compilation_dir_ = compilation_dir; 222 compilation_dir_ = compilation_dir;
222 } 223 }
223 void ReadProgram(const char* program, uint64 length, 224 void ReadProgram(const uint8_t *program, uint64 length,
224 Module* module, std::vector<Module::Line>* lines) { 225 Module* module, std::vector<Module::Line>* lines) {
225 DwarfLineToModule handler(module, compilation_dir_, lines); 226 DwarfLineToModule handler(module, compilation_dir_, lines);
226 dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); 227 dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
227 parser.Start(); 228 parser.Start();
228 } 229 }
229 private: 230 private:
230 string compilation_dir_; 231 string compilation_dir_;
231 dwarf2reader::ByteReader *byte_reader_; 232 dwarf2reader::ByteReader *byte_reader_;
232 }; 233 };
233 234
(...skipping 17 matching lines...) Expand all
251 // Build a map of the ELF file's sections. 252 // Build a map of the ELF file's sections.
252 const Shdr* sections = 253 const Shdr* sections =
253 GetOffset<ElfClass, Shdr>(elf_header, elf_header->e_shoff); 254 GetOffset<ElfClass, Shdr>(elf_header, elf_header->e_shoff);
254 int num_sections = elf_header->e_shnum; 255 int num_sections = elf_header->e_shnum;
255 const Shdr* section_names = sections + elf_header->e_shstrndx; 256 const Shdr* section_names = sections + elf_header->e_shstrndx;
256 for (int i = 0; i < num_sections; i++) { 257 for (int i = 0; i < num_sections; i++) {
257 const Shdr* section = &sections[i]; 258 const Shdr* section = &sections[i];
258 string name = GetOffset<ElfClass, char>(elf_header, 259 string name = GetOffset<ElfClass, char>(elf_header,
259 section_names->sh_offset) + 260 section_names->sh_offset) +
260 section->sh_name; 261 section->sh_name;
261 const char* contents = GetOffset<ElfClass, char>(elf_header, 262 const uint8_t *contents = GetOffset<ElfClass, uint8_t>(elf_header,
262 section->sh_offset); 263 section->sh_offset);
263 file_context.AddSectionToSectionMap(name, contents, section->sh_size); 264 file_context.AddSectionToSectionMap(name, contents, section->sh_size);
264 } 265 }
265 266
266 // Parse all the compilation units in the .debug_info section. 267 // Parse all the compilation units in the .debug_info section.
267 DumperLineToModule line_to_module(&byte_reader); 268 DumperLineToModule line_to_module(&byte_reader);
268 dwarf2reader::SectionMap::const_iterator debug_info_entry = 269 dwarf2reader::SectionMap::const_iterator debug_info_entry =
269 file_context.section_map().find(".debug_info"); 270 file_context.section_map().find(".debug_info");
270 assert(debug_info_entry != file_context.section_map().end()); 271 assert(debug_info_entry != file_context.section_map().end());
271 const std::pair<const char*, uint64>& debug_info_section = 272 const std::pair<const uint8_t *, uint64>& debug_info_section =
272 debug_info_entry->second; 273 debug_info_entry->second;
273 // This should never have been called if the file doesn't have a 274 // This should never have been called if the file doesn't have a
274 // .debug_info section. 275 // .debug_info section.
275 assert(debug_info_section.first); 276 assert(debug_info_section.first);
276 uint64 debug_info_length = debug_info_section.second; 277 uint64 debug_info_length = debug_info_section.second;
277 for (uint64 offset = 0; offset < debug_info_length;) { 278 for (uint64 offset = 0; offset < debug_info_length;) {
278 // Make a handler for the root DIE that populates MODULE with the 279 // Make a handler for the root DIE that populates MODULE with the
279 // data that was found. 280 // data that was found.
280 DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset); 281 DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset);
281 DwarfCUToModule root_handler(&file_context, &line_to_module, &reporter); 282 DwarfCUToModule root_handler(&file_context, &line_to_module, &reporter);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 fprintf(stderr, "%s: unrecognized ELF machine architecture '%d';" 339 fprintf(stderr, "%s: unrecognized ELF machine architecture '%d';"
339 " cannot convert DWARF call frame information\n", 340 " cannot convert DWARF call frame information\n",
340 dwarf_filename.c_str(), elf_header->e_machine); 341 dwarf_filename.c_str(), elf_header->e_machine);
341 return false; 342 return false;
342 } 343 }
343 344
344 const dwarf2reader::Endianness endianness = big_endian ? 345 const dwarf2reader::Endianness endianness = big_endian ?
345 dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE; 346 dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE;
346 347
347 // Find the call frame information and its size. 348 // Find the call frame information and its size.
348 const char* cfi = 349 const uint8_t *cfi =
349 GetOffset<ElfClass, char>(elf_header, section->sh_offset); 350 GetOffset<ElfClass, uint8_t>(elf_header, section->sh_offset);
350 size_t cfi_size = section->sh_size; 351 size_t cfi_size = section->sh_size;
351 352
352 // Plug together the parser, handler, and their entourages. 353 // Plug together the parser, handler, and their entourages.
353 DwarfCFIToModule::Reporter module_reporter(dwarf_filename, section_name); 354 DwarfCFIToModule::Reporter module_reporter(dwarf_filename, section_name);
354 DwarfCFIToModule handler(module, register_names, &module_reporter); 355 DwarfCFIToModule handler(module, register_names, &module_reporter);
355 dwarf2reader::ByteReader byte_reader(endianness); 356 dwarf2reader::ByteReader byte_reader(endianness);
356 357
357 byte_reader.SetAddressSize(ElfClass::kAddrSize); 358 byte_reader.SetAddressSize(ElfClass::kAddrSize);
358 359
359 // Provide the base addresses for .eh_frame encoded pointers, if 360 // Provide the base addresses for .eh_frame encoded pointers, if
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 // two absolute paths are the same. 427 // two absolute paths are the same.
427 bool IsSameFile(const char* left_abspath, const string& right_path) { 428 bool IsSameFile(const char* left_abspath, const string& right_path) {
428 char right_abspath[PATH_MAX]; 429 char right_abspath[PATH_MAX];
429 if (!realpath(right_path.c_str(), right_abspath)) 430 if (!realpath(right_path.c_str(), right_abspath))
430 return false; 431 return false;
431 return strcmp(left_abspath, right_abspath) == 0; 432 return strcmp(left_abspath, right_abspath) == 0;
432 } 433 }
433 434
434 // Read the .gnu_debuglink and get the debug file name. If anything goes 435 // Read the .gnu_debuglink and get the debug file name. If anything goes
435 // wrong, return an empty string. 436 // wrong, return an empty string.
436 string ReadDebugLink(const char* debuglink, 437 string ReadDebugLink(const uint8_t *debuglink,
437 const size_t debuglink_size, 438 const size_t debuglink_size,
438 const bool big_endian, 439 const bool big_endian,
439 const string& obj_file, 440 const string& obj_file,
440 const std::vector<string>& debug_dirs) { 441 const std::vector<string>& debug_dirs) {
441 size_t debuglink_len = strlen(debuglink) + 5; // Include '\0' + CRC32. 442 // Include '\0' + CRC32 (4 bytes).
443 size_t debuglink_len = strlen(reinterpret_cast<const char *>(debuglink)) + 5;
442 debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round up to 4 bytes. 444 debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round up to 4 bytes.
443 445
444 // Sanity check. 446 // Sanity check.
445 if (debuglink_len != debuglink_size) { 447 if (debuglink_len != debuglink_size) {
446 fprintf(stderr, "Mismatched .gnu_debuglink string / section size: " 448 fprintf(stderr, "Mismatched .gnu_debuglink string / section size: "
447 "%zx %zx\n", debuglink_len, debuglink_size); 449 "%zx %zx\n", debuglink_len, debuglink_size);
448 return string(); 450 return string();
449 } 451 }
450 452
451 char obj_file_abspath[PATH_MAX]; 453 char obj_file_abspath[PATH_MAX];
452 if (!realpath(obj_file.c_str(), obj_file_abspath)) { 454 if (!realpath(obj_file.c_str(), obj_file_abspath)) {
453 fprintf(stderr, "Cannot resolve absolute path for %s\n", obj_file.c_str()); 455 fprintf(stderr, "Cannot resolve absolute path for %s\n", obj_file.c_str());
454 return string(); 456 return string();
455 } 457 }
456 458
457 std::vector<string> searched_paths; 459 std::vector<string> searched_paths;
458 string debuglink_path; 460 string debuglink_path;
459 std::vector<string>::const_iterator it; 461 std::vector<string>::const_iterator it;
460 for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) { 462 for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
461 const string& debug_dir = *it; 463 const string& debug_dir = *it;
462 debuglink_path = debug_dir + "/" + debuglink; 464 debuglink_path = debug_dir + "/" +
465 reinterpret_cast<const char *>(debuglink);
463 466
464 // There is the annoying case of /path/to/foo.so having foo.so as the 467 // There is the annoying case of /path/to/foo.so having foo.so as the
465 // debug link file name. Thus this may end up opening /path/to/foo.so again, 468 // debug link file name. Thus this may end up opening /path/to/foo.so again,
466 // and there is a small chance of the two files having the same CRC. 469 // and there is a small chance of the two files having the same CRC.
467 if (IsSameFile(obj_file_abspath, debuglink_path)) 470 if (IsSameFile(obj_file_abspath, debuglink_path))
468 continue; 471 continue;
469 472
470 searched_paths.push_back(debug_dir); 473 searched_paths.push_back(debug_dir);
471 int debuglink_fd = open(debuglink_path.c_str(), O_RDONLY); 474 int debuglink_fd = open(debuglink_path.c_str(), O_RDONLY);
472 if (debuglink_fd < 0) 475 if (debuglink_fd < 0)
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 obj_file.c_str()); 765 obj_file.c_str());
763 766
764 // Failed, but maybe there's a .gnu_debuglink section? 767 // Failed, but maybe there's a .gnu_debuglink section?
765 if (read_gnu_debug_link) { 768 if (read_gnu_debug_link) {
766 const Shdr* gnu_debuglink_section 769 const Shdr* gnu_debuglink_section
767 = FindElfSectionByName<ElfClass>(".gnu_debuglink", SHT_PROGBITS, 770 = FindElfSectionByName<ElfClass>(".gnu_debuglink", SHT_PROGBITS,
768 sections, names, 771 sections, names,
769 names_end, elf_header->e_shnum); 772 names_end, elf_header->e_shnum);
770 if (gnu_debuglink_section) { 773 if (gnu_debuglink_section) {
771 if (!info->debug_dirs().empty()) { 774 if (!info->debug_dirs().empty()) {
772 const char* debuglink_contents = 775 const uint8_t *debuglink_contents =
773 GetOffset<ElfClass, char>(elf_header, 776 GetOffset<ElfClass, uint8_t>(elf_header,
774 gnu_debuglink_section->sh_offset); 777 gnu_debuglink_section->sh_offset);
775 string debuglink_file = 778 string debuglink_file =
776 ReadDebugLink(debuglink_contents, 779 ReadDebugLink(debuglink_contents,
777 gnu_debuglink_section->sh_size, 780 gnu_debuglink_section->sh_size,
778 big_endian, 781 big_endian,
779 obj_file, 782 obj_file,
780 info->debug_dirs()); 783 info->debug_dirs());
781 info->set_debuglink_file(debuglink_file); 784 info->set_debuglink_file(debuglink_file);
782 } else { 785 } else {
783 fprintf(stderr, ".gnu_debuglink section found in '%s', " 786 fprintf(stderr, ".gnu_debuglink section found in '%s', "
784 "but no debug path specified.\n", obj_file.c_str()); 787 "but no debug path specified.\n", obj_file.c_str());
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 MmapWrapper map_wrapper; 1000 MmapWrapper map_wrapper;
998 void* elf_header = NULL; 1001 void* elf_header = NULL;
999 if (!LoadELF(obj_file, &map_wrapper, &elf_header)) 1002 if (!LoadELF(obj_file, &map_wrapper, &elf_header))
1000 return false; 1003 return false;
1001 1004
1002 return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header), 1005 return ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(elf_header),
1003 obj_file, debug_dirs, options, module); 1006 obj_file, debug_dirs, options, module);
1004 } 1007 }
1005 1008
1006 } // namespace google_breakpad 1009 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « src/common/dwarf_cu_to_module_unittest.cc ('k') | src/common/mac/dump_syms.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698