diff options
Diffstat (limited to 'libdwfl')
| -rw-r--r-- | libdwfl/ChangeLog | 39 | ||||
| -rw-r--r-- | libdwfl/argp-std.c | 2 | ||||
| -rw-r--r-- | libdwfl/dwfl_build_id_find_elf.c | 9 | ||||
| -rw-r--r-- | libdwfl/dwfl_error.c | 4 | ||||
| -rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 2 | ||||
| -rw-r--r-- | libdwfl/dwfl_report_elf.c | 2 | ||||
| -rw-r--r-- | libdwfl/dwfl_segment_report_module.c | 2 | ||||
| -rw-r--r-- | libdwfl/find-debuginfo.c | 117 | ||||
| -rw-r--r-- | libdwfl/libdwflP.h | 4 | ||||
| -rw-r--r-- | libdwfl/link_map.c | 4 | ||||
| -rw-r--r-- | libdwfl/linux-kernel-modules.c | 24 | ||||
| -rw-r--r-- | libdwfl/linux-pid-attach.c | 6 | ||||
| -rw-r--r-- | libdwfl/linux-proc-maps.c | 14 | ||||
| -rw-r--r-- | libdwfl/offline.c | 2 |
14 files changed, 146 insertions, 85 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index acb4236a..d03268b6 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,40 @@ +2017-05-04 Ulf Hermann <[email protected]> + + * find-debuginfo.c: On windows, check various extra parameters of + struct stat to determine if two files are the same. + +2017-05-04 Ulf Hermann <[email protected]> + + * dwfl_build_id_find_elf.c: Don't assume unix file system conventions. + * find-debuginfo.c: Likewise. + * linux-kernel-modules.c: Likewise. + * linux-proc-maps.c: Likewise. + * libdwflP.h: Add a windows-compatible default debuginfo path. + +2017-05-04 Ulf Hermann <[email protected]> + + * argp-std.c: Open files in O_BINARY. + * dwfl_build_id_find_elf.c: Likewise. + * dwfl_build_id_find_elf.c: Likewise. + * dwfl_module_getdwarf.c: Likewise. + * dwfl_report_elf.c: Likewise. + * dwfl_segment_report_module.c: Likewise. + * find-debuginfo.c: Likewise. + * link_map.c: Likewise. + * linux-kernel-modules.c: Likewise. + * linux-pid-attach.c: Likewise. + * linux-proc-maps.c: Likewise. + * offline.c: Likewise. + +2017-04-27 Ulf Hermann <[email protected]> + + * linux-kernel-modules.c: Don't include system.h. + +2017-02-22 Ulf Hermann <[email protected]> + + * dwfl_error.c: If we don't have a strerror_r returning a char*, + output a less useful message in case of a system error. + 2018-06-04 Mark Wielaard <[email protected]> * libdwflP.h (__libdwfl_addrsym): Remove function declaration. @@ -169,7 +206,7 @@ * linux-pid-attach.c: Include sys/ptrace.h and sys/syscall.h only on linux. -2017-04-20 Ulf Hermann <[email protected]> +2017-04-20 Ulf Hermann <[email protected]> * linux-kernel-modules.c: Include sys/types.h before fts.h diff --git a/libdwfl/argp-std.c b/libdwfl/argp-std.c index 8ee91587..fbdbb231 100644 --- a/libdwfl/argp-std.c +++ b/libdwfl/argp-std.c @@ -280,7 +280,7 @@ parse_opt (int key, char *arg, struct argp_state *state) if (opt->core) { - int fd = open (opt->core, O_RDONLY); + int fd = open (opt->core, O_RDONLY | O_BINARY); if (fd < 0) { int code = errno; diff --git a/libdwfl/dwfl_build_id_find_elf.c b/libdwfl/dwfl_build_id_find_elf.c index cc6c3f62..1cf2751c 100644 --- a/libdwfl/dwfl_build_id_find_elf.c +++ b/libdwfl/dwfl_build_id_find_elf.c @@ -79,13 +79,14 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name, int fd = -1; char *dir; char *paths = path; - while (fd < 0 && (dir = strsep (&paths, ":")) != NULL) + char pathsep[] = { PATHSEP, '\0' }; + while (fd < 0 && (dir = strsep (&paths, pathsep)) != NULL) { if (dir[0] == '+' || dir[0] == '-') ++dir; /* Only absolute directory names are useful to us. */ - if (dir[0] != '/') + if (IS_ABSOLUTE_PATH(dir)) continue; size_t dirlen = strlen (dir); @@ -94,7 +95,7 @@ __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name, break; memcpy (mempcpy (name, dir, dirlen), id_name, sizeof id_name); - fd = TEMP_FAILURE_RETRY (open (name, O_RDONLY)); + fd = TEMP_FAILURE_RETRY (open (name, O_RDONLY | O_BINARY)); if (fd >= 0) { if (*file_name != NULL) @@ -154,7 +155,7 @@ dwfl_build_id_find_elf (Dwfl_Module *mod, recorded executable file when MOD was identified as main executable (which then triggers opening and reporting of the executable). */ const char *executable = mod->dwfl->user_core->executable_for_core; - int fd = open (executable, O_RDONLY); + int fd = open (executable, O_RDONLY | O_BINARY); if (fd >= 0) { *file_name = strdup (executable); diff --git a/libdwfl/dwfl_error.c b/libdwfl/dwfl_error.c index 7bcf61cc..aba3cca8 100644 --- a/libdwfl/dwfl_error.c +++ b/libdwfl/dwfl_error.c @@ -154,7 +154,11 @@ dwfl_errmsg (int error) switch (error &~ 0xffff) { case OTHER_ERROR (ERRNO): +#ifdef STRERROR_R_CHAR_P return strerror_r (error & 0xffff, "bad", 0); +#else + return "Unknown error. See errno"; +#endif case OTHER_ERROR (LIBELF): return elf_errmsg (error & 0xffff); case OTHER_ERROR (LIBDW): diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index af6838a6..095a853f 100644 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@ -51,7 +51,7 @@ open_elf_file (Elf **elf, int *fd, char **name) /* 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 (open (*name, O_RDONLY)); + *fd = TEMP_FAILURE_RETRY (open (*name, O_RDONLY | O_BINARY)); if (*fd < 0) return CBFAIL; diff --git a/libdwfl/dwfl_report_elf.c b/libdwfl/dwfl_report_elf.c index 3fc9384a..57f58538 100644 --- a/libdwfl/dwfl_report_elf.c +++ b/libdwfl/dwfl_report_elf.c @@ -295,7 +295,7 @@ dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd, if (fd < 0) { closefd = true; - fd = open (file_name, O_RDONLY); + fd = open (file_name, O_RDONLY | O_BINARY); if (fd < 0) { __libdwfl_seterrno (DWFL_E_ERRNO); diff --git a/libdwfl/dwfl_segment_report_module.c b/libdwfl/dwfl_segment_report_module.c index 207a2573..cd8f6135 100644 --- a/libdwfl/dwfl_segment_report_module.c +++ b/libdwfl/dwfl_segment_report_module.c @@ -688,7 +688,7 @@ dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name, name = file_note_name; name_is_final = true; bool invalid = false; - fd = open (name, O_RDONLY); + fd = open (name, O_RDONLY | O_BINARY); if (fd >= 0) { Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false); diff --git a/libdwfl/find-debuginfo.c b/libdwfl/find-debuginfo.c index 9267788d..96f98cac 100644 --- a/libdwfl/find-debuginfo.c +++ b/libdwfl/find-debuginfo.c @@ -52,20 +52,30 @@ try_open (const struct stat *main_stat, if (unlikely (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) + else if ((subdir == NULL ? asprintf (&fname, "%s%c%s", dir, DIRSEP, debuglink) + : dir == NULL ? asprintf (&fname, "%s%c%s", subdir, DIRSEP, debuglink) + : asprintf (&fname, "%s%c%s%c%s", dir, DIRSEP, subdir, DIRSEP, + debuglink)) < 0) return -1; struct stat st; - int fd = TEMP_FAILURE_RETRY (open (fname, O_RDONLY)); + int fd = TEMP_FAILURE_RETRY (open (fname, O_RDONLY | O_BINARY)); if (fd < 0) free (fname); else if (fstat (fd, &st) == 0 +#if defined _WIN32 || defined __WIN32__ + /* On windows, st_ino and st_dev are not unique, so we apply a heuristic */ + && st.st_size == main_stat->st_size + && st.st_mode == main_stat->st_mode + && st.st_mtime == main_stat->st_mtime + && st.st_ctime == main_stat->st_ctime +#endif && 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. */ + /* This doesn't happen on windows as windows doesn't have proper links. However, on windows + st_ino and st_dev is always 0. */ free (fname); close (fd); errno = ENOENT; @@ -231,7 +241,8 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, return -1; } char *p; - while ((p = strsep (&path, ":")) != NULL) + const char pathsep[] = { PATHSEP, '\0' }; + while ((p = strsep (&path, pathsep)) != NULL) { /* A leading - or + says whether to check file CRCs for this element. */ bool check = defcheck; @@ -244,53 +255,57 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, bool try_file_basename; 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; - try_file_basename = false; - 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; - /* We want to explore all sub-subdirs. Chop off one slash - at a time. */ - explore_dir: - subdir = strchr (subdir, '/'); - if (subdir != NULL) - subdir = subdir + 1; - if (subdir && *subdir == 0) - continue; - file = debuglink_file; - } - else - { + if (IS_ABSOLUTE_PATH(p)) + { + /* 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 || !IS_ABSOLUTE_PATH(file_dirname))) + continue; + dir = p; + if (mod->dw == NULL) { + subdir = file_dirname; + /* We want to explore all sub-subdirs. Chop off one slash + at a time. */ + explore_dir: + while (subdir && *subdir && !ISDIRSEP(*subdir)) + ++subdir; + if (subdir != NULL && *subdir != 0) + subdir = subdir + 1; + if (subdir && *subdir == 0) + continue; + file = debuglink_file; + } + else + { + subdir = NULL; + file = basename (debuglink_file); + } + try_file_basename = debuglink_null; + } + else + { + switch (p[0]) + { + case '\0': + /* An empty entry says to try the main file's directory. */ + dir = file_dirname; subdir = NULL; - file = basename (debuglink_file); + file = debuglink_file; + try_file_basename = false; + 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; + try_file_basename = debuglink_null; + break; } - try_file_basename = debuglink_null; - 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; - try_file_basename = debuglink_null; - break; } char *fname = NULL; @@ -304,7 +319,7 @@ find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name, 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] == '/')) + if (mod->dw != NULL && (p[0] == '\0' || IS_ABSOLUTE_PATH(p))) { fd = try_open (&main_stat, dir, ".dwz", basename (file), &fname); diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index 31e6e190..dcdb332c 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -771,7 +771,11 @@ INTDECL (dwfl_frame_pc) /* The default used by dwfl_standard_find_debuginfo. */ +#if (defined _WIN32 || defined __WIN32__) +#define DEFAULT_DEBUGINFO_PATH ";.debug" +#else #define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug" +#endif #endif /* libdwflP.h */ diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 29307c74..937cc1a0 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c @@ -389,7 +389,7 @@ report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata, { /* This code is mostly inlined dwfl_report_elf. */ // XXX hook for sysroot - int fd = open (name, O_RDONLY); + int fd = open (name, O_RDONLY | O_BINARY); if (fd >= 0) { Elf *elf; @@ -808,7 +808,7 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the core file. */ - int fd = open (dwfl->user_core->executable_for_core, O_RDONLY); + int fd = open (dwfl->user_core->executable_for_core, O_RDONLY | O_BINARY); Elf *elf; Dwfl_Error error = DWFL_E_ERRNO; if (fd != -1) diff --git a/libdwfl/linux-kernel-modules.c b/libdwfl/linux-kernel-modules.c index 9d0fef2c..4b454d37 100644 --- a/libdwfl/linux-kernel-modules.c +++ b/libdwfl/linux-kernel-modules.c @@ -37,7 +37,6 @@ #endif #include <config.h> -#include <system.h> #include "libdwflP.h" #include <inttypes.h> @@ -49,6 +48,7 @@ #include <sys/utsname.h> #include <fcntl.h> #include <unistd.h> +#include <system.h> /* If fts.h is included before config.h, its indirect inclusions may not give us the right LFS aliases of these functions, so map them manually. */ @@ -97,8 +97,8 @@ try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug) 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 (open (*fname, O_RDONLY))); + ?: DEFAULT_DEBUGINFO_PATH)[0] == PATHSEP) ? -1 + : TEMP_FAILURE_RETRY (open (*fname, O_RDONLY | O_BINARY))); if (fd < 0) { @@ -133,7 +133,7 @@ try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug) char *zname; if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0) { - fd = TEMP_FAILURE_RETRY (open (zname, O_RDONLY)); + fd = TEMP_FAILURE_RETRY (open (zname, O_RDONLY | O_BINARY)); if (fd < 0) free (zname); else @@ -492,7 +492,7 @@ intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes) { struct read_address_state state = { NULL, NULL, 0, 0, NULL, NULL }; - state.f = fopen (KSYMSFILE, "r"); + state.f = fopen (KSYMSFILE, "rb"); if (state.f == NULL) return errno; @@ -535,7 +535,7 @@ static int check_notes (Dwfl_Module *mod, const char *notesfile, Dwarf_Addr vaddr, const char *secname) { - int fd = open (notesfile, O_RDONLY); + int fd = open (notesfile, O_RDONLY | O_BINARY); if (fd < 0) return 1; @@ -793,7 +793,7 @@ dwfl_linux_kernel_find_elf (Dwfl_Module *mod, && (!memcmp (f->fts_name, module_name, namelen) || !memcmp (f->fts_name, alternate_name, namelen))) { - int fd = open (f->fts_accpath, O_RDONLY); + int fd = open (f->fts_accpath, O_RDONLY | O_BINARY); *file_name = strdup (f->fts_path); fts_close (fts); free (modulesdir[0]); @@ -846,7 +846,7 @@ dwfl_linux_kernel_module_section_address if (asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname) < 0) return DWARF_CB_ABORT; - FILE *f = fopen (sysfile, "r"); + FILE *f = fopen (sysfile, "rb"); free (sysfile); if (f == NULL) @@ -880,7 +880,7 @@ dwfl_linux_kernel_module_section_address if (asprintf (&sysfile, SECADDRDIRFMT "_%s", modname, &secname[1]) < 0) return ENOMEM; - f = fopen (sysfile, "r"); + f = fopen (sysfile, "rb"); free (sysfile); if (f != NULL) goto ok; @@ -900,11 +900,11 @@ dwfl_linux_kernel_module_section_address do { *--end = '\0'; - f = fopen (sysfile, "r"); + f = fopen (sysfile, "rb"); if (is_init && f == NULL && errno == ENOENT) { sysfile[len - namelen] = '_'; - f = fopen (sysfile, "r"); + f = fopen (sysfile, "rb"); sysfile[len - namelen] = '.'; } } @@ -938,7 +938,7 @@ INTDEF (dwfl_linux_kernel_module_section_address) int dwfl_linux_kernel_report_modules (Dwfl *dwfl) { - FILE *f = fopen (MODULELIST, "r"); + FILE *f = fopen (MODULELIST, "rb"); if (f == NULL) return errno; diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c index 1133db6c..7e0ff466 100644 --- a/libdwfl/linux-pid-attach.c +++ b/libdwfl/linux-pid-attach.c @@ -53,7 +53,7 @@ linux_proc_pid_is_stopped (pid_t pid) bool retval, have_state; snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid); - procfile = fopen (buffer, "r"); + procfile = fopen (buffer, "rb"); if (procfile == NULL) return false; @@ -383,7 +383,7 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped) /* 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"); + procfile = fopen (buffer, "rb"); if (procfile == NULL) { err = errno; @@ -433,7 +433,7 @@ dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped) Elf *elf; i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid); assert (i > 0 && i < (ssize_t) sizeof (name) - 1); - int elf_fd = open (name, O_RDONLY); + int elf_fd = open (name, O_RDONLY | O_BINARY); if (elf_fd >= 0) { elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL); diff --git a/libdwfl/linux-proc-maps.c b/libdwfl/linux-proc-maps.c index c4438c0f..8eb9a5cb 100644 --- a/libdwfl/linux-proc-maps.c +++ b/libdwfl/linux-proc-maps.c @@ -63,7 +63,7 @@ get_pid_class (pid_t pid) if (asprintf (&fname, PROCEXEFMT, pid) < 0) return ELFCLASSNONE; - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); free (fname); if (fd < 0) return ELFCLASSNONE; @@ -99,7 +99,7 @@ grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr) if (asprintf (&fname, PROCAUXVFMT, pid) < 0) return ENOMEM; - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); free (fname); if (fd < 0) return errno == ENOENT ? 0 : errno; @@ -245,7 +245,7 @@ proc_maps_report (Dwfl *dwfl, FILE *f, GElf_Addr sysinfo_ehdr, pid_t pid) } char *file = line + nread + strspn (line + nread, " \t"); - if (file[0] != '/' || (ino == 0 && dmajor == 0 && dminor == 0)) + if (!IS_ABSOLUTE_PATH(file) || (ino == 0 && dmajor == 0 && dminor == 0)) /* This line doesn't indicate a file mapping. */ continue; @@ -306,7 +306,7 @@ dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid) if (asprintf (&fname, PROCMAPSFMT, pid) < 0) return ENOMEM; - FILE *f = fopen (fname, "r"); + FILE *f = fopen (fname, "rb"); free (fname); if (f == NULL) return errno; @@ -362,7 +362,7 @@ dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)), char **file_name, Elf **elfp) { int pid = -1; - if (module_name[0] == '/') + if (IS_ABSOLUTE_PATH (module_name)) { /* When this callback is used together with dwfl_linux_proc_report then we might see mappings of special character devices. Make @@ -380,7 +380,7 @@ dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)), if (pid == -1) { - int fd = open (module_name, O_RDONLY); + int fd = open (module_name, O_RDONLY | O_BINARY); if (fd >= 0) { *file_name = strdup (module_name); @@ -417,7 +417,7 @@ dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)), if (asprintf (&fname, PROCMEMFMT, pid) < 0) goto detach; - int fd = open (fname, O_RDONLY); + int fd = open (fname, O_RDONLY | O_BINARY); free (fname); if (fd < 0) goto detach; diff --git a/libdwfl/offline.c b/libdwfl/offline.c index d8697cf2..be34a63f 100644 --- a/libdwfl/offline.c +++ b/libdwfl/offline.c @@ -305,7 +305,7 @@ dwfl_report_offline (Dwfl *dwfl, const char *name, if (fd < 0) { closefd = true; - fd = open (file_name, O_RDONLY); + fd = open (file_name, O_RDONLY | O_BINARY); if (fd < 0) { __libdwfl_seterrno (DWFL_E_ERRNO); |
