X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=lib%2Fbin-info.c;h=65f9051fb00efe087c24c1fe9f66696cf081ebd1;hp=023515effd510f1d118bab45f3e1f32382c279aa;hb=4a6f6ed3aeb9845dec4b8ec9ca8573ed1c064187;hpb=dae52e7673333cf41828c8686158948ce93ef104 diff --git a/lib/bin-info.c b/lib/bin-info.c index 023515ef..65f9051f 100644 --- a/lib/bin-info.c +++ b/lib/bin-info.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * An address printed in hex is at most 20 bytes (16 for 64-bits + @@ -188,7 +189,7 @@ error: * * @param bin bin_info instance for which to set DWARF info * @param path Presumed location of the DWARF info - * @returns 0 on success, -1 on failure + * @returns 0 on success, negative value on failure */ static int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path) @@ -203,6 +204,7 @@ int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path) fd = open(path, O_RDONLY); if (fd < 0) { + fd = -errno; goto error; } @@ -236,12 +238,15 @@ int bin_info_set_dwarf_info_from_path(struct bin_info *bin, char *path) return 0; error: - close(fd); + if (fd >= 0) { + close(fd); + fd = -1; + } dwarf_end(dwarf_info); g_free(dwarf_info); free(cu); - return -1; + return fd; } /** @@ -266,8 +271,7 @@ int bin_info_set_dwarf_info_build_id(struct bin_info *bin) dbg_dir = opt_debug_info_dir ? : DEFAULT_DEBUG_DIR; - /* 2 characters per byte printed in hex, +1 for '/' and +1 for - * '\0' */ + /* 2 characters per byte printed in hex, +1 for '/' and +1 for '\0' */ build_id_file_len = (2 * bin->build_id_len) + 1 + strlen(BUILD_ID_SUFFIX) + 1; build_id_file = malloc(build_id_file_len); @@ -325,12 +329,12 @@ int is_valid_debug_file(char *path, uint32_t crc) uint32_t _crc = 0; if (!path) { - goto end; + goto end_noclose; } fd = open(path, O_RDONLY); if (fd < 0) { - goto end; + goto end_noclose; } ret = crc32(fd, &_crc); @@ -343,6 +347,7 @@ int is_valid_debug_file(char *path, uint32_t crc) end: close(fd); +end_noclose: return ret; } @@ -437,7 +442,7 @@ found: * Initialize the DWARF info for a given executable. * * @param bin bin_info instance - * @returns 0 on success, -1 on failure + * @returns 0 on success, negative value on failure */ static int bin_info_set_dwarf_info(struct bin_info *bin) @@ -445,7 +450,8 @@ int bin_info_set_dwarf_info(struct bin_info *bin) int ret = 0; if (!bin) { - goto error; + ret = -1; + goto end; } /* First try to set the DWARF info from the ELF file */ @@ -468,8 +474,6 @@ int bin_info_set_dwarf_info(struct bin_info *bin) goto end; } -error: - ret = -1; end: return ret; } @@ -478,12 +482,12 @@ end: * Initialize the ELF file for a given executable. * * @param bin bin_info instance - * @returns 0 on success, -1 on failure + * @returns 0 on success, negative value on error. */ static int bin_info_set_elf_file(struct bin_info *bin) { - int elf_fd; + int elf_fd = -1; Elf *elf_file = NULL; if (!bin) { @@ -492,6 +496,7 @@ int bin_info_set_elf_file(struct bin_info *bin) elf_fd = open(bin->elf_path, O_RDONLY); if (elf_fd < 0) { + elf_fd = -errno; printf_verbose("Failed to open %s\n", bin->elf_path); goto error; } @@ -513,12 +518,14 @@ int bin_info_set_elf_file(struct bin_info *bin) return 0; error: - close(elf_fd); + if (elf_fd >= 0) { + close(elf_fd); + elf_fd = -1; + } elf_end(elf_file); - return -1; + return elf_fd; } - BT_HIDDEN void source_location_destroy(struct source_location *src_loc) { @@ -529,6 +536,7 @@ void source_location_destroy(struct source_location *src_loc) free(src_loc->filename); g_free(src_loc); } + /** * Append a string representation of an address offset to an existing * string. @@ -759,7 +767,7 @@ int bin_info_lookup_elf_function_name(struct bin_info *bin, uint64_t addr, error: g_free(shdr); g_free(sym); - return -1; + return ret; } /** @@ -779,7 +787,8 @@ static int bin_info_lookup_cu_function_name(struct bt_dwarf_cu *cu, uint64_t addr, char **func_name) { - int ret = 0, found = 0; + int ret = 0; + bool found = false; struct bt_dwarf_die *die = NULL; if (!cu || !func_name) { @@ -822,11 +831,13 @@ int bin_info_lookup_cu_function_name(struct bt_dwarf_cu *cu, uint64_t addr, ret = dwarf_lowpc(die->dwarf_die, &low_addr); if (ret) { + free(die_name); goto error; } ret = bin_info_append_offset_str(die_name, low_addr, addr, func_name); + free(die_name); if (ret) { goto error; } @@ -884,6 +895,8 @@ int bin_info_lookup_dwarf_function_name(struct bin_info *bin, uint64_t addr, if (_func_name) { *func_name = _func_name; + } else { + goto error; } bt_dwarf_cu_destroy(cu); @@ -909,6 +922,7 @@ int bin_info_lookup_function_name(struct bin_info *bin, uint64_t addr, if (!bin->dwarf_info && !bin->is_elf_only) { ret = bin_info_set_dwarf_info(bin); if (ret) { + printf_verbose("Failed to set bin dwarf info, falling back to ELF lookup.\n"); /* Failed to set DWARF info, fallback to ELF. */ bin->is_elf_only = true; } @@ -928,12 +942,10 @@ int bin_info_lookup_function_name(struct bin_info *bin, uint64_t addr, if (bin->is_elf_only) { ret = bin_info_lookup_elf_function_name(bin, addr, &_func_name); + printf_verbose("Failed to lookup function name (elf), error %i\n", ret); } else { ret = bin_info_lookup_dwarf_function_name(bin, addr, &_func_name); - } - - if (ret || !_func_name) { - goto error; + printf_verbose("Failed to lookup function name (dwarf), error %i\n", ret); } *func_name = _func_name; @@ -980,20 +992,27 @@ error: * subroutines are inlined within this function and would contain * `addr`. * + * On success, the out parameter `contains` is set with the boolean + * value indicating whether the DIE's range covers `addr`. On failure, + * it remains unchanged. + * * Do note that this function advances the position of `die`. If the * address is found within one of its children, `die` will be pointing * to that child upon returning from the function, allowing to extract * the information deemed necessary. * - * @param die The parent DIE in whose children the address will be - * looked for - * @param addr The address for which to look for in the DIEs - * @returns Returns 1 if the address was found, 0 if not + * @param die The parent DIE in whose children the address will be + * looked for + * @param addr The address for which to look for in the DIEs + * @param contains Out parameter, true if addr is contained, + * false if not + * @returns Returns 0 on success, -1 on failure */ static -int bin_info_child_die_has_address(struct bt_dwarf_die *die, uint64_t addr) +int bin_info_child_die_has_address(struct bt_dwarf_die *die, uint64_t addr, bool *contains) { - int ret = 0, contains = 0; + int ret = 0; + bool _contains = false; if (!die) { goto error; @@ -1013,24 +1032,23 @@ int bin_info_child_die_has_address(struct bt_dwarf_die *die, uint64_t addr) } if (tag == DW_TAG_inlined_subroutine) { - ret = bt_dwarf_die_contains_addr(die, addr, &contains); + ret = bt_dwarf_die_contains_addr(die, addr, &_contains); if (ret) { goto error; } - if (contains) { - ret = 1; + if (_contains) { goto end; } } } while (bt_dwarf_die_next(die) == 0); end: - return ret; + *contains = _contains; + return 0; error: - ret = 0; - goto end; + return -1; } /** @@ -1048,7 +1066,8 @@ static int bin_info_lookup_cu_src_loc_inl(struct bt_dwarf_cu *cu, uint64_t addr, struct source_location **src_loc) { - int ret = 0, found = 0; + int ret = 0; + bool found = false; struct bt_dwarf_die *die = NULL; struct source_location *_src_loc = NULL; @@ -1070,7 +1089,7 @@ int bin_info_lookup_cu_src_loc_inl(struct bt_dwarf_cu *cu, uint64_t addr, } if (tag == DW_TAG_subprogram) { - int contains = 0; + bool contains = false; ret = bt_dwarf_die_contains_addr(die, addr, &contains); if (ret) { @@ -1082,8 +1101,12 @@ int bin_info_lookup_cu_src_loc_inl(struct bt_dwarf_cu *cu, uint64_t addr, * Try to find an inlined subroutine * child of this DIE containing addr. */ - found = bin_info_child_die_has_address( - die, addr); + ret = bin_info_child_die_has_address(die, addr, + &found); + if(ret) { + goto error; + } + goto end; } }