aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux')
-rw-r--r--src/common/linux/breakpad_getcontext.S171
-rw-r--r--src/common/linux/breakpad_getcontext.h5
-rw-r--r--src/common/linux/breakpad_getcontext_unittest.cc24
-rw-r--r--src/common/linux/crc32.cc5
-rw-r--r--src/common/linux/crc32.h5
-rw-r--r--src/common/linux/dump_symbols.cc328
-rw-r--r--src/common/linux/dump_symbols.h24
-rw-r--r--src/common/linux/dump_symbols_unittest.cc11
-rw-r--r--src/common/linux/eintr_wrapper.h5
-rw-r--r--src/common/linux/elf_core_dump.cc33
-rw-r--r--src/common/linux/elf_core_dump.h13
-rw-r--r--src/common/linux/elf_core_dump_unittest.cc15
-rw-r--r--src/common/linux/elf_gnu_compat.h5
-rw-r--r--src/common/linux/elf_symbols_to_module.cc29
-rw-r--r--src/common/linux/elf_symbols_to_module.h10
-rw-r--r--src/common/linux/elf_symbols_to_module_unittest.cc19
-rw-r--r--src/common/linux/elfutils-inl.h5
-rw-r--r--src/common/linux/elfutils.cc33
-rw-r--r--src/common/linux/elfutils.h48
-rw-r--r--src/common/linux/file_id.cc13
-rw-r--r--src/common/linux/file_id.h7
-rw-r--r--src/common/linux/file_id_unittest.cc34
-rw-r--r--src/common/linux/google_crashdump_uploader.cc41
-rw-r--r--src/common/linux/google_crashdump_uploader.h15
-rw-r--r--src/common/linux/google_crashdump_uploader_test.cc77
-rw-r--r--src/common/linux/guid_creator.cc13
-rw-r--r--src/common/linux/guid_creator.h5
-rw-r--r--src/common/linux/http_upload.cc61
-rw-r--r--src/common/linux/http_upload.h29
-rw-r--r--src/common/linux/ignore_ret.h5
-rw-r--r--src/common/linux/libcurl_wrapper.cc20
-rw-r--r--src/common/linux/libcurl_wrapper.h35
-rw-r--r--src/common/linux/linux_libc_support.cc7
-rw-r--r--src/common/linux/linux_libc_support.h5
-rw-r--r--src/common/linux/linux_libc_support_unittest.cc5
-rw-r--r--src/common/linux/memory_mapped_file.cc13
-rw-r--r--src/common/linux/memory_mapped_file.h5
-rw-r--r--src/common/linux/memory_mapped_file_unittest.cc5
-rw-r--r--src/common/linux/safe_readlink.cc5
-rw-r--r--src/common/linux/safe_readlink.h5
-rw-r--r--src/common/linux/safe_readlink_unittest.cc5
-rw-r--r--src/common/linux/symbol_collector_client.cc5
-rw-r--r--src/common/linux/symbol_collector_client.h5
-rw-r--r--src/common/linux/symbol_upload.cc15
-rw-r--r--src/common/linux/symbol_upload.h5
-rw-r--r--src/common/linux/synth_elf.cc4
-rw-r--r--src/common/linux/synth_elf.h9
-rw-r--r--src/common/linux/synth_elf_unittest.cc9
-rw-r--r--src/common/linux/tests/auto_testfile.h5
-rw-r--r--src/common/linux/tests/crash_generator.cc16
-rw-r--r--src/common/linux/tests/crash_generator.h9
-rw-r--r--src/common/linux/ucontext_constants.h106
52 files changed, 913 insertions, 473 deletions
diff --git a/src/common/linux/breakpad_getcontext.S b/src/common/linux/breakpad_getcontext.S
index fea0109d..286047bf 100644
--- a/src/common/linux/breakpad_getcontext.S
+++ b/src/common/linux/breakpad_getcontext.S
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -32,7 +31,7 @@
#include "common/linux/ucontext_constants.h"
-/* int getcontext (ucontext_t *ucp) */
+/* int getcontext (ucontext_t* ucp) */
#if defined(__arm__)
@@ -90,6 +89,47 @@ breakpad_getcontext:
#elif defined(__aarch64__)
+#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT
+ // ENABLE_PAUTH must be defined to 1 since this value will be used in
+ // bitwise-shift later!
+ #define ENABLE_PAUTH 1
+
+ #if ((__ARM_FEATURE_PAC_DEFAULT&((1<<0)|(1<<1)))==0)
+ #error Pointer authentication defines no valid key!
+ #endif
+#else
+ #define ENABLE_PAUTH 0
+#endif
+
+#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT==1)
+ // ENABLE_BTI must be defined to 1 since this value will be used in
+ // bitwise-shift later!
+ #define ENABLE_BTI 1
+#else
+ #define ENABLE_BTI 0
+#endif
+
+
+// Although Pointer Authentication and Branch Target Instructions are technically
+// seperate features they work together, i.e. the paciasp and pacibsp instructions
+// serve as BTI landing pads.
+// Therefore PA-instructions are enabled when PA _or_ BTI is enabled!
+#if ENABLE_PAUTH || ENABLE_BTI
+ // See section "Pointer Authentication" of
+ // https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros
+ // for details how to interpret __ARM_FEATURE_PAC_DEFAULT
+ #if (__ARM_FEATURE_PAC_DEFAULT & (1<<0))
+ #define PAUTH_SIGN_SP paciasp
+ #define PAUTH_AUTH_SP autiasp
+ #else
+ #define PAUTH_SIGN_SP pacibsp
+ #define PAUTH_AUTH_SP autibsp
+ #endif
+#else
+ #define PAUTH_SIGN_SP
+ #define PAUTH_AUTH_SP
+#endif
+
#define _NSIG 64
#define __NR_rt_sigprocmask 135
@@ -101,6 +141,8 @@ breakpad_getcontext:
.cfi_startproc
breakpad_getcontext:
+ PAUTH_SIGN_SP
+
/* The saved context will return to the getcontext() call point
with a return value of 0 */
str xzr, [x0, MCONTEXT_GREGS_OFFSET + 0 * REGISTER_SIZE]
@@ -170,6 +212,9 @@ breakpad_getcontext:
/* Return x0 for success */
mov x0, 0
+
+ PAUTH_AUTH_SP
+
ret
.cfi_endproc
@@ -336,7 +381,7 @@ symbol: .frame sp, framesize, rpc;
.size function,.-function
#endif
-/* int getcontext (ucontext_t *ucp) */
+/* int getcontext (ucontext_t* ucp) */
NESTED (breakpad_getcontext, FRAME_SIZE, ra)
.mask 0x10000000, 0
@@ -481,6 +526,120 @@ breakpad_getcontext:
.cfi_endproc
.size breakpad_getcontext, . - breakpad_getcontext
+#elif defined(__riscv)
+
+# define SIG_BLOCK 0
+# define _NSIG8 8
+# define __NR_rt_sigprocmask 135
+
+ .text
+ .globl breakpad_getcontext
+ .type breakpad_getcontext, @function
+ .align 0
+ .cfi_startproc
+breakpad_getcontext:
+ REG_S ra, MCONTEXT_GREGS_PC(a0)
+ REG_S ra, MCONTEXT_GREGS_RA(a0)
+ REG_S sp, MCONTEXT_GREGS_SP(a0)
+ REG_S gp, MCONTEXT_GREGS_SP(a0)
+ REG_S tp, MCONTEXT_GREGS_TP(a0)
+ REG_S t0, MCONTEXT_GREGS_T0(a0)
+ REG_S t1, MCONTEXT_GREGS_T1(a0)
+ REG_S t2, MCONTEXT_GREGS_T2(a0)
+ REG_S s0, MCONTEXT_GREGS_S0(a0)
+ REG_S s1, MCONTEXT_GREGS_S1(a0)
+ REG_S a0, MCONTEXT_GREGS_A0(a0)
+ REG_S a1, MCONTEXT_GREGS_A1(a0)
+ REG_S a2, MCONTEXT_GREGS_A2(a0)
+ REG_S a3, MCONTEXT_GREGS_A3(a0)
+ REG_S a4, MCONTEXT_GREGS_A4(a0)
+ REG_S a5, MCONTEXT_GREGS_A5(a0)
+ REG_S a6, MCONTEXT_GREGS_A6(a0)
+ REG_S a7, MCONTEXT_GREGS_A7(a0)
+ REG_S s2, MCONTEXT_GREGS_S2(a0)
+ REG_S s3, MCONTEXT_GREGS_S3(a0)
+ REG_S s4, MCONTEXT_GREGS_S4(a0)
+ REG_S s5, MCONTEXT_GREGS_S5(a0)
+ REG_S s6, MCONTEXT_GREGS_S6(a0)
+ REG_S s7, MCONTEXT_GREGS_S7(a0)
+ REG_S s8, MCONTEXT_GREGS_S8(a0)
+ REG_S s9, MCONTEXT_GREGS_S9(a0)
+ REG_S s10, MCONTEXT_GREGS_S10(a0)
+ REG_S s11, MCONTEXT_GREGS_S11(a0)
+ REG_S t3, MCONTEXT_GREGS_T3(a0)
+ REG_S t4, MCONTEXT_GREGS_T4(a0)
+ REG_S t5, MCONTEXT_GREGS_T5(a0)
+ REG_S t6 , MCONTEXT_GREGS_T6(a0)
+# ifndef __riscv_float_abi_soft
+ frsr a1
+
+ FREG_S ft0, MCONTEXT_FPREGS_FT0(a0)
+ FREG_S ft1, MCONTEXT_FPREGS_FT1(a0)
+ FREG_S ft2, MCONTEXT_FPREGS_FT2(a0)
+ FREG_S ft3, MCONTEXT_FPREGS_FT3(a0)
+ FREG_S ft4, MCONTEXT_FPREGS_FT4(a0)
+ FREG_S ft5, MCONTEXT_FPREGS_FT5(a0)
+ FREG_S ft6, MCONTEXT_FPREGS_FT6(a0)
+ FREG_S ft7, MCONTEXT_FPREGS_FT7(a0)
+ FREG_S fs0, MCONTEXT_FPREGS_FS0(a0)
+ FREG_S fs1, MCONTEXT_FPREGS_FS1(a0)
+ FREG_S fa0, MCONTEXT_FPREGS_FA0(a0)
+ FREG_S fa1, MCONTEXT_FPREGS_FA1(a0)
+ FREG_S fa2, MCONTEXT_FPREGS_FA2(a0)
+ FREG_S fa3, MCONTEXT_FPREGS_FA3(a0)
+ FREG_S fa4, MCONTEXT_FPREGS_FA4(a0)
+ FREG_S fa5, MCONTEXT_FPREGS_FA5(a0)
+ FREG_S fa6, MCONTEXT_FPREGS_FA6(a0)
+ FREG_S fa7, MCONTEXT_FPREGS_FA7(a0)
+ FREG_S fs2, MCONTEXT_FPREGS_FS2(a0)
+ FREG_S fs3, MCONTEXT_FPREGS_FS3(a0)
+ FREG_S fs4, MCONTEXT_FPREGS_FS4(a0)
+ FREG_S fs5, MCONTEXT_FPREGS_FS5(a0)
+ FREG_S fs6, MCONTEXT_FPREGS_FS6(a0)
+ FREG_S fs7, MCONTEXT_FPREGS_FS7(a0)
+ FREG_S fs8, MCONTEXT_FPREGS_FS8(a0)
+ FREG_S fs9, MCONTEXT_FPREGS_FS9(a0)
+ FREG_S fs10, MCONTEXT_FPREGS_FS10(a0)
+ FREG_S fs11, MCONTEXT_FPREGS_FS11(a0)
+ FREG_S ft8, MCONTEXT_FPREGS_FT8(a0)
+ FREG_S ft9, MCONTEXT_FPREGS_FT9(a0)
+ FREG_S ft10, MCONTEXT_FPREGS_FT10(a0)
+ FREG_S ft11, MCONTEXT_FPREGS_FT11(a0)
+
+ sw a1, MCONTEXT_FPC_CSR(a0)
+# endif // __riscv_float_abi_soft
+ mv a1, zero
+ add a2, a0, UCONTEXT_SIGMASK_OFFSET
+ li a3, _NSIG8
+ mv a0, zero
+ li a7, __NR_rt_sigprocmask
+ ecall
+ mv a0, zero
+ ret
+
+ .cfi_endproc
+ .size breakpad_getcontext, . - breakpad_getcontext
+
#else
-#error "This file has not been ported for your CPU!"
+# error "This file has not been ported for your CPU!"
+#endif
+
+#if defined(__aarch64__)
+// ENABLE_PAUTH and ENABLE_BTI would be enabled at the definition
+// of AArch64 specific breakpad_getcontext function
+#if ENABLE_PAUTH || ENABLE_BTI
+// for further information on the .note.gnu.property section see
+// https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#program-property
+.pushsection .note.gnu.property, "a";
+ .balign 8
+ .long 4
+ .long 0x10
+ .long 0x5
+ .asciz "GNU"
+ .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
+ .long 4
+ .long ((ENABLE_PAUTH)<<1) | ((ENABLE_BTI)<<0) /* PAuth and BTI */
+ .long 0
+.popsection
+#endif
#endif
diff --git a/src/common/linux/breakpad_getcontext.h b/src/common/linux/breakpad_getcontext.h
index 1418cde6..c553219f 100644
--- a/src/common/linux/breakpad_getcontext.h
+++ b/src/common/linux/breakpad_getcontext.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/breakpad_getcontext_unittest.cc b/src/common/linux/breakpad_getcontext_unittest.cc
index a57bfedf..573ddd88 100644
--- a/src/common/linux/breakpad_getcontext_unittest.cc
+++ b/src/common/linux/breakpad_getcontext_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -114,6 +113,25 @@ TEST(AndroidUContext, GRegsOffset) {
ASSERT_EQ(static_cast<size_t>(MCONTEXT_FPC_CSR),
offsetof(ucontext_t,uc_mcontext.fpc_csr));
+#elif defined(__riscv)
+ ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
+ offsetof(ucontext_t,uc_mcontext.__gregs[0]));
+
+#define CHECK_REG(x) \
+ ASSERT_EQ(static_cast<size_t>(MCONTEXT_##x##_OFFSET), \
+ offsetof(ucontext_t,uc_mcontext.__gregs[REG_##x]))
+ CHECK_REG(PC)
+ CHECK_REG(RA)
+ CHECK_REG(SP)
+ CHECK_REG(S0)
+ CHECK_REG(S1)
+ CHECK_REG(S2)
+
+ ASSERT_EQ(static_cast<size_t>(MCONTEXT_FPREGS_OFFSET),
+ offsetof(ucontext_t,uc_mcontext.__fpregs));
+
+ ASSERT_EQ(static_cast<size_t>(MCONTEXT_FPC_CSR),
+ offsetof(ucontext_t,uc_mcontext.__fpregs.__fcsr));
#elif defined(__x86_64__)
COMPILE_ASSERT_EQ(static_cast<size_t>(MCONTEXT_GREGS_OFFSET),
diff --git a/src/common/linux/crc32.cc b/src/common/linux/crc32.cc
index 8df636ce..c02f06c4 100644
--- a/src/common/linux/crc32.cc
+++ b/src/common/linux/crc32.cc
@@ -1,5 +1,4 @@
-// Copyright 2014 Google Inc.
-// All rights reserved.
+// Copyright 2014 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/crc32.h b/src/common/linux/crc32.h
index e3d9db92..7df46999 100644
--- a/src/common/linux/crc32.h
+++ b/src/common/linux/crc32.h
@@ -1,5 +1,4 @@
-// Copyright 2014 Google Inc.
-// All rights reserved.
+// Copyright 2014 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index b7e77ab7..b436f765 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011 Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -47,8 +46,8 @@
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <zlib.h>
-#include <iostream>
#include <set>
#include <string>
#include <utility>
@@ -87,11 +86,11 @@ using google_breakpad::DwarfRangeListHandler;
using google_breakpad::ElfClass;
using google_breakpad::ElfClass32;
using google_breakpad::ElfClass64;
-using google_breakpad::FileID;
+using google_breakpad::elf::FileID;
using google_breakpad::FindElfSectionByName;
using google_breakpad::GetOffset;
using google_breakpad::IsValidElf;
-using google_breakpad::kDefaultBuildIdSize;
+using google_breakpad::elf::kDefaultBuildIdSize;
using google_breakpad::Module;
using google_breakpad::PageAllocator;
#ifndef NO_STABS_SUPPORT
@@ -144,7 +143,7 @@ class MmapWrapper {
munmap(base_, size_);
}
}
- 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;
@@ -228,62 +227,121 @@ bool LoadStabs(const typename ElfClass::Ehdr* elf_header,
#endif // NO_STABS_SUPPORT
// A range handler that accepts rangelist data parsed by
-// dwarf2reader::RangeListReader and populates a range vector (typically
+// google_breakpad::RangeListReader and populates a range vector (typically
// owned by a function) with the results.
class DumperRangesHandler : public DwarfCUToModule::RangesHandler {
public:
- DumperRangesHandler(const uint8_t *buffer, uint64_t size,
- dwarf2reader::ByteReader* reader)
- : buffer_(buffer), size_(size), reader_(reader) { }
-
- bool ReadRanges(uint64_t offset, Module::Address base_address,
- vector<Module::Range>* ranges) {
- DwarfRangeListHandler handler(base_address, ranges);
- dwarf2reader::RangeListReader rangelist_reader(buffer_, size_, reader_,
- &handler);
-
- return rangelist_reader.ReadRangeList(offset);
+ DumperRangesHandler(google_breakpad::ByteReader* reader) :
+ reader_(reader) { }
+
+ bool ReadRanges(
+ enum google_breakpad::DwarfForm form, uint64_t data,
+ google_breakpad::RangeListReader::CURangesInfo* cu_info,
+ vector<Module::Range>* ranges) {
+ DwarfRangeListHandler handler(ranges);
+ google_breakpad::RangeListReader range_list_reader(reader_, cu_info,
+ &handler);
+ return range_list_reader.ReadRanges(form, data);
}
private:
- const uint8_t *buffer_;
- uint64_t size_;
- dwarf2reader::ByteReader* reader_;
+ google_breakpad::ByteReader* reader_;
};
// A line-to-module loader that accepts line number info parsed by
-// dwarf2reader::LineInfo and populates a Module and a line vector
+// google_breakpad::LineInfo and populates a Module and a line vector
// with the results.
class DumperLineToModule: public DwarfCUToModule::LineToModuleHandler {
public:
// Create a line-to-module converter using BYTE_READER.
- explicit DumperLineToModule(dwarf2reader::ByteReader *byte_reader)
+ explicit DumperLineToModule(google_breakpad::ByteReader* byte_reader)
: byte_reader_(byte_reader) { }
void StartCompilationUnit(const string& compilation_dir) {
compilation_dir_ = compilation_dir;
}
- void ReadProgram(const uint8_t *program, uint64_t length,
- Module* module, std::vector<Module::Line>* lines) {
- DwarfLineToModule handler(module, compilation_dir_, lines);
- dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler);
+ void ReadProgram(const uint8_t* program,
+ uint64_t length,
+ const uint8_t* string_section,
+ uint64_t string_section_length,
+ const uint8_t* line_string_section,
+ uint64_t line_string_section_length,
+ Module* module,
+ std::vector<Module::Line>* lines,
+ std::map<uint32_t, Module::File*>* files) {
+ DwarfLineToModule handler(module, compilation_dir_, lines, files);
+ google_breakpad::LineInfo parser(program, length, byte_reader_,
+ string_section, string_section_length,
+ line_string_section,
+ line_string_section_length,
+ &handler);
parser.Start();
}
private:
string compilation_dir_;
- dwarf2reader::ByteReader *byte_reader_;
+ google_breakpad::ByteReader* byte_reader_;
};
template<typename ElfClass>
+bool IsCompressedHeader(const typename ElfClass::Shdr* section) {
+ return (section->sh_flags & SHF_COMPRESSED) != 0;
+}
+
+template<typename ElfClass>
+uint32_t GetCompressionHeader(
+ typename ElfClass::Chdr& compression_header,
+ const uint8_t* content, uint64_t size) {
+ const typename ElfClass::Chdr* header =
+ reinterpret_cast<const typename ElfClass::Chdr *>(content);
+
+ if (size < sizeof (*header)) {
+ return 0;
+ }
+
+ compression_header = *header;
+ return sizeof (*header);
+}
+
+std::pair<uint8_t *, uint64_t> UncompressSectionContents(
+ const uint8_t* compressed_buffer, uint64_t compressed_size, uint64_t uncompressed_size) {
+ z_stream stream;
+ memset(&stream, 0, sizeof stream);
+
+ stream.avail_in = compressed_size;
+ stream.avail_out = uncompressed_size;
+ stream.next_in = const_cast<uint8_t *>(compressed_buffer);
+
+ google_breakpad::scoped_array<uint8_t> uncompressed_buffer(
+ new uint8_t[uncompressed_size]);
+
+ int status = inflateInit(&stream);
+ while (stream.avail_in != 0 && status == Z_OK) {
+ stream.next_out =
+ uncompressed_buffer.get() + uncompressed_size - stream.avail_out;
+
+ if ((status = inflate(&stream, Z_FINISH)) != Z_STREAM_END) {
+ break;
+ }
+
+ status = inflateReset(&stream);
+ }
+
+ return inflateEnd(&stream) != Z_OK || status != Z_OK || stream.avail_out != 0
+ ? std::make_pair(nullptr, 0)
+ : std::make_pair(uncompressed_buffer.release(), uncompressed_size);
+}
+
+template<typename ElfClass>
bool LoadDwarf(const string& dwarf_filename,
const typename ElfClass::Ehdr* elf_header,
const bool big_endian,
bool handle_inter_cu_refs,
+ bool handle_inline,
Module* module) {
typedef typename ElfClass::Shdr Shdr;
- const dwarf2reader::Endianness endianness = big_endian ?
- dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE;
- dwarf2reader::ByteReader byte_reader(endianness);
+ const google_breakpad::Endianness endianness = big_endian ?
+ google_breakpad::ENDIANNESS_BIG : google_breakpad::ENDIANNESS_LITTLE;
+ google_breakpad::ByteReader byte_reader(endianness);
// Construct a context for this file.
DwarfCUToModule::FileContext file_context(dwarf_filename,
@@ -300,29 +358,44 @@ bool LoadDwarf(const string& dwarf_filename,
string name = GetOffset<ElfClass, char>(elf_header,
section_names->sh_offset) +
section->sh_name;
- const uint8_t *contents = GetOffset<ElfClass, uint8_t>(elf_header,
+ const uint8_t* contents = GetOffset<ElfClass, uint8_t>(elf_header,
section->sh_offset);
- file_context.AddSectionToSectionMap(name, contents, section->sh_size);
- }
+ uint64_t size = section->sh_size;
+
+ if (!IsCompressedHeader<ElfClass>(section)) {
+ file_context.AddSectionToSectionMap(name, contents, size);
+ continue;
+ }
+
+ typename ElfClass::Chdr chdr;
- // Optional .debug_ranges reader
- scoped_ptr<DumperRangesHandler> ranges_handler;
- dwarf2reader::SectionMap::const_iterator ranges_entry =
- file_context.section_map().find(".debug_ranges");
- if (ranges_entry != file_context.section_map().end()) {
- const std::pair<const uint8_t *, uint64_t>& ranges_section =
- ranges_entry->second;
- ranges_handler.reset(
- new DumperRangesHandler(ranges_section.first, ranges_section.second,
- &byte_reader));
+ uint32_t compression_header_size =
+ GetCompressionHeader<ElfClass>(chdr, contents, size);
+
+ if (compression_header_size == 0 || chdr.ch_size == 0) {
+ continue;
+ }
+
+ contents += compression_header_size;
+ size -= compression_header_size;
+
+ std::pair<uint8_t *, uint64_t> uncompressed =
+ UncompressSectionContents(contents, size, chdr.ch_size);
+
+ if (uncompressed.first != nullptr && uncompressed.second != 0) {
+ file_context.AddManagedSectionToSectionMap(name, uncompressed.first, uncompressed.second);
+ }
}
+ // .debug_ranges and .debug_rnglists reader
+ DumperRangesHandler ranges_handler(&byte_reader);
+
// Parse all the compilation units in the .debug_info section.
DumperLineToModule line_to_module(&byte_reader);
- dwarf2reader::SectionMap::const_iterator debug_info_entry =
+ google_breakpad::SectionMap::const_iterator debug_info_entry =
file_context.section_map().find(".debug_info");
assert(debug_info_entry != file_context.section_map().end());
- const std::pair<const uint8_t *, uint64_t>& debug_info_section =
+ const std::pair<const uint8_t*, uint64_t>& debug_info_section =
debug_info_entry->second;
// This should never have been called if the file doesn't have a
// .debug_info section.
@@ -333,11 +406,11 @@ bool LoadDwarf(const string& dwarf_filename,
// data that was found.
DwarfCUToModule::WarningReporter reporter(dwarf_filename, offset);
DwarfCUToModule root_handler(&file_context, &line_to_module,
- ranges_handler.get(), &reporter);
+ &ranges_handler, &reporter, handle_inline);
// Make a Dwarf2Handler that drives the DIEHandler.
- dwarf2reader::DIEDispatcher die_dispatcher(&root_handler);
+ google_breakpad::DIEDispatcher die_dispatcher(&root_handler);
// Make a DWARF parser for the compilation unit at OFFSET.
- dwarf2reader::CompilationUnit reader(dwarf_filename,
+ google_breakpad::CompilationUnit reader(dwarf_filename,
file_context.section_map(),
offset,
&byte_reader,
@@ -397,18 +470,18 @@ bool LoadDwarfCFI(const string& dwarf_filename,
return false;
}
- const dwarf2reader::Endianness endianness = big_endian ?
- dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE;
+ const google_breakpad::Endianness endianness = big_endian ?
+ google_breakpad::ENDIANNESS_BIG : google_breakpad::ENDIANNESS_LITTLE;
// Find the call frame information and its size.
- const uint8_t *cfi =
+ const uint8_t* cfi =
GetOffset<ElfClass, uint8_t>(elf_header, section->sh_offset);
size_t cfi_size = section->sh_size;
// Plug together the parser, handler, and their entourages.
DwarfCFIToModule::Reporter module_reporter(dwarf_filename, section_name);
DwarfCFIToModule handler(module, register_names, &module_reporter);
- dwarf2reader::ByteReader byte_reader(endianness);
+ google_breakpad::ByteReader byte_reader(endianness);
byte_reader.SetAddressSize(ElfClass::kAddrSize);
@@ -420,11 +493,44 @@ bool LoadDwarfCFI(const string& dwarf_filename,
if (text_section)
byte_reader.SetTextBase(text_section->sh_addr);
- dwarf2reader::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename,
+ google_breakpad::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename,
section_name);
- dwarf2reader::CallFrameInfo parser(cfi, cfi_size,
- &byte_reader, &handler, &dwarf_reporter,
- eh_frame);
+ if (!IsCompressedHeader<ElfClass>(section)) {
+ google_breakpad::CallFrameInfo parser(cfi, cfi_size,
+ &byte_reader, &handler,
+ &dwarf_reporter, eh_frame);
+ parser.Start();
+ return true;
+ }
+
+ typename ElfClass::Chdr chdr;
+ uint32_t compression_header_size =
+ GetCompressionHeader<ElfClass>(chdr, cfi, cfi_size);
+
+ if (compression_header_size == 0 || chdr.ch_size == 0) {
+ fprintf(stderr, "%s: decompression failed at header\n",
+ dwarf_filename.c_str());
+ return false;
+ }
+ if (compression_header_size > cfi_size) {
+ fprintf(stderr, "%s: decompression error, compression_header too large\n",
+ dwarf_filename.c_str());
+ return false;
+ }
+
+ cfi += compression_header_size;
+ cfi_size -= compression_header_size;
+
+ std::pair<uint8_t *, uint64_t> uncompressed =
+ UncompressSectionContents(cfi, cfi_size, chdr.ch_size);
+
+ if (uncompressed.first == nullptr || uncompressed.second == 0) {
+ fprintf(stderr, "%s: decompression failed\n", dwarf_filename.c_str());
+ return false;
+ }
+ google_breakpad::CallFrameInfo parser(uncompressed.first, uncompressed.second,
+ &byte_reader, &handler, &dwarf_reporter,
+ eh_frame);
parser.Start();
return true;
}
@@ -489,13 +595,13 @@ bool IsSameFile(const char* left_abspath, const string& right_path) {
// Read the .gnu_debuglink and get the debug file name. If anything goes
// wrong, return an empty string.
-string ReadDebugLink(const uint8_t *debuglink,
+string ReadDebugLink(const uint8_t* debuglink,
const size_t debuglink_size,
const bool big_endian,
const string& obj_file,
const std::vector<string>& debug_dirs) {
// Include '\0' + CRC32 (4 bytes).
- size_t debuglink_len = strlen(reinterpret_cast<const char *>(debuglink)) + 5;
+ size_t debuglink_len = strlen(reinterpret_cast<const char*>(debuglink)) + 5;
debuglink_len = 4 * ((debuglink_len + 3) / 4); // Round up to 4 bytes.
// Sanity check.
@@ -517,7 +623,7 @@ string ReadDebugLink(const uint8_t *debuglink,
for (it = debug_dirs.begin(); it < debug_dirs.end(); ++it) {
const string& debug_dir = *it;
debuglink_path = debug_dir + "/" +
- reinterpret_cast<const char *>(debuglink);
+ reinterpret_cast<const char*>(debuglink);
// There is the annoying case of /path/to/foo.so having foo.so as the
// debug link file name. Thus this may end up opening /path/to/foo.so again,
@@ -533,9 +639,9 @@ string ReadDebugLink(const uint8_t *debuglink,
FDWrapper debuglink_fd_wrapper(debuglink_fd);
// The CRC is the last 4 bytes in |debuglink|.
- const dwarf2reader::Endianness endianness = big_endian ?
- dwarf2reader::ENDIANNESS_BIG : dwarf2reader::ENDIANNESS_LITTLE;
- dwarf2reader::ByteReader byte_reader(endianness);
+ const google_breakpad::Endianness endianness = big_endian ?
+ google_breakpad::ENDIANNESS_BIG : google_breakpad::ENDIANNESS_LITTLE;
+ google_breakpad::ByteReader byte_reader(endianness);
uint32_t expected_crc =
byte_reader.ReadFourBytes(&debuglink[debuglink_size - 4]);
@@ -591,7 +697,7 @@ class LoadSymbolsInfo {
// Keeps track of which sections have been loaded so sections don't
// accidentally get loaded twice from two different files.
- void LoadedSection(const string &section) {
+ void LoadedSection(const string& section) {
if (loaded_sections_.count(section) == 0) {
loaded_sections_.insert(section);
} else {
@@ -602,7 +708,7 @@ class LoadSymbolsInfo {
// The ELF file and linked debug file are expected to have the same preferred
// loading address.
- void set_loading_addr(Addr addr, const string &filename) {
+ void set_loading_addr(Addr addr, const string& filename) {
if (!has_loading_addr_) {
loading_addr_ = addr;
loaded_file_ = filename;
@@ -679,11 +785,12 @@ bool LoadSymbols(const string& obj_file,
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;
+ const char* names_end = names + section_names->sh_size;
bool found_debug_info_section = false;
bool found_usable_info = false;
- if (options.symbol_data != ONLY_CFI) {
+ if ((options.symbol_data & SYMBOLS_AND_FILES) ||
+ (options.symbol_data & INLINES)) {
#ifndef NO_STABS_SUPPORT
// Look for STABS debugging information, and load it if present.
const Shdr* stab_section =
@@ -705,32 +812,6 @@ bool LoadSymbols(const string& obj_file,
}
#endif // NO_STABS_SUPPORT
- // 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);
-
- // .debug_info section type is SHT_PROGBITS for mips on pnacl toolchains,
- // but MIPS_DWARF for regular gnu toolchains, so both need to be checked
- if (elf_header->e_machine == EM_MIPS && !dwarf_section) {
- dwarf_section =
- FindElfSectionByName<ElfClass>(".debug_info", SHT_MIPS_DWARF,
- sections, names, names_end,
- elf_header->e_shnum);
- }
-
- if (dwarf_section) {
- found_debug_info_section = true;
- found_usable_info = true;
- info->LoadedSection(".debug_info");
- if (!LoadDwarf<ElfClass>(obj_file, elf_header, big_endian,
- options.handle_inter_cu_refs, module)) {
- fprintf(stderr, "%s: \".debug_info\" section found, but failed to load "
- "DWARF debugging information\n", obj_file.c_str());
- }
- }
-
// See if there are export symbols available.
const Shdr* symtab_section =
FindElfSectionByName<ElfClass>(".symtab", SHT_SYMTAB,
@@ -788,9 +869,38 @@ bool LoadSymbols(const string& obj_file,
found_usable_info = found_usable_info || result;
}
}
+
+ // Only Load .debug_info after loading symbol table to avoid duplicate
+ // PUBLIC records.
+ // 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);
+
+ // .debug_info section type is SHT_PROGBITS for mips on pnacl toolchains,
+ // but MIPS_DWARF for regular gnu toolchains, so both need to be checked
+ if (elf_header->e_machine == EM_MIPS && !dwarf_section) {
+ dwarf_section =
+ FindElfSectionByName<ElfClass>(".debug_info", SHT_MIPS_DWARF,
+ sections, names, names_end,
+ elf_header->e_shnum);
+ }
+
+ if (dwarf_section) {
+ found_debug_info_section = true;
+ found_usable_info = true;
+ info->LoadedSection(".debug_info");
+ if (!LoadDwarf<ElfClass>(obj_file, elf_header, big_endian,
+ options.handle_inter_cu_refs,
+ options.symbol_data & INLINES, module)) {
+ fprintf(stderr, "%s: \".debug_info\" section found, but failed to load "
+ "DWARF debugging information\n", obj_file.c_str());
+ }
+ }
}
- if (options.symbol_data != NO_CFI) {
+ if (options.symbol_data & CFI) {
// Dwarf Call Frame Information (CFI) is actually independent from
// the other DWARF debugging information, and can be used alone.
const Shdr* dwarf_cfi_section =
@@ -859,7 +969,7 @@ bool LoadSymbols(const string& obj_file,
names_end, elf_header->e_shnum);
if (gnu_debuglink_section) {
if (!info->debug_dirs().empty()) {
- const uint8_t *debuglink_contents =
+ const uint8_t* debuglink_contents =
GetOffset<ElfClass, uint8_t>(elf_header,
gnu_debuglink_section->sh_offset);
string debuglink_file =
@@ -947,7 +1057,8 @@ template<typename ElfClass>
bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header,
const string& obj_filename,
const string& obj_os,
- scoped_ptr<Module>& module) {
+ scoped_ptr<Module>& module,
+ bool enable_multiple_field) {
PageAllocator allocator;
wasteful_vector<uint8_t> identifier(&allocator, kDefaultBuildIdSize);
if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, identifier)) {
@@ -956,7 +1067,7 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header,
return false;
}
- const char *architecture = ElfArchitecture<ElfClass>(elf_header);
+ const char* architecture = ElfArchitecture<ElfClass>(elf_header);
if (!architecture) {
fprintf(stderr, "%s: unrecognized ELF machine architecture: %d\n",
obj_filename.c_str(), elf_header->e_machine);
@@ -976,7 +1087,8 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header,
// This is just the raw Build ID in hex.
string code_id = FileID::ConvertIdentifierToString(identifier);
- module.reset(new Module(name, obj_os, architecture, id, code_id));
+ module.reset(new Module(name, obj_os, architecture, id, code_id,
+ enable_multiple_field));
return true;
}
@@ -993,8 +1105,8 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header,
*out_module = NULL;
scoped_ptr<Module> module;
- if (!InitModuleForElfClass<ElfClass>(elf_header, obj_filename, obj_os,
- module)) {
+ if (!InitModuleForElfClass<ElfClass>(elf_header, obj_filename, obj_os, module,
+ options.enable_multiple_field)) {
return false;
}
@@ -1066,12 +1178,12 @@ bool ReadSymbolDataInternal(const uint8_t* obj_file,
return false;
}
-bool WriteSymbolFile(const string &load_path,
- const string &obj_file,
- const string &obj_os,
+bool WriteSymbolFile(const string& load_path,
+ const string& obj_file,
+ const string& obj_os,
const std::vector<string>& debug_dirs,
const DumpOptions& options,
- std::ostream &sym_stream) {
+ std::ostream& sym_stream) {
Module* module;
if (!ReadSymbolData(load_path, obj_file, obj_os, debug_dirs, options,
&module))
@@ -1088,7 +1200,7 @@ bool WriteSymbolFile(const string &load_path,
bool WriteSymbolFileHeader(const string& load_path,
const string& obj_file,
const string& obj_os,
- std::ostream &sym_stream) {
+ std::ostream& sym_stream) {
MmapWrapper map_wrapper;
void* elf_header = NULL;
if (!LoadELF(load_path, &map_wrapper, &elf_header)) {
@@ -1106,14 +1218,14 @@ bool WriteSymbolFileHeader(const string& load_path,
if (elfclass == ELFCLASS32) {
if (!InitModuleForElfClass<ElfClass32>(
reinterpret_cast<const Elf32_Ehdr*>(elf_header), obj_file, obj_os,
- module)) {
+ module, /*enable_multiple_field=*/false)) {
fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str());
return false;
}
} else if (elfclass == ELFCLASS64) {
if (!InitModuleForElfClass<ElfClass64>(
reinterpret_cast<const Elf64_Ehdr*>(elf_header), obj_file, obj_os,
- module)) {
+ module, /*enable_multiple_field=*/false)) {
fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str());
return false;
}
diff --git a/src/common/linux/dump_symbols.h b/src/common/linux/dump_symbols.h
index eaddd8b2..f1802ecc 100644
--- a/src/common/linux/dump_symbols.h
+++ b/src/common/linux/dump_symbols.h
@@ -1,7 +1,6 @@
// -*- mode: c++ -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -13,7 +12,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -47,13 +46,16 @@ namespace google_breakpad {
class Module;
struct DumpOptions {
- DumpOptions(SymbolData symbol_data, bool handle_inter_cu_refs)
+ DumpOptions(SymbolData symbol_data,
+ bool handle_inter_cu_refs,
+ bool enable_multiple_field)
: symbol_data(symbol_data),
- handle_inter_cu_refs(handle_inter_cu_refs) {
- }
+ handle_inter_cu_refs(handle_inter_cu_refs),
+ enable_multiple_field(enable_multiple_field) {}
SymbolData symbol_data;
bool handle_inter_cu_refs;
+ bool enable_multiple_field;
};
// Find all the debugging information in OBJ_FILE, an ELF executable
@@ -62,12 +64,12 @@ struct DumpOptions {
// If OBJ_FILE has been stripped but contains a .gnu_debuglink section,
// then look for the debug file in DEBUG_DIRS.
// SYMBOL_DATA allows limiting the type of symbol data written.
-bool WriteSymbolFile(const string &load_path,
- const string &obj_file,
- const string &obj_os,
+bool WriteSymbolFile(const string& load_path,
+ const string& obj_file,
+ const string& obj_os,
const std::vector<string>& debug_dirs,
const DumpOptions& options,
- std::ostream &sym_stream);
+ std::ostream& sym_stream);
// Read the selected object file's debugging information, and write out the
// header only to |stream|. Return true on success; if an error occurs, report
@@ -76,7 +78,7 @@ bool WriteSymbolFile(const string &load_path,
bool WriteSymbolFileHeader(const string& load_path,
const string& obj_file,
const string& obj_os,
- std::ostream &sym_stream);
+ std::ostream& sym_stream);
// As above, but simply return the debugging information in MODULE
// instead of writing it to a stream. The caller owns the resulting
diff --git a/src/common/linux/dump_symbols_unittest.cc b/src/common/linux/dump_symbols_unittest.cc
index 54c21096..97d5827e 100644
--- a/src/common/linux/dump_symbols_unittest.cc
+++ b/src/common/linux/dump_symbols_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011 Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -92,7 +91,7 @@ TYPED_TEST(DumpSymbols, Invalid) {
Elf32_Ehdr header;
memset(&header, 0, sizeof(header));
Module* module;
- DumpOptions options(ALL_SYMBOL_DATA, true);
+ DumpOptions options(ALL_SYMBOL_DATA, true, false);
EXPECT_FALSE(ReadSymbolDataInternal(reinterpret_cast<uint8_t*>(&header),
"foo",
"Linux",
@@ -129,7 +128,7 @@ TYPED_TEST(DumpSymbols, SimplePublic) {
this->GetElfContents(elf);
Module* module;
- DumpOptions options(ALL_SYMBOL_DATA, true);
+ DumpOptions options(ALL_SYMBOL_DATA, true, false);
EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata,
"foo",
"Linux",
@@ -186,7 +185,7 @@ TYPED_TEST(DumpSymbols, SimpleBuildID) {
this->GetElfContents(elf);
Module* module;
- DumpOptions options(ALL_SYMBOL_DATA, true);
+ DumpOptions options(ALL_SYMBOL_DATA, true, false);
EXPECT_TRUE(ReadSymbolDataInternal(this->elfdata,
"foo",
"Linux",
diff --git a/src/common/linux/eintr_wrapper.h b/src/common/linux/eintr_wrapper.h
index 3f1d1848..a8428a9d 100644
--- a/src/common/linux/eintr_wrapper.h
+++ b/src/common/linux/eintr_wrapper.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2010 Google Inc.
-// All rights reserved.
+// Copyright 2010 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/elf_core_dump.cc b/src/common/linux/elf_core_dump.cc
index 0e7db7b1..f5ee3033 100644
--- a/src/common/linux/elf_core_dump.cc
+++ b/src/common/linux/elf_core_dump.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -34,6 +33,7 @@
#include <stddef.h>
#include <string.h>
+#include <unistd.h>
namespace google_breakpad {
@@ -95,16 +95,29 @@ size_t ElfCoreDump::Note::AlignedSize(size_t size) {
// Implementation of ElfCoreDump.
-ElfCoreDump::ElfCoreDump() {}
+ElfCoreDump::ElfCoreDump() : proc_mem_fd_(-1) {}
ElfCoreDump::ElfCoreDump(const MemoryRange& content)
- : content_(content) {
+ : content_(content), proc_mem_fd_(-1) {}
+
+ElfCoreDump::~ElfCoreDump() {
+ if (proc_mem_fd_ != -1) {
+ close(proc_mem_fd_);
+ proc_mem_fd_ = -1;
+ }
}
void ElfCoreDump::SetContent(const MemoryRange& content) {
content_ = content;
}
+void ElfCoreDump::SetProcMem(int fd) {
+ if (proc_mem_fd_ != -1) {
+ close(proc_mem_fd_);
+ }
+ proc_mem_fd_ = fd;
+}
+
bool ElfCoreDump::IsValid() const {
const Ehdr* header = GetHeader();
return (header &&
@@ -163,6 +176,16 @@ bool ElfCoreDump::CopyData(void* buffer, Addr virtual_address, size_t length) {
}
}
}
+
+ /* fallback: if available, read from /proc/<pid>/mem */
+ if (proc_mem_fd_ != -1) {
+ off_t offset = virtual_address;
+ ssize_t r = pread(proc_mem_fd_, buffer, length, offset);
+ if (r < ssize_t(length)) {
+ return false;
+ }
+ return true;
+ }
return false;
}
diff --git a/src/common/linux/elf_core_dump.h b/src/common/linux/elf_core_dump.h
index 6e153745..4f27179f 100644
--- a/src/common/linux/elf_core_dump.h
+++ b/src/common/linux/elf_core_dump.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -106,6 +105,8 @@ class ElfCoreDump {
// Constructor that takes the core dump content from |content|.
explicit ElfCoreDump(const MemoryRange& content);
+ ~ElfCoreDump();
+
// Sets the core dump content to |content|.
void SetContent(const MemoryRange& content);
@@ -139,9 +140,15 @@ class ElfCoreDump {
// an empty note if no note is found.
Note GetFirstNote() const;
+ // Sets the mem fd.
+ void SetProcMem(const int fd);
+
private:
// Core dump content.
MemoryRange content_;
+
+ // Descriptor for /proc/<pid>/mem.
+ int proc_mem_fd_;
};
} // namespace google_breakpad
diff --git a/src/common/linux/elf_core_dump_unittest.cc b/src/common/linux/elf_core_dump_unittest.cc
index 2399c12f..6789dd84 100644
--- a/src/common/linux/elf_core_dump_unittest.cc
+++ b/src/common/linux/elf_core_dump_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -130,9 +129,13 @@ TEST(ElfCoreDumpTest, TestElfHeader) {
TEST(ElfCoreDumpTest, ValidCoreFile) {
CrashGenerator crash_generator;
if (!crash_generator.HasDefaultCorePattern()) {
- fprintf(stderr, "ElfCoreDumpTest.ValidCoreFile test is skipped "
- "due to non-default core pattern");
- return;
+ GTEST_SKIP() << "ElfCoreDumpTest.ValidCoreFile test is skipped "
+ "due to non-default core pattern";
+ }
+
+ if (!crash_generator.HasResourceLimitsAmenableToCrashCollection()) {
+ GTEST_SKIP() << "ElfCoreDumpTest.ValidCoreFile test is skipped "
+ "due to inadequate system resource limits";
}
const unsigned kNumOfThreads = 3;
diff --git a/src/common/linux/elf_gnu_compat.h b/src/common/linux/elf_gnu_compat.h
index 0a3dfedb..5d56c1e9 100644
--- a/src/common/linux/elf_gnu_compat.h
+++ b/src/common/linux/elf_gnu_compat.h
@@ -1,7 +1,6 @@
// -*- mode: C++ -*-
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
+// Copyright 2013 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -13,7 +12,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/elf_symbols_to_module.cc b/src/common/linux/elf_symbols_to_module.cc
index 562875e1..3c33be99 100644
--- a/src/common/linux/elf_symbols_to_module.cc
+++ b/src/common/linux/elf_symbols_to_module.cc
@@ -1,6 +1,6 @@
// -*- mode: c++ -*-
-// Copyright (c) 2011 Google Inc. All Rights Reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -12,7 +12,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -36,6 +36,9 @@
#include <elf.h>
#include <string.h>
+#include <memory>
+#include <utility>
+
#include "common/byte_cursor.h"
#include "common/module.h"
@@ -69,7 +72,7 @@ public:
// otherwise. Assume each symbol has a 'value' field whose size is
// VALUE_SIZE.
//
- ELFSymbolIterator(const ByteBuffer *buffer, bool big_endian,
+ ELFSymbolIterator(const ByteBuffer* buffer, bool big_endian,
size_t value_size)
: value_size_(value_size), cursor_(buffer, big_endian) {
// Actually, weird sizes could be handled just fine, but they're
@@ -81,13 +84,13 @@ public:
// Move to the next symbol. This function's behavior is undefined if
// at_end() is true when it is called.
- ELFSymbolIterator &operator++() { Fetch(); symbol_.index++; return *this; }
+ ELFSymbolIterator& operator++() { Fetch(); symbol_.index++; return *this; }
// Dereferencing this iterator produces a reference to an Symbol structure
// that holds the current symbol's values. The symbol is owned by this
// SymbolIterator, and will be invalidated at the next call to operator++.
- const Symbol &operator*() const { return symbol_; }
- const Symbol *operator->() const { return &symbol_; }
+ const Symbol& operator*() const { return symbol_; }
+ const Symbol* operator->() const { return &symbol_; }
private:
// Read the symbol at cursor_, and set symbol_ appropriately.
@@ -126,21 +129,21 @@ private:
Symbol symbol_;
};
-const char *SymbolString(ptrdiff_t offset, ByteBuffer& strings) {
+const char* SymbolString(ptrdiff_t offset, ByteBuffer& strings) {
if (offset < 0 || (size_t) offset >= strings.Size()) {
// Return the null string.
offset = 0;
}
- return reinterpret_cast<const char *>(strings.start + offset);
+ return reinterpret_cast<const char*>(strings.start + offset);
}
-bool ELFSymbolsToModule(const uint8_t *symtab_section,
+bool ELFSymbolsToModule(const uint8_t* symtab_section,
size_t symtab_size,
- const uint8_t *string_section,
+ const uint8_t* string_section,
size_t string_size,
const bool big_endian,
size_t value_size,
- Module *module) {
+ Module* module) {
ByteBuffer symbols(symtab_section, symtab_size);
// Ensure that the string section is null-terminated.
if (string_section[string_size - 1] != '\0') {
@@ -156,7 +159,7 @@ bool ELFSymbolsToModule(const uint8_t *symtab_section,
while(!iterator->at_end) {
if (ELF32_ST_TYPE(iterator->info) == STT_FUNC &&
iterator->shndx != SHN_UNDEF) {
- Module::Extern *ext = new Module::Extern(iterator->value);
+ auto ext = std::make_unique<Module::Extern>(iterator->value);
ext->name = SymbolString(iterator->name_offset, strings);
#if !defined(__ANDROID__) // Android NDK doesn't provide abi::__cxa_demangle.
int status = 0;
@@ -168,7 +171,7 @@ bool ELFSymbolsToModule(const uint8_t *symtab_section,
free(demangled);
}
#endif
- module->AddExtern(ext);
+ module->AddExtern(std::move(ext));
}
++iterator;
}
diff --git a/src/common/linux/elf_symbols_to_module.h b/src/common/linux/elf_symbols_to_module.h
index 2e7c0971..ab27ef6b 100644
--- a/src/common/linux/elf_symbols_to_module.h
+++ b/src/common/linux/elf_symbols_to_module.h
@@ -1,6 +1,6 @@
// -*- mode: c++ -*-
-// Copyright (c) 2011 Google Inc. All Rights Reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -12,7 +12,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -44,13 +44,13 @@ namespace google_breakpad {
class Module;
-bool ELFSymbolsToModule(const uint8_t *symtab_section,
+bool ELFSymbolsToModule(const uint8_t* symtab_section,
size_t symtab_size,
- const uint8_t *string_section,
+ const uint8_t* string_section,
size_t string_size,
const bool big_endian,
size_t value_size,
- Module *module);
+ Module* module);
} // namespace google_breakpad
diff --git a/src/common/linux/elf_symbols_to_module_unittest.cc b/src/common/linux/elf_symbols_to_module_unittest.cc
index 8984449a..17eb670f 100644
--- a/src/common/linux/elf_symbols_to_module_unittest.cc
+++ b/src/common/linux/elf_symbols_to_module_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011 Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -86,7 +85,7 @@ public:
// 4 or 8 (bytes)
size_t value_size;
- vector<Module::Extern *> externs;
+ vector<Module::Extern*> externs;
};
class ELFSymbolsToModuleTest32 : public ELFSymbolsToModuleTestFixture,
@@ -248,9 +247,9 @@ TEST_P(ELFSymbolsToModuleTest32, SkipStuff) {
}
// Run all the 32-bit tests with both endianness
-INSTANTIATE_TEST_CASE_P(Endian,
- ELFSymbolsToModuleTest32,
- ::testing::Values(kLittleEndian, kBigEndian));
+INSTANTIATE_TEST_SUITE_P(Endian,
+ ELFSymbolsToModuleTest32,
+ ::testing::Values(kLittleEndian, kBigEndian));
// Similar tests, but with 64-bit values. Ostensibly this could be
// shoehorned into the parameterization by using ::testing::Combine,
@@ -365,6 +364,6 @@ TEST_P(ELFSymbolsToModuleTest64, SkipStuff) {
}
// Run all the 64-bit tests with both endianness
-INSTANTIATE_TEST_CASE_P(Endian,
- ELFSymbolsToModuleTest64,
- ::testing::Values(kLittleEndian, kBigEndian));
+INSTANTIATE_TEST_SUITE_P(Endian,
+ ELFSymbolsToModuleTest64,
+ ::testing::Values(kLittleEndian, kBigEndian));
diff --git a/src/common/linux/elfutils-inl.h b/src/common/linux/elfutils-inl.h
index e56b37a9..5fcc9c44 100644
--- a/src/common/linux/elfutils-inl.h
+++ b/src/common/linux/elfutils-inl.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/elfutils.cc b/src/common/linux/elfutils.cc
index 9532d5ad..a68cc0af 100644
--- a/src/common/linux/elfutils.cc
+++ b/src/common/linux/elfutils.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -40,11 +39,11 @@ namespace google_breakpad {
namespace {
template<typename ElfClass>
-void FindElfClassSection(const char *elf_base,
- const char *section_name,
+void FindElfClassSection(const char* elf_base,
+ const char* section_name,
typename ElfClass::Word section_type,
- const void **section_start,
- size_t *section_size) {
+ const void** section_start,
+ size_t* section_size) {
typedef typename ElfClass::Ehdr Ehdr;
typedef typename ElfClass::Shdr Shdr;
@@ -57,12 +56,18 @@ void FindElfClassSection(const char *elf_base,
const Ehdr* elf_header = reinterpret_cast<const Ehdr*>(elf_base);
assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass);
+ if (elf_header->e_shoff == 0) {
+ *section_start = NULL;
+ *section_size = 0;
+ return;
+ }
+
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;
+ const char* names_end = names + section_names->sh_size;
const Shdr* section =
FindElfSectionByName<ElfClass>(section_name, section_type,
@@ -76,9 +81,9 @@ void FindElfClassSection(const char *elf_base,
}
template<typename ElfClass>
-void FindElfClassSegment(const char *elf_base,
+void FindElfClassSegment(const char* elf_base,
typename ElfClass::Word segment_type,
- wasteful_vector<ElfSegment> *segments) {
+ wasteful_vector<ElfSegment>* segments) {
typedef typename ElfClass::Ehdr Ehdr;
typedef typename ElfClass::Phdr Phdr;
@@ -117,11 +122,11 @@ int ElfClass(const void* elf_base) {
return elf_header->e_ident[EI_CLASS];
}
-bool FindElfSection(const void *elf_mapped_base,
- const char *section_name,
+bool FindElfSection(const void* elf_mapped_base,
+ const char* section_name,
uint32_t section_type,
- const void **section_start,
- size_t *section_size) {
+ const void** section_start,
+ size_t* section_size) {
assert(elf_mapped_base);
assert(section_start);
assert(section_size);
diff --git a/src/common/linux/elfutils.h b/src/common/linux/elfutils.h
index aefb6cf5..130a8ac1 100644
--- a/src/common/linux/elfutils.h
+++ b/src/common/linux/elfutils.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -41,6 +40,39 @@
namespace google_breakpad {
+typedef struct Elf32_Chdr {
+ typedef Elf32_Word Type;
+ typedef Elf32_Word Size;
+ typedef Elf32_Addr Addr;
+
+ static_assert(sizeof (Type) == 4);
+ static_assert(sizeof (Size) == 4);
+ static_assert(sizeof (Addr) == 4);
+
+ Type ch_type; // Compression type
+ Size ch_size; // Uncompressed data size in bytes
+ Addr ch_addralign; // Uncompressed data alignment
+} Elf32_Chdr;
+
+static_assert(sizeof (Elf32_Chdr) == 12);
+
+typedef struct Elf64_Chdr {
+ typedef Elf64_Word Type;
+ typedef Elf64_Xword Size;
+ typedef Elf64_Addr Addr;
+
+ static_assert(sizeof (Type) == 4);
+ static_assert(sizeof (Size) == 8);
+ static_assert(sizeof (Addr) == 8);
+
+ Type ch_type; // Compression type
+ Type ch_reserved; // Padding
+ Size ch_size; // Uncompressed data size in bytes
+ Addr ch_addralign; // Uncompressed data alignment
+} Elf64_Chdr;
+
+static_assert(sizeof (Elf64_Chdr) == 24);
+
// Traits classes so consumers can write templatized code to deal
// with specific ELF bits.
struct ElfClass32 {
@@ -50,6 +82,7 @@ struct ElfClass32 {
typedef Elf32_Nhdr Nhdr;
typedef Elf32_Phdr Phdr;
typedef Elf32_Shdr Shdr;
+ typedef Elf32_Chdr Chdr;
typedef Elf32_Half Half;
typedef Elf32_Off Off;
typedef Elf32_Sym Sym;
@@ -68,6 +101,7 @@ struct ElfClass64 {
typedef Elf64_Nhdr Nhdr;
typedef Elf64_Phdr Phdr;
typedef Elf64_Shdr Shdr;
+ typedef Elf64_Chdr Chdr;
typedef Elf64_Half Half;
typedef Elf64_Off Off;
typedef Elf64_Sym Sym;
@@ -86,11 +120,11 @@ int ElfClass(const void* elf_base);
// in the ELF binary data at |elf_mapped_base|. On success, returns true
// and sets |*section_start| to point to the start of the section data,
// and |*section_size| to the size of the section's data.
-bool FindElfSection(const void *elf_mapped_base,
- const char *section_name,
+bool FindElfSection(const void* elf_mapped_base,
+ const char* section_name,
uint32_t section_type,
- const void **section_start,
- size_t *section_size);
+ const void** section_start,
+ size_t* section_size);
// Internal helper method, exposed for convenience for callers
// that already have more info.
diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc
index 67921c45..0bd2a759 100644
--- a/src/common/linux/file_id.cc
+++ b/src/common/linux/file_id.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
+// Copyright 2006 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -49,6 +48,7 @@
#include "third_party/lss/linux_syscall_support.h"
namespace google_breakpad {
+namespace elf {
// Used in a few places for backwards-compatibility.
const size_t kMDGUIDSize = sizeof(MDGUID);
@@ -61,7 +61,7 @@ FileID::FileID(const char* path) : path_(path) {}
// These functions are also used inside the crashed process, so be safe
// and use the syscall/libc wrappers instead of direct syscalls or libc.
-static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
+static bool ElfClassBuildIDNoteIdentifier(const void* section, size_t length,
wasteful_vector<uint8_t>& identifier) {
static_assert(sizeof(ElfClass32::Nhdr) == sizeof(ElfClass64::Nhdr),
"Elf32_Nhdr and Elf64_Nhdr should be the same");
@@ -69,7 +69,7 @@ static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
const void* section_end = reinterpret_cast<const char*>(section) + length;
const Nhdr* note_header = reinterpret_cast<const Nhdr*>(section);
- while (reinterpret_cast<const void *>(note_header) < section_end) {
+ while (reinterpret_cast<const void*>(note_header) < section_end) {
if (note_header->n_type == NT_GNU_BUILD_ID)
break;
note_header = reinterpret_cast<const Nhdr*>(
@@ -77,7 +77,7 @@ static bool ElfClassBuildIDNoteIdentifier(const void *section, size_t length,
NOTE_PADDING(note_header->n_namesz) +
NOTE_PADDING(note_header->n_descsz));
}
- if (reinterpret_cast<const void *>(note_header) >= section_end ||
+ if (reinterpret_cast<const void*>(note_header) >= section_end ||
note_header->n_descsz == 0) {
return false;
}
@@ -198,4 +198,5 @@ string FileID::ConvertIdentifierToString(
return bytes_to_hex_string(&identifier[0], identifier.size());
}
+} // elf
} // namespace google_breakpad
diff --git a/src/common/linux/file_id.h b/src/common/linux/file_id.h
index 4aff021d..8e58d56e 100644
--- a/src/common/linux/file_id.h
+++ b/src/common/linux/file_id.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
+// Copyright 2006 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -41,6 +40,7 @@
#include "common/using_std_string.h"
namespace google_breakpad {
+namespace elf {
// GNU binutils' ld defaults to 'sha1', which is 160 bits == 20 bytes,
// so this is enough to fit that, which most binaries will use.
@@ -83,6 +83,7 @@ class FileID {
string path_;
};
+} // namespace elf
} // namespace google_breakpad
#endif // COMMON_LINUX_FILE_ID_H__
diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc
index f4f9ac45..74bf9e1b 100644
--- a/src/common/linux/file_id_unittest.cc
+++ b/src/common/linux/file_id_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2010, Google Inc.
-// All rights reserved.
+// Copyright 2010 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -30,7 +29,10 @@
// Unit tests for FileID
#include <elf.h>
+#include <spawn.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <string>
#include <vector>
@@ -42,10 +44,13 @@
#include "common/linux/synth_elf.h"
#include "common/test_assembler.h"
#include "common/tests/auto_tempdir.h"
+#include "common/tests/file_utils.h"
#include "common/using_std_string.h"
#include "breakpad_googletest_includes.h"
using namespace google_breakpad;
+using google_breakpad::elf::FileID;
+using google_breakpad::elf::kDefaultBuildIdSize;
using google_breakpad::synth_elf::ELF;
using google_breakpad::synth_elf::Notes;
using google_breakpad::test_assembler::kLittleEndian;
@@ -80,13 +85,18 @@ TEST(FileIDStripTest, StripSelf) {
// copy our binary to a temp file, and strip it
AutoTempDir temp_dir;
string templ = temp_dir.path() + "/file-id-unittest";
- char cmdline[4096];
- sprintf(cmdline, "cp \"%s\" \"%s\"", exe_name, templ.c_str());
- ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
- sprintf(cmdline, "chmod u+w \"%s\"", templ.c_str());
- ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
- sprintf(cmdline, "strip \"%s\"", templ.c_str());
- ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
+ ASSERT_TRUE(CopyFile(exe_name, templ));
+ pid_t pid;
+ char* argv[] = {
+ const_cast<char*>("strip"),
+ const_cast<char*>(templ.c_str()),
+ nullptr,
+ };
+ ASSERT_EQ(0, posix_spawnp(&pid, argv[0], nullptr, nullptr, argv, nullptr));
+ int status;
+ ASSERT_EQ(pid, waitpid(pid, &status, 0));
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(0, WEXITSTATUS(status));
PageAllocator allocator;
id_vector identifier1(&allocator, kDefaultBuildIdSize);
@@ -261,7 +271,7 @@ TYPED_TEST(FileIDTest, BuildIDPH) {
elf.AddSection(".text", text, SHT_PROGBITS);
Notes notes(kLittleEndian);
notes.AddNote(0, "Linux",
- reinterpret_cast<const uint8_t *>("\0x42\0x02\0\0"), 4);
+ reinterpret_cast<const uint8_t*>("\0x42\0x02\0\0"), 4);
notes.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
sizeof(kExpectedIdentifierBytes));
int note_idx = elf.AddSection(".note", notes, SHT_NOTE);
@@ -292,7 +302,7 @@ TYPED_TEST(FileIDTest, BuildIDMultiplePH) {
elf.AddSection(".text", text, SHT_PROGBITS);
Notes notes1(kLittleEndian);
notes1.AddNote(0, "Linux",
- reinterpret_cast<const uint8_t *>("\0x42\0x02\0\0"), 4);
+ reinterpret_cast<const uint8_t*>("\0x42\0x02\0\0"), 4);
Notes notes2(kLittleEndian);
notes2.AddNote(NT_GNU_BUILD_ID, "GNU", kExpectedIdentifierBytes,
sizeof(kExpectedIdentifierBytes));
diff --git a/src/common/linux/google_crashdump_uploader.cc b/src/common/linux/google_crashdump_uploader.cc
index a0d940b6..6242e6d2 100644
--- a/src/common/linux/google_crashdump_uploader.cc
+++ b/src/common/linux/google_crashdump_uploader.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -35,6 +34,7 @@
#include <unistd.h>
#include <iostream>
+#include <utility>
#include "common/using_std_string.h"
@@ -51,7 +51,7 @@ GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product,
const string& crash_server,
const string& proxy_host,
const string& proxy_userpassword) {
- LibcurlWrapper* http_layer = new LibcurlWrapper();
+ std::unique_ptr<LibcurlWrapper> http_layer{new LibcurlWrapper()};
Init(product,
version,
guid,
@@ -63,21 +63,22 @@ GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product,
crash_server,
proxy_host,
proxy_userpassword,
- http_layer);
+ std::move(http_layer));
}
-GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product,
- const string& version,
- const string& guid,
- const string& ptime,
- const string& ctime,
- const string& email,
- const string& comments,
- const string& minidump_pathname,
- const string& crash_server,
- const string& proxy_host,
- const string& proxy_userpassword,
- LibcurlWrapper* http_layer) {
+GoogleCrashdumpUploader::GoogleCrashdumpUploader(
+ const string& product,
+ const string& version,
+ const string& guid,
+ const string& ptime,
+ const string& ctime,
+ const string& email,
+ const string& comments,
+ const string& minidump_pathname,
+ const string& crash_server,
+ const string& proxy_host,
+ const string& proxy_userpassword,
+ std::unique_ptr<LibcurlWrapper> http_layer) {
Init(product,
version,
guid,
@@ -89,7 +90,7 @@ GoogleCrashdumpUploader::GoogleCrashdumpUploader(const string& product,
crash_server,
proxy_host,
proxy_userpassword,
- http_layer);
+ std::move(http_layer));
}
void GoogleCrashdumpUploader::Init(const string& product,
@@ -103,7 +104,7 @@ void GoogleCrashdumpUploader::Init(const string& product,
const string& crash_server,
const string& proxy_host,
const string& proxy_userpassword,
- LibcurlWrapper* http_layer) {
+ std::unique_ptr<LibcurlWrapper> http_layer) {
product_ = product;
version_ = version;
guid_ = guid;
@@ -111,7 +112,7 @@ void GoogleCrashdumpUploader::Init(const string& product,
ctime_ = ctime;
email_ = email;
comments_ = comments;
- http_layer_.reset(http_layer);
+ http_layer_ = std::move(http_layer);
crash_server_ = crash_server;
proxy_host_ = proxy_host;
diff --git a/src/common/linux/google_crashdump_uploader.h b/src/common/linux/google_crashdump_uploader.h
index a2d0575b..74b5e1be 100644
--- a/src/common/linux/google_crashdump_uploader.h
+++ b/src/common/linux/google_crashdump_uploader.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -31,11 +30,11 @@
#ifndef COMMON_LINUX_GOOGLE_CRASHDUMP_UPLOADER_H_
#define COMMON_LINUX_GOOGLE_CRASHDUMP_UPLOADER_H_
-#include <string>
#include <map>
+#include <memory>
+#include <string>
#include "common/linux/libcurl_wrapper.h"
-#include "common/scoped_ptr.h"
#include "common/using_std_string.h"
namespace google_breakpad {
@@ -65,7 +64,7 @@ class GoogleCrashdumpUploader {
const string& crash_server,
const string& proxy_host,
const string& proxy_userpassword,
- LibcurlWrapper* http_layer);
+ std::unique_ptr<LibcurlWrapper> http_layer);
void Init(const string& product,
const string& version,
@@ -78,7 +77,7 @@ class GoogleCrashdumpUploader {
const string& crash_server,
const string& proxy_host,
const string& proxy_userpassword,
- LibcurlWrapper* http_layer);
+ std::unique_ptr<LibcurlWrapper> http_layer);
bool Upload(int* http_status_code,
string* http_response_header,
string* http_response_body);
@@ -86,7 +85,7 @@ class GoogleCrashdumpUploader {
private:
bool CheckRequiredParametersArePresent();
- scoped_ptr<LibcurlWrapper> http_layer_;
+ std::unique_ptr<LibcurlWrapper> http_layer_;
string product_;
string version_;
string guid_;
diff --git a/src/common/linux/google_crashdump_uploader_test.cc b/src/common/linux/google_crashdump_uploader_test.cc
index 3d6612e8..39aab65d 100644
--- a/src/common/linux/google_crashdump_uploader_test.cc
+++ b/src/common/linux/google_crashdump_uploader_test.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -59,21 +58,12 @@ class GoogleCrashdumpUploaderTest : public ::testing::Test {
};
TEST_F(GoogleCrashdumpUploaderTest, InitFailsCausesUploadFailure) {
- MockLibcurlWrapper m;
- EXPECT_CALL(m, Init()).Times(1).WillOnce(Return(false));
- GoogleCrashdumpUploader *uploader = new GoogleCrashdumpUploader("foobar",
- "1.0",
- "AAA-BBB",
- "",
- "",
- "test@test.com",
- "none",
- "/tmp/foo.dmp",
- "http://foo.com",
- "",
- "",
- &m);
- ASSERT_FALSE(uploader->Upload(NULL, NULL, NULL));
+ std::unique_ptr<MockLibcurlWrapper> m{new MockLibcurlWrapper()};
+ EXPECT_CALL(*m, Init()).Times(1).WillOnce(Return(false));
+ GoogleCrashdumpUploader uploader("foobar", "1.0", "AAA-BBB", "", "",
+ "test@test.com", "none", "/tmp/foo.dmp",
+ "http://foo.com", "", "", std::move(m));
+ ASSERT_FALSE(uploader.Upload(NULL, NULL, NULL));
}
TEST_F(GoogleCrashdumpUploaderTest, TestSendRequestHappensWithValidParameters) {
@@ -83,44 +73,27 @@ TEST_F(GoogleCrashdumpUploaderTest, TestSendRequestHappensWithValidParameters) {
ASSERT_NE(fd, -1);
close(fd);
- MockLibcurlWrapper m;
- EXPECT_CALL(m, Init()).Times(1).WillOnce(Return(true));
- EXPECT_CALL(m, AddFile(tempfn, _)).WillOnce(Return(true));
- EXPECT_CALL(m,
- SendRequest("http://foo.com",_,_,_,_)).Times(1).WillOnce(Return(true));
- GoogleCrashdumpUploader *uploader = new GoogleCrashdumpUploader("foobar",
- "1.0",
- "AAA-BBB",
- "",
- "",
- "test@test.com",
- "none",
- tempfn,
- "http://foo.com",
- "",
- "",
- &m);
- ASSERT_TRUE(uploader->Upload(NULL, NULL, NULL));
+ std::unique_ptr<MockLibcurlWrapper> m{new MockLibcurlWrapper()};
+ EXPECT_CALL(*m, Init()).Times(1).WillOnce(Return(true));
+ EXPECT_CALL(*m, AddFile(tempfn, _)).WillOnce(Return(true));
+ EXPECT_CALL(*m, SendRequest("http://foo.com", _, _, _, _))
+ .Times(1)
+ .WillOnce(Return(true));
+ GoogleCrashdumpUploader uploader("foobar", "1.0", "AAA-BBB", "", "",
+ "test@test.com", "none", tempfn,
+ "http://foo.com", "", "", std::move(m));
+ ASSERT_TRUE(uploader.Upload(NULL, NULL, NULL));
}
TEST_F(GoogleCrashdumpUploaderTest, InvalidPathname) {
- MockLibcurlWrapper m;
- EXPECT_CALL(m, Init()).Times(1).WillOnce(Return(true));
- EXPECT_CALL(m, SendRequest(_,_,_,_,_)).Times(0);
- GoogleCrashdumpUploader *uploader = new GoogleCrashdumpUploader("foobar",
- "1.0",
- "AAA-BBB",
- "",
- "",
- "test@test.com",
- "none",
- "/tmp/foo.dmp",
- "http://foo.com",
- "",
- "",
- &m);
- ASSERT_FALSE(uploader->Upload(NULL, NULL, NULL));
+ std::unique_ptr<MockLibcurlWrapper> m{new MockLibcurlWrapper()};
+ EXPECT_CALL(*m, Init()).Times(1).WillOnce(Return(true));
+ EXPECT_CALL(*m, SendRequest(_,_,_,_,_)).Times(0);
+ GoogleCrashdumpUploader uploader("foobar", "1.0", "AAA-BBB", "", "",
+ "test@test.com", "none", "/tmp/foo.dmp",
+ "http://foo.com", "", "", std::move(m));
+ ASSERT_FALSE(uploader.Upload(NULL, NULL, NULL));
}
TEST_F(GoogleCrashdumpUploaderTest, TestRequiredParametersMustBePresent) {
diff --git a/src/common/linux/guid_creator.cc b/src/common/linux/guid_creator.cc
index 03e3d781..31a326c7 100644
--- a/src/common/linux/guid_creator.cc
+++ b/src/common/linux/guid_creator.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
+// Copyright 2006 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -105,7 +104,7 @@ class GUIDGenerator {
private:
#ifdef HAVE_ARC4RANDOM
static void CreateGuidFromArc4Random(GUID *guid) {
- char *buf = reinterpret_cast<char *>(guid);
+ char *buf = reinterpret_cast<char*>(guid);
for (size_t i = 0; i < sizeof(GUID); i += sizeof(uint32_t)) {
uint32_t random_data = arc4random();
@@ -129,7 +128,7 @@ class GUIDGenerator {
#if defined(HAVE_SYS_RANDOM_H) && defined(HAVE_GETRANDOM)
static bool CreateGUIDFromGetrandom(GUID *guid) {
- char *buf = reinterpret_cast<char *>(guid);
+ char *buf = reinterpret_cast<char*>(guid);
int read_bytes = getrandom(buf, sizeof(GUID), GRND_NONBLOCK);
return (read_bytes == static_cast<int>(sizeof(GUID)));
@@ -139,7 +138,7 @@ class GUIDGenerator {
// Populate the GUID using random bytes read from /dev/urandom, returns false
// if the GUID wasn't fully populated with random data.
static bool CreateGUIDFromDevUrandom(GUID *guid) {
- char *buf = reinterpret_cast<char *>(guid);
+ char *buf = reinterpret_cast<char*>(guid);
int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
if (fd == -1) {
@@ -154,7 +153,7 @@ class GUIDGenerator {
// Populate the GUID using a stream of random bytes obtained from rand().
static void CreateGUIDFromRand(GUID *guid) {
- char *buf = reinterpret_cast<char *>(guid);
+ char *buf = reinterpret_cast<char*>(guid);
InitOnce();
diff --git a/src/common/linux/guid_creator.h b/src/common/linux/guid_creator.h
index c86d856c..c02f5552 100644
--- a/src/common/linux/guid_creator.h
+++ b/src/common/linux/guid_creator.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
+// Copyright 2006 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/http_upload.cc b/src/common/linux/http_upload.cc
index 702526af..1b576ea6 100644
--- a/src/common/linux/http_upload.cc
+++ b/src/common/linux/http_upload.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
+// Copyright 2006 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -36,14 +35,14 @@
namespace {
// Callback to get the response data from server.
-static size_t WriteCallback(void *ptr, size_t size,
- size_t nmemb, void *userp) {
+static size_t WriteCallback(void* ptr, size_t size,
+ size_t nmemb, void* userp) {
if (!userp)
return 0;
- string *response = reinterpret_cast<string *>(userp);
+ string* response = reinterpret_cast<string*>(userp);
size_t real_size = size * nmemb;
- response->append(reinterpret_cast<char *>(ptr), real_size);
+ response->append(reinterpret_cast<char*>(ptr), real_size);
return real_size;
}
@@ -54,15 +53,15 @@ namespace google_breakpad {
static const char kUserAgent[] = "Breakpad/1.0 (Linux)";
// static
-bool HTTPUpload::SendRequest(const string &url,
- const map<string, string> &parameters,
- const map<string, string> &files,
- const string &proxy,
- const string &proxy_user_pwd,
- const string &ca_certificate_file,
- string *response_body,
- long *response_code,
- string *error_description) {
+bool HTTPUpload::SendRequest(const string& url,
+ const map<string, string>& parameters,
+ const map<string, string>& files,
+ const string& proxy,
+ const string& proxy_user_pwd,
+ const string& ca_certificate_file,
+ string* response_body,
+ long* response_code,
+ string* error_description) {
if (response_code != NULL)
*response_code = 0;
@@ -101,7 +100,7 @@ bool HTTPUpload::SendRequest(const string &url,
CURL* (*curl_easy_init)(void);
*(void**) (&curl_easy_init) = dlsym(curl_lib, "curl_easy_init");
- CURL *curl = (*curl_easy_init)();
+ CURL* curl = (*curl_easy_init)();
if (error_description != NULL)
*error_description = "No Error";
@@ -111,7 +110,7 @@ bool HTTPUpload::SendRequest(const string &url,
}
CURLcode err_code = CURLE_OK;
- CURLcode (*curl_easy_setopt)(CURL *, CURLoption, ...);
+ CURLcode (*curl_easy_setopt)(CURL*, CURLoption, ...);
*(void**) (&curl_easy_setopt) = dlsym(curl_lib, "curl_easy_setopt");
(*curl_easy_setopt)(curl, CURLOPT_URL, url.c_str());
(*curl_easy_setopt)(curl, CURLOPT_USERAGENT, kUserAgent);
@@ -128,10 +127,10 @@ bool HTTPUpload::SendRequest(const string &url,
if (!ca_certificate_file.empty())
(*curl_easy_setopt)(curl, CURLOPT_CAINFO, ca_certificate_file.c_str());
- struct curl_httppost *formpost = NULL;
- struct curl_httppost *lastptr = NULL;
+ struct curl_httppost* formpost = NULL;
+ struct curl_httppost* lastptr = NULL;
// Add form data.
- CURLFORMcode (*curl_formadd)(struct curl_httppost **, struct curl_httppost **, ...);
+ CURLFORMcode (*curl_formadd)(struct curl_httppost**, struct curl_httppost**, ...);
*(void**) (&curl_formadd) = dlsym(curl_lib, "curl_formadd");
map<string, string>::const_iterator iter = parameters.begin();
for (; iter != parameters.end(); ++iter)
@@ -151,9 +150,9 @@ bool HTTPUpload::SendRequest(const string &url,
(*curl_easy_setopt)(curl, CURLOPT_HTTPPOST, formpost);
// Disable 100-continue header.
- struct curl_slist *headerlist = NULL;
+ struct curl_slist* headerlist = NULL;
char buf[] = "Expect:";
- struct curl_slist* (*curl_slist_append)(struct curl_slist *, const char *);
+ struct curl_slist* (*curl_slist_append)(struct curl_slist*, const char*);
*(void**) (&curl_slist_append) = dlsym(curl_lib, "curl_slist_append");
headerlist = (*curl_slist_append)(headerlist, buf);
(*curl_easy_setopt)(curl, CURLOPT_HTTPHEADER, headerlist);
@@ -161,17 +160,17 @@ bool HTTPUpload::SendRequest(const string &url,
if (response_body != NULL) {
(*curl_easy_setopt)(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
(*curl_easy_setopt)(curl, CURLOPT_WRITEDATA,
- reinterpret_cast<void *>(response_body));
+ reinterpret_cast<void*>(response_body));
}
// Fail if 400+ is returned from the web server.
(*curl_easy_setopt)(curl, CURLOPT_FAILONERROR, 1);
- CURLcode (*curl_easy_perform)(CURL *);
+ CURLcode (*curl_easy_perform)(CURL*);
*(void**) (&curl_easy_perform) = dlsym(curl_lib, "curl_easy_perform");
err_code = (*curl_easy_perform)(curl);
if (response_code != NULL) {
- CURLcode (*curl_easy_getinfo)(CURL *, CURLINFO, ...);
+ CURLcode (*curl_easy_getinfo)(CURL*, CURLINFO, ...);
*(void**) (&curl_easy_getinfo) = dlsym(curl_lib, "curl_easy_getinfo");
(*curl_easy_getinfo)(curl, CURLINFO_RESPONSE_CODE, response_code);
}
@@ -186,16 +185,16 @@ bool HTTPUpload::SendRequest(const string &url,
if (error_description != NULL)
*error_description = (*curl_easy_strerror)(err_code);
- void (*curl_easy_cleanup)(CURL *);
+ void (*curl_easy_cleanup)(CURL*);
*(void**) (&curl_easy_cleanup) = dlsym(curl_lib, "curl_easy_cleanup");
(*curl_easy_cleanup)(curl);
if (formpost != NULL) {
- void (*curl_formfree)(struct curl_httppost *);
+ void (*curl_formfree)(struct curl_httppost*);
*(void**) (&curl_formfree) = dlsym(curl_lib, "curl_formfree");
(*curl_formfree)(formpost);
}
if (headerlist != NULL) {
- void (*curl_slist_free_all)(struct curl_slist *);
+ void (*curl_slist_free_all)(struct curl_slist*);
*(void**) (&curl_slist_free_all) = dlsym(curl_lib, "curl_slist_free_all");
(*curl_slist_free_all)(headerlist);
}
@@ -211,10 +210,10 @@ bool HTTPUpload::CheckCurlLib(void* curl_lib) {
}
// static
-bool HTTPUpload::CheckParameters(const map<string, string> &parameters) {
+bool HTTPUpload::CheckParameters(const map<string, string>& parameters) {
for (map<string, string>::const_iterator pos = parameters.begin();
pos != parameters.end(); ++pos) {
- const string &str = pos->first;
+ const string& str = pos->first;
if (str.size() == 0)
return false; // disallow empty parameter names
for (unsigned int i = 0; i < str.size(); ++i) {
diff --git a/src/common/linux/http_upload.h b/src/common/linux/http_upload.h
index bc1d5d57..b7e557a0 100644
--- a/src/common/linux/http_upload.h
+++ b/src/common/linux/http_upload.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
+// Copyright 2006 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -58,21 +57,21 @@ class HTTPUpload {
// received (or 0 if the request failed before getting an HTTP response).
// If the send fails, a description of the error will be
// returned in error_description.
- static bool SendRequest(const string &url,
- const map<string, string> &parameters,
- const map<string, string> &files,
- const string &proxy,
- const string &proxy_user_pwd,
- const string &ca_certificate_file,
- string *response_body,
- long *response_code,
- string *error_description);
+ static bool SendRequest(const string& url,
+ const map<string, string>& parameters,
+ const map<string, string>& files,
+ const string& proxy,
+ const string& proxy_user_pwd,
+ const string& ca_certificate_file,
+ string* response_body,
+ long* response_code,
+ string* error_description);
private:
// Checks that the given list of parameters has only printable
// ASCII characters in the parameter name, and does not contain
// any quote (") characters. Returns true if so.
- static bool CheckParameters(const map<string, string> &parameters);
+ static bool CheckParameters(const map<string, string>& parameters);
// Checks the curl_lib parameter points to a valid curl lib.
static bool CheckCurlLib(void* curl_lib);
@@ -80,8 +79,8 @@ class HTTPUpload {
// No instances of this class should be created.
// Disallow all constructors, destructors, and operator=.
HTTPUpload();
- explicit HTTPUpload(const HTTPUpload &);
- void operator=(const HTTPUpload &);
+ explicit HTTPUpload(const HTTPUpload&);
+ void operator=(const HTTPUpload&);
~HTTPUpload();
};
diff --git a/src/common/linux/ignore_ret.h b/src/common/linux/ignore_ret.h
index efd274c2..1f879e8f 100644
--- a/src/common/linux/ignore_ret.h
+++ b/src/common/linux/ignore_ret.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2012 Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/libcurl_wrapper.cc b/src/common/linux/libcurl_wrapper.cc
index e96c2038..a53087d9 100644
--- a/src/common/linux/libcurl_wrapper.cc
+++ b/src/common/linux/libcurl_wrapper.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -48,6 +47,7 @@ LibcurlWrapper::LibcurlWrapper()
LibcurlWrapper::~LibcurlWrapper() {
if (init_ok_) {
(*easy_cleanup_)(curl_);
+ (*global_cleanup_)();
dlclose(curl_lib_);
}
}
@@ -88,14 +88,14 @@ bool LibcurlWrapper::AddFile(const string& upload_file_path,
}
// Callback to get the response data from server.
-static size_t WriteCallback(void *ptr, size_t size,
- size_t nmemb, void *userp) {
+static size_t WriteCallback(void* ptr, size_t size,
+ size_t nmemb, void* userp) {
if (!userp)
return 0;
- string *response = reinterpret_cast<string *>(userp);
+ string* response = reinterpret_cast<string*>(userp);
size_t real_size = size * nmemb;
- response->append(reinterpret_cast<char *>(ptr), real_size);
+ response->append(reinterpret_cast<char*>(ptr), real_size);
return real_size;
}
@@ -250,7 +250,7 @@ bool LibcurlWrapper::SetFunctionPointers() {
SET_AND_CHECK_FUNCTION_POINTER(easy_getinfo_,
"curl_easy_getinfo",
- CURLcode(*)(CURL *, CURLINFO info, ...));
+ CURLcode(*)(CURL*, CURLINFO info, ...));
SET_AND_CHECK_FUNCTION_POINTER(easy_reset_,
"curl_easy_reset",
@@ -263,6 +263,10 @@ bool LibcurlWrapper::SetFunctionPointers() {
SET_AND_CHECK_FUNCTION_POINTER(formfree_,
"curl_formfree",
void(*)(curl_httppost*));
+
+ SET_AND_CHECK_FUNCTION_POINTER(global_cleanup_,
+ "curl_global_cleanup",
+ void(*)(void));
return true;
}
diff --git a/src/common/linux/libcurl_wrapper.h b/src/common/linux/libcurl_wrapper.h
index 77aa6cbb..f8f961c1 100644
--- a/src/common/linux/libcurl_wrapper.h
+++ b/src/common/linux/libcurl_wrapper.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -40,6 +39,9 @@
#include "third_party/curl/curl.h"
namespace google_breakpad {
+
+// This class is only safe to be used on single-threaded code because of its
+// usage of libcurl's curl_global_cleanup().
class LibcurlWrapper {
public:
LibcurlWrapper();
@@ -91,27 +93,28 @@ class LibcurlWrapper {
// dealing
// with CURL.
- CURL *curl_; // Pointer for handle for CURL calls.
+ CURL* curl_; // Pointer for handle for CURL calls.
CURL* (*easy_init_)(void);
// Stateful pointers for calling into curl_formadd()
- struct curl_httppost *formpost_;
- struct curl_httppost *lastptr_;
- struct curl_slist *headerlist_;
+ struct curl_httppost* formpost_;
+ struct curl_httppost* lastptr_;
+ struct curl_slist* headerlist_;
// Function pointers into CURL library
- CURLcode (*easy_setopt_)(CURL *, CURLoption, ...);
- CURLFORMcode (*formadd_)(struct curl_httppost **,
- struct curl_httppost **, ...);
- struct curl_slist* (*slist_append_)(struct curl_slist *, const char *);
- void (*slist_free_all_)(struct curl_slist *);
- CURLcode (*easy_perform_)(CURL *);
+ CURLcode (*easy_setopt_)(CURL*, CURLoption, ...);
+ CURLFORMcode (*formadd_)(struct curl_httppost**,
+ struct curl_httppost**, ...);
+ struct curl_slist* (*slist_append_)(struct curl_slist*, const char*);
+ void (*slist_free_all_)(struct curl_slist*);
+ CURLcode (*easy_perform_)(CURL*);
const char* (*easy_strerror_)(CURLcode);
- void (*easy_cleanup_)(CURL *);
- CURLcode (*easy_getinfo_)(CURL *, CURLINFO info, ...);
+ void (*easy_cleanup_)(CURL*);
+ CURLcode (*easy_getinfo_)(CURL*, CURLINFO info, ...);
void (*easy_reset_)(CURL*);
- void (*formfree_)(struct curl_httppost *);
+ void (*formfree_)(struct curl_httppost*);
+ void (*global_cleanup_)(void);
};
}
diff --git a/src/common/linux/linux_libc_support.cc b/src/common/linux/linux_libc_support.cc
index 08b0325e..10cbeaef 100644
--- a/src/common/linux/linux_libc_support.cc
+++ b/src/common/linux/linux_libc_support.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -190,7 +189,7 @@ const char* my_read_decimal_ptr(uintptr_t* result, const char* s) {
}
void my_memset(void* ip, char c, size_t len) {
- char* p = (char *) ip;
+ char* p = (char*) ip;
while (len--)
*p++ = c;
}
diff --git a/src/common/linux/linux_libc_support.h b/src/common/linux/linux_libc_support.h
index ec5a8d6b..05e2aa24 100644
--- a/src/common/linux/linux_libc_support.h
+++ b/src/common/linux/linux_libc_support.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/linux_libc_support_unittest.cc b/src/common/linux/linux_libc_support_unittest.cc
index adadfed4..449f995f 100644
--- a/src/common/linux/linux_libc_support_unittest.cc
+++ b/src/common/linux/linux_libc_support_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2009, Google Inc.
-// All rights reserved.
+// Copyright 2009 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc
index 4e938269..7e444607 100644
--- a/src/common/linux/memory_mapped_file.cc
+++ b/src/common/linux/memory_mapped_file.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -65,7 +64,8 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) {
}
#if defined(__x86_64__) || defined(__aarch64__) || \
- (defined(__mips__) && _MIPS_SIM == _ABI64)
+ (defined(__mips__) && _MIPS_SIM == _ABI64) || \
+ (defined(__riscv) && __riscv_xlen == 64)
struct kernel_stat st;
if (sys_fstat(fd, &st) == -1 || st.st_size < 0) {
@@ -87,13 +87,14 @@ bool MemoryMappedFile::Map(const char* path, size_t offset) {
return true;
}
- void* data = sys_mmap(NULL, file_len, PROT_READ, MAP_PRIVATE, fd, offset);
+ size_t content_len = file_len - offset;
+ void* data = sys_mmap(NULL, content_len, PROT_READ, MAP_PRIVATE, fd, offset);
sys_close(fd);
if (data == MAP_FAILED) {
return false;
}
- content_.Set(data, file_len - offset);
+ content_.Set(data, content_len);
return true;
}
diff --git a/src/common/linux/memory_mapped_file.h b/src/common/linux/memory_mapped_file.h
index fa660cc9..d4a85051 100644
--- a/src/common/linux/memory_mapped_file.h
+++ b/src/common/linux/memory_mapped_file.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/memory_mapped_file_unittest.cc b/src/common/linux/memory_mapped_file_unittest.cc
index fad59f40..5ed677df 100644
--- a/src/common/linux/memory_mapped_file_unittest.cc
+++ b/src/common/linux/memory_mapped_file_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/safe_readlink.cc b/src/common/linux/safe_readlink.cc
index 870c28af..97ea62c0 100644
--- a/src/common/linux/safe_readlink.cc
+++ b/src/common/linux/safe_readlink.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/safe_readlink.h b/src/common/linux/safe_readlink.h
index 4ae131b5..f3aa9332 100644
--- a/src/common/linux/safe_readlink.h
+++ b/src/common/linux/safe_readlink.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/safe_readlink_unittest.cc b/src/common/linux/safe_readlink_unittest.cc
index d346b2a8..6f5f9d75 100644
--- a/src/common/linux/safe_readlink_unittest.cc
+++ b/src/common/linux/safe_readlink_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/symbol_collector_client.cc b/src/common/linux/symbol_collector_client.cc
index 92b25ddb..1c1dc97a 100644
--- a/src/common/linux/symbol_collector_client.cc
+++ b/src/common/linux/symbol_collector_client.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2019 Google Inc.
-// All rights reserved.
+// Copyright 2019 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/symbol_collector_client.h b/src/common/linux/symbol_collector_client.h
index 0e23242a..6190376f 100644
--- a/src/common/linux/symbol_collector_client.h
+++ b/src/common/linux/symbol_collector_client.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2019, Google Inc.
-// All rights reserved.
+// Copyright 2019 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/symbol_upload.cc b/src/common/linux/symbol_upload.cc
index 87741a0a..c080533a 100644
--- a/src/common/linux/symbol_upload.cc
+++ b/src/common/linux/symbol_upload.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011 Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -46,8 +45,8 @@
namespace google_breakpad {
namespace sym_upload {
-void TokenizeByChar(const string &source_string, int c,
- std::vector<string> *results) {
+void TokenizeByChar(const string& source_string, int c,
+ std::vector<string>* results) {
assert(results);
string::size_type cur_pos = 0, next_pos = 0;
while ((next_pos = source_string.find(c, cur_pos)) != string::npos) {
@@ -62,8 +61,8 @@ void TokenizeByChar(const string &source_string, int c,
//=============================================================================
// Parse out the module line which have 5 parts.
// MODULE <os> <cpu> <uuid> <module-name>
-bool ModuleDataForSymbolFile(const string &file,
- std::vector<string> *module_parts) {
+bool ModuleDataForSymbolFile(const string& file,
+ std::vector<string>* module_parts) {
assert(module_parts);
const size_t kModulePartNumber = 5;
FILE* fp = fopen(file.c_str(), "r");
@@ -90,7 +89,7 @@ bool ModuleDataForSymbolFile(const string &file,
}
//=============================================================================
-string CompactIdentifier(const string &uuid) {
+string CompactIdentifier(const string& uuid) {
std::vector<string> components;
TokenizeByChar(uuid, '-', &components);
string result;
diff --git a/src/common/linux/symbol_upload.h b/src/common/linux/symbol_upload.h
index 9033152b..a9d30e7b 100644
--- a/src/common/linux/symbol_upload.h
+++ b/src/common/linux/symbol_upload.h
@@ -1,7 +1,6 @@
// -*- mode: c++ -*-
-// Copyright (c) 2011 Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -13,7 +12,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/synth_elf.cc b/src/common/linux/synth_elf.cc
index 98e81dab..2ba25e61 100644
--- a/src/common/linux/synth_elf.cc
+++ b/src/common/linux/synth_elf.cc
@@ -118,7 +118,7 @@ int ELF::AddSection(const string& name, const Section& section,
return index;
}
-void ELF::AppendSection(ElfSection &section) {
+void ELF::AppendSection(ElfSection& section) {
// NULL and NOBITS sections have no content, so they
// don't need to be written to the file.
if (section.type_ == SHT_NULL) {
@@ -242,7 +242,7 @@ void SymbolTable::AddSymbol(const string& name, uint64_t value,
D64(size);
}
-void Notes::AddNote(int type, const string &name, const uint8_t* desc_bytes,
+void Notes::AddNote(int type, const string& name, const uint8_t* desc_bytes,
size_t desc_size) {
// Elf32_Nhdr and Elf64_Nhdr are exactly the same.
Elf32_Nhdr note_header;
diff --git a/src/common/linux/synth_elf.h b/src/common/linux/synth_elf.h
index 1d2a20ca..bf22081b 100644
--- a/src/common/linux/synth_elf.h
+++ b/src/common/linux/synth_elf.h
@@ -1,7 +1,6 @@
// -*- mode: C++ -*-
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -13,7 +12,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -154,7 +153,7 @@ class ELF : public Section {
vector<ElfSection> sections_;
- void AppendSection(ElfSection &section);
+ void AppendSection(ElfSection& section);
};
// A class to build .symtab or .dynsym sections.
@@ -187,7 +186,7 @@ public:
}
// Add a note.
- void AddNote(int type, const string &name, const uint8_t* desc_bytes,
+ void AddNote(int type, const string& name, const uint8_t* desc_bytes,
size_t desc_size);
};
diff --git a/src/common/linux/synth_elf_unittest.cc b/src/common/linux/synth_elf_unittest.cc
index cd74c286..44ef6ef3 100644
--- a/src/common/linux/synth_elf_unittest.cc
+++ b/src/common/linux/synth_elf_unittest.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011 Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -381,9 +380,9 @@ TEST_F(ElfNotesTest, Empty) {
TEST_F(ElfNotesTest, Notes) {
Notes notes(kLittleEndian);
- notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t *>("\x42\x02\0\0"),
+ notes.AddNote(1, "Linux", reinterpret_cast<const uint8_t*>("\x42\x02\0\0"),
4);
- notes.AddNote(2, "a", reinterpret_cast<const uint8_t *>("foobar"),
+ notes.AddNote(2, "a", reinterpret_cast<const uint8_t*>("foobar"),
sizeof("foobar") - 1);
const uint8_t kExpectedNotesContents[] = {
diff --git a/src/common/linux/tests/auto_testfile.h b/src/common/linux/tests/auto_testfile.h
index 92fe017b..e2d2ff23 100644
--- a/src/common/linux/tests/auto_testfile.h
+++ b/src/common/linux/tests/auto_testfile.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2013, Google Inc.
-// All rights reserved.
+// Copyright 2013 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
diff --git a/src/common/linux/tests/crash_generator.cc b/src/common/linux/tests/crash_generator.cc
index 6896a688..0db0c4a2 100644
--- a/src/common/linux/tests/crash_generator.cc
+++ b/src/common/linux/tests/crash_generator.cc
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -79,7 +78,7 @@ int tkill(pid_t tid, int sig) {
// Core file size limit set to 1 MB, which is big enough for test purposes.
const rlim_t kCoreSizeLimit = 1024 * 1024;
-void *thread_function(void *data) {
+void* thread_function(void* data) {
ThreadData* thread_data = reinterpret_cast<ThreadData*>(data);
volatile pid_t thread_id = gettid();
*(thread_data->thread_id_ptr) = thread_id;
@@ -169,6 +168,15 @@ bool CrashGenerator::SetCoreFileSizeLimit(rlim_t limit) const {
return true;
}
+bool CrashGenerator::HasResourceLimitsAmenableToCrashCollection() const {
+ struct rlimit limits;
+ if (getrlimit(RLIMIT_CORE, &limits) == -1) {
+ perror("CrashGenerator: Failed to get core file size limit");
+ return false;
+ }
+ return limits.rlim_max >= kCoreSizeLimit;
+}
+
bool CrashGenerator::CreateChildCrash(
unsigned num_threads, unsigned crash_thread, int crash_signal,
pid_t* child_pid) {
diff --git a/src/common/linux/tests/crash_generator.h b/src/common/linux/tests/crash_generator.h
index 7e2fcbf9..71c05d27 100644
--- a/src/common/linux/tests/crash_generator.h
+++ b/src/common/linux/tests/crash_generator.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2011, Google Inc.
-// All rights reserved.
+// Copyright 2011 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -65,6 +64,10 @@ class CrashGenerator {
// Returns the directory of a copy of proc files of the child process.
string GetDirectoryOfProcFilesCopy() const;
+ // Returns whether current resource limits would prevent `CreateChildCrash`
+ // from operating.
+ bool HasResourceLimitsAmenableToCrashCollection() const;
+
// Creates a crash (and a core dump file) by creating a child process with
// |num_threads| threads, and the terminating the child process by sending
// a signal with number |crash_signal| to the |crash_thread|-th thread.
diff --git a/src/common/linux/ucontext_constants.h b/src/common/linux/ucontext_constants.h
index c390508a..3dcdecb0 100644
--- a/src/common/linux/ucontext_constants.h
+++ b/src/common/linux/ucontext_constants.h
@@ -1,5 +1,4 @@
-// Copyright (c) 2012, Google Inc.
-// All rights reserved.
+// Copyright 2012 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
@@ -11,7 +10,7 @@
// 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
+// * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
@@ -146,8 +145,107 @@
#endif
#define FPREGS_OFFSET_MXCSR 24
+#elif defined(__riscv)
+
+#if __riscv_xlen == 32
+#define UCONTEXT_SIGMASK_OFFSET 20
+#define MCONTEXT_GREGS_OFFSET 148
+#define MCONTEXT_GREGS_SIZE 4
+#define REG_S sw
+#elif __riscv_xlen == 64
+#define UCONTEXT_SIGMASK_OFFSET 40
+#define MCONTEXT_GREGS_OFFSET 168
+#define MCONTEXT_GREGS_SIZE 8
+#define REG_S sd
#else
-#error "This header has not been ported for your CPU"
+#error "Unexpected __riscv_xlen"
+#endif
+
+#define MCONTEXT_GREGS_PC MCONTEXT_GREGS_OFFSET + 0*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_RA MCONTEXT_GREGS_OFFSET + 1*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_SP MCONTEXT_GREGS_OFFSET + 2*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_GP MCONTEXT_GREGS_OFFSET + 3*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_TP MCONTEXT_GREGS_OFFSET + 4*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T0 MCONTEXT_GREGS_OFFSET + 5*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T1 MCONTEXT_GREGS_OFFSET + 6*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T2 MCONTEXT_GREGS_OFFSET + 7*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S0 MCONTEXT_GREGS_OFFSET + 8*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S1 MCONTEXT_GREGS_OFFSET + 9*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A0 MCONTEXT_GREGS_OFFSET + 10*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A1 MCONTEXT_GREGS_OFFSET + 11*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A2 MCONTEXT_GREGS_OFFSET + 12*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A3 MCONTEXT_GREGS_OFFSET + 13*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A4 MCONTEXT_GREGS_OFFSET + 14*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A5 MCONTEXT_GREGS_OFFSET + 15*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A6 MCONTEXT_GREGS_OFFSET + 16*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_A7 MCONTEXT_GREGS_OFFSET + 17*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S2 MCONTEXT_GREGS_OFFSET + 18*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S3 MCONTEXT_GREGS_OFFSET + 19*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S4 MCONTEXT_GREGS_OFFSET + 20*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S5 MCONTEXT_GREGS_OFFSET + 21*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S6 MCONTEXT_GREGS_OFFSET + 22*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S7 MCONTEXT_GREGS_OFFSET + 23*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S8 MCONTEXT_GREGS_OFFSET + 24*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S9 MCONTEXT_GREGS_OFFSET + 25*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S10 MCONTEXT_GREGS_OFFSET + 26*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_S11 MCONTEXT_GREGS_OFFSET + 27*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T3 MCONTEXT_GREGS_OFFSET + 28*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T4 MCONTEXT_GREGS_OFFSET + 29*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T5 MCONTEXT_GREGS_OFFSET + 30*MCONTEXT_GREGS_SIZE
+#define MCONTEXT_GREGS_T6 MCONTEXT_GREGS_OFFSET + 31*MCONTEXT_GREGS_SIZE
+
+#define MCONTEXT_FPREGS_OFFSET MCONTEXT_GREGS_OFFSET + 32*MCONTEXT_GREGS_SIZE
+
+#if __riscv_flen == 32
+#define MCONTEXT_FPREGS_SIZE 4
+#define FREG_S fsw
+#elif __riscv_flen == 64
+#define MCONTEXT_FPREGS_SIZE 8
+#define FREG_S fsd
+#elif __riscv_flen == 128
+#define MCONTEXT_FPREGS_SIZE 16
+#define FREG_S fsq
+#else
+#error "Unexpected __riscv_flen"
+#endif
+
+#define MCONTEXT_FPREGS_FT0 MCONTEXT_FPREGS_OFFSET + 0*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT1 MCONTEXT_FPREGS_OFFSET + 1*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT2 MCONTEXT_FPREGS_OFFSET + 2*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT3 MCONTEXT_FPREGS_OFFSET + 3*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT4 MCONTEXT_FPREGS_OFFSET + 4*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT5 MCONTEXT_FPREGS_OFFSET + 5*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT6 MCONTEXT_FPREGS_OFFSET + 6*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT7 MCONTEXT_FPREGS_OFFSET + 7*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS0 MCONTEXT_FPREGS_OFFSET + 8*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS1 MCONTEXT_FPREGS_OFFSET + 9*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA0 MCONTEXT_FPREGS_OFFSET + 10*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA1 MCONTEXT_FPREGS_OFFSET + 11*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA2 MCONTEXT_FPREGS_OFFSET + 12*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA3 MCONTEXT_FPREGS_OFFSET + 13*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA4 MCONTEXT_FPREGS_OFFSET + 14*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA5 MCONTEXT_FPREGS_OFFSET + 15*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA6 MCONTEXT_FPREGS_OFFSET + 16*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FA7 MCONTEXT_FPREGS_OFFSET + 17*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS2 MCONTEXT_FPREGS_OFFSET + 18*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS3 MCONTEXT_FPREGS_OFFSET + 19*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS4 MCONTEXT_FPREGS_OFFSET + 20*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS5 MCONTEXT_FPREGS_OFFSET + 21*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS6 MCONTEXT_FPREGS_OFFSET + 22*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS7 MCONTEXT_FPREGS_OFFSET + 23*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS8 MCONTEXT_FPREGS_OFFSET + 24*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS9 MCONTEXT_FPREGS_OFFSET + 25*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS10 MCONTEXT_FPREGS_OFFSET + 26*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FS11 MCONTEXT_FPREGS_OFFSET + 27*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT8 MCONTEXT_FPREGS_OFFSET + 28*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT9 MCONTEXT_FPREGS_OFFSET + 29*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT10 MCONTEXT_FPREGS_OFFSET + 30*MCONTEXT_FPREGS_SIZE
+#define MCONTEXT_FPREGS_FT11 MCONTEXT_FPREGS_OFFSET + 31*MCONTEXT_FPREGS_SIZE
+
+#define MCONTEXT_FPC_CSR MCONTEXT_FPREGS_OFFSET + 32*MCONTEXT_FPREGS_SIZE
+
+#else
+# error "This header has not been ported for your CPU"
#endif
#endif // GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H