diff --git a/Makefile.am b/Makefile.am index b6270ad8..6b04411c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -83,6 +83,7 @@ src_client_linux_libbreakpad_client_a_SOURCES = \ src/common/convert_UTF.c \ src/common/md5.cc \ src/common/string_conversion.cc \ + src/common/linux/elfutils.cc \ src/common/linux/file_id.cc \ src/common/linux/guid_creator.cc \ src/common/linux/memory_mapped_file.cc \ @@ -335,6 +336,7 @@ src_client_linux_linux_client_unittest_LDADD = \ src/common/convert_UTF.o \ src/common/md5.o \ src/common/linux/elf_core_dump.o \ + src/common/linux/elfutils.o \ src/common/linux/file_id.o \ src/common/linux/guid_creator.o \ src/common/linux/memory_mapped_file.o \ @@ -369,6 +371,7 @@ src_tools_linux_dump_syms_dump_syms_SOURCES = \ src/common/dwarf/dwarf2reader.cc \ src/common/linux/dump_symbols.cc \ src/common/linux/elf_symbols_to_module.cc \ + src/common/linux/elfutils.cc \ src/common/linux/file_id.cc \ src/common/linux/memory_mapped_file.cc \ src/common/linux/safe_readlink.cc \ @@ -423,6 +426,7 @@ src_common_dumper_unittest_SOURCES = \ src/common/linux/memory_mapped_file_unittest.cc \ src/common/linux/synth_elf.cc \ src/common/linux/synth_elf_unittest.cc \ + src/common/linux/elfutils.cc \ src/common/linux/file_id.cc \ src/common/linux/file_id_unittest.cc \ src/common/linux/safe_readlink.cc \ @@ -917,6 +921,8 @@ EXTRA_DIST = \ src/common/linux/dump_symbols.h \ src/common/linux/elf_symbols_to_module.cc \ src/common/linux/elf_symbols_to_module.h \ + src/common/linux/elfutils.cc \ + src/common/linux/elfutils.h \ src/common/linux/file_id.cc \ src/common/linux/file_id.h \ src/common/linux/guid_creator.cc \ diff --git a/Makefile.in b/Makefile.in index a4318fe9..3206f2b4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -177,7 +177,8 @@ am__src_client_linux_libbreakpad_client_a_SOURCES_DIST = \ src/client/linux/minidump_writer/minidump_writer.cc \ src/client/minidump_file_writer.cc src/common/convert_UTF.c \ src/common/md5.cc src/common/string_conversion.cc \ - src/common/linux/file_id.cc src/common/linux/guid_creator.cc \ + src/common/linux/elfutils.cc src/common/linux/file_id.cc \ + src/common/linux/guid_creator.cc \ src/common/linux/memory_mapped_file.cc \ src/common/linux/safe_readlink.cc am__dirstamp = $(am__leading_dot)dirstamp @@ -191,6 +192,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @LINUX_HOST_TRUE@ src/common/convert_UTF.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/md5.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/string_conversion.$(OBJEXT) \ +@LINUX_HOST_TRUE@ src/common/linux/elfutils.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/linux/file_id.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/linux/guid_creator.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.$(OBJEXT) \ @@ -466,7 +468,7 @@ am__src_common_dumper_unittest_SOURCES_DIST = \ src/common/linux/memory_mapped_file_unittest.cc \ src/common/linux/synth_elf.cc \ src/common/linux/synth_elf_unittest.cc \ - src/common/linux/file_id.cc \ + src/common/linux/elfutils.cc src/common/linux/file_id.cc \ src/common/linux/file_id_unittest.cc \ src/common/linux/safe_readlink.cc \ src/common/linux/safe_readlink_unittest.cc \ @@ -509,6 +511,7 @@ am__src_common_dumper_unittest_SOURCES_DIST = \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-synth_elf.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-synth_elf_unittest.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-elfutils.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-file_id.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-file_id_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-safe_readlink.$(OBJEXT) \ @@ -933,7 +936,7 @@ am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \ src/common/dwarf/dwarf2reader.cc \ src/common/linux/dump_symbols.cc \ src/common/linux/elf_symbols_to_module.cc \ - src/common/linux/file_id.cc \ + src/common/linux/elfutils.cc src/common/linux/file_id.cc \ src/common/linux/memory_mapped_file.cc \ src/common/linux/safe_readlink.cc \ src/tools/linux/dump_syms/dump_syms.cc @@ -949,6 +952,7 @@ am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elfutils.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/safe_readlink.$(OBJEXT) \ @@ -1237,6 +1241,7 @@ lib_LIBRARIES = $(am__append_1) $(am__append_3) @LINUX_HOST_TRUE@ src/common/convert_UTF.c \ @LINUX_HOST_TRUE@ src/common/md5.cc \ @LINUX_HOST_TRUE@ src/common/string_conversion.cc \ +@LINUX_HOST_TRUE@ src/common/linux/elfutils.cc \ @LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ @LINUX_HOST_TRUE@ src/common/linux/guid_creator.cc \ @LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \ @@ -1416,6 +1421,7 @@ TESTS_ENVIRONMENT = @LINUX_HOST_TRUE@ src/common/convert_UTF.o \ @LINUX_HOST_TRUE@ src/common/md5.o \ @LINUX_HOST_TRUE@ src/common/linux/elf_core_dump.o \ +@LINUX_HOST_TRUE@ src/common/linux/elfutils.o \ @LINUX_HOST_TRUE@ src/common/linux/file_id.o \ @LINUX_HOST_TRUE@ src/common/linux/guid_creator.o \ @LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.o \ @@ -1449,6 +1455,7 @@ TESTS_ENVIRONMENT = @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf/dwarf2reader.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.cc \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elfutils.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/safe_readlink.cc \ @@ -1503,6 +1510,7 @@ TESTS_ENVIRONMENT = @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/synth_elf.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/synth_elf_unittest.cc \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elfutils.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/safe_readlink.cc \ @@ -2027,6 +2035,7 @@ EXTRA_DIST = \ src/common/linux/dump_symbols.h \ src/common/linux/elf_symbols_to_module.cc \ src/common/linux/elf_symbols_to_module.h \ + src/common/linux/elfutils.cc \ src/common/linux/file_id.cc \ src/common/linux/file_id.h \ src/common/linux/guid_creator.cc \ @@ -2268,6 +2277,8 @@ src/common/linux/$(am__dirstamp): src/common/linux/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/common/linux/$(DEPDIR) @: > src/common/linux/$(DEPDIR)/$(am__dirstamp) +src/common/linux/elfutils.$(OBJEXT): src/common/linux/$(am__dirstamp) \ + src/common/linux/$(DEPDIR)/$(am__dirstamp) src/common/linux/file_id.$(OBJEXT): src/common/linux/$(am__dirstamp) \ src/common/linux/$(DEPDIR)/$(am__dirstamp) src/common/linux/guid_creator.$(OBJEXT): \ @@ -2655,6 +2666,9 @@ src/common/linux/src_common_dumper_unittest-synth_elf.$(OBJEXT): \ src/common/linux/src_common_dumper_unittest-synth_elf_unittest.$(OBJEXT): \ src/common/linux/$(am__dirstamp) \ src/common/linux/$(DEPDIR)/$(am__dirstamp) +src/common/linux/src_common_dumper_unittest-elfutils.$(OBJEXT): \ + src/common/linux/$(am__dirstamp) \ + src/common/linux/$(DEPDIR)/$(am__dirstamp) src/common/linux/src_common_dumper_unittest-file_id.$(OBJEXT): \ src/common/linux/$(am__dirstamp) \ src/common/linux/$(DEPDIR)/$(am__dirstamp) @@ -3144,6 +3158,7 @@ mostlyclean-compile: -rm -f src/common/linux/dump_symbols.$(OBJEXT) -rm -f src/common/linux/elf_core_dump.$(OBJEXT) -rm -f src/common/linux/elf_symbols_to_module.$(OBJEXT) + -rm -f src/common/linux/elfutils.$(OBJEXT) -rm -f src/common/linux/file_id.$(OBJEXT) -rm -f src/common/linux/guid_creator.$(OBJEXT) -rm -f src/common/linux/http_upload.$(OBJEXT) @@ -3156,6 +3171,7 @@ mostlyclean-compile: -rm -f src/common/linux/src_common_dumper_unittest-elf_core_dump_unittest.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-elf_symbols_to_module.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-elf_symbols_to_module_unittest.$(OBJEXT) + -rm -f src/common/linux/src_common_dumper_unittest-elfutils.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-file_id.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-file_id_unittest.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-memory_mapped_file.$(OBJEXT) @@ -3395,6 +3411,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/dump_symbols.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elf_core_dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elf_symbols_to_module.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/elfutils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/file_id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/guid_creator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/http_upload.Po@am__quote@ @@ -3407,6 +3424,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elf_core_dump_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elf_symbols_to_module.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elf_symbols_to_module_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Po@am__quote@ @@ -4324,6 +4342,20 @@ src/common/linux/src_common_dumper_unittest-synth_elf_unittest.obj: src/common/l @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-synth_elf_unittest.obj `if test -f 'src/common/linux/synth_elf_unittest.cc'; then $(CYGPATH_W) 'src/common/linux/synth_elf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/synth_elf_unittest.cc'; fi` +src/common/linux/src_common_dumper_unittest-elfutils.o: src/common/linux/elfutils.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-elfutils.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Tpo -c -o src/common/linux/src_common_dumper_unittest-elfutils.o `test -f 'src/common/linux/elfutils.cc' || echo '$(srcdir)/'`src/common/linux/elfutils.cc +@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/linux/elfutils.cc' object='src/common/linux/src_common_dumper_unittest-elfutils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-elfutils.o `test -f 'src/common/linux/elfutils.cc' || echo '$(srcdir)/'`src/common/linux/elfutils.cc + +src/common/linux/src_common_dumper_unittest-elfutils.obj: src/common/linux/elfutils.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-elfutils.obj -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Tpo -c -o src/common/linux/src_common_dumper_unittest-elfutils.obj `if test -f 'src/common/linux/elfutils.cc'; then $(CYGPATH_W) 'src/common/linux/elfutils.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/elfutils.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elfutils.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/linux/elfutils.cc' object='src/common/linux/src_common_dumper_unittest-elfutils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-elfutils.obj `if test -f 'src/common/linux/elfutils.cc'; then $(CYGPATH_W) 'src/common/linux/elfutils.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/elfutils.cc'; fi` + src/common/linux/src_common_dumper_unittest-file_id.o: src/common/linux/file_id.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-file_id.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id.Tpo -c -o src/common/linux/src_common_dumper_unittest-file_id.o `test -f 'src/common/linux/file_id.cc' || echo '$(srcdir)/'`src/common/linux/file_id.cc @am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id.Po diff --git a/android/google_breakpad/Android.mk b/android/google_breakpad/Android.mk index a77e3087..ba8420b5 100644 --- a/android/google_breakpad/Android.mk +++ b/android/google_breakpad/Android.mk @@ -83,6 +83,7 @@ LOCAL_SRC_FILES := \ src/client/linux/minidump_writer/minidump_writer.cc \ src/client/minidump_file_writer.cc src/common/convert_UTF.c \ src/common/md5.cc src/common/string_conversion.cc \ + src/common/linux/elfutils.cc \ src/common/linux/file_id.cc src/common/linux/guid_creator.cc \ src/common/linux/memory_mapped_file.cc \ src/common/linux/safe_readlink.cc diff --git a/src/common/linux/elfutils.cc b/src/common/linux/elfutils.cc new file mode 100644 index 00000000..2fd5c1ff --- /dev/null +++ b/src/common/linux/elfutils.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2012, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "common/linux/elfutils.h" + +#include +#include + +#include "common/linux/linux_libc_support.h" + +namespace google_breakpad { + +namespace { + +template +void FindElfClassSection(const char *elf_base, + const char *section_name, + uint32_t section_type, + const void **section_start, + int *section_size) { + typedef typename ElfClass::Ehdr Ehdr; + typedef typename ElfClass::Shdr Shdr; + + assert(elf_base); + assert(section_start); + assert(section_size); + + assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0); + + int name_len = my_strlen(section_name); + + const Ehdr* elf_header = reinterpret_cast(elf_base); + assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); + + const Shdr* sections = + reinterpret_cast(elf_base + elf_header->e_shoff); + const Shdr* string_section = sections + elf_header->e_shstrndx; + + const Shdr* section = NULL; + for (int i = 0; i < elf_header->e_shnum; ++i) { + if (sections[i].sh_type == section_type) { + const char* current_section_name = (char*)(elf_base + + string_section->sh_offset + + sections[i].sh_name); + if (!my_strncmp(current_section_name, section_name, name_len)) { + section = §ions[i]; + break; + } + } + } + if (section != NULL && section->sh_size > 0) { + *section_start = elf_base + section->sh_offset; + *section_size = section->sh_size; + } +} + +} // namespace + +bool FindElfSection(const void *elf_mapped_base, + const char *section_name, + uint32_t section_type, + const void **section_start, + int *section_size, + int *elfclass) { + assert(elf_mapped_base); + assert(section_start); + assert(section_size); + + *section_start = NULL; + *section_size = 0; + + const char* elf_base = + static_cast(elf_mapped_base); + const ElfW(Ehdr)* elf_header = + reinterpret_cast(elf_base); + if (my_strncmp(elf_base, ELFMAG, SELFMAG) != 0) + return false; + + if (elfclass) { + *elfclass = elf_header->e_ident[EI_CLASS]; + } + + if (elf_header->e_ident[EI_CLASS] == ELFCLASS32) { + FindElfClassSection(elf_base, section_name, section_type, + section_start, section_size); + return *section_start != NULL; + } else if (elf_header->e_ident[EI_CLASS] == ELFCLASS64) { + FindElfClassSection(elf_base, section_name, section_type, + section_start, section_size); + return *section_start != NULL; + } + + return false; +} + +} // namespace google_breakpad diff --git a/src/common/linux/elfutils.h b/src/common/linux/elfutils.h new file mode 100644 index 00000000..30f2af3f --- /dev/null +++ b/src/common/linux/elfutils.h @@ -0,0 +1,81 @@ +// Copyright (c) 2012, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// elfutils.h: Utilities for dealing with ELF files. +// + +#ifndef COMMON_LINUX_ELFUTILS_H__ +#define COMMON_LINUX_ELFUTILS_H__ + +#if defined(__ANDROID__) +#include +#include "client/linux/android_link.h" +#else +#include +#include +#endif +#include + +namespace google_breakpad { + +// Traits classes so consumers can write templatized code to deal +// with specific ELF bits. +struct ElfClass32 { + typedef Elf32_Addr Addr; + typedef Elf32_Ehdr Ehdr; + typedef Elf32_Nhdr Nhdr; + typedef Elf32_Phdr Phdr; + typedef Elf32_Shdr Shdr; + static const int kClass = ELFCLASS32; +}; + +struct ElfClass64 { + typedef Elf64_Addr Addr; + typedef Elf64_Ehdr Ehdr; + typedef Elf64_Nhdr Nhdr; + typedef Elf64_Phdr Phdr; + typedef Elf64_Shdr Shdr; + static const int kClass = ELFCLASS64; +}; + +// Attempt to find a section named |section_name| of type |section_type| +// 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. If |elfclass| +// is not NULL, set |*elfclass| to the ELF file class. +bool FindElfSection(const void *elf_mapped_base, + const char *section_name, + uint32_t section_type, + const void **section_start, + int *section_size, + int *elfclass); + +} // namespace google_breakpad + +#endif // COMMON_LINUX_ELFUTILS_H__ diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index ff2f29e2..4e380b06 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -36,17 +36,11 @@ #include #include -#if defined(__ANDROID__) -#include -#include "client/linux/android_link.h" -#else -#include -#include -#endif #include #include +#include "common/linux/elfutils.h" #include "common/linux/linux_libc_support.h" #include "common/linux/memory_mapped_file.h" #include "third_party/lss/linux_syscall_support.h" @@ -61,105 +55,8 @@ FileID::FileID(const char* path) { strncpy(path_, path, sizeof(path_)); } -struct ElfClass32 { - typedef Elf32_Ehdr Ehdr; - typedef Elf32_Nhdr Nhdr; - typedef Elf32_Shdr Shdr; - static const int kClass = ELFCLASS32; -}; - -struct ElfClass64 { - typedef Elf64_Ehdr Ehdr; - typedef Elf64_Nhdr Nhdr; - typedef Elf64_Shdr Shdr; - static const int kClass = ELFCLASS64; -}; - // These six functions are also used inside the crashed process, so be safe // and use the syscall/libc wrappers instead of direct syscalls or libc. -template -static void FindElfClassSection(const char *elf_base, - const char *section_name, - uint32_t section_type, - const void **section_start, - int *section_size) { - typedef typename ElfClass::Ehdr Ehdr; - typedef typename ElfClass::Shdr Shdr; - - assert(elf_base); - assert(section_start); - assert(section_size); - - assert(my_strncmp(elf_base, ELFMAG, SELFMAG) == 0); - - int name_len = my_strlen(section_name); - - const Ehdr* elf_header = reinterpret_cast(elf_base); - assert(elf_header->e_ident[EI_CLASS] == ElfClass::kClass); - - const Shdr* sections = - reinterpret_cast(elf_base + elf_header->e_shoff); - const Shdr* string_section = sections + elf_header->e_shstrndx; - - const Shdr* section = NULL; - for (int i = 0; i < elf_header->e_shnum; ++i) { - if (sections[i].sh_type == section_type) { - const char* current_section_name = (char*)(elf_base + - string_section->sh_offset + - sections[i].sh_name); - if (!my_strncmp(current_section_name, section_name, name_len)) { - section = §ions[i]; - break; - } - } - } - if (section != NULL && section->sh_size > 0) { - *section_start = elf_base + section->sh_offset; - *section_size = section->sh_size; - } -} - -// Attempt to find a section named |section_name| of type |section_type| -// 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. If |elfclass| -// is not NULL, set |*elfclass| to the ELF file class. -static bool FindElfSection(const void *elf_mapped_base, - const char *section_name, - uint32_t section_type, - const void **section_start, - int *section_size, - int *elfclass) { - assert(elf_mapped_base); - assert(section_start); - assert(section_size); - - *section_start = NULL; - *section_size = 0; - - const char* elf_base = - static_cast(elf_mapped_base); - const ElfW(Ehdr)* elf_header = - reinterpret_cast(elf_base); - if (my_strncmp(elf_base, ELFMAG, SELFMAG) != 0) - return false; - - if (elfclass) { - *elfclass = elf_header->e_ident[EI_CLASS]; - } - - if (elf_header->e_ident[EI_CLASS] == ELFCLASS32) { - FindElfClassSection(elf_base, section_name, section_type, - section_start, section_size); - return *section_start != NULL; - } else if (elf_header->e_ident[EI_CLASS] == ELFCLASS64) { - FindElfClassSection(elf_base, section_name, section_type, - section_start, section_size); - return *section_start != NULL; - } - - return false; -} template static bool ElfClassBuildIDNoteIdentifier(const void *section,