diff --git a/CMakeLists.txt b/CMakeLists.txt index 678a9fa8dc..8b67f9c036 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,7 @@ if (UNIX) find_package(Sigaltstack) find_package(SelfDbg) find_package(Ucontext) + find_package(BFD) find_package(Fcitx) if (Fcitx_FOUND) find_package(DBus1) diff --git a/cmake/FindBFD.cmake b/cmake/FindBFD.cmake new file mode 100644 index 0000000000..84ae71def2 --- /dev/null +++ b/cmake/FindBFD.cmake @@ -0,0 +1,73 @@ +include(CheckCXXSourceCompiles) + +macro(test_compile_libbfd var libs) + if (BFD_FOUND) + return() + endif () + + set(CMAKE_REQUIRED_LIBRARIES ${libs}) + + check_cxx_source_compiles(" + #define PACKAGE 1 + #define PACKAGE_VERSION 1 + #include + #include + int main() { + bfd_init(); + bfd *abfd = bfd_openr(\"test\", \"test\"); + bfd_check_format(abfd, bfd_object); + bfd_get_file_flags(abfd); + bfd_map_over_sections(abfd, (void (*)(bfd*, asection*, void*)) 0, (void *) 0); + asymbol *syms = 0; + long symcount = bfd_read_minisymbols(abfd, false, (void**) &syms, (unsigned int *) 0); + bfd_get_section_flags(abfd, (asection*) 0); + bfd_get_section_vma(abfd, (asection*) 0); + bfd_section_size(abfd, (asection*) 0); + bfd_find_nearest_line(abfd, (asection*) 0, (asymbol **) 0, (bfd_vma) 0, (const char **) 0, (const char **) 0, (unsigned int *) 0); + return (int) symcount; + }" + ${var}0 + ) + + check_cxx_source_compiles(" + #define PACKAGE 1 + #define PACKAGE_VERSION 1 + #include + #include + int main() { + bfd_init(); + bfd *abfd = bfd_openr(\"test\", \"test\"); + bfd_check_format(abfd, bfd_object); + bfd_get_file_flags(abfd); + bfd_map_over_sections(abfd, (void (*)(bfd*, asection*, void*)) 0, (void *) 0); + asymbol *syms = 0; + long symcount = bfd_read_minisymbols(abfd, false, (void**) &syms, (unsigned int *) 0); + bfd_section_flags((asection*) 0); + bfd_section_vma((asection*) 0); + bfd_section_size((asection*) 0); + bfd_find_nearest_line(abfd, (asection*) 0, (asymbol **) 0, (bfd_vma) 0, (const char **) 0, (const char **) 0, (unsigned int *) 0); + return (int) symcount; + }" + ${var}1 + ) + + if (${var}0) + set(BFD_FOUND ON) + add_compile_options( + -DWITH_BFD0 + ) + link_libraries(${libs}) + elseif (${var}1) + set(BFD_FOUND ON) + add_compile_options( + -DWITH_BFD1 + ) + link_libraries(${libs}) + endif () + + set(CMAKE_REQUIRED_LIBRARIES "") +endmacro() + +test_compile_libbfd("BFD_FOUND_A" "-lbfd;-lz") +test_compile_libbfd("BFD_FOUND_B" "-lbfd;-liberty;-lz") +test_compile_libbfd("BFD_FOUND_C" "-lbfd;-liberty;-lintl;-lz") diff --git a/src/crashlog.cpp b/src/crashlog.cpp index a03a10fa22..476be47ca0 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -853,7 +853,7 @@ static void find_address_in_section(bfd *abfd, asection *section, void *data) bfd_vma vma = bfd_get_section_vma(abfd, section); if (info->addr < vma) return; - bfd_size_type size = bfd_section_size(abfd, section); + bfd_size_type size = get_bfd_section_size(abfd, section); if (info->addr >= vma + size) return; info->found = bfd_find_nearest_line(abfd, section, info->syms, info->addr - vma, diff --git a/src/crashlog_bfd.h b/src/crashlog_bfd.h index 834bc2d1fe..c11b8f9fff 100644 --- a/src/crashlog_bfd.h +++ b/src/crashlog_bfd.h @@ -10,6 +10,16 @@ #ifndef CRASHLOG_BFD_H #define CRASHLOG_BFD_H +#if defined(WITH_BFD0) +#define WITH_BFD 1 +#define get_bfd_section_size(abfd, section) bfd_section_size(abfd, section) +#elif defined(WITH_BFD1) +#define WITH_BFD 1 +#define bfd_get_section_flags(abfd, section) bfd_section_flags(section) +#define bfd_get_section_vma(abfd, section) bfd_section_vma(section) +#define get_bfd_section_size(abfd, section) bfd_section_size(section) +#endif + #if defined(WITH_BFD) /* this is because newer versions of libbfd insist on seeing these, even though they aren't used for anything */ #define PACKAGE 1