static void symbol__ensure_annotate(struct map_symbol *ms, struct evsel *evsel)
 {
-       struct disasm_line *dl, *tmp_dl;
-       struct annotation *notes;
-
-       notes = symbol__annotation(ms->sym);
-       if (!list_empty(¬es->src->source))
-               return;
-
-       if (symbol__annotate(ms, evsel, NULL) < 0)
-               return;
+       struct annotation *notes = symbol__annotation(ms->sym);
 
-       /* remove non-insn disasm lines for simplicity */
-       list_for_each_entry_safe(dl, tmp_dl, ¬es->src->source, al.node) {
-               if (dl->al.offset == -1) {
-                       list_del(&dl->al.node);
-                       free(dl);
-               }
-       }
+       if (list_empty(¬es->src->source))
+               symbol__annotate(ms, evsel, NULL);
 }
 
 static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip,
        notes = symbol__annotation(sym);
 
        list_for_each_entry(dl, ¬es->src->source, al.node) {
+               if (dl->al.offset == -1)
+                       continue;
+
                if (sym->start + dl->al.offset == ip) {
                        /*
                         * llvm-objdump places "lock" in a separate line and
        return false;
 }
 
+static struct disasm_line *
+annotation__prev_asm_line(struct annotation *notes, struct disasm_line *curr)
+{
+       struct list_head *sources = ¬es->src->source;
+       struct disasm_line *prev;
+
+       if (curr == list_first_entry(sources, struct disasm_line, al.node))
+               return NULL;
+
+       prev = list_prev_entry(curr, al.node);
+       while (prev->al.offset == -1 &&
+              prev != list_first_entry(sources, struct disasm_line, al.node))
+               prev = list_prev_entry(prev, al.node);
+
+       if (prev->al.offset == -1)
+               return NULL;
+
+       return prev;
+}
+
+static struct disasm_line *
+annotation__next_asm_line(struct annotation *notes, struct disasm_line *curr)
+{
+       struct list_head *sources = ¬es->src->source;
+       struct disasm_line *next;
+
+       if (curr == list_last_entry(sources, struct disasm_line, al.node))
+               return NULL;
+
+       next = list_next_entry(curr, al.node);
+       while (next->al.offset == -1 &&
+              next != list_last_entry(sources, struct disasm_line, al.node))
+               next = list_next_entry(next, al.node);
+
+       if (next->al.offset == -1)
+               return NULL;
+
+       return next;
+}
+
 u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset,
                        struct disasm_line *dl)
 {
         * disasm_line.  If it's the last one, we can use symbol's end
         * address directly.
         */
-       if (&dl->al.node == notes->src->source.prev)
+       next = annotation__next_asm_line(notes, dl);
+       if (next == NULL)
                addr = ms->sym->end + offset;
-       else {
-               next = list_next_entry(dl, al.node);
+       else
                addr = ip + (next->al.offset - dl->al.offset) + offset;
-       }
+
        return map__rip_2objdump(ms->map, addr);
 }
 
         * from the previous instruction.
         */
        if (dl->al.offset > 0) {
+               struct annotation *notes;
                struct disasm_line *prev_dl;
 
-               prev_dl = list_prev_entry(dl, al.node);
-               if (ins__is_fused(arch, prev_dl->ins.name, dl->ins.name)) {
+               notes = symbol__annotation(ms->sym);
+               prev_dl = annotation__prev_asm_line(notes, dl);
+
+               if (prev_dl && ins__is_fused(arch, prev_dl->ins.name, dl->ins.name)) {
                        dl = prev_dl;
                        goto retry;
                }
 
        last_dl = list_last_entry(¬es->src->source,
                                  struct disasm_line, al.node);
+       if (last_dl->al.offset == -1)
+               last_dl = annotation__prev_asm_line(notes, last_dl);
+
+       if (last_dl == NULL)
+               return false;
 
        list_for_each_entry_from(dl, ¬es->src->source, al.node) {
+               /* Skip comment or debug info line */
+               if (dl->al.offset == -1)
+                       continue;
                /* Found the target instruction */
                if (sym->start + dl->al.offset == target) {
                        found = true;
                /* jump instruction creates new basic block(s) */
                next_dl = find_disasm_line(sym, sym->start + dl->ops.target.offset,
                                           /*allow_update=*/false);
-               add_basic_block(bb_data, link, next_dl);
+               if (next_dl)
+                       add_basic_block(bb_data, link, next_dl);
 
                /*
                 * FIXME: determine conditional jumps properly.
                 * next disasm line.
                 */
                if (!strstr(dl->ins.name, "jmp")) {
-                       next_dl = list_next_entry(dl, al.node);
-                       add_basic_block(bb_data, link, next_dl);
+                       next_dl = annotation__next_asm_line(notes, dl);
+                       if (next_dl)
+                               add_basic_block(bb_data, link, next_dl);
                }
                break;