#include <config.h>
#include <errno.h>
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
return strncmp (str, prefix, strlen (prefix)) == 0;
}
+/* Return TRUE if STR[FROM] is a valid string with a zero terminator
+ at or before STR[TO - 1]. Note FROM is an index into the STR
+ array, while TO is the maximum size of the STR array. This
+ function returns FALSE when TO is zero or FROM >= TO. */
+static inline bool
+validate_str (const char *str, size_t from, size_t to)
+{
+#if HAVE_DECL_MEMRCHR
+ // Check end first, which is likely a zero terminator,
+ // to prevent function call
+ return (to > 0
+ && (str[to - 1] == '\0'
+ || (to > from
+ && memrchr (&str[from], '\0', to - from - 1) != NULL)));
+#else
+ do {
+ if (to <= from)
+ return false;
+
+ to--;
+ } while (str[to]);
+
+ return true;
+#endif
+}
+
/* A special gettext function we use if the strings are too short. */
#define sgettext(Str) \
({ const char *__res = strrchr (_(Str), '|'); \
return zdata;
}
-static bool validate_str (const char *str, size_t from, size_t to)
-{
-#if HAVE_DECL_MEMRCHR
- // Check end first, which is likely a zero terminator, to prevent function call
- return ((to > 0 && str[to - 1] == '\0')
- || (to - from > 0 && memrchr (&str[from], '\0', to - from - 1) != NULL));
-#else
- do {
- if (to <= from)
- return false;
-
- to--;
- } while (str[to]);
-
- return true;
-#endif
-}
-
char *
elf_strptr (Elf *elf, size_t idx, size_t offset)
{
char typebuf[64];
char bindbuf[64];
char scnbuf[64];
+ const char *sym_name;
Elf32_Word xndx;
GElf_Sym sym_mem;
GElf_Sym *sym
/* Determine the real section index. */
if (likely (sym->st_shndx != SHN_XINDEX))
xndx = sym->st_shndx;
+ if (use_dynamic_segment == true)
+ {
+ if (validate_str (symstr_data->d_buf, sym->st_name,
+ symstr_data->d_size))
+ sym_name = (char *)symstr_data->d_buf + sym->st_name;
+ else
+ sym_name = NULL;
+ }
+ else
+ sym_name = elf_strptr (ebl->elf, idx, sym->st_name);
+
+ if (sym_name == NULL)
+ sym_name = "???";
printf (_ ("\
%5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
sizeof (scnbuf), NULL, shnum),
- use_dynamic_segment == true
- ? (char *)symstr_data->d_buf + sym->st_name
- : elf_strptr (ebl->elf, idx, sym->st_name));
+ sym_name);
if (versym_data != NULL)
{