diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c index a4cc60b3f59c25d626a0a52336b8b6ef782a0ebd..69d474634fbcb172c8bfb325d360cd814c436159 100644 --- a/agent/tcf/services/symbols_elf.c +++ b/agent/tcf/services/symbols_elf.c @@ -2461,6 +2461,16 @@ int get_context_isa(Context * ctx, ContextAddress ip, const char ** isa, /* TODO: faster handling of ARM mapping symbols */ ELF_SymbolInfo sym_info; elf_find_symbol_by_address(sec, lt_addr, &sym_info); + if (sym_info.type16bit && sym_info.value + sym_info.size > lt_addr) { + *isa = "Thumb"; + assert(sym_info.size > 0); + assert(sym_info.value <= lt_addr); + *range_addr = (ContextAddress)sym_info.value; + if (file->type == ET_REL) *range_addr += (ContextAddress)sec->addr; + *range_addr += ip - lt_addr; + *range_size = sym_info.size; + return 0; + } while (sym_info.sym_section != NULL) { assert(sym_info.section == sec); if (sym_info.name != NULL && *sym_info.name == '$') { diff --git a/agent/tcf/services/tcf_elf.c b/agent/tcf/services/tcf_elf.c index 9caa8cee37b687e076132c1280e2b35a886f1b37..c7206926156b6c249a5c7a2b7af34e119c99f752 100644 --- a/agent/tcf/services/tcf_elf.c +++ b/agent/tcf/services/tcf_elf.c @@ -467,6 +467,7 @@ static char * get_debug_info_file_name(ELF_File * file, int * error) { lnm = apply_path_map(NULL, NULL, lnm, PATH_MAP_TO_LOCAL); #endif if (stat(lnm, &buf) == 0) return loc_strdup(lnm); + trace(LOG_ALWAYS, "Cannot open debug info file '%s': %s", lnm, errno_to_str(errno)); } offs += desc_sz; while (offs % 4 != 0) offs++; @@ -494,6 +495,7 @@ static char * get_debug_info_file_name(ELF_File * file, int * error) { lnm = apply_path_map(NULL, NULL, lnm, PATH_MAP_TO_LOCAL); #endif if (stat(lnm, &buf) == 0) return loc_strdup(lnm); + trace(LOG_ALWAYS, "Cannot open debug info file '%s': %s", lnm, errno_to_str(errno)); } } } @@ -2081,9 +2083,17 @@ void unpack_elf_symbol_info(ELF_Section * sym_sec, U4_T index, ELF_SymbolInfo * } if (file->machine == EM_ARM) { - if (info->type == STT_FUNC || info->type == STT_ARM_TFUNC) { - info->value = info->value & ~ (U8_T)1; + if (info->type == STT_ARM_16BIT) { + info->type = STT_OBJECT; + info->type16bit = 1; + } + if (info->type == STT_ARM_TFUNC) { info->type = STT_FUNC; + info->type16bit = 1; + } + if (info->type == STT_FUNC || info->type16bit) { + if (info->value & 1) info->type16bit = 1; + info->value = info->value & ~(U8_T)1; } } else if (IS_PPC64_FUNC_OPD(file, info)) { @@ -2175,7 +2185,7 @@ static void create_symbol_addr_search_index(ELF_Section * sec) { ELF_SymbolInfo sym_info; unpack_elf_symbol_info(tbl, n, &sym_info); /* Don't register PPC64 dot function name */ - add = IS_PPC64_FUNC_OPD(file, &sym_info)|| \ + add = IS_PPC64_FUNC_OPD(file, &sym_info) || \ (sym_info.section == sec && !IS_PPC64_FUNC_DOT(file, &sym_info) && sym_info.type != STT_GNU_IFUNC); if (add) { addr = sym_info.value + (rel ? sec->addr : 0); @@ -2222,8 +2232,8 @@ static void create_symbol_addr_search_index(ELF_Section * sec) { } add = add && type != STT_GNU_IFUNC; if (add && file->machine == EM_ARM) { - if (type == STT_FUNC || type == STT_ARM_TFUNC) { - addr = addr & ~(U8_T) 1; + if (type == STT_FUNC || type == STT_ARM_TFUNC || type == STT_ARM_16BIT) { + addr = addr & ~(U8_T)1; } } } diff --git a/agent/tcf/services/tcf_elf.h b/agent/tcf/services/tcf_elf.h index c4978cb94249b5c70ff9d24a9b3fd863e155fd1b..530dae8af9ca3b935eda5820718be511c119f122 100644 --- a/agent/tcf/services/tcf_elf.h +++ b/agent/tcf/services/tcf_elf.h @@ -131,6 +131,7 @@ #define STT_LOPROC 13 #define STT_HIPROC 15 #define STT_ARM_TFUNC STT_LOPROC +#define STT_ARM_16BIT STT_HIPROC #define PT_NULL 0 #define PT_LOAD 1 @@ -500,6 +501,7 @@ struct ELF_SymbolInfo { char * name; U1_T bind; U1_T type; + U1_T type16bit; U8_T value; U8_T size; U8_T other;