global:
dwarf_cu_dwp_section_info;
} ELFUTILS_0.188;
+
+ELFUTILS_0.192 {
+ global:
+ dwfl_set_sysroot;
+} ELFUTILS_0.191;
dwfl_module_return_value_location.c \
dwfl_module_register_names.c \
dwfl_segment_report_module.c \
+ dwfl_set_sysroot.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 \
ndx = 0;
do
{
- int seg = dwfl_segment_report_module (dwfl, ndx, NULL,
+ int seg = dwfl_segment_report_module (dwfl, ndx, NULL, executable,
&dwfl_elf_phdr_memory_callback, elf,
core_file_read_eagerly, elf,
elf->maximum_size,
free (dwfl->lookup_addr);
free (dwfl->lookup_module);
free (dwfl->lookup_segndx);
+ free (dwfl->sysroot);
Dwfl_Module *next = dwfl->modulelist;
while (next != NULL)
int
dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
+ const char *executable,
Dwfl_Memory_Callback *memory_callback,
void *memory_callback_arg,
Dwfl_Module_Callback *read_eagerly,
name = file_note_name;
name_is_final = true;
bool invalid = false;
- fd = open (name, O_RDONLY);
+
+ /* We were not handed specific executable hence try to look for it in
+ sysroot if it is set. */
+ if (dwfl->sysroot && !executable)
+ {
+ int r;
+ char *n;
+
+ r = asprintf (&n, "%s%s", dwfl->sysroot, name);
+ if (r > 0)
+ {
+ fd = open (n, O_RDONLY);
+ free (n);
+ }
+ }
+ else
+ fd = open (name, O_RDONLY);
+
if (fd >= 0)
{
Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
--- /dev/null
+/* Return one of the sources lines of a CU.
+ Copyright (C) 2024 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 <sys/stat.h>
+
+#include "libdwflP.h"
+#include "libdwP.h"
+
+int
+dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot)
+{
+ if (!sysroot)
+ {
+ free (dwfl->sysroot);
+ dwfl->sysroot = NULL;
+ return 0;
+ }
+
+ char *r, *s;
+ r = realpath (sysroot, NULL);
+ if (!r)
+ return -1;
+
+ int rc;
+ struct stat sb;
+
+ rc = stat (r, &sb);
+ if (rc < 0 || !S_ISDIR (sb.st_mode))
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ rc = asprintf (&s, "%s/", r);
+ if (rc < 0)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ free (dwfl->sysroot);
+ free (r);
+
+ dwfl->sysroot = s;
+ return 0;
+}
+
+INTDEF (dwfl_set_sysroot)
*/
extern debuginfod_client *dwfl_get_debuginfod_client (Dwfl *dwfl);
+/* Set the sysroot to use when searching for shared libraries and binaries. If not
+ specified, search the system root. Passing NULL clears previously set sysroot. Note
+ that library creates a copy of the sysroot argument. */
+int dwfl_set_sysroot (Dwfl *dwfl, const char *sysroot)
+ __nonnull_attribute__ (1);
+
#ifdef __cplusplus
}
#endif
int next_segndx;
struct Dwfl_User_Core *user_core;
+ char *sysroot; /* sysroot, or NULL to search standard system
+ paths */
};
#define OFFLINE_REDZONE 0x10000
/* ...
*/
extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
+ const char *executable,
Dwfl_Memory_Callback *memory_callback,
void *memory_callback_arg,
Dwfl_Module_Callback *read_eagerly,
if (name != NULL)
{
/* This code is mostly inlined dwfl_report_elf. */
- // XXX hook for sysroot
+ char *sysroot_name = NULL;
+ const char *sysroot = dwfl->sysroot;
+
+ /* Don't use the sysroot if the path is already inside it. */
+ bool name_in_sysroot = sysroot && startswith (name, sysroot);
+
+ if (sysroot && !name_in_sysroot)
+ {
+ if (asprintf (&sysroot_name, "%s%s", sysroot, name) < 0)
+ return release_buffer (&memory_closure, &buffer, &buffer_available, -1);
+
+ name = sysroot_name;
+ }
+
int fd = open (name, O_RDONLY);
if (fd >= 0)
{
close (fd);
}
}
+ free(sysroot_name);
}
if (mod != NULL)