#define TEXT_SECTION_NAME ".text"
#define SYMBOL_TAB_SECTION_NAME ".symtab"
#define STRING_TAB_SECTION_NAME ".strtab"
+#define DYNAMIC_SYMBOL_TAB_SECTION_NAME ".dynsym"
+#define DYNAMIC_STRING_TAB_SECTION_NAME ".dynstr"
#define NOTE_STAPSDT_SECTION_NAME ".note.stapsdt"
#define NOTE_STAPSDT_NAME "stapsdt"
#define NOTE_STAPSDT_TYPE 3
char *curr_sym_str = NULL;
char *symbol_table_data = NULL;
char *string_table_data = NULL;
+ char *string_table_name = NULL;
struct lttng_elf_shdr *symtab_hdr = NULL;
struct lttng_elf_shdr *strtab_hdr = NULL;
struct lttng_elf *elf = NULL;
goto end;
}
- /* Get the symbol table section header. */
+ /*
+ * The .symtab section might not exist on stripped binaries.
+ * Try to get the symbol table section header first. If it's absent,
+ * try to get the dynamic symbol table. All symbols in the dynamic
+ * symbol tab are in the (normal) symbol table if it exists.
+ */
ret = lttng_elf_get_section_hdr_by_name(elf, SYMBOL_TAB_SECTION_NAME,
&symtab_hdr);
if (ret) {
- DBG("Cannot get ELF Symbol Table section.");
- ret = LTTNG_ERR_ELF_PARSING;
- goto destroy_elf;
+ DBG("Cannot get ELF Symbol Table section. Trying to get ELF Dynamic Symbol Table section.");
+ /* Get the dynamic symbol table section header. */
+ ret = lttng_elf_get_section_hdr_by_name(elf, DYNAMIC_SYMBOL_TAB_SECTION_NAME,
+ &symtab_hdr);
+ if (ret) {
+ DBG("Cannot get ELF Symbol Table nor Dynamic Symbol Table sections.");
+ ret = LTTNG_ERR_ELF_PARSING;
+ goto destroy_elf;
+ }
+ string_table_name = DYNAMIC_STRING_TAB_SECTION_NAME;
+ } else {
+ string_table_name = STRING_TAB_SECTION_NAME;
}
+
/* Get the data associated with the symbol table section. */
symbol_table_data = lttng_elf_get_section_data(elf, symtab_hdr);
if (symbol_table_data == NULL) {
}
/* Get the string table section header. */
- ret = lttng_elf_get_section_hdr_by_name(elf, STRING_TAB_SECTION_NAME,
+ ret = lttng_elf_get_section_hdr_by_name(elf, string_table_name,
&strtab_hdr);
if (ret) {
DBG("Cannot get ELF string table section.");
CURDIR=$(dirname "$0")/
TESTDIR=$CURDIR/../..
TESTAPP_DIR="$TESTDIR/utils/testapp/"
-ELF_TEST_BIN_DIR="$TESTAPP_DIR/userspace-probe-elf-binary/"
+ELF_TEST_BIN_DIR="$TESTAPP_DIR/userspace-probe-elf-binary/.libs/"
ELF_TEST_BIN_NAME="userspace-probe-elf-binary"
ELF_TEST_BIN="$ELF_TEST_BIN_DIR/$ELF_TEST_BIN_NAME"
ELF_CXX_TEST_BIN_DIR="$TESTAPP_DIR/userspace-probe-elf-cxx-binary/"
SDT_TEST_BIN="$SDT_TEST_BIN_DIR/$SDT_TEST_BIN_NAME"
ELF_SYMBOL="test_function"
PROBE_EVENT_NAME=userspace_probe_test_event
-NUM_TESTS=81
+NUM_TESTS=87
OUTPUT_DEST=/dev/null
ERROR_OUTPUT_DEST=/dev/null
rm -rf "$TRACE_PATH"
}
+function test_userspace_probe_elf_dynamic_symbol ()
+{
+ TRACE_PATH=$(mktemp -d)
+ SESSION_NAME="test_userprobe_elf"
+ LIBFOO_PATH="$ELF_TEST_BIN_DIR/libfoo.so"
+ ENABLE_EXPR="elf:$LIBFOO_PATH:dynamic_symbol"
+
+ diag "Userspace probe on Elf dynamic symbol enabled and traced"
+
+ create_lttng_session_ok $SESSION_NAME "$TRACE_PATH"
+
+ lttng_enable_kernel_userspace_probe_event_ok $SESSION_NAME "$ENABLE_EXPR" $PROBE_EVENT_NAME
+
+ start_lttng_tracing_ok $SESSION_NAME
+ eval "$ELF_TEST_BIN" > /dev/null
+ stop_lttng_tracing_ok $SESSION_NAME
+
+ validate_trace $PROBE_EVENT_NAME "$TRACE_PATH"
+
+ destroy_lttng_session_ok $SESSION_NAME
+
+ rm -rf "$TRACE_PATH"
+}
+
function test_userspace_probe_elf_cxx_function ()
{
TRACE_PATH=$(mktemp -d)
# Successful tracing userspace probe elf
test_userspace_probe_elf
+ test_userspace_probe_elf_dynamic_symbol
# Disable userspace-probe elf
test_userspace_probe_elf_disable
# no optimization
AM_CFLAGS = -O0
+noinst_LTLIBRARIES = libfoo.la
+
+libfoo_la_SOURCES = foo.c foo.h
+libfoo_la_LDFLAGS = -shared -module -avoid-version -rpath $(abs_builddir)/.libs/
+
noinst_PROGRAMS = userspace-probe-elf-binary
userspace_probe_elf_binary_SOURCES = userspace-probe-elf-binary.c
+userspace_probe_elf_binary_LDADD = libfoo.la
+
+libfoo.strip: libfoo.la
+ $(OBJCOPY) --strip-all .libs/libfoo.so
+
+all-local: libfoo.strip
+ @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+ for script in $(EXTRA_DIST); do \
+ cp -f $(srcdir)/$$script $(builddir); \
+ done; \
+ fi
--- /dev/null
+/*
+ * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+int dynamic_symbol(int a)
+{
+ return a + a;
+}
--- /dev/null
+/*
+ * Copyright (C) 2018 Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+int dynamic_symbol(int a);
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "foo.h"
volatile int not_a_function = 0;
void __attribute__ ((noinline)) test_function()
{
int main(int argc, char *argv[])
{
test_function();
+ dynamic_symbol(42);
return 0;
}