diff options
author | Eugene Tarassov | 2017-02-06 01:44:22 +0000 |
---|---|---|
committer | Eugene Tarassov | 2017-02-06 01:44:22 +0000 |
commit | 2c1313866f0de7d8f781047c4ce3ae63cbde1750 (patch) | |
tree | ce0c10b9b8762881da7a7db2bf0aa8275014ed55 /agent/tcf/services/tcf_elf.c | |
parent | 4618123ce0fd88b71f06d5da01468694949a32db (diff) | |
download | org.eclipse.tcf.agent-2c1313866f0de7d8f781047c4ce3ae63cbde1750.tar.gz org.eclipse.tcf.agent-2c1313866f0de7d8f781047c4ce3ae63cbde1750.tar.xz org.eclipse.tcf.agent-2c1313866f0de7d8f781047c4ce3ae63cbde1750.zip |
Bug 511631 - address_to_line does not find all CodeAreas
Diffstat (limited to 'agent/tcf/services/tcf_elf.c')
-rw-r--r-- | agent/tcf/services/tcf_elf.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/agent/tcf/services/tcf_elf.c b/agent/tcf/services/tcf_elf.c index 2d14e63e..3b43dd44 100644 --- a/agent/tcf/services/tcf_elf.c +++ b/agent/tcf/services/tcf_elf.c @@ -1371,7 +1371,7 @@ static void search_regions(MemoryMap * map, ContextAddress addr0, ContextAddress } } } - else if (r->addr <= addr1 && r->addr + r->size > addr0) { + else if (r->size > 0 && r->addr <= addr1 && r->addr + r->size - 1 >= addr0) { *add_region(res) = *r; } } @@ -1570,8 +1570,9 @@ UnitAddressRange * elf_find_unit(Context * ctx, ContextAddress addr_min, Context ContextAddress link_addr_min, link_addr_max; MemoryRegion * r = elf_map.regions + i; ELF_File * file = NULL; + assert(r->size > 0); assert(r->addr <= addr_max); - assert(r->addr + r->size > addr_min); + assert(r->addr + r->size - 1 >= addr_min); file = elf_open_memory_region_file(r, &error); if (file == NULL) { if (error) { @@ -1582,24 +1583,29 @@ UnitAddressRange * elf_find_unit(Context * ctx, ContextAddress addr_min, Context continue; } if (r->sect_name == NULL) { + U8_T offs_min = r->file_offs; + U8_T offs_max = r->file_offs + r->size - 1; ELF_File * debug = get_dwarf_file(file); + if (addr_min > r->addr) offs_min = addr_min - r->addr + r->file_offs; + if (addr_max < r->addr + r->size - 1) offs_max = addr_max - r->addr + r->file_offs; + assert(offs_min <= offs_max); + assert(offs_max >= r->file_offs); + assert(offs_min <= r->file_offs + r->size - 1); for (j = 0; range == NULL && j < file->pheader_cnt; j++) { - U8_T offs_min = 0; - U8_T offs_max = 0; U8_T pheader_address = 0; U8_T pheader_file_size = 0; ELF_PHeader * p = file->pheaders + j; ELF_Section * sec = NULL; + if (p->offset > offs_max) continue; if (!is_p_header_region(file, p, r)) continue; pheader_address = get_debug_pheader_address(file, debug, p); pheader_file_size = get_pheader_file_size(file, p, r); - offs_min = addr_min - r->addr + r->file_offs; - offs_max = addr_max - r->addr + r->file_offs; - if (p->offset > offs_max || p->offset + pheader_file_size <= offs_min) continue; + if (pheader_file_size == 0) continue; + if (p->offset + pheader_file_size <= offs_min) continue; link_addr_min = (ContextAddress)(offs_min - p->offset + pheader_address); link_addr_max = (ContextAddress)(offs_max - p->offset + pheader_address); if (link_addr_min < pheader_address) link_addr_min = (ContextAddress)pheader_address; - if (link_addr_max >= pheader_address + pheader_file_size) link_addr_max = (ContextAddress)(pheader_address + pheader_file_size - 1); + if (link_addr_max > pheader_address + pheader_file_size - 1) link_addr_max = (ContextAddress)(pheader_address + pheader_file_size - 1); if (!file->debug_info_file) sec = find_section_by_offset(file, offs_min); range = find_comp_unit_addr_range(get_dwarf_cache(debug), sec, link_addr_min, link_addr_max); if (range != NULL && range_rt_addr != NULL) { @@ -1613,10 +1619,12 @@ UnitAddressRange * elf_find_unit(Context * ctx, ContextAddress addr_min, Context for (idx = 1; range == NULL && idx < debug->section_cnt; idx++) { ELF_Section * sec = debug->sections + idx; if (sec->name != NULL && strcmp(sec->name, r->sect_name) == 0) { - link_addr_min = (ContextAddress)(addr_min - r->addr + sec->addr); - link_addr_max = (ContextAddress)(addr_max - r->addr + sec->addr); - if (link_addr_min < sec->addr) link_addr_min = (ContextAddress)sec->addr; - if (link_addr_max >= sec->addr + sec->size) link_addr_max = (ContextAddress)(sec->addr + sec->size - 1); + if (addr_min < r->addr) link_addr_min = sec->addr; + else link_addr_min = (ContextAddress)(addr_min - r->addr + sec->addr); + if (addr_max > r->addr + r->size - 1) link_addr_max = sec->addr + r->size - 1; + else link_addr_max = (ContextAddress)(addr_max - r->addr + sec->addr); + assert(link_addr_min >= sec->addr); + assert(link_addr_max <= sec->addr + r->size - 1); range = find_comp_unit_addr_range(get_dwarf_cache(debug), sec, link_addr_min, link_addr_max); if (range != NULL && range_rt_addr != NULL) { *range_rt_addr = (ContextAddress)(range->mAddr - sec->addr + r->addr); @@ -1633,6 +1641,10 @@ ContextAddress elf_run_time_address_in_region(Context * ctx, MemoryRegion * r, E /* Note: when debug info is in a separate file, debug file link-time addresses are not same as exec file link-time addresses, * because Linux has a habbit of re-linking execs after extracting debug info */ unsigned i; + if (r->size == 0) { + errno = ERR_INV_ADDRESS; + return 0; + } errno = 0; if (r->sect_name == NULL) { ContextAddress rt = 0; @@ -1641,7 +1653,7 @@ ContextAddress elf_run_time_address_in_region(Context * ctx, MemoryRegion * r, E if (!is_p_header_region(file, p, r)) continue; if (addr < p->address || addr >= p->address + p->mem_size) continue; rt = (ContextAddress)(addr - p->address + p->offset - r->file_offs + r->addr); - if (rt < r->addr || rt >= r->addr + r->size) continue; + if (rt < r->addr || rt > r->addr + r->size - 1) continue; return rt; } } @@ -1719,8 +1731,9 @@ ContextAddress elf_map_to_link_time_address(Context * ctx, ContextAddress addr, MemoryRegion * r = elf_map.regions + i; ELF_File * f = NULL; ELF_File * d = NULL; + assert(r->size > 0); assert(r->addr <= addr); - assert(r->addr + r->size > addr); + assert(r->addr + r->size - 1 >= addr); f = elf_open_memory_region_file(r, NULL); if (f == NULL) continue; d = to_dwarf ? get_dwarf_file(f) : f; |