[PATCH 1/4] libdwfl: return error from __libdwfl_relocate_value for unloaded sections
Omar Sandoval
osandov@osandov.com
Thu Dec 12 01:30:00 GMT 2019
From: Omar Sandoval <osandov@fb.com>
Currently, __libdwfl_relocate_value doesn't distinguish between unloaded
sections and sections loaded at address zero. This has a few
consequences:
* relocate.c attempts relocation on unloaded sections when we don't have
anything meaningful to relocate against.
* derelocate.c matches addresses which happen to be less than the
sh_size of an unloaded section, which can lead to confusing results
from dwfl_module_relocate_address and __libdwfl_find_section_ndx.
* find_elf_build_id returns an invalid non-zero address if the build ID
note is not loaded.
Let's return a new error, DWFL_E_NOT_LOADED, from
__libdwfl_relocate_value if the section is not loaded that callers can
handle appropriately.
Signed-off-by: Omar Sandoval <osandov@fb.com>
---
libdwfl/ChangeLog | 8 ++++++++
libdwfl/dwfl_module_getsym.c | 3 ++-
libdwfl/libdwflP.h | 3 ++-
libdwfl/relocate.c | 9 ++++++---
4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index b6b427d4..b00ac8d6 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,11 @@
+2019-12-11 Omar Sandoval <osandov@fb.com>
+
+ * libdwflP.h: Add new NOT_LOADED DWFL_ERROR.
+ * relocate.c (__libdwfl_relocate_value): Return
+ DWFL_E_NOT_LOADED if section is not loaded.
+ (relocate): Handle DWFL_E_NOT_LOADED.
+ * dwfl_module_getsym: Ignore DWFL_E_NOT_LOADED.
+
2019-12-05 Mark Wielaard <mark@klomp.org>
* linux-kernel-modules.c (find_kernel_elf): Also try to find
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
index 8de9a3eb..d75588b2 100644
--- a/libdwfl/dwfl_module_getsym.c
+++ b/libdwfl/dwfl_module_getsym.c
@@ -165,7 +165,8 @@ __libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym, GElf_Addr *addr,
Dwfl_Error result = __libdwfl_relocate_value (mod, elf,
&symshstrndx,
shndx, &st_value);
- if (unlikely (result != DWFL_E_NOERROR))
+ if (unlikely (result != DWFL_E_NOERROR
+ && result != DWFL_E_NOT_LOADED))
{
__libdwfl_seterrno (result);
return NULL;
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index f631f946..6c10eddc 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -90,7 +90,8 @@ typedef struct Dwfl_Process Dwfl_Process;
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"))
+ DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file")) \
+ DWFL_ERROR (NOT_LOADED, N_("Not loaded"))
#define DWFL_ERROR(name, text) DWFL_E_##name,
typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 88b5211d..5c9c08f3 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -73,9 +73,8 @@ __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
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. */
+ /* The callback indicated this section wasn't loaded. */
+ return DWFL_E_NOT_LOADED;
/* Update the in-core file's section header to show the final
load address (or unloadedness). This serves as a cache,
@@ -361,6 +360,8 @@ relocate (Dwfl_Module * const mod,
GElf_Word shndx;
Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab,
symndx, &sym, &shndx);
+ if (error == DWFL_E_NOT_LOADED)
+ return DWFL_E_NOERROR;
if (unlikely (error != DWFL_E_NOERROR))
return error;
@@ -368,6 +369,8 @@ relocate (Dwfl_Module * const mod,
{
/* Maybe we can figure it out anyway. */
error = resolve_symbol (mod, reloc_symtab, &sym, shndx);
+ if (error == DWFL_E_NOT_LOADED)
+ return DWFL_E_NOERROR;
if (error != DWFL_E_NOERROR
&& !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON))
return error;
--
2.24.0
More information about the Elfutils-devel
mailing list