summaryrefslogtreecommitdiffstats
path: root/src/libdwfl
diff options
context:
space:
mode:
Diffstat (limited to 'src/libdwfl')
-rwxr-xr-xsrc/libdwfl/Android.mk167
-rw-r--r--src/libdwfl/ChangeLog2345
-rw-r--r--src/libdwfl/Makefile801
-rw-r--r--src/libdwfl/Makefile.am94
-rw-r--r--src/libdwfl/Makefile.in801
-rw-r--r--src/libdwfl/argp-std.c364
-rw-r--r--src/libdwfl/bzip2.c4
-rw-r--r--src/libdwfl/core-file.c589
-rw-r--r--src/libdwfl/cu.c312
-rw-r--r--src/libdwfl/derelocate.c401
-rw-r--r--src/libdwfl/dwfl_addrdie.c36
-rw-r--r--src/libdwfl/dwfl_addrdwarf.c37
-rw-r--r--src/libdwfl/dwfl_addrmodule.c38
-rw-r--r--src/libdwfl/dwfl_begin.c51
-rw-r--r--src/libdwfl/dwfl_build_id_find_debuginfo.c128
-rw-r--r--src/libdwfl/dwfl_build_id_find_elf.c174
-rw-r--r--src/libdwfl/dwfl_cumodule.c36
-rw-r--r--src/libdwfl/dwfl_dwarf_line.c43
-rw-r--r--src/libdwfl/dwfl_end.c54
-rw-r--r--src/libdwfl/dwfl_error.c159
-rw-r--r--src/libdwfl/dwfl_frame.c474
-rw-r--r--src/libdwfl/dwfl_frame_pc.c64
-rw-r--r--src/libdwfl/dwfl_frame_regs.c57
-rw-r--r--src/libdwfl/dwfl_getdwarf.c59
-rw-r--r--src/libdwfl/dwfl_getmodules.c92
-rw-r--r--src/libdwfl/dwfl_getsrc.c36
-rw-r--r--src/libdwfl/dwfl_getsrclines.c48
-rw-r--r--src/libdwfl/dwfl_line_comp_dir.c43
-rw-r--r--src/libdwfl/dwfl_linecu.c41
-rw-r--r--src/libdwfl/dwfl_lineinfo.c55
-rw-r--r--src/libdwfl/dwfl_linemodule.c38
-rw-r--r--src/libdwfl/dwfl_module.c222
-rw-r--r--src/libdwfl/dwfl_module_addrdie.c45
-rw-r--r--src/libdwfl/dwfl_module_addrname.c38
-rw-r--r--src/libdwfl/dwfl_module_addrsym.c289
-rw-r--r--src/libdwfl/dwfl_module_build_id.c117
-rw-r--r--src/libdwfl/dwfl_module_dwarf_cfi.c71
-rw-r--r--src/libdwfl/dwfl_module_eh_cfi.c57
-rw-r--r--src/libdwfl/dwfl_module_getdwarf.c1358
-rw-r--r--src/libdwfl/dwfl_module_getelf.c67
-rw-r--r--src/libdwfl/dwfl_module_getsrc.c81
-rw-r--r--src/libdwfl/dwfl_module_getsrc_file.c167
-rw-r--r--src/libdwfl/dwfl_module_getsym.c216
-rw-r--r--src/libdwfl/dwfl_module_info.c61
-rw-r--r--src/libdwfl/dwfl_module_nextcu.c44
-rw-r--r--src/libdwfl/dwfl_module_register_names.c79
-rw-r--r--src/libdwfl/dwfl_module_report_build_id.c80
-rw-r--r--src/libdwfl/dwfl_module_return_value_location.c64
-rw-r--r--src/libdwfl/dwfl_nextcu.c82
-rw-r--r--src/libdwfl/dwfl_onesrcline.c56
-rw-r--r--src/libdwfl/dwfl_report_elf.c338
-rw-r--r--src/libdwfl/dwfl_segment_report_module.c922
-rw-r--r--src/libdwfl/dwfl_validate_address.c61
-rw-r--r--src/libdwfl/dwfl_version.c36
-rw-r--r--src/libdwfl/elf-from-memory.c370
-rw-r--r--src/libdwfl/find-debuginfo.c351
-rw-r--r--src/libdwfl/frame_unwind.c725
-rw-r--r--src/libdwfl/gzip.c295
-rw-r--r--src/libdwfl/image-header.c101
-rw-r--r--src/libdwfl/libdwfl.h812
-rw-r--r--src/libdwfl/libdwflP.h760
-rw-r--r--src/libdwfl/libdwfl_crc32.c35
-rw-r--r--src/libdwfl/libdwfl_crc32_file.c36
-rw-r--r--src/libdwfl/lines.c52
-rw-r--r--src/libdwfl/link_map.c1021
-rw-r--r--src/libdwfl/linux-core-attach.c427
-rw-r--r--src/libdwfl/linux-kernel-modules.c929
-rw-r--r--src/libdwfl/linux-pid-attach.c475
-rw-r--r--src/libdwfl/linux-proc-maps.c422
-rw-r--r--src/libdwfl/lzma.c4
-rw-r--r--src/libdwfl/offline.c311
-rw-r--r--src/libdwfl/open.c182
-rw-r--r--src/libdwfl/relocate.c683
-rw-r--r--src/libdwfl/segment.c332
74 files changed, 0 insertions, 20515 deletions
diff --git a/src/libdwfl/Android.mk b/src/libdwfl/Android.mk
deleted file mode 100755
index 377b58a3..00000000
--- a/src/libdwfl/Android.mk
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-LIBDWFL_SRC_FILES := \
- core-file.c \
- cu.c \
- derelocate.c \
- dwfl_addrdie.c \
- dwfl_addrdwarf.c \
- dwfl_addrmodule.c \
- dwfl_begin.c \
- dwfl_build_id_find_debuginfo.c \
- dwfl_build_id_find_elf.c \
- dwfl_cumodule.c \
- dwfl_dwarf_line.c \
- dwfl_end.c \
- dwfl_error.c \
- dwfl_frame.c \
- dwfl_frame_pc.c \
- dwfl_frame_regs.c \
- dwfl_getdwarf.c \
- dwfl_getmodules.c \
- dwfl_getsrc.c \
- dwfl_getsrclines.c \
- dwfl_line_comp_dir.c \
- dwfl_linecu.c \
- dwfl_lineinfo.c \
- dwfl_linemodule.c \
- dwfl_module_addrdie.c \
- dwfl_module_addrname.c \
- dwfl_module_addrsym.c \
- dwfl_module_build_id.c \
- dwfl_module.c \
- dwfl_module_dwarf_cfi.c \
- dwfl_module_eh_cfi.c \
- dwfl_module_getdwarf.c \
- dwfl_module_getelf.c \
- dwfl_module_getsrc.c \
- dwfl_module_getsrc_file.c \
- dwfl_module_getsym.c \
- dwfl_module_info.c \
- dwfl_module_nextcu.c \
- dwfl_module_register_names.c \
- dwfl_module_report_build_id.c \
- dwfl_module_return_value_location.c \
- dwfl_nextcu.c \
- dwfl_onesrcline.c \
- dwfl_report_elf.c \
- dwfl_segment_report_module.c \
- dwfl_validate_address.c \
- dwfl_version.c \
- elf-from-memory.c \
- find-debuginfo.c \
- frame_unwind.c \
- gzip.c \
- image-header.c \
- libdwfl_crc32.c \
- libdwfl_crc32_file.c \
- lines.c \
- link_map.c \
- linux-core-attach.c \
- linux-kernel-modules.c \
- linux-pid-attach.c \
- linux-proc-maps.c \
- offline.c \
- open.c \
- relocate.c \
- segment.c \
-
-
-ifeq ($(HOST_OS),linux)
-
-#
-# host libdwfl
-#
-
-include $(CLEAR_VARS)
-
-# Clang has no nested functions.
-LOCAL_CLANG := false
-
-LOCAL_SRC_FILES := $(LIBDWFL_SRC_FILES)
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/.. \
- $(LOCAL_PATH)/../lib \
- $(LOCAL_PATH)/../libdwelf \
- $(LOCAL_PATH)/../libdwfl \
- $(LOCAL_PATH)/../libebl \
- $(LOCAL_PATH)/../libdw \
- $(LOCAL_PATH)/../libelf
-
-LOCAL_CFLAGS += -DHAVE_CONFIG_H -std=gnu99 -D_GNU_SOURCE
-
-# to suppress the "pointer of type ‘void *’ used in arithmetic" warning
-LOCAL_CFLAGS += -Wno-pointer-arith
-
-# Asserts are not compiled, so some debug variables appear unused. Rather than
-# fix, we prefer to turn off the warning locally.
-LOCAL_CFLAGS += -Wno-unused-but-set-variable
-
-# Similar to the above. To stay in line with upstream, ignore the warning.
-LOCAL_CFLAGS += -Wno-unused-variable
-
-LOCAL_MODULE:= libdwfl
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-LOCAL_STATIC_LIBRARIES := libz
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-endif # linux
-
-#
-# target libdwfl
-#
-
-include $(CLEAR_VARS)
-
-# Clang has no nested functions.
-LOCAL_CLANG := false
-
-LOCAL_SRC_FILES := $(LIBDWFL_SRC_FILES)
-
-LOCAL_C_INCLUDES := \
- $(LOCAL_PATH)/.. \
- $(LOCAL_PATH)/../lib \
- $(LOCAL_PATH)/../libdwelf \
- $(LOCAL_PATH)/../libdwfl \
- $(LOCAL_PATH)/../libebl \
- $(LOCAL_PATH)/../libdw \
- $(LOCAL_PATH)/../libelf
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../bionic-fixup
-
-LOCAL_CFLAGS += -include $(LOCAL_PATH)/../../bionic-fixup/AndroidFixup.h
-
-LOCAL_CFLAGS += -DHAVE_CONFIG_H -std=gnu99 -D_GNU_SOURCE -Werror
-
-# to suppress the "pointer of type ‘void *’ used in arithmetic" warning
-LOCAL_CFLAGS += -Wno-pointer-arith
-
-# See above.
-LOCAL_CFLAGS += -Wno-unused-but-set-variable
-LOCAL_CFLAGS += -Wno-unused-variable
-
-LOCAL_MODULE:= libdwfl
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-LOCAL_STATIC_LIBRARIES := libz
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/src/libdwfl/ChangeLog b/src/libdwfl/ChangeLog
deleted file mode 100644
index 69e59a6f..00000000
--- a/src/libdwfl/ChangeLog
+++ /dev/null
@@ -1,2345 +0,0 @@
-2014-12-19 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (find_symtab): Always try find_dynsym last.
-
-2014-12-19 Mark Wielaard <mjw@redhat.com>
-
- * elf-from-memory.c (handle_segment): Remove palign sanity check.
-
-2014-12-18 Mark Wielaard <mjw@redhat.com>
-
- * relocate.c (resolve_symbol): Make sure symstrdata->d_buf != NULL.
-
-2014-12-13 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (find_dynsym): elf_getdata_rawchunk takes
- a size_t, make sure it doesn't overflow.
-
-2014-12-13 Mark Wielaard <mjw@redhat.com>
-
- * cu.c (cudie_offset): Make sure Dwarf_Off difference doesn't
- wrap around before returning as int.
-
-2014-12-11 Josh Stone <jistone@redhat.com>
-
- * dwfl_module_getsrc.c (dwfl_module_getsrc): Return the *last* line
- record <= addr, rather than returning immediately on matches.
-
-2014-12-09 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_segment_report_module.c (handle_file_note): Check count doesn't
- overflow.
-
-2014-12-07 Mark Wielaard <mjw@redhat.com>
-
- * relocate.c (relocate_section): Sanity check section overlap against
- actually used ehsize, shentsize and phentsize.
-
-2014-12-07 Mark Wielaard <mjw@redhat.com>
-
- * offline.c (dwfl_offline_section_address): Assert shndx is not zero.
- * relocate.c (__libdwfl_relocate_value): Don't relocate against
- section zero.
-
-2014-11-29 Mark Wielaard <mjw@redhat.com>
-
- * relocate.c (relocate_section): Check relocation section and target
- section data don't overlap any of the ELF headers.
- (relocate): Check for offset + size overflow.
-
-2014-11-22 Mark Wielaard <mjw@redhat.com>
-
- * link_map.c (consider_executable): Use elf_getphdrnum.
- (dwfl_link_map_report): Likewise.
-
-2014-11-18 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (find_symtab): Sanity check the data buffer,
- number of symbols and first_global before use.
-
-2014-11-14 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (load_symtab): Don't use tables which have
- a zero sh_entsize.
-
-2014-11-10 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (find_dynsym): New inner function
- translate_offs that takes an adjust argument. Try finding
- the symbol table with and without adjusting to main_bias.
-
-2014-09-26 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Support NT_FILE for locating files.
- * core-file.c (dwfl_core_file_report): New variables note_file and
- note_file_size, set them and pass them to dwfl_segment_report_module.
- * dwfl_segment_report_module.c: Include common.h and fcntl.h.
- (buf_has_data, buf_read_ulong, handle_file_note): New functions.
- (invalid_elf): New function from code of dwfl_segment_report_module.
- (dwfl_segment_report_module): Add parameters note_file and
- note_file_size. New variables elf and fd, clean them up in finish.
- Move some code to invalid_elf. Call handle_file_note, if it found
- a name verify the file by invalid_elf. Protect elf and fd against
- cleanup by finish if we found the file for new Dwfl_Module.
- * libdwflP.h (dwfl_segment_report_module): Add parameters note_file and
- note_file_size.
-
-2014-09-23 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_segment_report_module.c (dwfl_segment_report_module):
- Extract ei_class, ei_data and e_type early and use the result.
-
-2014-09-18 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Use IS_EXECUTABLE.
- * dwfl_segment_report_module.c (dwfl_segment_report_module): Set
- IS_EXECUTABLE.
- * libdwflP.h (struct Dwfl_Module): New field is_executable.
-
-2014-08-28 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_module_getdwarf.c (find_offsets): Add parameter main_bias, use
- it.
- (find_dynsym): Pass the new parameter main_bias.
-
-2014-08-14 Mark Wielaard <mjw@redhat.com>
-
- * linux-kernel-modules.c (check-suffix): Also TRY .ko.xz.
-
-2014-07-24 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Fix report_r_debug for prelinked libraries.
- * link_map.c (report_r_debug): Comment out variable l_addr.
- Use instead new variable base recalculated from l_ld.
-
-2014-06-24 Kurt Roeckx <kurt@roeckx.be>
-
- * linux-pid-attach.c: Make it build on non linux hosts.
-
-2014-06-17 Mark Wielaard <mjw@redhat.com>
-
- * frame_unwind.c (handle_cfi): Use ebl_func_addr_mask.
- * dwfl_module_getsym.c (__libdwfl_getsym): Likewise.
-
-2014-06-15 Mark Wielaard <mjw@redhat.com>
-
- * linux-core-attach.c (core_memory_read): Use libdw/memory-access.h
- macros read_4ubyte_unaligned_noncvt and read_8ubyte_unaligned_noncvt
- to read possibly unaligned data.
- (core_next_thread): Likewise.
- (core_set_initial_registers): Likewise.
- (dwfl_core_file_attach): Likewise.
-
-2014-06-11 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_frame.c (__libdwfl_process_free): Reset dwfl->attacherr.
- (dwfl_attach_state): Set dwfl->attacherr.
- (dwfl_pid): Check and return dwfl->attacherr if set.
- (dwfl_getthreads): Likewise.
- (getthread): Likewise.
- * libdwflP.h: Add DWFL_E_NO_CORE_FILE.
- (struct Dwfl): Add attacherr field.
- * linux-core-attach.c (dwfl_core_file_attach): Set dwfl->attacherr.
- Don't assert if ELF file is not ET_CORE, just return error.
- * linux-pid-attach.c (dwfl_linux_proc_attach): Set dwfl->attacherr.
-
-2014-06-10 Mark Wielaard <mjw@redhat.com>
-
- * argp-std.c (parse_opt): Ignore errors from dwfl_core_file_attach
- or dwfl_linux_proc_attach.
-
-2014-05-15 Mark Wielaard <mjw@redhat.com>
-
- * linux-proc-maps.c (grovel_auxv): Close fd on error.
-
-2014-05-02 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf: Remove ENABLE_DWZ ifdefs so find_debug_altlink
- is always called.
-
-2014-05-01 Mark Wielaard <mjw@redhat.com>
-
- * libdwflP.h (struct Dwfl_Module): Add alt, alt_fd and alt_elf fields.
- (__libdwfl_open_mod_by_build_id): Renamed __libdwfl_open_by_build_id.
- (__libdwfl_open_by_build_id): New declaration that takes an explicit
- build-id.
- * dwfl_build_id_find_debuginfo.c (dwfl_build_id_find_debuginfo): If
- we already have the Dwarf then look for the alt dwz multi file by
- build-id.
- * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Add the
- build-id we are looking for as argument.
- (__libdwfl_open_mod_by_build_id): New function, calls
- __libdwfl_open_by_build_id.
- (dwfl_build_id_find_elf): Call __libdwfl_open_mod_by_build_id.
- * dwfl_module.c (__libdwfl_module_free): Release alt, alt_elf and
- close alt_fd if necessary.
- * dwfl_module_getdwarf.c (__check_build_id): Removed.
- (try_debugaltlink): Removed.
- (open_debugaltlink): Removed.
- (open_elf_file): First half of open_elf that just opens the elf
- file but doesn't setup the load address.
- (open_elf): Call open_elf_file.
- (find_debug_altlink): New function.
- (load_dw): Remove loading of dwz multifile.
- (find_dw): Call find_debug_altlink.
- * find-debuginfo.c (validate): Handle alt debug case using
- dwelf_dwarf_gnu_debugaltlink and mod->alt_elf.
- (find_debuginfo_in_path): Handle alt debug files possibly in .dwz
- subdirs.
- * linux-kernel-modules.c (try_kernel_name): Use fakemod.debug.name
- to store name to find by dwfl_standard_find_debuginfo instead of
- allocating an extra variable on stack.
-
-2014-04-30 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_build_id.c (__libdwfl_find_elf_build_id): Moved to
- dwelf_elf_gnu_build_id.c.
- (__libdwfl_find_build_id): Add assert to make sure mod is never NULL.
- * dwfl_segment_report_module.c (dwfl_segment_report_module): Call
- dwelf_elf_gnu_build_id directly instead of __libdwfl_find_build_id.
- * dwfl_module_getdwarf.c (__check_build_id): Implement using
- dwelf_elf_gnu_build_id.
-
-2014-04-15 Florian Weimer <fweimer@redhat.com>
-
- * dwfl_module_getdwarf.c (__check_build_id): Moved from libdw.
- (try_debugaltlink): Likewise.
- (open_debugaltlink): Likewise.
- (load_dw): Locate alternate debug information using
- dwelf_dwarf_gnu_debugaltlink and call open_debugaltlink.
-
-2014-04-11 Mark Wielaard <mjw@redhat.com>
-
- * Makefile.am (AM_CPPFLAGS): Add libdwelf.
- * libdwflP.h: Include libdwelfP.h.
- * dwfl_module_getdwarf.c (find_debuglink): Moved to libdwelf.
- (find_debuginfo): Use dwelf_elf_gnu_debuglink.
-
-2014-04-22 Mark Wielaard <mjw@redhat.com>
-
- * frame_unwind.c (__libdwfl_frame_reg_get): Use uint64_t when
- checking bits.
- (__libdwfl_frame_reg_set): Likewise.
-
-2014-04-22 Kurt Roeckx <kurt@roeckx.be>
-
- * linux-pid-attach.c: Make linux only.
-
-2014-03-14 Mark Wielaard <mjw@redhat.com>
-
- * Makefile.am: Remove !MUDFLAP and MUDFLAP conditions.
- Remove libelf and libdw definitions when MUDFLAP is defined.
- * argp-std.c (__libdwfl_argp_mudflap_options): Removed.
-
-2014-03-03 Mark Wielaard <mjw@redhat.com>
-
- * elf-from-memory.c (elf_from_remote_memory): Keep track of
- segments_end_mem. Pass memsz to first handle_segment pass. Only
- extend contents_size and use shdrs if only file bits are in
- segment.
-
-2014-03-11 Josh Stone <jistone@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Only explicitly set
- mod->e_type when processing the main ELF file.
-
-2014-03-04 Mark Wielaard <mjw@redhat.com>
-
- * libdwflP.h (struct __libdwfl_pid_arg): Moved here and renamed from
- linux-pid-attach.c (struct pid_arg).
- (__libdwfl_get_pid_arg): New internal function declaration.
- (__libdwfl_ptrace_attach): Likewise.
- (__libdwfl_ptrace_detach): Likewise.
- * dwfl_frame.c (dwfl_attach_state): Add "(deleted)" files to the
- special exception modules that cannot be checked at this point.
- * linux-pid-attach.c (struct pid_arg): Moved to libdwflP.h
- (ptrace_attach): Renamed to...
- (__libdwfl_ptrace_attach): New internal function.
- (__libdwfl_ptrace_detach): Likewise. Extracted from ...
- (pid_thread_detach): Call __libdwfl_ptrace_detach now.
- (__libdwfl_get_pid_arg): New internal function.
- * linux-proc-maps.c (dwfl_linux_proc_find_elf): Check if special
- module name contains "(deleted)" and dwfl_pid gives an attached
- pid. If pid is set and try to (re)use ptrace attach state of
- process before reading memory.
-
-2014-03-03 Mark Wielaard <mjw@redhat.com>
-
- * elf-from-memory.c (elf_from_remote_memory): Take pagesize as
- argument. Free buffer when detecting bad elf. Check PT_LOAD
- alignment requirements on first handle_segment pass. Calculate
- loadbase, start and end of segment using pagesize, not p_align.
- * linux-proc-maps.c (dwfl_linux_proc_find_elf): Provide pagesize
- to elf_from_remote_memory.
-
-2014-02-26 Mark Wielaard <mjw@redhat.com>
-
- * linux-proc-maps.c (proc_maps_report): Don't assert on bad input.
-
-2014-02-26 Mark Wielaard <mjw@redhat.com>
-
- * elf-from-memory.c (elf_from_remote_memory): Check against p64
- p_type in case ELFCLASS64, not against p32 p_type.
-
-2014-01-17 Petr Machata <pmachata@redhat.com>
-
- * relocate.c (relocate_section): Use gelf_fsize instead of relying
- on shdr->sh_entsize.
-
-2014-01-05 Mark Wielaard <mjw@redhat.com>
-
- * frame_unwind.c (handle_cfi): Only skip resetting return register
- if the regno is not the actual CIE return address register.
-
-2014-01-02 Mark Wielaard <mjw@redhat.com>
-
- * linux-pid-attach.c (dwfl_linux_proc_attach): Use strtol, not atoi.
-
-2013-12-30 Mark Wielaard <mjw@redhat.com>
-
- * argp-std.c (parse_opt): Call dwfl_linux_proc_attach and
- dwfl_core_file_attach explicitly.
- * core-file.c (dwfl_core_file_report): Don't call
- __libdwfl_attach_state_for_core implicitly.
- * dwfl_begin.c (dwfl_begin): Remove setting of process_attach_error.
- * dwfl_frame.c (dwfl_pid): Set errno to DWFL_E_NO_ATTACH_STATE, not
- process_attach_error.
- (dwfl_getthreads): Likewise.
- (getthread): Likewise.
- * libdwfl.h (dwfl_core_file_report): Update documentation.
- (dwfl_linux_proc_report): Likewise.
- (dwfl_core_file_attach): New function declaration.
- (dwfl_linux_proc_attach): Likewise.
- * libdwflP.h (struct Dwfl): Remove process_attach_error.
- (__libdwfl_attach_state_for_pid): Removed declaration.
- (__libdwfl_attach_state_for_core): Likewise.
- (dwfl_core_file_attach): New internal declaration.
- (dwfl_linux_proc_attach): Likewise.
- (attach_state_for_core): Renamed to...
- (dwfl_core_file_attach): ...this. Change return type.
- (__libdwfl_attach_state_for_core): Removed.
- * linux-pid-attach.c (struct pid_arg): Add assume_ptrace_stopped.
- (pid_set_initial_registers): Check assume_ptrace_stopped before
- calling ptrace.
- (pid_thread_detach): Likewise.
- (__libdwfl_attach_state_for_pid): Renamed to...
- (dwfl_linux_proc_attach): ...this. Adjust return type.
- * linux-proc-maps.c (dwfl_linux_proc_report): Don't call
- __libdwfl_attach_state_for_pid implicitly.
-
-2013-12-28 Mark Wielaard <mjw@redhat.com>
-
- * linux-proc-maps.c (dwfl_linux_proc_find_elf): Don't return special
- character device files, only regular files.
-
-2013-12-24 Mark Wielaard <mjw@redhat.com>
-
- * linux-core-attach.c (core_next_thread): Check whether thread_argp
- is NULL. Reset core_arg->thread_note_offset and malloc a thread_arg
- in that case. Free thread_arg if there are no more threads.
-
-2013-12-23 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_segment_report_module.c (dwfl_segment_report_module): Free
- build_id before returning early.
-
-2013-12-23 Mark Wielaard <mjw@redhat.com>
-
- * linux-pid-attach.c (__libdwfl_attach_state_for_pid): Report actual
- pid (thread group leader) to dwfl_attach_state.
-
-2013-12-21 Mark Wielaard <mjw@redhat.com>
-
- * frame_unwind.c (handle_cfi): Track whether the return register
- has been set and only allow it to be set once.
-
-2013-12-20 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_frame.c (one_arg): New struct.
- (get_one_thread_cb): New function.
- (dwfl_getthread): Likewise.
- (one_thread): New struct.
- (get_one_thread_frames_cb): New function.
- (dwfl_getthread_frames): Likewise.
- * libdwfl.h (Dwfl_Thread_Callbacks): Add get_thread function.
- (dwfl_getthread_frames): Likewise.
- * libdwflP.h (dwfl_getthread_frames): New internal function declaration.
- * linux-core-attach.c (core_thread_callbacks): Initialize get_thread
- to NULL.
- * linux-pid-attach.c (pid_getthread): New function.
- (pid_thread_callbacks): Initialize get_thread to pid_getthread.
-
-2013-12-20 Mark Wielaard <mjw@redhat.com>
-
- * linux-kernel-modules.c (report_kernel_archive): Correct nested
- asprintf result check for debug.a.
-
-2013-12-18 Mark Wielaard <mjw@redhat.com>
-
- * derelocate.c (__libdwfl_find_section_ndx): New internal function.
- * dwfl_module_addrname.c (dwfl_module_addrname): Use
- dwfl_module_addrinfo.
- * dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Replace with...
- (__libdwfl_addrsym): ...this. Use __libdwfl_getsym, use value
- for comparisons, not st_value. Fill in off. Search for both value
- and the (adjusted) sym.st_value when different.
- (dwfl_module_addrsym): Implement using __libdwfl_addrsym.
- (dwfl_module_addrinfo): New function.
- * dwfl_module_getsym.c (dwfl_module_getsym_elf): Replace with...
- (__libdwfl_getsym): ...this. Use ebl_resolve_sym_value if requested
- and possible. Adjust sym->st_value only when requested. Fill in addr
- if available.
- (dwfl_module_getsym_info): New function.
- (dwfl_module_getsym): Use __libdwfl_getsym.
- * libdwfl.h (dwfl_module_getsym_elf): Removed.
- (dwfl_module_getsym_info): New function declaration.
- (dwfl_module_addrinfo): Likewise.
- (dwfl_module_addrsym): Add documentation describing differences
- with addrinfo variants.
- (dwfl_module_addrsym_elf): Removed.
- * libdwflP.h (__libdwfl_getsym): New internal function declaration.
- (__libdwfl_addrsym): Likewise.
- (__libdwfl_find_section_ndx): Likewise.
- (dwfl_module_addrinfo): New internal declaration.
- (dwfl_module_getsym_info): Likewise.
- (dwfl_module_addrsym_elf): Removed.
- (dwfl_module_getsym_elf): Likewise.
-
-2013-12-18 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * argp-std.c (offline_find_elf): Remove.
- (offline_callbacks): Use dwfl_build_id_find_elf instead.
- * dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Move here the code
- removed above.
-
-2013-12-18 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- unwinder: s390 and s390x
- * dwfl_frame_pc.c (dwfl_frame_pc): Call ebl_normalize_pc.
- * frame_unwind.c (new_unwound): New function from ...
- (handle_cfi): ... here. Call it.
- (setfunc, getfunc, readfunc): New functions.
- (__libdwfl_frame_unwind): Call ebl_unwind with those functions.
- * linux-core-attach.c (core_set_initial_registers): Always iterate
- through the Ebl_Register_Location loop. Call
- dwfl_thread_state_register_pc there.
-
-2013-12-17 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * frame_unwind.c (handle_cfi): Call ebl_dwarf_to_regno for RA.
-
-2013-12-17 Mark Wielaard <mjw@redhat.com>
-
- * linux-pid-attach.c (pid_next_thread): Call rewinddir on first
- traversal.
-
-2013-12-16 Mark Wielaard <mjw@redhat.com>
-
- * libdwfl.h (dwfl_module_getsymtab_first_global): New function
- definition.
- * dwfl_module_getdwarf.c (dwfl_module_getsymtab_first_global): New
- function.
- * libdwflP.h (dwfl_module_getsymtab_first_global): New internal
- function definition.
- * dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Use new function.
-
-2013-12-14 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module.c (__libdwfl_module_free): Free mod->reloc_info if
- allocated. Call dwarf_cfi_end on mod->eh_cfi if necessary.
- * frame_unwind.c (handle_cfi): Free frame result from
- dwarf_cfi_addrframe when done.
-
-2013-12-15 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- unwinder: ppc and ppc64
- * frame_unwind.c (__libdwfl_frame_reg_get, __libdwfl_frame_reg_set):
- Call ebl_dwarf_to_regno.
- * linux-core-attach.c (core_set_initial_registers): Implement
- pc_register support.
- * linux-pid-attach.c (pid_thread_state_registers_cb): Implement
- FIRSTREG -1.
-
-2013-11-30 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Introduce process_attach_error.
- * dwfl_begin.c (dwfl_begin): Initialize process_attach_error.
- * dwfl_frame.c (dwfl_pid, dwfl_getthreads): Use PROCESS_ATTACH_ERROR if
- PROCESS is NULL.
- * libdwflP.h (struct Dwfl): New field process_attach_error.
- * linux-core-attach.c (__libdwfl_attach_state_for_core): Rename to ...
- (attach_state_for_core): ... here, make it static, change return type,
- no longer use __libdwfl_seterrno.
- (__libdwfl_attach_state_for_core): New wrapper for it.
-
-2013-11-27 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Rename to and call...
- (dwfl_module_addrsym_elf): this. Add elfp and biasp arguments,
- keep track of symelf, addr_symelf, closest_elf and sizeless_elf
- instead of tracking dwfl_files.
- * dwfl_module_getsym.c (__libdwfl_module_getsym): Renamed to...
- (dwfl_module_getsym_elf): ...this. Remove dwfl_file argument, add
- new elfp and biasp arguments. Track elf instead of file.
- (dwfl_module_getsym): Call dwfl_module_getsym_elf.
- dwfl_module_info.c (dwfl_module_info): Pass elf to
- dwfl_adjusted_st_value.
- * libdwfl.h (dwfl_module_getsym): Document limitations of shndx.
- (dwfl_module_getsym_elf): New function declaration.
- (dwfl_module_addrsym_elf): Likewise.
- * libdwflP.h (dwfl_module_addrsym_elf): INTDECL.
- (dwfl_module_getsym_elf): Likewise.
- (dwfl_adjusted_st_value): Take and check elf not dwfl_file.
- (dwfl_deadjust_st_value): Likewise.
- (__libdwfl_module_getsym): Removed.
- * relocate.c (resolve_symbol): Pass elf to dwfl_adjusted_st_value.
-
-2013-11-21 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Fix non-build-id core files on build-id system.
- * link_map.c (report_r_debug): Remove valid clearing if build-id cannot
- be read from memory.
-
-2013-11-21 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_segment_report_module.c (dwfl_segment_report_module): New
- variable close_elf. Call __libdwfl_find_elf_build_id and compare the
- content, if possible.
-
-2013-11-21 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- link_map: Use proper bias, not l_addr.
- * core-file.c (dynamic_vaddr_get): Rename to ...
- (__libdwfl_dynamic_vaddr_get): ... here, make it global,
- internal_function.
- (dwfl_core_file_report): Update name in the caller.
- * libdwflP.h (__libdwfl_dynamic_vaddr_get): New declaration.
- * link_map.c (report_r_debug): New variable elf_dynamic_vaddr. Call
- __libdwfl_dynamic_vaddr_get for it. Remove L_ADDR FIXME comment.
- Use ELF_DYNAMIC_VADDR instead of L_ADDR.
-
-2013-11-19 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Compatibility with older kernels such as RHEL-6.
- * linux-pid-attach.c (struct pid_arg): New field tid_was_stopped.
- (ptrace_attach): New parameter tid_was_stoppedp. Set it.
- (pid_set_initial_registers): Pass tid_was_stopped.
- (pid_thread_detach): Use tid_was_stopped.
-
-2013-11-18 Josh Stone <jistone@redhat.com>
-
- * dwfl_module_getdwarf.c (find_aux_address_sync): New function.
- (find_aux_sym): Use it.
-
-2013-11-14 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Code cleanup: Remove const in prototype
- * dwfl_frame_regs.c (dwfl_thread_state_registers): Remove const from
- firstreg.
- * libdwfl.h (dwfl_thread_state_registers): Likewise.
- * linux-pid-attach.c (pid_thread_state_registers_cb): Likewise.
-
-2013-11-14 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Fix dwfl_attach_state machine->elf.
- * dwfl_frame.c (dwfl_attach_state): Change parameter machine to elf.
- Call ebl_openbackend instead of ebl_openbackend_machine.
- * libdwfl.h (dwfl_attach_state): Change parameter machine to elf.
- Update the function description.
- * linux-core-attach.c (__libdwfl_attach_state_for_core): Pass CORE to
- dwfl_attach_state.
- * linux-pid-attach.c (__libdwfl_attach_state_for_pid): Pass NULL to
- dwfl_attach_state.
-
-2013-11-06 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Provide __libdwfl_module_getsym to get dwfl_file *.
- * dwfl_module_addrsym.c (dwfl_module_addrsym) (i_to_symfile): Remove.
- (dwfl_module_addrsym) (search_table): New variable file. Use
- __libdwfl_module_getsym. Use file.
- * dwfl_module_getsym.c (dwfl_module_getsym): Rename to ...
- (__libdwfl_module_getsym): ... here. Add parameter filep. Set it.
- (dwfl_module_getsym): New wrapper.
- * libdwflP.h (__libdwfl_module_getsym): New declaration.
-
-2013-11-13 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Fix dwfl_module_addrsym for minidebuginfo.
- * dwfl_module_addrsym.c (dwfl_module_addrsym): New variable
- addr_symfile.
- (dwfl_module_addrsym) (same_section): Use it.
- (dwfl_module_addrsym) (i_to_symfile): New function.
- (dwfl_module_addrsym) (search_table): Use it.
-
-2013-11-07 Jan Kratochvil <jan.kratochvil@redhat.com>
- Mark Wielaard <mjw@redhat.com>
-
- * Makefile.am (libdwfl_a_SOURCES): Add dwfl_frame.c, frame_unwind.c,
- dwfl_frame_pc.c, linux-pid-attach.c, linux-core-attach.c and
- dwfl_frame_regs.c.
- * core-file.c (dwfl_core_file_report): Call
- __libdwfl_attach_state_for_core.
- * dwfl_end.c (dwfl_end): Call __libdwfl_process_free.
- * dwfl_frame.c: New file.
- * frame_unwind.c: New file.
- * dwfl_frame_pc.c: New file.
- * linux-pid-attach.c: New file.
- * linux-core-attach.c: New file.
- * dwfl_frame_regs.c: New file.
- * libdwfl.h (Dwfl_Thread, Dwfl_Frame): New typedefs.
- (dwfl_core_file_report, dwfl_linux_proc_report): Extend comments.
- (Dwfl_Thread_Callbacks): New definition.
- (struct ebl, dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl)
- (dwfl_thread_tid, dwfl_frame_thread, dwfl_thread_state_registers)
- (dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes)
- (dwfl_frame_pc): New declarations.
- * libdwflP.h (Dwfl_Process): New typedef.
- (LIBEBL_BAD, CORE_MISSING, INVALID_REGISTER, PROCESS_MEMORY_READ)
- (PROCESS_NO_ARCH, PARSE_PROC, INVALID_DWARF, UNSUPPORTED_DWARF)
- (NEXT_THREAD_FAIL, ATTACH_STATE_CONFLICT, NO_ATTACH_STATE, NO_UNWIND)
- (INVALID_ARGUMENT): New DWFL_ERROR entries.
- (struct Dwfl): New entry process.
- (struct Dwfl_Process, struct Dwfl_Thread, struct Dwfl_Frame)
- (__libdwfl_frame_reg_get, __libdwfl_frame_reg_set)
- (__libdwfl_process_free, __libdwfl_frame_unwind)
- (__libdwfl_attach_state_for_pid, __libdwfl_attach_state_for_core)
- (__libdwfl_segment_start, __libdwfl_segment_end): New declarations.
- (dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid)
- (dwfl_frame_thread, dwfl_thread_state_registers)
- (dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes)
- (dwfl_frame_pc): New INTDECL entries.
- * linux-proc-maps.c (dwfl_linux_proc_report): Call
- __libdwfl_attach_state_for_pid.
- * segment.c (segment_start): Rename to ...
- (__libdwfl_segment_start): ... here and make it internal_function.
- (segment_end): Rename to ...
- (__libdwfl_segment_end): ... here and make it internal_function.
- (reify_segments, dwfl_report_segment): Rename them at the callers.
-
-2013-11-07 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * core-file.c (dwfl_core_file_report): Remove the use of MAX.
-
-2013-11-07 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * core-file.c (dwfl_core_file_report): Replaced variable sniffed by
- retval. Fix one forgotten LISTED increase.
-
-2013-11-07 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Fix core files for re-prelink-ed files.
- * core-file.c (dynamic_vaddr_get): New function.
- (dwfl_core_file_report): New variable file_dynamic_vaddr. Call
- dynamic_vaddr_get instead of using L_ADDR.
- * libdwflP.h (struct r_debug_info_module): Remove field l_addr.
- * link_map.c (report_r_debug): Do not initialize l_addr.
-
-2013-11-07 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- Code cleanup.
- * core-file.c (dwfl_core_file_report): Reindent block of code by
- continue keyword.
-
-2013-10-30 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * argp-std.c (parse_opt): Use executable parameter of
- dwfl_core_file_report.
- * core-file.c (dwfl_core_file_report): Add parameter executable. Set
- it to DWFL. Add NEW_VERSION for it.
- (_compat_without_executable_dwfl_core_file_report): New. Twice.
- * libdwfl.h (dwfl_core_file_report): Add parameter executable, update
- the function comment.
-
-2013-10-15 Mark Wielaard <mjw@redhat.com>
-
- * linux-proc-maps.c (proc_maps_report): Ignore non-absolute file
- mappings.
- (dwfl_linux_proc_find_elf): Don't abort, just return failure.
-
-2013-09-12 Mark Wielaard <mjw@redhat.com>
-
- * cu.c (intern_cu): If dwarf_offdie fails free cu.
-
-2013-09-12 Mark Wielaard <mjw@redhat.com>
-
- * linux-proc-maps.c (proc_maps_report): Don't fclose FILE in
- bad_report.
-
-2013-09-12 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (find_symtab): Call elf_getdata with
- aux_xndxscn, not xndxscn, for aux_symxndxdata.
-
-2013-08-25 Mark Wielaard <mjw@redhat.com>
-
- * linux-kernel-modules.c (report_kernel): Pass add_p_vaddr as true
- to dwfl_report_elf.
-
-2013-07-25 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_segment_report_module.c (dwfl_segment_report_module): Check for
- conflicts all the modules, not just the first one. Compare L_LD if it
- is equal, not if it is in a module address range.
-
-2013-07-23 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * libdwflP.h (__libdwfl_elf_address_range): Add internal_function.
-
-2013-07-23 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * core-file.c (clear_r_debug_info): Close also ELF and FD.
- (dwfl_core_file_report): Call __libdwfl_report_elf for
- R_DEBUG_INFO.MODULE.
- * dwfl_report_elf.c (__libdwfl_elf_address_range): New function from
- code of ...
- (__libdwfl_report_elf): ... this function. Call it.
- * dwfl_segment_report_module.c: Include unistd.h.
- (dwfl_segment_report_module): Use basename for MODULE->NAME.
- Clear MODULE if it has no build-id and we have segment with build-id.
- Ignore this segment only if MODULE still contains valid ELF.
- * libdwflP.h (__libdwfl_elf_address_range): New declaration.
- (struct r_debug_info_module): New fields fd, elf, l_addr, start, end
- and disk_file_has_build_id.
- (dwfl_link_map_report): Extend the comment.
- * link_map.c (report_r_debug): Extend the comment. Always fill in new
- r_debug_info_module. Initialize also the new r_debug_info_module
- fields. Remove one FIXME comment. Call __libdwfl_elf_address_range
- instead of __libdwfl_report_elf when R_DEBUG_INFO is not NULL.
-
-2013-07-19 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * libdwflP.h (__libdwfl_find_elf_build_id): Add internal_function.
-
-2013-07-02 Mark Wielaard <mjw@redhat.com>
-
- * relocate.c (__libdwfl_relocate_value): Remove mod->e_type assert.
-
-2013-06-05 Mark Wielaard <mjw@redhat.com>
-
- * link_map.c (report_r_debug): Always call release_buffer after
- memory_callback succeeded reading build_id.
-
-2013-05-30 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * argp-std.c (parse_opt) <ARGP_KEY_SUCCESS> <opt->core> <opt->e>: Set
- executable_for_core before calling dwfl_core_file_report.
- * core-file.c (clear_r_debug_info): New function.
- (dwfl_core_file_report): Move raw segments reporting lower. New
- variable r_debug_info, pass it to dwfl_segment_report_module. Call
- clear_r_debug_info in the end. Return sum of LISTED and SNIFFED.
- * dwfl_module_build_id.c (check_notes): Move into
- __libdwfl_find_elf_build_id.
- (__libdwfl_find_build_id): Rename to ...
- (__libdwfl_find_elf_build_id): ... here. Add parameters build_id_bits,
- build_id_elfaddr and build_id_len. Verify MOD vs. ELF.
- (__libdwfl_find_elf_build_id) (check_notes): Remove parameters mod and
- set, rename data_vaddr to data_elfaddr. Do not call found_build_id.
- (__libdwfl_find_elf_build_id): Update the check_notes caller, do not
- adjust its data_elfaddr parameter.
- (__libdwfl_find_build_id): New wrapper of __libdwfl_find_elf_build_id.
- * dwfl_segment_report_module.c (dwfl_segment_report_module): New
- parameter r_debug_info. New variable name_is_final. Adjust addresses
- according to R_DEBUG_INFO->MODULE. Check conflicts against DWFL.
- Do not overwrite NAME by SONAME if NAME_IS_FINAL.
- * libdwflP.h (__libdwfl_find_elf_build_id): New declaration.
- (struct r_debug_info_module, struct r_debug_info): New definitions.
- (dwfl_segment_report_module, dwfl_link_map_report): Add parameter
- r_debug_info.
- * link_map.c: Include fcntl.h.
- (report_r_debug): Add parameter r_debug_info, describe it in the
- function comment. Delete dwfl_addrmodule call and its dependent code.
- Verify build-id before calling dwfl_report_elf, also supply
- executable_for_core to it. Store r_debug_info->module info when
- appropriate.
- (dwfl_link_map_report): Add parameter r_debug_info. New variable
- in_ok. Try to read IN from EXECUTABLE_FOR_CORE. Update report_r_debug
- caller parameters.
-
-2013-04-30 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr.
- Set it to true for ET_EXEC and ET_CORE. Provide alternative
- setup of START and BIAS if !ADD_P_VADDR. Set END from BIAS, not BASE.
- (dwfl_report_elf): Add parameter add_p_vaddr. Pass it down. Add
- NEW_VERSION.
- (_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with
- COMPAT_VERSION.
- * libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr. Describe it.
- * libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr.
- * link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf.
- * linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for
- dwfl_report_elf.
- * offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
-
-2013-04-27 Mark Wielaard <mjw@redhat.com>
-
- * link_map.c: #include system.h.
-
-2013-04-26 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * link_map.c (BE32, BE64, LE32, LE64): Delete the definitions, move
- them to lib/system.h.
-
-2013-04-24 Mark Wielaard <mjw@redhat.com>
-
- * Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
-
-2013-03-20 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Remove BASE aligning.
-
-2013-03-12 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_getsrclines.c (dwfl_getsrclines): Return 0 on success.
-
-2013-02-22 Mark Wielaard <mjw@redhat.com>
-
- * open.c (__libdw_gunzip,__libdw_bunzip2,__libdw_unlzma): Define
- as DWFL_E_BADELF when not used.
-
-2013-02-10 Mark Wielaard <mjw@redhat.com>
-
- * argp-std.c (parse_opt): Use opt->core and opt->e explicitly in
- failure messages When handling ARGP_KEY_SUCCESS because arg will
- not have been set.
-
-2013-01-30 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * linux-proc-maps.c: Include system.h.
- (PROCEXEFMT, get_pid_class): New.
- (grovel_auxv): Detect 32-bit vs. 64-bit auxv, possibly call
- get_pid_class.
-
-2013-01-23 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_getdwarf.c (find_aux_sym): Don't substract one
- from aux_syments by default.
- (find_symtab): Also succeed when only aux_symdata is found.
- When no symtab is found always try to load auxiliary table.
- (dwfl_module_getsymtab): Substract one from result when both
- tables have symbols.
- * dwfl_module_getsym.c (dwfl_module_getsym): Only skip auxiliary
- zero entry when both tables have symbols.
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Only substract
- one from first_global when both tables have symbols.
-
-2013-01-16 Mark Wielaard <mjw@redhat.com>
-
- * libdwflP.h (struct Dwfl_Module): Add aux_sym, aux_symdata,
- aux_syments, aux_symstrdata, aux_symxndxdata and aux_first_global.
- (dwfl_adjusted_aux_sym_addr): New function.
- (dwfl_deadjust_aux_sym_addr): Likewise.
- (dwfl_adjusted_st_value): Take and check symfile argument.
- (dwfl_deadjust_st_value): Likewise.
- * dwfl_module_getdwarf.c (find_prelink_address_sync): Take and
- use dwfl_file as argument to set address_sync.
- (find_debuginfo): Call find_prelink_address_sync with debug file.
- (find_aux_sym): New function.
- (find_symtab): Use find_aux_sym if all we have is the dynsym table
- and fill in aux DwflModule fields.
- (dwfl_module_getsymtab): Return syments plus aux_syments.
- (load_symtab): Always set first_global.
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Check symfile
- when using same_section. Calculate first_global based on both
- mod->first_global and mod->aux_first_global.
- * dwfl_module.c (__libdwfl_module_free): Free aux_sym.
- * dwfl_module_getsym.c (dwfl_module_getsym): Use auxsym table
- to retrieve symbol and name if necessary, making sure all locals
- from any table come before any globals.
- * dwfl_module_info.c (dwfl_module_info): Call dwfl_adjusted_st_value
- with symfile.
- * relocate.c (resolve_symbol): Likewise.
-
-2013-01-07 Roland McGrath <roland@hack.frob.com>
-
- * link_map.c (auxv_format_probe): Handle unaligned 64-bit data, but
- still assume the data is at least 32-bit aligned anyway.
- (dwfl_link_map_report): Handle unaligned auxv data.
-
-2012-12-11 Mark Wielaard <mjw@redhat.com>
-
- * linux-kernel-modules.c (report_kernel): Only free fname if
- find_kernel_elf succeeds and allocates it.
- (report_kernel_archive): Fix brackets around unlikely expression.
-
-2012-11-29 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * argp-std.c: Update Copyright year.
- (offline_find_elf): New function.
- (offline_callbacks): Use it for find_elf.
- (struct parse_opt): New.
- (parse_opt): New key ARGP_KEY_INIT. In other make hook struct
- parse_opt pointer from former Dwfl pointer. Delay 'e and OPT_COREFILE
- processing till ARGP_KEY_SUCCESS. Initialize state->input already from
- ARGP_KEY_SUCCESS. Modify the cleanup in ARGP_KEY_ERROR. Make the
- final state->input initialization optional.
- * dwfl_end.c: Update Copyright year.
- (dwfl_end): Free executable_for_core.
- * libdwflP.h: Update Copyright year.
- (struct Dwfl): New field executable_for_core.
-
-2012-11-20 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Simplify START and BIAS
- calculation.
-
-2012-10-17 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_module_getdwarf.c (mod_verify_build_id): New function with code
- from ...
- (__libdwfl_getelf): ... here. Call it.
-
-2012-10-17 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * libdwfl.h (dwfl_module_getelf): Add __nonnull_attribute__.
-
-2012-10-10 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_segment_report_module.c (dwfl_segment_report_module):
- Initialize mod->MAIN_BIAS.
-
-2012-10-10 Jan Kratochvil <jan.kratochvil@redhat.com>
-
- * dwfl_module_addrsym.c (dwfl_module_addrsym): New function
- binding_value. Use it for both zero and non-zero size symbols
- comparisons.
-
-2012-10-01 Mark Wielaard <mjw@redhat.com>
-
- * cu.c (cudie_offset): Don't use type_sig8, it might not be
- initialized and these are always real CUs, never TUs.
-
-2012-10-01 Mark Wielaard <mjw@redhat.com>
-
- * derelocate.c (find_section): Check next section exists before
- accessing it.
-
-2012-08-01 Petr Machata <pmachata@redhat.com>
-
- * offline.c (process_archive_member): Ignore entry "/SYM64/".
-
-2012-03-28 Roland McGrath <roland@hack.frob.com>
-
- * dwfl_segment_report_module.c
- (dwfl_segment_report_module: read_portion): Don't use existing buffer
- when FILESZ is zero (string mode) and available portion doesn't hold
- a terminated string.
-
-2011-12-02 Roland McGrath <roland@hack.frob.com>
-
- * elf-from-memory.c (elf_from_remote_memory): Fix ELFCLASS64 case
- to use elf64_xlatetom and PHDRS.p64.
- Reported by Serge Pavlov <serge.pavlov.at.gnu@gmail.com>.
-
-2011-11-31 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_addrsym.c (dwfl_module_addrsym): First search all
- global symbols. Then only when that doesn't provide a match search
- all local symbols too.
- * dwfl_module_getdwarf.c (load_symtab): Take first_global int arg
- and fill it in.
- (find_symtab): Initialize mod->first_global and pass it to load_symtab.
- * libdwfl/libdwflP.h (Dwfl_Module): Add first_global field.
-
-2011-11-31 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Only update
- sizeless_sym if needed and closer to desired addr.
-
-2011-10-20 Mark Wielaard <mjw@redhat.com>
-
- * derelocate.c (cache_sections): Intern mod->reloc_info check.
- (dwfl_module_relocations): Don't check mod->reloc_info.
- (dwfl_module_relocation_info): Likewise.
- (find_section): Likewise.
-
-2011-07-09 Roland McGrath <roland@hack.frob.com>
-
- * image-header.c (LE32): Macro removed (now in lib/system.h).
-
-2011-04-11 Mark Wielaard <mjw@redhat.com>
-
- * linux-kernel-modules.c (vmlinux_suffixes): Guard definition
- by check for zlib, bzlib or lzma defines to check it isn't empty.
- (try_kernel_name): Use same guard for use of vmlinux_suffixes.
-
-2011-03-08 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Clear errno before CBFAIL.
- Reported by Kurt Roeckx <kurt@roeckx.be>.
-
-2011-02-11 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (try_kernel_name): Try .gz, .bz2, .xz
- suffixes if corresponding decompression support is enabled.
-
-2011-02-01 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (find_prelink_address_sync): Use the
- section-end address as the synchronization point, rather than sh_addr.
-
- * dwfl_module_getdwarf.c (find_prelink_address_sync): Discover
- PT_INTERP p_vaddr separately from main phdrs and undo phdrs.
-
- * dwfl_module_getdwarf.c (find_prelink_address_sync): Fix pasto in
- last change, so we recognize PT_INTERP in ELFCLASS64 correctly.
-
-2011-01-11 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Remove section-based
- address_sync fixup from here.
- (find_prelink_address_sync): New function.
- (find_debuginfo): Call it.
- * libdwflP.h (DWFL_ERRORS): Add BAD_PRELINK error.
-
-2011-01-04 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Enhance address_sync calculation
- logic to consider section addresses, the better to survive all the
- possible prelink machinations.
- * libdwflP.h (struct dwfl_file): Comment change.
-
-2010-11-30 Roland McGrath <roland@redhat.com>
-
- * derelocate.c (dwfl_module_relocations): Remove over-eager assert.
-
-2010-11-12 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h (struct Dwfl_Module): New member main_bias.
- (dwfl_adjusted_address, dwfl_deadjust_address): Use it.
- * dwfl_module_getdwarf.c (__libdwfl_getelf): Initialize it.
-
- * libdwflP.h (dwfl_deadjust_address): New function.
- (dwfl_deadjust_dwarf_addr, dwfl_deadjust_st_value): New functions.
- * cu.c (addrarange): Use dwfl_deadjust_dwarf_addr.
- * dwfl_module_addrsym.c: Use dwfl_deadjust_st_value.
-
-2010-11-11 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h (struct dwfl_file): Remove bias member.
- Add vaddr and address_sync members instead.
- (dwfl_adjusted_address): Calculate using vaddr.
- (dwfl_adjusted_dwarf_addr): Calculate using address_sync and call that.
- (dwfl_adjusted_st_value): Use one of those calls.
- * dwfl_module_getdwarf.c (open_elf): Initialize vaddr and address_sync.
- * dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise.
- * derelocate.c (dwfl_module_relocations): Update ET_EXEC assertions.
- * link_map.c (consider_executable): Adjust only MOD->low_addr for
- detected PIE bias change.
-
- * libdwflP.h (dwfl_adjusted_dwarf_addr): New function.
- * dwfl_module_info.c: Use it.
- * cu.c (addrarange): Likewise.
- * dwfl_dwarf_line.c: Likewise.
- * dwfl_module_dwarf_cfi.c: Likewise.
- * dwfl_lineinfo.c: Likewise.
- * dwfl_nextcu.c: Likewise.
- * dwfl_module_getdwarf.c (dwfl_module_getdwarf): Likewise.
-
- * libdwflP.h (dwfl_adjusted_st_value): New function.
- * relocate.c (resolve_symbol): Use it.
- * dwfl_module_getsym.c: Likewise.
- * dwfl_module_addrsym.c: Likewise.
- * dwfl_module_info.c: Likewise.
-
- * libdwflP.h (dwfl_adjusted_address): New function.
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Use it.
- * relocate.c (__libdwfl_relocate_value): Likewise.
- * derelocate.c (cache_sections): Likewise.
- (dwfl_module_address_section): Likewise.
- * dwfl_module_getelf.c: Likewise.
- * dwfl_module_eh_cfi.c: Likewise.
- * link_map.c (consider_executable): Likewise.
-
-2010-08-24 Roland McGrath <roland@redhat.com>
-
- * dwfl_dwarf_line.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
-
-2010-08-18 Roland McGrath <roland@redhat.com>
-
- * link_map.c (report_r_debug): Use found name if we have no name,
- even if we already have an Elf handle.
-
-2010-06-30 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't be
- confused by -1 return from dwfl_build_id_find_elf after it opened
- the Elf handle.
- * find-debuginfo.c (dwfl_standard_find_debuginfo): Likewise for
- dwfl_build_id_find_debuginfo.
-
-2010-06-16 Roland McGrath <roland@redhat.com>
-
- * cu.c (cudie_offset): Use DIE_OFFSET_FROM_CU_OFFSET macro.
-
-2010-06-14 Roland McGrath <roland@redhat.com>
-
- * find-debuginfo.c (try_open): Take new arg MAIN_STAT. Compare
- candidate file to that st_dev/st_ino and pretend it didn't exist
- if they match.
- (find_debuginfo_in_path): Update caller, pass main file's info.
-
-2010-05-20 Roland McGrath <roland@redhat.com>
-
- * linux-proc-maps.c (find_sysinfo_ehdr): Renamed to ...
- (grovel_auxv): ... this. Take DWFL argument.
- (dwfl_linux_proc_report): Update caller.
-
- * dwfl_module_getdwarf.c (open_elf): Calculate alignment for bias
- based on dwfl->segment_align or manifest alignment of MOD->low_addr.
-
-2010-05-19 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (intuit_kernel_bounds): Rewritten.
-
-2010-05-06 Roland McGrath <roland@redhat.com>
-
- * segment.c (insert): Clear inserted elements of DWFL->lookup_module.
-
- * libdwflP.h (DWFL_ERRORS): Add WRONG_ID_ELF.
- * dwfl_build_id_find_elf.c: Set MOD->main.valid when there is a build
- ID but we didn't find a file.
- * dwfl_module_getdwarf.c (__libdwfl_getelf): When that's set, check
- and refuse any fallback file-by-name if it lacks the matching ID.
-
- * dwfl_error.c (dwfl_errno): Add INTDEF.
- * libdwflP.h: Add INTDECL.
-
- * dwfl_module_getdwarf.c (open_elf): Do elf_end and clear FILE->elf in
- failure cases.
-
-2010-05-04 Roland McGrath <roland@redhat.com>
-
- * dwfl_segment_report_module.c: Use "[pie]" rather than "[dso]" for an
- ET_DYN that has a DT_DEBUG.
-
- * dwfl_segment_report_module.c: Fix jump-start of NDX-finding loop.
-
- * segment.c (insert): Fix moving of values following insertion.
- (reify_segments): Fix up MOD->segment backpointer indices after
- later insertions in the main loop invalidate them.
-
- * link_map.c (dwfl_link_map_report): Detect bias of embedded phdrs and
- apply it to PT_DYNAMIC p_vaddr so we handle a PIE correctly.
-
- * core-file.c (dwfl_core_file_report): Return any nonzero count of
- modules reported, even if link_map grovelling failed and only sniffing
- found anything.
-
-2010-04-26 Roland McGrath <roland@redhat.com>
-
- * relocate.c (relocate_section): Treat R_*_NONE reloc as no reloc.
- Works around probably-wrong ld -r behavior for case of a DWARF address
- constant that refers to a discarded SHF_ALLOC section.
-
-2010-04-14 Roland McGrath <roland@redhat.com>
-
- * link_map.c (report_r_debug): Limit iterations on the l_next chain to
- an upper bound on sane possible number of elements.
-
-2010-03-11 Roland McGrath <roland@redhat.com>
-
- * link_map.c (auxv_format_probe): Fix scanning loop, so we really scan
- the second half for 32-bit matches.
-
-2010-03-10 Roland McGrath <roland@redhat.com>
-
- * core-file.c (dwfl_core_file_report): Punt EHDR argument.
- * argp-std.c (parse_opt): Update caller.
- * libdwfl.h: Declare dwfl_core_file_report.
- * libdwflP.h: Don't.
-
-2010-02-17 Roland McGrath <roland@redhat.com>
-
- * dwfl_segment_report_module.c (addr_segndx): Take new flag argument.
- If set, find the first index not below ADDR.
- (dwfl_segment_report_module): Update callers.
- Pass true when calculating return value.
-
-2010-02-15 Roland McGrath <roland@redhat.com>
-
- * Makefile.am: Use config/eu.am for common stuff.
-
- * find-debuginfo.c (find_debuginfo_in_path): Fix uninitialized
- variable in failure path.
-
-2010-02-02 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_module_dwarf_cfi.c (dwfl_module_dwarf_cfi): Always set bias.
- * dwfl_module_eh_cfi.c (dwfl_module_eh_cfi): Likewise
-
-2010-01-07 Roland McGrath <roland@redhat.com>
-
- * core-file.c (dwfl_core_file_report): Use elf_getphdrnum.
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise.
- * dwfl_module_getdwarf.c (open_elf, find_dynsym): Likewise.
- * dwfl_report_elf.c (__libdwfl_report_elf): Likewise.
-
-2010-01-06 Roland McGrath <roland@redhat.com>
-
- * relocate.c (relocate_getsym): For SHN_COMMON, zero st_value.
- (relocate_section): Let unresolved SHN_COMMON symbol stay 0.
-
-2009-11-16 Roland McGrath <roland@redhat.com>
-
- * relocate.c (relocate_section): Skip SHT_NOBITS or empty target scn.
-
-2009-11-12 Petr Machata <pmachata@redhat.com>
-
- * core-file.c (dwfl_elf_phdr_memory_callback): Only load ahead if
- the chunk is both offset-contiguous and vaddr-contiguous.
-
-2009-11-05 Roland McGrath <roland@redhat.com>
-
- * link_map.c (report_r_debug): Skip entries with l_ld==0.
- Use dwfl_addrmodule for l_ld lookup, don't bail on lookup failure.
-
-2009-09-04 Roland McGrath <roland@redhat.com>
-
- * image-header.c (__libdw_image_header): Fix tranposed comparison.
-
-2009-08-27 Roland McGrath <roland@redhat.com>
-
- * image-header.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwflP.h: Declare __libdw_image_header.
- * open.c (decompress): Don't consume ELF on failure.
- (what_kind): New function, broken out of ...
- (__libdw_open_file): ... here. Call it.
- If it fails, try __libdw_image_header and then try what_kind again.
-
- * gzip.c (unzip): Reuse *WHOLE as first INPUT_BUFFER,
- leave it behind for next decompressor.
- * open.c (decompress): Free BUFFER on failure.
-
-2009-08-26 Roland McGrath <roland@redhat.com>
-
- * gzip.c (find_zImage_payload): New function, broken out of ...
- (mapped_zImage): ... here. Call it.
- (find_zImage_payload) [LZMA]: Match LZMA-compressed kernels with
- stupid method of just trying the decoder.
-
- * open.c [USE_LZMA]: Try __libdw_unlzma.
- * libdwflP.h: Declare it.
- (DWFL_ERRORS): Add DWFL_E_LZMA.
- * gzip.c [LZMA]: Implement liblzma version for XZ file format.
- * lzma.c: New file.
- * Makefile.am [LZMA] (libdwfl_a_SOURCES): Add it.
-
- * gzip.c (mapped_zImage): Limit scan to 32kb.
- Make this unconditional, support bzip2 kernel images too.
- (unzip): Use direct inflate method for non-mmap case too.
- Only zlib uses the stream method.
-
-2009-08-09 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_build_id.c: Use new macros for versioned definitions.
-
-2009-07-08 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_dwarf_cfi.c: New file.
- * dwfl_module_eh_cfi.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add them.
- * libdwflP.h (struct Dwfl_Module): New members `dwarf_cfi', `eh_cfi.
- Add INTDECL for dwfl_module_eh_cfi, dwfl_module_dwarf_cfi.
-
-2009-07-08 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h (struct Dwfl_Module): Reorder members to pack better.
-
-2009-06-18 Mark Wielaard <mjw@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Return NULL on overlap.
-
-2009-06-13 Ulrich Drepper <drepper@redhat.com>
-
- * derelocate.c: Don't use deprecated libelf functions.
- * dwfl_module_getdwarf.c: Likewise.
- * relocate.c: Likewise.
-
-2009-04-23 Ulrich Drepper <drepper@redhat.com>
-
- * dwfl_module_build_id.c: Define versioned symbols only if SHARED is
- defined. Otherwise just define the latest version.
-
-2009-04-22 Roland McGrath <roland@redhat.com>
-
- * relocate.c (resolve_symbol): Apply correct bias to st_value found in
- a non-ET_REL module.
-
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Fix last change to
- adjust properly for non-ET_REL.
-
-2009-04-21 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getsym.c: Apply non-ET_REL bias only if SHF_ALLOC.
-
- * relocate.c (__libdwfl_relocate_value): Assert that MOD is ET_REL.
- * derelocate.c (cache_sections): Call __libdwfl_relocate_value only
- for ET_REL.
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise.
-
-2009-04-20 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (__libdwfl_getelf): Add internal_function.
-
-2009-04-19 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (find_file): Renamed to ...
- (__libdwfl_getelf): ... this. Make it global.
- (find_symtab, find_dw): Update callers.
- (dwfl_module_getelf): Functions moved ...
- * dwfl_module_getelf.c: ... here, new file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwflP.h: Declare __libdwfl_getelf.
-
-2009-04-14 Roland McGrath <roland@redhat.com>
-
- * dwfl_segment_report_module.c: Handle DT_STRTAB value being either
- absolute (already adjusted in place) or needing load bias adjustment.
-
- * core-file.c (dwfl_elf_phdr_memory_callback): Fix return value for
- gelf_getphdr failure. Fix file size limit checks.
-
- * dwfl_segment_report_module.c: Fix underflow in DYNSTRSZ check.
-
-2009-04-08 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getsym.c: Don't adjust for bias again after
- __libdwfl_relocate_value.
-
- * relocate.c (__libdwfl_relocate_value): Don't adjust a value from
- a non-SHF_ALLOC section.
- (relocate_getsym): Test st_shndx for SHN_* values, not *SHNDX.
- * dwfl_module_getsym.c (dwfl_module_getsym): Likewise.
-
-2009-03-09 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Move SHSTRNDX
- variable to outer scope, so we cache it for the loop.
-
- * relocate.c (__libdwfl_relocate_value): Add MOD->main.bias to sh_addr.
-
-2009-02-12 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Use
- __libdwfl_relocate_value to find correct sh_addr value.
-
-2009-02-10 Roland McGrath <roland@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Take new arg SANITY.
- If false, don't fail for NO_PHDR.
- (dwfl_report_elf): Update caller.
- * libdwflP.h: Update decl.
- * offline.c (process_elf): Call it with false, so we don't refuse
- dubiously-formed objects here.
-
- * link_map.c (consider_executable): Don't assert dwfl_addrsegment
- finds our module. We shouldn't crash when we confuse some guesses.
-
-2009-02-10 Ulrich Drepper <drepper@redhat.com>
-
- * open.c (decompress): Avoid crash with empty input file.
-
-2009-01-27 Roland McGrath <roland@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Ignore trailing PT_LOAD
- with zero vaddr and memsz.
-
-2009-01-22 Roland McGrath <roland@redhat.com>
-
- * open.c (decompress): Move BUFFER, SIZE decls outside #if.
-
- * dwfl_segment_report_module.c (addr_segndx): Remove bogus adjustments
- after address-matching loop.
-
- * segment.c (lookup): Fix fencepost in checking for HINT match.
-
-2009-01-14 Roland McGrath <roland@redhat.com>
-
- * gzip.c [!BZLIB] (mapped_zImage): New function.
- (unzip) [!BZLIB]: Grok Linux kernel zImage format.
-
-2009-01-10 Ulrich Drepper <drepper@redhat.com>
-
- * dwfl_error.c: Always use __thread. Remove all !USE_TLS code.
-
-2009-01-08 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_offline):
- Skip subdirectory named "source".
- (dwfl_linux_kernel_find_elf): Likewise.
-
-2009-01-06 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (check_suffix): New function.
- Match ".ko", ".ko.gz", and ".ko.bz2" suffixes.
- (dwfl_linux_kernel_report_offline): Use it.
- (dwfl_linux_kernel_find_elf): Likewise.
-
-2009-01-05 Roland McGrath <roland@redhat.com>
-
- * argp-std.c (parse_opt): Use __libdw_open_file for core file.
- * dwfl_build_id_find_debuginfo.c: Use it to open the file.
- * dwfl_build_id_find_elf.c: Likewise.
- * dwfl_module_getdwarf.c (open_elf): Likewise.
- * dwfl_report_elf.c: Likewise.
- * find-debuginfo.c (validate): Likewise.
- * offline.c (__libdwfl_report_offline): Likewise.
-
- * libdwflP.h: Declare __libdw_open_file.
- * open.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
-
- * gzip.c: New file.
- * Makefile.am [ZLIB] (libdwfl_a_SOURCES): Add it.
- * bzip2.c: New file.
- * Makefile.am [BZLIB] (libdwfl_a_SOURCES): Add it.
- * libdwflP.h: Declare __libdw_gunzip, __libdw_bunzip2.
-
-2008-12-16 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_build_id.c (dwfl_module_build_id): Define with alias and
- symver magic to bind to ELFUTILS_0.138.
- (_BUG_COMPAT_dwfl_module_build_id): New function, bug compatible
- wrapper for ELFUTILS_0.130 version set.
-
-2008-12-18 Roland McGrath <roland@redhat.com>
-
- * derelocate.c (dwfl_module_relocate_address): Fix last fix: ET_DYN
- addresses are taken as relative to MOD->low_addr.
-
-2008-12-15 Roland McGrath <roland@redhat.com>
-
- * derelocate.c (dwfl_module_relocate_address): Apply main.bias, not
- debug.bias.
-
-2008-12-11 Roland McGrath <roland@redhat.com>
-
- * offline.c (process_archive): Don't call elf_end and close if
- returning NULL. Check first elf_begin call and set error code
- specially for empty archive.
- Fixes RHBZ#465878.
-
-2008-12-02 Roland McGrath <roland@redhat.com>
-
- * dwfl_getmodules.c (dwfl_getmodules): Typo fix in last change.
-
-2008-11-26 Roland McGrath <roland@redhat.com>
-
- * dwfl_getmodules.c (dwfl_getmodules): Encode iteration style in
- return value, and interpret encoded OFFSET argument.
-
-2008-10-07 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_build_id.c (check_notes): Fix typo in vaddr calculation.
-
-2008-09-29 Roland McGrath <roland@redhat.com>
-
- * segment.c (insert): Must realloc DWFL->lookup_module here too.
- (dwfl_report_segment): Clear DWFL->lookup_module before insert calls.
-
-2008-08-28 Roland McGrath <roland@redhat.com>
-
- * segment.c (reify_segments): Fix last change.
-
-2008-08-27 Roland McGrath <roland@redhat.com>
-
- * linux-proc-maps.c (read_proc_memory): Return 0 for EINVAL or EPERM
- failure from pread64.
-
-2008-08-26 Roland McGrath <roland@redhat.com>
-
- * segment.c (reify_segments): Insert a trailing segment for a module
- end that is above the highest current segment.
-
-2008-08-25 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Extract elf_errno () for
- coded return value, not plain DWFL_E_LIBELF. Return DWFL_E_BADELF
- if FILE->elf is not ELF_K_ELF.
-
- * dwfl_segment_report_module.c: Add a cast.
-
-2008-08-21 Denys Vlasenko <dvlasenk@redhat.com>
-
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Improve logic
- which decides which symbol is "closest" to a given address.
-
-2008-08-15 Roland McGrath <roland@redhat.com>
-
- * argp-std.c (offline_callbacks): Use dwfl_build_id_find_elf.
- (options, parse_opt): Handle --core.
-
- * core-file.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwflP.h (dwfl_core_file_report): Declare it.
-
- * link_map.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwflP.h (dwfl_link_map_report): Declare it.
-
- * libdwflP.h (MIN, MAX): New macros.
- (Dwfl_Memory_Callback): New typedef.
- (Dwfl_Module_Callback): New typedef.
- (dwfl_segment_report_module): Declare it.
- * dwfl_segment_report_module.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
-
- * derelocate.c (dwfl_module_address_section): Add INTDEF.
- * libdwflP.h: Add INTDECL.
-
- * segment.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_addrsegment, dwfl_report_segment.
- * libdwflP.h (struct Dwfl): New members lookup_elts, lookup_alloc,
- lookup_addr, lookup_module, lookup_segndx, replace removed members
- modules, nmodules.
- (struct Dwfl_Module): New member segment.
- * dwfl_end.c (dwfl_end): Free the new ones. Iterate via modulelist
- to each free module.
- * dwfl_module.c (dwfl_report_begin_add): Do nothing.
- (dwfl_report_begin): Don't call it. Truncate the segment table instead.
- (dwfl_report_module): Don't touch DWFL->nmodules.
- (dwfl_report_end): Don't touch DWFL->modules and DWFL->nmodules.
- (compare_modules): Function removed.
- * dwfl_getmodules.c: Rewritten.
- Add INTDEF.
- * libdwflP.h: Add INTDECLs.
- * dwfl_getdwarf.c: Rewritten to call dwfl_getmodules.
- * dwfl_addrmodule.c: Rewritten to just call dwfl_addrsegment.
-
-2008-08-03 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c: Include <fts.h> before <config.h>.
-
-2008-07-17 Roland McGrath <roland@redhat.com>
-
- * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Set errno to
- zero if the failure was only ENOENT.
-
-2008-06-03 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_addrsym.c (dwfl_module_addrsym): Exclude undefined
- symbols.
-
-2008-05-22 Petr Machata <pmachata@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Bias of ET_EXEC files is always 0.
-
-2008-05-06 Roland McGrath <roland@frob.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Use
- FTS_LOGICAL here too.
- (dwfl_linux_kernel_find_elf): Likewise.
-
-2008-04-29 Roland McGrath <roland@redhat.com>
-
- * find-debuginfo.c (dwfl_standard_find_debuginfo): Try path search
- based on canonicalize_file_name if it differs from the supplied name.
-
- * linux-kernel-modules.c (check_module_notes): Use FTS_LOGICAL so
- we accept symlinks.
-
-2008-04-27 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (report_kernel): Fix crash when
- dwfl_report_elf fails.
-
-2008-04-05 Roland McGrath <roland@redhat.com>
-
- * linux-proc-maps.c (proc_maps_report): Don't leak LAST_FILE.
-
- * dwfl_module_getdwarf.c (find_file): Always free build_id_bits.
- Clear it after freeing.
- * dwfl_module_report_build_id.c (dwfl_module_report_build_id): Likewise.
-
-2008-03-26 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (load_symtab): Don't return success for
- SHT_DYNSYM, just set *SYMSCN like the comment says.
-
- * dwfl_end.c (dwfl_end): Iterate on modulelist chain, not modules array.
-
- * argp-std.c (parse_opt): On failure, call dwfl_end before argp_failure.
-
-2008-03-19 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getsrc.c: Adjust address for module bias before search.
-
-2008-03-01 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h (__libdwfl_seterrno): Remove parameter name from
- prototype to avoid older compiler's complaint about reuse of the name.
- (__libdwfl_canon_error): Likewise.
-
-2008-02-19 Roland McGrath <roland@redhat.com>
-
- * relocate.c (relocate_section): Check for an unhandled relocation
- type before resolving a reloc's symbol. Lift DWFL_E_BADRELTYPE ->
- DWFL_E_UNKNOWN_MACHINE check out of loops.
-
- * dwfl_module_getdwarf.c (load_dw): Skip relocation if
- DEBUGFILE->relocated is already set.
-
-2008-01-26 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (open_elf): Open FILE->name if it's non-null.
-
- * dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Don't clear
- incoming *FILE_NAME at the start.
-
-2008-01-08 Roland McGrath <roland@redhat.com>
-
- * Makefile.am (euinclude): Variable removed.
- (pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
-
-2007-10-23 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (report_kernel_archive): Reorder the kernel
- module to appear first.
-
-2007-10-20 Roland McGrath <roland@redhat.com>
-
- * offline.c (process_archive_member): Take FD argument, pass it down
- to process_file. Return Elf_Cmd, not bool.
- Call elf_next here, always before elf_end.
- (process_archive): Update caller. Don't close FD here unless there
- are no member refs.
-
- * dwfl_module.c (free_file): Close fd only when elf_end returns zero.
-
- * libdwflP.h (struct dwfl_file): New bool member `relocated'.
- * dwfl_module_getdwarf.c (dwfl_module_getelf): For ET_REL, apply
- partial relocation to one or both files.
- (dwfl_module_getdwarf): For ET_REL, make sure extra sections'
- relocations have been applied to the debug file if dwfl_module_getelf
- has been used before.
-
- * relocate.c (resolve_symbol): New function.
- (relocate_section): Call it.
-
- * relocate.c (relocate_getsym): Handle null MOD->symfile.
- (relocate_section): Take new bool arg, PARTIAL. If true,
- no error for BADRELTYPE/RELUNDEF, instead just skip them
- and leave only those skipped relocs behind the reloc section.
- (__libdwfl_relocate_section): Take new arg, pass it down.
- (__libdwfl_relocate): Take new bool arg, DEBUG. If false,
- do partial relocation on all sections.
- * dwfl_module_getdwarf.c (load_dw): Update caller.
- * libdwflP.h: Update decls.
- * derelocate.c (dwfl_module_address_section): Pass new argument
- to __libdwfl_relocate_section, true.
-
- * derelocate.c (cache_sections): Don't cache reloc sections when
- section_address callback is null.
-
-2007-10-19 Roland McGrath <roland@redhat.com>
-
- * relocate.c (relocate_section): Fix fencepost error in r_offset check.
-
- * derelocate.c (struct dwfl_relocation): Add member `relocs'.
- (struct secref): Likewise.
- (cache_sections): Cache the relocation section referring to each
- section we cache, if any.
- (dwfl_module_address_section): Use __libdwfl_relocate_section as
- necessary.
-
- * relocate.c (struct reloc_symtab_cache): New type.
- (relocate_getsym): Use it instead of four arguments.
- (__libdwfl_relocate): Update caller.
- (relocate_section): New function, broken out of ...
- (__libdwfl_relocate): ... here.
- (__libdwfl_relocate_section): New function.
- * libdwflP.h: Declare it.
-
-2007-10-17 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getsym.c (dwfl_module_getsym): Apply MOD->symfile->bias
- to relocated st_value.
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Align initial BASE for
- ET_REL to 0x100.
-
-2007-10-16 Roland McGrath <roland@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Readjust BASE when a later
- section has larger alignment requirements not met by the original BASE,
- rather than padding more between sections.
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Fix bias calculation.
-
- * dwfl_module_build_id.c (__libdwfl_find_build_id): Apply module bias
- to sh_addr value.
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Don't be confused by BASE
- at zero in ET_REL case. Adjust BASE to necessary alignment.
-
- * dwfl_module_build_id.c (check_notes): Take -1, not 0, as stub value
- for DATA_VADDR.
- (__libdwfl_find_build_id): Update caller.
-
- * relocate.c (__libdwfl_relocate_value): Don't use sh_offset.
- * dwfl_report_elf.c (__libdwfl_report_elf): Likewise.
- * offline.c (dwfl_offline_section_address): Bail early if there is
- separate debug file.
-
- * relocate.c (__libdwfl_relocate): Don't return DWFL_E_NO_DWARF.
-
-2007-10-09 Roland McGrath <roland@redhat.com>
-
- * dwfl_report_elf.c (__libdwfl_report_elf): Clear SHDR->sh_offset when
- caching SHDR->sh_addr = 0.
- * offline.c (dwfl_offline_section_address): Never called for sh_addr
- really at 0, don't check for it. Use MOD->debug directly, not symfile.
-
- * dwfl_module_getdwarf.c (load_symtab): Return success properly when
- we've found SHT_SYMTAB.
-
- * relocate.c (relocate_getsym): New function.
- (__libdwfl_relocate): Use it.
- (__libdwfl_relocate_value): Take new Elf * argument. Make SYMSHSTRNDX
- be a pointer instead of value; cache getshstrndx result there.
- * libdwflP.h: Update decl.
- * derelocate.c (cache_sections): Update caller.
- Always work on the main file, not the symfile.
- (dwfl_module_address_section): Likewise.
- * dwfl_module_getsym.c (dwfl_module_getsym): Update caller.
-
-2007-10-07 Roland McGrath <roland@redhat.com>
-
- * offline.c (process_archive): Initialize MOD.
-
- * linux-kernel-modules.c (get_release): New function, broken out of ...
- (report_kernel): ... here. Call it.
- (try_kernel_name): Take new arg TRY_DEBUG, only try ".debug" if set.
- (find_kernel_elf): Update caller.
- (report_kernel_archive): New function.
- (dwfl_linux_kernel_report_offline): Call it.
-
- * offline.c (process_file): Take new arg PREDICATE, pass it down.
- (process_archive): Likewise.
- (process_archive_member): Likewise. When nonnull, let the predicate
- decide whether to use this member.
- (__libdwfl_report_offline): New function, broken out of ...
- (dwfl_report_offline): ... here. Call it.
- * libdwflP.h: Declare it.
-
- * offline.c (process_archive, process_archive_member): New functions.
- (process_elf, process_file): New functions, broken out of ...
- (dwfl_report_offline): ... here. Call process_file, which recurses on
- ELF_K_AR files.
-
- * dwfl_report_elf.c (__libdwfl_report_elf): New, broken out of ...
- (dwfl_report_elf): ... here. Call it.
- * libdwflP.h: Declare it.
-
-2007-10-06 Roland McGrath <roland@redhat.com>
-
- * derelocate.c (dwfl_module_relocations): Don't call
- dwfl_module_getdwarf.
-
- * derelocate.c (find_section): Use __libdwfl_seterrno, not
- __libdw_seterrno.
-
- * relocate.c (__libdwfl_relocate_value): Abuse sh_offset, not
- SHF_ALLOC, to cache sh_addr resolved to 0.
-
- * dwfl_report_elf.c (dwfl_report_elf): When an ET_REL file has sh_addr
- values nonzero already, just use its existing layout.
-
- * relocate.c (__libdwfl_relocate): Clear size of reloc section in its
- in-core shdr after applying it.
-
-2007-10-04 Ulrich Drepper <drepper@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_kernel): Fake
- initialization of notes variable.
-
-2007-10-04 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (intuit_kernel_bounds): Take new arg NOTES,
- fill in with vaddr of "__start_notes" symbol if found.
- (check_notes): New function.
- (check_kernel_notes): New function.
- (dwfl_linux_kernel_report_kernel): Call it.
- (check_module_notes): New function.
- (dwfl_linux_kernel_report_modules): Call it.
-
- * linux-kernel-modules.c (dwfl_linux_kernel_find_elf):
- Try dwfl_build_id_find_elf first.
-
- * linux-kernel-modules.c (report_kernel): Don't leak FD if !REPORT.
- Set kernel module e_type to ET_DYN.
-
-2007-10-03 Roland McGrath <roland@redhat.com>
-
- * find-debuginfo.c (validate): New function, broken out of ...
- (find_debuginfo_in_path): ... here. New function, broken out of ...
- (dwfl_standard_find_debuginfo): ... here. Call it, after trying
- dwfl_build_id_find_debuginfo first.
-
- * dwfl_build_id_find_elf.c: New file.
- * dwfl_build_id_find_debuginfo.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add them.
- * libdwfl.h: Declare them.
- * libdwflP.h: Add INTDECLs.
-
- * dwfl_module_build_id.c: New file.
- * dwfl_module_report_build_id.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add them.
- * libdwfl.h: Declare them.
- * libdwflP.h (struct Dwfl_Module): New members build_id_bits,
- build_id_len, build_id_vaddr. Declare __libdwfl_find_build_id.
- * dwfl_module.c (__libdwfl_module_free): Free MOD->build_id_bits.
-
- * dwfl_module_getdwarf.c (find_offsets): New function.
- (find_dynsym): New function, calls that.
- (find_symtab): Call it.
-
-2007-09-11 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_addrsym.c: Prefer a later global symbol at the same
- address if its st_size is smaller.
-
-2007-08-13 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_addrsym.c: Add dead initializer for stupid compiler.
-
-2007-08-12 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Don't use
- FTS_LOGICAL.
-
- * elf-from-memory.c (elf_from_remote_memory): Don't reset LOADBASE on
- a second phdr if it happens to match EHDR_VMA exactly.
-
-2007-08-08 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_addrsym.c: Don't use STT_SECTION, STT_FILE symbols and
- those with no names. Rewrite best symbol algorithm not to assume a
- sorted table and to be smarter handling sizeless symbols.
-
-2007-07-16 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (dwfl_report_module): Increment DWFL->nmodules when
- reviving an existing module.
-
-2007-06-08 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h: Fix #ifndef for config.h to use PACKAGE_NAME.
-
-2007-05-17 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Look at
- whole /lib/modules/VERSION tree, not just /lib/modules/VERSION/kernel.
- (dwfl_linux_kernel_find_elf): Likewise.
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use
- getline and sscanf instead of fscanf.
-
-2007-05-08 Roland McGrath <roland@redhat.com>
-
- * offline.c (dwfl_offline_section_address): Don't assume section
- numbers match between stripped and debuginfo files. Instead, assume
- only that the ordering among SHF_ALLOC sections matches.
-
- * linux-kernel-modules.c (report_kernel): Change RELEASE argument to
- pointer to string.
- (dwfl_linux_kernel_report_offline): Update caller.
- (dwfl_linux_kernel_report_kernel): Likewise.
-
-2007-04-23 Roland McGrath <roland@redhat.com>
-
- * argp-std.c (options): Fix group title string.
-
- * argp-std.c (parse_opt): Handle ARGP_KEY_ERROR, free the Dwfl.
- Update via STATE->input every time we set STATE->hook, not only at
- ARGP_KEY_SUCCESS.
-
- * dwfl_module.c (free_file): Free FILE->name.
-
-2007-04-16 Roland McGrath <roland@redhat.com>
-
- * derelocate.c (cache_sections): Apply bias to sh_addr.
- (compare_secrefs): Fix address comparison to avoid signed overflow.
- (find_section): New function, broken out of ...
- (dwfl_module_relocate_address): ... here, call it.
- (check_module): New function, broken out of ...
- (dwfl_module_relocate_address): ... here, call it.
- (dwfl_module_address_section): New function.
- * libdwfl.h: Declare it.
-
-2007-03-26 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (__libdwfl_module_free): Free MOD itself.
-
-2007-03-18 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (find_debuglink): New function, broken out of
- (find_debuginfo): ... here. Call it.
- Don't return error for libelf errors finding .gnu_debuglink section.
-
-2007-03-12 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (dwfl_report_begin_add): New function broken out of ...
- (dwfl_report_begin): ... here. Call it.
- * libdwfl.h: Declare it.
- * libdwflP.h: Add INTDECL.
-
- * elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo.
-
- * offline.c: Comment typo fix.
-
-2007-03-04 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (KERNEL_MODNAME): New macro for "kernel".
- (find_kernel_elf): New function, broken out of ...
- (report_kernel): ... here. Call it.
- (dwfl_linux_kernel_find_elf): Use it for module named KERNEL_MODNAME.
- (intuit_kernel_bounds): New function, grovel /proc/kallsyms to guess
- virtual address bounds of kernel from symbols rounded to page size.
- (dwfl_linux_kernel_report_kernel): Use that if it works, before
- resorting to report_kernel.
-
- * dwfl_module_getdwarf.c (open_elf): Set MOD->e_type to ET_DYN for an
- ET_EXEC file with nonzero bias.
-
- * dwfl_module_addrname.c (dwfl_module_addrname): Just call
- dwfl_module_addrsym. Guts moved to ...
- * dwfl_module_addrsym.c: ... here; new file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_module_addrsym.
- * libdwflP.h: Add INTDECL.
-
-2007-03-03 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (free_file): New function, broken out of ...
- (__libdwfl_module_free): ... here. In it, close fd after elf_end.
-
- * dwfl_module_getdwarf.c (open_elf): Close fd and reset to -1
- on libelf failure.
-
-2007-03-02 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c: Fix bogus error test for asprintf call.
-
-2007-02-02 Roland McGrath <roland@redhat.com>
-
- * dwfl_addrmodule.c (dwfl_addrmodule): Match a module's high boundary
- address exactly if it's no other module's low boundary.
-
- * dwfl_module_addrname.c (dwfl_module_addrname): If no symbol's value
- and size cover the address, select the closest symbol with st_size==0
- that lies in the same section.
-
-2007-01-29 Roland McGrath <roland@redhat.com>
-
- * dwfl_version.c (dwfl_version): Return PACKAGE_VERSION,
- not PACKAGE_STRING.
-
-2007-01-20 Roland McGrath <roland@redhat.com>
-
- * relocate.c (__libdwfl_relocate_value): Treat section_address of -1
- as omitted, not 0.
- * libdwfl.h (Dwfl_Callbacks): Update comment.
- * derelocate.c (cache_sections): Don't ignore sh_addr == 0 sections.
- * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
- For ignored missing section, use -1 instead of 0.
- * offline.c (dwfl_offline_section_address): Expect a call for 0.
-
-2007-01-19 Roland McGrath <roland@redhat.com>
-
- * argp-std.c (parse_opt): For -e, reset DWFL->offline_next_address to
- zero so a lone -e foo.so is shown without address bias.
-
-2007-01-10 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (report_kernel): Check asprintf return value
- directly instead of via side effect, to silence warn_unused_result.
- (dwfl_linux_kernel_report_offline): Likewise.
- (dwfl_linux_kernel_find_elf): Likewise.
- (dwfl_linux_kernel_module_section_address): Likewise.
- * find-debuginfo.c (try_open): Likewise.
- * linux-proc-maps.c (find_sysinfo_ehdr): Likewise.
- (dwfl_linux_proc_report): Likewise.
-
- * libdwfl.h (dwfl_begin): Require nonnull argument.
-
-2006-12-27 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (compare_modules): Fix address comparison to avoid
- signed overflow. Patch by Frank Ch. Eigler <fche@redhat.com>.
-
-2006-10-30 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (dwfl_report_module): Comment typo fix.
-
-2006-09-05 Roland McGrath <roland@redhat.com>
-
- * derelocate.c (cache_sections): Use alloca instead of variable-sized
- auto array, in function already using alloca.
-
-2006-08-14 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (try_kernel_name): If the call to
- dwfl_standard_find_debuginfo produces no results, try it again
- with NULL as DEBUGLINK_FILE to try *FNAME with .debug suffix.
-
- * find-debuginfo.c (DEFAULT_DEBUGINFO_PATH): Macro moved ...
- * libdwflP.h: ... to here.
- * linux-kernel-modules.c (try_kernel_name): Skip manual open if it
- repeats the first thing dwfl_standard_find_debuginfo will try.
-
- * linux-kernel-modules.c (MODULE_SECT_NAME_LEN): New macro.
- (dwfl_linux_kernel_module_section_address): If a /sys file is missing
- and the section name is >= MODULE_SECT_NAME_LEN, try truncating the
- section name.
-
-2006-07-12 Ulrich Drepper <drepper@redhat.com>
-
- * cu.c: Adjust for internal_function_def removal.
- * dwfl_error.c: Likewise.
- * dwfl_module.c: Likewise.
- * dwfl_module_getdwarf.c: Likewise.
- * lines.c: Likewise.
- * relocate.c: Likewise.
-
-2006-07-11 Ulrich Drepper <drepper@redhat.com>
-
- * dwfl_module.c (compare_modules): Don't return GElf_Sxword value,
- it can overflow the return value type.
- Patch by Tim Moore <timoore@redhat.com>.
-
-2006-06-28 Roland McGrath <roland@redhat.com>
-
- * libdwfl.h: Cosmetic changes.
-
- * dwfl_line_comp_dir.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_line_comp_dir.
-
- * dwfl_lineinfo.c (dwfl_lineinfo): Remove stray extern in defn.
-
- * dwfl_linecu.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_linecu.
-
- * libdwflP.h (dwfl_linecu_inline): Function renamed from dwfl_linecu.
- (dwfl_linecu): Define as macro.
-
- * relocate.c (__libdwfl_relocate): Use dwfl_module_getsym.
-
- * dwfl_module_getdwarf.c (dwfl_module_getsymtab): New function.
- (dwfl_module_addrname): Function moved ...
- * dwfl_module_addrname.c: ... here, new file.
- * dwfl_module_getsym.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add them.
- * libdwfl.h: Declare dwfl_module_getsymtab, dwfl_module_getsym.
- * libdwflP.h: Add INTDECLs.
-
-2006-06-27 Roland McGrath <roland@redhat.com>
-
- * dwfl_module.c (dwfl_report_end): Whitespace fix.
-
-2006-06-13 Roland McGrath <roland@redhat.com>
-
- * elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo.
- Use __libdwfl_seterrno for elf_memory failure.
-
-2006-05-22 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_return_value_location.c
- (dwfl_module_return_value_location): Use __libdwfl_module_getebl.
-
-2006-05-27 Ulrich Drepper <drepper@redhat.com>
-
- * libdwfl.h: Add extern "C".
-
-2006-05-22 Ulrich Drepper <drepper@redhat.com>
-
- * cu.c (addrarange): Handle files without aranges information.
-
-2006-05-16 Ulrich Drepper <drepper@redhat.com>
-
- * dwfl_addrmodule.c (dwfl_addrmodule): Also return NULL of
- ->modules is NULL.
-
-2006-02-26 Roland McGrath <roland@redhat.com>
-
- * dwfl_version.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_version.
-
- * offline.c (dwfl_report_offline): Account for dwfl_report_elf having
- aligned up from DWFL->offline_next_address when checking for overlap.
-
-2005-12-22 Roland McGrath <roland@redhat.com>
-
- * argp-std.c (parse_opt): Call dwfl_end in failure cases.
-
- * linux-proc-maps.c (proc_maps_report): New function, broken out of ...
- (dwfl_linux_proc_report): ... here. Call it.
- (dwfl_linux_proc_maps_report): New function.
- * libdwfl.h: Declare it.
- * libdwflP.h: Add INTDECL.
- * argp-std.c (options, parse_opt): Grok -M/--linux-process-map.
-
- * dwfl_nextcu.c (dwfl_nextcu): Don't fail when dwfl_module_getdwarf
- failed with DWFL_E_NO_DWARF.
-
-2005-11-26 Roland McGrath <roland@redhat.com>
-
- * dwfl_end.c (dwfl_end): Free the DWFL itself.
-
-2005-11-25 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getdwarf.c (__libdwfl_module_getebl): New function.
- (load_dw): Use it.
- * dwfl_module_register_names.c (dwfl_module_register_names): Likewise.
- * libdwflP.h: Declare it.
-
- * dwfl_module_register_names.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_module_register_names.
-
-2005-11-21 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
- Don't leak malloc'd file name.
- If a /sys/.../sections file is missing and starts with ".init",
- try the variant with "_init" too; catches PPC64 kernel braindamage.
-
-2005-11-15 Roland McGrath <roland@redhat.com>
-
- * libdwfl.h: Comment fixes.
-
- * dwfl_module_return_value_location.c: Add unlikely for error case.
-
-2005-11-13 Roland McGrath <roland@redhat.com>
-
- * dwfl_return_value_location.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_module_return_value_location.
- * libdwflP.h (DWFL_ERRORS): Add DWFL_E_WEIRD_TYPE.
-
-2005-10-20 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h (DWFL_ERRORS): New error UNKNOWN_MACHINE.
- * relocate.c (__libdwfl_relocate): Return DWFL_E_UNKNOWN_MACHINE
- instead of DWFL_E_BADRELTYPE if ebl_get_elfmachine yields EM_NONE.
-
-2005-10-01 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (report_kernel): Return ENOENT if we fail
- with errno 0.
-
-2005-09-19 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use
- PRIx64 instead of PRIi64, lest addresses with high bits set overflow
- the signed integer reading; they will just have to be in hexadecimal.
- (dwfl_linux_kernel_module_section_address): Likewise.
-
-2005-08-28 Ulrich Drepper <drepper@redhat.com>
-
- * Makefile.am (%.os): Use COMPILE.os.
- (COMPILE.os): Filter out gconv options.
-
-2005-08-25 Roland McGrath <roland@redhat.com>
-
- * cu.c (__libdwfl_nextcu): Return success when dwarf_nextcu hits end.
- * dwfl_nextcu.c (dwfl_nextcu): Skip modules with no dwarf info.
-
-2005-08-24 Roland McGrath <roland@redhat.com>
-
- * dwfl_lineinfo.c (dwfl_lineinfo): Add bias, don't subtract it.
-
- * argp-std.c [_MUDFLAP] (__libdwfl_argp_mudflap_options): New function,
- magic initializer to set -heur-stack-bound option.
-
-2005-08-22 Roland McGrath <roland@redhat.com>
-
- * dwfl_validate_address.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_validate_address.
-
- * derelocate.c (dwfl_module_relocate_address): Add INTDEF.
- * libdwflP.h: Add INTDECL.
-
- * dwfl_module_getdwarf.c (find_symtab): Use elf_getdata instead of
- elf_rawdata for symbol-related sections.
-
- * offline.c (dwfl_report_offline): Move offline_next_address outside
- module's range, in case it's an ET_EXEC using fixed segment locations.
- * libdwfl.h: Update comment.
-
- * dwfl_report_elf.c (dwfl_report_elf): Align BASE to first segment's
- required alignment.
-
-2005-08-20 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (report_kernel): Take new argument PREDICATE,
- function to choose whether to report.
- (dwfl_linux_kernel_report_offline): Likewise.
- * libdwfl.h: Update decl.
- * argp-std.c (parse_opt): Update caller.
-
- * dwfl_getsrclines.c: New file.
- * dwfl_onesrcline.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add them.
- * libdwfl.h: Declare dwfl_getsrclines, dwfl_onesrcline.
-
- * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't leak
- MODULESDIR[0]. Call fts_close on failure.
-
- * dwfl_module_getdwarf.c (load_dw): Take dwfl_file * instead of Elf *.
- Close ET_REL file descriptors after relocation.
- (find_dw): Update caller.
- * offline.c (dwfl_report_offline): Get the file into memory and close
- the file descriptor.
-
- * dwfl_module_getdwarf.c (find_debuginfo): Do nothing when
- MOD->debug.elf is already set.
-
- * find-debuginfo.c (try_open): Use TEMP_FAILURE_RETRY.
- (dwfl_standard_find_debuginfo): Fail on errors not ENOENT or ENOTDIR.
-
- * argp-std.c (options, parse_opt): Grok -K/--offline-kernel, use
- dwfl_linux_kernel_report_offline with offline_callbacks.
-
- * linux-kernel-modules.c (report_kernel): New function, broken out of
- ...
- (dwfl_linux_kernel_report_kernel): ... here. Use it.
- (dwfl_linux_kernel_report_offline): New function.
- * libdwfl.h: Declare it.
- * libdwflP.h: Add INTDECL.
-
-2005-08-19 Roland McGrath <roland@redhat.com>
-
- Use standard debuginfo search path to look for vmlinux.
- * find-debuginfo.c (dwfl_standard_find_debuginfo): Don't check CRC if
- passed zero.
- * linux-kernel-modules.c (try_kernel_name): New function, broken out
- of ...
- (dwfl_linux_kernel_report_kernel): ... here. Use it.
-
- * argp-std.c (offline_callbacks): New variable.
- (parse_opt): Use it for -e. Allow multiple -e options.
-
- * offline.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
- * libdwfl.h: Declare dwfl_offline_section_address, dwfl_report_offline.
- * libdwflP.h: Add INTDECLs.
- (OFFLINE_REDZONE): New macro.
- (struct Dwfl): New member `offline_next_address'.
- * dwfl_begin.c (dwfl_begin): Initialize it.
- * dwfl_module.c (dwfl_report_begin): Likewise.
-
- * dwfl_report_elf.c (dwfl_report_elf): Accept all types. When ET_REL,
- do a nominal absolute section layout starting at BASE.
- * libdwfl.h: Update comment.
-
-2005-08-18 Roland McGrath <roland@redhat.com>
-
- * dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Do
- dwfl_module_getdwarf if necessary.
-
- * dwfl_report_elf.c (dwfl_report_elf): Permit ET_REL with BASE==0.
- * libdwfl.h: Update comment.
-
- * derelocate.c: New file.
- * Makefile.am (libdwfl_a_SOURCES): Add it.
-
- * libdwflP.h (struct Dwfl_Module): isrel -> e_type.
- * dwfl_report_elf.c (dwfl_report_elf): Initialize it.
- * dwfl_module_getdwarf.c (open_elf): Update initialization.
- (load_dw, dwfl_module_addrname): Update uses.
- * relocate.c (__libdwfl_relocate): Likewise.
-
-2005-08-04 Roland McGrath <roland@redhat.com>
-
- * libdwfl.h (Dwfl_Callbacks.section_address): Take additional
- arguments SHNDX, SHDR.
- (dwfl_linux_kernel_module_section_address): Update prototype.
- * relocate.c (__libdwfl_relocate_value): Update caller.
- * linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
- Take the new arguments.
-
-2005-08-10 Roland McGrath <roland@redhat.com>
-
- * relocate.c (__libdwfl_relocate): Take argument DEBUGFILE,
- use it instead of MOD->debug.file.
- * libdwflP.h: Update decl.
- * dwfl_module_getdwarf.c (load_dw): Update caller.
- Fixes bug #165598.
-
-2005-08-09 Roland McGrath <roland@redhat.com>
-
- * libdwflP.h: Include ../libdw/libdwP.h for its INTDECLs.
- * cu.c: Use INTUSE on dwarf_* calls.
- * dwfl_error.c: Likewise.
- * dwfl_module.c: Likewise.
- * dwfl_module_getdwarf.c: Likewise.
- * dwfl_module_getsrc_file.c: Likewise.
- * lines.c: Likewise.
-
-2005-08-07 Roland McGrath <roland@redhat.com>
-
- * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): When module
- names contain '_' or '-', look for files named either "foo-bar.ko"
- or "foo_bar.ko".
-
-2005-07-29 Roland McGrath <roland@redhat.com>
-
- * loc2c.c: File removed.
- * loc2c.h: File removed.
- * loc2c-runtime.h: File removed.
- * test2.c: File removed.
- * Makefile.am (EXTRA_DIST): Variable removed.
- (noinst_HEADERS): Remove loc2c.h from here.
-
-2005-07-28 Ulrich Drepper <drepper@redhat.com>
-
- * libdwfl.h: Add a few missing extern for function prototypes.
-
- * libdwfl_crc32.c: New file.
- * libdwfl_crc32_file.c: New file.
- * libdwflP.h: Declare the new functions.
- * Makefile.am (libdwfl_a_SOURCES): Add libdwfl_crc32.c and
- libdwfl_crc32_file.c.
- * libdwfl/find-debuginfo.c (check_crc): Use __libdwfl_crc32_file
- instead of crc32_file.
-
-2005-07-28 Roland McGrath <roland@redhat.com>
-
- * ptest.c: Moved to ../tests/dwflmodtest.c.
-
- * Makefile.am (noinst_PROGRAMS): Variable removed.
- (libdwfl_so_SOURCES, libdwfl_LIBS, libdwfl_so_LDADD): Likewise.
- (EXTRA_DIST, ptest_LDADD, test2_LDADD): Likewise.
- (libdwfl): Don't use libdwfl.so any more.
- (libdwfl.so, install, uninstall): Targets removed.
- (test2_SOURCES): Define EXTRA_DIST instead of this.
- * libdwfl.map: File removed.
-
- * libdwfl.h: Use "" for libdw.h #include.
-
-2005-07-27 Roland McGrath <roland@redhat.com>
-
- * libdwfl.map: Add dwfl_getmodules.
-
-2005-07-23 Ulrich Drepper <drepper@redhat.com>
-
- * Makefile.am: Fix rules to allow building with mudflap.
-
-2005-07-21 Roland McGrath <roland@redhat.com>
-
- * Makefile.am (noinst_HEADERS): Add loc2c.c.
-
- * test2.c (main): Check sscanf result to quiet warning.
-
-2005-07-20 Roland McGrath <roland@redhat.com>
-
- * libdwfl-branch merged, creating this direcotry.
diff --git a/src/libdwfl/Makefile b/src/libdwfl/Makefile
deleted file mode 100644
index 48180b24..00000000
--- a/src/libdwfl/Makefile
+++ /dev/null
@@ -1,801 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# libdwfl/Makefile. Generated from Makefile.in by configure.
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-
-
-
-
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/elfutils
-pkgincludedir = $(includedir)/elfutils
-pkglibdir = $(libdir)/elfutils
-pkglibexecdir = $(libexecdir)/elfutils
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = x86_64-unknown-linux-gnu
-host_triplet = x86_64-unknown-linux-gnu
-DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
- $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
- $(noinst_HEADERS) $(pkginclude_HEADERS) ChangeLog
-am__append_1 = gzip.c
-#am__append_2 = bzip2.c
-#am__append_3 = lzma.c
-subdir = libdwfl
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-LIBRARIES = $(noinst_LIBRARIES)
-ARFLAGS = cru
-AM_V_AR = $(am__v_AR_$(V))
-am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
-am__v_AR_0 = @echo " AR " $@;
-am__v_AR_1 =
-libdwfl_a_AR = $(AR) $(ARFLAGS)
-libdwfl_a_LIBADD =
-am__libdwfl_a_SOURCES_DIST = dwfl_begin.c dwfl_end.c dwfl_error.c \
- dwfl_version.c dwfl_module.c dwfl_report_elf.c relocate.c \
- dwfl_module_build_id.c dwfl_module_report_build_id.c \
- derelocate.c offline.c segment.c dwfl_module_info.c \
- dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \
- dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \
- find-debuginfo.c dwfl_build_id_find_elf.c \
- dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \
- linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \
- dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
- dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \
- dwfl_line_comp_dir.c dwfl_linemodule.c dwfl_linecu.c \
- dwfl_dwarf_line.c dwfl_getsrclines.c dwfl_onesrcline.c \
- dwfl_module_getsrc.c dwfl_getsrc.c dwfl_module_getsrc_file.c \
- libdwfl_crc32.c libdwfl_crc32_file.c elf-from-memory.c \
- dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \
- dwfl_module_getsym.c dwfl_module_addrname.c \
- dwfl_module_addrsym.c dwfl_module_return_value_location.c \
- dwfl_module_register_names.c dwfl_segment_report_module.c \
- link_map.c core-file.c open.c image-header.c dwfl_frame.c \
- frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \
- linux-core-attach.c dwfl_frame_regs.c gzip.c bzip2.c lzma.c
-am__objects_1 = gzip.$(OBJEXT)
-#am__objects_2 = bzip2.$(OBJEXT)
-#am__objects_3 = lzma.$(OBJEXT)
-am_libdwfl_a_OBJECTS = dwfl_begin.$(OBJEXT) dwfl_end.$(OBJEXT) \
- dwfl_error.$(OBJEXT) dwfl_version.$(OBJEXT) \
- dwfl_module.$(OBJEXT) dwfl_report_elf.$(OBJEXT) \
- relocate.$(OBJEXT) dwfl_module_build_id.$(OBJEXT) \
- dwfl_module_report_build_id.$(OBJEXT) derelocate.$(OBJEXT) \
- offline.$(OBJEXT) segment.$(OBJEXT) dwfl_module_info.$(OBJEXT) \
- dwfl_getmodules.$(OBJEXT) dwfl_getdwarf.$(OBJEXT) \
- dwfl_module_getdwarf.$(OBJEXT) dwfl_module_getelf.$(OBJEXT) \
- dwfl_validate_address.$(OBJEXT) argp-std.$(OBJEXT) \
- find-debuginfo.$(OBJEXT) dwfl_build_id_find_elf.$(OBJEXT) \
- dwfl_build_id_find_debuginfo.$(OBJEXT) \
- linux-kernel-modules.$(OBJEXT) linux-proc-maps.$(OBJEXT) \
- dwfl_addrmodule.$(OBJEXT) dwfl_addrdwarf.$(OBJEXT) \
- cu.$(OBJEXT) dwfl_module_nextcu.$(OBJEXT) \
- dwfl_nextcu.$(OBJEXT) dwfl_cumodule.$(OBJEXT) \
- dwfl_module_addrdie.$(OBJEXT) dwfl_addrdie.$(OBJEXT) \
- lines.$(OBJEXT) dwfl_lineinfo.$(OBJEXT) \
- dwfl_line_comp_dir.$(OBJEXT) dwfl_linemodule.$(OBJEXT) \
- dwfl_linecu.$(OBJEXT) dwfl_dwarf_line.$(OBJEXT) \
- dwfl_getsrclines.$(OBJEXT) dwfl_onesrcline.$(OBJEXT) \
- dwfl_module_getsrc.$(OBJEXT) dwfl_getsrc.$(OBJEXT) \
- dwfl_module_getsrc_file.$(OBJEXT) libdwfl_crc32.$(OBJEXT) \
- libdwfl_crc32_file.$(OBJEXT) elf-from-memory.$(OBJEXT) \
- dwfl_module_dwarf_cfi.$(OBJEXT) dwfl_module_eh_cfi.$(OBJEXT) \
- dwfl_module_getsym.$(OBJEXT) dwfl_module_addrname.$(OBJEXT) \
- dwfl_module_addrsym.$(OBJEXT) \
- dwfl_module_return_value_location.$(OBJEXT) \
- dwfl_module_register_names.$(OBJEXT) \
- dwfl_segment_report_module.$(OBJEXT) link_map.$(OBJEXT) \
- core-file.$(OBJEXT) open.$(OBJEXT) image-header.$(OBJEXT) \
- dwfl_frame.$(OBJEXT) frame_unwind.$(OBJEXT) \
- dwfl_frame_pc.$(OBJEXT) linux-pid-attach.$(OBJEXT) \
- linux-core-attach.$(OBJEXT) dwfl_frame_regs.$(OBJEXT) \
- $(am__objects_1) $(am__objects_2) $(am__objects_3)
-libdwfl_a_OBJECTS = $(am_libdwfl_a_OBJECTS)
-libdwfl_pic_a_AR = $(AR) $(ARFLAGS)
-libdwfl_pic_a_LIBADD =
-libdwfl_pic_a_OBJECTS = $(am_libdwfl_pic_a_OBJECTS)
-AM_V_P = $(am__v_P_$(V))
-am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
-am__v_at_1 =
-DEFAULT_INCLUDES = -I. -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
-am__v_CC_0 = @echo " CC " $@;
-am__v_CC_1 =
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
-am__v_CCLD_0 = @echo " CCLD " $@;
-am__v_CCLD_1 =
-SOURCES = $(libdwfl_a_SOURCES) $(libdwfl_pic_a_SOURCES)
-DIST_SOURCES = $(am__libdwfl_a_SOURCES_DIST) $(libdwfl_pic_a_SOURCES)
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
- }
-am__installdirs = "$(DESTDIR)$(pkgincludedir)"
-HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates. Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
- BEGIN { nonempty = 0; } \
- { items[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique. This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
- list='$(am__tagged_files)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = ${SHELL} /huge-ssd/aosp-arm64/external/elfutils/src/config/missing aclocal-1.14
-AMTAR = $${TAR-tar}
-AM_DEFAULT_VERBOSITY = 1
-AR = ar
-AUTOCONF = ${SHELL} /huge-ssd/aosp-arm64/external/elfutils/src/config/missing autoconf
-AUTOHEADER = ${SHELL} /huge-ssd/aosp-arm64/external/elfutils/src/config/missing autoheader
-AUTOMAKE = ${SHELL} /huge-ssd/aosp-arm64/external/elfutils/src/config/missing automake-1.14
-AWK = gawk
-CC = gcc
-CCDEPMODE = depmode=gcc3
-CC_BIARCH = gcc -m32
-CFLAGS = -g -O2
-CPP = gcc -E
-CPPFLAGS =
-CYGPATH_W = echo
-DEBUGPRED = 0
-DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"'
-DEPDIR = .deps
-ECHO_C =
-ECHO_N = -n
-ECHO_T =
-EGREP = /bin/grep -E
-EXEEXT =
-GETTEXT_MACRO_VERSION = 0.18
-GMSGFMT = /usr/bin/msgfmt
-GMSGFMT_015 = /usr/bin/msgfmt
-GREP = /bin/grep
-HAVE_VALGRIND =
-INSTALL = /usr/bin/install -c
-INSTALL_DATA = ${INSTALL} -m 644
-INSTALL_PROGRAM = ${INSTALL}
-INSTALL_SCRIPT = ${INSTALL}
-INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
-LDFLAGS =
-LEX = flex
-LEXLIB = -lfl
-LEX_OUTPUT_ROOT = lex.yy
-LIBEBL_SUBDIR = elfutils
-LIBOBJS =
-LIBS =
-LTLIBOBJS =
-MAINT = #
-MAKEINFO = ${SHELL} /huge-ssd/aosp-arm64/external/elfutils/src/config/missing makeinfo
-MKDIR_P = /bin/mkdir -p
-MODVERSION = Build on enh.mtv.corp.google.com 2015-02-18T19:32:04-0800
-MSGFMT = /usr/bin/msgfmt
-MSGFMT_015 = /usr/bin/msgfmt
-MSGMERGE = /usr/bin/msgmerge
-NM = nm
-OBJEXT = o
-PACKAGE = elfutils
-PACKAGE_BUGREPORT = https://bugzilla.redhat.com/
-PACKAGE_NAME = elfutils
-PACKAGE_STRING = elfutils 0.161
-PACKAGE_TARNAME = elfutils
-PACKAGE_URL =
-PACKAGE_VERSION = 0.161
-PATH_SEPARATOR = :
-RANLIB = ranlib
-READELF = readelf
-SET_MAKE =
-SHELL = /bin/sh
-STRIP =
-USE_NLS = yes
-VERSION = 1
-XGETTEXT = /usr/bin/xgettext
-XGETTEXT_015 = /usr/bin/xgettext
-XGETTEXT_EXTRA_OPTIONS =
-YACC = bison -y
-YFLAGS =
-abs_builddir = /huge-ssd/aosp-arm64/external/elfutils/src/libdwfl
-abs_srcdir = /huge-ssd/aosp-arm64/external/elfutils/src/libdwfl
-abs_top_builddir = /huge-ssd/aosp-arm64/external/elfutils/src
-abs_top_srcdir = /huge-ssd/aosp-arm64/external/elfutils/src
-ac_ct_AR = ar
-ac_ct_CC = gcc
-am__include = include
-am__leading_dot = .
-am__quote =
-am__tar = $${TAR-tar} chof - "$$tardir"
-am__untar = $${TAR-tar} xf -
-base_cpu = none
-bindir = ${exec_prefix}/bin
-build = x86_64-unknown-linux-gnu
-build_alias =
-build_cpu = x86_64
-build_os = linux-gnu
-build_vendor = unknown
-builddir = .
-datadir = ${datarootdir}
-datarootdir = ${prefix}/share
-docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
-dvidir = ${docdir}
-eu_version = 161
-exec_prefix = ${prefix}
-host = x86_64-unknown-linux-gnu
-host_alias =
-host_cpu = x86_64
-host_os = linux-gnu
-host_vendor = unknown
-htmldir = ${docdir}
-includedir = ${prefix}/include
-infodir = ${datarootdir}/info
-install_sh = ${SHELL} /huge-ssd/aosp-arm64/external/elfutils/src/config/install-sh
-libdir = ${exec_prefix}/lib
-libexecdir = ${exec_prefix}/libexec
-localedir = ${datarootdir}/locale
-localstatedir = ${prefix}/var
-mandir = ${datarootdir}/man
-mkdir_p = $(MKDIR_P)
-oldincludedir = /usr/include
-pdfdir = ${docdir}
-prefix = /usr/local
-program_transform_name = s,x,x,
-psdir = ${docdir}
-sbindir = ${exec_prefix}/sbin
-sharedstatedir = ${prefix}/com
-srcdir = .
-sysconfdir = ${prefix}/etc
-target_alias =
-top_build_prefix = ../
-top_builddir = ..
-top_srcdir = ..
-zip_LIBS = -lz
-AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. -I$(srcdir) \
- -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
- -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf
-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
- $(if $($(*F)_no_Werror),,-Werror) \
- $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
- $($(*F)_CFLAGS)
-
-COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
-CLEANFILES = *.gcno *.gcda $(am_libdwfl_pic_a_OBJECTS)
-textrel_msg = echo "WARNING: TEXTREL found in '$@'"
-#textrel_found = $(textrel_msg)
-textrel_found = $(textrel_msg); exit 1
-textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi
-noinst_LIBRARIES = libdwfl.a libdwfl_pic.a
-pkginclude_HEADERS = libdwfl.h
-libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c \
- dwfl_version.c dwfl_module.c dwfl_report_elf.c relocate.c \
- dwfl_module_build_id.c dwfl_module_report_build_id.c \
- derelocate.c offline.c segment.c dwfl_module_info.c \
- dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \
- dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \
- find-debuginfo.c dwfl_build_id_find_elf.c \
- dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \
- linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \
- dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
- dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \
- dwfl_line_comp_dir.c dwfl_linemodule.c dwfl_linecu.c \
- dwfl_dwarf_line.c dwfl_getsrclines.c dwfl_onesrcline.c \
- dwfl_module_getsrc.c dwfl_getsrc.c dwfl_module_getsrc_file.c \
- libdwfl_crc32.c libdwfl_crc32_file.c elf-from-memory.c \
- dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \
- dwfl_module_getsym.c dwfl_module_addrname.c \
- dwfl_module_addrsym.c dwfl_module_return_value_location.c \
- dwfl_module_register_names.c dwfl_segment_report_module.c \
- link_map.c core-file.c open.c image-header.c dwfl_frame.c \
- frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \
- linux-core-attach.c dwfl_frame_regs.c $(am__append_1) \
- $(am__append_2) $(am__append_3)
-libdwfl = $(libdw)
-libdw = ../libdw/libdw.so
-libelf = ../libelf/libelf.so
-libebl = ../libebl/libebl.a
-libeu = ../lib/libeu.a
-libdwfl_pic_a_SOURCES =
-am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
-noinst_HEADERS = libdwflP.h
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in: # $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdwfl/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnits libdwfl/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-$(top_srcdir)/config/eu.am:
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: # $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): # $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLIBRARIES:
- -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-
-libdwfl.a: $(libdwfl_a_OBJECTS) $(libdwfl_a_DEPENDENCIES) $(EXTRA_libdwfl_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libdwfl.a
- $(AM_V_AR)$(libdwfl_a_AR) libdwfl.a $(libdwfl_a_OBJECTS) $(libdwfl_a_LIBADD)
- $(AM_V_at)$(RANLIB) libdwfl.a
-
-libdwfl_pic.a: $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_DEPENDENCIES) $(EXTRA_libdwfl_pic_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libdwfl_pic.a
- $(AM_V_AR)$(libdwfl_pic_a_AR) libdwfl_pic.a $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_LIBADD)
- $(AM_V_at)$(RANLIB) libdwfl_pic.a
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-include ./$(DEPDIR)/argp-std.Po
-include ./$(DEPDIR)/bzip2.Po
-include ./$(DEPDIR)/core-file.Po
-include ./$(DEPDIR)/cu.Po
-include ./$(DEPDIR)/derelocate.Po
-include ./$(DEPDIR)/dwfl_addrdie.Po
-include ./$(DEPDIR)/dwfl_addrdwarf.Po
-include ./$(DEPDIR)/dwfl_addrmodule.Po
-include ./$(DEPDIR)/dwfl_begin.Po
-include ./$(DEPDIR)/dwfl_build_id_find_debuginfo.Po
-include ./$(DEPDIR)/dwfl_build_id_find_elf.Po
-include ./$(DEPDIR)/dwfl_cumodule.Po
-include ./$(DEPDIR)/dwfl_dwarf_line.Po
-include ./$(DEPDIR)/dwfl_end.Po
-include ./$(DEPDIR)/dwfl_error.Po
-include ./$(DEPDIR)/dwfl_frame.Po
-include ./$(DEPDIR)/dwfl_frame_pc.Po
-include ./$(DEPDIR)/dwfl_frame_regs.Po
-include ./$(DEPDIR)/dwfl_getdwarf.Po
-include ./$(DEPDIR)/dwfl_getmodules.Po
-include ./$(DEPDIR)/dwfl_getsrc.Po
-include ./$(DEPDIR)/dwfl_getsrclines.Po
-include ./$(DEPDIR)/dwfl_line_comp_dir.Po
-include ./$(DEPDIR)/dwfl_linecu.Po
-include ./$(DEPDIR)/dwfl_lineinfo.Po
-include ./$(DEPDIR)/dwfl_linemodule.Po
-include ./$(DEPDIR)/dwfl_module.Po
-include ./$(DEPDIR)/dwfl_module_addrdie.Po
-include ./$(DEPDIR)/dwfl_module_addrname.Po
-include ./$(DEPDIR)/dwfl_module_addrsym.Po
-include ./$(DEPDIR)/dwfl_module_build_id.Po
-include ./$(DEPDIR)/dwfl_module_dwarf_cfi.Po
-include ./$(DEPDIR)/dwfl_module_eh_cfi.Po
-include ./$(DEPDIR)/dwfl_module_getdwarf.Po
-include ./$(DEPDIR)/dwfl_module_getelf.Po
-include ./$(DEPDIR)/dwfl_module_getsrc.Po
-include ./$(DEPDIR)/dwfl_module_getsrc_file.Po
-include ./$(DEPDIR)/dwfl_module_getsym.Po
-include ./$(DEPDIR)/dwfl_module_info.Po
-include ./$(DEPDIR)/dwfl_module_nextcu.Po
-include ./$(DEPDIR)/dwfl_module_register_names.Po
-include ./$(DEPDIR)/dwfl_module_report_build_id.Po
-include ./$(DEPDIR)/dwfl_module_return_value_location.Po
-include ./$(DEPDIR)/dwfl_nextcu.Po
-include ./$(DEPDIR)/dwfl_onesrcline.Po
-include ./$(DEPDIR)/dwfl_report_elf.Po
-include ./$(DEPDIR)/dwfl_segment_report_module.Po
-include ./$(DEPDIR)/dwfl_validate_address.Po
-include ./$(DEPDIR)/dwfl_version.Po
-include ./$(DEPDIR)/elf-from-memory.Po
-include ./$(DEPDIR)/find-debuginfo.Po
-include ./$(DEPDIR)/frame_unwind.Po
-include ./$(DEPDIR)/gzip.Po
-include ./$(DEPDIR)/image-header.Po
-include ./$(DEPDIR)/libdwfl_crc32.Po
-include ./$(DEPDIR)/libdwfl_crc32_file.Po
-include ./$(DEPDIR)/lines.Po
-include ./$(DEPDIR)/link_map.Po
-include ./$(DEPDIR)/linux-core-attach.Po
-include ./$(DEPDIR)/linux-kernel-modules.Po
-include ./$(DEPDIR)/linux-pid-attach.Po
-include ./$(DEPDIR)/linux-proc-maps.Po
-include ./$(DEPDIR)/lzma.Po
-include ./$(DEPDIR)/offline.Po
-include ./$(DEPDIR)/open.Po
-include ./$(DEPDIR)/relocate.Po
-include ./$(DEPDIR)/segment.Po
-
-.c.o:
- $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-# $(AM_V_CC)source='$<' object='$@' libtool=no \
-# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
-# $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
-
-.c.obj:
- $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
- $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-# $(AM_V_CC)source='$<' object='$@' libtool=no \
-# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
-# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-install-pkgincludeHEADERS: $(pkginclude_HEADERS)
- @$(NORMAL_INSTALL)
- @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
- fi; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; \
- done | $(am__base_list) | \
- while read files; do \
- echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
- $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
- done
-
-uninstall-pkgincludeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
-
-ID: $(am__tagged_files)
- $(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- set x; \
- here=`pwd`; \
- $(am__define_uniq_tagged_files); \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- $(am__define_uniq_tagged_files); \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
- list='$(am__tagged_files)'; \
- case "$(srcdir)" in \
- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
- *) sdir=$(subdir)/$(srcdir) ;; \
- esac; \
- for i in $$list; do \
- if test -f "$$i"; then \
- echo "$(subdir)/$$i"; \
- else \
- echo "$$sdir/$$i"; \
- fi; \
- done >> $(top_builddir)/cscope.files
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LIBRARIES) $(HEADERS)
-installdirs:
- for dir in "$(DESTDIR)$(pkgincludedir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pkgincludeHEADERS
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-pkgincludeHEADERS
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
- clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
- distclean-compile distclean-generic distclean-tags distdir dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-pkgincludeHEADERS install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
- ps ps-am tags tags-am uninstall uninstall-am \
- uninstall-pkgincludeHEADERS
-
-
-%.os: %.c %.o
- if $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
- -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
- then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
- rm -f "$(DEPDIR)/$*.Tpo"; \
- else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
- fi
-# $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED $<
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/libdwfl/Makefile.am b/src/libdwfl/Makefile.am
deleted file mode 100644
index 72c980bf..00000000
--- a/src/libdwfl/Makefile.am
+++ /dev/null
@@ -1,94 +0,0 @@
-## Makefile.am for libdwfl library subdirectory in elfutils.
-##
-## Process this file with automake to create Makefile.in
-##
-## Copyright (C) 2005-2010, 2013 Red Hat, Inc.
-## This file is part of elfutils.
-##
-## This file is free software; you can redistribute it and/or modify
-## it under the terms of either
-##
-## * the GNU Lesser General Public License as published by the Free
-## Software Foundation; either version 3 of the License, or (at
-## your option) any later version
-##
-## or
-##
-## * the GNU General Public License as published by the Free
-## Software Foundation; either version 2 of the License, or (at
-## your option) any later version
-##
-## or both in parallel, as here.
-##
-## elfutils is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-## General Public License for more details.
-##
-## You should have received copies of the GNU General Public License and
-## the GNU Lesser General Public License along with this program. If
-## not, see <http://www.gnu.org/licenses/>.
-##
-include $(top_srcdir)/config/eu.am
-AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
- -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf
-VERSION = 1
-
-noinst_LIBRARIES = libdwfl.a
-noinst_LIBRARIES += libdwfl_pic.a
-
-pkginclude_HEADERS = libdwfl.h
-
-libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
- dwfl_module.c dwfl_report_elf.c relocate.c \
- dwfl_module_build_id.c dwfl_module_report_build_id.c \
- derelocate.c offline.c segment.c \
- dwfl_module_info.c dwfl_getmodules.c dwfl_getdwarf.c \
- dwfl_module_getdwarf.c dwfl_module_getelf.c \
- dwfl_validate_address.c \
- argp-std.c find-debuginfo.c \
- dwfl_build_id_find_elf.c \
- dwfl_build_id_find_debuginfo.c \
- linux-kernel-modules.c linux-proc-maps.c \
- dwfl_addrmodule.c dwfl_addrdwarf.c \
- cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
- dwfl_module_addrdie.c dwfl_addrdie.c \
- lines.c dwfl_lineinfo.c dwfl_line_comp_dir.c \
- dwfl_linemodule.c dwfl_linecu.c dwfl_dwarf_line.c \
- dwfl_getsrclines.c dwfl_onesrcline.c \
- dwfl_module_getsrc.c dwfl_getsrc.c \
- dwfl_module_getsrc_file.c \
- libdwfl_crc32.c libdwfl_crc32_file.c \
- elf-from-memory.c \
- dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \
- dwfl_module_getsym.c \
- dwfl_module_addrname.c dwfl_module_addrsym.c \
- dwfl_module_return_value_location.c \
- dwfl_module_register_names.c \
- dwfl_segment_report_module.c \
- link_map.c core-file.c open.c image-header.c \
- dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \
- linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c
-
-if ZLIB
-libdwfl_a_SOURCES += gzip.c
-endif
-if BZLIB
-libdwfl_a_SOURCES += bzip2.c
-endif
-if LZMA
-libdwfl_a_SOURCES += lzma.c
-endif
-
-libdwfl = $(libdw)
-libdw = ../libdw/libdw.so
-libelf = ../libelf/libelf.so
-libebl = ../libebl/libebl.a
-libeu = ../lib/libeu.a
-
-libdwfl_pic_a_SOURCES =
-am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
-
-noinst_HEADERS = libdwflP.h
-
-CLEANFILES += $(am_libdwfl_pic_a_OBJECTS)
diff --git a/src/libdwfl/Makefile.in b/src/libdwfl/Makefile.in
deleted file mode 100644
index f00e79e4..00000000
--- a/src/libdwfl/Makefile.in
+++ /dev/null
@@ -1,801 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-DIST_COMMON = $(top_srcdir)/config/eu.am $(srcdir)/Makefile.in \
- $(srcdir)/Makefile.am $(top_srcdir)/config/depcomp \
- $(noinst_HEADERS) $(pkginclude_HEADERS) ChangeLog
-@ZLIB_TRUE@am__append_1 = gzip.c
-@BZLIB_TRUE@am__append_2 = bzip2.c
-@LZMA_TRUE@am__append_3 = lzma.c
-subdir = libdwfl
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/biarch.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/zip.m4 \
- $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-LIBRARIES = $(noinst_LIBRARIES)
-ARFLAGS = cru
-AM_V_AR = $(am__v_AR_@AM_V@)
-am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
-am__v_AR_0 = @echo " AR " $@;
-am__v_AR_1 =
-libdwfl_a_AR = $(AR) $(ARFLAGS)
-libdwfl_a_LIBADD =
-am__libdwfl_a_SOURCES_DIST = dwfl_begin.c dwfl_end.c dwfl_error.c \
- dwfl_version.c dwfl_module.c dwfl_report_elf.c relocate.c \
- dwfl_module_build_id.c dwfl_module_report_build_id.c \
- derelocate.c offline.c segment.c dwfl_module_info.c \
- dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \
- dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \
- find-debuginfo.c dwfl_build_id_find_elf.c \
- dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \
- linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \
- dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
- dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \
- dwfl_line_comp_dir.c dwfl_linemodule.c dwfl_linecu.c \
- dwfl_dwarf_line.c dwfl_getsrclines.c dwfl_onesrcline.c \
- dwfl_module_getsrc.c dwfl_getsrc.c dwfl_module_getsrc_file.c \
- libdwfl_crc32.c libdwfl_crc32_file.c elf-from-memory.c \
- dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \
- dwfl_module_getsym.c dwfl_module_addrname.c \
- dwfl_module_addrsym.c dwfl_module_return_value_location.c \
- dwfl_module_register_names.c dwfl_segment_report_module.c \
- link_map.c core-file.c open.c image-header.c dwfl_frame.c \
- frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \
- linux-core-attach.c dwfl_frame_regs.c gzip.c bzip2.c lzma.c
-@ZLIB_TRUE@am__objects_1 = gzip.$(OBJEXT)
-@BZLIB_TRUE@am__objects_2 = bzip2.$(OBJEXT)
-@LZMA_TRUE@am__objects_3 = lzma.$(OBJEXT)
-am_libdwfl_a_OBJECTS = dwfl_begin.$(OBJEXT) dwfl_end.$(OBJEXT) \
- dwfl_error.$(OBJEXT) dwfl_version.$(OBJEXT) \
- dwfl_module.$(OBJEXT) dwfl_report_elf.$(OBJEXT) \
- relocate.$(OBJEXT) dwfl_module_build_id.$(OBJEXT) \
- dwfl_module_report_build_id.$(OBJEXT) derelocate.$(OBJEXT) \
- offline.$(OBJEXT) segment.$(OBJEXT) dwfl_module_info.$(OBJEXT) \
- dwfl_getmodules.$(OBJEXT) dwfl_getdwarf.$(OBJEXT) \
- dwfl_module_getdwarf.$(OBJEXT) dwfl_module_getelf.$(OBJEXT) \
- dwfl_validate_address.$(OBJEXT) argp-std.$(OBJEXT) \
- find-debuginfo.$(OBJEXT) dwfl_build_id_find_elf.$(OBJEXT) \
- dwfl_build_id_find_debuginfo.$(OBJEXT) \
- linux-kernel-modules.$(OBJEXT) linux-proc-maps.$(OBJEXT) \
- dwfl_addrmodule.$(OBJEXT) dwfl_addrdwarf.$(OBJEXT) \
- cu.$(OBJEXT) dwfl_module_nextcu.$(OBJEXT) \
- dwfl_nextcu.$(OBJEXT) dwfl_cumodule.$(OBJEXT) \
- dwfl_module_addrdie.$(OBJEXT) dwfl_addrdie.$(OBJEXT) \
- lines.$(OBJEXT) dwfl_lineinfo.$(OBJEXT) \
- dwfl_line_comp_dir.$(OBJEXT) dwfl_linemodule.$(OBJEXT) \
- dwfl_linecu.$(OBJEXT) dwfl_dwarf_line.$(OBJEXT) \
- dwfl_getsrclines.$(OBJEXT) dwfl_onesrcline.$(OBJEXT) \
- dwfl_module_getsrc.$(OBJEXT) dwfl_getsrc.$(OBJEXT) \
- dwfl_module_getsrc_file.$(OBJEXT) libdwfl_crc32.$(OBJEXT) \
- libdwfl_crc32_file.$(OBJEXT) elf-from-memory.$(OBJEXT) \
- dwfl_module_dwarf_cfi.$(OBJEXT) dwfl_module_eh_cfi.$(OBJEXT) \
- dwfl_module_getsym.$(OBJEXT) dwfl_module_addrname.$(OBJEXT) \
- dwfl_module_addrsym.$(OBJEXT) \
- dwfl_module_return_value_location.$(OBJEXT) \
- dwfl_module_register_names.$(OBJEXT) \
- dwfl_segment_report_module.$(OBJEXT) link_map.$(OBJEXT) \
- core-file.$(OBJEXT) open.$(OBJEXT) image-header.$(OBJEXT) \
- dwfl_frame.$(OBJEXT) frame_unwind.$(OBJEXT) \
- dwfl_frame_pc.$(OBJEXT) linux-pid-attach.$(OBJEXT) \
- linux-core-attach.$(OBJEXT) dwfl_frame_regs.$(OBJEXT) \
- $(am__objects_1) $(am__objects_2) $(am__objects_3)
-libdwfl_a_OBJECTS = $(am_libdwfl_a_OBJECTS)
-libdwfl_pic_a_AR = $(AR) $(ARFLAGS)
-libdwfl_pic_a_LIBADD =
-libdwfl_pic_a_OBJECTS = $(am_libdwfl_pic_a_OBJECTS)
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/config/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_@AM_V@)
-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo " CC " $@;
-am__v_CC_1 =
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_@AM_V@)
-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo " CCLD " $@;
-am__v_CCLD_1 =
-SOURCES = $(libdwfl_a_SOURCES) $(libdwfl_pic_a_SOURCES)
-DIST_SOURCES = $(am__libdwfl_a_SOURCES_DIST) $(libdwfl_pic_a_SOURCES)
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
- }
-am__installdirs = "$(DESTDIR)$(pkgincludedir)"
-HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates. Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
- BEGIN { nonempty = 0; } \
- { items[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique. This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
- list='$(am__tagged_files)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CC_BIARCH = @CC_BIARCH@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEBUGPRED = @DEBUGPRED@
-DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"'
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
-GMSGFMT = @GMSGFMT@
-GMSGFMT_015 = @GMSGFMT_015@
-GREP = @GREP@
-HAVE_VALGRIND = @HAVE_VALGRIND@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MODVERSION = @MODVERSION@
-MSGFMT = @MSGFMT@
-MSGFMT_015 = @MSGFMT_015@
-MSGMERGE = @MSGMERGE@
-NM = @NM@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-READELF = @READELF@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = 1
-XGETTEXT = @XGETTEXT@
-XGETTEXT_015 = @XGETTEXT_015@
-XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-base_cpu = @base_cpu@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-eu_version = @eu_version@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-zip_LIBS = @zip_LIBS@
-AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I.. -I$(srcdir) \
- -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
- -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf
-AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
- $(if $($(*F)_no_Werror),,-Werror) \
- $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
- $($(*F)_CFLAGS)
-
-COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
-CLEANFILES = *.gcno *.gcda $(am_libdwfl_pic_a_OBJECTS)
-textrel_msg = echo "WARNING: TEXTREL found in '$@'"
-@FATAL_TEXTREL_FALSE@textrel_found = $(textrel_msg)
-@FATAL_TEXTREL_TRUE@textrel_found = $(textrel_msg); exit 1
-textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi
-noinst_LIBRARIES = libdwfl.a libdwfl_pic.a
-pkginclude_HEADERS = libdwfl.h
-libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c \
- dwfl_version.c dwfl_module.c dwfl_report_elf.c relocate.c \
- dwfl_module_build_id.c dwfl_module_report_build_id.c \
- derelocate.c offline.c segment.c dwfl_module_info.c \
- dwfl_getmodules.c dwfl_getdwarf.c dwfl_module_getdwarf.c \
- dwfl_module_getelf.c dwfl_validate_address.c argp-std.c \
- find-debuginfo.c dwfl_build_id_find_elf.c \
- dwfl_build_id_find_debuginfo.c linux-kernel-modules.c \
- linux-proc-maps.c dwfl_addrmodule.c dwfl_addrdwarf.c cu.c \
- dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
- dwfl_module_addrdie.c dwfl_addrdie.c lines.c dwfl_lineinfo.c \
- dwfl_line_comp_dir.c dwfl_linemodule.c dwfl_linecu.c \
- dwfl_dwarf_line.c dwfl_getsrclines.c dwfl_onesrcline.c \
- dwfl_module_getsrc.c dwfl_getsrc.c dwfl_module_getsrc_file.c \
- libdwfl_crc32.c libdwfl_crc32_file.c elf-from-memory.c \
- dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \
- dwfl_module_getsym.c dwfl_module_addrname.c \
- dwfl_module_addrsym.c dwfl_module_return_value_location.c \
- dwfl_module_register_names.c dwfl_segment_report_module.c \
- link_map.c core-file.c open.c image-header.c dwfl_frame.c \
- frame_unwind.c dwfl_frame_pc.c linux-pid-attach.c \
- linux-core-attach.c dwfl_frame_regs.c $(am__append_1) \
- $(am__append_2) $(am__append_3)
-libdwfl = $(libdw)
-libdw = ../libdw/libdw.so
-libelf = ../libelf/libelf.so
-libebl = ../libebl/libebl.a
-libeu = ../lib/libeu.a
-libdwfl_pic_a_SOURCES =
-am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
-noinst_HEADERS = libdwflP.h
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/config/eu.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits libdwfl/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnits libdwfl/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-$(top_srcdir)/config/eu.am:
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLIBRARIES:
- -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-
-libdwfl.a: $(libdwfl_a_OBJECTS) $(libdwfl_a_DEPENDENCIES) $(EXTRA_libdwfl_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libdwfl.a
- $(AM_V_AR)$(libdwfl_a_AR) libdwfl.a $(libdwfl_a_OBJECTS) $(libdwfl_a_LIBADD)
- $(AM_V_at)$(RANLIB) libdwfl.a
-
-libdwfl_pic.a: $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_DEPENDENCIES) $(EXTRA_libdwfl_pic_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libdwfl_pic.a
- $(AM_V_AR)$(libdwfl_pic_a_AR) libdwfl_pic.a $(libdwfl_pic_a_OBJECTS) $(libdwfl_pic_a_LIBADD)
- $(AM_V_at)$(RANLIB) libdwfl_pic.a
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argp-std.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bzip2.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core-file.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cu.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/derelocate.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrdie.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrdwarf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_addrmodule.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_begin.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_build_id_find_debuginfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_build_id_find_elf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_cumodule.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_dwarf_line.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_end.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_error.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_frame.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_frame_pc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_frame_regs.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getdwarf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getmodules.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getsrc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_getsrclines.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_line_comp_dir.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_linecu.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_lineinfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_linemodule.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrdie.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrname.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_addrsym.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_build_id.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_dwarf_cfi.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_eh_cfi.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getdwarf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getelf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsrc.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsrc_file.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_getsym.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_info.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_nextcu.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_register_names.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_report_build_id.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_module_return_value_location.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_nextcu.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_onesrcline.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_report_elf.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_segment_report_module.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_validate_address.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwfl_version.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf-from-memory.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find-debuginfo.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame_unwind.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzip.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image-header.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwfl_crc32.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdwfl_crc32_file.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lines.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/link_map.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-core-attach.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-kernel-modules.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-pid-attach.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux-proc-maps.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lzma.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/offline.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/open.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relocate.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/segment.Po@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-install-pkgincludeHEADERS: $(pkginclude_HEADERS)
- @$(NORMAL_INSTALL)
- @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
- fi; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; \
- done | $(am__base_list) | \
- while read files; do \
- echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
- $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
- done
-
-uninstall-pkgincludeHEADERS:
- @$(NORMAL_UNINSTALL)
- @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
- files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
-
-ID: $(am__tagged_files)
- $(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- set x; \
- here=`pwd`; \
- $(am__define_uniq_tagged_files); \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- $(am__define_uniq_tagged_files); \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
- list='$(am__tagged_files)'; \
- case "$(srcdir)" in \
- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
- *) sdir=$(subdir)/$(srcdir) ;; \
- esac; \
- for i in $$list; do \
- if test -f "$$i"; then \
- echo "$(subdir)/$$i"; \
- else \
- echo "$$sdir/$$i"; \
- fi; \
- done >> $(top_builddir)/cscope.files
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LIBRARIES) $(HEADERS)
-installdirs:
- for dir in "$(DESTDIR)$(pkgincludedir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-pkgincludeHEADERS
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-pkgincludeHEADERS
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
- clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
- distclean-compile distclean-generic distclean-tags distdir dvi \
- dvi-am html html-am info info-am install install-am \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-pkgincludeHEADERS install-ps \
- install-ps-am install-strip installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
- ps ps-am tags tags-am uninstall uninstall-am \
- uninstall-pkgincludeHEADERS
-
-
-%.os: %.c %.o
-@AMDEP_TRUE@ if $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
-@AMDEP_TRUE@ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
-@AMDEP_TRUE@ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
-@AMDEP_TRUE@ rm -f "$(DEPDIR)/$*.Tpo"; \
-@AMDEP_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
-@AMDEP_TRUE@ fi
-@AMDEP_FALSE@ $(COMPILE.os) -c -o $@ -fpic -DPIC -DSHARED $<
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/libdwfl/argp-std.c b/src/libdwfl/argp-std.c
deleted file mode 100644
index 42b7e783..00000000
--- a/src/libdwfl/argp-std.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/* Standard argp argument parsers for tools using libdwfl.
- Copyright (C) 2005-2010, 2012 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <argp.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <libintl.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-/* gettext helper macros. */
-#define _(Str) dgettext ("elfutils", Str)
-
-
-#define OPT_DEBUGINFO 0x100
-#define OPT_COREFILE 0x101
-
-static const struct argp_option options[] =
-{
- { NULL, 0, NULL, 0, N_("Input selection options:"), 0 },
- { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 },
- { "core", OPT_COREFILE, "COREFILE", 0,
- N_("Find addresses from signatures found in COREFILE"), 0 },
- { "pid", 'p', "PID", 0,
- N_("Find addresses in files mapped into process PID"), 0 },
- { "linux-process-map", 'M', "FILE", 0,
- N_("Find addresses in files mapped as read from FILE"
- " in Linux /proc/PID/maps format"), 0 },
- { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 },
- { "offline-kernel", 'K', "RELEASE", OPTION_ARG_OPTIONAL,
- N_("Kernel with all modules"), 0 },
- { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0,
- N_("Search path for separate debuginfo files"), 0 },
- { NULL, 0, NULL, 0, NULL, 0 }
-};
-
-static char *debuginfo_path;
-
-static const Dwfl_Callbacks offline_callbacks =
- {
- .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
- .debuginfo_path = &debuginfo_path,
-
- .section_address = INTUSE(dwfl_offline_section_address),
-
- /* We use this table for core files too. */
- .find_elf = INTUSE(dwfl_build_id_find_elf),
- };
-
-static const Dwfl_Callbacks proc_callbacks =
- {
- .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
- .debuginfo_path = &debuginfo_path,
-
- .find_elf = INTUSE(dwfl_linux_proc_find_elf),
- };
-
-static const Dwfl_Callbacks kernel_callbacks =
- {
- .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
- .debuginfo_path = &debuginfo_path,
-
- .find_elf = INTUSE(dwfl_linux_kernel_find_elf),
- .section_address = INTUSE(dwfl_linux_kernel_module_section_address),
- };
-
-/* Structure held at state->HOOK. */
-struct parse_opt
-{
- Dwfl *dwfl;
- /* The -e|--executable parameter. */
- const char *e;
- /* The --core parameter. */
- const char *core;
-};
-
-static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
-{
- inline void failure (Dwfl *dwfl, int errnum, const char *msg)
- {
- if (dwfl != NULL)
- dwfl_end (dwfl);
- if (errnum == -1)
- argp_failure (state, EXIT_FAILURE, 0, "%s: %s",
- msg, INTUSE(dwfl_errmsg) (-1));
- else
- argp_failure (state, EXIT_FAILURE, errnum, "%s", msg);
- }
- inline error_t fail (Dwfl *dwfl, int errnum, const char *msg)
- {
- failure (dwfl, errnum, msg);
- return errnum == -1 ? EIO : errnum;
- }
-
- switch (key)
- {
- case ARGP_KEY_INIT:
- {
- assert (state->hook == NULL);
- struct parse_opt *opt = calloc (1, sizeof (*opt));
- if (opt == NULL)
- failure (NULL, DWFL_E_ERRNO, "calloc");
- state->hook = opt;
- }
- break;
-
- case OPT_DEBUGINFO:
- debuginfo_path = arg;
- break;
-
- case 'e':
- {
- struct parse_opt *opt = state->hook;
- Dwfl *dwfl = opt->dwfl;
- if (dwfl == NULL)
- {
- dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
- if (dwfl == NULL)
- return fail (dwfl, -1, arg);
- opt->dwfl = dwfl;
-
- /* Start at zero so if there is just one -e foo.so,
- the DSO is shown without address bias. */
- dwfl->offline_next_address = 0;
- }
- if (dwfl->callbacks != &offline_callbacks)
- {
- toomany:
- argp_error (state, "%s",
- _("only one of -e, -p, -k, -K, or --core allowed"));
- return EINVAL;
- }
- opt->e = arg;
- }
- break;
-
- case 'p':
- {
- struct parse_opt *opt = state->hook;
- if (opt->dwfl == NULL)
- {
- Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
- int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
- if (result != 0)
- return fail (dwfl, result, arg);
-
- /* Non-fatal to not be able to attach to process, ignore error. */
- INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false);
-
- opt->dwfl = dwfl;
- }
- else
- goto toomany;
- }
- break;
-
- case 'M':
- {
- struct parse_opt *opt = state->hook;
- if (opt->dwfl == NULL)
- {
- FILE *f = fopen (arg, "r");
- if (f == NULL)
- {
- int code = errno;
- argp_failure (state, EXIT_FAILURE, code,
- "cannot open '%s'", arg);
- return code;
- }
- Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
- int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f);
- fclose (f);
- if (result != 0)
- return fail (dwfl, result, arg);
- opt->dwfl = dwfl;
- }
- else
- goto toomany;
- }
- break;
-
- case OPT_COREFILE:
- {
- struct parse_opt *opt = state->hook;
- Dwfl *dwfl = opt->dwfl;
- if (dwfl == NULL)
- opt->dwfl = dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
- /* Permit -e and --core together. */
- else if (dwfl->callbacks != &offline_callbacks)
- goto toomany;
- opt->core = arg;
- }
- break;
-
- case 'k':
- {
- struct parse_opt *opt = state->hook;
- if (opt->dwfl == NULL)
- {
- Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
- int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
- if (result != 0)
- return fail (dwfl, result, _("cannot load kernel symbols"));
- result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
- if (result != 0)
- /* Non-fatal to have no modules since we do have the kernel. */
- failure (dwfl, result, _("cannot find kernel modules"));
- opt->dwfl = dwfl;
- }
- else
- goto toomany;
- }
- break;
-
- case 'K':
- {
- struct parse_opt *opt = state->hook;
- if (opt->dwfl == NULL)
- {
- Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
- int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
- NULL);
- if (result != 0)
- return fail (dwfl, result, _("cannot find kernel or modules"));
- opt->dwfl = dwfl;
- }
- else
- goto toomany;
- }
- break;
-
- case ARGP_KEY_SUCCESS:
- {
- struct parse_opt *opt = state->hook;
- Dwfl *dwfl = opt->dwfl;
-
- if (dwfl == NULL)
- {
- /* Default if no -e, -p, or -k, is "-e a.out". */
- arg = "a.out";
- dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
- if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
- return fail (dwfl, -1, arg);
- opt->dwfl = dwfl;
- }
-
- if (opt->core)
- {
- int fd = open64 (opt->core, O_RDONLY);
- if (fd < 0)
- {
- int code = errno;
- argp_failure (state, EXIT_FAILURE, code,
- "cannot open '%s'", opt->core);
- return code;
- }
-
- Elf *core;
- Dwfl_Error error = __libdw_open_file (&fd, &core, true, false);
- if (error != DWFL_E_NOERROR)
- {
- argp_failure (state, EXIT_FAILURE, 0,
- _("cannot read ELF core file: %s"),
- INTUSE(dwfl_errmsg) (error));
- return error == DWFL_E_ERRNO ? errno : EIO;
- }
-
- int result = INTUSE(dwfl_core_file_report) (dwfl, core, opt->e);
- if (result < 0)
- {
- elf_end (core);
- close (fd);
- return fail (dwfl, result, opt->core);
- }
-
- /* Non-fatal to not be able to attach to core, ignore error. */
- INTUSE(dwfl_core_file_attach) (dwfl, core);
-
- /* From now we leak FD and CORE. */
-
- if (result == 0)
- {
- argp_failure (state, EXIT_FAILURE, 0,
- _("No modules recognized in core file"));
- return ENOENT;
- }
- }
- else if (opt->e)
- {
- if (INTUSE(dwfl_report_offline) (dwfl, "", opt->e, -1) == NULL)
- return fail (dwfl, -1, opt->e);
- }
-
- /* One of the three flavors has done dwfl_begin and some reporting
- if we got here. Tie up the Dwfl and return it to the caller of
- argp_parse. */
-
- int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL);
- assert (result == 0);
-
- /* Update the input all along, so a parent parser can see it.
- As we free OPT the update below will be no longer active. */
- *(Dwfl **) state->input = dwfl;
- free (opt);
- state->hook = NULL;
- }
- break;
-
- case ARGP_KEY_ERROR:
- {
- struct parse_opt *opt = state->hook;
- dwfl_end (opt->dwfl);
- free (opt);
- state->hook = NULL;
- }
- break;
-
- default:
- return ARGP_ERR_UNKNOWN;
- }
-
- /* Update the input all along, so a parent parser can see it. */
- struct parse_opt *opt = state->hook;
- if (opt)
- *(Dwfl **) state->input = opt->dwfl;
-
- return 0;
-}
-
-static const struct argp libdwfl_argp =
- { .options = options, .parser = parse_opt };
-
-const struct argp *
-dwfl_standard_argp (void)
-{
- return &libdwfl_argp;
-}
diff --git a/src/libdwfl/bzip2.c b/src/libdwfl/bzip2.c
deleted file mode 100644
index 8ad4ee5a..00000000
--- a/src/libdwfl/bzip2.c
+++ /dev/null
@@ -1,4 +0,0 @@
-/* bzlib is almost just like zlib. */
-
-#define BZLIB
-#include "gzip.c"
diff --git a/src/libdwfl/core-file.c b/src/libdwfl/core-file.c
deleted file mode 100644
index 50031aed..00000000
--- a/src/libdwfl/core-file.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/* Core file handling.
- Copyright (C) 2008-2010, 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include "../libelf/libelfP.h" /* For NOTE_ALIGN. */
-#undef _
-#include "libdwflP.h"
-#include <gelf.h>
-
-#include <sys/param.h>
-#include <unistd.h>
-#include <endian.h>
-#include <byteswap.h>
-#include "system.h"
-
-
-/* This is a prototype of what a new libelf interface might be.
- This implementation is pessimal for non-mmap cases and should
- be replaced by more diddling inside libelf internals. */
-static Elf *
-elf_begin_rand (Elf *parent, loff_t offset, loff_t size, loff_t *next)
-{
- if (parent == NULL)
- return NULL;
-
- /* On failure return, we update *NEXT to point back at OFFSET. */
- inline Elf *fail (int error)
- {
- if (next != NULL)
- *next = offset;
- //__libelf_seterrno (error);
- __libdwfl_seterrno (DWFL_E (LIBELF, error));
- return NULL;
- }
-
- loff_t min = (parent->kind == ELF_K_ELF ?
- (parent->class == ELFCLASS32
- ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))
- : parent->kind == ELF_K_AR ? SARMAG
- : 0);
-
- if (unlikely (offset < min)
- || unlikely (offset >= (loff_t) parent->maximum_size))
- return fail (ELF_E_RANGE);
-
- /* For an archive, fetch just the size field
- from the archive header to override SIZE. */
- if (parent->kind == ELF_K_AR)
- {
- struct ar_hdr h = { .ar_size = "" };
-
- if (unlikely (parent->maximum_size - offset < sizeof h))
- return fail (ELF_E_RANGE);
-
- if (parent->map_address != NULL)
- memcpy (h.ar_size, parent->map_address + parent->start_offset + offset,
- sizeof h.ar_size);
- else if (unlikely (pread_retry (parent->fildes,
- h.ar_size, sizeof (h.ar_size),
- parent->start_offset + offset
- + offsetof (struct ar_hdr, ar_size))
- != sizeof (h.ar_size)))
- return fail (ELF_E_READ_ERROR);
-
- offset += sizeof h;
-
- char *endp;
- size = strtoll (h.ar_size, &endp, 10);
- if (unlikely (endp == h.ar_size)
- || unlikely ((loff_t) parent->maximum_size - offset < size))
- return fail (ELF_E_INVALID_ARCHIVE);
- }
-
- if (unlikely ((loff_t) parent->maximum_size - offset < size))
- return fail (ELF_E_RANGE);
-
- /* Even if we fail at this point, update *NEXT to point past the file. */
- if (next != NULL)
- *next = offset + size;
-
- if (unlikely (offset == 0)
- && unlikely (size == (loff_t) parent->maximum_size))
- return elf_clone (parent, parent->cmd);
-
- /* Note the image is guaranteed live only as long as PARENT
- lives. Using elf_memory is quite suboptimal if the whole
- file is not mmap'd. We really should have something like
- a generalization of the archive support. */
- Elf_Data *data = elf_getdata_rawchunk (parent, offset, size, ELF_T_BYTE);
- if (data == NULL)
- return NULL;
- assert ((loff_t) data->d_size == size);
- return elf_memory (data->d_buf, size);
-}
-
-
-int
-dwfl_report_core_segments (Dwfl *dwfl, Elf *elf, size_t phnum, GElf_Phdr *notes)
-{
- if (unlikely (dwfl == NULL))
- return -1;
-
- int result = 0;
-
- if (notes != NULL)
- notes->p_type = PT_NULL;
-
- for (size_t ndx = 0; result >= 0 && ndx < phnum; ++ndx)
- {
- GElf_Phdr phdr_mem;
- GElf_Phdr *phdr = gelf_getphdr (elf, ndx, &phdr_mem);
- if (unlikely (phdr == NULL))
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return -1;
- }
- switch (phdr->p_type)
- {
- case PT_LOAD:
- result = dwfl_report_segment (dwfl, ndx, phdr, 0, NULL);
- break;
-
- case PT_NOTE:
- if (notes != NULL)
- {
- *notes = *phdr;
- notes = NULL;
- }
- break;
- }
- }
-
- return result;
-}
-
-/* Never read more than this much without mmap. */
-#define MAX_EAGER_COST 8192
-
-static bool
-core_file_read_eagerly (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *name __attribute__ ((unused)),
- Dwarf_Addr start __attribute__ ((unused)),
- void **buffer, size_t *buffer_available,
- GElf_Off cost, GElf_Off worthwhile,
- GElf_Off whole,
- GElf_Off contiguous __attribute__ ((unused)),
- void *arg, Elf **elfp)
-{
- Elf *core = arg;
-
- if (whole <= *buffer_available)
- {
- /* All there ever was, we already have on hand. */
-
- if (core->map_address == NULL)
- {
- /* We already malloc'd the buffer. */
- *elfp = elf_memory (*buffer, whole);
- if (unlikely (*elfp == NULL))
- return false;
-
- (*elfp)->flags |= ELF_F_MALLOCED;
- *buffer = NULL;
- *buffer_available = 0;
- return true;
- }
-
- /* We can use the image inside the core file directly. */
- *elfp = elf_begin_rand (core, *buffer - core->map_address, whole, NULL);
- *buffer = NULL;
- *buffer_available = 0;
- return *elfp != NULL;
- }
-
- /* We don't have the whole file.
- Figure out if this is better than nothing. */
-
- if (worthwhile == 0)
- /* Caller doesn't think so. */
- return false;
-
- /*
- XXX would like to fall back to partial file via memory
- when build id find_elf fails
- also, link_map name may give file name from disk better than partial here
- requires find_elf hook re-doing the magic to fall back if no file found
- */
-
- if (mod->build_id_len > 0)
- /* There is a build ID that could help us find the whole file,
- which might be more useful than what we have.
- We'll just rely on that. */
- return false;
-
- if (core->map_address != NULL)
- /* It's cheap to get, so get it. */
- return true;
-
- /* Only use it if there isn't too much to be read. */
- return cost <= MAX_EAGER_COST;
-}
-
-bool
-dwfl_elf_phdr_memory_callback (Dwfl *dwfl, int ndx,
- void **buffer, size_t *buffer_available,
- GElf_Addr vaddr,
- size_t minread,
- void *arg)
-{
- Elf *elf = arg;
-
- if (ndx == -1)
- {
- /* Called for cleanup. */
- if (elf->map_address == NULL)
- free (*buffer);
- *buffer = NULL;
- *buffer_available = 0;
- return false;
- }
-
- const GElf_Off align = dwfl->segment_align ?: 1;
- GElf_Phdr phdr;
-
- do
- if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL))
- return false;
- while (phdr.p_type != PT_LOAD
- || ((phdr.p_vaddr + phdr.p_memsz + align - 1) & -align) <= vaddr);
-
- GElf_Off start = vaddr - phdr.p_vaddr + phdr.p_offset;
- GElf_Off end;
- GElf_Addr end_vaddr;
-
- inline void update_end ()
- {
- end = (phdr.p_offset + phdr.p_filesz + align - 1) & -align;
- end_vaddr = (phdr.p_vaddr + phdr.p_memsz + align - 1) & -align;
- }
-
- update_end ();
-
- /* Use following contiguous segments to get towards SIZE. */
- inline bool more (size_t size)
- {
- while (end <= start || end - start < size)
- {
- if (phdr.p_filesz < phdr.p_memsz)
- /* This segment is truncated, so no following one helps us. */
- return false;
-
- if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL))
- return false;
-
- if (phdr.p_type == PT_LOAD)
- {
- if (phdr.p_offset > end
- || phdr.p_vaddr > end_vaddr)
- /* It's discontiguous! */
- return false;
-
- update_end ();
- }
- }
- return true;
- }
-
- /* We need at least this much. */
- if (! more (minread))
- return false;
-
- /* See how much more we can get of what the caller wants. */
- (void) more (*buffer_available);
-
- /* If it's already on hand anyway, use as much as there is. */
- if (elf->map_address != NULL)
- (void) more (elf->maximum_size - start);
-
- /* Make sure we don't look past the end of the actual file,
- even if the headers tell us to. */
- if (unlikely (end > elf->maximum_size))
- end = elf->maximum_size;
-
- /* If the file is too small, there is nothing at all to get. */
- if (unlikely (start >= end))
- return false;
-
- if (elf->map_address != NULL)
- {
- void *contents = elf->map_address + elf->start_offset + start;
- size_t size = end - start;
-
- if (minread == 0) /* String mode. */
- {
- const void *eos = memchr (contents, '\0', size);
- if (unlikely (eos == NULL) || unlikely (eos == contents))
- return false;
- size = eos + 1 - contents;
- }
-
- if (*buffer == NULL)
- {
- *buffer = contents;
- *buffer_available = size;
- }
- else
- {
- *buffer_available = MIN (size, *buffer_available);
- memcpy (*buffer, contents, *buffer_available);
- }
- }
- else
- {
- void *into = *buffer;
- if (*buffer == NULL)
- {
- *buffer_available = MIN (minread ?: 512,
- MAX (4096, MIN (end - start,
- *buffer_available)));
- into = malloc (*buffer_available);
- if (unlikely (into == NULL))
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return false;
- }
- }
-
- ssize_t nread = pread_retry (elf->fildes, into, *buffer_available, start);
- if (nread < (ssize_t) minread)
- {
- if (into != *buffer)
- free (into);
- if (nread < 0)
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
- }
-
- if (minread == 0) /* String mode. */
- {
- const void *eos = memchr (into, '\0', nread);
- if (unlikely (eos == NULL) || unlikely (eos == into))
- {
- if (*buffer == NULL)
- free (into);
- return false;
- }
- nread = eos + 1 - into;
- }
-
- if (*buffer == NULL)
- *buffer = into;
- *buffer_available = nread;
- }
-
- return true;
-}
-
-/* Free the contents of R_DEBUG_INFO without the R_DEBUG_INFO memory itself. */
-
-static void
-clear_r_debug_info (struct r_debug_info *r_debug_info)
-{
- while (r_debug_info->module != NULL)
- {
- struct r_debug_info_module *module = r_debug_info->module;
- r_debug_info->module = module->next;
- elf_end (module->elf);
- if (module->fd != -1)
- close (module->fd);
- free (module);
- }
-}
-
-bool
-internal_function
-__libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
-{
- size_t phnum;
- if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
- return false;
- for (size_t i = 0; i < phnum; ++i)
- {
- GElf_Phdr phdr_mem;
- GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
- if (unlikely (phdr == NULL))
- return false;
- if (phdr->p_type == PT_DYNAMIC)
- {
- *vaddrp = phdr->p_vaddr;
- return true;
- }
- }
- return false;
-}
-
-int
-dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
-{
- size_t phnum;
- if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return -1;
- }
-
- free (dwfl->executable_for_core);
- if (executable == NULL)
- dwfl->executable_for_core = NULL;
- else
- {
- dwfl->executable_for_core = strdup (executable);
- if (dwfl->executable_for_core == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
- }
-
- /* First report each PT_LOAD segment. */
- GElf_Phdr notes_phdr;
- int ndx = dwfl_report_core_segments (dwfl, elf, phnum, &notes_phdr);
- if (unlikely (ndx <= 0))
- return ndx;
-
- /* Next, we should follow the chain from DT_DEBUG. */
-
- const void *auxv = NULL;
- const void *note_file = NULL;
- size_t auxv_size = 0;
- size_t note_file_size = 0;
- if (likely (notes_phdr.p_type == PT_NOTE))
- {
- /* PT_NOTE -> NT_AUXV -> AT_PHDR -> PT_DYNAMIC -> DT_DEBUG */
-
- Elf_Data *notes = elf_getdata_rawchunk (elf,
- notes_phdr.p_offset,
- notes_phdr.p_filesz,
- ELF_T_NHDR);
- if (likely (notes != NULL))
- {
- size_t pos = 0;
- GElf_Nhdr nhdr;
- size_t name_pos;
- size_t desc_pos;
- while ((pos = gelf_getnote (notes, pos, &nhdr,
- &name_pos, &desc_pos)) > 0)
- if (nhdr.n_namesz == sizeof "CORE"
- && !memcmp (notes->d_buf + name_pos, "CORE", sizeof "CORE"))
- {
- if (nhdr.n_type == NT_AUXV)
- {
- auxv = notes->d_buf + desc_pos;
- auxv_size = nhdr.n_descsz;
- }
- if (nhdr.n_type == NT_FILE)
- {
- note_file = notes->d_buf + desc_pos;
- note_file_size = nhdr.n_descsz;
- }
- }
- }
- }
-
- /* Now we have NT_AUXV contents. From here on this processing could be
- used for a live process with auxv read from /proc. */
-
- struct r_debug_info r_debug_info;
- memset (&r_debug_info, 0, sizeof r_debug_info);
- int retval = dwfl_link_map_report (dwfl, auxv, auxv_size,
- dwfl_elf_phdr_memory_callback, elf,
- &r_debug_info);
- int listed = retval > 0 ? retval : 0;
-
- /* Now sniff segment contents for modules hinted by information gathered
- from DT_DEBUG. */
-
- ndx = 0;
- do
- {
- int seg = dwfl_segment_report_module (dwfl, ndx, NULL,
- &dwfl_elf_phdr_memory_callback, elf,
- core_file_read_eagerly, elf,
- note_file, note_file_size,
- &r_debug_info);
- if (unlikely (seg < 0))
- {
- clear_r_debug_info (&r_debug_info);
- return seg;
- }
- if (seg > ndx)
- {
- ndx = seg;
- ++listed;
- }
- else
- ++ndx;
- }
- while (ndx < (int) phnum);
-
- /* Now report the modules from dwfl_link_map_report which were not filtered
- out by dwfl_segment_report_module. */
-
- Dwfl_Module **lastmodp = &dwfl->modulelist;
- while (*lastmodp != NULL)
- lastmodp = &(*lastmodp)->next;
- for (struct r_debug_info_module *module = r_debug_info.module;
- module != NULL; module = module->next)
- {
- if (module->elf == NULL)
- continue;
- GElf_Addr file_dynamic_vaddr;
- if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
- continue;
- Dwfl_Module *mod;
- mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
- module->fd, module->elf,
- module->l_ld - file_dynamic_vaddr,
- true, true);
- if (mod == NULL)
- continue;
- ++listed;
- module->elf = NULL;
- module->fd = -1;
- /* Move this module to the end of the list, so that we end
- up with a list in the same order as the link_map chain. */
- if (mod->next != NULL)
- {
- if (*lastmodp != mod)
- {
- lastmodp = &dwfl->modulelist;
- while (*lastmodp != mod)
- lastmodp = &(*lastmodp)->next;
- }
- *lastmodp = mod->next;
- mod->next = NULL;
- while (*lastmodp != NULL)
- lastmodp = &(*lastmodp)->next;
- *lastmodp = mod;
- }
- lastmodp = &mod->next;
- }
-
- clear_r_debug_info (&r_debug_info);
-
- /* We return the number of modules we found if we found any.
- If we found none, we return -1 instead of 0 if there was an
- error rather than just nothing found. */
- return listed > 0 ? listed : retval;
-}
-INTDEF (dwfl_core_file_report)
-NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
-
-#ifdef SHARED
-int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
-COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
- without_executable)
-
-int
-_compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
-{
- return dwfl_core_file_report (dwfl, elf, NULL);
-}
-#endif
diff --git a/src/libdwfl/cu.c b/src/libdwfl/cu.c
deleted file mode 100644
index 5ce531bd..00000000
--- a/src/libdwfl/cu.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/* Keeping track of DWARF compilation units in libdwfl.
- Copyright (C) 2005-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/libdwP.h"
-#include "../libdw/memory-access.h"
-#include <search.h>
-
-
-static inline Dwarf_Arange *
-dwar (Dwfl_Module *mod, unsigned int idx)
-{
- return &mod->dw->aranges->info[mod->aranges[idx].arange];
-}
-
-
-static Dwfl_Error
-addrarange (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_arange **arange)
-{
- if (mod->aranges == NULL)
- {
- struct dwfl_arange *aranges = NULL;
- Dwarf_Aranges *dwaranges = NULL;
- size_t naranges;
- if (INTUSE(dwarf_getaranges) (mod->dw, &dwaranges, &naranges) != 0)
- return DWFL_E_LIBDW;
-
- /* If the module has no aranges (when no code is included) we
- allocate nothing. */
- if (naranges != 0)
- {
- aranges = malloc (naranges * sizeof *aranges);
- if (unlikely (aranges == NULL))
- return DWFL_E_NOMEM;
-
- /* libdw has sorted its list by address, which is how we want it.
- But the sorted list is full of not-quite-contiguous runs pointing
- to the same CU. We don't care about the little gaps inside the
- module, we'll consider them part of the surrounding CU anyway.
- Collect our own array with just one record for each run of ranges
- pointing to one CU. */
-
- naranges = 0;
- Dwarf_Off lastcu = 0;
- for (size_t i = 0; i < dwaranges->naranges; ++i)
- if (i == 0 || dwaranges->info[i].offset != lastcu)
- {
- aranges[naranges].arange = i;
- aranges[naranges].cu = NULL;
- ++naranges;
- lastcu = dwaranges->info[i].offset;
- }
- }
-
- /* Store the final array, which is probably much smaller than before. */
- mod->naranges = naranges;
- mod->aranges = (realloc (aranges, naranges * sizeof aranges[0])
- ?: aranges);
- mod->lazycu += naranges;
- }
-
- /* The address must be inside the module to begin with. */
- addr = dwfl_deadjust_dwarf_addr (mod, addr);
-
- /* The ranges are sorted by address, so we can use binary search. */
- size_t l = 0, u = mod->naranges;
- while (l < u)
- {
- size_t idx = (l + u) / 2;
- Dwarf_Addr start = dwar (mod, idx)->addr;
- if (addr < start)
- {
- u = idx;
- continue;
- }
- else if (addr > start)
- {
- if (idx + 1 < mod->naranges)
- {
- if (addr >= dwar (mod, idx + 1)->addr)
- {
- l = idx + 1;
- continue;
- }
- }
- else
- {
- /* It might be in the last range. */
- const Dwarf_Arange *last
- = &mod->dw->aranges->info[mod->dw->aranges->naranges - 1];
- if (addr > last->addr + last->length)
- break;
- }
- }
-
- *arange = &mod->aranges[idx];
- return DWFL_E_NOERROR;
- }
-
- return DWFL_E_ADDR_OUTOFRANGE;
-}
-
-
-static void
-nofree (void *arg)
-{
- struct dwfl_cu *cu = arg;
- if (cu == (void *) -1l)
- return;
-
- assert (cu->mod->lazycu == 0);
-}
-
-/* One reason fewer to keep the lazy lookup table for CUs. */
-static inline void
-less_lazy (Dwfl_Module *mod)
-{
- if (--mod->lazycu > 0)
- return;
-
- /* We know about all the CUs now, we don't need this table. */
- tdestroy (mod->lazy_cu_root, nofree);
- mod->lazy_cu_root = NULL;
-}
-
-static inline Dwarf_Off
-cudie_offset (const struct dwfl_cu *cu)
-{
- /* These are real CUs, so there never is a type_sig8. Note
- initialization of dwkey.start and offset_size in intern_cu ()
- to see why this calculates the same value for both key and
- die.cu search items. */
- return DIE_OFFSET_FROM_CU_OFFSET (cu->die.cu->start, cu->die.cu->offset_size,
- 0);
-}
-
-static int
-compare_cukey (const void *a, const void *b)
-{
- Dwarf_Off a_off = cudie_offset (a);
- Dwarf_Off b_off = cudie_offset (b);
- return (a_off < b_off) ? -1 : ((a_off > b_off) ? 1 : 0);
-}
-
-/* Intern the CU if necessary. */
-static Dwfl_Error
-intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result)
-{
- struct Dwarf_CU dwkey;
- struct dwfl_cu key;
- key.die.cu = &dwkey;
- dwkey.offset_size = 0;
- dwkey.start = cuoff - (3 * 0 - 4 + 3);
- struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey);
- if (unlikely (found == NULL))
- return DWFL_E_NOMEM;
-
- if (*found == &key || *found == NULL)
- {
- if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size))
- {
- /* This is the EOF marker. Now we have interned all the CUs.
- One increment in MOD->lazycu counts not having hit EOF yet. */
- *found = (void *) -1l;
- less_lazy (mod);
- }
- else
- {
- /* This is a new entry, meaning we haven't looked at this CU. */
-
- *found = NULL;
-
- struct dwfl_cu *cu = malloc (sizeof *cu);
- if (unlikely (cu == NULL))
- return DWFL_E_NOMEM;
-
- cu->mod = mod;
- cu->next = NULL;
- cu->lines = NULL;
-
- /* XXX use non-searching lookup */
- Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cu->die);
- if (die == NULL)
- {
- free (cu);
- return DWFL_E_LIBDW;
- }
- assert (die == &cu->die);
-
- struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1)
- * sizeof (mod->cu[0])));
- if (newvec == NULL)
- {
- free (cu);
- return DWFL_E_NOMEM;
- }
- mod->cu = newvec;
-
- mod->cu[mod->ncu++] = cu;
- if (cu->die.cu->start == 0)
- mod->first_cu = cu;
-
- *found = cu;
- }
- }
-
- *result = *found;
- return DWFL_E_NOERROR;
-}
-
-
-/* Traverse all the CUs in the module. */
-
-Dwfl_Error
-internal_function
-__libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
- struct dwfl_cu **cu)
-{
- Dwarf_Off cuoff;
- struct dwfl_cu **nextp;
-
- if (lastcu == NULL)
- {
- /* Start the traversal. */
- cuoff = 0;
- nextp = &mod->first_cu;
- }
- else
- {
- /* Continue following LASTCU. */
- cuoff = lastcu->die.cu->end;
- nextp = &lastcu->next;
- }
-
- if (*nextp == NULL)
- {
- size_t cuhdrsz;
- Dwarf_Off nextoff;
- int end = INTUSE(dwarf_nextcu) (mod->dw, cuoff, &nextoff, &cuhdrsz,
- NULL, NULL, NULL);
- if (end < 0)
- return DWFL_E_LIBDW;
- if (end > 0)
- {
- *cu = NULL;
- return DWFL_E_NOERROR;
- }
-
- Dwfl_Error result = intern_cu (mod, cuoff + cuhdrsz, nextp);
- if (result != DWFL_E_NOERROR)
- return result;
-
- if ((*nextp)->next == NULL && nextoff == (Dwarf_Off) -1l)
- (*nextp)->next = (void *) -1l;
- }
-
- *cu = *nextp == (void *) -1l ? NULL : *nextp;
- return DWFL_E_NOERROR;
-}
-
-
-/* Intern the CU arange points to, if necessary. */
-
-static Dwfl_Error
-arangecu (Dwfl_Module *mod, struct dwfl_arange *arange, struct dwfl_cu **cu)
-{
- if (arange->cu == NULL)
- {
- const Dwarf_Arange *dwarange = &mod->dw->aranges->info[arange->arange];
- Dwfl_Error result = intern_cu (mod, dwarange->offset, &arange->cu);
- if (result != DWFL_E_NOERROR)
- return result;
- assert (arange->cu != NULL && arange->cu != (void *) -1l);
- less_lazy (mod); /* Each arange with null ->cu counts once. */
- }
-
- *cu = arange->cu;
- return DWFL_E_NOERROR;
-}
-
-Dwfl_Error
-internal_function
-__libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_cu **cu)
-{
- struct dwfl_arange *arange;
- return addrarange (mod, addr, &arange) ?: arangecu (mod, arange, cu);
-}
diff --git a/src/libdwfl/derelocate.c b/src/libdwfl/derelocate.c
deleted file mode 100644
index da679089..00000000
--- a/src/libdwfl/derelocate.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/* Recover relocatibility for addresses computed from debug information.
- Copyright (C) 2005-2010, 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-struct dwfl_relocation
-{
- size_t count;
- struct
- {
- Elf_Scn *scn;
- Elf_Scn *relocs;
- const char *name;
- GElf_Addr start, end;
- } refs[0];
-};
-
-
-struct secref
-{
- struct secref *next;
- Elf_Scn *scn;
- Elf_Scn *relocs;
- const char *name;
- GElf_Addr start, end;
-};
-
-static int
-compare_secrefs (const void *a, const void *b)
-{
- struct secref *const *p1 = a;
- struct secref *const *p2 = b;
-
- /* No signed difference calculation is correct here, since the
- terms are unsigned and could be more than INT64_MAX apart. */
- if ((*p1)->start < (*p2)->start)
- return -1;
- if ((*p1)->start > (*p2)->start)
- return 1;
-
- return 0;
-}
-
-static int
-cache_sections (Dwfl_Module *mod)
-{
- if (likely (mod->reloc_info != NULL))
- return mod->reloc_info->count;
-
- struct secref *refs = NULL;
- size_t nrefs = 0;
-
- size_t shstrndx;
- if (unlikely (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0))
- {
- elf_error:
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return -1;
- }
-
- bool check_reloc_sections = false;
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- goto elf_error;
-
- if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0
- && mod->e_type == ET_REL)
- {
- /* This section might not yet have been looked at. */
- if (__libdwfl_relocate_value (mod, mod->main.elf, &shstrndx,
- elf_ndxscn (scn),
- &shdr->sh_addr) != DWFL_E_NOERROR)
- continue;
- shdr = gelf_getshdr (scn, &shdr_mem);
- if (unlikely (shdr == NULL))
- goto elf_error;
- }
-
- if (shdr->sh_flags & SHF_ALLOC)
- {
- const char *name = elf_strptr (mod->main.elf, shstrndx,
- shdr->sh_name);
- if (unlikely (name == NULL))
- goto elf_error;
-
- struct secref *newref = alloca (sizeof *newref);
- newref->scn = scn;
- newref->relocs = NULL;
- newref->name = name;
- newref->start = dwfl_adjusted_address (mod, shdr->sh_addr);
- newref->end = newref->start + shdr->sh_size;
- newref->next = refs;
- refs = newref;
- ++nrefs;
- }
-
- if (mod->e_type == ET_REL
- && shdr->sh_size != 0
- && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
- && mod->dwfl->callbacks->section_address != NULL)
- {
- if (shdr->sh_info < elf_ndxscn (scn))
- {
- /* We've already looked at the section these relocs apply to. */
- Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info);
- if (likely (tscn != NULL))
- for (struct secref *sec = refs; sec != NULL; sec = sec->next)
- if (sec->scn == tscn)
- {
- sec->relocs = scn;
- break;
- }
- }
- else
- /* We'll have to do a second pass. */
- check_reloc_sections = true;
- }
- }
-
- mod->reloc_info = malloc (offsetof (struct dwfl_relocation, refs[nrefs]));
- if (mod->reloc_info == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
-
- struct secref **sortrefs = alloca (nrefs * sizeof sortrefs[0]);
- for (size_t i = nrefs; i-- > 0; refs = refs->next)
- sortrefs[i] = refs;
- assert (refs == NULL);
-
- qsort (sortrefs, nrefs, sizeof sortrefs[0], &compare_secrefs);
-
- mod->reloc_info->count = nrefs;
- for (size_t i = 0; i < nrefs; ++i)
- {
- mod->reloc_info->refs[i].name = sortrefs[i]->name;
- mod->reloc_info->refs[i].scn = sortrefs[i]->scn;
- mod->reloc_info->refs[i].relocs = sortrefs[i]->relocs;
- mod->reloc_info->refs[i].start = sortrefs[i]->start;
- mod->reloc_info->refs[i].end = sortrefs[i]->end;
- }
-
- if (unlikely (check_reloc_sections))
- {
- /* There was a reloc section that preceded its target section.
- So we have to scan again now that we have cached all the
- possible target sections we care about. */
-
- scn = NULL;
- while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- goto elf_error;
-
- if (shdr->sh_size != 0
- && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA))
- {
- Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info);
- if (likely (tscn != NULL))
- for (size_t i = 0; i < nrefs; ++i)
- if (mod->reloc_info->refs[i].scn == tscn)
- {
- mod->reloc_info->refs[i].relocs = scn;
- break;
- }
- }
- }
- }
-
- return nrefs;
-}
-
-
-int
-dwfl_module_relocations (Dwfl_Module *mod)
-{
- if (mod == NULL)
- return -1;
-
- switch (mod->e_type)
- {
- case ET_REL:
- return cache_sections (mod);
-
- case ET_DYN:
- return 1;
-
- case ET_EXEC:
- assert (mod->main.vaddr == mod->low_addr);
- break;
- }
-
- return 0;
-}
-
-const char *
-dwfl_module_relocation_info (Dwfl_Module *mod, unsigned int idx,
- Elf32_Word *shndxp)
-{
- if (mod == NULL)
- return NULL;
-
- switch (mod->e_type)
- {
- case ET_REL:
- break;
-
- case ET_DYN:
- if (idx != 0)
- return NULL;
- if (shndxp)
- *shndxp = SHN_ABS;
- return "";
-
- default:
- return NULL;
- }
-
- if (cache_sections (mod) < 0)
- return NULL;
-
- struct dwfl_relocation *sections = mod->reloc_info;
-
- if (idx >= sections->count)
- return NULL;
-
- if (shndxp)
- *shndxp = elf_ndxscn (sections->refs[idx].scn);
-
- return sections->refs[idx].name;
-}
-
-/* Check that MOD is valid and make sure its relocation has been done. */
-static bool
-check_module (Dwfl_Module *mod)
-{
- if (INTUSE(dwfl_module_getsymtab) (mod) < 0)
- {
- Dwfl_Error error = dwfl_errno ();
- if (error != DWFL_E_NO_SYMTAB)
- {
- __libdwfl_seterrno (error);
- return true;
- }
- }
-
- if (mod->dw == NULL)
- {
- Dwarf_Addr bias;
- if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
- {
- Dwfl_Error error = dwfl_errno ();
- if (error != DWFL_E_NO_DWARF)
- {
- __libdwfl_seterrno (error);
- return true;
- }
- }
- }
-
- return false;
-}
-
-/* Find the index in MOD->reloc_info.refs containing *ADDR. */
-static int
-find_section (Dwfl_Module *mod, Dwarf_Addr *addr)
-{
- if (cache_sections (mod) < 0)
- return -1;
-
- struct dwfl_relocation *sections = mod->reloc_info;
-
- /* The sections are sorted by address, so we can use binary search. */
- size_t l = 0, u = sections->count;
- while (l < u)
- {
- size_t idx = (l + u) / 2;
- if (*addr < sections->refs[idx].start)
- u = idx;
- else if (*addr > sections->refs[idx].end)
- l = idx + 1;
- else
- {
- /* Consider the limit of a section to be inside it, unless it's
- inside the next one. A section limit address can appear in
- line records. */
- if (*addr == sections->refs[idx].end
- && idx + 1 < sections->count
- && *addr == sections->refs[idx + 1].start)
- ++idx;
-
- *addr -= sections->refs[idx].start;
- return idx;
- }
- }
-
- __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_NO_MATCH));
- return -1;
-}
-
-size_t
-internal_function
-__libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr)
-{
- int idx = find_section (mod, addr);
- if (unlikely (idx == -1))
- return SHN_UNDEF;
-
- return elf_ndxscn (mod->reloc_info->refs[idx].scn);
-}
-
-int
-dwfl_module_relocate_address (Dwfl_Module *mod, Dwarf_Addr *addr)
-{
- if (unlikely (check_module (mod)))
- return -1;
-
- switch (mod->e_type)
- {
- case ET_REL:
- return find_section (mod, addr);
-
- case ET_DYN:
- /* All relative to first and only relocation base: module start. */
- *addr -= mod->low_addr;
- break;
-
- default:
- /* Already absolute, dwfl_module_relocations returned zero. We
- shouldn't really have been called, but it's a harmless no-op. */
- break;
- }
-
- return 0;
-}
-INTDEF (dwfl_module_relocate_address)
-
-Elf_Scn *
-dwfl_module_address_section (Dwfl_Module *mod, Dwarf_Addr *address,
- Dwarf_Addr *bias)
-{
- if (check_module (mod))
- return NULL;
-
- int idx = find_section (mod, address);
- if (idx < 0)
- return NULL;
-
- if (mod->reloc_info->refs[idx].relocs != NULL)
- {
- assert (mod->e_type == ET_REL);
-
- Elf_Scn *tscn = mod->reloc_info->refs[idx].scn;
- Elf_Scn *relocscn = mod->reloc_info->refs[idx].relocs;
- Dwfl_Error result = __libdwfl_relocate_section (mod, mod->main.elf,
- relocscn, tscn, true);
- if (likely (result == DWFL_E_NOERROR))
- mod->reloc_info->refs[idx].relocs = NULL;
- else
- {
- __libdwfl_seterrno (result);
- return NULL;
- }
- }
-
- *bias = dwfl_adjusted_address (mod, 0);
- return mod->reloc_info->refs[idx].scn;
-}
-INTDEF (dwfl_module_address_section)
diff --git a/src/libdwfl/dwfl_addrdie.c b/src/libdwfl/dwfl_addrdie.c
deleted file mode 100644
index 1e9b3ab6..00000000
--- a/src/libdwfl/dwfl_addrdie.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Fetch CU DIE from address.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwarf_Die *
-dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
-{
- return INTUSE(dwfl_module_addrdie) (INTUSE(dwfl_addrmodule) (dwfl, addr),
- addr, bias);
-}
diff --git a/src/libdwfl/dwfl_addrdwarf.c b/src/libdwfl/dwfl_addrdwarf.c
deleted file mode 100644
index ba412eca..00000000
--- a/src/libdwfl/dwfl_addrdwarf.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Fetch libdw handle from address.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwarf *
-dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Addr *bias)
-{
- return INTUSE(dwfl_module_getdwarf) (INTUSE(dwfl_addrmodule) (dwfl, address),
- bias);
-}
-INTDEF (dwfl_addrdwarf)
diff --git a/src/libdwfl/dwfl_addrmodule.c b/src/libdwfl/dwfl_addrmodule.c
deleted file mode 100644
index 9234eb71..00000000
--- a/src/libdwfl/dwfl_addrmodule.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Find module containing address.
- Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwfl_Module *
-dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address)
-{
- Dwfl_Module *mod;
- (void) INTUSE(dwfl_addrsegment) (dwfl, address, &mod);
- return mod;
-}
-INTDEF (dwfl_addrmodule)
diff --git a/src/libdwfl/dwfl_begin.c b/src/libdwfl/dwfl_begin.c
deleted file mode 100644
index 44c16a92..00000000
--- a/src/libdwfl/dwfl_begin.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Set up a session using libdwfl.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwfl *
-dwfl_begin (const Dwfl_Callbacks *callbacks)
-{
- if (elf_version (EV_CURRENT) == EV_NONE)
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return NULL;
- }
-
- Dwfl *dwfl = calloc (1, sizeof *dwfl);
- if (dwfl == NULL)
- __libdwfl_seterrno (DWFL_E_NOMEM);
- else
- {
- dwfl->callbacks = callbacks;
- dwfl->offline_next_address = OFFLINE_REDZONE;
- }
-
- return dwfl;
-}
-INTDEF (dwfl_begin)
diff --git a/src/libdwfl/dwfl_build_id_find_debuginfo.c b/src/libdwfl/dwfl_build_id_find_debuginfo.c
deleted file mode 100644
index f1c64bcd..00000000
--- a/src/libdwfl/dwfl_build_id_find_debuginfo.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Find the debuginfo file for a module from its build ID.
- Copyright (C) 2007, 2009, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <unistd.h>
-
-
-int
-dwfl_build_id_find_debuginfo (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *modname __attribute__ ((unused)),
- Dwarf_Addr base __attribute__ ((unused)),
- const char *file __attribute__ ((unused)),
- const char *debuglink __attribute__ ((unused)),
- GElf_Word crc __attribute__ ((unused)),
- char **debuginfo_file_name)
-{
- int fd = -1;
-
- /* Are we looking for a separate debug file for the main file or for
- an alternate (dwz multi) debug file? Alternatively we could check
- whether the dwbias == -1. */
- if (mod->dw != NULL)
- {
- const void *build_id;
- const char *altname;
- ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
- &altname,
- &build_id);
- if (build_id_len > 0)
- fd = __libdwfl_open_by_build_id (mod, true, debuginfo_file_name,
- build_id_len, build_id);
-
- if (fd >= 0)
- {
- /* We need to open an Elf handle on the file so we can check its
- build ID note for validation. Backdoor the handle into the
- module data structure since we had to open it early anyway. */
- Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf,
- true, false);
- if (error != DWFL_E_NOERROR)
- __libdwfl_seterrno (error);
- else
- {
- const void *alt_build_id;
- ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf,
- &alt_build_id);
- if (alt_len > 0 && alt_len == build_id_len
- && memcmp (build_id, alt_build_id, alt_len) == 0)
- return fd;
- else
- {
- /* A mismatch! */
- elf_end (mod->alt_elf);
- mod->alt_elf = NULL;
- close (fd);
- fd = -1;
- }
- free (*debuginfo_file_name);
- *debuginfo_file_name = NULL;
- errno = 0;
- }
- }
- return fd;
- }
-
- /* We don't even have the Dwarf yet and it isn't in the main file.
- Try to find separate debug file now using the module build id. */
- const unsigned char *bits;
- GElf_Addr vaddr;
-
- if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0)
- fd = __libdwfl_open_mod_by_build_id (mod, true, debuginfo_file_name);
- if (fd >= 0)
- {
- /* We need to open an Elf handle on the file so we can check its
- build ID note for validation. Backdoor the handle into the
- module data structure since we had to open it early anyway. */
- Dwfl_Error error = __libdw_open_file (&fd, &mod->debug.elf, true, false);
- if (error != DWFL_E_NOERROR)
- __libdwfl_seterrno (error);
- else if (likely (__libdwfl_find_build_id (mod, false,
- mod->debug.elf) == 2))
- {
- /* Also backdoor the gratuitous flag. */
- mod->debug.valid = true;
- return fd;
- }
- else
- {
- /* A mismatch! */
- elf_end (mod->debug.elf);
- mod->debug.elf = NULL;
- close (fd);
- fd = -1;
- }
- free (*debuginfo_file_name);
- *debuginfo_file_name = NULL;
- errno = 0;
- }
- return fd;
-}
-INTDEF (dwfl_build_id_find_debuginfo)
diff --git a/src/libdwfl/dwfl_build_id_find_elf.c b/src/libdwfl/dwfl_build_id_find_elf.c
deleted file mode 100644
index 062aad1f..00000000
--- a/src/libdwfl/dwfl_build_id_find_elf.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Find an ELF file for a module from its build ID.
- Copyright (C) 2007-2010, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <inttypes.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-
-int
-internal_function
-__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name,
- const size_t id_len, const uint8_t *id)
-{
- /* Search debuginfo_path directories' .build-id/ subdirectories. */
-
- char id_name[sizeof "/.build-id/" + 1 + id_len * 2 + sizeof ".debug" - 1];
- strcpy (id_name, "/.build-id/");
- int n = snprintf (&id_name[sizeof "/.build-id/" - 1],
- 4, "%02" PRIx8 "/", (uint8_t) id[0]);
- assert (n == 3);
- for (size_t i = 1; i < id_len; ++i)
- {
- n = snprintf (&id_name[sizeof "/.build-id/" - 1 + 3 + (i - 1) * 2],
- 3, "%02" PRIx8, (uint8_t) id[i]);
- assert (n == 2);
- }
- if (debug)
- strcpy (&id_name[sizeof "/.build-id/" - 1 + 3 + (id_len - 1) * 2],
- ".debug");
-
- const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
- char *path = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
- ?: DEFAULT_DEBUGINFO_PATH);
-
- int fd = -1;
- char *dir;
- while (fd < 0 && (dir = strsep (&path, ":")) != NULL)
- {
- if (dir[0] == '+' || dir[0] == '-')
- ++dir;
-
- /* Only absolute directory names are useful to us. */
- if (dir[0] != '/')
- continue;
-
- size_t dirlen = strlen (dir);
- char *name = malloc (dirlen + sizeof id_name);
- if (unlikely (name == NULL))
- break;
- memcpy (mempcpy (name, dir, dirlen), id_name, sizeof id_name);
-
- fd = TEMP_FAILURE_RETRY (open64 (name, O_RDONLY));
- if (fd >= 0)
- {
- if (*file_name != NULL)
- free (*file_name);
- *file_name = canonicalize_file_name (name);
- if (*file_name == NULL)
- {
- *file_name = name;
- name = NULL;
- }
- }
- free (name);
- }
-
- /* If we simply found nothing, clear errno. If we had some other error
- with the file, report that. Possibly this should treat other errors
- like ENOENT too. But ignoring all errors could mask some that should
- be reported. */
- if (fd < 0 && errno == ENOENT)
- errno = 0;
-
- return fd;
-}
-
-int
-internal_function
-__libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, char **file_name)
-{
- /* If *FILE_NAME was primed into the module, leave it there
- as the fallback when we have nothing to offer. */
- errno = 0;
- if (mod->build_id_len <= 0)
- return -1;
-
- const size_t id_len = mod->build_id_len;
- const uint8_t *id = mod->build_id_bits;
-
- return __libdwfl_open_by_build_id (mod, debug, file_name, id_len, id);
-}
-
-int
-dwfl_build_id_find_elf (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *modname __attribute__ ((unused)),
- Dwarf_Addr base __attribute__ ((unused)),
- char **file_name, Elf **elfp)
-{
- *elfp = NULL;
- if (mod->is_executable && mod->dwfl->executable_for_core != NULL)
- {
- /* When dwfl_core_file_report was called with a non-NULL executable file
- name this callback will replace the Dwfl_Module main.name with the
- recorded executable file when MOD was identified as main executable
- (which then triggers opening and reporting of the executable). */
- int fd = open64 (mod->dwfl->executable_for_core, O_RDONLY);
- if (fd >= 0)
- {
- *file_name = strdup (mod->dwfl->executable_for_core);
- if (*file_name != NULL)
- return fd;
- else
- close (fd);
- }
- }
- int fd = __libdwfl_open_mod_by_build_id (mod, false, file_name);
- if (fd >= 0)
- {
- Dwfl_Error error = __libdw_open_file (&fd, elfp, true, false);
- if (error != DWFL_E_NOERROR)
- __libdwfl_seterrno (error);
- else if (__libdwfl_find_build_id (mod, false, *elfp) == 2)
- {
- /* This is a backdoor signal to short-circuit the ID refresh. */
- mod->main.valid = true;
- return fd;
- }
- else
- {
- /* This file does not contain the ID it should! */
- elf_end (*elfp);
- *elfp = NULL;
- close (fd);
- fd = -1;
- }
- free (*file_name);
- *file_name = NULL;
- }
- else if (errno == 0 && mod->build_id_len > 0)
- /* Setting this with no file yet loaded is a marker that
- the build ID is authoritative even if we also know a
- putative *FILE_NAME. */
- mod->main.valid = true;
-
- return fd;
-}
-INTDEF (dwfl_build_id_find_elf)
diff --git a/src/libdwfl/dwfl_cumodule.c b/src/libdwfl/dwfl_cumodule.c
deleted file mode 100644
index c5cf004d..00000000
--- a/src/libdwfl/dwfl_cumodule.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Find the module for a CU DIE previously returned by libdwfl.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwfl_Module *
-dwfl_cumodule (Dwarf_Die *cudie)
-{
- struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
- return cu->mod;
-}
diff --git a/src/libdwfl/dwfl_dwarf_line.c b/src/libdwfl/dwfl_dwarf_line.c
deleted file mode 100644
index e96f859a..00000000
--- a/src/libdwfl/dwfl_dwarf_line.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Get information from a source line record returned by libdwfl.
- Copyright (C) 2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/libdwP.h"
-
-Dwarf_Line *
-dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias)
-{
- if (line == NULL)
- return NULL;
-
- struct dwfl_cu *cu = dwfl_linecu (line);
- const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
-
- *bias = dwfl_adjusted_dwarf_addr (cu->mod, 0);
- return (Dwarf_Line *) info;
-}
diff --git a/src/libdwfl/dwfl_end.c b/src/libdwfl/dwfl_end.c
deleted file mode 100644
index 33cae48c..00000000
--- a/src/libdwfl/dwfl_end.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Finish a session using libdwfl.
- Copyright (C) 2005, 2008, 2012-2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-void
-dwfl_end (Dwfl *dwfl)
-{
- if (dwfl == NULL)
- return;
-
- if (dwfl->process)
- __libdwfl_process_free (dwfl->process);
-
- free (dwfl->lookup_addr);
- free (dwfl->lookup_module);
- free (dwfl->lookup_segndx);
-
- Dwfl_Module *next = dwfl->modulelist;
- while (next != NULL)
- {
- Dwfl_Module *dead = next;
- next = dead->next;
- __libdwfl_module_free (dead);
- }
-
- free (dwfl->executable_for_core);
- free (dwfl);
-}
diff --git a/src/libdwfl/dwfl_error.c b/src/libdwfl/dwfl_error.c
deleted file mode 100644
index d9ca9e7e..00000000
--- a/src/libdwfl/dwfl_error.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* Error handling in libdwfl.
- Copyright (C) 2005-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <assert.h>
-#include <libintl.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "libdwflP.h"
-
-
-/* The error number. */
-static __thread int global_error;
-
-
-int
-dwfl_errno (void)
-{
- int result = global_error;
- global_error = DWFL_E_NOERROR;
- return result;
-}
-INTDEF (dwfl_errno)
-
-
-static const struct msgtable
-{
-#define DWFL_ERROR(name, text) char msg_##name[sizeof text];
- DWFL_ERRORS
-#undef DWFL_ERROR
-} msgtable =
- {
-#define DWFL_ERROR(name, text) text,
- DWFL_ERRORS
-#undef DWFL_ERROR
- };
-#define msgstr (&msgtable.msg_NOERROR[0])
-
-static const uint_fast16_t msgidx[] =
-{
-#define DWFL_ERROR(name, text) \
- [DWFL_E_##name] = offsetof (struct msgtable, msg_##name),
- DWFL_ERRORS
-#undef DWFL_ERROR
-};
-#define nmsgidx (sizeof msgidx / sizeof msgidx[0])
-
-
-static inline int
-canonicalize (Dwfl_Error error)
-{
- unsigned int value;
-
- switch (error)
- {
- default:
- value = error;
- if ((value &~ 0xffff) != 0)
- break;
- assert (value < nmsgidx);
- break;
- case DWFL_E_ERRNO:
- value = DWFL_E (ERRNO, errno);
- break;
- case DWFL_E_LIBELF:
- value = DWFL_E (LIBELF, elf_errno ());
- break;
- case DWFL_E_LIBDW:
- value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
- break;
-#if 0
- DWFL_E_LIBEBL:
- value = DWFL_E (LIBEBL, ebl_errno ());
- break;
-#endif
- }
-
- return value;
-}
-
-int
-internal_function
-__libdwfl_canon_error (Dwfl_Error error)
-{
- return canonicalize (error);
-}
-
-void
-internal_function
-__libdwfl_seterrno (Dwfl_Error error)
-{
- global_error = canonicalize (error);
-}
-
-
-const char *
-dwfl_errmsg (error)
- int error;
-{
- if (error == 0 || error == -1)
- {
- int last_error = global_error;
-
- if (error == 0 && last_error == 0)
- return NULL;
-
- error = last_error;
- global_error = DWFL_E_NOERROR;
- }
-
- switch (error &~ 0xffff)
- {
- case OTHER_ERROR (ERRNO):
- return strerror_r (error & 0xffff, "bad", 0);
- case OTHER_ERROR (LIBELF):
- return elf_errmsg (error & 0xffff);
- case OTHER_ERROR (LIBDW):
- return INTUSE(dwarf_errmsg) (error & 0xffff);
-#if 0
- case OTHER_ERROR (LIBEBL):
- return ebl_errmsg (error & 0xffff);
-#endif
- }
-
- return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
- ? error : DWFL_E_UNKNOWN_ERROR]]);
-}
-INTDEF (dwfl_errmsg)
diff --git a/src/libdwfl/dwfl_frame.c b/src/libdwfl/dwfl_frame.c
deleted file mode 100644
index f6f86c0d..00000000
--- a/src/libdwfl/dwfl_frame.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/* Get Dwarf Frame state for target PID or core file.
- Copyright (C) 2013, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <sys/ptrace.h>
-#include <unistd.h>
-
-/* Set STATE->pc_set from STATE->regs according to the backend. Return true on
- success, false on error. */
-static bool
-state_fetch_pc (Dwfl_Frame *state)
-{
- switch (state->pc_state)
- {
- case DWFL_FRAME_STATE_PC_SET:
- return true;
- case DWFL_FRAME_STATE_PC_UNDEFINED:
- abort ();
- case DWFL_FRAME_STATE_ERROR:
- {
- Ebl *ebl = state->thread->process->ebl;
- Dwarf_CIE abi_info;
- if (ebl_abi_cfi (ebl, &abi_info) != 0)
- {
- __libdwfl_seterrno (DWFL_E_LIBEBL);
- return false;
- }
- unsigned ra = abi_info.return_address_register;
- /* dwarf_frame_state_reg_is_set is not applied here. */
- if (ra >= ebl_frame_nregs (ebl))
- {
- __libdwfl_seterrno (DWFL_E_LIBEBL_BAD);
- return false;
- }
- state->pc = state->regs[ra];
- state->pc_state = DWFL_FRAME_STATE_PC_SET;
- }
- return true;
- }
- abort ();
-}
-
-/* Do not call it on your own, to be used by thread_* functions only. */
-
-static void
-state_free (Dwfl_Frame *state)
-{
- Dwfl_Thread *thread = state->thread;
- assert (thread->unwound == state);
- thread->unwound = state->unwound;
- free (state);
-}
-
-static void
-thread_free_all_states (Dwfl_Thread *thread)
-{
- while (thread->unwound)
- state_free (thread->unwound);
-}
-
-static Dwfl_Frame *
-state_alloc (Dwfl_Thread *thread)
-{
- assert (thread->unwound == NULL);
- Ebl *ebl = thread->process->ebl;
- size_t nregs = ebl_frame_nregs (ebl);
- if (nregs == 0)
- return NULL;
- assert (nregs < sizeof (((Dwfl_Frame *) NULL)->regs_set) * 8);
- Dwfl_Frame *state = malloc (sizeof (*state) + sizeof (*state->regs) * nregs);
- if (state == NULL)
- return NULL;
- state->thread = thread;
- state->signal_frame = false;
- state->initial_frame = true;
- state->pc_state = DWFL_FRAME_STATE_ERROR;
- memset (state->regs_set, 0, sizeof (state->regs_set));
- thread->unwound = state;
- state->unwound = NULL;
- return state;
-}
-
-void
-internal_function
-__libdwfl_process_free (Dwfl_Process *process)
-{
- Dwfl *dwfl = process->dwfl;
- if (process->callbacks->detach != NULL)
- process->callbacks->detach (dwfl, process->callbacks_arg);
- assert (dwfl->process == process);
- dwfl->process = NULL;
- if (process->ebl_close)
- ebl_closebackend (process->ebl);
- free (process);
- dwfl->attacherr = DWFL_E_NOERROR;
-}
-
-/* Allocate new Dwfl_Process for DWFL. */
-static void
-process_alloc (Dwfl *dwfl)
-{
- Dwfl_Process *process = malloc (sizeof (*process));
- if (process == NULL)
- return;
- process->dwfl = dwfl;
- dwfl->process = process;
-}
-
-bool
-dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
- const Dwfl_Thread_Callbacks *thread_callbacks, void *arg)
-{
- if (dwfl->process != NULL)
- {
- __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
- return false;
- }
-
- /* Reset any previous error, we are just going to try again. */
- dwfl->attacherr = DWFL_E_NOERROR;
- if (thread_callbacks == NULL || thread_callbacks->next_thread == NULL
- || thread_callbacks->set_initial_registers == NULL)
- {
- dwfl->attacherr = DWFL_E_INVALID_ARGUMENT;
- fail:
- dwfl->attacherr = __libdwfl_canon_error (dwfl->attacherr);
- __libdwfl_seterrno (dwfl->attacherr);
- return false;
- }
-
- Ebl *ebl;
- bool ebl_close;
- if (elf != NULL)
- {
- ebl = ebl_openbackend (elf);
- ebl_close = true;
- }
- else
- {
- ebl = NULL;
- for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
- {
- /* Reading of the vDSO or (deleted) modules may fail as
- /proc/PID/mem is unreadable without PTRACE_ATTACH and
- we may not be PTRACE_ATTACH-ed now. MOD would not be
- re-read later to unwind it when we are already
- PTRACE_ATTACH-ed to PID. This happens when this function
- is called from dwfl_linux_proc_attach with elf == NULL.
- __libdwfl_module_getebl will call __libdwfl_getelf which
- will call the find_elf callback. */
- if (strncmp (mod->name, "[vdso: ", 7) == 0
- || strcmp (strrchr (mod->name, ' ') ?: "",
- " (deleted)") == 0)
- continue;
- Dwfl_Error error = __libdwfl_module_getebl (mod);
- if (error != DWFL_E_NOERROR)
- continue;
- ebl = mod->ebl;
- break;
- }
- ebl_close = false;
- }
- if (ebl == NULL)
- {
- /* Not identified EBL from any of the modules. */
- dwfl->attacherr = DWFL_E_PROCESS_NO_ARCH;
- goto fail;
- }
- process_alloc (dwfl);
- Dwfl_Process *process = dwfl->process;
- if (process == NULL)
- {
- if (ebl_close)
- ebl_closebackend (ebl);
- dwfl->attacherr = DWFL_E_NOMEM;
- goto fail;
- }
- process->ebl = ebl;
- process->ebl_close = ebl_close;
- process->pid = pid;
- process->callbacks = thread_callbacks;
- process->callbacks_arg = arg;
- return true;
-}
-INTDEF(dwfl_attach_state)
-
-pid_t
-dwfl_pid (Dwfl *dwfl)
-{
- if (dwfl->attacherr != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (dwfl->attacherr);
- return -1;
- }
-
- if (dwfl->process == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
- return -1;
- }
- return dwfl->process->pid;
-}
-INTDEF(dwfl_pid)
-
-Dwfl *
-dwfl_thread_dwfl (Dwfl_Thread *thread)
-{
- return thread->process->dwfl;
-}
-INTDEF(dwfl_thread_dwfl)
-
-pid_t
-dwfl_thread_tid (Dwfl_Thread *thread)
-{
- return thread->tid;
-}
-INTDEF(dwfl_thread_tid)
-
-Dwfl_Thread *
-dwfl_frame_thread (Dwfl_Frame *state)
-{
- return state->thread;
-}
-INTDEF(dwfl_frame_thread)
-
-int
-dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg),
- void *arg)
-{
- if (dwfl->attacherr != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (dwfl->attacherr);
- return -1;
- }
-
- Dwfl_Process *process = dwfl->process;
- if (process == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
- return -1;
- }
-
- Dwfl_Thread thread;
- thread.process = process;
- thread.unwound = NULL;
- thread.callbacks_arg = NULL;
- for (;;)
- {
- thread.tid = process->callbacks->next_thread (dwfl,
- process->callbacks_arg,
- &thread.callbacks_arg);
- if (thread.tid < 0)
- {
- Dwfl_Error saved_errno = dwfl_errno ();
- thread_free_all_states (&thread);
- __libdwfl_seterrno (saved_errno);
- return -1;
- }
- if (thread.tid == 0)
- {
- thread_free_all_states (&thread);
- __libdwfl_seterrno (DWFL_E_NOERROR);
- return 0;
- }
- int err = callback (&thread, arg);
- if (err != DWARF_CB_OK)
- {
- thread_free_all_states (&thread);
- return err;
- }
- assert (thread.unwound == NULL);
- }
- /* NOTREACHED */
-}
-INTDEF(dwfl_getthreads)
-
-struct one_arg
-{
- pid_t tid;
- bool seen;
- int (*callback) (Dwfl_Thread *thread, void *arg);
- void *arg;
- int ret;
-};
-
-static int
-get_one_thread_cb (Dwfl_Thread *thread, void *arg)
-{
- struct one_arg *oa = (struct one_arg *) arg;
- if (! oa->seen && INTUSE(dwfl_thread_tid) (thread) == oa->tid)
- {
- oa->seen = true;
- oa->ret = oa->callback (thread, oa->arg);
- return DWARF_CB_ABORT;
- }
-
- return DWARF_CB_OK;
-}
-
-/* Note not currently exported, will be when there are more Dwfl_Thread
- properties to query. Use dwfl_getthread_frames for now directly. */
-static int
-getthread (Dwfl *dwfl, pid_t tid,
- int (*callback) (Dwfl_Thread *thread, void *arg),
- void *arg)
-{
- if (dwfl->attacherr != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (dwfl->attacherr);
- return -1;
- }
-
- Dwfl_Process *process = dwfl->process;
- if (process == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
- return -1;
- }
-
- if (process->callbacks->get_thread != NULL)
- {
- Dwfl_Thread thread;
- thread.process = process;
- thread.unwound = NULL;
- thread.callbacks_arg = NULL;
-
- if (process->callbacks->get_thread (dwfl, tid, process->callbacks_arg,
- &thread.callbacks_arg))
- {
- int err;
- thread.tid = tid;
- err = callback (&thread, arg);
- thread_free_all_states (&thread);
- return err;
- }
-
- return -1;
- }
-
- struct one_arg oa = { .tid = tid, .callback = callback,
- .arg = arg, .seen = false };
- int err = INTUSE(dwfl_getthreads) (dwfl, get_one_thread_cb, &oa);
-
- if (err == DWARF_CB_ABORT && oa.seen)
- return oa.ret;
-
- if (err == DWARF_CB_OK && ! oa.seen)
- {
- errno = ESRCH;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return -1;
- }
-
- return err;
-}
-
-struct one_thread
-{
- int (*callback) (Dwfl_Frame *frame, void *arg);
- void *arg;
-};
-
-static int
-get_one_thread_frames_cb (Dwfl_Thread *thread, void *arg)
-{
- struct one_thread *ot = (struct one_thread *) arg;
- return INTUSE(dwfl_thread_getframes) (thread, ot->callback, ot->arg);
-}
-
-int
-dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
- int (*callback) (Dwfl_Frame *frame, void *arg),
- void *arg)
-{
- struct one_thread ot = { .callback = callback, .arg = arg };
- return getthread (dwfl, tid, get_one_thread_frames_cb, &ot);
-}
-INTDEF(dwfl_getthread_frames)
-
-int
-dwfl_thread_getframes (Dwfl_Thread *thread,
- int (*callback) (Dwfl_Frame *state, void *arg),
- void *arg)
-{
- if (thread->unwound != NULL)
- {
- /* We had to be called from inside CALLBACK. */
- __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
- return -1;
- }
- Ebl *ebl = thread->process->ebl;
- if (ebl_frame_nregs (ebl) == 0)
- {
- __libdwfl_seterrno (DWFL_E_NO_UNWIND);
- return -1;
- }
- if (state_alloc (thread) == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
- Dwfl_Process *process = thread->process;
- if (! process->callbacks->set_initial_registers (thread,
- thread->callbacks_arg))
- {
- thread_free_all_states (thread);
- return -1;
- }
- if (! state_fetch_pc (thread->unwound))
- {
- if (process->callbacks->thread_detach)
- process->callbacks->thread_detach (thread, thread->callbacks_arg);
- thread_free_all_states (thread);
- return -1;
- }
-
- Dwfl_Frame *state;
- do
- {
- state = thread->unwound;
- int err = callback (state, arg);
- if (err != DWARF_CB_OK)
- {
- if (process->callbacks->thread_detach)
- process->callbacks->thread_detach (thread, thread->callbacks_arg);
- thread_free_all_states (thread);
- return err;
- }
- __libdwfl_frame_unwind (state);
- /* The old frame is no longer needed. */
- state_free (thread->unwound);
- state = thread->unwound;
- }
- while (state && state->pc_state == DWFL_FRAME_STATE_PC_SET);
-
- Dwfl_Error err = dwfl_errno ();
- if (process->callbacks->thread_detach)
- process->callbacks->thread_detach (thread, thread->callbacks_arg);
- if (state == NULL || state->pc_state == DWFL_FRAME_STATE_ERROR)
- {
- thread_free_all_states (thread);
- __libdwfl_seterrno (err);
- return -1;
- }
- assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
- thread_free_all_states (thread);
- return 0;
-}
-INTDEF(dwfl_thread_getframes)
diff --git a/src/libdwfl/dwfl_frame_pc.c b/src/libdwfl/dwfl_frame_pc.c
deleted file mode 100644
index 296c815b..00000000
--- a/src/libdwfl/dwfl_frame_pc.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Get return address register value for frame.
- Copyright (C) 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "libdwflP.h"
-
-bool
-dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation)
-{
- assert (state->pc_state == DWFL_FRAME_STATE_PC_SET);
- *pc = state->pc;
- ebl_normalize_pc (state->thread->process->ebl, pc);
- if (isactivation)
- {
- /* Bottom frame? */
- if (state->initial_frame)
- *isactivation = true;
- /* *ISACTIVATION is logical union of whether current or previous frame
- state is SIGNAL_FRAME. */
- else if (state->signal_frame)
- *isactivation = true;
- else
- {
- /* If the previous frame has unwound unsuccessfully just silently do
- not consider it could be a SIGNAL_FRAME. */
- __libdwfl_frame_unwind (state);
- if (state->unwound == NULL
- || state->unwound->pc_state != DWFL_FRAME_STATE_PC_SET)
- *isactivation = false;
- else
- *isactivation = state->unwound->signal_frame;
- }
- }
- return true;
-}
-INTDEF (dwfl_frame_pc)
diff --git a/src/libdwfl/dwfl_frame_regs.c b/src/libdwfl/dwfl_frame_regs.c
deleted file mode 100644
index 10803fe7..00000000
--- a/src/libdwfl/dwfl_frame_regs.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Get Dwarf Frame state from modules present in DWFL.
- Copyright (C) 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-bool
-dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg,
- unsigned nregs, const Dwarf_Word *regs)
-{
- Dwfl_Frame *state = thread->unwound;
- assert (state && state->unwound == NULL);
- assert (state->initial_frame);
- for (unsigned regno = firstreg; regno < firstreg + nregs; regno++)
- if (! __libdwfl_frame_reg_set (state, regno, regs[regno - firstreg]))
- {
- __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
- return false;
- }
- return true;
-}
-INTDEF(dwfl_thread_state_registers)
-
-void
-dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
-{
- Dwfl_Frame *state = thread->unwound;
- assert (state && state->unwound == NULL);
- assert (state->initial_frame);
- state->pc = pc;
- state->pc_state = DWFL_FRAME_STATE_PC_SET;
-}
-INTDEF(dwfl_thread_state_register_pc)
diff --git a/src/libdwfl/dwfl_getdwarf.c b/src/libdwfl/dwfl_getdwarf.c
deleted file mode 100644
index 8d1d9ba7..00000000
--- a/src/libdwfl/dwfl_getdwarf.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Iterate through modules to fetch Dwarf information.
- Copyright (C) 2005, 2008 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-struct module_callback_info
-{
- int (*callback) (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- Dwarf *, Dwarf_Addr, void *);
- void *arg;
-};
-
-static int
-module_callback (Dwfl_Module *mod, void **userdata,
- const char *name, Dwarf_Addr start, void *arg)
-{
- const struct module_callback_info *info = arg;
- Dwarf_Addr bias = 0;
- Dwarf *dw = INTUSE(dwfl_module_getdwarf) (mod, &bias);
- return (*info->callback) (mod, userdata, name, start, dw, bias, info->arg);
-}
-
-ptrdiff_t
-dwfl_getdwarf (Dwfl *dwfl,
- int (*callback) (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- Dwarf *, Dwarf_Addr, void *),
- void *arg,
- ptrdiff_t offset)
-{
- struct module_callback_info info = { callback, arg };
- return INTUSE(dwfl_getmodules) (dwfl, &module_callback, &info, offset);
-}
diff --git a/src/libdwfl/dwfl_getmodules.c b/src/libdwfl/dwfl_getmodules.c
deleted file mode 100644
index eed9b4ff..00000000
--- a/src/libdwfl/dwfl_getmodules.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Iterate through modules.
- Copyright (C) 2005, 2008 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-ptrdiff_t
-dwfl_getmodules (Dwfl *dwfl,
- int (*callback) (Dwfl_Module *, void **,
- const char *, Dwarf_Addr, void *),
- void *arg,
- ptrdiff_t offset)
-{
- if (dwfl == NULL)
- return -1;
-
- /* We iterate through the linked list when it's all we have.
- But continuing from an offset is slow that way. So when
- DWFL->lookup_module is populated, we can instead keep our
- place by jumping directly into the array. Since the actions
- of a callback could cause it to get populated, we must
- choose the style of place-holder when we return an offset,
- and we encode the choice in the low bits of that value. */
-
- Dwfl_Module *m = dwfl->modulelist;
-
- if ((offset & 3) == 1)
- {
- offset >>= 2;
- for (ptrdiff_t pos = 0; pos < offset; ++pos)
- if (m == NULL)
- return -1;
- else
- m = m->next;
- }
- else if (((offset & 3) == 2) && likely (dwfl->lookup_module != NULL))
- {
- offset >>= 2;
-
- if ((size_t) offset - 1 == dwfl->lookup_elts)
- return 0;
-
- if (unlikely ((size_t) offset - 1 > dwfl->lookup_elts))
- return -1;
-
- m = dwfl->lookup_module[offset - 1];
- if (unlikely (m == NULL))
- return -1;
- }
- else if (offset != 0)
- {
- __libdwfl_seterrno (DWFL_E_BADSTROFF);
- return -1;
- }
-
- while (m != NULL)
- {
- int ok = (*callback) (MODCB_ARGS (m), arg);
- ++offset;
- m = m->next;
- if (ok != DWARF_CB_OK)
- return ((dwfl->lookup_module == NULL) ? ((offset << 2) | 1)
- : (((m == NULL ? (ptrdiff_t) dwfl->lookup_elts + 1
- : m->segment + 1) << 2) | 2));
- }
- return 0;
-}
-INTDEF (dwfl_getmodules)
diff --git a/src/libdwfl/dwfl_getsrc.c b/src/libdwfl/dwfl_getsrc.c
deleted file mode 100644
index 8d4ae022..00000000
--- a/src/libdwfl/dwfl_getsrc.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Find source location for PC address.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwfl_Line *
-dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr)
-{
- return INTUSE(dwfl_module_getsrc) (INTUSE(dwfl_addrmodule) (dwfl, addr),
- addr);
-}
diff --git a/src/libdwfl/dwfl_getsrclines.c b/src/libdwfl/dwfl_getsrclines.c
deleted file mode 100644
index bdfcf5c6..00000000
--- a/src/libdwfl/dwfl_getsrclines.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Fetch source line information for CU.
- Copyright (C) 2005, 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-int
-dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines)
-{
- struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
-
- if (cu->lines == NULL)
- {
- Dwfl_Error error = __libdwfl_cu_getsrclines (cu);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return -1;
- }
- }
-
- *nlines = cu->die.cu->lines->nlines;
- return 0;
-}
diff --git a/src/libdwfl/dwfl_line_comp_dir.c b/src/libdwfl/dwfl_line_comp_dir.c
deleted file mode 100644
index bda09c46..00000000
--- a/src/libdwfl/dwfl_line_comp_dir.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Get information from a source line record returned by libdwfl.
- Copyright (C) 2005, 2006 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <dwarf.h>
-
-const char *
-dwfl_line_comp_dir (Dwfl_Line *line)
-{
- if (line == NULL)
- return NULL;
-
- struct dwfl_cu *cu = dwfl_linecu (line);
- Dwarf_Attribute attr_mem;
- return INTUSE(dwarf_formstring) (INTUSE(dwarf_attr) (&cu->die,
- DW_AT_comp_dir,
- &attr_mem));
-}
diff --git a/src/libdwfl/dwfl_linecu.c b/src/libdwfl/dwfl_linecu.c
deleted file mode 100644
index ce78d297..00000000
--- a/src/libdwfl/dwfl_linecu.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Fetch the module containing a source line record returned by libdwfl.
- Copyright (C) 2006 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-#undef dwfl_linecu
-
-Dwarf_Die *
-dwfl_linecu (Dwfl_Line *line)
-{
- if (line == NULL)
- return NULL;
-
- struct dwfl_cu *cu = dwfl_linecu_inline (line);
- return &cu->die;
-}
diff --git a/src/libdwfl/dwfl_lineinfo.c b/src/libdwfl/dwfl_lineinfo.c
deleted file mode 100644
index dfb27d82..00000000
--- a/src/libdwfl/dwfl_lineinfo.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Get information from a source line record returned by libdwfl.
- Copyright (C) 2005-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/libdwP.h"
-
-const char *
-dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, int *linep, int *colp,
- Dwarf_Word *mtime, Dwarf_Word *length)
-{
- if (line == NULL)
- return NULL;
-
- struct dwfl_cu *cu = dwfl_linecu (line);
- const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
-
- if (addr != NULL)
- *addr = dwfl_adjusted_dwarf_addr (cu->mod, info->addr);
- if (linep != NULL)
- *linep = info->line;
- if (colp != NULL)
- *colp = info->column;
-
- struct Dwarf_Fileinfo_s *file = &info->files->info[info->file];
- if (mtime != NULL)
- *mtime = file->mtime;
- if (length != NULL)
- *length = file->length;
- return file->name;
-}
diff --git a/src/libdwfl/dwfl_linemodule.c b/src/libdwfl/dwfl_linemodule.c
deleted file mode 100644
index e4a35e09..00000000
--- a/src/libdwfl/dwfl_linemodule.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Fetch the module containing a source line record returned by libdwfl.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwfl_Module *
-dwfl_linemodule (Dwfl_Line *line)
-{
- if (line == NULL)
- return NULL;
-
- return dwfl_linecu (line)->mod;
-}
diff --git a/src/libdwfl/dwfl_module.c b/src/libdwfl/dwfl_module.c
deleted file mode 100644
index 8efcfaa5..00000000
--- a/src/libdwfl/dwfl_module.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* Maintenance of module list in libdwfl.
- Copyright (C) 2005, 2006, 2007, 2008, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <search.h>
-#include <unistd.h>
-
-static void
-free_cu (struct dwfl_cu *cu)
-{
- if (cu->lines != NULL)
- free (cu->lines);
- free (cu);
-}
-
-static void
-nofree (void *arg __attribute__ ((unused)))
-{
-}
-
-static void
-free_file (struct dwfl_file *file)
-{
- free (file->name);
-
- /* Close the fd only on the last reference. */
- if (file->elf != NULL && elf_end (file->elf) == 0 && file->fd != -1)
- close (file->fd);
-}
-
-void
-internal_function
-__libdwfl_module_free (Dwfl_Module *mod)
-{
- if (mod->lazy_cu_root != NULL)
- tdestroy (mod->lazy_cu_root, nofree);
-
- if (mod->aranges != NULL)
- free (mod->aranges);
-
- if (mod->cu != NULL)
- {
- for (size_t i = 0; i < mod->ncu; ++i)
- free_cu (mod->cu[i]);
- free (mod->cu);
- }
-
- if (mod->dw != NULL)
- {
- INTUSE(dwarf_end) (mod->dw);
- if (mod->alt != NULL)
- {
- INTUSE(dwarf_end) (mod->alt);
- if (mod->alt_elf != NULL)
- elf_end (mod->alt_elf);
- if (mod->alt_fd != -1)
- close (mod->alt_fd);
- }
- }
-
- if (mod->ebl != NULL)
- ebl_closebackend (mod->ebl);
-
- if (mod->debug.elf != mod->main.elf)
- free_file (&mod->debug);
- free_file (&mod->main);
- free_file (&mod->aux_sym);
-
- if (mod->build_id_bits != NULL)
- free (mod->build_id_bits);
-
- if (mod->reloc_info != NULL)
- free (mod->reloc_info);
-
- if (mod->eh_cfi != NULL)
- dwarf_cfi_end (mod->eh_cfi);
-
- free (mod->name);
- free (mod);
-}
-
-void
-dwfl_report_begin_add (Dwfl *dwfl __attribute__ ((unused)))
-{
- /* The lookup table will be cleared on demand, there is nothing we need
- to do here. */
-}
-INTDEF (dwfl_report_begin_add)
-
-void
-dwfl_report_begin (Dwfl *dwfl)
-{
- /* Clear the segment lookup table. */
- dwfl->lookup_elts = 0;
-
- for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
- m->gc = true;
-
- dwfl->offline_next_address = OFFLINE_REDZONE;
-}
-INTDEF (dwfl_report_begin)
-
-/* Report that a module called NAME spans addresses [START, END).
- Returns the module handle, either existing or newly allocated,
- or returns a null pointer for an allocation error. */
-Dwfl_Module *
-dwfl_report_module (Dwfl *dwfl, const char *name,
- GElf_Addr start, GElf_Addr end)
-{
- Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
-
- inline Dwfl_Module *use (Dwfl_Module *mod)
- {
- mod->next = *tailp;
- *tailp = mod;
-
- if (unlikely (dwfl->lookup_module != NULL))
- {
- free (dwfl->lookup_module);
- dwfl->lookup_module = NULL;
- }
-
- return mod;
- }
-
- for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
- {
- if (m->low_addr == start && m->high_addr == end
- && !strcmp (m->name, name))
- {
- /* This module is still here. Move it to the place in the list
- after the last module already reported. */
- *prevp = m->next;
- m->gc = false;
- return use (m);
- }
-
- if (! m->gc)
- tailp = &m->next;
- }
-
- Dwfl_Module *mod = calloc (1, sizeof *mod);
- if (mod == NULL)
- goto nomem;
-
- mod->name = strdup (name);
- if (mod->name == NULL)
- {
- free (mod);
- nomem:
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return NULL;
- }
-
- mod->low_addr = start;
- mod->high_addr = end;
- mod->dwfl = dwfl;
-
- return use (mod);
-}
-INTDEF (dwfl_report_module)
-
-
-/* Finish reporting the current set of modules to the library.
- If REMOVED is not null, it's called for each module that
- existed before but was not included in the current report.
- Returns a nonzero return value from the callback.
- DWFL cannot be used until this function has returned zero. */
-int
-dwfl_report_end (Dwfl *dwfl,
- int (*removed) (Dwfl_Module *, void *,
- const char *, Dwarf_Addr,
- void *arg),
- void *arg)
-{
- Dwfl_Module **tailp = &dwfl->modulelist;
- while (*tailp != NULL)
- {
- Dwfl_Module *m = *tailp;
- if (m->gc && removed != NULL)
- {
- int result = (*removed) (MODCB_ARGS (m), arg);
- if (result != 0)
- return result;
- }
- if (m->gc)
- {
- *tailp = m->next;
- __libdwfl_module_free (m);
- }
- else
- tailp = &m->next;
- }
-
- return 0;
-}
-INTDEF (dwfl_report_end)
diff --git a/src/libdwfl/dwfl_module_addrdie.c b/src/libdwfl/dwfl_module_addrdie.c
deleted file mode 100644
index 20d2842a..00000000
--- a/src/libdwfl/dwfl_module_addrdie.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Fetch the CU DIE for a PC address in a given module.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwarf_Die *
-dwfl_module_addrdie (Dwfl_Module *mod, Dwarf_Addr addr, Dwarf_Addr *bias)
-{
- if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
- return NULL;
-
- struct dwfl_cu *cu;
- Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu);
- if (likely (error == DWFL_E_NOERROR))
- return &cu->die;
-
- __libdwfl_seterrno (error);
- return NULL;
-}
-INTDEF (dwfl_module_addrdie)
diff --git a/src/libdwfl/dwfl_module_addrname.c b/src/libdwfl/dwfl_module_addrname.c
deleted file mode 100644
index 88a8139d..00000000
--- a/src/libdwfl/dwfl_module_addrname.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Find debugging and symbol information for a module in libdwfl.
- Copyright (C) 2005, 2006, 2007, 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-const char *
-dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr)
-{
- GElf_Off off;
- GElf_Sym sym;
- return INTUSE(dwfl_module_addrinfo) (mod, addr, &off, &sym,
- NULL, NULL, NULL);
-}
diff --git a/src/libdwfl/dwfl_module_addrsym.c b/src/libdwfl/dwfl_module_addrsym.c
deleted file mode 100644
index d205832c..00000000
--- a/src/libdwfl/dwfl_module_addrsym.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* Find debugging and symbol information for a module in libdwfl.
- Copyright (C) 2005-2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-/* Returns the name of the symbol "closest" to ADDR.
- Never returns symbols at addresses above ADDR. */
-
-const char *
-internal_function
-__libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
- GElf_Sym *closest_sym, GElf_Word *shndxp,
- Elf **elfp, Dwarf_Addr *biasp, bool adjust_st_value)
-{
- int syments = INTUSE(dwfl_module_getsymtab) (mod);
- if (syments < 0)
- return NULL;
-
- /* Return true iff we consider ADDR to lie in the same section as SYM. */
- GElf_Word addr_shndx = SHN_UNDEF;
- Elf *addr_symelf = NULL;
- inline bool same_section (GElf_Addr value, Elf *symelf, GElf_Word shndx)
- {
- /* For absolute symbols and the like, only match exactly. */
- if (shndx >= SHN_LORESERVE)
- return value == addr;
-
- /* If value might not be st_value, the shndx of the symbol might
- not match the section of the value. Explicitly look both up. */
- if (! adjust_st_value)
- {
- Dwarf_Addr v;
- if (addr_shndx == SHN_UNDEF)
- {
- v = addr;
- addr_shndx = __libdwfl_find_section_ndx (mod, &v);
- }
-
- v = value;
- return addr_shndx == __libdwfl_find_section_ndx (mod, &v);
- }
-
- /* Figure out what section ADDR lies in. */
- if (addr_shndx == SHN_UNDEF || addr_symelf != symelf)
- {
- GElf_Addr mod_addr = dwfl_deadjust_st_value (mod, symelf, addr);
- Elf_Scn *scn = NULL;
- addr_shndx = SHN_ABS;
- addr_symelf = symelf;
- while ((scn = elf_nextscn (symelf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (likely (shdr != NULL)
- && mod_addr >= shdr->sh_addr
- && mod_addr < shdr->sh_addr + shdr->sh_size)
- {
- addr_shndx = elf_ndxscn (scn);
- break;
- }
- }
- }
-
- return shndx == addr_shndx && addr_symelf == symelf;
- }
-
- /* Keep track of the closest symbol we have seen so far.
- Here we store only symbols with nonzero st_size. */
- const char *closest_name = NULL;
- GElf_Addr closest_value = 0;
- GElf_Word closest_shndx = SHN_UNDEF;
- Elf *closest_elf = NULL;
-
- /* Keep track of an eligible symbol with st_size == 0 as a fallback. */
- const char *sizeless_name = NULL;
- GElf_Sym sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF };
- GElf_Addr sizeless_value = 0;
- GElf_Word sizeless_shndx = SHN_UNDEF;
- Elf *sizeless_elf = NULL;
-
- /* Keep track of the lowest address a relevant sizeless symbol could have. */
- GElf_Addr min_label = 0;
-
- /* Try one symbol and associated value from the search table. */
- inline void try_sym_value (GElf_Addr value, GElf_Sym *sym,
- const char *name, GElf_Word shndx,
- Elf *elf, bool resolved)
- {
- /* Even if we don't choose this symbol, its existence excludes
- any sizeless symbol (assembly label) that is below its upper
- bound. */
- if (value + sym->st_size > min_label)
- min_label = value + sym->st_size;
-
- if (sym->st_size == 0 || addr - value < sym->st_size)
- {
- /* Return GELF_ST_BIND as higher-is-better integer. */
- inline int binding_value (const GElf_Sym *symp)
- {
- switch (GELF_ST_BIND (symp->st_info))
- {
- case STB_GLOBAL:
- return 3;
- case STB_WEAK:
- return 2;
- case STB_LOCAL:
- return 1;
- default:
- return 0;
- }
- }
-
- /* This symbol is a better candidate than the current one
- if it's closer to ADDR or is global when it was local. */
- if (closest_name == NULL
- || closest_value < value
- || binding_value (closest_sym) < binding_value (sym))
- {
- if (sym->st_size != 0)
- {
- *closest_sym = *sym;
- closest_value = value;
- closest_shndx = shndx;
- closest_elf = elf;
- closest_name = name;
- }
- else if (closest_name == NULL
- && value >= min_label
- && same_section (value,
- resolved ? mod->main.elf : elf, shndx))
- {
- /* Handwritten assembly symbols sometimes have no
- st_size. If no symbol with proper size includes
- the address, we'll use the closest one that is in
- the same section as ADDR. */
- sizeless_sym = *sym;
- sizeless_value = value;
- sizeless_shndx = shndx;
- sizeless_elf = elf;
- sizeless_name = name;
- }
- }
- /* When the beginning of its range is no closer,
- the end of its range might be. Otherwise follow
- GELF_ST_BIND preference. If all are equal prefer
- the first symbol found. */
- else if (sym->st_size != 0
- && closest_value == value
- && ((closest_sym->st_size > sym->st_size
- && (binding_value (closest_sym)
- <= binding_value (sym)))
- || (closest_sym->st_size >= sym->st_size
- && (binding_value (closest_sym)
- < binding_value (sym)))))
- {
- *closest_sym = *sym;
- closest_value = value;
- closest_shndx = shndx;
- closest_elf = elf;
- closest_name = name;
- }
- }
- }
-
- /* Look through the symbol table for a matching symbol. */
- inline void search_table (int start, int end)
- {
- for (int i = start; i < end; ++i)
- {
- GElf_Sym sym;
- GElf_Addr value;
- GElf_Word shndx;
- Elf *elf;
- bool resolved;
- const char *name = __libdwfl_getsym (mod, i, &sym, &value,
- &shndx, &elf, NULL,
- &resolved, adjust_st_value);
- if (name != NULL && name[0] != '\0'
- && sym.st_shndx != SHN_UNDEF
- && value <= addr
- && GELF_ST_TYPE (sym.st_info) != STT_SECTION
- && GELF_ST_TYPE (sym.st_info) != STT_FILE
- && GELF_ST_TYPE (sym.st_info) != STT_TLS)
- {
- try_sym_value (value, &sym, name, shndx, elf, resolved);
-
- /* If this is an addrinfo variant and the value could be
- resolved then also try matching the (adjusted) st_value. */
- if (resolved && mod->e_type != ET_REL)
- {
- GElf_Addr adjusted_st_value;
- adjusted_st_value = dwfl_adjusted_st_value (mod, elf,
- sym.st_value);
- if (value != adjusted_st_value && adjusted_st_value <= addr)
- try_sym_value (adjusted_st_value, &sym, name, shndx,
- elf, false);
- }
- }
- }
- }
-
- /* First go through global symbols. mod->first_global and
- mod->aux_first_global are setup by dwfl_module_getsymtab to the
- index of the first global symbol in those symbol tables. Both
- are non-zero when the table exist, except when there is only a
- dynsym table loaded through phdrs, then first_global is zero and
- there will be no auxiliary table. All symbols with local binding
- come first in the symbol table, then all globals. The zeroth,
- null entry, in the auxiliary table is skipped if there is a main
- table. */
- int first_global = INTUSE (dwfl_module_getsymtab_first_global) (mod);
- if (first_global < 0)
- return NULL;
- search_table (first_global == 0 ? 1 : first_global, syments);
-
- /* If we found nothing searching the global symbols, then try the locals.
- Unless we have a global sizeless symbol that matches exactly. */
- if (closest_name == NULL && first_global > 1
- && (sizeless_name == NULL || sizeless_value != addr))
- search_table (1, first_global);
-
- /* If we found no proper sized symbol to use, fall back to the best
- candidate sizeless symbol we found, if any. */
- if (closest_name == NULL
- && sizeless_name != NULL && sizeless_value >= min_label)
- {
- *closest_sym = sizeless_sym;
- closest_value = sizeless_value;
- closest_shndx = sizeless_shndx;
- closest_elf = sizeless_elf;
- closest_name = sizeless_name;
- }
-
- *off = addr - closest_value;
-
- if (shndxp != NULL)
- *shndxp = closest_shndx;
- if (elfp != NULL)
- *elfp = closest_elf;
- if (biasp != NULL)
- *biasp = dwfl_adjusted_st_value (mod, closest_elf, 0);
- return closest_name;
-}
-
-
-const char *
-dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
- GElf_Sym *closest_sym, GElf_Word *shndxp)
-{
- GElf_Off off;
- return __libdwfl_addrsym (mod, addr, &off, closest_sym, shndxp,
- NULL, NULL, true);
-}
-INTDEF (dwfl_module_addrsym)
-
-const char
-*dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address,
- GElf_Off *offset, GElf_Sym *sym,
- GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *bias)
-{
- return __libdwfl_addrsym (mod, address, offset, sym, shndxp, elfp, bias,
- false);
-}
-INTDEF (dwfl_module_addrinfo)
diff --git a/src/libdwfl/dwfl_module_build_id.c b/src/libdwfl/dwfl_module_build_id.c
deleted file mode 100644
index 350bbf83..00000000
--- a/src/libdwfl/dwfl_module_build_id.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/* Return build ID information for a module.
- Copyright (C) 2007-2010, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-static int
-found_build_id (Dwfl_Module *mod, bool set,
- const void *bits, int len, GElf_Addr vaddr)
-{
- if (!set)
- /* When checking bits, we do not compare VADDR because the
- address found in a debuginfo file may not match the main
- file as modified by prelink. */
- return 1 + (mod->build_id_len == len
- && !memcmp (bits, mod->build_id_bits, len));
-
- void *copy = malloc (len);
- if (unlikely (copy == NULL))
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
-
- mod->build_id_bits = memcpy (copy, bits, len);
- mod->build_id_vaddr = vaddr;
- mod->build_id_len = len;
- return len;
-}
-
-int
-internal_function
-__libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
-{
- const void *build_id_bits;
- GElf_Addr build_id_elfaddr;
- int build_id_len;
-
- /* For mod == NULL use dwelf_elf_gnu_build_id directly. */
- assert (mod != NULL);
-
- int result = __libdwfl_find_elf_build_id (mod, elf, &build_id_bits,
- &build_id_elfaddr, &build_id_len);
- if (result <= 0)
- return result;
-
- GElf_Addr build_id_vaddr = build_id_elfaddr + (build_id_elfaddr != 0
- ? mod->main_bias : 0);
- return found_build_id (mod, set, build_id_bits, build_id_len, build_id_vaddr);
-}
-
-int
-dwfl_module_build_id (Dwfl_Module *mod,
- const unsigned char **bits, GElf_Addr *vaddr)
-{
- if (mod == NULL)
- return -1;
-
- if (mod->build_id_len == 0 && mod->main.elf != NULL)
- {
- /* We have the file, but have not examined it yet. */
- int result = __libdwfl_find_build_id (mod, true, mod->main.elf);
- if (result <= 0)
- {
- mod->build_id_len = -1; /* Cache negative result. */
- return result;
- }
- }
-
- if (mod->build_id_len <= 0)
- return 0;
-
- *bits = mod->build_id_bits;
- *vaddr = mod->build_id_vaddr;
- return mod->build_id_len;
-}
-INTDEF (dwfl_module_build_id)
-NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
-
-#ifdef SHARED
-COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
-
-int
-_compat_vaddr_at_end_dwfl_module_build_id (Dwfl_Module *mod,
- const unsigned char **bits,
- GElf_Addr *vaddr)
-{
- int result = INTUSE(dwfl_module_build_id) (mod, bits, vaddr);
- if (result > 0)
- *vaddr += (result + 3) & -4;
- return result;
-}
-#endif
diff --git a/src/libdwfl/dwfl_module_dwarf_cfi.c b/src/libdwfl/dwfl_module_dwarf_cfi.c
deleted file mode 100644
index 5182d6a0..00000000
--- a/src/libdwfl/dwfl_module_dwarf_cfi.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Find DWARF CFI for a module in libdwfl.
- Copyright (C) 2009-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/cfi.h"
-
-Dwarf_CFI *
-internal_function
-__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot, Dwarf_CFI *cfi)
-{
- if (cfi != NULL && cfi->ebl == NULL)
- {
- Dwfl_Error error = __libdwfl_module_getebl (mod);
- if (error == DWFL_E_NOERROR)
- cfi->ebl = mod->ebl;
- else
- {
- if (slot == &mod->eh_cfi)
- INTUSE(dwarf_cfi_end) (cfi);
- __libdwfl_seterrno (error);
- return NULL;
- }
- }
-
- return *slot = cfi;
-}
-
-Dwarf_CFI *
-dwfl_module_dwarf_cfi (mod, bias)
- Dwfl_Module *mod;
- Dwarf_Addr *bias;
-{
- if (mod == NULL)
- return NULL;
-
- if (mod->dwarf_cfi != NULL)
- {
- *bias = dwfl_adjusted_dwarf_addr (mod, 0);
- return mod->dwarf_cfi;
- }
-
- return __libdwfl_set_cfi (mod, &mod->dwarf_cfi,
- INTUSE(dwarf_getcfi)
- (INTUSE(dwfl_module_getdwarf) (mod, bias)));
-}
-INTDEF (dwfl_module_dwarf_cfi)
diff --git a/src/libdwfl/dwfl_module_eh_cfi.c b/src/libdwfl/dwfl_module_eh_cfi.c
deleted file mode 100644
index da10d9fb..00000000
--- a/src/libdwfl/dwfl_module_eh_cfi.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Find EH CFI for a module in libdwfl.
- Copyright (C) 2009-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/cfi.h"
-
-Dwarf_CFI *
-dwfl_module_eh_cfi (mod, bias)
- Dwfl_Module *mod;
- Dwarf_Addr *bias;
-{
- if (mod == NULL)
- return NULL;
-
- if (mod->eh_cfi != NULL)
- {
- *bias = dwfl_adjusted_address (mod, 0);
- return mod->eh_cfi;
- }
-
- __libdwfl_getelf (mod);
- if (mod->elferr != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (mod->elferr);
- return NULL;
- }
-
- *bias = dwfl_adjusted_address (mod, 0);
- return __libdwfl_set_cfi (mod, &mod->eh_cfi,
- INTUSE(dwarf_getcfi_elf) (mod->main.elf));
-}
-INTDEF (dwfl_module_eh_cfi)
diff --git a/src/libdwfl/dwfl_module_getdwarf.c b/src/libdwfl/dwfl_module_getdwarf.c
deleted file mode 100644
index 494407dd..00000000
--- a/src/libdwfl/dwfl_module_getdwarf.c
+++ /dev/null
@@ -1,1358 +0,0 @@
-/* Find debugging and symbol information for a module in libdwfl.
- Copyright (C) 2005-2012, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <inttypes.h>
-#include <fcntl.h>
-#include <string.h>
-#include <unistd.h>
-#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
-#include "../libelf/libelfP.h"
-
-static inline Dwfl_Error
-open_elf_file (Elf **elf, int *fd, char **name)
-{
- if (*elf == NULL)
- {
- /* CBFAIL uses errno if it's set, so clear it first in case we don't
- set it with an open failure below. */
- errno = 0;
-
- /* If there was a pre-primed file name left that the callback left
- behind, try to open that file name. */
- if (*fd < 0 && *name != NULL)
- *fd = TEMP_FAILURE_RETRY (open64 (*name, O_RDONLY));
-
- if (*fd < 0)
- return CBFAIL;
-
- return __libdw_open_file (fd, elf, true, false);
- }
- else if (unlikely (elf_kind (*elf) != ELF_K_ELF))
- {
- elf_end (*elf);
- *elf = NULL;
- close (*fd);
- *fd = -1;
- return DWFL_E_BADELF;
- }
-
- /* Elf file already open and looks fine. */
- return DWFL_E_NOERROR;
-}
-
-/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD.
- When we return success, FILE->elf and FILE->vaddr are set up. */
-static inline Dwfl_Error
-open_elf (Dwfl_Module *mod, struct dwfl_file *file)
-{
- Dwfl_Error error = open_elf_file (&file->elf, &file->fd, &file->name);
- if (error != DWFL_E_NOERROR)
- return error;
-
- GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
- if (ehdr == NULL)
- {
- elf_error:
- elf_end (file->elf);
- file->elf = NULL;
- close (file->fd);
- file->fd = -1;
- return DWFL_E (LIBELF, elf_errno ());
- }
-
- if (ehdr->e_type != ET_REL)
- {
- /* In any non-ET_REL file, we compute the "synchronization address".
-
- We start with the address at the end of the first PT_LOAD
- segment. When prelink converts REL to RELA in an ET_DYN
- file, it expands the space between the beginning of the
- segment and the actual code/data addresses. Since that
- change wasn't made in the debug file, the distance from
- p_vaddr to an address of interest (in an st_value or DWARF
- data) now differs between the main and debug files. The
- distance from address_sync to an address of interest remains
- consistent.
-
- If there are no section headers at all (full stripping), then
- the end of the first segment is a valid synchronization address.
- This cannot happen in a prelinked file, since prelink itself
- relies on section headers for prelinking and for undoing it.
- (If you do full stripping on a prelinked file, then you get what
- you deserve--you can neither undo the prelinking, nor expect to
- line it up with a debug file separated before prelinking.)
-
- However, when prelink processes an ET_EXEC file, it can do
- something different. There it juggles the "special" sections
- (SHT_DYNSYM et al) to make space for the additional prelink
- special sections. Sometimes it will do this by moving a special
- section like .dynstr after the real program sections in the first
- PT_LOAD segment--i.e. to the end. That changes the end address of
- the segment, so it no longer lines up correctly and is not a valid
- synchronization address to use. Because of this, we need to apply
- a different prelink-savvy means to discover the synchronization
- address when there is a separate debug file and a prelinked main
- file. That is done in find_debuginfo, below. */
-
- size_t phnum;
- if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0))
- goto elf_error;
-
- file->vaddr = file->address_sync = 0;
- for (size_t i = 0; i < phnum; ++i)
- {
- GElf_Phdr ph_mem;
- GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
- if (unlikely (ph == NULL))
- goto elf_error;
- if (ph->p_type == PT_LOAD)
- {
- file->vaddr = ph->p_vaddr & -ph->p_align;
- file->address_sync = ph->p_vaddr + ph->p_memsz;
- break;
- }
- }
- }
-
- /* We only want to set the module e_type explictly once, derived from
- the main ELF file. (It might be changed for the kernel, because
- that is special - see below.) open_elf is always called first for
- the main ELF file, because both find_dw and find_symtab call
- __libdwfl_getelf first to open the main file. So don't let debug
- or aux files override the module e_type. The kernel heuristic
- below could otherwise trigger for non-kernel/non-main files, since
- their phdrs might not match the actual load addresses. */
- if (file == &mod->main)
- {
- mod->e_type = ehdr->e_type;
-
- /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN. */
- if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
- mod->e_type = ET_DYN;
- }
- else
- assert (mod->main.elf != NULL);
-
- return DWFL_E_NOERROR;
-}
-
-/* We have an authoritative build ID for this module MOD, so don't use
- a file by name that doesn't match that ID. */
-static void
-mod_verify_build_id (Dwfl_Module *mod)
-{
- assert (mod->build_id_len > 0);
-
- switch (__builtin_expect (__libdwfl_find_build_id (mod, false,
- mod->main.elf), 2))
- {
- case 2:
- /* Build ID matches as it should. */
- return;
-
- case -1: /* ELF error. */
- mod->elferr = INTUSE(dwfl_errno) ();
- break;
-
- case 0: /* File has no build ID note. */
- case 1: /* FIle has a build ID that does not match. */
- mod->elferr = DWFL_E_WRONG_ID_ELF;
- break;
-
- default:
- abort ();
- }
-
- /* We get here when it was the right ELF file. Clear it out. */
- elf_end (mod->main.elf);
- mod->main.elf = NULL;
- if (mod->main.fd >= 0)
- {
- close (mod->main.fd);
- mod->main.fd = -1;
- }
-}
-
-/* Find the main ELF file for this module and open libelf on it.
- When we return success, MOD->main.elf and MOD->main.bias are set up. */
-void
-internal_function
-__libdwfl_getelf (Dwfl_Module *mod)
-{
- if (mod->main.elf != NULL /* Already done. */
- || mod->elferr != DWFL_E_NOERROR) /* Cached failure. */
- return;
-
- mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
- &mod->main.name,
- &mod->main.elf);
- const bool fallback = mod->main.elf == NULL && mod->main.fd < 0;
- mod->elferr = open_elf (mod, &mod->main);
- if (mod->elferr != DWFL_E_NOERROR)
- return;
-
- if (!mod->main.valid)
- {
- /* Clear any explicitly reported build ID, just in case it was wrong.
- We'll fetch it from the file when asked. */
- free (mod->build_id_bits);
- mod->build_id_bits = NULL;
- mod->build_id_len = 0;
- }
- else if (fallback)
- mod_verify_build_id (mod);
-
- mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
-}
-
-/* If the main file might have been prelinked, then we need to
- discover the correct synchronization address between the main and
- debug files. Because of prelink's section juggling, we cannot rely
- on the address_sync computed from PT_LOAD segments (see open_elf).
-
- We will attempt to discover a synchronization address based on the
- section headers instead. But finding a section address that is
- safe to use requires identifying which sections are SHT_PROGBITS.
- We can do that in the main file, but in the debug file all the
- allocated sections have been transformed into SHT_NOBITS so we have
- lost the means to match them up correctly.
-
- The only method left to us is to decode the .gnu.prelink_undo
- section in the prelinked main file. This shows what the sections
- looked like before prelink juggled them--when they still had a
- direct correspondence to the debug file. */
-static Dwfl_Error
-find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
-{
- /* The magic section is only identified by name. */
- size_t shstrndx;
- if (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)
- return DWFL_E_LIBELF;
-
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (unlikely (shdr == NULL))
- return DWFL_E_LIBELF;
- if (shdr->sh_type == SHT_PROGBITS
- && !(shdr->sh_flags & SHF_ALLOC)
- && shdr->sh_name != 0)
- {
- const char *secname = elf_strptr (mod->main.elf, shstrndx,
- shdr->sh_name);
- if (unlikely (secname == NULL))
- return DWFL_E_LIBELF;
- if (!strcmp (secname, ".gnu.prelink_undo"))
- break;
- }
- }
-
- if (scn == NULL)
- /* There was no .gnu.prelink_undo section. */
- return DWFL_E_NOERROR;
-
- Elf_Data *undodata = elf_rawdata (scn, NULL);
- if (unlikely (undodata == NULL))
- return DWFL_E_LIBELF;
-
- /* Decode the section. It consists of the original ehdr, phdrs,
- and shdrs (but omits section 0). */
-
- union
- {
- Elf32_Ehdr e32;
- Elf64_Ehdr e64;
- } ehdr;
- Elf_Data dst =
- {
- .d_buf = &ehdr,
- .d_size = sizeof ehdr,
- .d_type = ELF_T_EHDR,
- .d_version = EV_CURRENT
- };
- Elf_Data src = *undodata;
- src.d_size = gelf_fsize (mod->main.elf, ELF_T_EHDR, 1, EV_CURRENT);
- src.d_type = ELF_T_EHDR;
- if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
- elf_getident (mod->main.elf, NULL)[EI_DATA])
- == NULL))
- return DWFL_E_LIBELF;
-
- size_t shentsize = gelf_fsize (mod->main.elf, ELF_T_SHDR, 1, EV_CURRENT);
- size_t phentsize = gelf_fsize (mod->main.elf, ELF_T_PHDR, 1, EV_CURRENT);
-
- uint_fast16_t phnum;
- uint_fast16_t shnum;
- if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
- {
- if (ehdr.e32.e_shentsize != shentsize
- || ehdr.e32.e_phentsize != phentsize)
- return DWFL_E_BAD_PRELINK;
- phnum = ehdr.e32.e_phnum;
- shnum = ehdr.e32.e_shnum;
- }
- else
- {
- if (ehdr.e64.e_shentsize != shentsize
- || ehdr.e64.e_phentsize != phentsize)
- return DWFL_E_BAD_PRELINK;
- phnum = ehdr.e64.e_phnum;
- shnum = ehdr.e64.e_shnum;
- }
-
- /* Since prelink does not store the zeroth section header in the undo
- section, it cannot support SHN_XINDEX encoding. */
- if (unlikely (shnum >= SHN_LORESERVE)
- || unlikely (undodata->d_size != (src.d_size
- + phnum * phentsize
- + (shnum - 1) * shentsize)))
- return DWFL_E_BAD_PRELINK;
-
- /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections. (Most
- every file will have some SHT_PROGBITS sections, but it's possible to
- have one with nothing but .bss, i.e. SHT_NOBITS.) The special sections
- that can be moved around have different sh_type values--except for
- .interp, the section that became the PT_INTERP segment. So we exclude
- the SHT_PROGBITS section whose address matches the PT_INTERP p_vaddr.
- For this reason, we must examine the phdrs first to find PT_INTERP. */
-
- GElf_Addr main_interp = 0;
- {
- size_t main_phnum;
- if (unlikely (elf_getphdrnum (mod->main.elf, &main_phnum)))
- return DWFL_E_LIBELF;
- for (size_t i = 0; i < main_phnum; ++i)
- {
- GElf_Phdr phdr;
- if (unlikely (gelf_getphdr (mod->main.elf, i, &phdr) == NULL))
- return DWFL_E_LIBELF;
- if (phdr.p_type == PT_INTERP)
- {
- main_interp = phdr.p_vaddr;
- break;
- }
- }
- }
-
- src.d_buf += src.d_size;
- src.d_type = ELF_T_PHDR;
- src.d_size = phnum * phentsize;
-
- GElf_Addr undo_interp = 0;
- {
- union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdr;
- dst.d_buf = &phdr;
- dst.d_size = sizeof phdr;
- if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
- ehdr.e32.e_ident[EI_DATA]) == NULL))
- return DWFL_E_LIBELF;
- if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
- {
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdr.p32[i].p_type == PT_INTERP)
- {
- undo_interp = phdr.p32[i].p_vaddr;
- break;
- }
- }
- else
- {
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdr.p64[i].p_type == PT_INTERP)
- {
- undo_interp = phdr.p64[i].p_vaddr;
- break;
- }
- }
- }
-
- if (unlikely ((main_interp == 0) != (undo_interp == 0)))
- return DWFL_E_BAD_PRELINK;
-
- src.d_buf += src.d_size;
- src.d_type = ELF_T_SHDR;
- src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT);
-
- union
- {
- Elf32_Shdr s32[shnum - 1];
- Elf64_Shdr s64[shnum - 1];
- } shdr;
- dst.d_buf = &shdr;
- dst.d_size = sizeof shdr;
- if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
- ehdr.e32.e_ident[EI_DATA]) == NULL))
- return DWFL_E_LIBELF;
-
- /* Now we can look at the original section headers of the main file
- before it was prelinked. First we'll apply our method to the main
- file sections as they are after prelinking, to calculate the
- synchronization address of the main file. Then we'll apply that
- same method to the saved section headers, to calculate the matching
- synchronization address of the debug file.
-
- The method is to consider SHF_ALLOC sections that are either
- SHT_PROGBITS or SHT_NOBITS, excluding the section whose sh_addr
- matches the PT_INTERP p_vaddr. The special sections that can be
- moved by prelink have other types, except for .interp (which
- becomes PT_INTERP). The "real" sections cannot move as such, but
- .bss can be split into .dynbss and .bss, with the total memory
- image remaining the same but being spread across the two sections.
- So we consider the highest section end, which still matches up. */
-
- GElf_Addr highest;
-
- inline void consider_shdr (GElf_Addr interp,
- GElf_Word sh_type,
- GElf_Xword sh_flags,
- GElf_Addr sh_addr,
- GElf_Xword sh_size)
- {
- if ((sh_flags & SHF_ALLOC)
- && ((sh_type == SHT_PROGBITS && sh_addr != interp)
- || sh_type == SHT_NOBITS))
- {
- const GElf_Addr sh_end = sh_addr + sh_size;
- if (sh_end > highest)
- highest = sh_end;
- }
- }
-
- highest = 0;
- scn = NULL;
- while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
- {
- GElf_Shdr sh_mem;
- GElf_Shdr *sh = gelf_getshdr (scn, &sh_mem);
- if (unlikely (sh == NULL))
- return DWFL_E_LIBELF;
- consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
- sh->sh_addr, sh->sh_size);
- }
- if (highest > mod->main.vaddr)
- {
- mod->main.address_sync = highest;
-
- highest = 0;
- if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
- for (size_t i = 0; i < shnum - 1; ++i)
- consider_shdr (undo_interp, shdr.s32[i].sh_type, shdr.s32[i].sh_flags,
- shdr.s32[i].sh_addr, shdr.s32[i].sh_size);
- else
- for (size_t i = 0; i < shnum - 1; ++i)
- consider_shdr (undo_interp, shdr.s64[i].sh_type, shdr.s64[i].sh_flags,
- shdr.s64[i].sh_addr, shdr.s64[i].sh_size);
-
- if (highest > file->vaddr)
- file->address_sync = highest;
- else
- return DWFL_E_BAD_PRELINK;
- }
-
- return DWFL_E_NOERROR;
-}
-
-/* Find the separate debuginfo file for this module and open libelf on it.
- When we return success, MOD->debug is set up. */
-static Dwfl_Error
-find_debuginfo (Dwfl_Module *mod)
-{
- if (mod->debug.elf != NULL)
- return DWFL_E_NOERROR;
-
- GElf_Word debuglink_crc = 0;
- const char *debuglink_file;
- debuglink_file = INTUSE(dwelf_elf_gnu_debuglink) (mod->main.elf,
- &debuglink_crc);
-
- mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
- mod->main.name,
- debuglink_file,
- debuglink_crc,
- &mod->debug.name);
- Dwfl_Error result = open_elf (mod, &mod->debug);
- if (result == DWFL_E_NOERROR && mod->debug.address_sync != 0)
- result = find_prelink_address_sync (mod, &mod->debug);
- return result;
-}
-
-/* Try to find the alternative debug link for the given DWARF and set
- it if found. Only called when mod->dw is already setup but still
- might need an alternative (dwz multi) debug file. filename is either
- the main or debug name from which the Dwarf was created. */
-static void
-find_debug_altlink (Dwfl_Module *mod, const char *filename)
-{
- assert (mod->dw != NULL);
-
- const char *altname;
- const void *build_id;
- ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
- &altname,
- &build_id);
-
- if (build_id_len > 0)
- {
- /* We could store altfile in the module, but don't really need it. */
- char *altfile = NULL;
- mod->alt_fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
- filename,
- altname,
- 0,
- &altfile);
-
- /* The (internal) callbacks might just set mod->alt_elf directly
- because they open the Elf anyway for sanity checking.
- Otherwise open either the given file name or use the fd
- returned. */
- Dwfl_Error error = open_elf_file (&mod->alt_elf, &mod->alt_fd,
- &altfile);
- if (error == DWFL_E_NOERROR)
- {
- mod->alt = INTUSE(dwarf_begin_elf) (mod->alt_elf,
- DWARF_C_READ, NULL);
- if (mod->alt == NULL)
- {
- elf_end (mod->alt_elf);
- mod->alt_elf = NULL;
- close (mod->alt_fd);
- mod->alt_fd = -1;
- }
- else
- dwarf_setalt (mod->dw, mod->alt);
- }
-
- free (altfile); /* See above, we don't really need it. */
- }
-}
-
-/* Try to find a symbol table in FILE.
- Returns DWFL_E_NOERROR if a proper one is found.
- Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM. */
-static Dwfl_Error
-load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
- Elf_Scn **symscn, Elf_Scn **xndxscn,
- size_t *syments, int *first_global, GElf_Word *strshndx)
-{
- bool symtab = false;
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (file->elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr != NULL)
- switch (shdr->sh_type)
- {
- case SHT_SYMTAB:
- if (shdr->sh_entsize == 0)
- break;
- symtab = true;
- *symscn = scn;
- *symfile = file;
- *strshndx = shdr->sh_link;
- *syments = shdr->sh_size / shdr->sh_entsize;
- *first_global = shdr->sh_info;
- if (*xndxscn != NULL)
- return DWFL_E_NOERROR;
- break;
-
- case SHT_DYNSYM:
- if (symtab)
- break;
- /* Use this if need be, but keep looking for SHT_SYMTAB. */
- if (shdr->sh_entsize == 0)
- break;
- *symscn = scn;
- *symfile = file;
- *strshndx = shdr->sh_link;
- *syments = shdr->sh_size / shdr->sh_entsize;
- *first_global = shdr->sh_info;
- break;
-
- case SHT_SYMTAB_SHNDX:
- *xndxscn = scn;
- if (symtab)
- return DWFL_E_NOERROR;
- break;
-
- default:
- break;
- }
- }
-
- if (symtab)
- /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
- return DWFL_E_NOERROR;
-
- /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus.
- We might have found an SHT_DYNSYM and set *SYMSCN et al though. */
- *xndxscn = NULL;
- return DWFL_E_NO_SYMTAB;
-}
-
-
-/* Translate addresses into file offsets.
- OFFS[*] start out zero and remain zero if unresolved. */
-static void
-find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n,
- GElf_Addr addrs[n], GElf_Off offs[n])
-{
- size_t unsolved = n;
- for (size_t i = 0; i < phnum; ++i)
- {
- GElf_Phdr phdr_mem;
- GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
- if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
- for (size_t j = 0; j < n; ++j)
- if (offs[j] == 0
- && addrs[j] >= phdr->p_vaddr + main_bias
- && addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz)
- {
- offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
- if (--unsolved == 0)
- break;
- }
- }
-}
-
-/* Try to find a dynamic symbol table via phdrs. */
-static void
-find_dynsym (Dwfl_Module *mod)
-{
- GElf_Ehdr ehdr_mem;
- GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
-
- size_t phnum;
- if (unlikely (elf_getphdrnum (mod->main.elf, &phnum) != 0))
- return;
-
- for (size_t i = 0; i < phnum; ++i)
- {
- GElf_Phdr phdr_mem;
- GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
- if (phdr == NULL)
- break;
-
- if (phdr->p_type == PT_DYNAMIC)
- {
- /* Examine the dynamic section for the pointers we need. */
-
- Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
- phdr->p_offset, phdr->p_filesz,
- ELF_T_DYN);
- if (data == NULL)
- continue;
-
- enum
- {
- i_symtab,
- i_strtab,
- i_hash,
- i_gnu_hash,
- i_max
- };
- GElf_Addr addrs[i_max] = { 0, };
- GElf_Xword strsz = 0;
- size_t n = data->d_size / gelf_fsize (mod->main.elf,
- ELF_T_DYN, 1, EV_CURRENT);
- for (size_t j = 0; j < n; ++j)
- {
- GElf_Dyn dyn_mem;
- GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
- if (dyn != NULL)
- switch (dyn->d_tag)
- {
- case DT_SYMTAB:
- addrs[i_symtab] = dyn->d_un.d_ptr;
- continue;
-
- case DT_HASH:
- addrs[i_hash] = dyn->d_un.d_ptr;
- continue;
-
- case DT_GNU_HASH:
- addrs[i_gnu_hash] = dyn->d_un.d_ptr;
- continue;
-
- case DT_STRTAB:
- addrs[i_strtab] = dyn->d_un.d_ptr;
- continue;
-
- case DT_STRSZ:
- strsz = dyn->d_un.d_val;
- continue;
-
- default:
- continue;
-
- case DT_NULL:
- break;
- }
- break;
- }
-
- /* Translate pointers into file offsets. ADJUST is either zero
- in case the dynamic segment wasn't adjusted or mod->main_bias. */
- void translate_offs (GElf_Addr adjust)
- {
- GElf_Off offs[i_max] = { 0, };
- find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs);
-
- /* Figure out the size of the symbol table. */
- if (offs[i_hash] != 0)
- {
- /* In the original format, .hash says the size of .dynsym. */
-
- size_t entsz = SH_ENTSIZE_HASH (ehdr);
- data = elf_getdata_rawchunk (mod->main.elf,
- offs[i_hash] + entsz, entsz,
- entsz == 4 ? ELF_T_WORD
- : ELF_T_XWORD);
- if (data != NULL)
- mod->syments = (entsz == 4
- ? *(const GElf_Word *) data->d_buf
- : *(const GElf_Xword *) data->d_buf);
- }
- if (offs[i_gnu_hash] != 0 && mod->syments == 0)
- {
- /* In the new format, we can derive it with some work. */
-
- const struct
- {
- Elf32_Word nbuckets;
- Elf32_Word symndx;
- Elf32_Word maskwords;
- Elf32_Word shift2;
- } *header;
-
- data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
- sizeof *header, ELF_T_WORD);
- if (data != NULL)
- {
- header = data->d_buf;
- Elf32_Word nbuckets = header->nbuckets;
- Elf32_Word symndx = header->symndx;
- GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
- + (gelf_getclass (mod->main.elf)
- * sizeof (Elf32_Word)
- * header->maskwords));
-
- // elf_getdata_rawchunk takes a size_t, make sure it
- // doesn't overflow.
-#if SIZE_MAX <= UINT32_MAX
- if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
- data = NULL;
- else
-#endif
- data
- = elf_getdata_rawchunk (mod->main.elf, buckets_at,
- nbuckets * sizeof (Elf32_Word),
- ELF_T_WORD);
- if (data != NULL && symndx < nbuckets)
- {
- const Elf32_Word *const buckets = data->d_buf;
- Elf32_Word maxndx = symndx;
- for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
- if (buckets[bucket] > maxndx)
- maxndx = buckets[bucket];
-
- GElf_Off hasharr_at = (buckets_at
- + nbuckets * sizeof (Elf32_Word));
- hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
- do
- {
- data = elf_getdata_rawchunk (mod->main.elf,
- hasharr_at,
- sizeof (Elf32_Word),
- ELF_T_WORD);
- if (data != NULL
- && (*(const Elf32_Word *) data->d_buf & 1u))
- {
- mod->syments = maxndx + 1;
- break;
- }
- ++maxndx;
- hasharr_at += sizeof (Elf32_Word);
- } while (data != NULL);
- }
- }
- }
- if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
- mod->syments = ((offs[i_strtab] - offs[i_symtab])
- / gelf_fsize (mod->main.elf,
- ELF_T_SYM, 1, EV_CURRENT));
-
- if (mod->syments > 0)
- {
- mod->symdata = elf_getdata_rawchunk (mod->main.elf,
- offs[i_symtab],
- gelf_fsize (mod->main.elf,
- ELF_T_SYM,
- mod->syments,
- EV_CURRENT),
- ELF_T_SYM);
- if (mod->symdata != NULL)
- {
- mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
- offs[i_strtab],
- strsz,
- ELF_T_BYTE);
- if (mod->symstrdata == NULL)
- mod->symdata = NULL;
- }
- if (mod->symdata == NULL)
- mod->symerr = DWFL_E (LIBELF, elf_errno ());
- else
- {
- mod->symfile = &mod->main;
- mod->symerr = DWFL_E_NOERROR;
- }
- }
- }
-
- /* First try unadjusted, like ELF files from disk, vdso.
- Then try for already adjusted dynamic section, like ELF
- from remote memory. */
- translate_offs (0);
- if (mod->symfile == NULL)
- translate_offs (mod->main_bias);
-
- return;
- }
- }
-}
-
-
-#if USE_LZMA
-/* Try to find the offset between the main file and .gnu_debugdata. */
-static bool
-find_aux_address_sync (Dwfl_Module *mod)
-{
- /* Don't trust the phdrs in the minisymtab elf file to be setup correctly.
- The address_sync is equal to the main file it is embedded in at first. */
- mod->aux_sym.address_sync = mod->main.address_sync;
-
- /* Adjust address_sync for the difference in entry addresses, attempting to
- account for ELF relocation changes after aux was split. */
- GElf_Ehdr ehdr_main, ehdr_aux;
- if (unlikely (gelf_getehdr (mod->main.elf, &ehdr_main) == NULL)
- || unlikely (gelf_getehdr (mod->aux_sym.elf, &ehdr_aux) == NULL))
- return false;
- mod->aux_sym.address_sync += ehdr_aux.e_entry - ehdr_main.e_entry;
-
- /* The shdrs are setup OK to make find_prelink_address_sync () do the right
- thing, which is possibly more reliable, but it needs .gnu.prelink_undo. */
- if (mod->aux_sym.address_sync != 0)
- return find_prelink_address_sync (mod, &mod->aux_sym) == DWFL_E_NOERROR;
-
- return true;
-}
-#endif
-
-/* Try to find the auxiliary symbol table embedded in the main elf file
- section .gnu_debugdata. Only matters if the symbol information comes
- from the main file dynsym. No harm done if not found. */
-static void
-find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
- Elf_Scn **aux_symscn __attribute__ ((unused)),
- Elf_Scn **aux_xndxscn __attribute__ ((unused)),
- GElf_Word *aux_strshndx __attribute__ ((unused)))
-{
- /* Since a .gnu_debugdata section is compressed using lzma don't do
- anything unless we have support for that. */
-#if USE_LZMA
- Elf *elf = mod->main.elf;
-
- size_t shstrndx;
- if (elf_getshdrstrndx (elf, &shstrndx) < 0)
- return;
-
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return;
-
- const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
- if (name == NULL)
- return;
-
- if (!strcmp (name, ".gnu_debugdata"))
- break;
- }
-
- if (scn == NULL)
- return;
-
- /* Found the .gnu_debugdata section. Uncompress the lzma image and
- turn it into an ELF image. */
- Elf_Data *rawdata = elf_rawdata (scn, NULL);
- if (rawdata == NULL)
- return;
-
- Dwfl_Error error;
- void *buffer = NULL;
- size_t size = 0;
- error = __libdw_unlzma (-1, 0, rawdata->d_buf, rawdata->d_size,
- &buffer, &size);
- if (error == DWFL_E_NOERROR)
- {
- if (unlikely (size == 0))
- free (buffer);
- else
- {
- mod->aux_sym.elf = elf_memory (buffer, size);
- if (mod->aux_sym.elf == NULL)
- free (buffer);
- else
- {
- mod->aux_sym.fd = -1;
- mod->aux_sym.elf->flags |= ELF_F_MALLOCED;
- if (open_elf (mod, &mod->aux_sym) != DWFL_E_NOERROR)
- return;
- if (! find_aux_address_sync (mod))
- {
- elf_end (mod->aux_sym.elf);
- mod->aux_sym.elf = NULL;
- return;
- }
-
- /* So far, so good. Get minisymtab table data and cache it. */
- bool minisymtab = false;
- scn = NULL;
- while ((scn = elf_nextscn (mod->aux_sym.elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr != NULL)
- switch (shdr->sh_type)
- {
- case SHT_SYMTAB:
- minisymtab = true;
- *aux_symscn = scn;
- *aux_strshndx = shdr->sh_link;
- mod->aux_syments = shdr->sh_size / shdr->sh_entsize;
- mod->aux_first_global = shdr->sh_info;
- if (*aux_xndxscn != NULL)
- return;
- break;
-
- case SHT_SYMTAB_SHNDX:
- *aux_xndxscn = scn;
- if (minisymtab)
- return;
- break;
-
- default:
- break;
- }
- }
-
- if (minisymtab)
- /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
- return;
-
- /* We found no SHT_SYMTAB, so everything else is bogus. */
- *aux_xndxscn = NULL;
- *aux_strshndx = 0;
- mod->aux_syments = 0;
- elf_end (mod->aux_sym.elf);
- mod->aux_sym.elf = NULL;
- return;
- }
- }
- }
- else
- free (buffer);
-#endif
-}
-
-/* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf. */
-static void
-find_symtab (Dwfl_Module *mod)
-{
- if (mod->symdata != NULL || mod->aux_symdata != NULL /* Already done. */
- || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */
- return;
-
- __libdwfl_getelf (mod);
- mod->symerr = mod->elferr;
- if (mod->symerr != DWFL_E_NOERROR)
- return;
-
- /* First see if the main ELF file has the debugging information. */
- Elf_Scn *symscn = NULL, *xndxscn = NULL;
- Elf_Scn *aux_symscn = NULL, *aux_xndxscn = NULL;
- GElf_Word strshndx, aux_strshndx = 0;
- mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn,
- &xndxscn, &mod->syments, &mod->first_global,
- &strshndx);
- switch (mod->symerr)
- {
- default:
- return;
-
- case DWFL_E_NOERROR:
- break;
-
- case DWFL_E_NO_SYMTAB:
- /* Now we have to look for a separate debuginfo file. */
- mod->symerr = find_debuginfo (mod);
- switch (mod->symerr)
- {
- default:
- return;
-
- case DWFL_E_NOERROR:
- mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn,
- &xndxscn, &mod->syments,
- &mod->first_global, &strshndx);
- break;
-
- case DWFL_E_CB: /* The find_debuginfo hook failed. */
- mod->symerr = DWFL_E_NO_SYMTAB;
- break;
- }
-
- switch (mod->symerr)
- {
- default:
- return;
-
- case DWFL_E_NOERROR:
- break;
-
- case DWFL_E_NO_SYMTAB:
- /* There might be an auxiliary table. */
- find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx);
-
- if (symscn != NULL)
- {
- /* We still have the dynamic symbol table. */
- mod->symerr = DWFL_E_NOERROR;
- break;
- }
-
- if (aux_symscn != NULL)
- {
- /* We still have the auxiliary symbol table. */
- mod->symerr = DWFL_E_NOERROR;
- goto aux_cache;
- }
-
- /* Last ditch, look for dynamic symbols without section headers. */
- find_dynsym (mod);
- return;
- }
- break;
- }
-
- /* This does some sanity checks on the string table section. */
- if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL)
- {
- elferr:
- mod->symerr = DWFL_E (LIBELF, elf_errno ());
- goto aux_cleanup; /* This cleans up some more and tries find_dynsym. */
- }
-
- /* Cache the data; MOD->syments and MOD->first_global were set above. */
-
- mod->symstrdata = elf_getdata (elf_getscn (mod->symfile->elf, strshndx),
- NULL);
- if (mod->symstrdata == NULL || mod->symstrdata->d_buf == NULL)
- goto elferr;
-
- if (xndxscn == NULL)
- mod->symxndxdata = NULL;
- else
- {
- mod->symxndxdata = elf_getdata (xndxscn, NULL);
- if (mod->symxndxdata == NULL || mod->symxndxdata->d_buf == NULL)
- goto elferr;
- }
-
- mod->symdata = elf_getdata (symscn, NULL);
- if (mod->symdata == NULL || mod->symdata->d_buf == NULL)
- goto elferr;
-
- // Sanity check number of symbols.
- GElf_Shdr shdr_mem, *shdr = gelf_getshdr (symscn, &shdr_mem);
- if (mod->syments > mod->symdata->d_size / shdr->sh_entsize
- || (size_t) mod->first_global > mod->syments)
- goto elferr;
-
- /* Cache any auxiliary symbol info, when it fails, just ignore aux_sym. */
- if (aux_symscn != NULL)
- {
- aux_cache:
- /* This does some sanity checks on the string table section. */
- if (elf_strptr (mod->aux_sym.elf, aux_strshndx, 0) == NULL)
- {
- aux_cleanup:
- mod->aux_syments = 0;
- elf_end (mod->aux_sym.elf);
- mod->aux_sym.elf = NULL;
- /* We thought we had something through shdrs, but it failed...
- Last ditch, look for dynamic symbols without section headers. */
- find_dynsym (mod);
- return;
- }
-
- mod->aux_symstrdata = elf_getdata (elf_getscn (mod->aux_sym.elf,
- aux_strshndx),
- NULL);
- if (mod->aux_symstrdata == NULL || mod->aux_symstrdata->d_buf == NULL)
- goto aux_cleanup;
-
- if (aux_xndxscn == NULL)
- mod->aux_symxndxdata = NULL;
- else
- {
- mod->aux_symxndxdata = elf_getdata (aux_xndxscn, NULL);
- if (mod->aux_symxndxdata == NULL
- || mod->aux_symxndxdata->d_buf == NULL)
- goto aux_cleanup;
- }
-
- mod->aux_symdata = elf_getdata (aux_symscn, NULL);
- if (mod->aux_symdata == NULL || mod->aux_symdata->d_buf == NULL)
- goto aux_cleanup;
-
- // Sanity check number of aux symbols.
- shdr = gelf_getshdr (aux_symscn, &shdr_mem);
- if (mod->aux_syments > mod->aux_symdata->d_size / shdr->sh_entsize
- || (size_t) mod->aux_first_global > mod->aux_syments)
- goto aux_cleanup;
- }
-}
-
-
-/* Try to open a libebl backend for MOD. */
-Dwfl_Error
-internal_function
-__libdwfl_module_getebl (Dwfl_Module *mod)
-{
- if (mod->ebl == NULL)
- {
- __libdwfl_getelf (mod);
- if (mod->elferr != DWFL_E_NOERROR)
- return mod->elferr;
-
- mod->ebl = ebl_openbackend (mod->main.elf);
- if (mod->ebl == NULL)
- return DWFL_E_LIBEBL;
- }
- return DWFL_E_NOERROR;
-}
-
-/* Try to start up libdw on DEBUGFILE. */
-static Dwfl_Error
-load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
-{
- if (mod->e_type == ET_REL && !debugfile->relocated)
- {
- const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
-
- /* The debugging sections have to be relocated. */
- if (cb->section_address == NULL)
- return DWFL_E_NOREL;
-
- Dwfl_Error error = __libdwfl_module_getebl (mod);
- if (error != DWFL_E_NOERROR)
- return error;
-
- find_symtab (mod);
- Dwfl_Error result = mod->symerr;
- if (result == DWFL_E_NOERROR)
- result = __libdwfl_relocate (mod, debugfile->elf, true);
- if (result != DWFL_E_NOERROR)
- return result;
-
- /* Don't keep the file descriptors around. */
- if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
- {
- close (mod->main.fd);
- mod->main.fd = -1;
- }
- if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0)
- {
- close (debugfile->fd);
- debugfile->fd = -1;
- }
- }
-
- mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL);
- if (mod->dw == NULL)
- {
- int err = INTUSE(dwarf_errno) ();
- return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
- }
-
- /* Until we have iterated through all CU's, we might do lazy lookups. */
- mod->lazycu = 1;
-
- return DWFL_E_NOERROR;
-}
-
-/* Try to start up libdw on either the main file or the debuginfo file. */
-static void
-find_dw (Dwfl_Module *mod)
-{
- if (mod->dw != NULL /* Already done. */
- || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure. */
- return;
-
- __libdwfl_getelf (mod);
- mod->dwerr = mod->elferr;
- if (mod->dwerr != DWFL_E_NOERROR)
- return;
-
- /* First see if the main ELF file has the debugging information. */
- mod->dwerr = load_dw (mod, &mod->main);
- switch (mod->dwerr)
- {
- case DWFL_E_NOERROR:
- mod->debug.elf = mod->main.elf;
- mod->debug.address_sync = mod->main.address_sync;
-
- /* The Dwarf might need an alt debug file, find that now after
- everything about the debug file has been setup (the
- find_debuginfo callback might need it). */
- find_debug_altlink (mod, mod->main.name);
- return;
-
- case DWFL_E_NO_DWARF:
- break;
-
- default:
- goto canonicalize;
- }
-
- /* Now we have to look for a separate debuginfo file. */
- mod->dwerr = find_debuginfo (mod);
- switch (mod->dwerr)
- {
- case DWFL_E_NOERROR:
- mod->dwerr = load_dw (mod, &mod->debug);
- if (mod->dwerr == DWFL_E_NOERROR)
- {
- /* The Dwarf might need an alt debug file, find that now after
- everything about the debug file has been setup (the
- find_debuginfo callback might need it). */
- find_debug_altlink (mod, mod->debug.name);
- return;
- }
-
- break;
-
- case DWFL_E_CB: /* The find_debuginfo hook failed. */
- mod->dwerr = DWFL_E_NO_DWARF;
- return;
-
- default:
- break;
- }
-
- canonicalize:
- mod->dwerr = __libdwfl_canon_error (mod->dwerr);
-}
-
-Dwarf *
-dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
-{
- if (mod == NULL)
- return NULL;
-
- find_dw (mod);
- if (mod->dwerr == DWFL_E_NOERROR)
- {
- /* If dwfl_module_getelf was used previously, then partial apply
- relocation to miscellaneous sections in the debug file too. */
- if (mod->e_type == ET_REL
- && mod->main.relocated && ! mod->debug.relocated)
- {
- mod->debug.relocated = true;
- if (mod->debug.elf != mod->main.elf)
- (void) __libdwfl_relocate (mod, mod->debug.elf, false);
- }
-
- *bias = dwfl_adjusted_dwarf_addr (mod, 0);
- return mod->dw;
- }
-
- __libdwfl_seterrno (mod->dwerr);
- return NULL;
-}
-INTDEF (dwfl_module_getdwarf)
-
-int
-dwfl_module_getsymtab (Dwfl_Module *mod)
-{
- if (mod == NULL)
- return -1;
-
- find_symtab (mod);
- if (mod->symerr == DWFL_E_NOERROR)
- /* We will skip the auxiliary zero entry if there is another one. */
- return (mod->syments + mod->aux_syments
- - (mod->syments > 0 && mod->aux_syments > 0 ? 1 : 0));
-
- __libdwfl_seterrno (mod->symerr);
- return -1;
-}
-INTDEF (dwfl_module_getsymtab)
-
-int
-dwfl_module_getsymtab_first_global (Dwfl_Module *mod)
-{
- if (mod == NULL)
- return -1;
-
- find_symtab (mod);
- if (mod->symerr == DWFL_E_NOERROR)
- {
- /* All local symbols should come before all global symbols. If
- we have an auxiliary table make sure all the main locals come
- first, then all aux locals, then all main globals and finally all
- aux globals. And skip the auxiliary table zero undefined
- entry. */
- int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
- return mod->first_global + mod->aux_first_global - skip_aux_zero;
- }
-
- __libdwfl_seterrno (mod->symerr);
- return -1;
-}
-INTDEF (dwfl_module_getsymtab_first_global)
diff --git a/src/libdwfl/dwfl_module_getelf.c b/src/libdwfl/dwfl_module_getelf.c
deleted file mode 100644
index f20fb042..00000000
--- a/src/libdwfl/dwfl_module_getelf.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Find debugging and symbol information for a module in libdwfl.
- Copyright (C) 2009-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Elf *
-dwfl_module_getelf (Dwfl_Module *mod, GElf_Addr *loadbase)
-{
- if (mod == NULL)
- return NULL;
-
- __libdwfl_getelf (mod);
- if (mod->elferr == DWFL_E_NOERROR)
- {
- if (mod->e_type == ET_REL && ! mod->main.relocated)
- {
- /* Before letting them get at the Elf handle,
- apply all the relocations we know how to. */
-
- mod->main.relocated = true;
- if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR))
- {
- (void) __libdwfl_relocate (mod, mod->main.elf, false);
-
- if (mod->debug.elf == mod->main.elf)
- mod->debug.relocated = true;
- else if (mod->debug.elf != NULL && ! mod->debug.relocated)
- {
- mod->debug.relocated = true;
- (void) __libdwfl_relocate (mod, mod->debug.elf, false);
- }
- }
- }
-
- *loadbase = dwfl_adjusted_address (mod, 0);
- return mod->main.elf;
- }
-
- __libdwfl_seterrno (mod->elferr);
- return NULL;
-}
-INTDEF (dwfl_module_getelf)
diff --git a/src/libdwfl/dwfl_module_getsrc.c b/src/libdwfl/dwfl_module_getsrc.c
deleted file mode 100644
index f6d88390..00000000
--- a/src/libdwfl/dwfl_module_getsrc.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Find source location for PC address in module.
- Copyright (C) 2005, 2008, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/libdwP.h"
-
-Dwfl_Line *
-dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr)
-{
- Dwarf_Addr bias;
- if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
- return NULL;
-
- struct dwfl_cu *cu;
- Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu);
- if (likely (error == DWFL_E_NOERROR))
- error = __libdwfl_cu_getsrclines (cu);
- if (likely (error == DWFL_E_NOERROR))
- {
- Dwarf_Lines *lines = cu->die.cu->lines;
- size_t nlines = lines->nlines;
- if (nlines > 0)
- {
- /* This is guaranteed for us by libdw read_srclines. */
- assert(lines->info[nlines - 1].end_sequence);
-
- /* Now we look at the module-relative address. */
- addr -= bias;
-
- /* The lines are sorted by address, so we can use binary search. */
- size_t l = 0, u = nlines - 1;
- while (l < u)
- {
- size_t idx = u - (u - l) / 2;
- Dwarf_Line *line = &lines->info[idx];
- if (addr < line->addr)
- u = idx - 1;
- else
- l = idx;
- }
-
- /* The last line which is less than or equal to addr is what we want,
- except with an end_sequence which can only be strictly equal. */
- Dwarf_Line *line = &lines->info[l];
- if (line->addr == addr
- || (! line->end_sequence && line->addr < addr))
- return &cu->lines->idx[l];
- }
-
- error = DWFL_E_ADDR_OUTOFRANGE;
- }
-
- __libdwfl_seterrno (error);
- return NULL;
-}
-INTDEF (dwfl_module_getsrc)
diff --git a/src/libdwfl/dwfl_module_getsrc_file.c b/src/libdwfl/dwfl_module_getsrc_file.c
deleted file mode 100644
index 20aa8a5f..00000000
--- a/src/libdwfl/dwfl_module_getsrc_file.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Find matching source locations in a module.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/libdwP.h"
-
-
-int
-dwfl_module_getsrc_file (Dwfl_Module *mod,
- const char *fname, int lineno, int column,
- Dwfl_Line ***srcsp, size_t *nsrcs)
-{
- if (mod == NULL)
- return -1;
-
- if (mod->dw == NULL)
- {
- Dwarf_Addr bias;
- if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
- return -1;
- }
-
- bool is_basename = strchr (fname, '/') == NULL;
-
- size_t max_match = *nsrcs ?: ~0u;
- size_t act_match = *nsrcs;
- size_t cur_match = 0;
- Dwfl_Line **match = *nsrcs == 0 ? NULL : *srcsp;
-
- struct dwfl_cu *cu = NULL;
- Dwfl_Error error;
- while ((error = __libdwfl_nextcu (mod, cu, &cu)) == DWFL_E_NOERROR
- && cu != NULL
- && (error = __libdwfl_cu_getsrclines (cu)) == DWFL_E_NOERROR)
- {
- inline const char *INTUSE(dwarf_line_file) (const Dwarf_Line *line)
- {
- return line->files->info[line->file].name;
- }
- inline Dwarf_Line *dwfl_line (const Dwfl_Line *line)
- {
- return &dwfl_linecu (line)->die.cu->lines->info[line->idx];
- }
- inline const char *dwfl_line_file (const Dwfl_Line *line)
- {
- return INTUSE(dwarf_line_file) (dwfl_line (line));
- }
-
- /* Search through all the line number records for a matching
- file and line/column number. If any of the numbers is zero,
- no match is performed. */
- const char *lastfile = NULL;
- bool lastmatch = false;
- for (size_t cnt = 0; cnt < cu->die.cu->lines->nlines; ++cnt)
- {
- Dwarf_Line *line = &cu->die.cu->lines->info[cnt];
-
- if (unlikely (line->file >= line->files->nfiles))
- {
- __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
- return -1;
- }
- else
- {
- const char *file = INTUSE(dwarf_line_file) (line);
- if (file != lastfile)
- {
- /* Match the name with the name the user provided. */
- lastfile = file;
- lastmatch = !strcmp (is_basename ? basename (file) : file,
- fname);
- }
- }
- if (!lastmatch)
- continue;
-
- /* See whether line and possibly column match. */
- if (lineno != 0
- && (lineno > line->line
- || (column != 0 && column > line->column)))
- /* Cannot match. */
- continue;
-
- /* Determine whether this is the best match so far. */
- size_t inner;
- for (inner = 0; inner < cur_match; ++inner)
- if (dwfl_line_file (match[inner])
- == INTUSE(dwarf_line_file) (line))
- break;
- if (inner < cur_match
- && (dwfl_line (match[inner])->line != line->line
- || dwfl_line (match[inner])->line != lineno
- || (column != 0
- && (dwfl_line (match[inner])->column != line->column
- || dwfl_line (match[inner])->column != column))))
- {
- /* We know about this file already. If this is a better
- match for the line number, use it. */
- if (dwfl_line (match[inner])->line >= line->line
- && (dwfl_line (match[inner])->line != line->line
- || dwfl_line (match[inner])->column >= line->column))
- /* Use the new line. Otherwise the old one. */
- match[inner] = &cu->lines->idx[cnt];
- continue;
- }
-
- if (cur_match < max_match)
- {
- if (cur_match == act_match)
- {
- /* Enlarge the array for the results. */
- act_match += 10;
- Dwfl_Line **newp = realloc (match,
- act_match
- * sizeof (Dwfl_Line *));
- if (newp == NULL)
- {
- free (match);
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
- match = newp;
- }
-
- match[cur_match++] = &cu->lines->idx[cnt];
- }
- }
- }
-
- if (cur_match > 0)
- {
- assert (*nsrcs == 0 || *srcsp == match);
-
- *nsrcs = cur_match;
- *srcsp = match;
-
- return 0;
- }
-
- __libdwfl_seterrno (DWFL_E_NO_MATCH);
- return -1;
-}
diff --git a/src/libdwfl/dwfl_module_getsym.c b/src/libdwfl/dwfl_module_getsym.c
deleted file mode 100644
index 42d2b679..00000000
--- a/src/libdwfl/dwfl_module_getsym.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/* Find debugging and symbol information for a module in libdwfl.
- Copyright (C) 2006-2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-const char *
-internal_function
-__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym, GElf_Addr *addr,
- GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *biasp,
- bool *resolved, bool adjust_st_value)
-{
- if (unlikely (mod == NULL))
- return NULL;
-
- if (unlikely (mod->symdata == NULL))
- {
- int result = INTUSE(dwfl_module_getsymtab) (mod);
- if (result < 0)
- return NULL;
- }
-
- /* All local symbols should come before all global symbols. If we
- have an auxiliary table make sure all the main locals come first,
- then all aux locals, then all main globals and finally all aux globals.
- And skip the auxiliary table zero undefined entry. */
- GElf_Word shndx;
- int tndx = ndx;
- int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
- Elf *elf;
- Elf_Data *symdata;
- Elf_Data *symxndxdata;
- Elf_Data *symstrdata;
- if (mod->aux_symdata == NULL
- || ndx < mod->first_global)
- {
- /* main symbol table (locals). */
- tndx = ndx;
- elf = mod->symfile->elf;
- symdata = mod->symdata;
- symxndxdata = mod->symxndxdata;
- symstrdata = mod->symstrdata;
- }
- else if (ndx < mod->first_global + mod->aux_first_global - skip_aux_zero)
- {
- /* aux symbol table (locals). */
- tndx = ndx - mod->first_global + skip_aux_zero;
- elf = mod->aux_sym.elf;
- symdata = mod->aux_symdata;
- symxndxdata = mod->aux_symxndxdata;
- symstrdata = mod->aux_symstrdata;
- }
- else if ((size_t) ndx < mod->syments + mod->aux_first_global - skip_aux_zero)
- {
- /* main symbol table (globals). */
- tndx = ndx - mod->aux_first_global + skip_aux_zero;
- elf = mod->symfile->elf;
- symdata = mod->symdata;
- symxndxdata = mod->symxndxdata;
- symstrdata = mod->symstrdata;
- }
- else
- {
- /* aux symbol table (globals). */
- tndx = ndx - mod->syments + skip_aux_zero;
- elf = mod->aux_sym.elf;
- symdata = mod->aux_symdata;
- symxndxdata = mod->aux_symxndxdata;
- symstrdata = mod->aux_symstrdata;
- }
- sym = gelf_getsymshndx (symdata, symxndxdata, tndx, sym, &shndx);
-
- if (unlikely (sym == NULL))
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return NULL;
- }
-
- if (sym->st_shndx != SHN_XINDEX)
- shndx = sym->st_shndx;
-
- /* Figure out whether this symbol points into an SHF_ALLOC section. */
- bool alloc = true;
- if ((shndxp != NULL || mod->e_type != ET_REL)
- && (sym->st_shndx == SHN_XINDEX
- || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF)))
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, shndx), &shdr_mem);
- alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC);
- }
-
- /* In case of an value in an allocated section the main Elf Ebl
- might know where the real value is (e.g. for function
- descriptors). */
-
- char *ident;
- GElf_Addr st_value = sym->st_value & ebl_func_addr_mask (mod->ebl);
- *resolved = false;
- if (! adjust_st_value && mod->e_type != ET_REL && alloc
- && (GELF_ST_TYPE (sym->st_info) == STT_FUNC
- || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
- && (ident = elf_getident (elf, NULL)) != NULL
- && ident[EI_OSABI] == ELFOSABI_LINUX)))
- {
- if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR))
- {
- if (elf != mod->main.elf)
- {
- st_value = dwfl_adjusted_st_value (mod, elf, st_value);
- st_value = dwfl_deadjust_st_value (mod, mod->main.elf, st_value);
- }
-
- *resolved = ebl_resolve_sym_value (mod->ebl, &st_value);
- if (! *resolved)
- st_value = sym->st_value;
- }
- }
-
- if (shndxp != NULL)
- /* Yield -1 in case of a non-SHF_ALLOC section. */
- *shndxp = alloc ? shndx : (GElf_Word) -1;
-
- switch (sym->st_shndx)
- {
- case SHN_ABS: /* XXX sometimes should use bias?? */
- case SHN_UNDEF:
- case SHN_COMMON:
- break;
-
- default:
- if (mod->e_type == ET_REL)
- {
- /* In an ET_REL file, the symbol table values are relative
- to the section, not to the module's load base. */
- size_t symshstrndx = SHN_UNDEF;
- Dwfl_Error result = __libdwfl_relocate_value (mod, elf,
- &symshstrndx,
- shndx, &st_value);
- if (unlikely (result != DWFL_E_NOERROR))
- {
- __libdwfl_seterrno (result);
- return NULL;
- }
- }
- else if (alloc)
- /* Apply the bias to the symbol value. */
- st_value = dwfl_adjusted_st_value (mod,
- *resolved ? mod->main.elf : elf,
- st_value);
- break;
- }
-
- if (adjust_st_value)
- sym->st_value = st_value;
-
- if (addr != NULL)
- *addr = st_value;
-
- if (unlikely (sym->st_name >= symstrdata->d_size))
- {
- __libdwfl_seterrno (DWFL_E_BADSTROFF);
- return NULL;
- }
- if (elfp)
- *elfp = elf;
- if (biasp)
- *biasp = dwfl_adjusted_st_value (mod, elf, 0);
- return (const char *) symstrdata->d_buf + sym->st_name;
-}
-
-const char *
-dwfl_module_getsym_info (Dwfl_Module *mod, int ndx,
- GElf_Sym *sym, GElf_Addr *addr,
- GElf_Word *shndxp,
- Elf **elfp, Dwarf_Addr *bias)
-{
- bool resolved;
- return __libdwfl_getsym (mod, ndx, sym, addr, shndxp, elfp, bias,
- &resolved, false);
-}
-INTDEF (dwfl_module_getsym_info)
-
-const char *
-dwfl_module_getsym (Dwfl_Module *mod, int ndx,
- GElf_Sym *sym, GElf_Word *shndxp)
-{
- bool resolved;
- return __libdwfl_getsym (mod, ndx, sym, NULL, shndxp, NULL, NULL,
- &resolved, true);
-}
-INTDEF (dwfl_module_getsym)
diff --git a/src/libdwfl/dwfl_module_info.c b/src/libdwfl/dwfl_module_info.c
deleted file mode 100644
index df16be41..00000000
--- a/src/libdwfl/dwfl_module_info.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Return information about a module.
- Copyright (C) 2005-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-const char *
-dwfl_module_info (Dwfl_Module *mod, void ***userdata,
- Dwarf_Addr *start, Dwarf_Addr *end,
- Dwarf_Addr *dwbias, Dwarf_Addr *symbias,
- const char **mainfile, const char **debugfile)
-{
- if (mod == NULL)
- return NULL;
-
- if (userdata)
- *userdata = &mod->userdata;
- if (start)
- *start = mod->low_addr;
- if (end)
- *end = mod->high_addr;
-
- if (dwbias)
- *dwbias = (mod->debug.elf == NULL ? (Dwarf_Addr) -1
- : dwfl_adjusted_dwarf_addr (mod, 0));
- if (symbias)
- *symbias = (mod->symfile == NULL ? (Dwarf_Addr) -1
- : dwfl_adjusted_st_value (mod, mod->symfile->elf, 0));
-
- if (mainfile)
- *mainfile = mod->main.name;
-
- if (debugfile)
- *debugfile = mod->debug.name;
-
- return mod->name;
-}
diff --git a/src/libdwfl/dwfl_module_nextcu.c b/src/libdwfl/dwfl_module_nextcu.c
deleted file mode 100644
index 6f81f4cc..00000000
--- a/src/libdwfl/dwfl_module_nextcu.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Iterate through DWARF compilation units in a module.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwarf_Die *
-dwfl_module_nextcu (Dwfl_Module *mod, Dwarf_Die *lastcu, Dwarf_Addr *bias)
-{
- if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
- return NULL;
-
- struct dwfl_cu *cu;
- Dwfl_Error error = __libdwfl_nextcu (mod, (struct dwfl_cu *) lastcu, &cu);
- if (likely (error == DWFL_E_NOERROR))
- return &cu->die; /* Same as a cast, so ok for null too. */
-
- __libdwfl_seterrno (error);
- return NULL;
-}
diff --git a/src/libdwfl/dwfl_module_register_names.c b/src/libdwfl/dwfl_module_register_names.c
deleted file mode 100644
index 2da4b539..00000000
--- a/src/libdwfl/dwfl_module_register_names.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Enumerate DWARF register numbers and their names.
- Copyright (C) 2005, 2006 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-
-int
-dwfl_module_register_names (mod, func, arg)
- Dwfl_Module *mod;
- int (*func) (void *, int regno, const char *setname,
- const char *prefix, const char *regname,
- int bits, int type);
- void *arg;
-{
- if (unlikely (mod == NULL))
- return -1;
-
- if (unlikely (mod->ebl == NULL))
- {
- Dwfl_Error error = __libdwfl_module_getebl (mod);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return -1;
- }
- }
-
- int nregs = ebl_register_info (mod->ebl, -1, NULL, 0,
- NULL, NULL, NULL, NULL);
- int result = 0;
- for (int regno = 0; regno < nregs && likely (result == 0); ++regno)
- {
- char name[32];
- const char *setname = NULL;
- const char *prefix = NULL;
- int bits = -1;
- int type = -1;
- ssize_t len = ebl_register_info (mod->ebl, regno, name, sizeof name,
- &prefix, &setname, &bits, &type);
- if (unlikely (len < 0))
- {
- __libdwfl_seterrno (DWFL_E_LIBEBL);
- result = -1;
- break;
- }
- if (likely (len > 0))
- {
- assert (len > 1); /* Backend should never yield "". */
- result = (*func) (arg, regno, setname, prefix, name, bits, type);
- }
- }
-
- return result;
-}
diff --git a/src/libdwfl/dwfl_module_report_build_id.c b/src/libdwfl/dwfl_module_report_build_id.c
deleted file mode 100644
index b41512b4..00000000
--- a/src/libdwfl/dwfl_module_report_build_id.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Report build ID information for a module.
- Copyright (C) 2007, 2008 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-// XXX vs report changed module: punting old file
-int
-dwfl_module_report_build_id (Dwfl_Module *mod,
- const unsigned char *bits, size_t len,
- GElf_Addr vaddr)
-{
- if (mod == NULL)
- return -1;
-
- if (mod->main.elf != NULL)
- {
- /* Once we know about a file, we won't take any lies about
- its contents. The only permissible call is a no-op. */
-
- if ((size_t) mod->build_id_len == len
- && (mod->build_id_vaddr == vaddr || vaddr == 0)
- && !memcmp (bits, mod->build_id_bits, len))
- return 0;
-
- __libdwfl_seterrno (DWFL_E_ALREADY_ELF);
- return -1;
- }
-
- if (vaddr != 0 && (vaddr < mod->low_addr || vaddr + len > mod->high_addr))
- {
- __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
- return -1;
- }
-
- void *copy = NULL;
- if (len > 0)
- {
- copy = malloc (len);
- if (unlikely (copy == NULL))
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
- memcpy (copy, bits, len);
- }
-
- free (mod->build_id_bits);
-
- mod->build_id_bits = copy;
- mod->build_id_len = len;
- mod->build_id_vaddr = vaddr;
-
- return 0;
-}
-INTDEF (dwfl_module_report_build_id)
diff --git a/src/libdwfl/dwfl_module_return_value_location.c b/src/libdwfl/dwfl_module_return_value_location.c
deleted file mode 100644
index ad83cbf9..00000000
--- a/src/libdwfl/dwfl_module_return_value_location.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Return location expression to find return value given a function type DIE.
- Copyright (C) 2005, 2006 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-
-int
-dwfl_module_return_value_location (mod, functypedie, locops)
- Dwfl_Module *mod;
- Dwarf_Die *functypedie;
- const Dwarf_Op **locops;
-{
- if (mod == NULL)
- return -1;
-
- if (mod->ebl == NULL)
- {
- Dwfl_Error error = __libdwfl_module_getebl (mod);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return -1;
- }
- }
-
- int nops = ebl_return_value_location (mod->ebl, functypedie, locops);
- if (unlikely (nops < 0))
- {
- if (nops == -1)
- __libdwfl_seterrno (DWFL_E_LIBDW);
- else if (nops == -2)
- __libdwfl_seterrno (DWFL_E_WEIRD_TYPE);
- else
- __libdwfl_seterrno (DWFL_E_LIBEBL);
- nops = -1;
- }
-
- return nops;
-}
diff --git a/src/libdwfl/dwfl_nextcu.c b/src/libdwfl/dwfl_nextcu.c
deleted file mode 100644
index 9ea83881..00000000
--- a/src/libdwfl/dwfl_nextcu.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Iterate through DWARF compilation units across all modules.
- Copyright (C) 2005-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwarf_Die *
-dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias)
-{
- if (dwfl == NULL)
- return NULL;
-
- struct dwfl_cu *cu = (struct dwfl_cu *) lastcu;
- Dwfl_Module *mod;
-
- if (cu == NULL)
- {
- mod = dwfl->modulelist;
- goto nextmod;
- }
- else
- mod = cu->mod;
-
- Dwfl_Error error;
- do
- {
- error = __libdwfl_nextcu (mod, cu, &cu);
- if (error != DWFL_E_NOERROR)
- break;
-
- if (cu != NULL)
- {
- *bias = dwfl_adjusted_dwarf_addr (mod, 0);
- return &cu->die;
- }
-
- do
- {
- mod = mod->next;
-
- nextmod:
- if (mod == NULL)
- return NULL;
-
- if (mod->dwerr == DWFL_E_NOERROR
- && (mod->dw != NULL
- || INTUSE(dwfl_module_getdwarf) (mod, bias) != NULL))
- break;
- }
- while (mod->dwerr == DWFL_E_NO_DWARF);
- error = mod->dwerr;
- }
- while (error == DWFL_E_NOERROR);
-
- __libdwfl_seterrno (error);
- return NULL;
-}
-INTDEF (dwfl_nextcu)
diff --git a/src/libdwfl/dwfl_onesrcline.c b/src/libdwfl/dwfl_onesrcline.c
deleted file mode 100644
index 4c20d657..00000000
--- a/src/libdwfl/dwfl_onesrcline.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Return one of the sources lines of a CU.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-Dwfl_Line *
-dwfl_onesrcline (Dwarf_Die *cudie, size_t idx)
-{
- struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
-
- if (cudie == NULL)
- return NULL;
-
- if (cu->lines == NULL)
- {
- Dwfl_Error error = __libdwfl_cu_getsrclines (cu);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return NULL;
- }
- }
-
- if (idx >= cu->die.cu->lines->nlines)
- {
- __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_LINE_IDX));
- return NULL;
- }
-
- return &cu->lines->idx[idx];
-}
diff --git a/src/libdwfl/dwfl_report_elf.c b/src/libdwfl/dwfl_report_elf.c
deleted file mode 100644
index 3a4ae2ef..00000000
--- a/src/libdwfl/dwfl_report_elf.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/* Report a module to libdwfl based on ELF program headers.
- Copyright (C) 2005-2010 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <fcntl.h>
-#include <unistd.h>
-
-
-/* We start every ET_REL module at a moderately aligned boundary.
- This keeps the low addresses easy to read compared to a layout
- starting at 0 (as when using -e). It also makes it unlikely
- that a middle section will have a larger alignment and require
- rejiggering (see below). */
-#define REL_MIN_ALIGN ((GElf_Xword) 0x100)
-
-bool
-internal_function
-__libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
- bool sanity, GElf_Addr *vaddrp,
- GElf_Addr *address_syncp, GElf_Addr *startp,
- GElf_Addr *endp, GElf_Addr *biasp,
- GElf_Half *e_typep)
-{
- GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
- if (ehdr == NULL)
- {
- elf_error:
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return false;
- }
-
- GElf_Addr vaddr = 0;
- GElf_Addr address_sync = 0;
- GElf_Addr start = 0, end = 0, bias = 0;
- switch (ehdr->e_type)
- {
- case ET_REL:
- /* For a relocatable object, we do an arbitrary section layout.
- By updating the section header in place, we leave the layout
- information to be found by relocation. */
-
- start = end = base = (base + REL_MIN_ALIGN - 1) & -REL_MIN_ALIGN;
-
- bool first = true;
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
- if (unlikely (shdr == NULL))
- goto elf_error;
-
- if (shdr->sh_flags & SHF_ALLOC)
- {
- const GElf_Xword align = shdr->sh_addralign ?: 1;
- const GElf_Addr next = (end + align - 1) & -align;
- if (shdr->sh_addr == 0
- /* Once we've started doing layout we have to do it all,
- unless we just layed out the first section at 0 when
- it already was at 0. */
- || (bias == 0 && end > start && end != next))
- {
- shdr->sh_addr = next;
- if (end == base)
- /* This is the first section assigned a location.
- Use its aligned address as the module's base. */
- start = base = shdr->sh_addr;
- else if (unlikely (base & (align - 1)))
- {
- /* If BASE has less than the maximum alignment of
- any section, we eat more than the optimal amount
- of padding and so make the module's apparent
- size come out larger than it would when placed
- at zero. So reset the layout with a better base. */
-
- start = end = base = (base + align - 1) & -align;
- Elf_Scn *prev_scn = NULL;
- do
- {
- prev_scn = elf_nextscn (elf, prev_scn);
- GElf_Shdr prev_shdr_mem;
- GElf_Shdr *prev_shdr = gelf_getshdr (prev_scn,
- &prev_shdr_mem);
- if (unlikely (prev_shdr == NULL))
- goto elf_error;
- if (prev_shdr->sh_flags & SHF_ALLOC)
- {
- const GElf_Xword prev_align
- = prev_shdr->sh_addralign ?: 1;
-
- prev_shdr->sh_addr
- = (end + prev_align - 1) & -prev_align;
- end = prev_shdr->sh_addr + prev_shdr->sh_size;
-
- if (unlikely (! gelf_update_shdr (prev_scn,
- prev_shdr)))
- goto elf_error;
- }
- }
- while (prev_scn != scn);
- continue;
- }
-
- end = shdr->sh_addr + shdr->sh_size;
- if (likely (shdr->sh_addr != 0)
- && unlikely (! gelf_update_shdr (scn, shdr)))
- goto elf_error;
- }
- else
- {
- /* The address is already assigned. Just track it. */
- if (first || end < shdr->sh_addr + shdr->sh_size)
- end = shdr->sh_addr + shdr->sh_size;
- if (first || bias > shdr->sh_addr)
- /* This is the lowest address in the module. */
- bias = shdr->sh_addr;
-
- if ((shdr->sh_addr - bias + base) & (align - 1))
- /* This section winds up misaligned using BASE.
- Adjust BASE upwards to make it congruent to
- the lowest section address in the file modulo ALIGN. */
- base = (((base + align - 1) & -align)
- + (bias & (align - 1)));
- }
-
- first = false;
- }
- }
-
- if (bias != 0)
- {
- /* The section headers had nonzero sh_addr values. The layout
- was already done. We've just collected the total span.
- Now just compute the bias from the requested base. */
- start = base;
- end = end - bias + start;
- bias = start - bias;
- }
- break;
-
- /* Everything else has to have program headers. */
-
- case ET_EXEC:
- case ET_CORE:
- /* An assigned base address is meaningless for these. */
- base = 0;
- add_p_vaddr = true;
-
- case ET_DYN:
- default:;
- size_t phnum;
- if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
- goto elf_error;
- for (size_t i = 0; i < phnum; ++i)
- {
- GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
- if (unlikely (ph == NULL))
- goto elf_error;
- if (ph->p_type == PT_LOAD)
- {
- vaddr = ph->p_vaddr & -ph->p_align;
- address_sync = ph->p_vaddr + ph->p_memsz;
- break;
- }
- }
- if (add_p_vaddr)
- {
- start = base + vaddr;
- bias = base;
- }
- else
- {
- start = base;
- bias = base - vaddr;
- }
-
- for (size_t i = phnum; i-- > 0;)
- {
- GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
- if (unlikely (ph == NULL))
- goto elf_error;
- if (ph->p_type == PT_LOAD
- && ph->p_vaddr + ph->p_memsz > 0)
- {
- end = bias + (ph->p_vaddr + ph->p_memsz);
- break;
- }
- }
-
- if (end == 0 && sanity)
- {
- __libdwfl_seterrno (DWFL_E_NO_PHDR);
- return false;
- }
- break;
- }
- if (vaddrp)
- *vaddrp = vaddr;
- if (address_syncp)
- *address_syncp = address_sync;
- if (startp)
- *startp = start;
- if (endp)
- *endp = end;
- if (biasp)
- *biasp = bias;
- if (e_typep)
- *e_typep = ehdr->e_type;
- return true;
-}
-
-Dwfl_Module *
-internal_function
-__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
- int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr,
- bool sanity)
-{
- GElf_Addr vaddr, address_sync, start, end, bias;
- GElf_Half e_type;
- if (! __libdwfl_elf_address_range (elf, base, add_p_vaddr, sanity, &vaddr,
- &address_sync, &start, &end, &bias,
- &e_type))
- return NULL;
- Dwfl_Module *m = INTUSE(dwfl_report_module) (dwfl, name, start, end);
- if (m != NULL)
- {
- if (m->main.name == NULL)
- {
- m->main.name = strdup (file_name);
- m->main.fd = fd;
- }
- else if ((fd >= 0 && m->main.fd != fd)
- || strcmp (m->main.name, file_name))
- {
- overlap:
- m->gc = true;
- __libdwfl_seterrno (DWFL_E_OVERLAP);
- return NULL;
- }
-
- /* Preinstall the open ELF handle for the module. */
- if (m->main.elf == NULL)
- {
- m->main.elf = elf;
- m->main.vaddr = vaddr;
- m->main.address_sync = address_sync;
- m->main_bias = bias;
- m->e_type = e_type;
- }
- else
- {
- elf_end (elf);
- if (m->main_bias != bias
- || m->main.vaddr != vaddr || m->main.address_sync != address_sync)
- goto overlap;
- }
- }
- return m;
-}
-
-Dwfl_Module *
-dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
- GElf_Addr base, bool add_p_vaddr)
-{
- bool closefd = false;
- if (fd < 0)
- {
- closefd = true;
- fd = open64 (file_name, O_RDONLY);
- if (fd < 0)
- {
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return NULL;
- }
- }
-
- Elf *elf;
- Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, false);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return NULL;
- }
-
- Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name,
- fd, elf, base, add_p_vaddr, true);
- if (mod == NULL)
- {
- elf_end (elf);
- if (closefd)
- close (fd);
- }
-
- return mod;
-}
-INTDEF (dwfl_report_elf)
-NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
-
-#ifdef SHARED
-Dwfl_Module *
- _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
- const char *file_name, int fd,
- GElf_Addr base);
-COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr)
-
-Dwfl_Module *
-_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
- const char *file_name, int fd,
- GElf_Addr base)
-{
- return dwfl_report_elf (dwfl, name, file_name, fd, base, true);
-}
-#endif
diff --git a/src/libdwfl/dwfl_segment_report_module.c b/src/libdwfl/dwfl_segment_report_module.c
deleted file mode 100644
index 898457f1..00000000
--- a/src/libdwfl/dwfl_segment_report_module.c
+++ /dev/null
@@ -1,922 +0,0 @@
-/* Sniff out modules from ELF headers visible in memory segments.
- Copyright (C) 2008-2012, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include "../libelf/libelfP.h" /* For NOTE_ALIGN. */
-#undef _
-#include "libdwflP.h"
-#include "common.h"
-
-#include <elf.h>
-#include <gelf.h>
-#include <inttypes.h>
-#include <sys/param.h>
-#include <alloca.h>
-#include <endian.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-
-/* A good size for the initial read from memory, if it's not too costly.
- This more than covers the phdrs and note segment in the average 64-bit
- binary. */
-
-#define INITIAL_READ 1024
-
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-# define MY_ELFDATA ELFDATA2LSB
-#else
-# define MY_ELFDATA ELFDATA2MSB
-#endif
-
-
-/* Return user segment index closest to ADDR but not above it.
- If NEXT, return the closest to ADDR but not below it. */
-static int
-addr_segndx (Dwfl *dwfl, size_t segment, GElf_Addr addr, bool next)
-{
- int ndx = -1;
- do
- {
- if (dwfl->lookup_segndx[segment] >= 0)
- ndx = dwfl->lookup_segndx[segment];
- if (++segment >= dwfl->lookup_elts - 1)
- return next ? ndx + 1 : ndx;
- }
- while (dwfl->lookup_addr[segment] < addr);
-
- if (next)
- {
- while (dwfl->lookup_segndx[segment] < 0)
- if (++segment >= dwfl->lookup_elts - 1)
- return ndx + 1;
- ndx = dwfl->lookup_segndx[segment];
- }
-
- return ndx;
-}
-
-/* Return whether there is SZ bytes available at PTR till END. */
-
-static bool
-buf_has_data (const void *ptr, const void *end, size_t sz)
-{
- return ptr < end && (size_t) (end - ptr) >= sz;
-}
-
-/* Read SZ bytes into *RETP from *PTRP (limited by END) in format EI_DATA.
- Function comes from src/readelf.c . */
-
-static bool
-buf_read_ulong (unsigned char ei_data, size_t sz,
- const void **ptrp, const void *end, uint64_t *retp)
-{
- if (! buf_has_data (*ptrp, end, sz))
- return false;
-
- union
- {
- uint64_t u64;
- uint32_t u32;
- } u;
-
- memcpy (&u, *ptrp, sz);
- (*ptrp) += sz;
-
- if (retp == NULL)
- return true;
-
- if (MY_ELFDATA != ei_data)
- {
- if (sz == 4)
- CONVERT (u.u32);
- else
- CONVERT (u.u64);
- }
- if (sz == 4)
- *retp = u.u32;
- else
- *retp = u.u64;
- return true;
-}
-
-/* Try to find matching entry for module from address MODULE_START to
- MODULE_END in NT_FILE note located at NOTE_FILE of NOTE_FILE_SIZE
- bytes in format EI_CLASS and EI_DATA. */
-
-static const char *
-handle_file_note (GElf_Addr module_start, GElf_Addr module_end,
- unsigned char ei_class, unsigned char ei_data,
- const void *note_file, size_t note_file_size)
-{
- if (note_file == NULL)
- return NULL;
-
- size_t sz;
- switch (ei_class)
- {
- case ELFCLASS32:
- sz = 4;
- break;
- case ELFCLASS64:
- sz = 8;
- break;
- default:
- return NULL;
- }
-
- const void *ptr = note_file;
- const void *end = note_file + note_file_size;
- uint64_t count;
- if (! buf_read_ulong (ei_data, sz, &ptr, end, &count))
- return NULL;
- if (! buf_read_ulong (ei_data, sz, &ptr, end, NULL)) // page_size
- return NULL;
-
- uint64_t maxcount = (size_t) (end - ptr) / (3 * sz);
- if (count > maxcount)
- return NULL;
-
- /* Where file names are stored. */
- const char *fptr = ptr + 3 * count * sz;
-
- ssize_t firstix = -1;
- ssize_t lastix = -1;
- for (size_t mix = 0; mix < count; mix++)
- {
- uint64_t mstart, mend, moffset;
- if (! buf_read_ulong (ei_data, sz, &ptr, fptr, &mstart)
- || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &mend)
- || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &moffset))
- return NULL;
- if (mstart == module_start && moffset == 0)
- firstix = lastix = mix;
- if (firstix != -1 && mstart < module_end)
- lastix = mix;
- if (mend >= module_end)
- break;
- }
- if (firstix == -1)
- return NULL;
-
- const char *retval = NULL;
- for (ssize_t mix = 0; mix <= lastix; mix++)
- {
- const char *fnext = memchr (fptr, 0, (const char *) end - fptr);
- if (fnext == NULL)
- return NULL;
- if (mix == firstix)
- retval = fptr;
- if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0)
- return NULL;
- fptr = fnext + 1;
- }
- return retval;
-}
-
-/* Return true iff we are certain ELF cannot match BUILD_ID of
- BUILD_ID_LEN bytes. Pass DISK_FILE_HAS_BUILD_ID as false if it is
- certain ELF does not contain build-id (it is only a performance hit
- to pass it always as true). */
-
-static bool
-invalid_elf (Elf *elf, bool disk_file_has_build_id,
- const void *build_id, size_t build_id_len)
-{
- if (! disk_file_has_build_id && build_id_len > 0)
- {
- /* Module found in segments with build-id is more reliable
- than a module found via DT_DEBUG on disk without any
- build-id. */
- return true;
- }
- if (disk_file_has_build_id && build_id_len > 0)
- {
- const void *elf_build_id;
- ssize_t elf_build_id_len;
-
- /* If there is a build id in the elf file, check it. */
- elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id);
- if (elf_build_id_len > 0)
- {
- if (build_id_len != (size_t) elf_build_id_len
- || memcmp (build_id, elf_build_id, build_id_len) != 0)
- return true;
- }
- }
- return false;
-}
-
-int
-dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg,
- Dwfl_Module_Callback *read_eagerly,
- void *read_eagerly_arg,
- const void *note_file, size_t note_file_size,
- const struct r_debug_info *r_debug_info)
-{
- size_t segment = ndx;
-
- if (segment >= dwfl->lookup_elts)
- segment = dwfl->lookup_elts - 1;
-
- while (segment > 0
- && (dwfl->lookup_segndx[segment] > ndx
- || dwfl->lookup_segndx[segment] == -1))
- --segment;
-
- while (dwfl->lookup_segndx[segment] < ndx)
- if (++segment == dwfl->lookup_elts)
- return 0;
-
- GElf_Addr start = dwfl->lookup_addr[segment];
-
- inline bool segment_read (int segndx,
- void **buffer, size_t *buffer_available,
- GElf_Addr addr, size_t minread)
- {
- return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
- addr, minread, memory_callback_arg);
- }
-
- inline void release_buffer (void **buffer, size_t *buffer_available)
- {
- if (*buffer != NULL)
- (void) segment_read (-1, buffer, buffer_available, 0, 0);
- }
-
- /* First read in the file header and check its sanity. */
-
- void *buffer = NULL;
- size_t buffer_available = INITIAL_READ;
- Elf *elf = NULL;
- int fd = -1;
-
- inline int finish (void)
- {
- release_buffer (&buffer, &buffer_available);
- if (elf != NULL)
- elf_end (elf);
- if (fd != -1)
- close (fd);
- return ndx;
- }
-
- if (segment_read (ndx, &buffer, &buffer_available,
- start, sizeof (Elf64_Ehdr))
- || memcmp (buffer, ELFMAG, SELFMAG) != 0)
- return finish ();
-
- inline bool read_portion (void **data, size_t *data_size,
- GElf_Addr vaddr, size_t filesz)
- {
- if (vaddr - start + filesz > buffer_available
- /* If we're in string mode, then don't consider the buffer we have
- sufficient unless it contains the terminator of the string. */
- || (filesz == 0 && memchr (vaddr - start + buffer, '\0',
- buffer_available - (vaddr - start)) == NULL))
- {
- *data = NULL;
- *data_size = filesz;
- return segment_read (addr_segndx (dwfl, segment, vaddr, false),
- data, data_size, vaddr, filesz);
- }
-
- /* We already have this whole note segment from our initial read. */
- *data = vaddr - start + buffer;
- *data_size = 0;
- return false;
- }
-
- inline void finish_portion (void **data, size_t *data_size)
- {
- if (*data_size != 0)
- release_buffer (data, data_size);
- }
-
- /* Extract the information we need from the file header. */
- const unsigned char *e_ident;
- unsigned char ei_class;
- unsigned char ei_data;
- uint16_t e_type;
- union
- {
- Elf32_Ehdr e32;
- Elf64_Ehdr e64;
- } ehdr;
- GElf_Off phoff;
- uint_fast16_t phnum;
- uint_fast16_t phentsize;
- GElf_Off shdrs_end;
- Elf_Data xlatefrom =
- {
- .d_type = ELF_T_EHDR,
- .d_buf = (void *) buffer,
- .d_version = EV_CURRENT,
- };
- Elf_Data xlateto =
- {
- .d_type = ELF_T_EHDR,
- .d_buf = &ehdr,
- .d_size = sizeof ehdr,
- .d_version = EV_CURRENT,
- };
- e_ident = ((const unsigned char *) buffer);
- ei_class = e_ident[EI_CLASS];
- ei_data = e_ident[EI_DATA];
- switch (ei_class)
- {
- case ELFCLASS32:
- xlatefrom.d_size = sizeof (Elf32_Ehdr);
- if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
- return finish ();
- e_type = ehdr.e32.e_type;
- phoff = ehdr.e32.e_phoff;
- phnum = ehdr.e32.e_phnum;
- phentsize = ehdr.e32.e_phentsize;
- if (phentsize != sizeof (Elf32_Phdr))
- return finish ();
- shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
- break;
-
- case ELFCLASS64:
- xlatefrom.d_size = sizeof (Elf64_Ehdr);
- if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
- return finish ();
- e_type = ehdr.e64.e_type;
- phoff = ehdr.e64.e_phoff;
- phnum = ehdr.e64.e_phnum;
- phentsize = ehdr.e64.e_phentsize;
- if (phentsize != sizeof (Elf64_Phdr))
- return finish ();
- shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
- break;
-
- default:
- return finish ();
- }
-
- /* The file header tells where to find the program headers.
- These are what we need to find the boundaries of the module.
- Without them, we don't have a module to report. */
-
- if (phnum == 0)
- return finish ();
-
- xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
- xlatefrom.d_size = phnum * phentsize;
-
- void *ph_buffer = NULL;
- size_t ph_buffer_size = 0;
- if (read_portion (&ph_buffer, &ph_buffer_size,
- start + phoff, xlatefrom.d_size))
- return finish ();
-
- xlatefrom.d_buf = ph_buffer;
-
- union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrs;
-
- xlateto.d_buf = &phdrs;
- xlateto.d_size = sizeof phdrs;
-
- /* Track the bounds of the file visible in memory. */
- GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
- GElf_Off file_end = 0; /* Rounded up to effective page size. */
- GElf_Off contiguous = 0; /* Visible as contiguous file from START. */
- GElf_Off total_filesz = 0; /* Total size of data to read. */
-
- /* Collect the bias between START and the containing PT_LOAD's p_vaddr. */
- GElf_Addr bias = 0;
- bool found_bias = false;
-
- /* Collect the unbiased bounds of the module here. */
- GElf_Addr module_start = -1l;
- GElf_Addr module_end = 0;
- GElf_Addr module_address_sync = 0;
-
- /* If we see PT_DYNAMIC, record it here. */
- GElf_Addr dyn_vaddr = 0;
- GElf_Xword dyn_filesz = 0;
-
- /* Collect the build ID bits here. */
- void *build_id = NULL;
- size_t build_id_len = 0;
- GElf_Addr build_id_vaddr = 0;
-
- /* Consider a PT_NOTE we've found in the image. */
- inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz)
- {
- /* If we have already seen a build ID, we don't care any more. */
- if (build_id != NULL || filesz == 0)
- return;
-
- void *data;
- size_t data_size;
- if (read_portion (&data, &data_size, vaddr, filesz))
- return;
-
- assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
-
- void *notes;
- if (ei_data == MY_ELFDATA)
- notes = data;
- else
- {
- notes = malloc (filesz);
- if (unlikely (notes == NULL))
- return;
- xlatefrom.d_type = xlateto.d_type = ELF_T_NHDR;
- xlatefrom.d_buf = (void *) data;
- xlatefrom.d_size = filesz;
- xlateto.d_buf = notes;
- xlateto.d_size = filesz;
- if (elf32_xlatetom (&xlateto, &xlatefrom,
- ehdr.e32.e_ident[EI_DATA]) == NULL)
- goto done;
- }
-
- const GElf_Nhdr *nh = notes;
- while ((const void *) nh < (const void *) notes + filesz)
- {
- const void *note_name = nh + 1;
- const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz);
- if (unlikely ((size_t) ((const void *) notes + filesz
- - note_desc) < nh->n_descsz))
- break;
-
- if (nh->n_type == NT_GNU_BUILD_ID
- && nh->n_descsz > 0
- && nh->n_namesz == sizeof "GNU"
- && !memcmp (note_name, "GNU", sizeof "GNU"))
- {
- build_id_vaddr = note_desc - (const void *) notes + vaddr;
- build_id_len = nh->n_descsz;
- build_id = malloc (nh->n_descsz);
- if (likely (build_id != NULL))
- memcpy (build_id, note_desc, build_id_len);
- break;
- }
-
- nh = note_desc + NOTE_ALIGN (nh->n_descsz);
- }
-
- done:
- if (notes != data)
- free (notes);
- finish_portion (&data, &data_size);
- }
-
- /* Consider each of the program headers we've read from the image. */
- inline void consider_phdr (GElf_Word type,
- GElf_Addr vaddr, GElf_Xword memsz,
- GElf_Off offset, GElf_Xword filesz,
- GElf_Xword align)
- {
- switch (type)
- {
- case PT_DYNAMIC:
- dyn_vaddr = vaddr;
- dyn_filesz = filesz;
- break;
-
- case PT_NOTE:
- /* We calculate from the p_offset of the note segment,
- because we don't yet know the bias for its p_vaddr. */
- consider_notes (start + offset, filesz);
- break;
-
- case PT_LOAD:
- align = dwfl->segment_align > 1 ? dwfl->segment_align : align ?: 1;
-
- GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align;
- GElf_Addr filesz_vaddr = filesz < memsz ? vaddr + filesz : vaddr_end;
- GElf_Off filesz_offset = filesz_vaddr - vaddr + offset;
-
- if (file_trimmed_end < offset + filesz)
- {
- file_trimmed_end = offset + filesz;
-
- /* Trim the last segment so we don't bother with zeros
- in the last page that are off the end of the file.
- However, if the extra bit in that page includes the
- section headers, keep them. */
- if (shdrs_end <= filesz_offset && shdrs_end > file_trimmed_end)
- {
- filesz += shdrs_end - file_trimmed_end;
- file_trimmed_end = shdrs_end;
- }
- }
-
- total_filesz += filesz;
-
- if (file_end < filesz_offset)
- {
- file_end = filesz_offset;
- if (filesz_vaddr - start == filesz_offset)
- contiguous = file_end;
- }
-
- if (!found_bias && (offset & -align) == 0
- && likely (filesz_offset >= phoff + phnum * phentsize))
- {
- bias = start - vaddr;
- found_bias = true;
- }
-
- if ((vaddr & -align) < module_start)
- {
- module_start = vaddr & -align;
- module_address_sync = vaddr + memsz;
- }
-
- if (module_end < vaddr_end)
- module_end = vaddr_end;
- break;
- }
- }
- if (ei_class == ELFCLASS32)
- {
- if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
- found_bias = false; /* Trigger error check. */
- else
- for (uint_fast16_t i = 0; i < phnum; ++i)
- consider_phdr (phdrs.p32[i].p_type,
- phdrs.p32[i].p_vaddr, phdrs.p32[i].p_memsz,
- phdrs.p32[i].p_offset, phdrs.p32[i].p_filesz,
- phdrs.p32[i].p_align);
- }
- else
- {
- if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
- found_bias = false; /* Trigger error check. */
- else
- for (uint_fast16_t i = 0; i < phnum; ++i)
- consider_phdr (phdrs.p64[i].p_type,
- phdrs.p64[i].p_vaddr, phdrs.p64[i].p_memsz,
- phdrs.p64[i].p_offset, phdrs.p64[i].p_filesz,
- phdrs.p64[i].p_align);
- }
-
- finish_portion (&ph_buffer, &ph_buffer_size);
-
- /* We must have seen the segment covering offset 0, or else the ELF
- header we read at START was not produced by these program headers. */
- if (unlikely (!found_bias))
- {
- free (build_id);
- return finish ();
- }
-
- /* Now we know enough to report a module for sure: its bounds. */
- module_start += bias;
- module_end += bias;
-
- dyn_vaddr += bias;
-
- /* NAME found from link map has precedence over DT_SONAME possibly read
- below. */
- bool name_is_final = false;
-
- /* Try to match up DYN_VADDR against L_LD as found in link map.
- Segments sniffing may guess invalid address as the first read-only memory
- mapping may not be dumped to the core file (if ELF headers are not dumped)
- and the ELF header is dumped first with the read/write mapping of the same
- file at higher addresses. */
- if (r_debug_info != NULL)
- for (const struct r_debug_info_module *module = r_debug_info->module;
- module != NULL; module = module->next)
- if (module_start <= module->l_ld && module->l_ld < module_end)
- {
- /* L_LD read from link map must be right while DYN_VADDR is unsafe.
- Therefore subtract DYN_VADDR and add L_LD to get a possibly
- corrective displacement for all addresses computed so far. */
- GElf_Addr fixup = module->l_ld - dyn_vaddr;
- if ((fixup & (dwfl->segment_align - 1)) == 0
- && module_start + fixup <= module->l_ld
- && module->l_ld < module_end + fixup)
- {
- module_start += fixup;
- module_end += fixup;
- dyn_vaddr += fixup;
- bias += fixup;
- if (module->name[0] != '\0')
- {
- name = basename (module->name);
- name_is_final = true;
- }
- break;
- }
- }
-
- if (r_debug_info != NULL)
- {
- bool skip_this_module = false;
- for (struct r_debug_info_module *module = r_debug_info->module;
- module != NULL; module = module->next)
- if ((module_end > module->start && module_start < module->end)
- || dyn_vaddr == module->l_ld)
- {
- if (module->elf != NULL
- && invalid_elf (module->elf, module->disk_file_has_build_id,
- build_id, build_id_len))
- {
- elf_end (module->elf);
- close (module->fd);
- module->elf = NULL;
- module->fd = -1;
- }
- if (module->elf != NULL)
- {
- /* Ignore this found module if it would conflict in address
- space with any already existing module of DWFL. */
- skip_this_module = true;
- }
- }
- if (skip_this_module)
- {
- free (build_id);
- return finish ();
- }
- }
-
- const char *file_note_name = handle_file_note (module_start, module_end,
- ei_class, ei_data,
- note_file, note_file_size);
- if (file_note_name)
- {
- name = file_note_name;
- name_is_final = true;
- bool invalid = false;
- fd = open64 (name, O_RDONLY);
- if (fd >= 0)
- {
- Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
- if (error == DWFL_E_NOERROR)
- invalid = invalid_elf (elf, true /* disk_file_has_build_id */,
- build_id, build_id_len);
- }
- if (invalid)
- {
- free (build_id);
- return finish ();
- }
- }
-
- /* Our return value now says to skip the segments contained
- within the module. */
- ndx = addr_segndx (dwfl, segment, module_end, true);
-
- /* Examine its .dynamic section to get more interesting details.
- If it has DT_SONAME, we'll use that as the module name.
- If it has a DT_DEBUG, then it's actually a PIE rather than a DSO.
- We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
- and they also tell us the essential portion of the file
- for fetching symbols. */
- GElf_Addr soname_stroff = 0;
- GElf_Addr dynstr_vaddr = 0;
- GElf_Xword dynstrsz = 0;
- bool execlike = false;
- inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
- {
- switch (tag)
- {
- default:
- return false;
-
- case DT_DEBUG:
- execlike = true;
- break;
-
- case DT_SONAME:
- soname_stroff = val;
- break;
-
- case DT_STRTAB:
- dynstr_vaddr = val;
- break;
-
- case DT_STRSZ:
- dynstrsz = val;
- break;
- }
-
- return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
- }
-
- const size_t dyn_entsize = (ei_class == ELFCLASS32
- ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
- void *dyn_data = NULL;
- size_t dyn_data_size = 0;
- if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
- && ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
- {
- union
- {
- Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
- Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
- } dyn;
-
- xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
- xlatefrom.d_buf = (void *) dyn_data;
- xlatefrom.d_size = dyn_filesz;
- xlateto.d_buf = &dyn;
- xlateto.d_size = sizeof dyn;
-
- if (ei_class == ELFCLASS32)
- {
- if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
- for (size_t i = 0; i < dyn_filesz / sizeof dyn.d32[0]; ++i)
- if (consider_dyn (dyn.d32[i].d_tag, dyn.d32[i].d_un.d_val))
- break;
- }
- else
- {
- if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
- for (size_t i = 0; i < dyn_filesz / sizeof dyn.d64[0]; ++i)
- if (consider_dyn (dyn.d64[i].d_tag, dyn.d64[i].d_un.d_val))
- break;
- }
- }
- finish_portion (&dyn_data, &dyn_data_size);
-
- /* We'll use the name passed in or a stupid default if not DT_SONAME. */
- if (name == NULL)
- name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]";
-
- void *soname = NULL;
- size_t soname_size = 0;
- if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0)
- {
- /* We know the bounds of the .dynstr section.
-
- The DYNSTR_VADDR pointer comes from the .dynamic section
- (DT_STRTAB, detected above). Ordinarily the dynamic linker
- will have adjusted this pointer in place so it's now an
- absolute address. But sometimes .dynamic is read-only (in
- vDSOs and odd architectures), and sometimes the adjustment
- just hasn't happened yet in the memory image we looked at.
- So treat DYNSTR_VADDR as an absolute address if it falls
- within the module bounds, or try applying the phdr bias
- when that adjusts it to fall within the module bounds. */
-
- if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end)
- && dynstr_vaddr + bias >= module_start
- && dynstr_vaddr + bias < module_end)
- dynstr_vaddr += bias;
-
- if (unlikely (dynstr_vaddr + dynstrsz > module_end))
- dynstrsz = 0;
-
- /* Try to get the DT_SONAME string. */
- if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz
- && ! read_portion (&soname, &soname_size,
- dynstr_vaddr + soname_stroff, 0))
- name = soname;
- }
-
- /* Now that we have chosen the module's name and bounds, report it.
- If we found a build ID, report that too. */
-
- Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name,
- module_start, module_end);
-
- // !execlike && ET_EXEC is PIE.
- // execlike && !ET_EXEC is a static executable.
- if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC))
- mod->is_executable = true;
-
- if (likely (mod != NULL) && build_id != NULL
- && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
- build_id,
- build_id_len,
- build_id_vaddr)))
- {
- mod->gc = true;
- mod = NULL;
- }
-
- /* At this point we do not need BUILD_ID or NAME any more.
- They have been copied. */
- free (build_id);
- finish_portion (&soname, &soname_size);
-
- if (unlikely (mod == NULL))
- {
- ndx = -1;
- return finish ();
- }
-
- /* We have reported the module. Now let the caller decide whether we
- should read the whole thing in right now. */
-
- const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz
- : buffer_available >= contiguous ? 0
- : contiguous - buffer_available);
- const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0
- : dynstr_vaddr + dynstrsz - start);
- const GElf_Off whole = MAX (file_trimmed_end, shdrs_end);
-
- if (elf == NULL
- && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available,
- cost, worthwhile, whole, contiguous,
- read_eagerly_arg, &elf)
- && elf == NULL)
- {
- /* The caller wants to read the whole file in right now, but hasn't
- done it for us. Fill in a local image of the virtual file. */
-
- void *contents = calloc (1, file_trimmed_end);
- if (unlikely (contents == NULL))
- return finish ();
-
- inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
- {
- void *into = contents + offset;
- size_t read_size = size;
- (void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
- &into, &read_size, vaddr, size);
- }
-
- if (contiguous < file_trimmed_end)
- {
- /* We can't use the memory image verbatim as the file image.
- So we'll be reading into a local image of the virtual file. */
-
- inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
- GElf_Off offset, GElf_Xword filesz)
- {
- if (type == PT_LOAD)
- final_read (offset, vaddr + bias, filesz);
- }
-
- if (ei_class == ELFCLASS32)
- for (uint_fast16_t i = 0; i < phnum; ++i)
- read_phdr (phdrs.p32[i].p_type, phdrs.p32[i].p_vaddr,
- phdrs.p32[i].p_offset, phdrs.p32[i].p_filesz);
- else
- for (uint_fast16_t i = 0; i < phnum; ++i)
- read_phdr (phdrs.p64[i].p_type, phdrs.p64[i].p_vaddr,
- phdrs.p64[i].p_offset, phdrs.p64[i].p_filesz);
- }
- else
- {
- /* The whole file sits contiguous in memory,
- but the caller didn't want to just do it. */
-
- const size_t have = MIN (buffer_available, file_trimmed_end);
- memcpy (contents, buffer, have);
-
- if (have < file_trimmed_end)
- final_read (have, start + have, file_trimmed_end - have);
- }
-
- elf = elf_memory (contents, file_trimmed_end);
- if (unlikely (elf == NULL))
- free (contents);
- else
- elf->flags |= ELF_F_MALLOCED;
- }
-
- if (elf != NULL)
- {
- /* Install the file in the module. */
- mod->main.elf = elf;
- elf = NULL;
- fd = -1;
- mod->main.vaddr = module_start - bias;
- mod->main.address_sync = module_address_sync;
- mod->main_bias = bias;
- }
-
- return finish ();
-}
diff --git a/src/libdwfl/dwfl_validate_address.c b/src/libdwfl/dwfl_validate_address.c
deleted file mode 100644
index 7334c3e2..00000000
--- a/src/libdwfl/dwfl_validate_address.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Validate an address and the relocatability of an offset from it.
- Copyright (C) 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-int
-dwfl_validate_address (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Sword offset)
-{
- Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (dwfl, address);
- if (mod == NULL)
- return -1;
-
- Dwarf_Addr relative = address;
- int idx = INTUSE(dwfl_module_relocate_address) (mod, &relative);
- if (idx < 0)
- return -1;
-
- if (offset != 0)
- {
- int offset_idx = -1;
- relative = address + offset;
- if (relative >= mod->low_addr && relative <= mod->high_addr)
- {
- offset_idx = INTUSE(dwfl_module_relocate_address) (mod, &relative);
- if (offset_idx < 0)
- return -1;
- }
- if (offset_idx != idx)
- {
- __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/src/libdwfl/dwfl_version.c b/src/libdwfl/dwfl_version.c
deleted file mode 100644
index 9673a536..00000000
--- a/src/libdwfl/dwfl_version.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Return implementation's version string suitable for printing.
- Copyright (C) 2006, 2007 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-const char *
-dwfl_version (dwfl)
- Dwfl *dwfl __attribute__ ((unused));
-{
- return PACKAGE_VERSION;
-}
diff --git a/src/libdwfl/elf-from-memory.c b/src/libdwfl/elf-from-memory.c
deleted file mode 100644
index b35fac71..00000000
--- a/src/libdwfl/elf-from-memory.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* Reconstruct an ELF file by reading the segments out of remote memory.
- Copyright (C) 2005-2011, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include "../libelf/libelfP.h"
-#undef _
-
-#include "libdwflP.h"
-
-#include <gelf.h>
-#include <sys/types.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Reconstruct an ELF file by reading the segments out of remote memory
- based on the ELF file header at EHDR_VMA and the ELF program headers it
- points to. If not null, *LOADBASEP is filled in with the difference
- between the addresses from which the segments were read, and the
- addresses the file headers put them at.
-
- The function READ_MEMORY is called to copy at least MINREAD and at most
- MAXREAD bytes from the remote memory at target address ADDRESS into the
- local buffer at DATA; it should return -1 for errors (with code in
- `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or
- the number of bytes read if >= MINREAD. ARG is passed through.
-
- PAGESIZE is the minimum page size and alignment used for the PT_LOAD
- segments. */
-
-Elf *
-elf_from_remote_memory (GElf_Addr ehdr_vma,
- GElf_Xword pagesize,
- GElf_Addr *loadbasep,
- ssize_t (*read_memory) (void *arg, void *data,
- GElf_Addr address,
- size_t minread,
- size_t maxread),
- void *arg)
-{
- /* First read in the file header and check its sanity. */
-
- const size_t initial_bufsize = 256;
- unsigned char *buffer = malloc (initial_bufsize);
- if (buffer == NULL)
- {
- no_memory:
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return NULL;
- }
-
- ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
- sizeof (Elf32_Ehdr), initial_bufsize);
- if (nread <= 0)
- {
- read_error:
- free (buffer);
- __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
- return NULL;
- }
-
- if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
- {
- bad_elf:
- free (buffer);
- __libdwfl_seterrno (DWFL_E_BADELF);
- return NULL;
- }
-
- /* Extract the information we need from the file header. */
-
- union
- {
- Elf32_Ehdr e32;
- Elf64_Ehdr e64;
- } ehdr;
- Elf_Data xlatefrom =
- {
- .d_type = ELF_T_EHDR,
- .d_buf = buffer,
- .d_version = EV_CURRENT,
- };
- Elf_Data xlateto =
- {
- .d_type = ELF_T_EHDR,
- .d_buf = &ehdr,
- .d_size = sizeof ehdr,
- .d_version = EV_CURRENT,
- };
-
- GElf_Off phoff;
- uint_fast16_t phnum;
- uint_fast16_t phentsize;
- GElf_Off shdrs_end;
-
- switch (buffer[EI_CLASS])
- {
- case ELFCLASS32:
- xlatefrom.d_size = sizeof (Elf32_Ehdr);
- if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
- {
- libelf_error:
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return NULL;
- }
- phoff = ehdr.e32.e_phoff;
- phnum = ehdr.e32.e_phnum;
- phentsize = ehdr.e32.e_phentsize;
- if (phentsize != sizeof (Elf32_Phdr) || phnum == 0)
- goto bad_elf;
- shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
- break;
-
- case ELFCLASS64:
- xlatefrom.d_size = sizeof (Elf64_Ehdr);
- if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
- goto libelf_error;
- phoff = ehdr.e64.e_phoff;
- phnum = ehdr.e64.e_phnum;
- phentsize = ehdr.e64.e_phentsize;
- if (phentsize != sizeof (Elf64_Phdr) || phnum == 0)
- goto bad_elf;
- shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
- break;
-
- default:
- goto bad_elf;
- }
-
-
- /* The file header tells where to find the program headers.
- These are what we use to actually choose what to read. */
-
- xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
- xlatefrom.d_size = phnum * phentsize;
-
- if ((size_t) nread >= phoff + phnum * phentsize)
- /* We already have all the phdrs from the initial read. */
- xlatefrom.d_buf = buffer + phoff;
- else
- {
- /* Read in the program headers. */
-
- if (initial_bufsize < phnum * phentsize)
- {
- unsigned char *newbuf = realloc (buffer, phnum * phentsize);
- if (newbuf == NULL)
- {
- free (buffer);
- goto no_memory;
- }
- buffer = newbuf;
- }
- nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
- phnum * phentsize, phnum * phentsize);
- if (nread <= 0)
- goto read_error;
-
- xlatefrom.d_buf = buffer;
- }
-
- union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } phdrs;
-
- xlateto.d_buf = &phdrs;
- xlateto.d_size = sizeof phdrs;
-
- /* Scan for PT_LOAD segments to find the total size of the file image. */
- size_t contents_size = 0;
- GElf_Off segments_end = 0;
- GElf_Off segments_end_mem = 0;
- GElf_Addr loadbase = ehdr_vma;
- bool found_base = false;
- switch (ehdr.e32.e_ident[EI_CLASS])
- {
- /* Sanity checks segments and calculates segment_end,
- segments_end, segments_end_mem and loadbase (if not
- found_base yet). Returns true if sanity checking failed,
- false otherwise. */
- inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
- GElf_Xword filesz, GElf_Xword memsz)
- {
- /* Sanity check the segment load aligns with the pagesize. */
- if (((vaddr - offset) & (pagesize - 1)) != 0)
- return true;
-
- GElf_Off segment_end = ((offset + filesz + pagesize - 1)
- & -pagesize);
-
- if (segment_end > (GElf_Off) contents_size)
- contents_size = segment_end;
-
- if (!found_base && (offset & -pagesize) == 0)
- {
- loadbase = ehdr_vma - (vaddr & -pagesize);
- found_base = true;
- }
-
- segments_end = offset + filesz;
- segments_end_mem = offset + memsz;
- return false;
- }
-
- case ELFCLASS32:
- if (elf32_xlatetom (&xlateto, &xlatefrom,
- ehdr.e32.e_ident[EI_DATA]) == NULL)
- goto libelf_error;
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs.p32[i].p_type == PT_LOAD)
- if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
- phdrs.p32[i].p_filesz, phdrs.p32[i].p_memsz))
- goto bad_elf;
- break;
-
- case ELFCLASS64:
- if (elf64_xlatetom (&xlateto, &xlatefrom,
- ehdr.e64.e_ident[EI_DATA]) == NULL)
- goto libelf_error;
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs.p64[i].p_type == PT_LOAD)
- if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
- phdrs.p64[i].p_filesz, phdrs.p64[i].p_memsz))
- goto bad_elf;
- break;
-
- default:
- abort ();
- break;
- }
-
- /* Trim the last segment so we don't bother with zeros in the last page
- that are off the end of the file. However, if the extra bit in that
- page includes the section headers and the memory isn't extended (which
- might indicate it will have been reused otherwise), keep them. */
- if ((GElf_Off) contents_size > segments_end
- && (GElf_Off) contents_size >= shdrs_end
- && segments_end == segments_end_mem)
- {
- contents_size = segments_end;
- if ((GElf_Off) contents_size < shdrs_end)
- contents_size = shdrs_end;
- }
- else
- contents_size = segments_end;
-
- free (buffer);
-
- /* Now we know the size of the whole image we want read in. */
- buffer = calloc (1, contents_size);
- if (buffer == NULL)
- goto no_memory;
-
- switch (ehdr.e32.e_ident[EI_CLASS])
- {
- /* Reads the given segment. Returns true if reading fails,
- false otherwise. */
- inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
- GElf_Xword filesz)
- {
- GElf_Off start = offset & -pagesize;
- GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
- if (end > (GElf_Off) contents_size)
- end = contents_size;
- nread = (*read_memory) (arg, buffer + start,
- (loadbase + vaddr) & -pagesize,
- end - start, end - start);
- return nread <= 0;
- }
-
- case ELFCLASS32:
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs.p32[i].p_type == PT_LOAD)
- if (handle_segment (phdrs.p32[i].p_vaddr, phdrs.p32[i].p_offset,
- phdrs.p32[i].p_filesz))
- goto read_error;
-
- /* If the segments visible in memory didn't include the section
- headers, then clear them from the file header. */
- if (contents_size < shdrs_end)
- {
- ehdr.e32.e_shoff = 0;
- ehdr.e32.e_shnum = 0;
- ehdr.e32.e_shstrndx = 0;
- }
-
- /* This will normally have been in the first PT_LOAD segment. But it
- conceivably could be missing, and we might have just changed it. */
- xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
- xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
- xlatefrom.d_buf = &ehdr.e32;
- xlateto.d_buf = buffer;
- if (elf32_xlatetof (&xlateto, &xlatefrom,
- ehdr.e32.e_ident[EI_DATA]) == NULL)
- goto libelf_error;
- break;
-
- case ELFCLASS64:
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdrs.p64[i].p_type == PT_LOAD)
- if (handle_segment (phdrs.p64[i].p_vaddr, phdrs.p64[i].p_offset,
- phdrs.p64[i].p_filesz))
- goto read_error;
-
- /* If the segments visible in memory didn't include the section
- headers, then clear them from the file header. */
- if (contents_size < shdrs_end)
- {
- ehdr.e64.e_shoff = 0;
- ehdr.e64.e_shnum = 0;
- ehdr.e64.e_shstrndx = 0;
- }
-
- /* This will normally have been in the first PT_LOAD segment. But it
- conceivably could be missing, and we might have just changed it. */
- xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
- xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
- xlatefrom.d_buf = &ehdr.e64;
- xlateto.d_buf = buffer;
- if (elf64_xlatetof (&xlateto, &xlatefrom,
- ehdr.e64.e_ident[EI_DATA]) == NULL)
- goto libelf_error;
- break;
-
- default:
- abort ();
- break;
- }
-
- /* Now we have the image. Open libelf on it. */
-
- Elf *elf = elf_memory ((char *) buffer, contents_size);
- if (elf == NULL)
- {
- free (buffer);
- goto libelf_error;
- }
-
- elf->flags |= ELF_F_MALLOCED;
- if (loadbasep != NULL)
- *loadbasep = loadbase;
- return elf;
-}
diff --git a/src/libdwfl/find-debuginfo.c b/src/libdwfl/find-debuginfo.c
deleted file mode 100644
index 3f5314ad..00000000
--- a/src/libdwfl/find-debuginfo.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/* Standard find_debuginfo callback for libdwfl.
- Copyright (C) 2005-2010, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include "system.h"
-
-
-/* Try to open64 [DIR/][SUBDIR/]DEBUGLINK, return file descriptor or -1.
- On success, *DEBUGINFO_FILE_NAME has the malloc'd name of the open file. */
-static int
-try_open (const struct stat64 *main_stat,
- const char *dir, const char *subdir, const char *debuglink,
- char **debuginfo_file_name)
-{
- char *fname;
- if (dir == NULL && subdir == NULL)
- {
- fname = strdup (debuglink);
- if (fname == NULL)
- return -1;
- }
- else if ((subdir == NULL ? asprintf (&fname, "%s/%s", dir, debuglink)
- : dir == NULL ? asprintf (&fname, "%s/%s", subdir, debuglink)
- : asprintf (&fname, "%s/%s/%s", dir, subdir, debuglink)) < 0)
- return -1;
-
- struct stat64 st;
- int fd = TEMP_FAILURE_RETRY (open64 (fname, O_RDONLY));
- if (fd < 0)
- free (fname);
- else if (fstat64 (fd, &st) == 0
- && st.st_ino == main_stat->st_ino
- && st.st_dev == main_stat->st_dev)
- {
- /* This is the main file by another name. Don't look at it again. */
- close (fd);
- errno = ENOENT;
- fd = -1;
- }
- else
- *debuginfo_file_name = fname;
-
- return fd;
-}
-
-/* Return true iff the FD's contents CRC matches DEBUGLINK_CRC. */
-static inline bool
-check_crc (int fd, GElf_Word debuglink_crc)
-{
- uint32_t file_crc;
- return (__libdwfl_crc32_file (fd, &file_crc) == 0
- && file_crc == debuglink_crc);
-}
-
-static bool
-validate (Dwfl_Module *mod, int fd, bool check, GElf_Word debuglink_crc)
-{
- /* For alt debug files always check the build-id from the Dwarf and alt. */
- if (mod->dw != NULL)
- {
- bool valid = false;
- const void *build_id;
- const char *altname;
- ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
- &altname,
- &build_id);
- if (build_id_len > 0)
- {
- /* We need to open an Elf handle on the file so we can check its
- build ID note for validation. Backdoor the handle into the
- module data structure since we had to open it early anyway. */
- Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf,
- false, false);
- if (error != DWFL_E_NOERROR)
- __libdwfl_seterrno (error);
- else
- {
- const void *alt_build_id;
- ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf,
- &alt_build_id);
- if (alt_len > 0 && alt_len == build_id_len
- && memcmp (build_id, alt_build_id, alt_len) == 0)
- valid = true;
- else
- {
- /* A mismatch! */
- elf_end (mod->alt_elf);
- mod->alt_elf = NULL;
- close (fd);
- fd = -1;
- }
- }
- }
- return valid;
- }
-
- /* If we have a build ID, check only that. */
- if (mod->build_id_len > 0)
- {
- /* We need to open an Elf handle on the file so we can check its
- build ID note for validation. Backdoor the handle into the
- module data structure since we had to open it early anyway. */
-
- mod->debug.valid = false;
- Dwfl_Error error = __libdw_open_file (&fd, &mod->debug.elf, false, false);
- if (error != DWFL_E_NOERROR)
- __libdwfl_seterrno (error);
- else if (likely (__libdwfl_find_build_id (mod, false,
- mod->debug.elf) == 2))
- /* Also backdoor the gratuitous flag. */
- mod->debug.valid = true;
- else
- {
- /* A mismatch! */
- elf_end (mod->debug.elf);
- mod->debug.elf = NULL;
- close (fd);
- fd = -1;
- }
-
- return mod->debug.valid;
- }
-
- return !check || check_crc (fd, debuglink_crc);
-}
-
-static int
-find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
- const char *debuglink_file, GElf_Word debuglink_crc,
- char **debuginfo_file_name)
-{
- bool cancheck = debuglink_crc != (GElf_Word) 0;
-
- const char *file_basename = file_name == NULL ? NULL : basename (file_name);
- if (debuglink_file == NULL)
- {
- /* For a alt debug multi file we need a name, for a separate debug
- name we may be able to fall back on file_basename.debug. */
- if (file_basename == NULL || mod->dw != NULL)
- {
- errno = 0;
- return -1;
- }
-
- size_t len = strlen (file_basename);
- char *localname = alloca (len + sizeof ".debug");
- memcpy (localname, file_basename, len);
- memcpy (&localname[len], ".debug", sizeof ".debug");
- debuglink_file = localname;
- cancheck = false;
- }
-
- /* Look for a file named DEBUGLINK_FILE in the directories
- indicated by the debug directory path setting. */
-
- const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
- char *path = strdupa ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
- ?: DEFAULT_DEBUGINFO_PATH);
-
- /* A leading - or + in the whole path sets whether to check file CRCs. */
- bool defcheck = true;
- if (path[0] == '-' || path[0] == '+')
- {
- defcheck = path[0] == '+';
- ++path;
- }
-
- /* XXX dev/ino should be cached in struct dwfl_file. */
- struct stat64 main_stat;
- if (unlikely ((mod->main.fd != -1 ? fstat64 (mod->main.fd, &main_stat)
- : file_name != NULL ? stat64 (file_name, &main_stat)
- : -1) < 0))
- {
- main_stat.st_dev = 0;
- main_stat.st_ino = 0;
- }
-
- char *file_dirname = (file_basename == file_name ? NULL
- : strndupa (file_name, file_basename - 1 - file_name));
- char *p;
- while ((p = strsep (&path, ":")) != NULL)
- {
- /* A leading - or + says whether to check file CRCs for this element. */
- bool check = defcheck;
- if (*p == '+' || *p == '-')
- check = *p++ == '+';
- check = check && cancheck;
-
- const char *dir, *subdir, *file;
- switch (p[0])
- {
- case '\0':
- /* An empty entry says to try the main file's directory. */
- dir = file_dirname;
- subdir = NULL;
- file = debuglink_file;
- break;
- case '/':
- /* An absolute path says to look there for a subdirectory
- named by the main file's absolute directory. This cannot
- be applied to a relative file name. For alt debug files
- it means to look for the basename file in that dir or the
- .dwz subdir (see below). */
- if (mod->dw == NULL
- && (file_dirname == NULL || file_dirname[0] != '/'))
- continue;
- dir = p;
- if (mod->dw == NULL)
- {
- subdir = file_dirname + 1;
- file = debuglink_file;
- }
- else
- {
- subdir = NULL;
- file = basename (debuglink_file);
- }
- break;
- default:
- /* A relative path says to try a subdirectory of that name
- in the main file's directory. */
- dir = file_dirname;
- subdir = p;
- file = debuglink_file;
- break;
- }
-
- char *fname = NULL;
- int fd = try_open (&main_stat, dir, subdir, file, &fname);
- if (fd < 0)
- switch (errno)
- {
- case ENOENT:
- case ENOTDIR:
- /* If we are looking for the alt file also try the .dwz subdir.
- But only if this is the empty or absolute path. */
- if (mod->dw != NULL && (p[0] == '\0' || p[0] == '/'))
- {
- fd = try_open (&main_stat, dir, ".dwz",
- basename (file), &fname);
- if (fd < 0)
- {
- if (errno != ENOENT && errno != ENOTDIR)
- return -1;
- else
- continue;
- }
- break;
- }
- continue;
- default:
- return -1;
- }
- if (validate (mod, fd, check, debuglink_crc))
- {
- *debuginfo_file_name = fname;
- return fd;
- }
- free (fname);
- close (fd);
- }
-
- /* No dice. */
- errno = 0;
- return -1;
-}
-
-int
-dwfl_standard_find_debuginfo (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *modname __attribute__ ((unused)),
- GElf_Addr base __attribute__ ((unused)),
- const char *file_name,
- const char *debuglink_file,
- GElf_Word debuglink_crc,
- char **debuginfo_file_name)
-{
- /* First try by build ID if we have one. If that succeeds or fails
- other than just by finding nothing, that's all we do. */
- const unsigned char *bits;
- GElf_Addr vaddr;
- if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0)
- {
- /* Dropping most arguments means we cannot rely on them in
- dwfl_build_id_find_debuginfo. But leave it that way since
- some user code out there also does this, so we'll have to
- handle it anyway. */
- int fd = INTUSE(dwfl_build_id_find_debuginfo) (mod,
- NULL, NULL, 0,
- NULL, NULL, 0,
- debuginfo_file_name);
-
- /* Did the build_id callback find something or report an error?
- Then we are done. Otherwise fallback on path based search. */
- if (fd >= 0
- || (mod->dw == NULL && mod->debug.elf != NULL)
- || (mod->dw != NULL && mod->alt_elf != NULL)
- || errno != 0)
- return fd;
- }
-
- /* Failing that, search the path by name. */
- int fd = find_debuginfo_in_path (mod, file_name,
- debuglink_file, debuglink_crc,
- debuginfo_file_name);
-
- if (fd < 0 && errno == 0)
- {
- /* If FILE_NAME is a symlink, the debug file might be associated
- with the symlink target name instead. */
-
- char *canon = canonicalize_file_name (file_name);
- if (canon != NULL && strcmp (file_name, canon))
- fd = find_debuginfo_in_path (mod, canon,
- debuglink_file, debuglink_crc,
- debuginfo_file_name);
- free (canon);
- }
-
- return fd;
-}
-INTDEF (dwfl_standard_find_debuginfo)
diff --git a/src/libdwfl/frame_unwind.c b/src/libdwfl/frame_unwind.c
deleted file mode 100644
index 16cebd08..00000000
--- a/src/libdwfl/frame_unwind.c
+++ /dev/null
@@ -1,725 +0,0 @@
-/* Get previous frame state for an existing frame state.
- Copyright (C) 2013, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "cfi.h"
-#include <stdlib.h>
-#include "libdwflP.h"
-#include "../libdw/dwarf.h"
-#include <sys/ptrace.h>
-
-/* Maximum number of DWARF expression stack slots before returning an error. */
-#define DWARF_EXPR_STACK_MAX 0x100
-
-/* Maximum number of DWARF expression executed operations before returning an
- error. */
-#define DWARF_EXPR_STEPS_MAX 0x1000
-
-#ifndef MAX
-# define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-bool
-internal_function
-__libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
-{
- Ebl *ebl = state->thread->process->ebl;
- if (! ebl_dwarf_to_regno (ebl, &regno))
- return false;
- if (regno >= ebl_frame_nregs (ebl))
- return false;
- if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
- & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
- return false;
- if (val)
- *val = state->regs[regno];
- return true;
-}
-
-bool
-internal_function
-__libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
-{
- Ebl *ebl = state->thread->process->ebl;
- if (! ebl_dwarf_to_regno (ebl, &regno))
- return false;
- if (regno >= ebl_frame_nregs (ebl))
- return false;
- /* For example i386 user_regs_struct has signed fields. */
- if (ebl_get_elfclass (ebl) == ELFCLASS32)
- val &= 0xffffffff;
- state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
- ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
- state->regs[regno] = val;
- return true;
-}
-
-static bool
-state_get_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
-{
- if (! __libdwfl_frame_reg_get (state, regno, val))
- {
- __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
- return false;
- }
- return true;
-}
-
-static int
-bra_compar (const void *key_voidp, const void *elem_voidp)
-{
- Dwarf_Word offset = (uintptr_t) key_voidp;
- const Dwarf_Op *op = elem_voidp;
- return (offset > op->offset) - (offset < op->offset);
-}
-
-/* If FRAME is NULL is are computing CFI frame base. In such case another
- DW_OP_call_frame_cfa is no longer permitted. */
-
-static bool
-expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
- size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
-{
- Dwfl_Process *process = state->thread->process;
- if (nops == 0)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- Dwarf_Addr *stack = NULL;
- size_t stack_used = 0, stack_allocated = 0;
-
- bool
- push (Dwarf_Addr val)
- {
- if (stack_used >= DWARF_EXPR_STACK_MAX)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- if (stack_used == stack_allocated)
- {
- stack_allocated = MAX (stack_allocated * 2, 32);
- Dwarf_Addr *stack_new = realloc (stack, stack_allocated * sizeof (*stack));
- if (stack_new == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return false;
- }
- stack = stack_new;
- }
- stack[stack_used++] = val;
- return true;
- }
-
- bool
- pop (Dwarf_Addr *val)
- {
- if (stack_used == 0)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- *val = stack[--stack_used];
- return true;
- }
-
- Dwarf_Addr val1, val2;
- bool is_location = false;
- size_t steps_count = 0;
- for (const Dwarf_Op *op = ops; op < ops + nops; op++)
- {
- if (++steps_count > DWARF_EXPR_STEPS_MAX)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- switch (op->atom)
- {
- /* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op: */
- case DW_OP_lit0 ... DW_OP_lit31:
- if (! push (op->atom - DW_OP_lit0))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_addr:
- if (! push (op->number + bias))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_GNU_encoded_addr:
- /* Missing support in the rest of elfutils. */
- __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF);
- return false;
- case DW_OP_const1u:
- case DW_OP_const1s:
- case DW_OP_const2u:
- case DW_OP_const2s:
- case DW_OP_const4u:
- case DW_OP_const4s:
- case DW_OP_const8u:
- case DW_OP_const8s:
- case DW_OP_constu:
- case DW_OP_consts:
- if (! push (op->number))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_reg0 ... DW_OP_reg31:
- if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
- || ! push (val1))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_regx:
- if (! state_get_reg (state, op->number, &val1) || ! push (val1))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_breg0 ... DW_OP_breg31:
- if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
- {
- free (stack);
- return false;
- }
- val1 += op->number;
- if (! push (val1))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_bregx:
- if (! state_get_reg (state, op->number, &val1))
- {
- free (stack);
- return false;
- }
- val1 += op->number2;
- if (! push (val1))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_dup:
- if (! pop (&val1) || ! push (val1) || ! push (val1))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_drop:
- if (! pop (&val1))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_pick:
- if (stack_used <= op->number)
- {
- free (stack);
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- if (! push (stack[stack_used - 1 - op->number]))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_over:
- if (! pop (&val1) || ! pop (&val2)
- || ! push (val2) || ! push (val1) || ! push (val2))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_swap:
- if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
- {
- free (stack);
- return false;
- }
- break;
- case DW_OP_rot:
- {
- Dwarf_Addr val3;
- if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
- || ! push (val1) || ! push (val3) || ! push (val2))
- {
- free (stack);
- return false;
- }
- }
- break;
- case DW_OP_deref:
- case DW_OP_deref_size:
- if (process->callbacks->memory_read == NULL)
- {
- free (stack);
- __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
- return false;
- }
- if (! pop (&val1)
- || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
- process->callbacks_arg))
- {
- free (stack);
- return false;
- }
- if (op->atom == DW_OP_deref_size)
- {
- const int elfclass = frame->cache->e_ident[EI_CLASS];
- const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
- if (op->number > addr_bytes)
- {
- free (stack);
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
-#if BYTE_ORDER == BIG_ENDIAN
- if (op->number == 0)
- val1 = 0;
- else
- val1 >>= (addr_bytes - op->number) * 8;
-#else
- if (op->number < 8)
- val1 &= (1 << (op->number * 8)) - 1;
-#endif
- }
- if (! push (val1))
- {
- free (stack);
- return false;
- }
- break;
-#define UNOP(atom, expr) \
- case atom: \
- if (! pop (&val1) || ! push (expr)) \
- { \
- free (stack); \
- return false; \
- } \
- break;
- UNOP (DW_OP_abs, abs ((int64_t) val1))
- UNOP (DW_OP_neg, -(int64_t) val1)
- UNOP (DW_OP_not, ~val1)
-#undef UNOP
- case DW_OP_plus_uconst:
- if (! pop (&val1) || ! push (val1 + op->number))
- {
- free (stack);
- return false;
- }
- break;
-#define BINOP(atom, op) \
- case atom: \
- if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2)) \
- { \
- free (stack); \
- return false; \
- } \
- break;
-#define BINOP_SIGNED(atom, op) \
- case atom: \
- if (! pop (&val2) || ! pop (&val1) \
- || ! push ((int64_t) val1 op (int64_t) val2)) \
- { \
- free (stack); \
- return false; \
- } \
- break;
- BINOP (DW_OP_and, &)
- case DW_OP_div:
- if (! pop (&val2) || ! pop (&val1))
- {
- free (stack);
- return false;
- }
- if (val2 == 0)
- {
- free (stack);
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- if (! push ((int64_t) val1 / (int64_t) val2))
- {
- free (stack);
- return false;
- }
- break;
- BINOP (DW_OP_minus, -)
- case DW_OP_mod:
- if (! pop (&val2) || ! pop (&val1))
- {
- free (stack);
- return false;
- }
- if (val2 == 0)
- {
- free (stack);
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- if (! push (val1 % val2))
- {
- free (stack);
- return false;
- }
- break;
- BINOP (DW_OP_mul, *)
- BINOP (DW_OP_or, |)
- BINOP (DW_OP_plus, +)
- BINOP (DW_OP_shl, <<)
- BINOP (DW_OP_shr, >>)
- BINOP_SIGNED (DW_OP_shra, >>)
- BINOP (DW_OP_xor, ^)
- BINOP_SIGNED (DW_OP_le, <=)
- BINOP_SIGNED (DW_OP_ge, >=)
- BINOP_SIGNED (DW_OP_eq, ==)
- BINOP_SIGNED (DW_OP_lt, <)
- BINOP_SIGNED (DW_OP_gt, >)
- BINOP_SIGNED (DW_OP_ne, !=)
-#undef BINOP
-#undef BINOP_SIGNED
- case DW_OP_bra:
- if (! pop (&val1))
- {
- free (stack);
- return false;
- }
- if (val1 == 0)
- break;
- /* FALLTHRU */
- case DW_OP_skip:;
- Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
- const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
- sizeof (*ops), bra_compar);
- if (found == NULL)
- {
- free (stack);
- /* PPC32 vDSO has such invalid operations. */
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- /* Undo the 'for' statement increment. */
- op = found - 1;
- break;
- case DW_OP_nop:
- break;
- /* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op: */
- case DW_OP_call_frame_cfa:;
- // Not used by CFI itself but it is synthetized by elfutils internation.
- Dwarf_Op *cfa_ops;
- size_t cfa_nops;
- Dwarf_Addr cfa;
- if (frame == NULL
- || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
- || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
- || ! push (cfa))
- {
- __libdwfl_seterrno (DWFL_E_LIBDW);
- free (stack);
- return false;
- }
- is_location = true;
- break;
- case DW_OP_stack_value:
- // Not used by CFI itself but it is synthetized by elfutils internation.
- is_location = false;
- break;
- default:
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- return false;
- }
- }
- if (! pop (result))
- {
- free (stack);
- return false;
- }
- free (stack);
- if (is_location)
- {
- if (process->callbacks->memory_read == NULL)
- {
- __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
- return false;
- }
- if (! process->callbacks->memory_read (process->dwfl, *result, result,
- process->callbacks_arg))
- return false;
- }
- return true;
-}
-
-static void
-new_unwound (Dwfl_Frame *state)
-{
- assert (state->unwound == NULL);
- Dwfl_Thread *thread = state->thread;
- Dwfl_Process *process = thread->process;
- Ebl *ebl = process->ebl;
- size_t nregs = ebl_frame_nregs (ebl);
- assert (nregs > 0);
- Dwfl_Frame *unwound;
- unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
- state->unwound = unwound;
- unwound->thread = thread;
- unwound->unwound = NULL;
- unwound->signal_frame = false;
- unwound->initial_frame = false;
- unwound->pc_state = DWFL_FRAME_STATE_ERROR;
- memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
-}
-
-/* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation
- error so one can easily catch the problem with a debugger. Still there are
- archs with invalid CFI for some registers where the registers are never used
- later. Therefore we continue unwinding leaving the registers undefined. */
-
-static void
-handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
-{
- Dwarf_Frame *frame;
- if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
- {
- __libdwfl_seterrno (DWFL_E_LIBDW);
- return;
- }
- new_unwound (state);
- Dwfl_Frame *unwound = state->unwound;
- unwound->signal_frame = frame->fde->cie->signal_frame;
- Dwfl_Thread *thread = state->thread;
- Dwfl_Process *process = thread->process;
- Ebl *ebl = process->ebl;
- size_t nregs = ebl_frame_nregs (ebl);
- assert (nregs > 0);
-
- /* The return register is special for setting the unwound->pc_state. */
- unsigned ra = frame->fde->cie->return_address_register;
- bool ra_set = false;
- ebl_dwarf_to_regno (ebl, &ra);
-
- for (unsigned regno = 0; regno < nregs; regno++)
- {
- Dwarf_Op reg_ops_mem[3], *reg_ops;
- size_t reg_nops;
- if (dwarf_frame_register (frame, regno, reg_ops_mem, &reg_ops,
- &reg_nops) != 0)
- {
- __libdwfl_seterrno (DWFL_E_LIBDW);
- continue;
- }
- Dwarf_Addr regval;
- if (reg_nops == 0)
- {
- if (reg_ops == reg_ops_mem)
- {
- /* REGNO is undefined. */
- if (regno == ra)
- unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
- continue;
- }
- else if (reg_ops == NULL)
- {
- /* REGNO is same-value. */
- if (! state_get_reg (state, regno, &regval))
- continue;
- }
- else
- {
- __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
- continue;
- }
- }
- else if (! expr_eval (state, frame, reg_ops, reg_nops, &regval, bias))
- {
- /* PPC32 vDSO has various invalid operations, ignore them. The
- register will look as unset causing an error later, if used.
- But PPC32 does not use such registers. */
- continue;
- }
-
- /* Some architectures encode some extra info in the return address. */
- if (regno == frame->fde->cie->return_address_register)
- regval &= ebl_func_addr_mask (ebl);
-
- /* This is another strange PPC[64] case. There are two
- registers numbers that can represent the same DWARF return
- register number. We only want one to actually set the return
- register value. But we always want to override the value if
- the register is the actual CIE return address register. */
- if (ra_set && regno != frame->fde->cie->return_address_register)
- {
- unsigned r = regno;
- if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
- continue;
- }
-
- if (! __libdwfl_frame_reg_set (unwound, regno, regval))
- {
- __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
- continue;
- }
- else if (! ra_set)
- {
- unsigned r = regno;
- if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
- ra_set = true;
- }
- }
- if (unwound->pc_state == DWFL_FRAME_STATE_ERROR
- && __libdwfl_frame_reg_get (unwound,
- frame->fde->cie->return_address_register,
- &unwound->pc))
- {
- /* PPC32 __libc_start_main properly CFI-unwinds PC as zero. Currently
- none of the archs supported for unwinding have zero as a valid PC. */
- if (unwound->pc == 0)
- unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
- else
- unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
- }
- free (frame);
-}
-
-static bool
-setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
-{
- Dwfl_Frame *state = arg;
- Dwfl_Frame *unwound = state->unwound;
- if (firstreg < 0)
- {
- assert (firstreg == -1);
- assert (nregs == 1);
- assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
- unwound->pc = *regs;
- unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
- return true;
- }
- while (nregs--)
- if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
- return false;
- return true;
-}
-
-static bool
-getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
-{
- Dwfl_Frame *state = arg;
- assert (firstreg >= 0);
- while (nregs--)
- if (! __libdwfl_frame_reg_get (state, firstreg++, regs++))
- return false;
- return true;
-}
-
-static bool
-readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
-{
- Dwfl_Frame *state = arg;
- Dwfl_Thread *thread = state->thread;
- Dwfl_Process *process = thread->process;
- return process->callbacks->memory_read (process->dwfl, addr, datap,
- process->callbacks_arg);
-}
-
-void
-internal_function
-__libdwfl_frame_unwind (Dwfl_Frame *state)
-{
- if (state->unwound)
- return;
- /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE
- which would deadlock us. */
- Dwarf_Addr pc;
- bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
- assert (ok);
- /* Check whether this is the initial frame or a signal frame.
- Then we need to unwind from the original, unadjusted PC. */
- if (! state->initial_frame && ! state->signal_frame)
- pc--;
- Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
- if (mod == NULL)
- __libdwfl_seterrno (DWFL_E_NO_DWARF);
- else
- {
- Dwarf_Addr bias;
- Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
- if (cfi_eh)
- {
- handle_cfi (state, pc - bias, cfi_eh, bias);
- if (state->unwound)
- return;
- }
- Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
- if (cfi_dwarf)
- {
- handle_cfi (state, pc - bias, cfi_dwarf, bias);
- if (state->unwound)
- return;
- }
- }
- assert (state->unwound == NULL);
- Dwfl_Thread *thread = state->thread;
- Dwfl_Process *process = thread->process;
- Ebl *ebl = process->ebl;
- new_unwound (state);
- state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
- // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
- bool signal_frame = false;
- if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame))
- {
- // Discard the unwind attempt. During next __libdwfl_frame_unwind call
- // we may have for example the appropriate Dwfl_Module already mapped.
- assert (state->unwound->unwound == NULL);
- free (state->unwound);
- state->unwound = NULL;
- // __libdwfl_seterrno has been called above.
- return;
- }
- assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
- state->unwound->signal_frame = signal_frame;
-}
diff --git a/src/libdwfl/gzip.c b/src/libdwfl/gzip.c
deleted file mode 100644
index b7dde5d4..00000000
--- a/src/libdwfl/gzip.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/* Decompression support for libdwfl: zlib (gzip) and/or bzlib (bzip2).
- Copyright (C) 2009 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "system.h"
-
-#include <unistd.h>
-
-#ifdef LZMA
-# define USE_INFLATE 1
-# include <lzma.h>
-# define unzip __libdw_unlzma
-# define DWFL_E_ZLIB DWFL_E_LZMA
-# define MAGIC "\xFD" "7zXZ\0" /* XZ file format. */
-# define MAGIC2 "\x5d\0" /* Raw LZMA format. */
-# define Z(what) LZMA_##what
-# define LZMA_ERRNO LZMA_PROG_ERROR
-# define z_stream lzma_stream
-# define inflateInit(z) lzma_auto_decoder (z, 1 << 30, 0)
-# define do_inflate(z) lzma_code (z, LZMA_RUN)
-# define inflateEnd(z) lzma_end (z)
-#elif defined BZLIB
-# define USE_INFLATE 1
-# include <bzlib.h>
-# define unzip __libdw_bunzip2
-# define DWFL_E_ZLIB DWFL_E_BZLIB
-# define MAGIC "BZh"
-# define Z(what) BZ_##what
-# define BZ_ERRNO BZ_IO_ERROR
-# define z_stream bz_stream
-# define inflateInit(z) BZ2_bzDecompressInit (z, 0, 0)
-# define do_inflate(z) BZ2_bzDecompress (z)
-# define inflateEnd(z) BZ2_bzDecompressEnd (z)
-#else
-# define USE_INFLATE 0
-# define crc32 loser_crc32
-# include <zlib.h>
-# define unzip __libdw_gunzip
-# define MAGIC "\037\213"
-# define Z(what) Z_##what
-#endif
-
-#define READ_SIZE (1 << 20)
-
-/* If this is not a compressed image, return DWFL_E_BADELF.
- If we uncompressed it into *WHOLE, *WHOLE_SIZE, return DWFL_E_NOERROR.
- Otherwise return an error for bad compressed data or I/O failure.
- If we return an error after reading the first part of the file,
- leave that portion malloc'd in *WHOLE, *WHOLE_SIZE. If *WHOLE
- is not null on entry, we'll use it in lieu of repeating a read. */
-
-Dwfl_Error internal_function
-unzip (int fd, off64_t start_offset,
- void *mapped, size_t mapped_size,
- void **whole, size_t *whole_size)
-{
- void *buffer = NULL;
- size_t size = 0;
- inline bool bigger_buffer (size_t start)
- {
- size_t more = size ? size * 2 : start;
- char *b = realloc (buffer, more);
- while (unlikely (b == NULL) && more >= size + 1024)
- b = realloc (buffer, more -= 1024);
- if (unlikely (b == NULL))
- return false;
- buffer = b;
- size = more;
- return true;
- }
- inline void smaller_buffer (size_t end)
- {
- buffer = realloc (buffer, end) ?: end == 0 ? NULL : buffer;
- size = end;
- }
-
- void *input_buffer = NULL;
- off_t input_pos = 0;
-
- inline Dwfl_Error fail (Dwfl_Error failure)
- {
- if (input_pos == (off_t) mapped_size)
- *whole = input_buffer;
- else
- {
- free (input_buffer);
- *whole = NULL;
- }
- free (buffer);
- return failure;
- }
-
- inline Dwfl_Error zlib_fail (int result)
- {
- switch (result)
- {
- case Z (MEM_ERROR):
- return fail (DWFL_E_NOMEM);
- case Z (ERRNO):
- return fail (DWFL_E_ERRNO);
- default:
- return fail (DWFL_E_ZLIB);
- }
- }
-
- if (mapped == NULL)
- {
- if (*whole == NULL)
- {
- input_buffer = malloc (READ_SIZE);
- if (unlikely (input_buffer == NULL))
- return DWFL_E_NOMEM;
-
- ssize_t n = pread_retry (fd, input_buffer, READ_SIZE, start_offset);
- if (unlikely (n < 0))
- return zlib_fail (Z (ERRNO));
-
- input_pos = n;
- mapped = input_buffer;
- mapped_size = n;
- }
- else
- {
- input_buffer = *whole;
- input_pos = mapped_size = *whole_size;
- }
- }
-
-#define NOMAGIC(magic) \
- (mapped_size <= sizeof magic || memcmp (mapped, magic, sizeof magic - 1))
-
- /* First, look at the header. */
- if (NOMAGIC (MAGIC)
-#ifdef MAGIC2
- && NOMAGIC (MAGIC2)
-#endif
- )
- /* Not a compressed file. */
- return DWFL_E_BADELF;
-
-#if USE_INFLATE
-
- /* This style actually only works with bzlib and liblzma.
- The stupid zlib interface has nothing to grok the
- gzip file headers except the slow gzFile interface. */
-
- z_stream z = { .next_in = mapped, .avail_in = mapped_size };
- int result = inflateInit (&z);
- if (result != Z (OK))
- {
- inflateEnd (&z);
- return zlib_fail (result);
- }
-
- do
- {
- if (z.avail_in == 0 && input_buffer != NULL)
- {
- ssize_t n = pread_retry (fd, input_buffer, READ_SIZE,
- start_offset + input_pos);
- if (unlikely (n < 0))
- {
- inflateEnd (&z);
- return zlib_fail (Z (ERRNO));
- }
- z.next_in = input_buffer;
- z.avail_in = n;
- input_pos += n;
- }
- if (z.avail_out == 0)
- {
- ptrdiff_t pos = (void *) z.next_out - buffer;
- if (!bigger_buffer (z.avail_in))
- {
- result = Z (MEM_ERROR);
- break;
- }
- z.next_out = buffer + pos;
- z.avail_out = size - pos;
- }
- }
- while ((result = do_inflate (&z)) == Z (OK));
-
-#ifdef BZLIB
- uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32)
- | z.total_out_lo32);
- smaller_buffer (total_out);
-#else
- smaller_buffer (z.total_out);
-#endif
-
- inflateEnd (&z);
-
- if (result != Z (STREAM_END))
- return zlib_fail (result);
-
-#else /* gzip only. */
-
- /* Let the decompression library read the file directly. */
-
- gzFile zf;
- Dwfl_Error open_stream (void)
- {
- int d = dup (fd);
- if (unlikely (d < 0))
- return DWFL_E_BADELF;
- if (start_offset != 0)
- {
- off64_t off = lseek (d, start_offset, SEEK_SET);
- if (off != start_offset)
- {
- close (d);
- return DWFL_E_BADELF;
- }
- }
- zf = gzdopen (d, "r");
- if (unlikely (zf == NULL))
- {
- close (d);
- return zlib_fail (Z (MEM_ERROR));
- }
-
- /* From here on, zlib will close D. */
-
- return DWFL_E_NOERROR;
- }
-
- Dwfl_Error result = open_stream ();
-
- if (result == DWFL_E_NOERROR && gzdirect (zf))
- {
- gzclose (zf);
- return fail (DWFL_E_BADELF);
- }
-
- if (result != DWFL_E_NOERROR)
- return fail (result);
-
- ptrdiff_t pos = 0;
- while (1)
- {
- if (!bigger_buffer (1024))
- {
- gzclose (zf);
- return zlib_fail (Z (MEM_ERROR));
- }
- int n = gzread (zf, buffer + pos, size - pos);
- if (n < 0)
- {
- int code;
- gzerror (zf, &code);
- gzclose (zf);
- return zlib_fail (code);
- }
- if (n == 0)
- break;
- pos += n;
- }
-
- gzclose (zf);
- smaller_buffer (pos);
-#endif
-
- free (input_buffer);
-
- *whole = buffer;
- *whole_size = size;
-
- return DWFL_E_NOERROR;
-}
diff --git a/src/libdwfl/image-header.c b/src/libdwfl/image-header.c
deleted file mode 100644
index a4f6799a..00000000
--- a/src/libdwfl/image-header.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Linux kernel image support for libdwfl.
- Copyright (C) 2009-2011 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "system.h"
-
-#include <unistd.h>
-#include <endian.h>
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-# define LE16(x) (x)
-#else
-# define LE16(x) bswap_16 (x)
-#endif
-
-/* See Documentation/x86/boot.txt in Linux kernel sources
- for an explanation of these format details. */
-
-#define MAGIC1 0xaa55
-#define MAGIC2 0x53726448 /* "HdrS" little-endian */
-#define MIN_VERSION 0x0208
-
-#define H_START (H_SETUP_SECTS & -4)
-#define H_SETUP_SECTS 0x1f1
-#define H_MAGIC1 0x1fe
-#define H_MAGIC2 0x202
-#define H_VERSION 0x206
-#define H_PAYLOAD_OFFSET 0x248
-#define H_PAYLOAD_LENGTH 0x24c
-#define H_END 0x250
-#define H_READ_SIZE (H_END - H_START)
-
-Dwfl_Error
-internal_function
-__libdw_image_header (int fd, off64_t *start_offset,
- void *mapped, size_t mapped_size)
-{
- if (likely (mapped_size > H_END))
- {
- const void *header = mapped;
- char header_buffer[H_READ_SIZE];
- if (header == NULL)
- {
- ssize_t n = pread_retry (fd, header_buffer, H_READ_SIZE,
- *start_offset + H_START);
- if (n < 0)
- return DWFL_E_ERRNO;
- if (n < H_READ_SIZE)
- return DWFL_E_BADELF;
-
- header = header_buffer - H_START;
- }
-
- if (*(uint16_t *) (header + H_MAGIC1) == LE16 (MAGIC1)
- && *(uint32_t *) (header + H_MAGIC2) == LE32 (MAGIC2)
- && LE16 (*(uint16_t *) (header + H_VERSION)) >= MIN_VERSION)
- {
- /* The magic numbers match and the version field is sufficient.
- Extract the payload bounds. */
-
- uint32_t offset = LE32 (*(uint32_t *) (header + H_PAYLOAD_OFFSET));
- uint32_t length = LE32 (*(uint32_t *) (header + H_PAYLOAD_LENGTH));
-
- offset += ((*(uint8_t *) (header + H_SETUP_SECTS) ?: 4) + 1) * 512;
-
- if (offset > H_END && offset < mapped_size
- && mapped_size - offset >= length)
- {
- /* It looks kosher. Use it! */
- *start_offset += offset;
- return DWFL_E_NOERROR;
- }
- }
- }
- return DWFL_E_BADELF;
-}
diff --git a/src/libdwfl/libdwfl.h b/src/libdwfl/libdwfl.h
deleted file mode 100644
index 2bb4f455..00000000
--- a/src/libdwfl/libdwfl.h
+++ /dev/null
@@ -1,812 +0,0 @@
-/* Interfaces for libdwfl.
- Copyright (C) 2005-2010, 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef _LIBDWFL_H
-#define _LIBDWFL_H 1
-
-#include "libdw.h"
-#include <stdio.h>
-
-/* Handle for a session using the library. */
-typedef struct Dwfl Dwfl;
-
-/* Handle for a module. */
-typedef struct Dwfl_Module Dwfl_Module;
-
-/* Handle describing a line record. */
-typedef struct Dwfl_Line Dwfl_Line;
-
-/* This holds information common for all the frames of one backtrace for
- a partical thread/task/TID. Several threads belong to one Dwfl. */
-typedef struct Dwfl_Thread Dwfl_Thread;
-
-/* This holds everything we know about the state of the frame at a particular
- PC location described by an FDE belonging to Dwfl_Thread. */
-typedef struct Dwfl_Frame Dwfl_Frame;
-
-/* Callbacks. */
-typedef struct
-{
- int (*find_elf) (Dwfl_Module *mod, void **userdata,
- const char *modname, Dwarf_Addr base,
- char **file_name, Elf **elfp);
-
- int (*find_debuginfo) (Dwfl_Module *mod, void **userdata,
- const char *modname, Dwarf_Addr base,
- const char *file_name,
- const char *debuglink_file, GElf_Word debuglink_crc,
- char **debuginfo_file_name);
-
- /* Fill *ADDR with the loaded address of the section called SECNAME in
- the given module. Use (Dwarf_Addr) -1 if this section is omitted from
- accessible memory. This is called exactly once for each SHF_ALLOC
- section that relocations affecting DWARF data refer to, so it can
- easily be used to collect state about the sections referenced. */
- int (*section_address) (Dwfl_Module *mod, void **userdata,
- const char *modname, Dwarf_Addr base,
- const char *secname,
- GElf_Word shndx, const GElf_Shdr *shdr,
- Dwarf_Addr *addr);
-
- char **debuginfo_path; /* See dwfl_standard_find_debuginfo. */
-} Dwfl_Callbacks;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Start a new session with the library. */
-extern Dwfl *dwfl_begin (const Dwfl_Callbacks *callbacks)
- __nonnull_attribute__ (1);
-
-
-/* End a session. */
-extern void dwfl_end (Dwfl *);
-
-/* Return implementation's version string suitable for printing. */
-extern const char *dwfl_version (Dwfl *);
-
-/* Return error code of last failing function call. This value is kept
- separately for each thread. */
-extern int dwfl_errno (void);
-
-/* Return error string for ERROR. If ERROR is zero, return error string
- for most recent error or NULL if none occurred. If ERROR is -1 the
- behaviour is similar to the last case except that not NULL but a legal
- string is returned. */
-extern const char *dwfl_errmsg (int err);
-
-
-/* Start reporting the current set of segments and modules to the library.
- All existing segments are wiped. Existing modules are marked to be
- deleted, and will not be found via dwfl_addrmodule et al if they are not
- re-reported before dwfl_report_end is called. */
-extern void dwfl_report_begin (Dwfl *dwfl);
-
-/* Report that segment NDX begins at PHDR->p_vaddr + BIAS.
- If NDX is < 0, the value succeeding the last call's NDX
- is used instead (zero on the first call).
-
- If nonzero, the smallest PHDR->p_align value seen sets the
- effective page size for the address space DWFL describes.
- This is the granularity at which reported module boundary
- addresses will be considered to fall in or out of a segment.
-
- Returns -1 for errors, or NDX (or its assigned replacement) on success.
-
- When NDX is the value succeeding the last call's NDX (or is implicitly
- so as above), IDENT is nonnull and matches the value in the last call,
- and the PHDR and BIAS values reflect a segment that would be contiguous,
- in both memory and file, with the last segment reported, then this
- segment may be coalesced internally with preceding segments. When given
- an address inside this segment, dwfl_addrsegment may return the NDX of a
- preceding contiguous segment. To prevent coalesced segments, always
- pass a null pointer for IDENT.
-
- The values passed are not stored (except to track coalescence).
- The only information that can be extracted from DWFL later is the
- mapping of an address to a segment index that starts at or below
- it. Reporting segments at all is optional. Its only benefit to
- the caller is to offer this quick lookup via dwfl_addrsegment,
- or use other segment-based calls. */
-extern int dwfl_report_segment (Dwfl *dwfl, int ndx,
- const GElf_Phdr *phdr, GElf_Addr bias,
- const void *ident);
-
-/* Report that a module called NAME spans addresses [START, END).
- Returns the module handle, either existing or newly allocated,
- or returns a null pointer for an allocation error. */
-extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name,
- Dwarf_Addr start, Dwarf_Addr end);
-
-/* Report a module to address BASE with start and end addresses computed
- from the ELF program headers in the given file - see the table below.
- FD may be -1 to open FILE_NAME. On success, FD is consumed by the
- library, and the `find_elf' callback will not be used for this module.
- ADD_P_VADDR BASE
- ET_EXEC ignored ignored
- ET_DYN false absolute address where to place the file
- true start address relative to ELF's phdr p_vaddr
- ET_REL ignored absolute address where to place the file
- ET_CORE ignored ignored
- ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library
- has been prelinked by tool prelink(8). */
-extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name,
- const char *file_name, int fd,
- GElf_Addr base, bool add_p_vaddr);
-
-/* Similar, but report the module for offline use. All ET_EXEC files
- being reported must be reported before any relocatable objects.
- If this is used, dwfl_report_module and dwfl_report_elf may not be
- used in the same reporting session. */
-extern Dwfl_Module *dwfl_report_offline (Dwfl *dwfl, const char *name,
- const char *file_name, int fd);
-
-
-/* Finish reporting the current set of modules to the library.
- If REMOVED is not null, it's called for each module that
- existed before but was not included in the current report.
- Returns a nonzero return value from the callback.
- The callback may call dwfl_report_module; doing so with the
- details of the module being removed prevents its removal.
- DWFL cannot be used until this function has returned zero. */
-extern int dwfl_report_end (Dwfl *dwfl,
- int (*removed) (Dwfl_Module *, void *,
- const char *, Dwarf_Addr,
- void *arg),
- void *arg);
-
-/* Start reporting additional modules to the library. No calls but
- dwfl_report_* can be made on DWFL until dwfl_report_end is called.
- This is like dwfl_report_begin, but all the old modules are kept on.
- More dwfl_report_* calls can follow to add more modules.
- When dwfl_report_end is called, no old modules will be removed. */
-extern void dwfl_report_begin_add (Dwfl *dwfl);
-
-
-/* Return the name of the module, and for each non-null argument store
- interesting details: *USERDATA is a location for storing your own
- pointer, **USERDATA is initially null; *START and *END give the address
- range covered by the module; *DWBIAS is the address bias for debugging
- information, and *SYMBIAS for symbol table entries (either is -1 if not
- yet accessed); *MAINFILE is the name of the ELF file, and *DEBUGFILE the
- name of the debuginfo file (might be equal to *MAINFILE; either is null
- if not yet accessed). */
-extern const char *dwfl_module_info (Dwfl_Module *mod, void ***userdata,
- Dwarf_Addr *start, Dwarf_Addr *end,
- Dwarf_Addr *dwbias, Dwarf_Addr *symbias,
- const char **mainfile,
- const char **debugfile);
-
-/* Iterate through the modules, starting the walk with OFFSET == 0.
- Calls *CALLBACK for each module as long as it returns DWARF_CB_OK.
- When *CALLBACK returns another value, the walk stops and the
- return value can be passed as OFFSET to resume it. Returns 0 when
- there are no more modules, or -1 for errors. */
-extern ptrdiff_t dwfl_getmodules (Dwfl *dwfl,
- int (*callback) (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- void *arg),
- void *arg,
- ptrdiff_t offset);
-
-/* Find the module containing the given address. */
-extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address);
-
-/* Find the segment, if any, and module, if any, containing ADDRESS.
- Returns a segment index returned by dwfl_report_segment, or -1
- if no segment matches the address. Regardless of the return value,
- *MOD is always set to the module containing ADDRESS, or to null. */
-extern int dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod);
-
-
-
-/* Report the known build ID bits associated with a module.
- If VADDR is nonzero, it gives the absolute address where those
- bits are found within the module. This can be called at any
- time, but is usually used immediately after dwfl_report_module.
- Once the module's main ELF file is opened, the ID note found
- there takes precedence and cannot be changed. */
-extern int dwfl_module_report_build_id (Dwfl_Module *mod,
- const unsigned char *bits, size_t len,
- GElf_Addr vaddr)
- __nonnull_attribute__ (2);
-
-/* Extract the build ID bits associated with a module.
- Returns -1 for errors, 0 if no ID is known, or the number of ID bytes.
- When an ID is found, *BITS points to it; *VADDR is the absolute address
- at which the ID bits are found within the module, or 0 if unknown.
-
- This returns 0 when the module's main ELF file has not yet been loaded
- and its build ID bits were not reported. To ensure the ID is always
- returned when determinable, call dwfl_module_getelf first. */
-extern int dwfl_module_build_id (Dwfl_Module *mod,
- const unsigned char **bits, GElf_Addr *vaddr)
- __nonnull_attribute__ (2, 3);
-
-
-/*** Standard callbacks ***/
-
-/* These standard find_elf and find_debuginfo callbacks are
- controlled by a string specifying directories to look in.
- If `debuginfo_path' is set in the Dwfl_Callbacks structure
- and the char * it points to is not null, that supplies the
- string. Otherwise a default path is used.
-
- If the first character of the string is + or - that enables or
- disables CRC32 checksum validation when it's necessary. The
- remainder of the string is composed of elements separated by
- colons. Each element can start with + or - to override the
- global checksum behavior. This flag is never relevant when
- working with build IDs, but it's always parsed in the path
- string. The remainder of the element indicates a directory.
-
- Searches by build ID consult only the elements naming absolute
- directory paths. They look under those directories for a link
- named ".build-id/xx/yy" or ".build-id/xx/yy.debug", where "xxyy"
- is the lower-case hexadecimal representation of the ID bytes.
-
- In searches for debuginfo by name, if the remainder of the
- element is empty, the directory containing the main file is
- tried; if it's an absolute path name, the absolute directory path
- containing the main file is taken as a subdirectory of this path;
- a relative path name is taken as a subdirectory of the directory
- containing the main file. Hence for /bin/ls, the default string
- ":.debug:/usr/lib/debug" says to look in /bin, then /bin/.debug,
- then /usr/lib/debug/bin, for the file name in the .gnu_debuglink
- section (or "ls.debug" if none was found). */
-
-/* Standard find_elf callback function working solely on build ID.
- This can be tried first by any find_elf callback, to use the
- bits passed to dwfl_module_report_build_id, if any. */
-extern int dwfl_build_id_find_elf (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- char **, Elf **);
-
-/* Standard find_debuginfo callback function working solely on build ID.
- This can be tried first by any find_debuginfo callback,
- to use the build ID bits from the main file when present. */
-extern int dwfl_build_id_find_debuginfo (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- const char *, const char *,
- GElf_Word, char **);
-
-/* Standard find_debuginfo callback function.
- If a build ID is available, this tries first to use that.
- If there is no build ID or no valid debuginfo found by ID,
- it searches the debuginfo path by name, as described above.
- Any file found in the path is validated by build ID if possible,
- or else by CRC32 checksum if enabled, and skipped if it does not match. */
-extern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- const char *, const char *,
- GElf_Word, char **);
-
-
-/* This callback must be used when using dwfl_offline_* to report modules,
- if ET_REL is to be supported. */
-extern int dwfl_offline_section_address (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- const char *, GElf_Word,
- const GElf_Shdr *,
- Dwarf_Addr *addr);
-
-
-/* Callbacks for working with kernel modules in the running Linux kernel. */
-extern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- char **, Elf **);
-extern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- const char *, GElf_Word,
- const GElf_Shdr *,
- Dwarf_Addr *addr);
-
-/* Call dwfl_report_elf for the running Linux kernel.
- Returns zero on success, -1 if dwfl_report_module failed,
- or an errno code if opening the kernel binary failed. */
-extern int dwfl_linux_kernel_report_kernel (Dwfl *dwfl);
-
-/* Call dwfl_report_module for each kernel module in the running Linux kernel.
- Returns zero on success, -1 if dwfl_report_module failed,
- or an errno code if reading the list of modules failed. */
-extern int dwfl_linux_kernel_report_modules (Dwfl *dwfl);
-
-/* Report a kernel and its modules found on disk, for offline use.
- If RELEASE starts with '/', it names a directory to look in;
- if not, it names a directory to find under /lib/modules/;
- if null, /lib/modules/`uname -r` is used.
- Returns zero on success, -1 if dwfl_report_module failed,
- or an errno code if finding the files on disk failed.
-
- If PREDICATE is not null, it is called with each module to be reported;
- its arguments are the module name, and the ELF file name or null if unknown,
- and its return value should be zero to skip the module, one to report it,
- or -1 to cause the call to fail and return errno. */
-extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
- int (*predicate) (const char *,
- const char *));
-
-/* Examine an ET_CORE file and report modules based on its contents.
- This can follow a dwfl_report_offline call to bootstrap the
- DT_DEBUG method of following the dynamic linker link_map chain, in
- case the core file does not contain enough of the executable's text
- segment to locate its PT_DYNAMIC in the dump. In such case you need to
- supply non-NULL EXECUTABLE, otherwise dynamic libraries will not be loaded
- into the DWFL map. This might call dwfl_report_elf on file names found in
- the dump if reading some link_map files is the only way to ascertain those
- modules' addresses. Returns the number of modules reported, or -1 for
- errors. */
-extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable);
-
-/* Call dwfl_report_module for each file mapped into the address space of PID.
- Returns zero on success, -1 if dwfl_report_module failed,
- or an errno code if opening the proc files failed. */
-extern int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid);
-
-/* Similar, but reads an input stream in the format of Linux /proc/PID/maps
- files giving module layout, not the file for a live process. */
-extern int dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *);
-
-/* Trivial find_elf callback for use with dwfl_linux_proc_report.
- This uses the module name as a file name directly and tries to open it
- if it begin with a slash, or handles the magic string "[vdso]". */
-extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata,
- const char *module_name, Dwarf_Addr base,
- char **file_name, Elf **);
-
-/* Standard argument parsing for using a standard callback set. */
-struct argp;
-extern const struct argp *dwfl_standard_argp (void) __attribute__ ((const));
-
-
-/*** Relocation of addresses from Dwfl ***/
-
-/* Return the number of relocatable bases associated with the module,
- which is zero for ET_EXEC and one for ET_DYN. Returns -1 for errors. */
-extern int dwfl_module_relocations (Dwfl_Module *mod);
-
-/* Return the relocation base index associated with the *ADDRESS location,
- and adjust *ADDRESS to be an offset relative to that base.
- Returns -1 for errors. */
-extern int dwfl_module_relocate_address (Dwfl_Module *mod,
- Dwarf_Addr *address);
-
-/* Return the ELF section name for the given relocation base index;
- if SHNDXP is not null, set *SHNDXP to the ELF section index.
- For ET_DYN, returns "" and sets *SHNDXP to SHN_ABS; the relocation
- base is the runtime start address reported for the module.
- Returns null for errors. */
-extern const char *dwfl_module_relocation_info (Dwfl_Module *mod,
- unsigned int idx,
- GElf_Word *shndxp);
-
-/* Validate that ADDRESS and ADDRESS+OFFSET lie in a known module
- and both within the same contiguous region for relocation purposes.
- Returns zero for success and -1 for errors. */
-extern int dwfl_validate_address (Dwfl *dwfl,
- Dwarf_Addr address, Dwarf_Sword offset);
-
-
-/*** ELF access functions ***/
-
-/* Fetch the module main ELF file (where the allocated sections
- are found) for use with libelf. If successful, fills in *BIAS
- with the difference between addresses within the loaded module
- and those in symbol tables or Dwarf information referring to it. */
-extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias)
- __nonnull_attribute__ (1, 2);
-
-/* Return the number of symbols in the module's symbol table,
- or -1 for errors. */
-extern int dwfl_module_getsymtab (Dwfl_Module *mod);
-
-/* Return the index of the first global symbol in the module's symbol
- table, or -1 for errors. In each symbol table, all symbols with
- STB_LOCAL binding precede the weak and global symbols. This
- function returns the symbol table index one greater than the last
- local symbol. */
-extern int dwfl_module_getsymtab_first_global (Dwfl_Module *mod);
-
-/* Fetch one entry from the module's symbol table. On errors, returns
- NULL. If successful, fills in *SYM and returns the string for st_name.
- This works like gelf_getsym except that st_value is always adjusted to
- an absolute value based on the module's location, when the symbol is in
- an SHF_ALLOC section. If SHNDXP is non-null, it's set with the section
- index (whether from st_shndx or extended index table); in case of a
- symbol in a non-allocated section, *SHNDXP is instead set to -1.
- Note that since symbols can come from either the main, debug or auxiliary
- ELF symbol file (either dynsym or symtab) the section index can only
- be reliably used to compare against special section constants like
- SHN_UNDEF or SHN_ABS. It is recommended to use dwfl_module_getsym_info
- which doesn't have these deficiencies. */
-extern const char *dwfl_module_getsym (Dwfl_Module *mod, int ndx,
- GElf_Sym *sym, GElf_Word *shndxp)
- __nonnull_attribute__ (3);
-
-/* Fetch one entry from the module's symbol table and the associated
- address value. On errors, returns NULL. If successful, fills in
- *SYM, *ADDR and returns the string for st_name. This works like
- gelf_getsym. *ADDR is set to the st_value adjusted to an absolute
- value based on the module's location, when the symbol is in an
- SHF_ALLOC section. For non-ET_REL files, if the arch uses function
- descriptors, and the st_value points to one, *ADDR will be resolved
- to the actual function entry address. The SYM->ST_VALUE itself
- isn't adjusted in any way. Fills in ELFP, if not NULL, with the
- ELF file the symbol originally came from. Note that symbols can
- come from either the main, debug or auxiliary ELF symbol file
- (either dynsym or symtab). If SHNDXP is non-null, it's set with
- the section index (whether from st_shndx or extended index table);
- in case of a symbol in a non-allocated section, *SHNDXP is instead
- set to -1. Fills in BIAS, if not NULL, with the difference between
- addresses within the loaded module and those in symbol table of the
- ELF file. Note that the address associated with the symbol might
- be in a different section than the returned symbol. The section in
- the main elf file in which returned ADDR falls can be found with
- dwfl_module_address_section. */
-extern const char *dwfl_module_getsym_info (Dwfl_Module *mod, int ndx,
- GElf_Sym *sym, GElf_Addr *addr,
- GElf_Word *shndxp,
- Elf **elfp, Dwarf_Addr *bias)
- __nonnull_attribute__ (3, 4);
-
-/* Find the symbol that ADDRESS lies inside, and return its name. */
-extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address);
-
-/* Find the symbol associated with ADDRESS. Return its name or NULL
- when nothing was found. If the architecture uses function
- descriptors, and symbol st_value points to one, ADDRESS wil be
- matched against either the adjusted st_value or the associated
- function entry value as described in dwfl_module_getsym_info. If
- OFFSET is not NULL it will be filled in with the difference from
- the start of the symbol (or function entry). If SYM is not NULL it
- is filled in with the symbol associated with the matched ADDRESS.
- The SYM->ST_VALUE itself isn't adjusted in any way. Fills in ELFP,
- if not NULL, with the ELF file the symbol originally came from.
- Note that symbols can come from either the main, debug or auxiliary
- ELF symbol file (either dynsym or symtab). If SHNDXP is non-null,
- it's set with the section index (whether from st_shndx or extended
- index table). Fills in BIAS, if not NULL, with the difference
- between addresses within the loaded module and those in symbol
- table of the ELF file. Note that the address matched against the
- symbol might be in a different section than the returned symbol.
- The section in the main elf file in ADDRESS falls can be found with
- dwfl_module_address_section. */
-extern const char *dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address,
- GElf_Off *offset, GElf_Sym *sym,
- GElf_Word *shndxp, Elf **elfp,
- Dwarf_Addr *bias)
- __nonnull_attribute__ (3);
-
-/* Find the symbol that ADDRESS lies inside, and return detailed
- information as for dwfl_module_getsym (above). Note that like
- dwfl_module_getsym this function also adjusts SYM->ST_VALUE to an
- absolute value based on the module's location. ADDRESS is only
- matched against this adjusted SYM->ST_VALUE. This means that
- depending on architecture this might only match symbols that
- represent function descriptor addresses (and not function entry
- addresses). For these reasons it is recommended to use
- dwfl_module_addrinfo instead. */
-extern const char *dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr address,
- GElf_Sym *sym, GElf_Word *shndxp)
- __nonnull_attribute__ (3);
-
-/* Find the ELF section that *ADDRESS lies inside and return it.
- On success, adjusts *ADDRESS to be relative to the section,
- and sets *BIAS to the difference between addresses used in
- the returned section's headers and run-time addresses. */
-extern Elf_Scn *dwfl_module_address_section (Dwfl_Module *mod,
- Dwarf_Addr *address,
- Dwarf_Addr *bias)
- __nonnull_attribute__ (2, 3);
-
-
-/*** Dwarf access functions ***/
-
-/* Fetch the module's debug information for use with libdw.
- If successful, fills in *BIAS with the difference between
- addresses within the loaded module and those to use with libdw. */
-extern Dwarf *dwfl_module_getdwarf (Dwfl_Module *, Dwarf_Addr *bias)
- __nonnull_attribute__ (2);
-
-/* Get the libdw handle for each module. */
-extern ptrdiff_t dwfl_getdwarf (Dwfl *,
- int (*callback) (Dwfl_Module *, void **,
- const char *, Dwarf_Addr,
- Dwarf *, Dwarf_Addr, void *),
- void *arg, ptrdiff_t offset);
-
-/* Look up the module containing ADDR and return its debugging information,
- loading it if necessary. */
-extern Dwarf *dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
- __nonnull_attribute__ (3);
-
-
-/* Find the CU containing ADDR and return its DIE. */
-extern Dwarf_Die *dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
- __nonnull_attribute__ (3);
-extern Dwarf_Die *dwfl_module_addrdie (Dwfl_Module *mod,
- Dwarf_Addr addr, Dwarf_Addr *bias)
- __nonnull_attribute__ (3);
-
-/* Iterate through the CUs, start with null for LASTCU. */
-extern Dwarf_Die *dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias)
- __nonnull_attribute__ (3);
-extern Dwarf_Die *dwfl_module_nextcu (Dwfl_Module *mod,
- Dwarf_Die *lastcu, Dwarf_Addr *bias)
- __nonnull_attribute__ (3);
-
-/* Return the module containing the CU DIE. */
-extern Dwfl_Module *dwfl_cumodule (Dwarf_Die *cudie);
-
-
-/* Cache the source line information fo the CU and return the
- number of Dwfl_Line entries it has. */
-extern int dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines);
-
-/* Access one line number entry within the CU. */
-extern Dwfl_Line *dwfl_onesrcline (Dwarf_Die *cudie, size_t idx);
-
-/* Get source for address. */
-extern Dwfl_Line *dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr);
-extern Dwfl_Line *dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr);
-
-/* Get address for source. */
-extern int dwfl_module_getsrc_file (Dwfl_Module *mod,
- const char *fname, int lineno, int column,
- Dwfl_Line ***srcsp, size_t *nsrcs);
-
-/* Return the module containing this line record. */
-extern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line);
-
-/* Return the CU containing this line record. */
-extern Dwarf_Die *dwfl_linecu (Dwfl_Line *line);
-
-/* Return the source file name and fill in other information.
- Arguments may be null for unneeded fields. */
-extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr,
- int *linep, int *colp,
- Dwarf_Word *mtime, Dwarf_Word *length);
-
- /* Return the equivalent Dwarf_Line and the bias to apply to its address. */
-extern Dwarf_Line *dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias);
-
-/* Return the compilation directory (AT_comp_dir) from this line's CU. */
-extern const char *dwfl_line_comp_dir (Dwfl_Line *line);
-
-
-/*** Machine backend access functions ***/
-
-/* Return location expression to find return value given a
- DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing
- function itself (whose DW_AT_type attribute describes its return type).
- The given DIE must come from the given module. Returns -1 for errors.
- Returns zero if the function has no return value (e.g. "void" in C).
- Otherwise, *LOCOPS gets a location expression to find the return value,
- and returns the number of operations in the expression. The pointer is
- permanently allocated at least as long as the module is live. */
-extern int dwfl_module_return_value_location (Dwfl_Module *mod,
- Dwarf_Die *functypedie,
- const Dwarf_Op **locops);
-
-/* Enumerate the DWARF register numbers and their names.
- For each register, CALLBACK gets its DWARF number, a string describing
- the register set (such as "integer" or "FPU"), a prefix used in
- assembler syntax (such as "%" or "$", may be ""), and the name for the
- register (contains identifier characters only, possibly all digits).
- The REGNAME string is valid only during the callback. */
-extern int dwfl_module_register_names (Dwfl_Module *mod,
- int (*callback) (void *arg,
- int regno,
- const char *setname,
- const char *prefix,
- const char *regname,
- int bits, int type),
- void *arg);
-
-
-/* Find the CFI for this module. Returns NULL if there is no CFI.
- On success, fills in *BIAS with the difference between addresses
- within the loaded module and those in the CFI referring to it.
- The pointer returned can be used until the module is cleaned up.
- Calling these more than once returns the same pointers.
-
- dwfl_module_dwarf_cfi gets the '.debug_frame' information found with the
- rest of the DWARF information. dwfl_module_eh_cfi gets the '.eh_frame'
- information found linked into the text. A module might have either or
- both. */
-extern Dwarf_CFI *dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
-extern Dwarf_CFI *dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
-
-
-typedef struct
-{
- /* Called to iterate through threads. Returns next TID (thread ID) on
- success, a negative number on failure and zero if there are no more
- threads. dwfl_errno () should be set if negative number has been
- returned. *THREAD_ARGP is NULL on first call, and may be optionally
- set by the implementation. The value set by the implementation will
- be passed in on the next call to NEXT_THREAD. THREAD_ARGP is never
- NULL. *THREAD_ARGP will be passed to set_initial_registers or
- thread_detach callbacks together with Dwfl_Thread *thread. This
- method must not be NULL. */
- pid_t (*next_thread) (Dwfl *dwfl, void *dwfl_arg, void **thread_argp)
- __nonnull_attribute__ (1);
-
- /* Called to get a specific thread. Returns true if there is a
- thread with the given thread id number, returns false if no such
- thread exists and will set dwfl_errno in that case. THREAD_ARGP
- is never NULL. *THREAD_ARGP will be passed to
- set_initial_registers or thread_detach callbacks together with
- Dwfl_Thread *thread. This method may be NULL and will then be
- emulated using the next_thread callback. */
- bool (*get_thread) (Dwfl *dwfl, pid_t tid, void *dwfl_arg,
- void **thread_argp)
- __nonnull_attribute__ (1);
-
- /* Called during unwinding to access memory (stack) state. Returns true for
- successfully read *RESULT or false and sets dwfl_errno () on failure.
- This method may be NULL - in such case dwfl_thread_getframes will return
- only the initial frame. */
- bool (*memory_read) (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result,
- void *dwfl_arg)
- __nonnull_attribute__ (1, 3);
-
- /* Called on initial unwind to get the initial register state of the first
- frame. Should call dwfl_thread_state_registers, possibly multiple times
- for different ranges and possibly also dwfl_thread_state_register_pc, to
- fill in initial (DWARF) register values. After this call, till at least
- thread_detach is called, the thread is assumed to be frozen, so that it is
- safe to unwind. Returns true on success or false and sets dwfl_errno ()
- on failure. In the case of a failure thread_detach will not be called.
- This method must not be NULL. */
- bool (*set_initial_registers) (Dwfl_Thread *thread, void *thread_arg)
- __nonnull_attribute__ (1);
-
- /* Called by dwfl_end. All thread_detach method calls have been already
- done. This method may be NULL. */
- void (*detach) (Dwfl *dwfl, void *dwfl_arg)
- __nonnull_attribute__ (1);
-
- /* Called when unwinding is done. No callback will be called after
- this method has been called. Iff set_initial_registers was called for
- a TID and it returned success thread_detach will be called before the
- detach method above. This method may be NULL. */
- void (*thread_detach) (Dwfl_Thread *thread, void *thread_arg)
- __nonnull_attribute__ (1);
-} Dwfl_Thread_Callbacks;
-
-/* PID is the process id associated with the DWFL state. Architecture of DWFL
- modules is specified by ELF, ELF must remain valid during DWFL lifetime.
- Use NULL ELF to detect architecture from DWFL, the function will then detect
- it from arbitrary Dwfl_Module of DWFL. DWFL_ARG is the callback backend
- state. DWFL_ARG will be provided to the callbacks. *THREAD_CALLBACKS
- function pointers must remain valid during lifetime of DWFL. Function
- returns true on success, false otherwise. */
-bool dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
- const Dwfl_Thread_Callbacks *thread_callbacks,
- void *dwfl_arg)
- __nonnull_attribute__ (1, 4);
-
-/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting
- thread state from the ELF core file. Returns the pid number extracted
- from the core file, or -1 for errors. */
-extern int dwfl_core_file_attach (Dwfl *dwfl, Elf *elf);
-
-/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting
- thread state from the proc file system. Uses ptrace to attach and stop
- the thread under inspection and detaches when thread_detach is called
- and unwinding for the thread is done, unless ASSUME_PTRACE_STOPPED is
- true. If ASSUME_PTRACE_STOPPED is true the caller should make sure that
- the thread is ptrace attached and stopped before unwinding by calling
- either dwfl_thread_getframes or dwfl_getthread_frames. Returns zero on
- success, -1 if dwfl_attach_state failed, or an errno code if opening the
- proc files failed. */
-extern int dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid,
- bool assume_ptrace_stopped);
-
-/* Return PID for the process associated with DWFL. Function returns -1 if
- dwfl_attach_state was not called for DWFL. */
-pid_t dwfl_pid (Dwfl *dwfl)
- __nonnull_attribute__ (1);
-
-/* Return DWFL from which THREAD was created using dwfl_getthreads. */
-Dwfl *dwfl_thread_dwfl (Dwfl_Thread *thread)
- __nonnull_attribute__ (1);
-
-/* Return positive TID (thread ID) for THREAD. This function never fails. */
-pid_t dwfl_thread_tid (Dwfl_Thread *thread)
- __nonnull_attribute__ (1);
-
-/* Return thread for frame STATE. This function never fails. */
-Dwfl_Thread *dwfl_frame_thread (Dwfl_Frame *state)
- __nonnull_attribute__ (1);
-
-/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation.
- For every known continuous block of registers <FIRSTREG..FIRSTREG+NREGS)
- (inclusive..exclusive) set their content to REGS (array of NREGS items).
- Function returns false if any of the registers has invalid number. */
-bool dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg,
- unsigned nregs, const Dwarf_Word *regs)
- __nonnull_attribute__ (1, 4);
-
-/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation.
- If PC is not contained among DWARF registers passed by
- dwfl_thread_state_registers on the target architecture pass the PC value
- here. */
-void dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
- __nonnull_attribute__ (1);
-
-/* Iterate through the threads for a process. Returns zero if all threads have
- been processed by the callback, returns -1 on error, or the value of the
- callback when not DWARF_CB_OK. -1 returned on error will set dwfl_errno ().
- Keeps calling the callback with the next thread while the callback returns
- DWARF_CB_OK, till there are no more threads. */
-int dwfl_getthreads (Dwfl *dwfl,
- int (*callback) (Dwfl_Thread *thread, void *arg),
- void *arg)
- __nonnull_attribute__ (1, 2);
-
-/* Iterate through the frames for a thread. Returns zero if all frames
- have been processed by the callback, returns -1 on error, or the value of
- the callback when not DWARF_CB_OK. -1 returned on error will
- set dwfl_errno (). Some systems return error instead of zero on end of the
- backtrace, for cross-platform compatibility callers should consider error as
- a zero. Keeps calling the callback with the next frame while the callback
- returns DWARF_CB_OK, till there are no more frames. On start will call the
- set_initial_registers callback and on return will call the detach_thread
- callback of the Dwfl_Thread. */
-int dwfl_thread_getframes (Dwfl_Thread *thread,
- int (*callback) (Dwfl_Frame *state, void *arg),
- void *arg)
- __nonnull_attribute__ (1, 2);
-
-/* Like dwfl_thread_getframes, but specifying the thread by its unique
- identifier number. Returns zero if all frames have been processed
- by the callback, returns -1 on error (and when no thread with
- the given thread id number exists), or the value of the callback
- when not DWARF_CB_OK. -1 returned on error will set dwfl_errno (). */
-int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
- int (*callback) (Dwfl_Frame *thread, void *arg),
- void *arg)
- __nonnull_attribute__ (1, 3);
-
-/* Return *PC (program counter) for thread-specific frame STATE.
- Set *ISACTIVATION according to DWARF frame "activation" definition.
- Typically you need to substract 1 from *PC if *ACTIVATION is false to safely
- find function of the caller. ACTIVATION may be NULL. PC must not be NULL.
- Function returns false if it failed to find *PC. */
-bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation)
- __nonnull_attribute__ (1, 2);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* libdwfl.h */
diff --git a/src/libdwfl/libdwflP.h b/src/libdwfl/libdwflP.h
deleted file mode 100644
index 12ee116e..00000000
--- a/src/libdwfl/libdwflP.h
+++ /dev/null
@@ -1,760 +0,0 @@
-/* Internal definitions for libdwfl.
- Copyright (C) 2005-2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifndef _LIBDWFLP_H
-#define _LIBDWFLP_H 1
-
-#ifndef PACKAGE_NAME
-# include <config.h>
-#endif
-#include <libdwfl.h>
-#include <libebl.h>
-#include <assert.h>
-#include <dirent.h>
-#include <errno.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../libdw/libdwP.h" /* We need its INTDECLs. */
-#include "../libdwelf/libdwelfP.h"
-
-typedef struct Dwfl_Process Dwfl_Process;
-
-/* gettext helper macros. */
-#define _(Str) dgettext ("elfutils", Str)
-
-#define DWFL_ERRORS \
- DWFL_ERROR (NOERROR, N_("no error")) \
- DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error")) \
- DWFL_ERROR (NOMEM, N_("out of memory")) \
- DWFL_ERROR (ERRNO, N_("See errno")) \
- DWFL_ERROR (LIBELF, N_("See elf_errno")) \
- DWFL_ERROR (LIBDW, N_("See dwarf_errno")) \
- DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)")) \
- DWFL_ERROR (ZLIB, N_("gzip decompression failed")) \
- DWFL_ERROR (BZLIB, N_("bzip2 decompression failed")) \
- DWFL_ERROR (LZMA, N_("LZMA decompression failed")) \
- DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine")) \
- DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file")) \
- DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type")) \
- DWFL_ERROR (BADRELOFF, N_("r_offset is bogus")) \
- DWFL_ERROR (BADSTROFF, N_("offset out of range")) \
- DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol")) \
- DWFL_ERROR (CB, N_("Callback returned failure")) \
- DWFL_ERROR (NO_DWARF, N_("No DWARF information found")) \
- DWFL_ERROR (NO_SYMTAB, N_("No symbol table found")) \
- DWFL_ERROR (NO_PHDR, N_("No ELF program headers")) \
- DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module")) \
- DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range")) \
- DWFL_ERROR (NO_MATCH, N_("no matching address range")) \
- DWFL_ERROR (TRUNCATED, N_("image truncated")) \
- DWFL_ERROR (ALREADY_ELF, N_("ELF file opened")) \
- DWFL_ERROR (BADELF, N_("not a valid ELF file")) \
- DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description")) \
- DWFL_ERROR (WRONG_ID_ELF, N_("ELF file does not match build ID")) \
- DWFL_ERROR (BAD_PRELINK, N_("corrupt .gnu.prelink_undo section data")) \
- DWFL_ERROR (LIBEBL_BAD, N_("Internal error due to ebl")) \
- DWFL_ERROR (CORE_MISSING, N_("Missing data in core file")) \
- DWFL_ERROR (INVALID_REGISTER, N_("Invalid register")) \
- DWFL_ERROR (PROCESS_MEMORY_READ, N_("Error reading process memory")) \
- DWFL_ERROR (PROCESS_NO_ARCH, N_("Couldn't find architecture of any ELF")) \
- DWFL_ERROR (PARSE_PROC, N_("Error parsing /proc filesystem")) \
- DWFL_ERROR (INVALID_DWARF, N_("Invalid DWARF")) \
- DWFL_ERROR (UNSUPPORTED_DWARF, N_("Unsupported DWARF")) \
- DWFL_ERROR (NEXT_THREAD_FAIL, N_("Unable to find more threads")) \
- DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state")) \
- DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state")) \
- DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \
- DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument")) \
- DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file"))
-
-#define DWFL_ERROR(name, text) DWFL_E_##name,
-typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
-#undef DWFL_ERROR
-
-#define OTHER_ERROR(name) ((unsigned int) DWFL_E_##name << 16)
-#define DWFL_E(name, errno) (OTHER_ERROR (name) | (errno))
-
-extern int __libdwfl_canon_error (Dwfl_Error) internal_function;
-extern void __libdwfl_seterrno (Dwfl_Error) internal_function;
-
-struct Dwfl
-{
- const Dwfl_Callbacks *callbacks;
-
- Dwfl_Module *modulelist; /* List in order used by full traversals. */
-
- Dwfl_Process *process;
- Dwfl_Error attacherr; /* Previous error attaching process. */
-
- GElf_Addr offline_next_address;
-
- GElf_Addr segment_align; /* Smallest granularity of segments. */
-
- /* Binary search table in three parallel malloc'd arrays. */
- size_t lookup_elts; /* Elements in use. */
- size_t lookup_alloc; /* Elements allococated. */
- GElf_Addr *lookup_addr; /* Start address of segment. */
- Dwfl_Module **lookup_module; /* Module associated with segment, or null. */
- int *lookup_segndx; /* User segment index, or -1. */
-
- /* Cache from last dwfl_report_segment call. */
- const void *lookup_tail_ident;
- GElf_Off lookup_tail_vaddr;
- GElf_Off lookup_tail_offset;
- int lookup_tail_ndx;
-
- char *executable_for_core; /* --executable if --core was specified. */
-};
-
-#define OFFLINE_REDZONE 0x10000
-
-struct dwfl_file
-{
- char *name;
- int fd;
- bool valid; /* The build ID note has been matched. */
- bool relocated; /* Partial relocation of all sections done. */
-
- Elf *elf;
-
- /* This is the lowest p_vaddr in this ELF file, aligned to p_align.
- For a file without phdrs, this is zero. */
- GElf_Addr vaddr;
-
- /* This is an address chosen for synchronization between the main file
- and the debug file. See dwfl_module_getdwarf.c for how it's chosen. */
- GElf_Addr address_sync;
-};
-
-struct Dwfl_Module
-{
- Dwfl *dwfl;
- struct Dwfl_Module *next; /* Link on Dwfl.modulelist. */
-
- void *userdata;
-
- char *name; /* Iterator name for this module. */
- GElf_Addr low_addr, high_addr;
-
- struct dwfl_file main, debug, aux_sym;
- GElf_Addr main_bias;
- Ebl *ebl;
- GElf_Half e_type; /* GElf_Ehdr.e_type cache. */
- Dwfl_Error elferr; /* Previous failure to open main file. */
-
- struct dwfl_relocation *reloc_info; /* Relocatable sections. */
-
- struct dwfl_file *symfile; /* Either main or debug. */
- Elf_Data *symdata; /* Data in the ELF symbol table section. */
- Elf_Data *aux_symdata; /* Data in the auxiliary ELF symbol table. */
- size_t syments; /* sh_size / sh_entsize of that section. */
- size_t aux_syments; /* sh_size / sh_entsize of aux_sym section. */
- int first_global; /* Index of first global symbol of table. */
- int aux_first_global; /* Index of first global of aux_sym table. */
- Elf_Data *symstrdata; /* Data for its string table. */
- Elf_Data *aux_symstrdata; /* Data for aux_sym string table. */
- Elf_Data *symxndxdata; /* Data in the extended section index table. */
- Elf_Data *aux_symxndxdata; /* Data in the extended auxiliary table. */
-
- Dwarf *dw; /* libdw handle for its debugging info. */
- Dwarf *alt; /* Dwarf used for dwarf_setalt, or NULL. */
- int alt_fd; /* descriptor, only valid when alt != NULL. */
- Elf *alt_elf; /* Elf for alt Dwarf. */
-
- Dwfl_Error symerr; /* Previous failure to load symbols. */
- Dwfl_Error dwerr; /* Previous failure to load DWARF. */
-
- /* Known CU's in this module. */
- struct dwfl_cu *first_cu, **cu;
-
- void *lazy_cu_root; /* Table indexed by Dwarf_Off of CU. */
-
- struct dwfl_arange *aranges; /* Mapping of addresses in module to CUs. */
-
- void *build_id_bits; /* malloc'd copy of build ID bits. */
- GElf_Addr build_id_vaddr; /* Address where they reside, 0 if unknown. */
- int build_id_len; /* -1 for prior failure, 0 if unset. */
-
- unsigned int ncu;
- unsigned int lazycu; /* Possible users, deleted when none left. */
- unsigned int naranges;
-
- Dwarf_CFI *dwarf_cfi; /* Cached DWARF CFI for this module. */
- Dwarf_CFI *eh_cfi; /* Cached EH CFI for this module. */
-
- int segment; /* Index of first segment table entry. */
- bool gc; /* Mark/sweep flag. */
- bool is_executable; /* Use Dwfl::executable_for_core? */
-};
-
-/* This holds information common for all the threads/tasks/TIDs of one process
- for backtraces. */
-
-struct Dwfl_Process
-{
- struct Dwfl *dwfl;
- pid_t pid;
- const Dwfl_Thread_Callbacks *callbacks;
- void *callbacks_arg;
- struct ebl *ebl;
- bool ebl_close:1;
-};
-
-/* See its typedef in libdwfl.h. */
-
-struct Dwfl_Thread
-{
- Dwfl_Process *process;
- pid_t tid;
- /* The current frame being unwound. Initially it is the bottom frame.
- Later the processed frames get freed and this pointer is updated. */
- Dwfl_Frame *unwound;
- void *callbacks_arg;
-};
-
-/* See its typedef in libdwfl.h. */
-
-struct Dwfl_Frame
-{
- Dwfl_Thread *thread;
- /* Previous (outer) frame. */
- Dwfl_Frame *unwound;
- bool signal_frame : 1;
- bool initial_frame : 1;
- enum
- {
- /* This structure is still being initialized or there was an error
- initializing it. */
- DWFL_FRAME_STATE_ERROR,
- /* PC field is valid. */
- DWFL_FRAME_STATE_PC_SET,
- /* PC field is undefined, this means the next (inner) frame was the
- outermost frame. */
- DWFL_FRAME_STATE_PC_UNDEFINED
- } pc_state;
- /* Either initialized from appropriate REGS element or on some archs
- initialized separately as the return address has no DWARF register. */
- Dwarf_Addr pc;
- /* (1 << X) bitmask where 0 <= X < ebl_frame_nregs. */
- uint64_t regs_set[3];
- /* REGS array size is ebl_frame_nregs.
- REGS_SET tells which of the REGS are valid. */
- Dwarf_Addr regs[];
-};
-
-/* Fetch value from Dwfl_Frame->regs indexed by DWARF REGNO.
- No error code is set if the function returns FALSE. */
-bool __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno,
- Dwarf_Addr *val)
- internal_function;
-
-/* Store value to Dwfl_Frame->regs indexed by DWARF REGNO.
- No error code is set if the function returns FALSE. */
-bool __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno,
- Dwarf_Addr val)
- internal_function;
-
-/* Information cached about each CU in Dwfl_Module.dw. */
-struct dwfl_cu
-{
- /* This caches libdw information about the CU. It's also the
- address passed back to users, so we take advantage of the
- fact that it's placed first to cast back. */
- Dwarf_Die die;
-
- Dwfl_Module *mod; /* Pointer back to containing module. */
-
- struct dwfl_cu *next; /* CU immediately following in the file. */
-
- struct Dwfl_Lines *lines;
-};
-
-struct Dwfl_Lines
-{
- struct dwfl_cu *cu;
-
- /* This is what the opaque Dwfl_Line * pointers we pass to users are.
- We need to recover pointers to our struct dwfl_cu and a record in
- libdw's Dwarf_Line table. To minimize the memory used in addition
- to libdw's Dwarf_Lines buffer, we just point to our own index in
- this table, and have one pointer back to the CU. The indices here
- match those in libdw's Dwarf_CU.lines->info table. */
- struct Dwfl_Line
- {
- unsigned int idx; /* My index in the dwfl_cu.lines table. */
- } idx[0];
-};
-
-static inline struct dwfl_cu *
-dwfl_linecu_inline (const Dwfl_Line *line)
-{
- const struct Dwfl_Lines *lines = ((const void *) line
- - offsetof (struct Dwfl_Lines,
- idx[line->idx]));
- return lines->cu;
-}
-#define dwfl_linecu dwfl_linecu_inline
-
-static inline GElf_Addr
-dwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr)
-{
- return addr + mod->main_bias;
-}
-
-static inline GElf_Addr
-dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr)
-{
- return addr - mod->main_bias;
-}
-
-static inline Dwarf_Addr
-dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
-{
- return dwfl_adjusted_address (mod, (addr
- - mod->debug.address_sync
- + mod->main.address_sync));
-}
-
-static inline Dwarf_Addr
-dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
-{
- return (dwfl_deadjust_address (mod, addr)
- - mod->main.address_sync
- + mod->debug.address_sync);
-}
-
-static inline Dwarf_Addr
-dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
-{
- return dwfl_adjusted_address (mod, (addr
- - mod->aux_sym.address_sync
- + mod->main.address_sync));
-}
-
-static inline Dwarf_Addr
-dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
-{
- return (dwfl_deadjust_address (mod, addr)
- - mod->main.address_sync
- + mod->aux_sym.address_sync);
-}
-
-static inline GElf_Addr
-dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
-{
- if (symelf == mod->main.elf)
- return dwfl_adjusted_address (mod, addr);
- if (symelf == mod->debug.elf)
- return dwfl_adjusted_dwarf_addr (mod, addr);
- return dwfl_adjusted_aux_sym_addr (mod, addr);
-}
-
-static inline GElf_Addr
-dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
-{
- if (symelf == mod->main.elf)
- return dwfl_deadjust_address (mod, addr);
- if (symelf == mod->debug.elf)
- return dwfl_deadjust_dwarf_addr (mod, addr);
- return dwfl_deadjust_aux_sym_addr (mod, addr);
-}
-
-/* This describes a contiguous address range that lies in a single CU.
- We condense runs of Dwarf_Arange entries for the same CU into this. */
-struct dwfl_arange
-{
- struct dwfl_cu *cu;
- size_t arange; /* Index in Dwarf_Aranges. */
-};
-
-
-/* Structure used for keeping track of ptrace attaching a thread.
- Shared by linux-pid-attach and linux-proc-maps. If it has been setup
- then get the instance through __libdwfl_get_pid_arg. */
-struct __libdwfl_pid_arg
-{
- DIR *dir;
- /* It is 0 if not used. */
- pid_t tid_attached;
- /* Valid only if TID_ATTACHED is not zero. */
- bool tid_was_stopped;
- /* True if threads are ptrace stopped by caller. */
- bool assume_ptrace_stopped;
-};
-
-/* If DWfl is not NULL and a Dwfl_Process has been setup that has
- Dwfl_Thread_Callbacks set to pid_thread_callbacks, then return the
- callbacks_arg, which will be a struct __libdwfl_pid_arg. Otherwise
- returns NULL. */
-extern struct __libdwfl_pid_arg *__libdwfl_get_pid_arg (Dwfl *dwfl)
- internal_function;
-
-/* Makes sure the given tid is attached. On success returns true and
- sets tid_was_stopped. */
-extern bool __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
- internal_function;
-
-/* Detaches a tid that was attached through
- __libdwfl_ptrace_attach. Must be given the tid_was_stopped as set
- by __libdwfl_ptrace_attach. */
-extern void __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
- internal_function;
-
-
-/* Internal wrapper for old dwfl_module_getsym and new dwfl_module_getsym_info.
- adjust_st_value set to true returns adjusted SYM st_value, set to false
- it will not adjust SYM at all, but does match against resolved *ADDR. */
-extern const char *__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym,
- GElf_Addr *addr, GElf_Word *shndxp,
- Elf **elfp, Dwarf_Addr *biasp,
- bool *resolved, bool adjust_st_value)
- internal_function;
-
-/* Internal wrapper for old dwfl_module_addrsym and new dwfl_module_addrinfo.
- adjust_st_value set to true returns adjusted SYM st_value, set to false
- it will not adjust SYM at all, but does match against resolved values. */
-extern const char *__libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr,
- GElf_Off *off, GElf_Sym *sym,
- GElf_Word *shndxp, Elf **elfp,
- Dwarf_Addr *bias,
- bool adjust_st_value) internal_function;
-
-extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
-
-/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf. */
-extern void __libdwfl_getelf (Dwfl_Module *mod) internal_function;
-
-/* Process relocations in debugging sections in an ET_REL file.
- FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ,
- to make it possible to relocate the data in place (or ELF_C_RDWR or
- ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk). After
- this, dwarf_begin_elf on FILE will read the relocated data.
-
- When DEBUG is false, apply partial relocation to all sections. */
-extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug)
- internal_function;
-
-/* Find the section index in mod->main.elf that contains the given
- *ADDR. Adjusts *ADDR to be section relative on success, returns
- SHN_UNDEF on failure. */
-extern size_t __libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr)
- internal_function;
-
-/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file.
- RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section. */
-extern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
- Elf_Scn *relocscn, Elf_Scn *tscn,
- bool partial)
- internal_function;
-
-/* Adjust *VALUE from section-relative to absolute.
- MOD->dwfl->callbacks->section_address is called to determine the actual
- address of a loaded section. */
-extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf,
- size_t *shstrndx_cache,
- Elf32_Word shndx,
- GElf_Addr *value)
- internal_function;
-
-/* Ensure that MOD->ebl is set up. */
-extern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function;
-
-/* Install a new Dwarf_CFI in *SLOT (MOD->eh_cfi or MOD->dwarf_cfi). */
-extern Dwarf_CFI *__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot,
- Dwarf_CFI *cfi)
- internal_function;
-
-/* Iterate through all the CU's in the module. Start by passing a null
- LASTCU, and then pass the last *CU returned. Success return with null
- *CU no more CUs. */
-extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
- struct dwfl_cu **cu) internal_function;
-
-/* Find the CU by address. */
-extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr,
- struct dwfl_cu **cu) internal_function;
-
-/* Ensure that CU->lines (and CU->cu->lines) is set up. */
-extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu)
- internal_function;
-
-/* Look in ELF for an NT_GNU_BUILD_ID note. Store it to BUILD_ID_BITS,
- its vaddr in ELF to BUILD_ID_VADDR (it is unrelocated, even if MOD is not
- NULL) and store length to BUILD_ID_LEN. Returns -1 for errors, 1 if it was
- stored and 0 if no note is found. MOD may be NULL, MOD must be non-NULL
- only if ELF is ET_REL. */
-extern int __libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf,
- const void **build_id_bits,
- GElf_Addr *build_id_elfaddr,
- int *build_id_len)
- internal_function;
-
-/* Look in ELF for an NT_GNU_BUILD_ID note. If SET is true, store it
- in MOD and return its length. If SET is false, instead compare it
- to that stored in MOD and return 2 if they match, 1 if they do not.
- Returns -1 for errors, 0 if no note is found. */
-extern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
- internal_function;
-
-/* Open a main or debuginfo file by its build ID, returns the fd. */
-extern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug,
- char **file_name) internal_function;
-
-/* Same, but takes an explicit build_id, can also be used for alt debug. */
-extern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug,
- char **file_name, const size_t id_len,
- const uint8_t *id) internal_function;
-
-extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len)
- attribute_hidden;
-extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden;
-
-
-/* Given ELF and some parameters return TRUE if the *P return value parameters
- have been successfully filled in. Any of the *P parameters can be NULL. */
-extern bool __libdwfl_elf_address_range (Elf *elf, GElf_Addr base,
- bool add_p_vaddr, bool sanity,
- GElf_Addr *vaddrp,
- GElf_Addr *address_syncp,
- GElf_Addr *startp, GElf_Addr *endp,
- GElf_Addr *biasp, GElf_Half *e_typep)
- internal_function;
-
-/* Meat of dwfl_report_elf, given elf_begin just called.
- Consumes ELF on success, not on failure. */
-extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name,
- const char *file_name, int fd,
- Elf *elf, GElf_Addr base,
- bool add_p_vaddr, bool sanity)
- internal_function;
-
-/* Meat of dwfl_report_offline. */
-extern Dwfl_Module *__libdwfl_report_offline (Dwfl *dwfl, const char *name,
- const char *file_name,
- int fd, bool closefd,
- int (*predicate) (const char *,
- const char *))
- internal_function;
-
-/* Free PROCESS. Unlink and free also any structures it references. */
-extern void __libdwfl_process_free (Dwfl_Process *process)
- internal_function;
-
-/* Update STATE->unwound for the unwound frame.
- On error STATE->unwound == NULL
- or STATE->unwound->pc_state == DWFL_FRAME_STATE_ERROR;
- in such case dwfl_errno () is set.
- If STATE->unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED
- then STATE was the last valid frame. */
-extern void __libdwfl_frame_unwind (Dwfl_Frame *state)
- internal_function;
-
-/* Align segment START downwards or END upwards addresses according to DWFL. */
-extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
- internal_function;
-extern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end)
- internal_function;
-
-/* Decompression wrappers: decompress whole file into memory. */
-extern Dwfl_Error __libdw_gunzip (int fd, off64_t start_offset,
- void *mapped, size_t mapped_size,
- void **whole, size_t *whole_size)
- internal_function;
-extern Dwfl_Error __libdw_bunzip2 (int fd, off64_t start_offset,
- void *mapped, size_t mapped_size,
- void **whole, size_t *whole_size)
- internal_function;
-extern Dwfl_Error __libdw_unlzma (int fd, off64_t start_offset,
- void *mapped, size_t mapped_size,
- void **whole, size_t *whole_size)
- internal_function;
-
-/* Skip the image header before a file image: updates *START_OFFSET. */
-extern Dwfl_Error __libdw_image_header (int fd, off64_t *start_offset,
- void *mapped, size_t mapped_size)
- internal_function;
-
-/* Open Elf handle on *FDP. This handles decompression and checks
- elf_kind. Succeed only for ELF_K_ELF, or also ELF_K_AR if ARCHIVE_OK.
- Returns DWFL_E_NOERROR and sets *ELFP on success, resets *FDP to -1 if
- it's no longer used. Resets *FDP on failure too iff CLOSE_ON_FAIL. */
-extern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp,
- bool close_on_fail, bool archive_ok)
- internal_function;
-
-/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP. Return success.
- *VADDRP is not modified if the function fails. */
-extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
- internal_function;
-
-/* These are working nicely for --core, but are not ready to be
- exported interfaces quite yet. */
-
-/* Type of callback function ...
- */
-typedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx,
- void **buffer, size_t *buffer_available,
- GElf_Addr vaddr, size_t minread, void *arg);
-
-/* Type of callback function ...
- */
-typedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata,
- const char *name, Dwarf_Addr base,
- void **buffer, size_t *buffer_available,
- GElf_Off cost, GElf_Off worthwhile,
- GElf_Off whole, GElf_Off contiguous,
- void *arg, Elf **elfp);
-
-/* One shared library (or executable) info from DT_DEBUG link map. */
-struct r_debug_info_module
-{
- struct r_debug_info_module *next;
- /* FD is -1 iff ELF is NULL. */
- int fd;
- Elf *elf;
- GElf_Addr l_ld;
- /* START and END are both zero if not valid. */
- GElf_Addr start, end;
- bool disk_file_has_build_id;
- char name[0];
-};
-
-/* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to
- dwfl_segment_report_module. */
-struct r_debug_info
-{
- struct r_debug_info_module *module;
-};
-
-/* ...
- */
-extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg,
- Dwfl_Module_Callback *read_eagerly,
- void *read_eagerly_arg,
- const void *note_file,
- size_t note_file_size,
- const struct r_debug_info *r_debug_info);
-
-/* Report a module for entry in the dynamic linker's struct link_map list.
- For each link_map entry, if an existing module resides at its address,
- this just modifies that module's name and suggested file name. If
- no such module exists, this calls dwfl_report_elf on the l_name string.
-
- If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector
- data as contained in an NT_AUXV note or read from a /proc/pid/auxv
- file. When this is available, it guides the search. If AUXV is null
- or the memory it points to is not accessible, then this search can
- only find where to begin if the correct executable file was
- previously reported and preloaded as with dwfl_report_elf.
-
- Fill in R_DEBUG_INFO if it is not NULL. It should be cleared by the
- caller, this function does not touch fields it does not need to modify.
- If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller
- has to add them from filled in R_DEBUG_INFO.
-
- Returns the number of modules found, or -1 for errors. */
-extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg,
- struct r_debug_info *r_debug_info);
-
-
-/* Avoid PLT entries. */
-INTDECL (dwfl_begin)
-INTDECL (dwfl_errmsg)
-INTDECL (dwfl_errno)
-INTDECL (dwfl_addrmodule)
-INTDECL (dwfl_addrsegment)
-INTDECL (dwfl_addrdwarf)
-INTDECL (dwfl_addrdie)
-INTDECL (dwfl_core_file_attach)
-INTDECL (dwfl_core_file_report)
-INTDECL (dwfl_getmodules)
-INTDECL (dwfl_module_addrdie)
-INTDECL (dwfl_module_address_section)
-INTDECL (dwfl_module_addrinfo)
-INTDECL (dwfl_module_addrsym)
-INTDECL (dwfl_module_build_id)
-INTDECL (dwfl_module_getdwarf)
-INTDECL (dwfl_module_getelf)
-INTDECL (dwfl_module_getsym)
-INTDECL (dwfl_module_getsym_info)
-INTDECL (dwfl_module_getsymtab)
-INTDECL (dwfl_module_getsymtab_first_global)
-INTDECL (dwfl_module_getsrc)
-INTDECL (dwfl_module_report_build_id)
-INTDECL (dwfl_report_elf)
-INTDECL (dwfl_report_begin)
-INTDECL (dwfl_report_begin_add)
-INTDECL (dwfl_report_module)
-INTDECL (dwfl_report_segment)
-INTDECL (dwfl_report_offline)
-INTDECL (dwfl_report_end)
-INTDECL (dwfl_build_id_find_elf)
-INTDECL (dwfl_build_id_find_debuginfo)
-INTDECL (dwfl_standard_find_debuginfo)
-INTDECL (dwfl_link_map_report)
-INTDECL (dwfl_linux_kernel_find_elf)
-INTDECL (dwfl_linux_kernel_module_section_address)
-INTDECL (dwfl_linux_proc_attach)
-INTDECL (dwfl_linux_proc_report)
-INTDECL (dwfl_linux_proc_maps_report)
-INTDECL (dwfl_linux_proc_find_elf)
-INTDECL (dwfl_linux_kernel_report_kernel)
-INTDECL (dwfl_linux_kernel_report_modules)
-INTDECL (dwfl_linux_kernel_report_offline)
-INTDECL (dwfl_offline_section_address)
-INTDECL (dwfl_module_relocate_address)
-INTDECL (dwfl_module_dwarf_cfi)
-INTDECL (dwfl_module_eh_cfi)
-INTDECL (dwfl_attach_state)
-INTDECL (dwfl_pid)
-INTDECL (dwfl_thread_dwfl)
-INTDECL (dwfl_thread_tid)
-INTDECL (dwfl_frame_thread)
-INTDECL (dwfl_thread_state_registers)
-INTDECL (dwfl_thread_state_register_pc)
-INTDECL (dwfl_getthread_frames)
-INTDECL (dwfl_getthreads)
-INTDECL (dwfl_thread_getframes)
-INTDECL (dwfl_frame_pc)
-
-/* Leading arguments standard to callbacks passed a Dwfl_Module. */
-#define MODCB_ARGS(mod) (mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
-#define CBFAIL (errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
-
-
-/* The default used by dwfl_standard_find_debuginfo. */
-#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
-
-
-#endif /* libdwflP.h */
diff --git a/src/libdwfl/libdwfl_crc32.c b/src/libdwfl/libdwfl_crc32.c
deleted file mode 100644
index b89d0d36..00000000
--- a/src/libdwfl/libdwfl_crc32.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright (C) 2002, 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define crc32 attribute_hidden __libdwfl_crc32
-#define LIB_SYSTEM_H 1
-#include <libdwflP.h>
-#include "../lib/crc32.c"
diff --git a/src/libdwfl/libdwfl_crc32_file.c b/src/libdwfl/libdwfl_crc32_file.c
deleted file mode 100644
index 6b6b7d3f..00000000
--- a/src/libdwfl/libdwfl_crc32_file.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 2002, 2005 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define crc32_file attribute_hidden __libdwfl_crc32_file
-#define crc32 __libdwfl_crc32
-#define LIB_SYSTEM_H 1
-#include <libdwflP.h>
-#include "../lib/crc32_file.c"
diff --git a/src/libdwfl/lines.c b/src/libdwfl/lines.c
deleted file mode 100644
index 721e29cc..00000000
--- a/src/libdwfl/lines.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Fetch source line info for CU.
- Copyright (C) 2005, 2006 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include "../libdw/libdwP.h"
-
-Dwfl_Error
-internal_function
-__libdwfl_cu_getsrclines (struct dwfl_cu *cu)
-{
- if (cu->lines == NULL)
- {
- Dwarf_Lines *lines;
- size_t nlines;
- if (INTUSE(dwarf_getsrclines) (&cu->die, &lines, &nlines) != 0)
- return DWFL_E_LIBDW;
-
- cu->lines = malloc (offsetof (struct Dwfl_Lines, idx[nlines]));
- if (cu->lines == NULL)
- return DWFL_E_NOMEM;
- cu->lines->cu = cu;
- for (unsigned int i = 0; i < nlines; ++i)
- cu->lines->idx[i].idx = i;
- }
-
- return DWFL_E_NOERROR;
-}
diff --git a/src/libdwfl/link_map.c b/src/libdwfl/link_map.c
deleted file mode 100644
index eaf43b57..00000000
--- a/src/libdwfl/link_map.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/* Report modules by examining dynamic linker data structures.
- Copyright (C) 2008-2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include "libdwflP.h"
-#include "../libdw/memory-access.h"
-#include "system.h"
-
-#include <byteswap.h>
-#include <endian.h>
-#include <fcntl.h>
-
-/* This element is always provided and always has a constant value.
- This makes it an easy thing to scan for to discern the format. */
-#define PROBE_TYPE AT_PHENT
-#define PROBE_VAL32 sizeof (Elf32_Phdr)
-#define PROBE_VAL64 sizeof (Elf64_Phdr)
-
-
-/* Examine an auxv data block and determine its format.
- Return true iff we figured it out. */
-static bool
-auxv_format_probe (const void *auxv, size_t size,
- uint_fast8_t *elfclass, uint_fast8_t *elfdata)
-{
- const union
- {
- char buf[size];
- Elf32_auxv_t a32[size / sizeof (Elf32_auxv_t)];
- Elf64_auxv_t a64[size / sizeof (Elf64_auxv_t)];
- } *u = auxv;
-
- inline bool check64 (size_t i)
- {
- /* The AUXV pointer might not even be naturally aligned for 64-bit
- data, because note payloads in a core file are not aligned.
- But we assume the data is 32-bit aligned. */
-
- uint64_t type = read_8ubyte_unaligned_noncvt (&u->a64[i].a_type);
- uint64_t val = read_8ubyte_unaligned_noncvt (&u->a64[i].a_un.a_val);
-
- if (type == BE64 (PROBE_TYPE)
- && val == BE64 (PROBE_VAL64))
- {
- *elfdata = ELFDATA2MSB;
- return true;
- }
-
- if (type == LE64 (PROBE_TYPE)
- && val == LE64 (PROBE_VAL64))
- {
- *elfdata = ELFDATA2LSB;
- return true;
- }
-
- return false;
- }
-
- inline bool check32 (size_t i)
- {
- if (u->a32[i].a_type == BE32 (PROBE_TYPE)
- && u->a32[i].a_un.a_val == BE32 (PROBE_VAL32))
- {
- *elfdata = ELFDATA2MSB;
- return true;
- }
-
- if (u->a32[i].a_type == LE32 (PROBE_TYPE)
- && u->a32[i].a_un.a_val == LE32 (PROBE_VAL32))
- {
- *elfdata = ELFDATA2LSB;
- return true;
- }
-
- return false;
- }
-
- for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i)
- {
- if (check64 (i))
- {
- *elfclass = ELFCLASS64;
- return true;
- }
-
- if (check32 (i * 2) || check32 (i * 2 + 1))
- {
- *elfclass = ELFCLASS32;
- return true;
- }
- }
-
- return false;
-}
-
-/* This is a Dwfl_Memory_Callback that wraps another memory callback.
- If the underlying callback cannot fill the data, then this will
- fall back to fetching data from module files. */
-
-struct integrated_memory_callback
-{
- Dwfl_Memory_Callback *memory_callback;
- void *memory_callback_arg;
- void *buffer;
-};
-
-static bool
-integrated_memory_callback (Dwfl *dwfl, int ndx,
- void **buffer, size_t *buffer_available,
- GElf_Addr vaddr,
- size_t minread,
- void *arg)
-{
- struct integrated_memory_callback *info = arg;
-
- if (ndx == -1)
- {
- /* Called for cleanup. */
- if (info->buffer != NULL)
- {
- /* The last probe buffer came from the underlying callback.
- Let it do its cleanup. */
- assert (*buffer == info->buffer); /* XXX */
- *buffer = info->buffer;
- info->buffer = NULL;
- return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available,
- vaddr, minread,
- info->memory_callback_arg);
- }
- *buffer = NULL;
- *buffer_available = 0;
- return false;
- }
-
- if (*buffer != NULL)
- /* For a final-read request, we only use the underlying callback. */
- return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available,
- vaddr, minread, info->memory_callback_arg);
-
- /* Let the underlying callback try to fill this request. */
- if ((*info->memory_callback) (dwfl, ndx, &info->buffer, buffer_available,
- vaddr, minread, info->memory_callback_arg))
- {
- *buffer = info->buffer;
- return true;
- }
-
- /* Now look for module text covering this address. */
-
- Dwfl_Module *mod;
- (void) INTUSE(dwfl_addrsegment) (dwfl, vaddr, &mod);
- if (mod == NULL)
- return false;
-
- Dwarf_Addr bias;
- Elf_Scn *scn = INTUSE(dwfl_module_address_section) (mod, &vaddr, &bias);
- if (unlikely (scn == NULL))
- {
-#if 0 // XXX would have to handle ndx=-1 cleanup calls passed down.
- /* If we have no sections we can try to fill it from the module file
- based on its phdr mappings. */
- if (likely (mod->e_type != ET_REL) && mod->main.elf != NULL)
- return INTUSE(dwfl_elf_phdr_memory_callback)
- (dwfl, 0, buffer, buffer_available,
- vaddr - mod->main.bias, minread, mod->main.elf);
-#endif
- return false;
- }
-
- Elf_Data *data = elf_rawdata (scn, NULL);
- if (unlikely (data == NULL))
- // XXX throw error?
- return false;
-
- if (unlikely (data->d_size < vaddr))
- return false;
-
- /* Provide as much data as we have. */
- void *contents = data->d_buf + vaddr;
- size_t avail = data->d_size - vaddr;
- if (unlikely (avail < minread))
- return false;
-
- /* If probing for a string, make sure it's terminated. */
- if (minread == 0 && unlikely (memchr (contents, '\0', avail) == NULL))
- return false;
-
- /* We have it! */
- *buffer = contents;
- *buffer_available = avail;
- return true;
-}
-
-static size_t
-addrsize (uint_fast8_t elfclass)
-{
- return elfclass * 4;
-}
-
-/* Report a module for each struct link_map in the linked list at r_map
- in the struct r_debug at R_DEBUG_VADDR. For r_debug_info description
- see dwfl_link_map_report in libdwflP.h. If R_DEBUG_INFO is not NULL then no
- modules get added to DWFL, caller has to add them from filled in
- R_DEBUG_INFO.
-
- For each link_map entry, if an existing module resides at its address,
- this just modifies that module's name and suggested file name. If
- no such module exists, this calls dwfl_report_elf on the l_name string.
-
- Returns the number of modules found, or -1 for errors. */
-
-static int
-report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
- Dwfl *dwfl, GElf_Addr r_debug_vaddr,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg,
- struct r_debug_info *r_debug_info)
-{
- /* Skip r_version, to aligned r_map field. */
- GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);
-
- void *buffer = NULL;
- size_t buffer_available = 0;
- inline int release_buffer (int result)
- {
- if (buffer != NULL)
- (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
- memory_callback_arg);
- return result;
- }
-
- GElf_Addr addrs[4];
- inline bool read_addrs (GElf_Addr vaddr, size_t n)
- {
- size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read. */
-
- /* Read a new buffer if the old one doesn't cover these words. */
- if (buffer == NULL
- || vaddr < read_vaddr
- || vaddr - read_vaddr + nb > buffer_available)
- {
- release_buffer (0);
-
- read_vaddr = vaddr;
- int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL);
- if (unlikely (segndx < 0)
- || unlikely (! (*memory_callback) (dwfl, segndx,
- &buffer, &buffer_available,
- vaddr, nb, memory_callback_arg)))
- return true;
- }
-
- const union
- {
- Elf32_Addr a32[n];
- Elf64_Addr a64[n];
- } *in = vaddr - read_vaddr + buffer;
-
- if (elfclass == ELFCLASS32)
- {
- if (elfdata == ELFDATA2MSB)
- for (size_t i = 0; i < n; ++i)
- addrs[i] = BE32 (in->a32[i]);
- else
- for (size_t i = 0; i < n; ++i)
- addrs[i] = LE32 (in->a32[i]);
- }
- else
- {
- if (elfdata == ELFDATA2MSB)
- for (size_t i = 0; i < n; ++i)
- addrs[i] = BE64 (in->a64[i]);
- else
- for (size_t i = 0; i < n; ++i)
- addrs[i] = LE64 (in->a64[i]);
- }
-
- return false;
- }
-
- if (unlikely (read_addrs (read_vaddr, 1)))
- return release_buffer (-1);
-
- GElf_Addr next = addrs[0];
-
- Dwfl_Module **lastmodp = &dwfl->modulelist;
- int result = 0;
-
- /* There can't be more elements in the link_map list than there are
- segments. DWFL->lookup_elts is probably twice that number, so it
- is certainly above the upper bound. If we iterate too many times,
- there must be a loop in the pointers due to link_map clobberation. */
- size_t iterations = 0;
- while (next != 0 && ++iterations < dwfl->lookup_elts)
- {
- if (read_addrs (next, 4))
- return release_buffer (-1);
-
- /* Unused: l_addr is the difference between the address in memory
- and the ELF file when the core was created. We need to
- recalculate the difference below because the ELF file we use
- might be differently pre-linked. */
- // GElf_Addr l_addr = addrs[0];
- GElf_Addr l_name = addrs[1];
- GElf_Addr l_ld = addrs[2];
- next = addrs[3];
-
- /* If a clobbered or truncated memory image has no useful pointer,
- just skip this element. */
- if (l_ld == 0)
- continue;
-
- /* Fetch the string at the l_name address. */
- const char *name = NULL;
- if (buffer != NULL
- && read_vaddr <= l_name
- && l_name + 1 - read_vaddr < buffer_available
- && memchr (l_name - read_vaddr + buffer, '\0',
- buffer_available - (l_name - read_vaddr)) != NULL)
- name = l_name - read_vaddr + buffer;
- else
- {
- release_buffer (0);
- read_vaddr = l_name;
- int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_name, NULL);
- if (likely (segndx >= 0)
- && (*memory_callback) (dwfl, segndx,
- &buffer, &buffer_available,
- l_name, 0, memory_callback_arg))
- name = buffer;
- }
-
- if (name != NULL && name[0] == '\0')
- name = NULL;
-
- if (iterations == 1 && dwfl->executable_for_core != NULL)
- name = dwfl->executable_for_core;
-
- struct r_debug_info_module *r_debug_info_module = NULL;
- if (r_debug_info != NULL)
- {
- /* Save link map information about valid shared library (or
- executable) which has not been found on disk. */
- const char *name1 = name == NULL ? "" : name;
- r_debug_info_module = malloc (sizeof (*r_debug_info_module)
- + strlen (name1) + 1);
- if (r_debug_info_module == NULL)
- return release_buffer (result);
- r_debug_info_module->fd = -1;
- r_debug_info_module->elf = NULL;
- r_debug_info_module->l_ld = l_ld;
- r_debug_info_module->start = 0;
- r_debug_info_module->end = 0;
- r_debug_info_module->disk_file_has_build_id = false;
- strcpy (r_debug_info_module->name, name1);
- r_debug_info_module->next = r_debug_info->module;
- r_debug_info->module = r_debug_info_module;
- }
-
- Dwfl_Module *mod = NULL;
- if (name != NULL)
- {
- /* This code is mostly inlined dwfl_report_elf. */
- // XXX hook for sysroot
- int fd = open64 (name, O_RDONLY);
- if (fd >= 0)
- {
- Elf *elf;
- Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
- GElf_Addr elf_dynamic_vaddr;
- if (error == DWFL_E_NOERROR
- && __libdwfl_dynamic_vaddr_get (elf, &elf_dynamic_vaddr))
- {
- const void *build_id_bits;
- GElf_Addr build_id_elfaddr;
- int build_id_len;
- bool valid = true;
-
- if (__libdwfl_find_elf_build_id (NULL, elf, &build_id_bits,
- &build_id_elfaddr,
- &build_id_len) > 0
- && build_id_elfaddr != 0)
- {
- if (r_debug_info_module != NULL)
- r_debug_info_module->disk_file_has_build_id = true;
- GElf_Addr build_id_vaddr = (build_id_elfaddr
- - elf_dynamic_vaddr + l_ld);
-
- release_buffer (0);
- int segndx = INTUSE(dwfl_addrsegment) (dwfl,
- build_id_vaddr,
- NULL);
- if (! (*memory_callback) (dwfl, segndx,
- &buffer, &buffer_available,
- build_id_vaddr, build_id_len,
- memory_callback_arg))
- {
- /* File has valid build-id which cannot be read from
- memory. This happens for core files without bit 4
- (0x10) set in Linux /proc/PID/coredump_filter. */
- }
- else
- {
- if (memcmp (build_id_bits, buffer, build_id_len) != 0)
- /* File has valid build-id which does not match
- the one in memory. */
- valid = false;
- release_buffer (0);
- }
- }
-
- if (valid)
- {
- // It is like l_addr but it handles differently prelinked
- // files at core dumping vs. core loading time.
- GElf_Addr base = l_ld - elf_dynamic_vaddr;
- if (r_debug_info_module == NULL)
- {
- // XXX hook for sysroot
- mod = __libdwfl_report_elf (dwfl, basename (name),
- name, fd, elf, base,
- true, true);
- if (mod != NULL)
- {
- elf = NULL;
- fd = -1;
- }
- }
- else if (__libdwfl_elf_address_range (elf, base, true,
- true, NULL, NULL,
- &r_debug_info_module->start,
- &r_debug_info_module->end,
- NULL, NULL))
- {
- r_debug_info_module->elf = elf;
- r_debug_info_module->fd = fd;
- elf = NULL;
- fd = -1;
- }
- }
- if (elf != NULL)
- elf_end (elf);
- if (fd != -1)
- close (fd);
- }
- }
- }
-
- if (mod != NULL)
- {
- ++result;
-
- /* Move this module to the end of the list, so that we end
- up with a list in the same order as the link_map chain. */
- if (mod->next != NULL)
- {
- if (*lastmodp != mod)
- {
- lastmodp = &dwfl->modulelist;
- while (*lastmodp != mod)
- lastmodp = &(*lastmodp)->next;
- }
- *lastmodp = mod->next;
- mod->next = NULL;
- while (*lastmodp != NULL)
- lastmodp = &(*lastmodp)->next;
- *lastmodp = mod;
- }
-
- lastmodp = &mod->next;
- }
- }
-
- return release_buffer (result);
-}
-
-static GElf_Addr
-consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry,
- uint_fast8_t *elfclass, uint_fast8_t *elfdata,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg)
-{
- GElf_Ehdr ehdr;
- if (unlikely (gelf_getehdr (mod->main.elf, &ehdr) == NULL))
- return 0;
-
- if (at_entry != 0)
- {
- /* If we have an AT_ENTRY value, reject this executable if
- its entry point address could not have supplied that. */
-
- if (ehdr.e_entry == 0)
- return 0;
-
- if (mod->e_type == ET_EXEC)
- {
- if (ehdr.e_entry != at_entry)
- return 0;
- }
- else
- {
- /* It could be a PIE. */
- }
- }
-
- // XXX this could be saved in the file cache: phdr vaddr, DT_DEBUG d_val vaddr
- /* Find the vaddr of the DT_DEBUG's d_ptr. This is the memory
- address where &r_debug was written at runtime. */
- GElf_Xword align = mod->dwfl->segment_align;
- GElf_Addr d_val_vaddr = 0;
- size_t phnum;
- if (elf_getphdrnum (mod->main.elf, &phnum) != 0)
- return 0;
-
- for (size_t i = 0; i < phnum; ++i)
- {
- GElf_Phdr phdr_mem;
- GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
- if (phdr == NULL)
- break;
-
- if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align))
- align = phdr->p_align;
-
- if (at_phdr != 0
- && phdr->p_type == PT_LOAD
- && (phdr->p_offset & -align) == (ehdr.e_phoff & -align))
- {
- /* This is the segment that would map the phdrs.
- If we have an AT_PHDR value, reject this executable
- if its phdr mapping could not have supplied that. */
- if (mod->e_type == ET_EXEC)
- {
- if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr)
- return 0;
- }
- else
- {
- /* It could be a PIE. If the AT_PHDR value and our
- phdr address don't match modulo ALIGN, then this
- could not have been the right PIE. */
- if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align)
- != (at_phdr & -align))
- return 0;
-
- /* Calculate the bias applied to the PIE's p_vaddr values. */
- GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset
- + phdr->p_vaddr));
-
- /* Final sanity check: if we have an AT_ENTRY value,
- reject this PIE unless its biased e_entry matches. */
- if (at_entry != 0 && at_entry != ehdr.e_entry + bias)
- return 0;
-
- /* If we're changing the module's address range,
- we've just invalidated the module lookup table. */
- GElf_Addr mod_bias = dwfl_adjusted_address (mod, 0);
- if (bias != mod_bias)
- {
- mod->low_addr -= mod_bias;
- mod->high_addr -= mod_bias;
- mod->low_addr += bias;
- mod->high_addr += bias;
-
- free (mod->dwfl->lookup_module);
- mod->dwfl->lookup_module = NULL;
- }
- }
- }
-
- if (phdr->p_type == PT_DYNAMIC)
- {
- Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset,
- phdr->p_filesz, ELF_T_DYN);
- if (data == NULL)
- continue;
- const size_t entsize = gelf_fsize (mod->main.elf,
- ELF_T_DYN, 1, EV_CURRENT);
- const size_t n = data->d_size / entsize;
- for (size_t j = 0; j < n; ++j)
- {
- GElf_Dyn dyn_mem;
- GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
- if (dyn != NULL && dyn->d_tag == DT_DEBUG)
- {
- d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2;
- break;
- }
- }
- }
- }
-
- if (d_val_vaddr != 0)
- {
- /* Now we have the final address from which to read &r_debug. */
- d_val_vaddr = dwfl_adjusted_address (mod, d_val_vaddr);
-
- void *buffer = NULL;
- size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]);
-
- int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, NULL);
-
- if ((*memory_callback) (mod->dwfl, segndx,
- &buffer, &buffer_available,
- d_val_vaddr, buffer_available,
- memory_callback_arg))
- {
- const union
- {
- Elf32_Addr a32;
- Elf64_Addr a64;
- } *u = buffer;
-
- GElf_Addr vaddr;
- if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
- vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
- ? BE32 (u->a32) : LE32 (u->a32));
- else
- vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
- ? BE64 (u->a64) : LE64 (u->a64));
-
- (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0,
- memory_callback_arg);
-
- if (*elfclass == ELFCLASSNONE)
- *elfclass = ehdr.e_ident[EI_CLASS];
- else if (*elfclass != ehdr.e_ident[EI_CLASS])
- return 0;
-
- if (*elfdata == ELFDATANONE)
- *elfdata = ehdr.e_ident[EI_DATA];
- else if (*elfdata != ehdr.e_ident[EI_DATA])
- return 0;
-
- return vaddr;
- }
- }
-
- return 0;
-}
-
-/* Try to find an existing executable module with a DT_DEBUG. */
-static GElf_Addr
-find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry,
- uint_fast8_t *elfclass, uint_fast8_t *elfdata,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg)
-{
- for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
- if (mod->main.elf != NULL)
- {
- GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry,
- elfclass, elfdata,
- memory_callback,
- memory_callback_arg);
- if (r_debug_vaddr != 0)
- return r_debug_vaddr;
- }
-
- return 0;
-}
-
-
-int
-dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
- Dwfl_Memory_Callback *memory_callback,
- void *memory_callback_arg,
- struct r_debug_info *r_debug_info)
-{
- GElf_Addr r_debug_vaddr = 0;
-
- uint_fast8_t elfclass = ELFCLASSNONE;
- uint_fast8_t elfdata = ELFDATANONE;
- if (likely (auxv != NULL)
- && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata)))
- {
- GElf_Addr entry = 0;
- GElf_Addr phdr = 0;
- GElf_Xword phent = 0;
- GElf_Xword phnum = 0;
-
-#define READ_AUXV32(ptr) read_4ubyte_unaligned_noncvt (ptr)
-#define READ_AUXV64(ptr) read_8ubyte_unaligned_noncvt (ptr)
-#define AUXV_SCAN(NN, BL) do \
- { \
- const Elf##NN##_auxv_t *av = auxv; \
- for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i) \
- { \
- uint##NN##_t type = READ_AUXV##NN (&av[i].a_type); \
- uint##NN##_t val = BL##NN (READ_AUXV##NN (&av[i].a_un.a_val)); \
- if (type == BL##NN (AT_ENTRY)) \
- entry = val; \
- else if (type == BL##NN (AT_PHDR)) \
- phdr = val; \
- else if (type == BL##NN (AT_PHNUM)) \
- phnum = val; \
- else if (type == BL##NN (AT_PHENT)) \
- phent = val; \
- else if (type == BL##NN (AT_PAGESZ)) \
- { \
- if (val > 1 \
- && (dwfl->segment_align == 0 \
- || val < dwfl->segment_align)) \
- dwfl->segment_align = val; \
- } \
- } \
- } \
- while (0)
-
- if (elfclass == ELFCLASS32)
- {
- if (elfdata == ELFDATA2MSB)
- AUXV_SCAN (32, BE);
- else
- AUXV_SCAN (32, LE);
- }
- else
- {
- if (elfdata == ELFDATA2MSB)
- AUXV_SCAN (64, BE);
- else
- AUXV_SCAN (64, LE);
- }
-
- /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC. */
- GElf_Addr dyn_vaddr = 0;
- GElf_Xword dyn_filesz = 0;
- GElf_Addr dyn_bias = (GElf_Addr) -1;
-
- inline bool consider_phdr (GElf_Word type,
- GElf_Addr vaddr, GElf_Xword filesz)
- {
- switch (type)
- {
- case PT_PHDR:
- if (dyn_bias == (GElf_Addr) -1
- /* Do a sanity check on the putative address. */
- && ((vaddr & (dwfl->segment_align - 1))
- == (phdr & (dwfl->segment_align - 1))))
- {
- dyn_bias = phdr - vaddr;
- return dyn_vaddr != 0;
- }
- break;
-
- case PT_DYNAMIC:
- dyn_vaddr = vaddr;
- dyn_filesz = filesz;
- return dyn_bias != (GElf_Addr) -1;
- }
-
- return false;
- }
-
- if (phdr != 0 && phnum != 0)
- {
- Dwfl_Module *phdr_mod;
- int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod);
- Elf_Data in =
- {
- .d_type = ELF_T_PHDR,
- .d_version = EV_CURRENT,
- .d_size = phnum * phent,
- .d_buf = NULL
- };
- bool in_ok = (*memory_callback) (dwfl, phdr_segndx, &in.d_buf,
- &in.d_size, phdr, phnum * phent,
- memory_callback_arg);
- if (! in_ok && dwfl->executable_for_core != NULL)
- {
- /* AUXV -> PHDR -> DYNAMIC
- Both AUXV and DYNAMIC should be always present in a core file.
- PHDR may be missing in core file, try to read it from
- EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the
- core file. */
-
- int fd = open (dwfl->executable_for_core, O_RDONLY);
- Elf *elf;
- Dwfl_Error error = DWFL_E_ERRNO;
- if (fd != -1)
- error = __libdw_open_file (&fd, &elf, true, false);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return false;
- }
- GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
- if (ehdr == NULL)
- {
- elf_end (elf);
- close (fd);
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return false;
- }
- size_t e_phnum;
- if (elf_getphdrnum (elf, &e_phnum) != 0)
- {
- elf_end (elf);
- close (fd);
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return false;
- }
- if (e_phnum != phnum || ehdr->e_phentsize != phent)
- {
- elf_end (elf);
- close (fd);
- __libdwfl_seterrno (DWFL_E_BADELF);
- return false;
- }
- off_t off = ehdr->e_phoff;
- assert (in.d_buf == NULL);
- assert (in.d_size == phnum * phent);
- in.d_buf = malloc (in.d_size);
- if (unlikely (in.d_buf == NULL))
- {
- elf_end (elf);
- close (fd);
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return false;
- }
- ssize_t nread = pread_retry (fd, in.d_buf, in.d_size, off);
- elf_end (elf);
- close (fd);
- if (nread != (ssize_t) in.d_size)
- {
- free (in.d_buf);
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
- }
- in_ok = true;
- }
- if (in_ok)
- {
- union
- {
- Elf32_Phdr p32;
- Elf64_Phdr p64;
- char data[phnum * phent];
- } buf;
- Elf_Data out =
- {
- .d_type = ELF_T_PHDR,
- .d_version = EV_CURRENT,
- .d_size = phnum * phent,
- .d_buf = &buf
- };
- in.d_size = out.d_size;
- if (likely ((elfclass == ELFCLASS32
- ? elf32_xlatetom : elf64_xlatetom)
- (&out, &in, elfdata) != NULL))
- {
- /* We are looking for PT_DYNAMIC. */
- const union
- {
- Elf32_Phdr p32[phnum];
- Elf64_Phdr p64[phnum];
- } *u = (void *) &buf;
- if (elfclass == ELFCLASS32)
- {
- for (size_t i = 0; i < phnum; ++i)
- if (consider_phdr (u->p32[i].p_type,
- u->p32[i].p_vaddr,
- u->p32[i].p_filesz))
- break;
- }
- else
- {
- for (size_t i = 0; i < phnum; ++i)
- if (consider_phdr (u->p64[i].p_type,
- u->p64[i].p_vaddr,
- u->p64[i].p_filesz))
- break;
- }
- }
-
- (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
- memory_callback_arg);
- }
- else
- /* We could not read the executable's phdrs from the
- memory image. If we have a presupplied executable,
- we can still use the AT_PHDR and AT_ENTRY values to
- verify it, and to adjust its bias if it's a PIE.
-
- If there was an ET_EXEC module presupplied that contains
- the AT_PHDR address, then we only consider that one.
- We'll either accept it if its phdr location and e_entry
- make sense or reject it if they don't. If there is no
- presupplied ET_EXEC, then look for a presupplied module,
- which might be a PIE (ET_DYN) that needs its bias adjusted. */
- r_debug_vaddr = ((phdr_mod == NULL
- || phdr_mod->main.elf == NULL
- || phdr_mod->e_type != ET_EXEC)
- ? find_executable (dwfl, phdr, entry,
- &elfclass, &elfdata,
- memory_callback,
- memory_callback_arg)
- : consider_executable (phdr_mod, phdr, entry,
- &elfclass, &elfdata,
- memory_callback,
- memory_callback_arg));
- }
-
- /* If we found PT_DYNAMIC, search it for DT_DEBUG. */
- if (dyn_filesz != 0)
- {
- if (dyn_bias != (GElf_Addr) -1)
- dyn_vaddr += dyn_bias;
-
- Elf_Data in =
- {
- .d_type = ELF_T_DYN,
- .d_version = EV_CURRENT,
- .d_size = dyn_filesz,
- .d_buf = NULL
- };
- int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL);
- if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
- dyn_vaddr, dyn_filesz, memory_callback_arg))
- {
- union
- {
- Elf32_Dyn d32;
- Elf64_Dyn d64;
- char data[dyn_filesz];
- } buf;
- Elf_Data out =
- {
- .d_type = ELF_T_DYN,
- .d_version = EV_CURRENT,
- .d_size = dyn_filesz,
- .d_buf = &buf
- };
- in.d_size = out.d_size;
- if (likely ((elfclass == ELFCLASS32
- ? elf32_xlatetom : elf64_xlatetom)
- (&out, &in, elfdata) != NULL))
- {
- /* We are looking for DT_DEBUG. */
- const union
- {
- Elf32_Dyn d32[dyn_filesz / sizeof (Elf32_Dyn)];
- Elf64_Dyn d64[dyn_filesz / sizeof (Elf64_Dyn)];
- } *u = (void *) &buf;
- if (elfclass == ELFCLASS32)
- {
- size_t n = dyn_filesz / sizeof (Elf32_Dyn);
- for (size_t i = 0; i < n; ++i)
- if (u->d32[i].d_tag == DT_DEBUG)
- {
- r_debug_vaddr = u->d32[i].d_un.d_val;
- break;
- }
- }
- else
- {
- size_t n = dyn_filesz / sizeof (Elf64_Dyn);
- for (size_t i = 0; i < n; ++i)
- if (u->d64[i].d_tag == DT_DEBUG)
- {
- r_debug_vaddr = u->d64[i].d_un.d_val;
- break;
- }
- }
- }
-
- (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
- memory_callback_arg);
- }
- }
- }
- else
- /* We have to look for a presupplied executable file to determine
- the vaddr of its dynamic section and DT_DEBUG therein. */
- r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata,
- memory_callback, memory_callback_arg);
-
- if (r_debug_vaddr == 0)
- return 0;
-
- /* For following pointers from struct link_map, we will use an
- integrated memory access callback that can consult module text
- elided from the core file. This is necessary when the l_name
- pointer for the dynamic linker's own entry is a pointer into the
- executable's .interp section. */
- struct integrated_memory_callback mcb =
- {
- .memory_callback = memory_callback,
- .memory_callback_arg = memory_callback_arg
- };
-
- /* Now we can follow the dynamic linker's library list. */
- return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr,
- &integrated_memory_callback, &mcb, r_debug_info);
-}
-INTDEF (dwfl_link_map_report)
diff --git a/src/libdwfl/linux-core-attach.c b/src/libdwfl/linux-core-attach.c
deleted file mode 100644
index 5a7b3b3d..00000000
--- a/src/libdwfl/linux-core-attach.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/* Get Dwarf Frame state for target core file.
- Copyright (C) 2013, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <fcntl.h>
-#include "system.h"
-
-#include "../libdw/memory-access.h"
-
-#ifndef MIN
-# define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-
-struct core_arg
-{
- Elf *core;
- Elf_Data *note_data;
- size_t thread_note_offset;
- Ebl *ebl;
-};
-
-struct thread_arg
-{
- struct core_arg *core_arg;
- size_t note_offset;
-};
-
-static bool
-core_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result,
- void *dwfl_arg)
-{
- Dwfl_Process *process = dwfl->process;
- struct core_arg *core_arg = dwfl_arg;
- Elf *core = core_arg->core;
- assert (core != NULL);
- static size_t phnum;
- if (elf_getphdrnum (core, &phnum) < 0)
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return false;
- }
- for (size_t cnt = 0; cnt < phnum; ++cnt)
- {
- GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem);
- if (phdr == NULL || phdr->p_type != PT_LOAD)
- continue;
- /* Bias is zero here, a core file itself has no bias. */
- GElf_Addr start = __libdwfl_segment_start (dwfl, phdr->p_vaddr);
- GElf_Addr end = __libdwfl_segment_end (dwfl,
- phdr->p_vaddr + phdr->p_memsz);
- unsigned bytes = ebl_get_elfclass (process->ebl) == ELFCLASS64 ? 8 : 4;
- if (addr < start || addr + bytes > end)
- continue;
- Elf_Data *data;
- data = elf_getdata_rawchunk (core, phdr->p_offset + addr - start,
- bytes, ELF_T_ADDR);
- if (data == NULL)
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- return false;
- }
- assert (data->d_size == bytes);
- if (bytes == 8)
- *result = read_8ubyte_unaligned_noncvt (data->d_buf);
- else
- *result = read_4ubyte_unaligned_noncvt (data->d_buf);
- return true;
- }
- __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
- return false;
-}
-
-static pid_t
-core_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
- void **thread_argp)
-{
- struct core_arg *core_arg = dwfl_arg;
- Elf *core = core_arg->core;
- GElf_Nhdr nhdr;
- size_t name_offset;
- size_t desc_offset;
- Elf_Data *note_data = core_arg->note_data;
- size_t offset;
-
- struct thread_arg *thread_arg;
- if (*thread_argp == NULL)
- {
- core_arg->thread_note_offset = 0;
- thread_arg = malloc (sizeof (*thread_arg));
- if (thread_arg == NULL)
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
- thread_arg->core_arg = core_arg;
- *thread_argp = thread_arg;
- }
- else
- thread_arg = (struct thread_arg *) *thread_argp;
-
- while (offset = core_arg->thread_note_offset, offset < note_data->d_size
- && (core_arg->thread_note_offset = gelf_getnote (note_data, offset,
- &nhdr, &name_offset,
- &desc_offset)) > 0)
- {
- /* Do not check NAME for now, help broken Linux kernels. */
- const char *name = note_data->d_buf + name_offset;
- const char *desc = note_data->d_buf + desc_offset;
- GElf_Word regs_offset;
- size_t nregloc;
- const Ebl_Register_Location *reglocs;
- size_t nitems;
- const Ebl_Core_Item *items;
- if (! ebl_core_note (core_arg->ebl, &nhdr, name,
- &regs_offset, &nregloc, &reglocs, &nitems, &items))
- {
- /* This note may be just not recognized, skip it. */
- continue;
- }
- if (nhdr.n_type != NT_PRSTATUS)
- continue;
- const Ebl_Core_Item *item;
- for (item = items; item < items + nitems; item++)
- if (strcmp (item->name, "pid") == 0)
- break;
- if (item == items + nitems)
- continue;
- uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
- val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be32toh (val32) : le32toh (val32));
- pid_t tid = (int32_t) val32;
- eu_static_assert (sizeof val32 <= sizeof tid);
- thread_arg->note_offset = offset;
- return tid;
- }
-
- free (thread_arg);
- return 0;
-}
-
-static bool
-core_set_initial_registers (Dwfl_Thread *thread, void *thread_arg_voidp)
-{
- struct thread_arg *thread_arg = thread_arg_voidp;
- struct core_arg *core_arg = thread_arg->core_arg;
- Elf *core = core_arg->core;
- size_t offset = thread_arg->note_offset;
- GElf_Nhdr nhdr;
- size_t name_offset;
- size_t desc_offset;
- Elf_Data *note_data = core_arg->note_data;
- size_t nregs = ebl_frame_nregs (core_arg->ebl);
- assert (nregs > 0);
- assert (offset < note_data->d_size);
- size_t getnote_err = gelf_getnote (note_data, offset, &nhdr, &name_offset,
- &desc_offset);
- /* __libdwfl_attach_state_for_core already verified the note is there. */
- assert (getnote_err != 0);
- /* Do not check NAME for now, help broken Linux kernels. */
- const char *name = note_data->d_buf + name_offset;
- const char *desc = note_data->d_buf + desc_offset;
- GElf_Word regs_offset;
- size_t nregloc;
- const Ebl_Register_Location *reglocs;
- size_t nitems;
- const Ebl_Core_Item *items;
- int core_note_err = ebl_core_note (core_arg->ebl, &nhdr, name, &regs_offset,
- &nregloc, &reglocs, &nitems, &items);
- /* __libdwfl_attach_state_for_core already verified the note is there. */
- assert (core_note_err != 0);
- assert (nhdr.n_type == NT_PRSTATUS);
- const Ebl_Core_Item *item;
- for (item = items; item < items + nitems; item++)
- if (strcmp (item->name, "pid") == 0)
- break;
- assert (item < items + nitems);
- pid_t tid;
- {
- uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
- val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be32toh (val32) : le32toh (val32));
- tid = (int32_t) val32;
- eu_static_assert (sizeof val32 <= sizeof tid);
- }
- /* core_next_thread already found this TID there. */
- assert (tid == INTUSE(dwfl_thread_tid) (thread));
- for (item = items; item < items + nitems; item++)
- if (item->pc_register)
- break;
- if (item < items + nitems)
- {
- Dwarf_Word pc;
- switch (gelf_getclass (core) == ELFCLASS32 ? 32 : 64)
- {
- case 32:;
- uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
- val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be32toh (val32) : le32toh (val32));
- /* Do a host width conversion. */
- pc = val32;
- break;
- case 64:;
- uint64_t val64 = read_8ubyte_unaligned_noncvt (desc + item->offset);
- val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be64toh (val64) : le64toh (val64));
- pc = val64;
- break;
- default:
- abort ();
- }
- INTUSE(dwfl_thread_state_register_pc) (thread, pc);
- }
- desc += regs_offset;
- for (size_t regloci = 0; regloci < nregloc; regloci++)
- {
- const Ebl_Register_Location *regloc = reglocs + regloci;
- // Iterate even regs out of NREGS range so that we can find pc_register.
- if (regloc->bits != 32 && regloc->bits != 64)
- continue;
- const char *reg_desc = desc + regloc->offset;
- for (unsigned regno = regloc->regno;
- regno < regloc->regno + (regloc->count ?: 1U);
- regno++)
- {
- /* PPC provides DWARF register 65 irrelevant for
- CFI which clashes with register 108 (LR) we need.
- LR (108) is provided earlier (in NT_PRSTATUS) than the # 65.
- FIXME: It depends now on their order in core notes.
- FIXME: It uses private function. */
- if (regno < nregs
- && __libdwfl_frame_reg_get (thread->unwound, regno, NULL))
- continue;
- Dwarf_Word val;
- switch (regloc->bits)
- {
- case 32:;
- uint32_t val32 = read_4ubyte_unaligned_noncvt (reg_desc);
- reg_desc += sizeof val32;
- val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be32toh (val32) : le32toh (val32));
- /* Do a host width conversion. */
- val = val32;
- break;
- case 64:;
- uint64_t val64 = read_8ubyte_unaligned_noncvt (reg_desc);
- reg_desc += sizeof val64;
- val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be64toh (val64) : le64toh (val64));
- assert (sizeof (*thread->unwound->regs) == sizeof val64);
- val = val64;
- break;
- default:
- abort ();
- }
- /* Registers not valid for CFI are just ignored. */
- if (regno < nregs)
- INTUSE(dwfl_thread_state_registers) (thread, regno, 1, &val);
- if (regloc->pc_register)
- INTUSE(dwfl_thread_state_register_pc) (thread, val);
- reg_desc += regloc->pad;
- }
- }
- return true;
-}
-
-static void
-core_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
-{
- struct core_arg *core_arg = dwfl_arg;
- ebl_closebackend (core_arg->ebl);
- free (core_arg);
-}
-
-static const Dwfl_Thread_Callbacks core_thread_callbacks =
-{
- core_next_thread,
- NULL, /* get_thread */
- core_memory_read,
- core_set_initial_registers,
- core_detach,
- NULL, /* core_thread_detach */
-};
-
-int
-dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
-{
- Dwfl_Error err = DWFL_E_NOERROR;
- Ebl *ebl = ebl_openbackend (core);
- if (ebl == NULL)
- {
- err = DWFL_E_LIBEBL;
- fail_err:
- if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
- dwfl->attacherr = __libdwfl_canon_error (err);
- __libdwfl_seterrno (err);
- return -1;
- }
- size_t nregs = ebl_frame_nregs (ebl);
- if (nregs == 0)
- {
- err = DWFL_E_NO_UNWIND;
- fail:
- ebl_closebackend (ebl);
- goto fail_err;
- }
- GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (core, &ehdr_mem);
- if (ehdr == NULL)
- {
- err = DWFL_E_LIBELF;
- goto fail;
- }
- if (ehdr->e_type != ET_CORE)
- {
- err = DWFL_E_NO_CORE_FILE;
- goto fail;
- }
- size_t phnum;
- if (elf_getphdrnum (core, &phnum) < 0)
- {
- err = DWFL_E_LIBELF;
- goto fail;
- }
- pid_t pid = -1;
- Elf_Data *note_data = NULL;
- for (size_t cnt = 0; cnt < phnum; ++cnt)
- {
- GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem);
- if (phdr != NULL && phdr->p_type == PT_NOTE)
- {
- note_data = elf_getdata_rawchunk (core, phdr->p_offset,
- phdr->p_filesz, ELF_T_NHDR);
- break;
- }
- }
- if (note_data == NULL)
- {
- err = DWFL_E_LIBELF;
- goto fail;
- }
- size_t offset = 0;
- GElf_Nhdr nhdr;
- size_t name_offset;
- size_t desc_offset;
- while (offset < note_data->d_size
- && (offset = gelf_getnote (note_data, offset,
- &nhdr, &name_offset, &desc_offset)) > 0)
- {
- /* Do not check NAME for now, help broken Linux kernels. */
- const char *name = note_data->d_buf + name_offset;
- const char *desc = note_data->d_buf + desc_offset;
- GElf_Word regs_offset;
- size_t nregloc;
- const Ebl_Register_Location *reglocs;
- size_t nitems;
- const Ebl_Core_Item *items;
- if (! ebl_core_note (ebl, &nhdr, name,
- &regs_offset, &nregloc, &reglocs, &nitems, &items))
- {
- /* This note may be just not recognized, skip it. */
- continue;
- }
- if (nhdr.n_type != NT_PRPSINFO)
- continue;
- const Ebl_Core_Item *item;
- for (item = items; item < items + nitems; item++)
- if (strcmp (item->name, "pid") == 0)
- break;
- if (item == items + nitems)
- continue;
- uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
- val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
- ? be32toh (val32) : le32toh (val32));
- pid = (int32_t) val32;
- eu_static_assert (sizeof val32 <= sizeof pid);
- break;
- }
- if (pid == -1)
- {
- /* No valid NT_PRPSINFO recognized in this CORE. */
- err = DWFL_E_BADELF;
- goto fail;
- }
- struct core_arg *core_arg = malloc (sizeof *core_arg);
- if (core_arg == NULL)
- {
- err = DWFL_E_NOMEM;
- goto fail;
- }
- core_arg->core = core;
- core_arg->note_data = note_data;
- core_arg->thread_note_offset = 0;
- core_arg->ebl = ebl;
- if (! INTUSE(dwfl_attach_state) (dwfl, core, pid, &core_thread_callbacks,
- core_arg))
- {
- free (core_arg);
- ebl_closebackend (ebl);
- return -1;
- }
- return pid;
-}
-INTDEF (dwfl_core_file_attach)
diff --git a/src/libdwfl/linux-kernel-modules.c b/src/libdwfl/linux-kernel-modules.c
deleted file mode 100644
index 8f2dab3a..00000000
--- a/src/libdwfl/linux-kernel-modules.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/* Standard libdwfl callbacks for debugging the running Linux kernel.
- Copyright (C) 2005-2011, 2013, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-/* We include this before config.h because it can't handle _FILE_OFFSET_BITS.
- Everything we need here is fine if its declarations just come first. */
-
-#undef _FILE_OFFSET_BITS // Undo the damage caused by AndroidConfig.h.
-#include <fts.h>
-
-#include <config.h>
-
-#include "libdwflP.h"
-#include <inttypes.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/utsname.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-
-#define KERNEL_MODNAME "kernel"
-
-#define MODULEDIRFMT "/lib/modules/%s"
-
-#define KNOTESFILE "/sys/kernel/notes"
-#define MODNOTESFMT "/sys/module/%s/notes"
-#define KSYMSFILE "/proc/kallsyms"
-#define MODULELIST "/proc/modules"
-#define SECADDRDIRFMT "/sys/module/%s/sections/"
-#define MODULE_SECT_NAME_LEN 32 /* Minimum any linux/module.h has had. */
-
-
-#if defined (USE_ZLIB) || defined (USE_BZLIB) || defined (USE_LZMA)
-static const char *vmlinux_suffixes[] =
- {
-#ifdef USE_ZLIB
- ".gz",
-#endif
-#ifdef USE_BZLIB
- ".bz2",
-#endif
-#ifdef USE_LZMA
- ".xz",
-#endif
- };
-#endif
-
-/* Try to open the given file as it is or under the debuginfo directory. */
-static int
-try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
-{
- if (*fname == NULL)
- return -1;
-
- /* Don't bother trying *FNAME itself here if the path will cause it to be
- tried because we give its own basename as DEBUGLINK_FILE. */
- int fd = ((((dwfl->callbacks->debuginfo_path
- ? *dwfl->callbacks->debuginfo_path : NULL)
- ?: DEFAULT_DEBUGINFO_PATH)[0] == ':') ? -1
- : TEMP_FAILURE_RETRY (open64 (*fname, O_RDONLY)));
-
- if (fd < 0)
- {
- Dwfl_Module fakemod = { .dwfl = dwfl };
- /* First try the file's unadorned basename as DEBUGLINK_FILE,
- to look for "vmlinux" files. */
- fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
- *fname, basename (*fname), 0,
- &fakemod.debug.name);
- if (fd < 0 && try_debug)
- /* Next, let the call use the default of basename + ".debug",
- to look for "vmlinux.debug" files. */
- fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
- *fname, NULL, 0,
- &fakemod.debug.name);
- if (fakemod.debug.name != NULL)
- {
- free (*fname);
- *fname = fakemod.debug.name;
- }
- }
-
-#if defined (USE_ZLIB) || defined (USE_BZLIB) || defined (USE_LZMA)
- if (fd < 0)
- for (size_t i = 0;
- i < sizeof vmlinux_suffixes / sizeof vmlinux_suffixes[0];
- ++i)
- {
- char *zname;
- if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0)
- {
- fd = TEMP_FAILURE_RETRY (open64 (zname, O_RDONLY));
- if (fd < 0)
- free (zname);
- else
- {
- free (*fname);
- *fname = zname;
- }
- }
- }
-#endif
-
- if (fd < 0)
- {
- free (*fname);
- *fname = NULL;
- }
-
- return fd;
-}
-
-static inline const char *
-kernel_release (void)
-{
- /* Cache the `uname -r` string we'll use. */
- static struct utsname utsname;
- if (utsname.release[0] == '\0' && uname (&utsname) != 0)
- return NULL;
- return utsname.release;
-}
-
-static int
-find_kernel_elf (Dwfl *dwfl, const char *release, char **fname)
-{
- if ((release[0] == '/'
- ? asprintf (fname, "%s/vmlinux", release)
- : asprintf (fname, "/boot/vmlinux-%s", release)) < 0)
- return -1;
-
- int fd = try_kernel_name (dwfl, fname, true);
- if (fd < 0 && release[0] != '/')
- {
- free (*fname);
- if (asprintf (fname, MODULEDIRFMT "/vmlinux", release) < 0)
- return -1;
- fd = try_kernel_name (dwfl, fname, true);
- }
-
- return fd;
-}
-
-static int
-get_release (Dwfl *dwfl, const char **release)
-{
- if (dwfl == NULL)
- return -1;
-
- const char *release_string = release == NULL ? NULL : *release;
- if (release_string == NULL)
- {
- release_string = kernel_release ();
- if (release_string == NULL)
- return errno;
- if (release != NULL)
- *release = release_string;
- }
-
- return 0;
-}
-
-static int
-report_kernel (Dwfl *dwfl, const char **release,
- int (*predicate) (const char *module, const char *file))
-{
- int result = get_release (dwfl, release);
- if (unlikely (result != 0))
- return result;
-
- char *fname;
- int fd = find_kernel_elf (dwfl, *release, &fname);
-
- if (fd < 0)
- result = ((predicate != NULL && !(*predicate) (KERNEL_MODNAME, NULL))
- ? 0 : errno ?: ENOENT);
- else
- {
- bool report = true;
-
- if (predicate != NULL)
- {
- /* Let the predicate decide whether to use this one. */
- int want = (*predicate) (KERNEL_MODNAME, fname);
- if (want < 0)
- result = errno;
- report = want > 0;
- }
-
- if (report)
- {
- /* Note that on some architectures (e.g. x86_64) the vmlinux
- is ET_EXEC, while on others (e.g. ppc64) it is ET_DYN.
- In both cases the phdr p_vaddr load address will be non-zero.
- We want the image to be placed as if it was ET_DYN, so
- pass true for add_p_vaddr which will do the right thing
- (in combination with a zero base) in either case. */
- Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME,
- fname, fd, 0, true);
- if (mod == NULL)
- result = -1;
- else
- /* The kernel is ET_EXEC, but always treat it as relocatable. */
- mod->e_type = ET_DYN;
- }
-
- free (fname);
-
- if (!report || result < 0)
- close (fd);
- }
-
- return result;
-}
-
-/* Look for a kernel debug archive. If we find one, report all its modules.
- If not, return ENOENT. */
-static int
-report_kernel_archive (Dwfl *dwfl, const char **release,
- int (*predicate) (const char *module, const char *file))
-{
- int result = get_release (dwfl, release);
- if (unlikely (result != 0))
- return result;
-
- char *archive;
- int res = (((*release)[0] == '/')
- ? asprintf (&archive, "%s/debug.a", *release)
- : asprintf (&archive, MODULEDIRFMT "/debug.a", *release));
- if (unlikely (res < 0))
- return ENOMEM;
-
- int fd = try_kernel_name (dwfl, &archive, false);
- if (fd < 0)
- result = errno ?: ENOENT;
- else
- {
- /* We have the archive file open! */
- Dwfl_Module *last = __libdwfl_report_offline (dwfl, NULL, archive, fd,
- true, predicate);
- if (unlikely (last == NULL))
- result = -1;
- else
- {
- /* Find the kernel and move it to the head of the list. */
- Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
- for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
- if (!m->gc && m->e_type != ET_REL && !strcmp (m->name, "kernel"))
- {
- *prevp = m->next;
- m->next = *tailp;
- *tailp = m;
- break;
- }
- }
- }
-
- free (archive);
- return result;
-}
-
-static size_t
-check_suffix (const FTSENT *f, size_t namelen)
-{
-#define TRY(sfx) \
- if ((namelen ? f->fts_namelen == namelen + sizeof sfx - 1 \
- : f->fts_namelen >= sizeof sfx) \
- && !memcmp (f->fts_name + f->fts_namelen - (sizeof sfx - 1), \
- sfx, sizeof sfx)) \
- return sizeof sfx - 1
-
- TRY (".ko");
-#if USE_ZLIB
- TRY (".ko.gz");
-#endif
-#if USE_BZLIB
- TRY (".ko.bz2");
-#endif
-#if USE_LZMA
- TRY (".ko.xz");
-#endif
-
- return 0;
-
-#undef TRY
-}
-
-/* Report a kernel and all its modules found on disk, for offline use.
- If RELEASE starts with '/', it names a directory to look in;
- if not, it names a directory to find under /lib/modules/;
- if null, /lib/modules/`uname -r` is used.
- Returns zero on success, -1 if dwfl_report_module failed,
- or an errno code if finding the files on disk failed. */
-int
-dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
- int (*predicate) (const char *module,
- const char *file))
-{
- int result = report_kernel_archive (dwfl, &release, predicate);
- if (result != ENOENT)
- return result;
-
- /* First report the kernel. */
- result = report_kernel (dwfl, &release, predicate);
- if (result == 0)
- {
- /* Do "find /lib/modules/RELEASE -name *.ko". */
-
- char *modulesdir[] = { NULL, NULL };
- if (release[0] == '/')
- modulesdir[0] = (char *) release;
- else
- {
- if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
- return errno;
- }
-
- FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
- if (modulesdir[0] == (char *) release)
- modulesdir[0] = NULL;
- if (fts == NULL)
- {
- free (modulesdir[0]);
- return errno;
- }
-
- FTSENT *f;
- while ((f = fts_read (fts)) != NULL)
- {
- /* Skip a "source" subtree, which tends to be large.
- This insane hard-coding of names is what depmod does too. */
- if (f->fts_namelen == sizeof "source" - 1
- && !strcmp (f->fts_name, "source"))
- {
- fts_set (fts, f, FTS_SKIP);
- continue;
- }
-
- switch (f->fts_info)
- {
- case FTS_F:
- case FTS_SL:
- case FTS_NSOK:;
- /* See if this file name matches "*.ko". */
- const size_t suffix = check_suffix (f, 0);
- if (suffix)
- {
- /* We have a .ko file to report. Following the algorithm
- by which the kernel makefiles set KBUILD_MODNAME, we
- replace all ',' or '-' with '_' in the file name and
- call that the module name. Modules could well be
- built using different embedded names than their file
- names. To handle that, we would have to look at the
- __this_module.name contents in the module's text. */
-
- char name[f->fts_namelen - suffix + 1];
- for (size_t i = 0; i < f->fts_namelen - 3U; ++i)
- if (f->fts_name[i] == '-' || f->fts_name[i] == ',')
- name[i] = '_';
- else
- name[i] = f->fts_name[i];
- name[f->fts_namelen - suffix] = '\0';
-
- if (predicate != NULL)
- {
- /* Let the predicate decide whether to use this one. */
- int want = (*predicate) (name, f->fts_path);
- if (want < 0)
- {
- result = -1;
- break;
- }
- if (!want)
- continue;
- }
-
- if (dwfl_report_offline (dwfl, name, f->fts_path, -1) == NULL)
- {
- result = -1;
- break;
- }
- }
- continue;
-
- case FTS_ERR:
- case FTS_DNR:
- case FTS_NS:
- result = f->fts_errno;
- break;
-
- case FTS_SLNONE:
- default:
- continue;
- }
-
- /* We only get here in error cases. */
- break;
- }
- fts_close (fts);
- free (modulesdir[0]);
- }
-
- return result;
-}
-INTDEF (dwfl_linux_kernel_report_offline)
-
-
-/* Grovel around to guess the bounds of the runtime kernel image. */
-static int
-intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes)
-{
- FILE *f = fopen (KSYMSFILE, "r");
- if (f == NULL)
- return errno;
-
- (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
-
- *notes = 0;
-
- char *line = NULL;
- size_t linesz = 0;
- size_t n;
- char *p = NULL;
- const char *type;
-
- inline bool read_address (Dwarf_Addr *addr)
- {
- if ((n = getline (&line, &linesz, f)) < 1 || line[n - 2] == ']')
- return false;
- *addr = strtoull (line, &p, 16);
- p += strspn (p, " \t");
- type = strsep (&p, " \t\n");
- if (type == NULL)
- return false;
- return p != NULL && p != line;
- }
-
- int result;
- do
- result = read_address (start) ? 0 : -1;
- while (result == 0 && strchr ("TtRr", *type) == NULL);
-
- if (result == 0)
- {
- *end = *start;
- while (read_address (end))
- if (*notes == 0 && !strcmp (p, "__start_notes\n"))
- *notes = *end;
-
- Dwarf_Addr round_kernel = sysconf (_SC_PAGE_SIZE);
- *start &= -(Dwarf_Addr) round_kernel;
- *end += round_kernel - 1;
- *end &= -(Dwarf_Addr) round_kernel;
- if (*start >= *end || *end - *start < round_kernel)
- result = -1;
- }
- free (line);
-
- if (result == -1)
- result = ferror_unlocked (f) ? errno : ENOEXEC;
-
- fclose (f);
-
- return result;
-}
-
-
-/* Look for a build ID note in NOTESFILE and associate the ID with MOD. */
-static int
-check_notes (Dwfl_Module *mod, const char *notesfile,
- Dwarf_Addr vaddr, const char *secname)
-{
- int fd = open64 (notesfile, O_RDONLY);
- if (fd < 0)
- return 1;
-
- assert (sizeof (Elf32_Nhdr) == sizeof (GElf_Nhdr));
- assert (sizeof (Elf64_Nhdr) == sizeof (GElf_Nhdr));
- union
- {
- GElf_Nhdr nhdr;
- unsigned char data[8192];
- } buf;
-
- ssize_t n = read (fd, buf.data, sizeof buf);
- close (fd);
-
- if (n <= 0)
- return 1;
-
- unsigned char *p = buf.data;
- while (p < &buf.data[n])
- {
- /* No translation required since we are reading the native kernel. */
- GElf_Nhdr *nhdr = (void *) p;
- p += sizeof *nhdr;
- unsigned char *name = p;
- p += (nhdr->n_namesz + 3) & -4U;
- unsigned char *bits = p;
- p += (nhdr->n_descsz + 3) & -4U;
-
- if (p <= &buf.data[n]
- && nhdr->n_type == NT_GNU_BUILD_ID
- && nhdr->n_namesz == sizeof "GNU"
- && !memcmp (name, "GNU", sizeof "GNU"))
- {
- /* Found it. For a module we must figure out its VADDR now. */
-
- if (secname != NULL
- && (INTUSE(dwfl_linux_kernel_module_section_address)
- (mod, NULL, mod->name, 0, secname, 0, NULL, &vaddr) != 0
- || vaddr == (GElf_Addr) -1l))
- vaddr = 0;
-
- if (vaddr != 0)
- vaddr += bits - buf.data;
- return INTUSE(dwfl_module_report_build_id) (mod, bits,
- nhdr->n_descsz, vaddr);
- }
- }
-
- return 0;
-}
-
-/* Look for a build ID for the kernel. */
-static int
-check_kernel_notes (Dwfl_Module *kernelmod, GElf_Addr vaddr)
-{
- return check_notes (kernelmod, KNOTESFILE, vaddr, NULL) < 0 ? -1 : 0;
-}
-
-/* Look for a build ID for a loaded kernel module. */
-static int
-check_module_notes (Dwfl_Module *mod)
-{
- char *dirs[2] = { NULL, NULL };
- if (asprintf (&dirs[0], MODNOTESFMT, mod->name) < 0)
- return ENOMEM;
-
- FTS *fts = fts_open (dirs, FTS_NOSTAT | FTS_LOGICAL, NULL);
- if (fts == NULL)
- {
- free (dirs[0]);
- return 0;
- }
-
- int result = 0;
- FTSENT *f;
- while ((f = fts_read (fts)) != NULL)
- {
- switch (f->fts_info)
- {
- case FTS_F:
- case FTS_SL:
- case FTS_NSOK:
- result = check_notes (mod, f->fts_accpath, 0, f->fts_name);
- if (result > 0) /* Nothing found. */
- {
- result = 0;
- continue;
- }
- break;
-
- case FTS_ERR:
- case FTS_DNR:
- result = f->fts_errno;
- break;
-
- case FTS_NS:
- case FTS_SLNONE:
- default:
- continue;
- }
-
- /* We only get here when finished or in error cases. */
- break;
- }
- fts_close (fts);
- free (dirs[0]);
-
- return result;
-}
-
-int
-dwfl_linux_kernel_report_kernel (Dwfl *dwfl)
-{
- Dwarf_Addr start;
- Dwarf_Addr end;
- inline Dwfl_Module *report (void)
- {
- return INTUSE(dwfl_report_module) (dwfl, KERNEL_MODNAME, start, end);
- }
-
- /* This is a bit of a kludge. If we already reported the kernel,
- don't bother figuring it out again--it never changes. */
- for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
- if (!strcmp (m->name, KERNEL_MODNAME))
- {
- start = m->low_addr;
- end = m->high_addr;
- return report () == NULL ? -1 : 0;
- }
-
- /* Try to figure out the bounds of the kernel image without
- looking for any vmlinux file. */
- Dwarf_Addr notes;
- /* The compiler cannot deduce that if intuit_kernel_bounds returns
- zero NOTES will be initialized. Fake the initialization. */
- asm ("" : "=m" (notes));
- int result = intuit_kernel_bounds (&start, &end, &notes);
- if (result == 0)
- {
- Dwfl_Module *mod = report ();
- return unlikely (mod == NULL) ? -1 : check_kernel_notes (mod, notes);
- }
- if (result != ENOENT)
- return result;
-
- /* Find the ELF file for the running kernel and dwfl_report_elf it. */
- return report_kernel (dwfl, NULL, NULL);
-}
-INTDEF (dwfl_linux_kernel_report_kernel)
-
-
-/* Dwfl_Callbacks.find_elf for the running Linux kernel and its modules. */
-
-int
-dwfl_linux_kernel_find_elf (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *module_name,
- Dwarf_Addr base __attribute__ ((unused)),
- char **file_name, Elf **elfp)
-{
- if (mod->build_id_len > 0)
- {
- int fd = INTUSE(dwfl_build_id_find_elf) (mod, NULL, NULL, 0,
- file_name, elfp);
- if (fd >= 0 || mod->main.elf != NULL || errno != 0)
- return fd;
- }
-
- const char *release = kernel_release ();
- if (release == NULL)
- return errno;
-
- if (!strcmp (module_name, KERNEL_MODNAME))
- return find_kernel_elf (mod->dwfl, release, file_name);
-
- /* Do "find /lib/modules/`uname -r` -name MODULE_NAME.ko". */
-
- char *modulesdir[] = { NULL, NULL };
- if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
- return -1;
-
- FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
- if (fts == NULL)
- {
- free (modulesdir[0]);
- return -1;
- }
-
- size_t namelen = strlen (module_name);
-
- /* This is a kludge. There is no actual necessary relationship between
- the name of the .ko file installed and the module name the kernel
- knows it by when it's loaded. The kernel's only idea of the module
- name comes from the name embedded in the object's magic
- .gnu.linkonce.this_module section.
-
- In practice, these module names match the .ko file names except for
- some using '_' and some using '-'. So our cheap kludge is to look for
- two files when either a '_' or '-' appears in a module name, one using
- only '_' and one only using '-'. */
-
- char alternate_name[namelen + 1];
- inline bool subst_name (char from, char to)
- {
- const char *n = memchr (module_name, from, namelen);
- if (n == NULL)
- return false;
- char *a = mempcpy (alternate_name, module_name, n - module_name);
- *a++ = to;
- ++n;
- const char *p;
- while ((p = memchr (n, from, namelen - (n - module_name))) != NULL)
- {
- a = mempcpy (a, n, p - n);
- *a++ = to;
- n = p + 1;
- }
- memcpy (a, n, namelen - (n - module_name) + 1);
- return true;
- }
- if (!subst_name ('-', '_') && !subst_name ('_', '-'))
- alternate_name[0] = '\0';
-
- FTSENT *f;
- int error = ENOENT;
- while ((f = fts_read (fts)) != NULL)
- {
- /* Skip a "source" subtree, which tends to be large.
- This insane hard-coding of names is what depmod does too. */
- if (f->fts_namelen == sizeof "source" - 1
- && !strcmp (f->fts_name, "source"))
- {
- fts_set (fts, f, FTS_SKIP);
- continue;
- }
-
- error = ENOENT;
- switch (f->fts_info)
- {
- case FTS_F:
- case FTS_SL:
- case FTS_NSOK:
- /* See if this file name is "MODULE_NAME.ko". */
- if (check_suffix (f, namelen)
- && (!memcmp (f->fts_name, module_name, namelen)
- || !memcmp (f->fts_name, alternate_name, namelen)))
- {
- int fd = open64 (f->fts_accpath, O_RDONLY);
- *file_name = strdup (f->fts_path);
- fts_close (fts);
- free (modulesdir[0]);
- if (fd < 0)
- free (*file_name);
- else if (*file_name == NULL)
- {
- close (fd);
- fd = -1;
- }
- return fd;
- }
- break;
-
- case FTS_ERR:
- case FTS_DNR:
- case FTS_NS:
- error = f->fts_errno;
- break;
-
- case FTS_SLNONE:
- default:
- break;
- }
- }
-
- fts_close (fts);
- free (modulesdir[0]);
- errno = error;
- return -1;
-}
-INTDEF (dwfl_linux_kernel_find_elf)
-
-
-/* Dwfl_Callbacks.section_address for kernel modules in the running Linux.
- We read the information from /sys/module directly. */
-
-int
-dwfl_linux_kernel_module_section_address
-(Dwfl_Module *mod __attribute__ ((unused)),
- void **userdata __attribute__ ((unused)),
- const char *modname, Dwarf_Addr base __attribute__ ((unused)),
- const char *secname, Elf32_Word shndx __attribute__ ((unused)),
- const GElf_Shdr *shdr __attribute__ ((unused)),
- Dwarf_Addr *addr)
-{
- char *sysfile;
- if (asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname) < 0)
- return DWARF_CB_ABORT;
-
- FILE *f = fopen (sysfile, "r");
- free (sysfile);
-
- if (f == NULL)
- {
- if (errno == ENOENT)
- {
- /* The .modinfo and .data.percpu sections are never kept
- loaded in the kernel. If the kernel was compiled without
- CONFIG_MODULE_UNLOAD, the .exit.* sections are not
- actually loaded at all.
-
- Setting *ADDR to -1 tells the caller this section is
- actually absent from memory. */
-
- if (!strcmp (secname, ".modinfo")
- || !strcmp (secname, ".data.percpu")
- || !strncmp (secname, ".exit", 5))
- {
- *addr = (Dwarf_Addr) -1l;
- return DWARF_CB_OK;
- }
-
- /* The goofy PPC64 module_frob_arch_sections function tweaks
- the section names as a way to control other kernel code's
- behavior, and this cruft leaks out into the /sys information.
- The file name for ".init*" may actually look like "_init*". */
-
- const bool is_init = !strncmp (secname, ".init", 5);
- if (is_init)
- {
- if (asprintf (&sysfile, SECADDRDIRFMT "_%s",
- modname, &secname[1]) < 0)
- return ENOMEM;
- f = fopen (sysfile, "r");
- free (sysfile);
- if (f != NULL)
- goto ok;
- }
-
- /* The kernel truncates section names to MODULE_SECT_NAME_LEN - 1.
- In case that size increases in the future, look for longer
- truncated names first. */
- size_t namelen = strlen (secname);
- if (namelen >= MODULE_SECT_NAME_LEN)
- {
- int len = asprintf (&sysfile, SECADDRDIRFMT "%s",
- modname, secname);
- if (len < 0)
- return DWARF_CB_ABORT;
- char *end = sysfile + len;
- do
- {
- *--end = '\0';
- f = fopen (sysfile, "r");
- if (is_init && f == NULL && errno == ENOENT)
- {
- sysfile[len - namelen] = '_';
- f = fopen (sysfile, "r");
- sysfile[len - namelen] = '.';
- }
- }
- while (f == NULL && errno == ENOENT
- && end - &sysfile[len - namelen] >= MODULE_SECT_NAME_LEN);
- free (sysfile);
-
- if (f != NULL)
- goto ok;
- }
- }
-
- return DWARF_CB_ABORT;
- }
-
- ok:
- (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
-
- int result = (fscanf (f, "%" PRIx64 "\n", addr) == 1 ? 0
- : ferror_unlocked (f) ? errno : ENOEXEC);
- fclose (f);
-
- if (result == 0)
- return DWARF_CB_OK;
-
- errno = result;
- return DWARF_CB_ABORT;
-}
-INTDEF (dwfl_linux_kernel_module_section_address)
-
-int
-dwfl_linux_kernel_report_modules (Dwfl *dwfl)
-{
- FILE *f = fopen (MODULELIST, "r");
- if (f == NULL)
- return errno;
-
- (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
-
- int result = 0;
- Dwarf_Addr modaddr;
- unsigned long int modsz;
- char modname[128];
- char *line = NULL;
- size_t linesz = 0;
- /* We can't just use fscanf here because it's not easy to distinguish \n
- from other whitespace so as to take the optional word following the
- address but always stop at the end of the line. */
- while (getline (&line, &linesz, f) > 0
- && sscanf (line, "%128s %lu %*s %*s %*s %" PRIx64 " %*s\n",
- modname, &modsz, &modaddr) == 3)
- {
- Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, modname,
- modaddr, modaddr + modsz);
- if (mod == NULL)
- {
- result = -1;
- break;
- }
-
- result = check_module_notes (mod);
- }
- free (line);
-
- if (result == 0)
- result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
-
- fclose (f);
-
- return result;
-}
-INTDEF (dwfl_linux_kernel_report_modules)
diff --git a/src/libdwfl/linux-pid-attach.c b/src/libdwfl/linux-pid-attach.c
deleted file mode 100644
index ae717028..00000000
--- a/src/libdwfl/linux-pid-attach.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/* Get Dwarf Frame state for target live PID process.
- Copyright (C) 2013, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <sys/ptrace.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-#ifndef MAX
-# define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifdef __linux__
-
-static bool
-linux_proc_pid_is_stopped (pid_t pid)
-{
- char buffer[64];
- FILE *procfile;
- bool retval, have_state;
-
- snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
- procfile = fopen (buffer, "r");
- if (procfile == NULL)
- return false;
-
- have_state = false;
- while (fgets (buffer, sizeof (buffer), procfile) != NULL)
- if (strncmp (buffer, "State:", 6) == 0)
- {
- have_state = true;
- break;
- }
- retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
- fclose (procfile);
- return retval;
-}
-
-bool
-internal_function
-__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
-{
- if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
- {
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
- }
- *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
- if (*tid_was_stoppedp)
- {
- /* Make sure there is a SIGSTOP signal pending even when the process is
- already State: T (stopped). Older kernels might fail to generate
- a SIGSTOP notification in that case in response to our PTRACE_ATTACH
- above. Which would make the waitpid below wait forever. So emulate
- it. Since there can only be one SIGSTOP notification pending this is
- safe. See also gdb/linux-nat.c linux_nat_post_attach_wait. */
- syscall (__NR_tkill, tid, SIGSTOP);
- ptrace (PTRACE_CONT, tid, NULL, NULL);
- }
- for (;;)
- {
- int status;
- if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
- {
- int saved_errno = errno;
- ptrace (PTRACE_DETACH, tid, NULL, NULL);
- errno = saved_errno;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
- }
- if (WSTOPSIG (status) == SIGSTOP)
- break;
- if (ptrace (PTRACE_CONT, tid, NULL,
- (void *) (uintptr_t) WSTOPSIG (status)) != 0)
- {
- int saved_errno = errno;
- ptrace (PTRACE_DETACH, tid, NULL, NULL);
- errno = saved_errno;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
- }
- }
- return true;
-}
-
-static bool
-pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
-{
- struct __libdwfl_pid_arg *pid_arg = arg;
- pid_t tid = pid_arg->tid_attached;
- assert (tid > 0);
- Dwfl_Process *process = dwfl->process;
- if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
- {
-#if SIZEOF_LONG == 8
- errno = 0;
- *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
- return errno == 0;
-#else /* SIZEOF_LONG != 8 */
- /* This should not happen. */
- return false;
-#endif /* SIZEOF_LONG != 8 */
- }
-#if SIZEOF_LONG == 8
- /* We do not care about reads unaliged to 4 bytes boundary.
- But 0x...ffc read of 8 bytes could overrun a page. */
- bool lowered = (addr & 4) != 0;
- if (lowered)
- addr -= 4;
-#endif /* SIZEOF_LONG == 8 */
- errno = 0;
- *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
- if (errno != 0)
- return false;
-#if SIZEOF_LONG == 8
-# if BYTE_ORDER == BIG_ENDIAN
- if (! lowered)
- *result >>= 32;
-# else
- if (lowered)
- *result >>= 32;
-# endif
-#endif /* SIZEOF_LONG == 8 */
- *result &= 0xffffffff;
- return true;
-}
-
-static pid_t
-pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
- void **thread_argp)
-{
- struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
- struct dirent *dirent;
- /* Start fresh on first traversal. */
- if (*thread_argp == NULL)
- rewinddir (pid_arg->dir);
- do
- {
- errno = 0;
- dirent = readdir (pid_arg->dir);
- if (dirent == NULL)
- {
- if (errno != 0)
- {
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return -1;
- }
- return 0;
- }
- }
- while (strcmp (dirent->d_name, ".") == 0
- || strcmp (dirent->d_name, "..") == 0);
- char *end;
- errno = 0;
- long tidl = strtol (dirent->d_name, &end, 10);
- if (errno != 0)
- {
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return -1;
- }
- pid_t tid = tidl;
- if (tidl <= 0 || (end && *end) || tid != tidl)
- {
- __libdwfl_seterrno (DWFL_E_PARSE_PROC);
- return -1;
- }
- *thread_argp = dwfl_arg;
- return tid;
-}
-
-/* Just checks that the thread id exists. */
-static bool
-pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
- void *dwfl_arg, void **thread_argp)
-{
- *thread_argp = dwfl_arg;
- if (kill (tid, 0) < 0)
- {
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
- }
- return true;
-}
-
-/* Implement the ebl_set_initial_registers_tid setfunc callback. */
-
-static bool
-pid_thread_state_registers_cb (int firstreg, unsigned nregs,
- const Dwarf_Word *regs, void *arg)
-{
- Dwfl_Thread *thread = (Dwfl_Thread *) arg;
- if (firstreg < 0)
- {
- assert (firstreg == -1);
- assert (nregs == 1);
- INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
- return true;
- }
- assert (nregs > 0);
- return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
-}
-
-static bool
-pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
-{
- struct __libdwfl_pid_arg *pid_arg = thread_arg;
- assert (pid_arg->tid_attached == 0);
- pid_t tid = INTUSE(dwfl_thread_tid) (thread);
- if (! pid_arg->assume_ptrace_stopped
- && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
- return false;
- pid_arg->tid_attached = tid;
- Dwfl_Process *process = thread->process;
- Ebl *ebl = process->ebl;
- return ebl_set_initial_registers_tid (ebl, tid,
- pid_thread_state_registers_cb, thread);
-}
-
-static void
-pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
-{
- struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
- closedir (pid_arg->dir);
- free (pid_arg);
-}
-
-void
-internal_function
-__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
-{
- /* This handling is needed only on older Linux kernels such as
- 2.6.32-358.23.2.el6.ppc64. Later kernels such as
- 3.11.7-200.fc19.x86_64 remember the T (stopped) state
- themselves and no longer need to pass SIGSTOP during
- PTRACE_DETACH. */
- ptrace (PTRACE_DETACH, tid, NULL,
- (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
-}
-
-static void
-pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
-{
- struct __libdwfl_pid_arg *pid_arg = thread_arg;
- pid_t tid = INTUSE(dwfl_thread_tid) (thread);
- assert (pid_arg->tid_attached == tid);
- pid_arg->tid_attached = 0;
- if (! pid_arg->assume_ptrace_stopped)
- __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
-}
-
-static const Dwfl_Thread_Callbacks pid_thread_callbacks =
-{
- pid_next_thread,
- pid_getthread,
- pid_memory_read,
- pid_set_initial_registers,
- pid_detach,
- pid_thread_detach,
-};
-
-int
-dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
-{
- char buffer[36];
- FILE *procfile;
- int err = 0; /* The errno to return and set for dwfl->attcherr. */
-
- /* Make sure to report the actual PID (thread group leader) to
- dwfl_attach_state. */
- snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
- procfile = fopen (buffer, "r");
- if (procfile == NULL)
- {
- err = errno;
- fail:
- if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
- {
- errno = err;
- dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
- }
- return err;
- }
-
- char *line = NULL;
- size_t linelen = 0;
- while (getline (&line, &linelen, procfile) >= 0)
- if (strncmp (line, "Tgid:", 5) == 0)
- {
- errno = 0;
- char *endptr;
- long val = strtol (&line[5], &endptr, 10);
- if ((errno == ERANGE && val == LONG_MAX)
- || *endptr != '\n' || val < 0 || val != (pid_t) val)
- pid = 0;
- else
- pid = (pid_t) val;
- break;
- }
- free (line);
- fclose (procfile);
-
- if (pid == 0)
- {
- err = ESRCH;
- goto fail;
- }
-
- char dirname[64];
- int i = snprintf (dirname, sizeof (dirname), "/proc/%ld/task", (long) pid);
- assert (i > 0 && i < (ssize_t) sizeof (dirname) - 1);
- DIR *dir = opendir (dirname);
- if (dir == NULL)
- {
- err = errno;
- goto fail;
- }
- struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
- if (pid_arg == NULL)
- {
- closedir (dir);
- err = ENOMEM;
- goto fail;
- }
- pid_arg->dir = dir;
- pid_arg->tid_attached = 0;
- pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
- if (! INTUSE(dwfl_attach_state) (dwfl, NULL, pid, &pid_thread_callbacks,
- pid_arg))
- {
- closedir (dir);
- free (pid_arg);
- return -1;
- }
- return 0;
-}
-INTDEF (dwfl_linux_proc_attach)
-
-struct __libdwfl_pid_arg *
-internal_function
-__libdwfl_get_pid_arg (Dwfl *dwfl)
-{
- if (dwfl != NULL && dwfl->process != NULL
- && dwfl->process->callbacks == &pid_thread_callbacks)
- return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
-
- return NULL;
-}
-
-#else /* __linux__ */
-
-static pid_t
-pid_next_thread (Dwfl *dwfl __attribute__ ((unused)),
- void *dwfl_arg __attribute__ ((unused)),
- void **thread_argp __attribute__ ((unused)))
-{
- errno = ENOSYS;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return -1;
-}
-
-static bool
-pid_getthread (Dwfl *dwfl __attribute__ ((unused)),
- pid_t tid __attribute__ ((unused)),
- void *dwfl_arg __attribute__ ((unused)),
- void **thread_argp __attribute__ ((unused)))
-{
- errno = ENOSYS;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
-}
-
-bool
-internal_function
-__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
- bool *tid_was_stoppedp __attribute__ ((unused)))
-{
- errno = ENOSYS;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
-}
-
-static bool
-pid_memory_read (Dwfl *dwfl __attribute__ ((unused)),
- Dwarf_Addr addr __attribute__ ((unused)),
- Dwarf_Word *result __attribute__ ((unused)),
- void *arg __attribute__ ((unused)))
-{
- errno = ENOSYS;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
-}
-
-static bool
-pid_set_initial_registers (Dwfl_Thread *thread __attribute__ ((unused)),
- void *thread_arg __attribute__ ((unused)))
-{
- errno = ENOSYS;
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return false;
-}
-
-static void
-pid_detach (Dwfl *dwfl __attribute__ ((unused)),
- void *dwfl_arg __attribute__ ((unused)))
-{
-}
-
-void
-internal_function
-__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
- bool tid_was_stopped __attribute__ ((unused)))
-{
-}
-
-static void
-pid_thread_detach (Dwfl_Thread *thread __attribute__ ((unused)),
- void *thread_arg __attribute__ ((unused)))
-{
-}
-
-static const Dwfl_Thread_Callbacks pid_thread_callbacks =
-{
- pid_next_thread,
- pid_getthread,
- pid_memory_read,
- pid_set_initial_registers,
- pid_detach,
- pid_thread_detach,
-};
-
-int
-dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
- pid_t pid __attribute__ ((unused)),
- bool assume_ptrace_stopped __attribute__ ((unused)))
-{
- return ENOSYS;
-}
-INTDEF (dwfl_linux_proc_attach)
-
-struct __libdwfl_pid_arg *
-internal_function
-__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
-{
- return NULL;
-}
-
-#endif /* ! __linux __ */
-
diff --git a/src/libdwfl/linux-proc-maps.c b/src/libdwfl/linux-proc-maps.c
deleted file mode 100644
index d0858342..00000000
--- a/src/libdwfl/linux-proc-maps.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/* Standard libdwfl callbacks for debugging a live Linux process.
- Copyright (C) 2005-2010, 2013, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdio_ext.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <assert.h>
-#include <endian.h>
-#include "system.h"
-
-
-#define PROCMAPSFMT "/proc/%d/maps"
-#define PROCMEMFMT "/proc/%d/mem"
-#define PROCAUXVFMT "/proc/%d/auxv"
-#define PROCEXEFMT "/proc/%d/exe"
-
-
-/* Return ELFCLASS64 or ELFCLASS32 for the main ELF executable. Return
- ELFCLASSNONE for an error. */
-
-static unsigned char
-get_pid_class (pid_t pid)
-{
- char *fname;
- if (asprintf (&fname, PROCEXEFMT, pid) < 0)
- return ELFCLASSNONE;
-
- int fd = open64 (fname, O_RDONLY);
- free (fname);
- if (fd < 0)
- return ELFCLASSNONE;
-
- unsigned char buf[EI_CLASS + 1];
- ssize_t nread = pread_retry (fd, &buf, sizeof buf, 0);
- close (fd);
- if (nread != sizeof buf || buf[EI_MAG0] != ELFMAG0
- || buf[EI_MAG1] != ELFMAG1 || buf[EI_MAG2] != ELFMAG2
- || buf[EI_MAG3] != ELFMAG3
- || (buf[EI_CLASS] != ELFCLASS64 && buf[EI_CLASS] != ELFCLASS32))
- return ELFCLASSNONE;
-
- return buf[EI_CLASS];
-}
-
-/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag.
-
- It would be easiest to call get_pid_class and parse everything according to
- the 32-bit or 64-bit class. But this would bring the overhead of syscalls
- to open and read the "/proc/%d/exe" file.
-
- Therefore this function tries to parse the "/proc/%d/auxv" content both
- ways, as if it were the 32-bit format and also if it were the 64-bit format.
- Only if it gives some valid data in both cases get_pid_class gets called.
- In most cases only one of the format bit sizes gives valid data and the
- get_pid_class call overhead can be saved. */
-
-static int
-grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
-{
- char *fname;
- if (asprintf (&fname, PROCAUXVFMT, pid) < 0)
- return ENOMEM;
-
- int fd = open64 (fname, O_RDONLY);
- free (fname);
- if (fd < 0)
- return errno == ENOENT ? 0 : errno;
-
- GElf_Addr sysinfo_ehdr64 = 0;
- GElf_Addr sysinfo_ehdr32 = 0;
- GElf_Addr segment_align64 = dwfl->segment_align;
- GElf_Addr segment_align32 = dwfl->segment_align;
- off_t offset = 0;
- ssize_t nread;
- union
- {
- Elf64_auxv_t a64[64];
- Elf32_auxv_t a32[128];
- } d;
- do
- {
- eu_static_assert (sizeof d.a64 == sizeof d.a32);
- nread = pread_retry (fd, d.a64, sizeof d.a64, offset);
- if (nread < 0)
- {
- int ret = errno;
- close (fd);
- return ret;
- }
- for (size_t a32i = 0; a32i < nread / sizeof d.a32[0]; a32i++)
- {
- const Elf32_auxv_t *a32 = d.a32 + a32i;
- switch (a32->a_type)
- {
- case AT_SYSINFO_EHDR:
- sysinfo_ehdr32 = a32->a_un.a_val;
- break;
- case AT_PAGESZ:
- segment_align32 = a32->a_un.a_val;
- break;
- }
- }
- for (size_t a64i = 0; a64i < nread / sizeof d.a64[0]; a64i++)
- {
- const Elf64_auxv_t *a64 = d.a64 + a64i;
- switch (a64->a_type)
- {
- case AT_SYSINFO_EHDR:
- sysinfo_ehdr64 = a64->a_un.a_val;
- break;
- case AT_PAGESZ:
- segment_align64 = a64->a_un.a_val;
- break;
- }
- }
- offset += nread;
- }
- while (nread == sizeof d.a64);
-
- close (fd);
-
- bool valid64 = sysinfo_ehdr64 != 0 || segment_align64 != dwfl->segment_align;
- bool valid32 = sysinfo_ehdr32 != 0 || segment_align32 != dwfl->segment_align;
-
- unsigned char pid_class = ELFCLASSNONE;
- if (valid64 && valid32)
- pid_class = get_pid_class (pid);
-
- if (pid_class == ELFCLASS64 || (valid64 && ! valid32))
- {
- *sysinfo_ehdr = sysinfo_ehdr64;
- dwfl->segment_align = segment_align64;
- return 0;
- }
- if (pid_class == ELFCLASS32 || (! valid64 && valid32))
- {
- *sysinfo_ehdr = sysinfo_ehdr32;
- dwfl->segment_align = segment_align32;
- return 0;
- }
- return ENOEXEC;
-}
-
-static int
-proc_maps_report (Dwfl *dwfl, FILE *f, GElf_Addr sysinfo_ehdr, pid_t pid)
-{
- unsigned int last_dmajor = -1, last_dminor = -1;
- uint64_t last_ino = -1;
- char *last_file = NULL;
- Dwarf_Addr low = 0, high = 0;
-
- inline bool report (void)
- {
- if (last_file != NULL)
- {
- Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, last_file,
- low, high);
- free (last_file);
- last_file = NULL;
- if (unlikely (mod == NULL))
- return true;
- }
- return false;
- }
-
- char *line = NULL;
- size_t linesz;
- ssize_t len;
- while ((len = getline (&line, &linesz, f)) > 0)
- {
- if (line[len - 1] == '\n')
- line[len - 1] = '\0';
-
- Dwarf_Addr start, end, offset;
- unsigned int dmajor, dminor;
- uint64_t ino;
- int nread = -1;
- if (sscanf (line, "%" PRIx64 "-%" PRIx64 " %*s %" PRIx64
- " %x:%x %" PRIi64 " %n",
- &start, &end, &offset, &dmajor, &dminor, &ino, &nread) < 6
- || nread <= 0)
- {
- free (line);
- return ENOEXEC;
- }
-
- /* If this is the special mapping AT_SYSINFO_EHDR pointed us at,
- report the last one and then this special one. */
- if (start == sysinfo_ehdr && start != 0)
- {
- if (report ())
- {
- bad_report:
- free (line);
- return -1;
- }
-
- low = start;
- high = end;
- if (asprintf (&last_file, "[vdso: %d]", (int) pid) < 0
- || report ())
- goto bad_report;
- }
-
- char *file = line + nread + strspn (line + nread, " \t");
- if (file[0] != '/' || (ino == 0 && dmajor == 0 && dminor == 0))
- /* This line doesn't indicate a file mapping. */
- continue;
-
- if (last_file != NULL
- && ino == last_ino && dmajor == last_dmajor && dminor == last_dminor)
- {
- /* This is another portion of the same file's mapping. */
- if (strcmp (last_file, file) != 0)
- goto bad_report;
- high = end;
- }
- else
- {
- /* This is a different file mapping. Report the last one. */
- if (report ())
- goto bad_report;
- low = start;
- high = end;
- last_file = strdup (file);
- last_ino = ino;
- last_dmajor = dmajor;
- last_dminor = dminor;
- }
- }
- free (line);
-
- int result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
-
- /* Report the final one. */
- bool lose = report ();
-
- return result != 0 ? result : lose ? -1 : 0;
-}
-
-int
-dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *f)
-{
- return proc_maps_report (dwfl, f, 0, 0);
-}
-INTDEF (dwfl_linux_proc_maps_report)
-
-int
-dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid)
-{
- if (dwfl == NULL)
- return -1;
-
- /* We'll notice the AT_SYSINFO_EHDR address specially when we hit it. */
- GElf_Addr sysinfo_ehdr = 0;
- int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr);
- if (result != 0)
- return result;
-
- char *fname;
- if (asprintf (&fname, PROCMAPSFMT, pid) < 0)
- return ENOMEM;
-
- FILE *f = fopen (fname, "r");
- free (fname);
- if (f == NULL)
- return errno;
-
- (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
-
- result = proc_maps_report (dwfl, f, sysinfo_ehdr, pid);
-
- fclose (f);
-
- return result;
-}
-INTDEF (dwfl_linux_proc_report)
-
-static ssize_t
-read_proc_memory (void *arg, void *data, GElf_Addr address,
- size_t minread, size_t maxread)
-{
- const int fd = *(const int *) arg;
- ssize_t nread = pread64 (fd, data, maxread, (off64_t) address);
- /* Some kernels don't actually let us do this read, ignore those errors. */
- if (nread < 0 && (errno == EINVAL || errno == EPERM))
- return 0;
- if (nread > 0 && (size_t) nread < minread)
- nread = 0;
- return nread;
-}
-
-extern Elf *elf_from_remote_memory (GElf_Addr ehdr_vma,
- GElf_Xword pagesize,
- GElf_Addr *loadbasep,
- ssize_t (*read_memory) (void *arg,
- void *data,
- GElf_Addr address,
- size_t minread,
- size_t maxread),
- void *arg);
-
-
-/* Dwfl_Callbacks.find_elf */
-
-int
-dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
- void **userdata __attribute__ ((unused)),
- const char *module_name, Dwarf_Addr base,
- char **file_name, Elf **elfp)
-{
- int pid = -1;
- if (module_name[0] == '/')
- {
- /* When this callback is used together with dwfl_linux_proc_report
- then we might see mappings of special character devices. Make
- sure we only open and return regular files. Special devices
- might hang on open or read. (deleted) files are super special.
- The image might come from memory if we are attached. */
- struct stat sb;
- if (stat (module_name, &sb) == -1 || (sb.st_mode & S_IFMT) != S_IFREG)
- {
- if (strcmp (strrchr (module_name, ' ') ?: "", " (deleted)") == 0)
- pid = INTUSE(dwfl_pid) (mod->dwfl);
- else
- return -1;
- }
-
- if (pid == -1)
- {
- int fd = open64 (module_name, O_RDONLY);
- if (fd >= 0)
- {
- *file_name = strdup (module_name);
- if (*file_name == NULL)
- {
- close (fd);
- return ENOMEM;
- }
- }
- return fd;
- }
- }
-
- if (pid != -1 || sscanf (module_name, "[vdso: %d]", &pid) == 1)
- {
- /* Special case for in-memory ELF image. */
-
- bool detach = false;
- bool tid_was_stopped = false;
- struct __libdwfl_pid_arg *pid_arg = __libdwfl_get_pid_arg (mod->dwfl);
- if (pid_arg != NULL && ! pid_arg->assume_ptrace_stopped)
- {
- /* If any thread is already attached we are fine. Read
- through that thread. It doesn't have to be the main
- thread pid. */
- pid_t tid = pid_arg->tid_attached;
- if (tid != 0)
- pid = tid;
- else
- detach = __libdwfl_ptrace_attach (pid, &tid_was_stopped);
- }
-
- char *fname;
- if (asprintf (&fname, PROCMEMFMT, pid) < 0)
- goto detach;
-
- int fd = open64 (fname, O_RDONLY);
- free (fname);
- if (fd < 0)
- goto detach;
-
- *elfp = elf_from_remote_memory (base, getpagesize (), NULL,
- &read_proc_memory, &fd);
-
- close (fd);
-
- *file_name = NULL;
-
- detach:
- if (detach)
- __libdwfl_ptrace_detach (pid, tid_was_stopped);
- return -1;
- }
-
- return -1;
-}
-INTDEF (dwfl_linux_proc_find_elf)
diff --git a/src/libdwfl/lzma.c b/src/libdwfl/lzma.c
deleted file mode 100644
index 3edfdc22..00000000
--- a/src/libdwfl/lzma.c
+++ /dev/null
@@ -1,4 +0,0 @@
-/* liblzma is pretty close to zlib and bzlib. */
-
-#define LZMA
-#include "gzip.c"
diff --git a/src/libdwfl/offline.c b/src/libdwfl/offline.c
deleted file mode 100644
index 982ceab0..00000000
--- a/src/libdwfl/offline.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/* Recover relocatibility for addresses computed from debug information.
- Copyright (C) 2005-2009, 2012 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-#include <fcntl.h>
-#include <unistd.h>
-
-/* Since dwfl_report_elf lays out the sections already, this will only be
- called when the section headers of the debuginfo file are being
- consulted instead, or for the section placed at 0. With binutils
- strip-to-debug, the symbol table is in the debuginfo file and relocation
- looks there. */
-int
-dwfl_offline_section_address (Dwfl_Module *mod,
- void **userdata __attribute__ ((unused)),
- const char *modname __attribute__ ((unused)),
- Dwarf_Addr base __attribute__ ((unused)),
- const char *secname __attribute__ ((unused)),
- Elf32_Word shndx,
- const GElf_Shdr *shdr __attribute__ ((unused)),
- Dwarf_Addr *addr)
-{
- assert (mod->e_type == ET_REL);
- assert (shdr->sh_addr == 0);
- assert (shdr->sh_flags & SHF_ALLOC);
- assert (shndx != 0);
-
- if (mod->debug.elf == NULL)
- /* We are only here because sh_addr is zero even though layout is complete.
- The first section in the first file under -e is placed at 0. */
- return 0;
-
- /* The section numbers might not match between the two files.
- The best we can rely on is the order of SHF_ALLOC sections. */
-
- Elf_Scn *ourscn = elf_getscn (mod->debug.elf, shndx);
- Elf_Scn *scn = NULL;
- uint_fast32_t skip_alloc = 0;
- while ((scn = elf_nextscn (mod->debug.elf, scn)) != ourscn)
- {
- assert (scn != NULL);
- GElf_Shdr shdr_mem;
- GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem);
- if (unlikely (sh == NULL))
- return -1;
- if (sh->sh_flags & SHF_ALLOC)
- ++skip_alloc;
- }
-
- scn = NULL;
- while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *main_shdr = gelf_getshdr (scn, &shdr_mem);
- if (unlikely (main_shdr == NULL))
- return -1;
- if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0)
- {
- assert (main_shdr->sh_flags == shdr->sh_flags);
- *addr = main_shdr->sh_addr;
- return 0;
- }
- }
-
- /* This should never happen. */
- return -1;
-}
-INTDEF (dwfl_offline_section_address)
-
-/* Forward declarations. */
-static Dwfl_Module *process_elf (Dwfl *dwfl, const char *name,
- const char *file_name, int fd, Elf *elf);
-static Dwfl_Module *process_archive (Dwfl *dwfl, const char *name,
- const char *file_name, int fd, Elf *elf,
- int (*predicate) (const char *module,
- const char *file));
-
-/* Report one module for an ELF file, or many for an archive.
- Always consumes ELF and FD. */
-static Dwfl_Module *
-process_file (Dwfl *dwfl, const char *name, const char *file_name, int fd,
- Elf *elf, int (*predicate) (const char *module,
- const char *file))
-{
- switch (elf_kind (elf))
- {
- default:
- case ELF_K_NONE:
- __libdwfl_seterrno (elf == NULL ? DWFL_E_LIBELF : DWFL_E_BADELF);
- return NULL;
-
- case ELF_K_ELF:
- return process_elf (dwfl, name, file_name, fd, elf);
-
- case ELF_K_AR:
- return process_archive (dwfl, name, file_name, fd, elf, predicate);
- }
-}
-
-/* Report the open ELF file as a module. Always consumes ELF and FD. */
-static Dwfl_Module *
-process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
- Elf *elf)
-{
- Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf,
- dwfl->offline_next_address, true,
- false);
- if (mod != NULL)
- {
- /* If this is an ET_EXEC file with fixed addresses, the address range
- it consumed may or may not intersect with the arbitrary range we
- will use for relocatable modules. Make sure we always use a free
- range for the offline allocations. If this module did use
- offline_next_address, it may have rounded it up for the module's
- alignment requirements. */
- if ((dwfl->offline_next_address >= mod->low_addr
- || mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE)
- && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE)
- dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE;
-
- /* Don't keep the file descriptor around. */
- if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
- {
- close (mod->main.fd);
- mod->main.fd = -1;
- }
- }
-
- return mod;
-}
-
-/* Always consumes MEMBER. Returns elf_next result on success.
- For errors returns ELF_C_NULL with *MOD set to null. */
-static Elf_Cmd
-process_archive_member (Dwfl *dwfl, const char *name, const char *file_name,
- int (*predicate) (const char *module, const char *file),
- int fd, Elf *member, Dwfl_Module **mod)
-{
- const Elf_Arhdr *h = elf_getarhdr (member);
- if (unlikely (h == NULL))
- {
- __libdwfl_seterrno (DWFL_E_LIBELF);
- fail:
- elf_end (member);
- *mod = NULL;
- return ELF_C_NULL;
- }
-
- if (!strcmp (h->ar_name, "/") || !strcmp (h->ar_name, "//")
- || !strcmp (h->ar_name, "/SYM64/"))
- {
- skip:;
- /* Skip this and go to the next. */
- Elf_Cmd result = elf_next (member);
- elf_end (member);
- return result;
- }
-
- char *member_name;
- if (unlikely (asprintf (&member_name, "%s(%s)", file_name, h->ar_name) < 0))
- {
- nomem:
- __libdwfl_seterrno (DWFL_E_NOMEM);
- elf_end (member);
- *mod = NULL;
- return ELF_C_NULL;
- }
-
- char *module_name = NULL;
- if (name == NULL || name[0] == '\0')
- name = h->ar_name;
- else if (unlikely (asprintf (&module_name, "%s:%s", name, h->ar_name) < 0))
- {
- free (member_name);
- goto nomem;
- }
- else
- name = module_name;
-
- if (predicate != NULL)
- {
- /* Let the predicate decide whether to use this one. */
- int want = (*predicate) (name, member_name);
- if (want <= 0)
- {
- free (member_name);
- free (module_name);
- if (unlikely (want < 0))
- {
- __libdwfl_seterrno (DWFL_E_CB);
- goto fail;
- }
- goto skip;
- }
- }
-
- /* We let __libdwfl_report_elf cache the fd in mod->main.fd,
- though it's the same fd for all the members.
- On module teardown we will close it only on the last Elf reference. */
- *mod = process_file (dwfl, name, member_name, fd, member, predicate);
- free (member_name);
- free (module_name);
-
- if (*mod == NULL) /* process_file called elf_end. */
- return ELF_C_NULL;
-
- /* Advance the archive-reading offset for the next iteration. */
- return elf_next (member);
-}
-
-/* Report each member of the archive as its own module. */
-static Dwfl_Module *
-process_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd,
- Elf *archive,
- int (*predicate) (const char *module, const char *file))
-
-{
- Dwfl_Module *mod = NULL;
- Elf *member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive);
- if (unlikely (member == NULL)) /* Empty archive. */
- {
- __libdwfl_seterrno (DWFL_E_BADELF);
- return NULL;
- }
-
- while (process_archive_member (dwfl, name, file_name, predicate,
- fd, member, &mod) != ELF_C_NULL)
- member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive);
-
- /* We can drop the archive Elf handle even if we're still using members
- in live modules. When the last module's elf_end on a member returns
- zero, that module will close FD. If no modules survived the predicate,
- we are all done with the file right here. */
- if (mod != NULL /* If no modules, caller will clean up. */
- && elf_end (archive) == 0)
- close (fd);
-
- return mod;
-}
-
-Dwfl_Module *
-internal_function
-__libdwfl_report_offline (Dwfl *dwfl, const char *name,
- const char *file_name, int fd, bool closefd,
- int (*predicate) (const char *module,
- const char *file))
-{
- Elf *elf;
- Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, true);
- if (error != DWFL_E_NOERROR)
- {
- __libdwfl_seterrno (error);
- return NULL;
- }
- Dwfl_Module *mod = process_file (dwfl, name, file_name, fd, elf, predicate);
- if (mod == NULL)
- {
- elf_end (elf);
- if (closefd)
- close (fd);
- }
- return mod;
-}
-
-Dwfl_Module *
-dwfl_report_offline (Dwfl *dwfl, const char *name,
- const char *file_name, int fd)
-{
- if (dwfl == NULL)
- return NULL;
-
- bool closefd = false;
- if (fd < 0)
- {
- closefd = true;
- fd = open64 (file_name, O_RDONLY);
- if (fd < 0)
- {
- __libdwfl_seterrno (DWFL_E_ERRNO);
- return NULL;
- }
- }
-
- return __libdwfl_report_offline (dwfl, name, file_name, fd, closefd, NULL);
-}
-INTDEF (dwfl_report_offline)
diff --git a/src/libdwfl/open.c b/src/libdwfl/open.c
deleted file mode 100644
index 40aac388..00000000
--- a/src/libdwfl/open.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Decompression support for libdwfl: zlib (gzip) and/or bzlib (bzip2).
- Copyright (C) 2009 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "../libelf/libelfP.h"
-#undef _
-#include "libdwflP.h"
-
-#include <unistd.h>
-
-#if !USE_ZLIB
-# define __libdw_gunzip(...) DWFL_E_BADELF
-#endif
-
-#if !USE_BZLIB
-# define __libdw_bunzip2(...) DWFL_E_BADELF
-#endif
-
-#if !USE_LZMA
-# define __libdw_unlzma(...) DWFL_E_BADELF
-#endif
-
-/* Consumes and replaces *ELF only on success. */
-static Dwfl_Error
-decompress (int fd __attribute__ ((unused)), Elf **elf)
-{
- Dwfl_Error error = DWFL_E_BADELF;
- void *buffer = NULL;
- size_t size = 0;
-
-#if USE_ZLIB || USE_BZLIB || USE_LZMA
- const off64_t offset = (*elf)->start_offset;
- void *const mapped = ((*elf)->map_address == NULL ? NULL
- : (*elf)->map_address + offset);
- const size_t mapped_size = (*elf)->maximum_size;
- if (mapped_size == 0)
- return error;
-
- error = __libdw_gunzip (fd, offset, mapped, mapped_size, &buffer, &size);
- if (error == DWFL_E_BADELF)
- error = __libdw_bunzip2 (fd, offset, mapped, mapped_size, &buffer, &size);
- if (error == DWFL_E_BADELF)
- error = __libdw_unlzma (fd, offset, mapped, mapped_size, &buffer, &size);
-#endif
-
- if (error == DWFL_E_NOERROR)
- {
- if (unlikely (size == 0))
- {
- error = DWFL_E_BADELF;
- free (buffer);
- }
- else
- {
- Elf *memelf = elf_memory (buffer, size);
- if (memelf == NULL)
- {
- error = DWFL_E_LIBELF;
- free (buffer);
- }
- else
- {
- memelf->flags |= ELF_F_MALLOCED;
- elf_end (*elf);
- *elf = memelf;
- }
- }
- }
- else
- free (buffer);
-
- return error;
-}
-
-static Dwfl_Error
-what_kind (int fd, Elf **elfp, Elf_Kind *kind, bool *close_fd)
-{
- Dwfl_Error error = DWFL_E_NOERROR;
- *kind = elf_kind (*elfp);
- if (unlikely (*kind == ELF_K_NONE))
- {
- if (unlikely (*elfp == NULL))
- error = DWFL_E_LIBELF;
- else
- {
- error = decompress (fd, elfp);
- if (error == DWFL_E_NOERROR)
- {
- *close_fd = true;
- *kind = elf_kind (*elfp);
- }
- }
- }
- return error;
-}
-
-Dwfl_Error internal_function
-__libdw_open_file (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok)
-{
- bool close_fd = false;
-
- Elf *elf = elf_begin (*fdp, ELF_C_READ_MMAP_PRIVATE, NULL);
-
- Elf_Kind kind;
- Dwfl_Error error = what_kind (*fdp, &elf, &kind, &close_fd);
- if (error == DWFL_E_BADELF)
- {
- /* It's not an ELF file or a compressed file.
- See if it's an image with a header preceding the real file. */
-
- off64_t offset = elf->start_offset;
- error = __libdw_image_header (*fdp, &offset,
- (elf->map_address == NULL ? NULL
- : elf->map_address + offset),
- elf->maximum_size);
- if (error == DWFL_E_NOERROR)
- {
- /* Pure evil. libelf needs some better interfaces. */
- elf->kind = ELF_K_AR;
- elf->state.ar.elf_ar_hdr.ar_name = "libdwfl is faking you out";
- elf->state.ar.elf_ar_hdr.ar_size = elf->maximum_size - offset;
- elf->state.ar.offset = offset - sizeof (struct ar_hdr);
- Elf *subelf = elf_begin (-1, ELF_C_READ_MMAP_PRIVATE, elf);
- elf->kind = ELF_K_NONE;
- if (unlikely (subelf == NULL))
- error = DWFL_E_LIBELF;
- else
- {
- subelf->parent = NULL;
- subelf->flags |= elf->flags & (ELF_F_MMAPPED | ELF_F_MALLOCED);
- elf->flags &= ~(ELF_F_MMAPPED | ELF_F_MALLOCED);
- elf_end (elf);
- elf = subelf;
- error = what_kind (*fdp, &elf, &kind, &close_fd);
- }
- }
- }
-
- if (error == DWFL_E_NOERROR
- && kind != ELF_K_ELF
- && !(archive_ok && kind == ELF_K_AR))
- error = DWFL_E_BADELF;
-
- if (error != DWFL_E_NOERROR)
- {
- elf_end (elf);
- elf = NULL;
- }
-
- if (error == DWFL_E_NOERROR ? close_fd : close_on_fail)
- {
- close (*fdp);
- *fdp = -1;
- }
-
- *elfp = elf;
- return error;
-}
diff --git a/src/libdwfl/relocate.c b/src/libdwfl/relocate.c
deleted file mode 100644
index e102e1e4..00000000
--- a/src/libdwfl/relocate.c
+++ /dev/null
@@ -1,683 +0,0 @@
-/* Relocate debug information.
- Copyright (C) 2005-2011, 2014 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-typedef uint8_t GElf_Byte;
-
-/* Adjust *VALUE to add the load address of the SHNDX section.
- We update the section header in place to cache the result. */
-
-Dwfl_Error
-internal_function
-__libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
- Elf32_Word shndx, GElf_Addr *value)
-{
- /* No adjustment needed for section zero, it is never loaded.
- Handle it first, just in case the ELF file has strange section
- zero flags set. */
- if (shndx == 0)
- return DWFL_E_NOERROR;
-
- Elf_Scn *refscn = elf_getscn (elf, shndx);
- GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
- if (refshdr == NULL)
- return DWFL_E_LIBELF;
-
- if (refshdr->sh_addr == 0 && (refshdr->sh_flags & SHF_ALLOC))
- {
- /* This is a loaded section. Find its actual
- address and update the section header. */
-
- if (*shstrndx == SHN_UNDEF
- && unlikely (elf_getshdrstrndx (elf, shstrndx) < 0))
- return DWFL_E_LIBELF;
-
- const char *name = elf_strptr (elf, *shstrndx, refshdr->sh_name);
- if (unlikely (name == NULL))
- return DWFL_E_LIBELF;
-
- if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod),
- name, shndx, refshdr,
- &refshdr->sh_addr))
- return CBFAIL;
-
- if (refshdr->sh_addr == (Dwarf_Addr) -1l)
- /* The callback indicated this section wasn't really loaded but we
- don't really care. */
- refshdr->sh_addr = 0; /* Make no adjustment below. */
-
- /* Update the in-core file's section header to show the final
- load address (or unloadedness). This serves as a cache,
- so we won't get here again for the same section. */
- if (likely (refshdr->sh_addr != 0)
- && unlikely (! gelf_update_shdr (refscn, refshdr)))
- return DWFL_E_LIBELF;
- }
-
- if (refshdr->sh_flags & SHF_ALLOC)
- /* Apply the adjustment. */
- *value += dwfl_adjusted_address (mod, refshdr->sh_addr);
-
- return DWFL_E_NOERROR;
-}
-
-
-/* Cache used by relocate_getsym. */
-struct reloc_symtab_cache
-{
- Elf *symelf;
- Elf_Data *symdata;
- Elf_Data *symxndxdata;
- Elf_Data *symstrdata;
- size_t symshstrndx;
- size_t strtabndx;
-};
-#define RELOC_SYMTAB_CACHE(cache) \
- struct reloc_symtab_cache cache = \
- { NULL, NULL, NULL, NULL, SHN_UNDEF, SHN_UNDEF }
-
-/* This is just doing dwfl_module_getsym, except that we must always use
- the symbol table in RELOCATED itself when it has one, not MOD->symfile. */
-static Dwfl_Error
-relocate_getsym (Dwfl_Module *mod,
- Elf *relocated, struct reloc_symtab_cache *cache,
- int symndx, GElf_Sym *sym, GElf_Word *shndx)
-{
- if (cache->symdata == NULL)
- {
- if (mod->symfile == NULL || mod->symfile->elf != relocated)
- {
- /* We have to look up the symbol table in the file we are
- relocating, if it has its own. These reloc sections refer to
- the symbol table in this file, and a symbol table in the main
- file might not match. However, some tools did produce ET_REL
- .debug files with relocs but no symtab of their own. */
- Elf_Scn *scn = NULL;
- while ((scn = elf_nextscn (relocated, scn)) != NULL)
- {
- GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr != NULL)
- switch (shdr->sh_type)
- {
- default:
- continue;
- case SHT_SYMTAB:
- cache->symelf = relocated;
- cache->symdata = elf_getdata (scn, NULL);
- cache->strtabndx = shdr->sh_link;
- if (unlikely (cache->symdata == NULL))
- return DWFL_E_LIBELF;
- break;
- case SHT_SYMTAB_SHNDX:
- cache->symxndxdata = elf_getdata (scn, NULL);
- if (unlikely (cache->symxndxdata == NULL))
- return DWFL_E_LIBELF;
- break;
- }
- if (cache->symdata != NULL && cache->symxndxdata != NULL)
- break;
- }
- }
- if (cache->symdata == NULL)
- {
- /* We might not have looked for a symbol table file yet,
- when coming from __libdwfl_relocate_section. */
- if (unlikely (mod->symfile == NULL)
- && unlikely (INTUSE(dwfl_module_getsymtab) (mod) < 0))
- return dwfl_errno ();
-
- /* The symbol table we have already cached is the one from
- the file being relocated, so it's what we need. Or else
- this is an ET_REL .debug file with no .symtab of its own;
- the symbols refer to the section indices in the main file. */
- cache->symelf = mod->symfile->elf;
- cache->symdata = mod->symdata;
- cache->symxndxdata = mod->symxndxdata;
- cache->symstrdata = mod->symstrdata;
- }
- }
-
- if (unlikely (gelf_getsymshndx (cache->symdata, cache->symxndxdata,
- symndx, sym, shndx) == NULL))
- return DWFL_E_LIBELF;
-
- if (sym->st_shndx != SHN_XINDEX)
- *shndx = sym->st_shndx;
-
- switch (sym->st_shndx)
- {
- case SHN_ABS:
- case SHN_UNDEF:
- return DWFL_E_NOERROR;
-
- case SHN_COMMON:
- sym->st_value = 0; /* Value is size, not helpful. */
- return DWFL_E_NOERROR;
- }
-
- return __libdwfl_relocate_value (mod, cache->symelf, &cache->symshstrndx,
- *shndx, &sym->st_value);
-}
-
-/* Handle an undefined symbol. We really only support ET_REL for Linux
- kernel modules, and offline archives. The behavior of the Linux module
- loader is very simple and easy to mimic. It only matches magically
- exported symbols, and we match any defined symbols. But we get the same
- answer except when the module's symbols are undefined and would prevent
- it from being loaded. */
-static Dwfl_Error
-resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab,
- GElf_Sym *sym, GElf_Word shndx)
-{
- /* First we need its name. */
- if (sym->st_name != 0)
- {
- if (symtab->symstrdata == NULL)
- {
- /* Cache the strtab for this symtab. */
- assert (referer->symfile == NULL
- || referer->symfile->elf != symtab->symelf);
- symtab->symstrdata = elf_getdata (elf_getscn (symtab->symelf,
- symtab->strtabndx),
- NULL);
- if (unlikely (symtab->symstrdata == NULL
- || symtab->symstrdata->d_buf == NULL))
- return DWFL_E_LIBELF;
- }
- if (unlikely (sym->st_name >= symtab->symstrdata->d_size))
- return DWFL_E_BADSTROFF;
-
- const char *name = symtab->symstrdata->d_buf;
- name += sym->st_name;
-
- for (Dwfl_Module *m = referer->dwfl->modulelist; m != NULL; m = m->next)
- if (m != referer)
- {
- /* Get this module's symtab.
- If we got a fresh error reading the table, report it.
- If we just have no symbols in this module, no harm done. */
- if (m->symdata == NULL
- && m->symerr == DWFL_E_NOERROR
- && INTUSE(dwfl_module_getsymtab) (m) < 0
- && m->symerr != DWFL_E_NO_SYMTAB)
- return m->symerr;
-
- for (size_t ndx = 1; ndx < m->syments; ++ndx)
- {
- sym = gelf_getsymshndx (m->symdata, m->symxndxdata,
- ndx, sym, &shndx);
- if (unlikely (sym == NULL))
- return DWFL_E_LIBELF;
- if (sym->st_shndx != SHN_XINDEX)
- shndx = sym->st_shndx;
-
- /* We are looking for a defined global symbol with a name. */
- if (shndx == SHN_UNDEF || shndx == SHN_COMMON
- || GELF_ST_BIND (sym->st_info) == STB_LOCAL
- || sym->st_name == 0)
- continue;
-
- /* Get this candidate symbol's name. */
- if (unlikely (sym->st_name >= m->symstrdata->d_size))
- return DWFL_E_BADSTROFF;
- const char *n = m->symstrdata->d_buf;
- n += sym->st_name;
-
- /* Does the name match? */
- if (strcmp (name, n))
- continue;
-
- /* We found it! */
- if (shndx == SHN_ABS) /* XXX maybe should apply bias? */
- return DWFL_E_NOERROR;
-
- if (m->e_type != ET_REL)
- {
- sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf,
- sym->st_value);
- return DWFL_E_NOERROR;
- }
-
- /* In an ET_REL file, the symbol table values are relative
- to the section, not to the module's load base. */
- size_t symshstrndx = SHN_UNDEF;
- return __libdwfl_relocate_value (m, m->symfile->elf,
- &symshstrndx,
- shndx, &sym->st_value);
- }
- }
- }
-
- return DWFL_E_RELUNDEF;
-}
-
-static Dwfl_Error
-relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
- size_t shstrndx, struct reloc_symtab_cache *reloc_symtab,
- Elf_Scn *scn, GElf_Shdr *shdr,
- Elf_Scn *tscn, bool debugscn, bool partial)
-{
- /* First, fetch the name of the section these relocations apply to. */
- GElf_Shdr tshdr_mem;
- GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
- const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name);
- if (tname == NULL)
- return DWFL_E_LIBELF;
-
- if (unlikely (tshdr->sh_type == SHT_NOBITS) || unlikely (tshdr->sh_size == 0))
- /* No contents to relocate. */
- return DWFL_E_NOERROR;
-
- if (debugscn && ! ebl_debugscn_p (mod->ebl, tname))
- /* This relocation section is not for a debugging section.
- Nothing to do here. */
- return DWFL_E_NOERROR;
-
- /* Fetch the section data that needs the relocations applied. */
- Elf_Data *tdata = elf_rawdata (tscn, NULL);
- if (tdata == NULL)
- return DWFL_E_LIBELF;
-
- /* If either the section that needs the relocation applied, or the
- section that the relocations come from overlap one of the ehdrs,
- shdrs or phdrs data then we refuse to do the relocations. It
- isn't illegal for ELF section data to overlap the header data,
- but updating the (relocation) data might corrupt the in-memory
- libelf headers causing strange corruptions or errors. */
- size_t ehsize = gelf_fsize (relocated, ELF_T_EHDR, 1, EV_CURRENT);
- if (unlikely (shdr->sh_offset < ehsize
- || tshdr->sh_offset < ehsize))
- return DWFL_E_BADELF;
-
- GElf_Off shdrs_start = ehdr->e_shoff;
- size_t shnums;
- if (elf_getshdrnum (relocated, &shnums) < 0)
- return DWFL_E_LIBELF;
- /* Overflows will have been checked by elf_getshdrnum/get|rawdata. */
- size_t shentsize = gelf_fsize (relocated, ELF_T_SHDR, 1, EV_CURRENT);
- GElf_Off shdrs_end = shdrs_start + shnums * shentsize;
- if (unlikely ((shdrs_start < shdr->sh_offset + shdr->sh_size
- && shdr->sh_offset < shdrs_end)
- || (shdrs_start < tshdr->sh_offset + tshdr->sh_size
- && tshdr->sh_offset < shdrs_end)))
- return DWFL_E_BADELF;
-
- GElf_Off phdrs_start = ehdr->e_phoff;
- size_t phnums;
- if (elf_getphdrnum (relocated, &phnums) < 0)
- return DWFL_E_LIBELF;
- if (phdrs_start != 0 && phnums != 0)
- {
- /* Overflows will have been checked by elf_getphdrnum/get|rawdata. */
- size_t phentsize = gelf_fsize (relocated, ELF_T_PHDR, 1, EV_CURRENT);
- GElf_Off phdrs_end = phdrs_start + phnums * phentsize;
- if (unlikely ((phdrs_start < shdr->sh_offset + shdr->sh_size
- && shdr->sh_offset < phdrs_end)
- || (phdrs_start < tshdr->sh_offset + tshdr->sh_size
- && tshdr->sh_offset < phdrs_end)))
- return DWFL_E_BADELF;
- }
-
- /* Apply one relocation. Returns true for any invalid data. */
- Dwfl_Error relocate (GElf_Addr offset, const GElf_Sxword *addend,
- int rtype, int symndx)
- {
- /* First see if this is a reloc we can handle.
- If we are skipping it, don't bother resolving the symbol. */
-
- if (unlikely (rtype == 0))
- /* In some odd situations, the linker can leave R_*_NONE relocs
- behind. This is probably bogus ld -r behavior, but the only
- cases it's known to appear in are harmless: DWARF data
- referring to addresses in a section that has been discarded.
- So we just pretend it's OK without further relocation. */
- return DWFL_E_NOERROR;
-
- Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
- if (unlikely (type == ELF_T_NUM))
- return DWFL_E_BADRELTYPE;
-
- /* First, resolve the symbol to an absolute value. */
- GElf_Addr value;
-
- if (symndx == STN_UNDEF)
- /* When strip removes a section symbol referring to a
- section moved into the debuginfo file, it replaces
- that symbol index in relocs with STN_UNDEF. We
- don't actually need the symbol, because those relocs
- are always references relative to the nonallocated
- debugging sections, which start at zero. */
- value = 0;
- else
- {
- GElf_Sym sym;
- GElf_Word shndx;
- Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab,
- symndx, &sym, &shndx);
- if (unlikely (error != DWFL_E_NOERROR))
- return error;
-
- if (shndx == SHN_UNDEF || shndx == SHN_COMMON)
- {
- /* Maybe we can figure it out anyway. */
- error = resolve_symbol (mod, reloc_symtab, &sym, shndx);
- if (error != DWFL_E_NOERROR
- && !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON))
- return error;
- }
-
- value = sym.st_value;
- }
-
- /* These are the types we can relocate. */
-#define TYPES DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half); \
- DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword); \
- DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
- size_t size;
- switch (type)
- {
-#define DO_TYPE(NAME, Name) \
- case ELF_T_##NAME: \
- size = sizeof (GElf_##Name); \
- break
- TYPES;
-#undef DO_TYPE
- default:
- return DWFL_E_BADRELTYPE;
- }
-
- if (offset > tdata->d_size || tdata->d_size - offset < size)
- return DWFL_E_BADRELOFF;
-
-#define DO_TYPE(NAME, Name) GElf_##Name Name;
- union { TYPES; } tmpbuf;
-#undef DO_TYPE
- Elf_Data tmpdata =
- {
- .d_type = type,
- .d_buf = &tmpbuf,
- .d_size = size,
- .d_version = EV_CURRENT,
- };
- Elf_Data rdata =
- {
- .d_type = type,
- .d_buf = tdata->d_buf + offset,
- .d_size = size,
- .d_version = EV_CURRENT,
- };
-
- /* XXX check for overflow? */
- if (addend)
- {
- /* For the addend form, we have the value already. */
- value += *addend;
- switch (type)
- {
-#define DO_TYPE(NAME, Name) \
- case ELF_T_##NAME: \
- tmpbuf.Name = value; \
- break
- TYPES;
-#undef DO_TYPE
- default:
- abort ();
- }
- }
- else
- {
- /* Extract the original value and apply the reloc. */
- Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
- ehdr->e_ident[EI_DATA]);
- if (d == NULL)
- return DWFL_E_LIBELF;
- assert (d == &tmpdata);
- switch (type)
- {
-#define DO_TYPE(NAME, Name) \
- case ELF_T_##NAME: \
- tmpbuf.Name += (GElf_##Name) value; \
- break
- TYPES;
-#undef DO_TYPE
- default:
- abort ();
- }
- }
-
- /* Now convert the relocated datum back to the target
- format. This will write into rdata.d_buf, which
- points into the raw section data being relocated. */
- Elf_Data *s = gelf_xlatetof (relocated, &rdata, &tmpdata,
- ehdr->e_ident[EI_DATA]);
- if (s == NULL)
- return DWFL_E_LIBELF;
- assert (s == &rdata);
-
- /* We have applied this relocation! */
- return DWFL_E_NOERROR;
- }
-
- /* Fetch the relocation section and apply each reloc in it. */
- Elf_Data *reldata = elf_getdata (scn, NULL);
- if (reldata == NULL)
- return DWFL_E_LIBELF;
-
- Dwfl_Error result = DWFL_E_NOERROR;
- bool first_badreltype = true;
- inline void check_badreltype (void)
- {
- if (first_badreltype)
- {
- first_badreltype = false;
- if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
- /* This might be because ebl_openbackend failed to find
- any libebl_CPU.so library. Diagnose that clearly. */
- result = DWFL_E_UNKNOWN_MACHINE;
- }
- }
-
- size_t sh_entsize
- = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
- 1, EV_CURRENT);
- size_t nrels = shdr->sh_size / sh_entsize;
- size_t complete = 0;
- if (shdr->sh_type == SHT_REL)
- for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
- {
- GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem);
- if (r == NULL)
- return DWFL_E_LIBELF;
- result = relocate (r->r_offset, NULL,
- GELF_R_TYPE (r->r_info),
- GELF_R_SYM (r->r_info));
- check_badreltype ();
- if (partial)
- switch (result)
- {
- case DWFL_E_NOERROR:
- /* We applied the relocation. Elide it. */
- memset (&rel_mem, 0, sizeof rel_mem);
- gelf_update_rel (reldata, relidx, &rel_mem);
- ++complete;
- break;
- case DWFL_E_BADRELTYPE:
- case DWFL_E_RELUNDEF:
- /* We couldn't handle this relocation. Skip it. */
- result = DWFL_E_NOERROR;
- break;
- default:
- break;
- }
- }
- else
- for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
- {
- GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx,
- &rela_mem);
- if (r == NULL)
- return DWFL_E_LIBELF;
- result = relocate (r->r_offset, &r->r_addend,
- GELF_R_TYPE (r->r_info),
- GELF_R_SYM (r->r_info));
- check_badreltype ();
- if (partial)
- switch (result)
- {
- case DWFL_E_NOERROR:
- /* We applied the relocation. Elide it. */
- memset (&rela_mem, 0, sizeof rela_mem);
- gelf_update_rela (reldata, relidx, &rela_mem);
- ++complete;
- break;
- case DWFL_E_BADRELTYPE:
- case DWFL_E_RELUNDEF:
- /* We couldn't handle this relocation. Skip it. */
- result = DWFL_E_NOERROR;
- break;
- default:
- break;
- }
- }
-
- if (likely (result == DWFL_E_NOERROR))
- {
- if (!partial || complete == nrels)
- /* Mark this relocation section as being empty now that we have
- done its work. This affects unstrip -R, so e.g. it emits an
- empty .rela.debug_info along with a .debug_info that has
- already been fully relocated. */
- nrels = 0;
- else if (complete != 0)
- {
- /* We handled some of the relocations but not all.
- We've zeroed out the ones we processed.
- Now remove them from the section. */
-
- size_t next = 0;
- if (shdr->sh_type == SHT_REL)
- for (size_t relidx = 0; relidx < nrels; ++relidx)
- {
- GElf_Rel rel_mem;
- GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
- if (r->r_info != 0 || r->r_offset != 0)
- {
- if (next != relidx)
- gelf_update_rel (reldata, next, r);
- ++next;
- }
- }
- else
- for (size_t relidx = 0; relidx < nrels; ++relidx)
- {
- GElf_Rela rela_mem;
- GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
- if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0)
- {
- if (next != relidx)
- gelf_update_rela (reldata, next, r);
- ++next;
- }
- }
- nrels = next;
- }
-
- shdr->sh_size = reldata->d_size = nrels * sh_entsize;
- gelf_update_shdr (scn, shdr);
- }
-
- return result;
-}
-
-Dwfl_Error
-internal_function
-__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
-{
- assert (mod->e_type == ET_REL);
-
- GElf_Ehdr ehdr_mem;
- const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
- if (ehdr == NULL)
- return DWFL_E_LIBELF;
-
- size_t d_shstrndx;
- if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0)
- return DWFL_E_LIBELF;
-
- RELOC_SYMTAB_CACHE (reloc_symtab);
-
- /* Look at each section in the debuginfo file, and process the
- relocation sections for debugging sections. */
- Dwfl_Error result = DWFL_E_NOERROR;
- Elf_Scn *scn = NULL;
- while (result == DWFL_E_NOERROR
- && (scn = elf_nextscn (debugfile, scn)) != NULL)
- {
- GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
-
- if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
- && shdr->sh_size != 0)
- {
- /* It's a relocation section. */
-
- Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
- if (unlikely (tscn == NULL))
- result = DWFL_E_LIBELF;
- else
- result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
- &reloc_symtab, scn, shdr, tscn,
- debug, !debug);
- }
- }
-
- return result;
-}
-
-Dwfl_Error
-internal_function
-__libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
- Elf_Scn *relocscn, Elf_Scn *tscn, bool partial)
-{
- GElf_Ehdr ehdr_mem;
- GElf_Shdr shdr_mem;
-
- RELOC_SYMTAB_CACHE (reloc_symtab);
-
- size_t shstrndx;
- if (elf_getshdrstrndx (relocated, &shstrndx) < 0)
- return DWFL_E_LIBELF;
-
- return (__libdwfl_module_getebl (mod)
- ?: relocate_section (mod, relocated,
- gelf_getehdr (relocated, &ehdr_mem), shstrndx,
- &reloc_symtab,
- relocscn, gelf_getshdr (relocscn, &shdr_mem),
- tscn, false, partial));
-}
diff --git a/src/libdwfl/segment.c b/src/libdwfl/segment.c
deleted file mode 100644
index 92769174..00000000
--- a/src/libdwfl/segment.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/* Manage address space lookup table for libdwfl.
- Copyright (C) 2008, 2009, 2010, 2013 Red Hat, Inc.
- This file is part of elfutils.
-
- This file is free software; you can redistribute it and/or modify
- it under the terms of either
-
- * the GNU Lesser General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at
- your option) any later version
-
- or
-
- * the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at
- your option) any later version
-
- or both in parallel, as here.
-
- elfutils is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received copies of the GNU General Public License and
- the GNU Lesser General Public License along with this program. If
- not, see <http://www.gnu.org/licenses/>. */
-
-#include "libdwflP.h"
-
-GElf_Addr
-internal_function
-__libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
-{
- if (dwfl->segment_align > 1)
- start &= -dwfl->segment_align;
- return start;
-}
-
-GElf_Addr
-internal_function
-__libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end)
-{
- if (dwfl->segment_align > 1)
- end = (end + dwfl->segment_align - 1) & -dwfl->segment_align;
- return end;
-}
-
-static bool
-insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx)
-{
- bool need_start = (i == 0 || dwfl->lookup_addr[i - 1] != start);
- bool need_end = (i >= dwfl->lookup_elts || dwfl->lookup_addr[i + 1] != end);
- size_t need = need_start + need_end;
- if (need == 0)
- return false;
-
- if (dwfl->lookup_alloc - dwfl->lookup_elts < need)
- {
- size_t n = dwfl->lookup_alloc == 0 ? 16 : dwfl->lookup_alloc * 2;
- GElf_Addr *naddr = realloc (dwfl->lookup_addr, sizeof naddr[0] * n);
- if (unlikely (naddr == NULL))
- return true;
- int *nsegndx = realloc (dwfl->lookup_segndx, sizeof nsegndx[0] * n);
- if (unlikely (nsegndx == NULL))
- {
- if (naddr != dwfl->lookup_addr)
- free (naddr);
- return true;
- }
- dwfl->lookup_alloc = n;
- dwfl->lookup_addr = naddr;
- dwfl->lookup_segndx = nsegndx;
-
- if (dwfl->lookup_module != NULL)
- {
- /* Make sure this array is big enough too. */
- Dwfl_Module **old = dwfl->lookup_module;
- dwfl->lookup_module = realloc (dwfl->lookup_module,
- sizeof dwfl->lookup_module[0] * n);
- if (unlikely (dwfl->lookup_module == NULL))
- {
- free (old);
- return true;
- }
- }
- }
-
- if (unlikely (i < dwfl->lookup_elts))
- {
- const size_t move = dwfl->lookup_elts - i;
- memmove (&dwfl->lookup_addr[i + need], &dwfl->lookup_addr[i],
- move * sizeof dwfl->lookup_addr[0]);
- memmove (&dwfl->lookup_segndx[i + need], &dwfl->lookup_segndx[i],
- move * sizeof dwfl->lookup_segndx[0]);
- if (dwfl->lookup_module != NULL)
- memmove (&dwfl->lookup_module[i + need], &dwfl->lookup_module[i],
- move * sizeof dwfl->lookup_module[0]);
- }
-
- if (need_start)
- {
- dwfl->lookup_addr[i] = start;
- dwfl->lookup_segndx[i] = segndx;
- if (dwfl->lookup_module != NULL)
- dwfl->lookup_module[i] = NULL;
- ++i;
- }
- else
- dwfl->lookup_segndx[i - 1] = segndx;
-
- if (need_end)
- {
- dwfl->lookup_addr[i] = end;
- dwfl->lookup_segndx[i] = -1;
- if (dwfl->lookup_module != NULL)
- dwfl->lookup_module[i] = NULL;
- }
-
- dwfl->lookup_elts += need;
-
- return false;
-}
-
-static int
-lookup (Dwfl *dwfl, GElf_Addr address, int hint)
-{
- if (hint >= 0
- && address >= dwfl->lookup_addr[hint]
- && ((size_t) hint + 1 == dwfl->lookup_elts
- || address < dwfl->lookup_addr[hint + 1]))
- return hint;
-
- /* Do binary search on the array indexed by module load address. */
- size_t l = 0, u = dwfl->lookup_elts;
- while (l < u)
- {
- size_t idx = (l + u) / 2;
- if (address < dwfl->lookup_addr[idx])
- u = idx;
- else
- {
- l = idx + 1;
- if (l == dwfl->lookup_elts || address < dwfl->lookup_addr[l])
- return idx;
- }
- }
-
- return -1;
-}
-
-static bool
-reify_segments (Dwfl *dwfl)
-{
- int hint = -1;
- int highest = -1;
- bool fixup = false;
- for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
- if (! mod->gc)
- {
- const GElf_Addr start = __libdwfl_segment_start (dwfl, mod->low_addr);
- const GElf_Addr end = __libdwfl_segment_end (dwfl, mod->high_addr);
- bool resized = false;
-
- int idx = lookup (dwfl, start, hint);
- if (unlikely (idx < 0))
- {
- /* Module starts below any segment. Insert a low one. */
- if (unlikely (insert (dwfl, 0, start, end, -1)))
- return true;
- idx = 0;
- resized = true;
- }
- else if (dwfl->lookup_addr[idx] > start)
- {
- /* The module starts in the middle of this segment. Split it. */
- if (unlikely (insert (dwfl, idx + 1, start, end,
- dwfl->lookup_segndx[idx])))
- return true;
- ++idx;
- resized = true;
- }
- else if (dwfl->lookup_addr[idx] < start)
- {
- /* The module starts past the end of this segment.
- Add a new one. */
- if (unlikely (insert (dwfl, idx + 1, start, end, -1)))
- return true;
- ++idx;
- resized = true;
- }
-
- if ((size_t) idx + 1 < dwfl->lookup_elts
- && end < dwfl->lookup_addr[idx + 1])
- {
- /* The module ends in the middle of this segment. Split it. */
- if (unlikely (insert (dwfl, idx + 1,
- end, dwfl->lookup_addr[idx + 1], -1)))
- return true;
- resized = true;
- }
-
- if (dwfl->lookup_module == NULL)
- {
- dwfl->lookup_module = calloc (dwfl->lookup_alloc,
- sizeof dwfl->lookup_module[0]);
- if (unlikely (dwfl->lookup_module == NULL))
- return true;
- }
-
- /* Cache a backpointer in the module. */
- mod->segment = idx;
-
- /* Put MOD in the table for each segment that's inside it. */
- do
- dwfl->lookup_module[idx++] = mod;
- while ((size_t) idx < dwfl->lookup_elts
- && dwfl->lookup_addr[idx] < end);
- assert (dwfl->lookup_module[mod->segment] == mod);
-
- if (resized && idx - 1 >= highest)
- /* Expanding the lookup tables invalidated backpointers
- we've already stored. Reset those ones. */
- fixup = true;
-
- highest = idx - 1;
- hint = (size_t) idx < dwfl->lookup_elts ? idx : -1;
- }
-
- if (fixup)
- /* Reset backpointer indices invalidated by table insertions. */
- for (size_t idx = 0; idx < dwfl->lookup_elts; ++idx)
- if (dwfl->lookup_module[idx] != NULL)
- dwfl->lookup_module[idx]->segment = idx;
-
- return false;
-}
-
-int
-dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod)
-{
- if (unlikely (dwfl == NULL))
- return -1;
-
- if (unlikely (dwfl->lookup_module == NULL)
- && mod != NULL
- && unlikely (reify_segments (dwfl)))
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
-
- int idx = lookup (dwfl, address, -1);
- if (likely (mod != NULL))
- {
- if (unlikely (idx < 0) || unlikely (dwfl->lookup_module == NULL))
- *mod = NULL;
- else
- {
- *mod = dwfl->lookup_module[idx];
-
- /* If this segment does not have a module, but the address is
- the upper boundary of the previous segment's module, use that. */
- if (*mod == NULL && idx > 0 && dwfl->lookup_addr[idx] == address)
- {
- *mod = dwfl->lookup_module[idx - 1];
- if (*mod != NULL && (*mod)->high_addr != address)
- *mod = NULL;
- }
- }
- }
-
- if (likely (idx >= 0))
- /* Translate internal segment table index to user segment index. */
- idx = dwfl->lookup_segndx[idx];
-
- return idx;
-}
-INTDEF (dwfl_addrsegment)
-
-int
-dwfl_report_segment (Dwfl *dwfl, int ndx, const GElf_Phdr *phdr, GElf_Addr bias,
- const void *ident)
-{
- if (dwfl == NULL)
- return -1;
-
- if (ndx < 0)
- ndx = dwfl->lookup_tail_ndx;
-
- if (phdr->p_align > 1 && (dwfl->segment_align <= 1 ||
- phdr->p_align < dwfl->segment_align))
- dwfl->segment_align = phdr->p_align;
-
- if (unlikely (dwfl->lookup_module != NULL))
- {
- free (dwfl->lookup_module);
- dwfl->lookup_module = NULL;
- }
-
- GElf_Addr start = __libdwfl_segment_start (dwfl, bias + phdr->p_vaddr);
- GElf_Addr end = __libdwfl_segment_end (dwfl,
- bias + phdr->p_vaddr + phdr->p_memsz);
-
- /* Coalesce into the last one if contiguous and matching. */
- if (ndx != dwfl->lookup_tail_ndx
- || ident == NULL
- || ident != dwfl->lookup_tail_ident
- || start != dwfl->lookup_tail_vaddr
- || phdr->p_offset != dwfl->lookup_tail_offset)
- {
- /* Normally just appending keeps us sorted. */
-
- size_t i = dwfl->lookup_elts;
- while (i > 0 && unlikely (start < dwfl->lookup_addr[i - 1]))
- --i;
-
- if (unlikely (insert (dwfl, i, start, end, ndx)))
- {
- __libdwfl_seterrno (DWFL_E_NOMEM);
- return -1;
- }
- }
-
- dwfl->lookup_tail_ident = ident;
- dwfl->lookup_tail_vaddr = end;
- dwfl->lookup_tail_offset = end - bias - phdr->p_vaddr + phdr->p_offset;
- dwfl->lookup_tail_ndx = ndx + 1;
-
- return ndx;
-}
-INTDEF (dwfl_report_segment)