Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--agent/tcf/services/dwarfcache.c5
-rw-r--r--agent/tcf/services/dwarfcache.h1
-rw-r--r--agent/tcf/services/linenumbers_elf.c43
-rw-r--r--tests/test-dwarf/tcf/backend/backend.c6
4 files changed, 34 insertions, 21 deletions
diff --git a/agent/tcf/services/dwarfcache.c b/agent/tcf/services/dwarfcache.c
index 73c8e13e..b272bf8e 100644
--- a/agent/tcf/services/dwarfcache.c
+++ b/agent/tcf/services/dwarfcache.c
@@ -1396,11 +1396,6 @@ static void compute_reverse_lookup_indices(DWARFCache * Cache, CompUnit * Unit)
Unit->mStatesIndex = (LineNumbersState **)loc_alloc(sizeof(LineNumbersState *) * Unit->mStatesCnt);
for (i = 0; i < Unit->mStatesCnt; i++) Unit->mStatesIndex[i] = Unit->mStates + i;
qsort(Unit->mStatesIndex, Unit->mStatesCnt, sizeof(LineNumbersState *), state_text_pos_comparator);
- for (i = 1; i < Unit->mStatesCnt; i++) {
- LineNumbersState * s = Unit->mStatesIndex[i - 1];
- LineNumbersState * n = Unit->mStatesIndex[i];
- s->mNext = n - Unit->mStates;
- }
if (Cache->mFileInfoHash == NULL) {
Cache->mFileInfoHashSize = 251;
Cache->mFileInfoHash = (FileInfo **)loc_alloc_zero(sizeof(FileInfo *) * Cache->mFileInfoHashSize);
diff --git a/agent/tcf/services/dwarfcache.h b/agent/tcf/services/dwarfcache.h
index e4a357bc..ef7c63ab 100644
--- a/agent/tcf/services/dwarfcache.h
+++ b/agent/tcf/services/dwarfcache.h
@@ -151,7 +151,6 @@ struct PropertyValue {
struct LineNumbersState {
ContextAddress mAddress;
char * mFileName;
- U4_T mNext;
U4_T mFile;
U4_T mLine;
U2_T mColumn;
diff --git a/agent/tcf/services/linenumbers_elf.c b/agent/tcf/services/linenumbers_elf.c
index a5453a34..a81d1228 100644
--- a/agent/tcf/services/linenumbers_elf.c
+++ b/agent/tcf/services/linenumbers_elf.c
@@ -91,12 +91,14 @@ static int compare_path(Channel * chnl, Context * ctx, const char * file, const
return i <= j && strcmp(file, full_name + j - i) == 0;
}
-static LineNumbersState * get_next_in_text(CompUnit * unit, LineNumbersState * state) {
- LineNumbersState * next = unit->mStates + state->mNext;
- if (state->mNext == 0) return NULL;
+static LineNumbersState * get_next_in_text(CompUnit * unit, unsigned index) {
+ LineNumbersState * state = unit->mStatesIndex[index++];
+ LineNumbersState * next = NULL;
+ if (index >= unit->mStatesCnt) return NULL;
+ next = unit->mStatesIndex[index++];
while (next->mLine == state->mLine && next->mColumn == state->mColumn) {
- if (next->mNext == 0) return NULL;
- next = unit->mStates + next->mNext;
+ if (index >= unit->mStatesCnt) return NULL;
+ next = unit->mStatesIndex[index++];
}
if (state->mFile != next->mFile) return NULL;
return next;
@@ -110,10 +112,9 @@ static LineNumbersState * get_next_in_code(CompUnit * unit, LineNumbersState * s
}
static void call_client(CompUnit * unit, LineNumbersState * state,
+ LineNumbersState * code_next, LineNumbersState * text_next,
ContextAddress state_addr, LineNumbersCallBack * client, void * args) {
CodeArea area;
- LineNumbersState * code_next = get_next_in_code(unit, state);
- LineNumbersState * text_next = get_next_in_text(unit, state);
FileInfo * file_info = unit->mFiles + state->mFile;
if (code_next == NULL) return;
@@ -168,12 +169,14 @@ static void unit_line_to_address(Context * ctx, CompUnit * unit, unsigned file,
if (state->mFile < file) {
l = k + 1;
}
- else if (state->mFile > file || state->mLine > line) {
+ else if (state->mFile > file || state->mLine > line || (state->mLine == line && state->mColumn > column)) {
h = k;
}
else {
- LineNumbersState * next = get_next_in_text(unit, state);
- if ((next == NULL ? state->mLine + 1 : next->mLine) <= line) {
+ LineNumbersState * next = get_next_in_text(unit, k);
+ U4_T next_line = next ? next->mLine : state->mLine + 1;
+ U4_T next_column = next ? next->mColumn : 0;
+ if (next_line < line || (next_line == line && next_column <= column)) {
l = k + 1;
}
else {
@@ -188,7 +191,19 @@ static void unit_line_to_address(Context * ctx, CompUnit * unit, unsigned file,
}
for (;;) {
ContextAddress addr = elf_map_to_run_time_address(ctx, unit->mFile, unit->mTextSection, state->mAddress);
- if (errno == 0) call_client(unit, state, addr, client, args);
+ if (errno == 0) {
+ LineNumbersState * code_next = get_next_in_code(unit, state);
+ if (code_next != NULL) {
+ LineNumbersState * text_next = get_next_in_text(unit, k);
+ U4_T next_line = text_next ? text_next->mLine : state->mLine + 1;
+ U4_T next_column = text_next ? text_next->mColumn : 0;
+ if (next_line > line || (next_line == line && next_column > column)) {
+ assert(state->mLine <= line);
+ assert(state->mLine < line || state->mColumn <= column);
+ call_client(unit, state, code_next, text_next, addr, client, args);
+ }
+ }
+ }
if (++k >= unit->mStatesCnt) break;
state = unit->mStatesIndex[k];
if (state->mFile > file) break;
@@ -299,7 +314,11 @@ int address_to_line(Context * ctx, ContextAddress addr0, ContextAddress addr1, L
k--;
}
for (;;) {
- call_client(unit, state, state->mAddress - range->mAddr + range_rt_addr, client, args);
+ LineNumbersState * code_next = get_next_in_code(unit, state);
+ if (code_next != NULL) {
+ LineNumbersState * text_next = get_next_in_text(unit, k);
+ call_client(unit, state, code_next, text_next, state->mAddress - range->mAddr + range_rt_addr, client, args);
+ }
if (++k >= unit->mStatesCnt) break;
state = unit->mStates + k;
if (state->mAddress >= addr_max) break;
diff --git a/tests/test-dwarf/tcf/backend/backend.c b/tests/test-dwarf/tcf/backend/backend.c
index d42c3e58..d8a20adc 100644
--- a/tests/test-dwarf/tcf/backend/backend.c
+++ b/tests/test-dwarf/tcf/backend/backend.c
@@ -282,7 +282,8 @@ static void addr_to_line_callback(CodeArea * area, void * args) {
static void line_to_addr_callback(CodeArea * area, void * args) {
CodeArea * org = (CodeArea *)args;
- if (area->start_line > org->start_line || area->end_line <= org->start_line) {
+ if (area->start_line > org->start_line || (area->start_line == org->start_line && area->start_column > org->start_column) ||
+ area->end_line < org->start_line || (area->end_line == org->start_line && area->end_column <= org->start_column)) {
errno = set_errno(ERR_OTHER, "Invalid line area line numbers");
error("line_to_address");
}
@@ -605,12 +606,11 @@ static void next_pc(void) {
error("address_to_line");
}
else if (area.start_line > 0) {
- char elf_file_name[0x1000];
+ char * elf_file_name = tmp_strdup(area.file);
if (area.start_address > pc || area.end_address <= pc) {
errno = set_errno(ERR_OTHER, "Invalid line area address");
error("address_to_line");
}
- strlcpy(elf_file_name, area.file, sizeof(elf_file_name));
if (line_to_address(elf_ctx, elf_file_name, area.start_line, area.start_column, line_to_addr_callback, &area) < 0) {
error("line_to_address");
}

Back to the top