Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2017-02-06 01:44:22 +0000
committerEugene Tarassov2017-02-06 01:44:22 +0000
commit2c1313866f0de7d8f781047c4ce3ae63cbde1750 (patch)
treece0c10b9b8762881da7a7db2bf0aa8275014ed55 /agent/tcf/services/tcf_elf.c
parent4618123ce0fd88b71f06d5da01468694949a32db (diff)
downloadorg.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.c41
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;

Back to the top