From eb5d20c68aaf73661ffc02ba8fea3683c0358702 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 17 Feb 2011 14:18:08 -0500 Subject: [PATCH] markers: export pointer array instead of struct marker Ensures we don't end up running in gcc/linker structure alignment problems by exporting an array of pointers instead of the structures per se. Same fix as done for tracepoints for the mainline kernel. Signed-off-by: Mathieu Desnoyers --- include/ust/marker.h | 45 ++++++++++++++++++++++++-------------------- libust/marker.c | 39 ++++++++++++++++++++------------------ libust/tracectl.c | 14 +++++++------- 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/include/ust/marker.h b/include/ust/marker.h index ef3c1bd..cac71ff 100644 --- a/include/ust/marker.h +++ b/include/ust/marker.h @@ -75,11 +75,7 @@ struct marker { const char *tp_name; /* Optional tracepoint name */ void *tp_cb; /* Optional tracepoint callback */ void *location; /* Address of marker in code */ -} __attribute__((aligned(128)));/* - * Aligned on 128 bytes because it is - * globally visible and gcc happily - * align these on the structure size. - */ +}; #define GET_MARKER(channel, name) (__mark_##channel##_##name) @@ -111,7 +107,6 @@ struct marker { asm volatile ( \ /*".section __markers\n\t"*/ \ ".section __markers,\"aw\",@progbits\n\t" \ - ".balign 128\n\t" \ "2:\n\t" \ _ASM_PTR "(__mstrtab_" __stringify(channel) "_" __stringify(name) "_channel_" __stringify(unique) ")\n\t" /* channel string */ \ _ASM_PTR "(__mstrtab_" __stringify(channel) "_" __stringify(name) "_name_" __stringify(unique) ")\n\t" /* name string */ \ @@ -129,7 +124,12 @@ struct marker { _ASM_PTR "0\n\t" /* tp_cb */ \ _ASM_PTR "(1f)\n\t" /* location */ \ ".previous\n\t" \ - "1:\n\t" \ + /*".section __markers_ptrs\n\t"*/ \ + ".section __markers_ptrs,\"a\",@progbits\n\t" \ + ".balign 8\n\t" \ + _ASM_PTR "(2b)\n\t" \ + ".previous\n\t" \ + "1:\n\t" \ ARCH_COPY_ADDR("%[outptr]") \ : [outptr] "=r" (m) ); \ \ @@ -147,13 +147,16 @@ struct marker { __attribute__((section("__markers_strings"))) \ = #channel "\0" #name "\0" format; \ static struct marker GET_MARKER(channel, name) \ - __attribute__((section("__markers"), aligned(128))) = \ + __attribute__((section("__markers"))) = \ { __mstrtab_##channel##_##name, \ &__mstrtab_##channel##_##name[sizeof(#channel)], \ &__mstrtab_##channel##_##name[sizeof(#channel) + sizeof(#name)], \ 0, 0, 0, 0, marker_probe_cb, \ { __mark_empty_function, NULL}, \ - NULL, tp_name_str, tp_cb } + NULL, tp_name_str, tp_cb }; \ + static struct marker * const __mark_ptr_##channel##_##name \ + __attribute__((used, section("__markers_ptrs"))) = \ + &GET_MARKER(channel, name); /* * Make sure the alignment of the structure in the __markers section will @@ -198,8 +201,8 @@ struct marker { call_private, ®s, ## args); \ } while (0) -extern void marker_update_probe_range(struct marker *begin, - struct marker *end); +extern void marker_update_probe_range(struct marker * const *begin, + struct marker * const *end); /** * trace_mark - Marker using code patching @@ -302,15 +305,15 @@ extern void *marker_get_private_data(const char *channel, const char *name, struct marker_iter { //ust// struct module *module; struct lib *lib; - struct marker *marker; + struct marker * const *marker; }; extern void marker_iter_start(struct marker_iter *iter); extern void marker_iter_next(struct marker_iter *iter); extern void marker_iter_stop(struct marker_iter *iter); extern void marker_iter_reset(struct marker_iter *iter); -extern int marker_get_iter_range(struct marker **marker, struct marker *begin, - struct marker *end); +extern int marker_get_iter_range(struct marker * const **marker, struct marker * const *begin, + struct marker * const *end); extern void marker_update_process(void); extern int is_marker_enabled(const char *channel, const char *name); @@ -329,7 +332,7 @@ struct marker_addr { }; struct lib { - struct marker *markers_start; + struct marker * const *markers_start; #ifdef CONFIG_UST_GDB_INTEGRATION struct marker_addr *markers_addr_start; #endif @@ -337,16 +340,18 @@ struct lib { struct cds_list_head list; }; -extern int marker_register_lib(struct marker *markers_start, int markers_count); -extern int marker_unregister_lib(struct marker *markers_start); +extern int marker_register_lib(struct marker * const *markers_start, int markers_count); +extern int marker_unregister_lib(struct marker * const *markers_start); #define MARKER_LIB \ - extern struct marker __start___markers[] __attribute__((weak, visibility("hidden"))); \ - extern struct marker __stop___markers[] __attribute__((weak, visibility("hidden"))); \ + extern struct marker * const __start___markers[] __attribute__((weak, visibility("hidden"))); \ + extern struct marker * const __stop___markers[] __attribute__((weak, visibility("hidden"))); \ \ static void __attribute__((constructor)) __markers__init(void) \ { \ - marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker)); \ + marker_register_lib(__start___markers, \ + (((long)__stop___markers) - ((long)__start___markers)) \ + / sizeof(*__start___markers)); \ } \ \ static void __attribute__((destructor)) __markers__destroy(void) \ diff --git a/libust/marker.c b/libust/marker.c index 7a32351..664f59c 100644 --- a/libust/marker.c +++ b/libust/marker.c @@ -35,8 +35,8 @@ __thread long ust_reg_stack[500]; volatile __thread long *ust_reg_stack_ptr = (long *) 0; -extern struct marker __start___markers[] __attribute__((visibility("hidden"))); -extern struct marker __stop___markers[] __attribute__((visibility("hidden"))); +extern struct marker * const __start___markers[] __attribute__((visibility("hidden"))); +extern struct marker * const __stop___markers[] __attribute__((visibility("hidden"))); /* Set to 1 to enable marker debug output */ static const int marker_debug; @@ -677,17 +677,17 @@ int is_marker_enabled(const char *channel, const char *name) * * Updates the probe callback corresponding to a range of markers. */ -void marker_update_probe_range(struct marker *begin, - struct marker *end) +void marker_update_probe_range(struct marker * const *begin, + struct marker * const *end) { - struct marker *iter; + struct marker * const *iter; struct marker_entry *mark_entry; pthread_mutex_lock(&markers_mutex); for (iter = begin; iter < end; iter++) { - mark_entry = get_marker(iter->channel, iter->name); + mark_entry = get_marker((*iter)->channel, (*iter)->name); if (mark_entry) { - set_marker(mark_entry, iter, !!mark_entry->refcount); + set_marker(mark_entry, *iter, !!mark_entry->refcount); /* * ignore error, continue */ @@ -702,11 +702,11 @@ void marker_update_probe_range(struct marker *begin, "channel %s name %s event_id %hu " "int #1u%zu long #1u%zu pointer #1u%zu " "size_t #1u%zu alignment #1u%u", - iter->channel, iter->name, mark_entry->event_id, + (*iter)->channel, (*iter)->name, mark_entry->event_id, sizeof(int), sizeof(long), sizeof(void *), sizeof(size_t), ltt_get_alignment()); } else { - disable_marker(iter); + disable_marker(*iter); } } pthread_mutex_unlock(&markers_mutex); @@ -1114,8 +1114,9 @@ int lib_get_iter_markers(struct marker_iter *iter) * Returns whether a next marker has been found (1) or not (0). * Will return the first marker in the range if the input marker is NULL. */ -int marker_get_iter_range(struct marker **marker, struct marker *begin, - struct marker *end) +int marker_get_iter_range(struct marker * const **marker, + struct marker * const *begin, + struct marker * const *end) { if (!*marker && begin != end) { *marker = begin; @@ -1351,17 +1352,17 @@ void marker_set_new_marker_cb(void (*cb)(struct marker *)) new_marker_cb = cb; } -static void new_markers(struct marker *start, struct marker *end) +static void new_markers(struct marker * const *start, struct marker * const *end) { - if(new_marker_cb) { - struct marker *m; + if (new_marker_cb) { + struct marker * const *m; for(m=start; m < end; m++) { - new_marker_cb(m); + new_marker_cb(*m); } } } -int marker_register_lib(struct marker *markers_start, int markers_count) +int marker_register_lib(struct marker * const *markers_start, int markers_count) { struct lib *pl; @@ -1385,7 +1386,7 @@ int marker_register_lib(struct marker *markers_start, int markers_count) return 0; } -int marker_unregister_lib(struct marker *markers_start) +int marker_unregister_lib(struct marker * const *markers_start) { struct lib *lib; @@ -1415,7 +1416,9 @@ static int initialized = 0; void __attribute__((constructor)) init_markers(void) { if(!initialized) { - marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker)); + marker_register_lib(__start___markers, + (((long)__stop___markers) - ((long)__start___markers)) + / sizeof(*__start___markers)); initialized = 1; } } diff --git a/libust/tracectl.c b/libust/tracectl.c index 25f84cc..233a460 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -100,11 +100,11 @@ static void print_markers(FILE *fp) while (iter.marker) { fprintf(fp, "marker: %s/%s %d \"%s\" %p\n", - iter.marker->channel, - iter.marker->name, - (int)imv_read(iter.marker->state), - iter.marker->format, - iter.marker->location); + (*iter.marker)->channel, + (*iter.marker)->name, + (int)imv_read((*iter.marker)->state), + (*iter.marker)->format, + (*iter.marker)->location); marker_iter_next(&iter); } unlock_markers(); @@ -1314,8 +1314,8 @@ static void __attribute__((constructor)) init() DBG("now iterating on markers already registered"); while (iter.marker) { - DBG("now iterating on marker %s", iter.marker->name); - auto_probe_connect(iter.marker); + DBG("now iterating on marker %s", (*iter.marker)->name); + auto_probe_connect(*iter.marker); marker_iter_next(&iter); } } -- 2.34.1