BT_HIDDEN
int so_info_lookup_source_location(struct so_info *so, uint64_t addr,
struct source_location **src_loc);
+/**
+ * Get a string representing the location within the binary of a given
+ * address.
+ *
+ * In the case of a PIC binary, the location is relative (+0x1234).
+ * For a non-PIC binary, the location is absolute (@0x1234)
+ *
+ * On success, the out parameter `bin_loc` is set. The ownership is
+ * passed to the caller. On failure, `bin_loc` remains unchanged.
+ *
+ * @param so so_info instance for the executable containing
+ * the address
+ * @param addr Virtual memory address for which to find the
+ * binary location
+ * @param bin_loc Out parameter, the binary location
+ * @returns 0 on success, -1 on failure
+ */
+BT_HIDDEN
+int so_info_get_bin_loc(struct so_info *so, uint64_t addr, char **bin_loc);
/**
* Destroy the given source_location instance
fprintf(pos->fp, ", ");
}
- fprintf(pos->fp, "bin = \"%s\"",
+ fprintf(pos->fp, "bin = \"%s%s\"",
opt_debug_info_full_path ?
debug_info_src->bin_path :
- debug_info_src->short_bin_path);
+ debug_info_src->short_bin_path,
+ debug_info_src->bin_loc);
}
fprintf(pos->fp, " }");
free(debug_info_src->func);
free(debug_info_src->src_path);
free(debug_info_src->bin_path);
+ free(debug_info_src->bin_loc);
g_free(debug_info_src);
}
debug_info_src->short_bin_path = get_filename_from_path(
debug_info_src->bin_path);
+
+ ret = so_info_get_bin_loc(so, ip, &(debug_info_src->bin_loc));
+ if (ret) {
+ goto error;
+ }
}
end:
}
BT_HIDDEN
-int so_info_lookup_function_name(struct so_info *so, uint64_t ip,
+int so_info_lookup_function_name(struct so_info *so, uint64_t addr,
char **func_name)
{
int ret = 0;
char *_func_name = NULL;
- uint64_t relative_addr;
if (!so || !func_name) {
goto error;
}
}
- if (!so_info_has_address(so, ip)) {
+ if (!so_info_has_address(so, addr)) {
goto error;
}
- relative_addr = ip - so->low_addr;
/*
* Addresses in ELF and DWARF are relative to base address for
* PIC, so make the address argument relative too if needed.
*/
+ if (so->is_pic) {
+ addr -= so->low_addr;
+ }
+
if (so->is_elf_only) {
- ret = so_info_lookup_elf_function_name(so,
- so->is_pic ? relative_addr : ip,
- &_func_name);
+ ret = so_info_lookup_elf_function_name(so, addr, &_func_name);
} else {
- ret = so_info_lookup_dwarf_function_name(so,
- so->is_pic ? relative_addr : ip,
- &_func_name);
+ ret = so_info_lookup_dwarf_function_name(so, addr, &_func_name);
}
- if (ret) {
+ if (ret || !_func_name) {
goto error;
}
- if (!_func_name) {
- /*
- * Can't map to a function; fallback to a generic output of the
- * form binary+/@address.
- *
- * FIXME check position independence flag.
- */
- const char *binary_name = get_filename_from_path(so->elf_path);
+ *func_name = _func_name;
+ return 0;
- ret = asprintf(&_func_name, "%s+%#0" PRIx64, binary_name,
- relative_addr);
- if (!_func_name) {
- goto error;
- }
+error:
+ return -1;
+}
+
+BT_HIDDEN
+int so_info_get_bin_loc(struct so_info *so, uint64_t addr, char **bin_loc)
+{
+ int ret = 0;
+ char *_bin_loc = NULL;
+
+ if (!so || !bin_loc) {
+ goto error;
}
- *func_name = _func_name;
+ if (so->is_pic) {
+ addr -= so->low_addr;
+ ret = asprintf(&_bin_loc, "+%#0" PRIx64, addr);
+ } else {
+ ret = asprintf(&_bin_loc, "@%#0" PRIx64, addr);
+ }
+
+ if (ret == -1 || !_bin_loc) {
+ goto error;
+ }
+
+ *bin_loc = _bin_loc;
return 0;
error: