From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by sourceware.org (Postfix) with ESMTPS id 0F6A13850401 for ; Mon, 20 Jul 2020 12:55:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0F6A13850401 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=andrew.burgess@embecosm.com Received: by mail-wm1-x32f.google.com with SMTP id o2so25123985wmh.2 for ; Mon, 20 Jul 2020 05:55:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=XS987PkUeG5U4daSKudZ937gaZQy/dkHETeSL7ySCBo=; b=NwGJV5WK8OAjPAYLCjgzYX/vu6CcoQ0Fwh/ivFV/mIzeOO9ND3yXwvGzvValO5F8iW uSxi2VEc9rHP70YBlvvrsQFK62tMNi8+6bIx6+lz7ijuy1Xo+voX5qzzXxhWrw4vlDcy ScP+IFB++ms0FoXN28hZQ4VYZcUrJbhavV5DRx0XTI1sGh9rN3wt3BFf0gf4rk+TEyHU Pq24s2Vs3V/3ZINOjnVzGUT1oG6bm7xz/OycbqwE4j9FAmDjgurJDZFl9B8gPRxTyNCw 9nguMAs+4A6AedYxSZX/JTq9kfqBe8eiO9LkRz+Yh10AOxSbR53FmBehkQUk8eVdVvXL dzVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=XS987PkUeG5U4daSKudZ937gaZQy/dkHETeSL7ySCBo=; b=m6E2lk+TKT3kXbVSCo68ppcXKcS494H1mlxff2SMI7ySB/Jd+paK1ZZjbnE4PjRL+d Ny+vZM0gODHBJlwf+l0WGRlMHLepZEmBJj3YqS6JfvOrvnuQ53smOQuyaPBo71rCoW/c LAZ9uZ3uDF+3nVkuExeJrZoZ+VagoRFuKozIrD32RplS/mxQwz+8cXO3F3D2RV2DPdLc UjYV+xwzC/cFsMjgYsY+6nj1ZzzpIKC9TfZcwhmOVjgESd299Rj7ISl0ctcAkrfbDePr Nz3lAx0dgRToFALUbpq10xgc5N/X4cv+FQJOYP/IOBZr9hnu+HAVaacVClbRxEqfWchJ 6+qw== X-Gm-Message-State: AOAM531TbJdFNAW7urFGTzdPsLQO7FFZ/wfsFGXzPyPWuNbfKNPnnvh4 jTPbiUY922p9zn3DbKzc+X0k39l066g= X-Google-Smtp-Source: ABdhPJxNX8zaQXHN0MUb1RmyjL16cd5NaeKJSOGKmf6oZn9YWUKu05zGw/PcGEec7Uw8fEEb4YCihQ== X-Received: by 2002:a7b:c775:: with SMTP id x21mr21774221wmk.34.1595249710203; Mon, 20 Jul 2020 05:55:10 -0700 (PDT) Received: from localhost (host86-134-151-238.range86-134.btcentralplus.com. [86.134.151.238]) by smtp.gmail.com with ESMTPSA id u17sm32879022wrp.70.2020.07.20.05.55.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jul 2020 05:55:09 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Subject: [PATCH] gdb: Don't hard code 0 as end marker in GDB's line table Date: Mon, 20 Jul 2020 13:55:05 +0100 Message-Id: <20200720125505.1506140-1-andrew.burgess@embecosm.com> X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Jul 2020 12:55:15 -0000 Currently GDB hard-codes the use of 0 as the end of sequence marker in its line tables. After this commit GDB now uses a named constant (linetable_entry::end_marker) as the end of sequence marker. The value of this constant is -1, not 0. This change was made in order to aid fixing bug PR gdb/26243. Bug PR gdb/26243 is about allowing line number 0 to be used to indicate a program address that has no corresponding source line (this use is specified in the DWARF standard). Currently GDB can't use line number 0 as this line number is hard coded as the end of sequence marker, but, after this commit line number 0 no longer has any special meaning. This commit does not fix PR gdb/26243, but it is step towards allowing that issue to be fixed. gdb/ChangeLog: PR gdb/26243 * buildsym.c (buildsym_compunit::record_line): Add an assert for the incoming line number. Update comments to not mention 0 specifically. Update to check for linetable_entry::end_marker rather than 0. * disasm.c (do_mixed_source_and_assembly_deprecated): Check for linetable_entry::end_marker not 0. (do_mixed_source_and_assembly): Likewise. * dwarf2/read.c (dwarf_finish_line): Pass linetable_entry::end_marker not 0. * mdebugread.c (add_line): Set is_stmt field. * python/py-linetable.c (ltpy_get_all_source_lines): Check for linetable_entry::end_marker not 0, update comments. (ltpy_iternext): Likewise. * record-btrace.c (btrace_find_line_range): Likewise. * symmisc.c (maintenance_print_one_line_table): Likewise. * symtab.c (find_pc_sect_line): Likewise. (find_line_symtab): Likewise. (skip_prologue_using_sal): Likewise. * symtab.h (linetable_entry::end_marker): New const static member variable. Add a static assert for this field. * xcoffread.c (arrange_linetable): Check for linetable_entry::end_marker not 0. --- gdb/ChangeLog | 26 ++++++++++++++++++++++++++ gdb/buildsym.c | 36 ++++++++++++++++++++---------------- gdb/disasm.c | 9 +++++---- gdb/dwarf2/read.c | 3 ++- gdb/mdebugread.c | 1 + gdb/python/py-linetable.c | 13 +++++++------ gdb/record-btrace.c | 3 ++- gdb/symmisc.c | 2 +- gdb/symtab.c | 22 +++++++++++++--------- gdb/symtab.h | 12 ++++++++++++ gdb/xcoffread.c | 11 +++++++---- 11 files changed, 96 insertions(+), 42 deletions(-) diff --git a/gdb/buildsym.c b/gdb/buildsym.c index bd0ca491401..e6d4dc117c1 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -671,6 +671,10 @@ buildsym_compunit::record_line (struct subfile *subfile, int line, { struct linetable_entry *e; + /* Is this an asset? Or is this processing user input and so should we + be handling, or throwing an error for invalid data? */ + gdb_assert (line == linetable_entry::end_marker || line >= 0); + /* Make sure line vector exists and is big enough. */ if (!subfile->line_vector) { @@ -692,20 +696,19 @@ buildsym_compunit::record_line (struct subfile *subfile, int line, * sizeof (struct linetable_entry)))); } - /* Normally, we treat lines as unsorted. But the end of sequence - marker is special. We sort line markers at the same PC by line - number, so end of sequence markers (which have line == 0) appear - first. This is right if the marker ends the previous function, - and there is no padding before the next function. But it is - wrong if the previous line was empty and we are now marking a - switch to a different subfile. We must leave the end of sequence - marker at the end of this group of lines, not sort the empty line - to after the marker. The easiest way to accomplish this is to - delete any empty lines from our table, if they are followed by - end of sequence markers. All we lose is the ability to set - breakpoints at some lines which contain no instructions - anyway. */ - if (line == 0) + /* Normally, we treat lines as unsorted. But the end of sequence marker + is special. We sort line markers at the same PC by line number, so + end of sequence markers (which have line == + linetable_entry::end_marker) appear first. This is right if the + marker ends the previous function, and there is no padding before the + next function. But it is wrong if the previous line was empty and we + are now marking a switch to a different subfile. We must leave the + end of sequence marker at the end of this group of lines, not sort the + empty line to after the marker. The easiest way to accomplish this is + to delete any empty lines from our table, if they are followed by end + of sequence markers. All we lose is the ability to set breakpoints at + some lines which contain no instructions anyway. */ + if (line == linetable_entry::end_marker) { while (subfile->line_vector->nitems > 0) { @@ -944,8 +947,9 @@ buildsym_compunit::end_symtab_with_blockvector (struct block *static_block, const linetable_entry &ln2) -> bool { if (ln1.pc == ln2.pc - && ((ln1.line == 0) != (ln2.line == 0))) - return ln1.line == 0; + && ((ln1.line == linetable_entry::end_marker) + != (ln2.line == linetable_entry::end_marker))) + return ln1.line == linetable_entry::end_marker; return (ln1.pc < ln2.pc); }; diff --git a/gdb/disasm.c b/gdb/disasm.c index 143ba2f59b9..4b7cc88fbfb 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -383,7 +383,7 @@ do_mixed_source_and_assembly_deprecated continue; /* Skip any end-of-function markers. */ - if (le[i].line == 0) + if (le[i].line == linetable_entry::end_marker) continue; mle[newlines].line = le[i].line; @@ -571,7 +571,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, gdb::optional list_emitter; last_symtab = NULL; - last_line = 0; + last_line = linetable_entry::end_marker; pc = low; while (pc < high) @@ -591,7 +591,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, /* If this is the first line of output, check for any preceding lines. */ - if (last_line == 0 + if (last_line == linetable_entry::end_marker && first_le != NULL && first_le->line < sal.line) { @@ -604,7 +604,8 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, /* Same source file as last time. */ if (sal.symtab != NULL) { - if (sal.line > last_line + 1 && last_line != 0) + if (last_line != linetable_entry::end_marker + && sal.line > last_line + 1) { int l; diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 39ed455def5..bdbecf640ff 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -20390,7 +20390,8 @@ dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile, paddress (gdbarch, address)); } - dwarf_record_line_1 (gdbarch, subfile, 0, address, true, cu); + dwarf_record_line_1 (gdbarch, subfile, linetable_entry::end_marker, + address, true, cu); } void diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index d38372041d7..01029fbd971 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -4516,6 +4516,7 @@ add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last) return lineno; lt->item[lt->nitems].line = lineno; + lt->item[lt->nitems].is_stmt = 1; lt->item[lt->nitems++].pc = adr << 2; return lineno; } diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c index 858313bb22d..22a44fe5f36 100644 --- a/gdb/python/py-linetable.c +++ b/gdb/python/py-linetable.c @@ -238,10 +238,11 @@ ltpy_get_all_source_lines (PyObject *self, PyObject *args) { item = &(SYMTAB_LINETABLE (symtab)->item[index]); - /* 0 is used to signify end of line table information. Do not - include in the source set. */ - if (item->line > 0) + /* The special value linetable_entry::end_marker is used to signify + end of line table information. Do not include in the source set. */ + if (item->line != linetable_entry::end_marker) { + gdb_assert (item->line >= 0); gdbpy_ref<> line = gdb_py_object_from_longest (item->line); if (line == NULL) @@ -407,9 +408,9 @@ ltpy_iternext (PyObject *self) item = &(SYMTAB_LINETABLE (symtab)->item[iter_obj->current_index]); - /* Skip over internal entries such as 0. 0 signifies the end of - line table data and is not useful to the API user. */ - while (item->line < 1) + /* Skip over internal entries such as the end of sequence marker, + linetable_entry::end_marker as this is not useful to the API user. */ + while (item->line == linetable_entry::end_marker) { iter_obj->current_index++; diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 718de62f280..36ae671fa90 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -732,7 +732,8 @@ btrace_find_line_range (CORE_ADDR pc) possibly adding more line numbers to the range. At the time this change was made I was unsure how to test this so chose to go with maintaining the existing experience. */ - if ((lines[i].pc == pc) && (lines[i].line != 0) + if ((lines[i].pc == pc) + && (lines[i].line != linetable_entry::end_marker) && (lines[i].is_stmt == 1)) range = btrace_line_range_add (range, lines[i].line); } diff --git a/gdb/symmisc.c b/gdb/symmisc.c index fc56cfa9381..9b05ca2f4da 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -1036,7 +1036,7 @@ maintenance_print_one_line_table (struct symtab *symtab, void *data) item = &linetable->item [i]; ui_out_emit_tuple tuple_emitter (uiout, nullptr); uiout->field_signed ("index", i); - if (item->line > 0) + if (item->line != linetable_entry::end_marker) uiout->field_signed ("line", item->line); else uiout->field_string ("line", _("END")); diff --git a/gdb/symtab.c b/gdb/symtab.c index f96ad9554d9..02a08481008 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -3248,7 +3248,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) save prev if it represents the end of a function (i.e. line number 0) instead of a real line. */ - if (prev && prev->line && (!best || prev->pc > best->pc)) + if (prev && prev->line != linetable_entry::end_marker + && (!best || prev->pc > best->pc)) { best = prev; best_symtab = iter_s; @@ -3264,7 +3265,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) { struct linetable_entry *tmp = best; while (tmp > first && (tmp - 1)->pc == tmp->pc - && (tmp - 1)->line != 0 && !tmp->is_stmt) + && (tmp - 1)->line != linetable_entry::end_marker + && !tmp->is_stmt) --tmp; if (tmp->is_stmt) best = tmp; @@ -3291,7 +3293,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) don't make some up. */ val.pc = pc; } - else if (best->line == 0) + else if (best->line == linetable_entry::end_marker) { /* If our best fit is in a range of PC's for which no line number info is available (line number is zero) then we didn't @@ -3378,14 +3380,14 @@ find_line_symtab (struct symtab *sym_tab, int line, the GLOBAL_BLOCK of a symtab has a begin and end address). */ /* BEST is the smallest linenumber > LINE so far seen, - or 0 if none has been seen so far. + or the end marker if none has been seen so far. BEST_INDEX and BEST_LINETABLE identify the item for it. */ int best; if (best_index >= 0) best = best_linetable->item[best_index].line; else - best = 0; + best = linetable_entry::end_marker; for (objfile *objfile : current_program_space->objfiles ()) { @@ -3419,7 +3421,8 @@ find_line_symtab (struct symtab *sym_tab, int line, best_symtab = s; goto done; } - if (best == 0 || l->item[ind].line < best) + if (best == linetable_entry::end_marker + || l->item[ind].line < best) { best = l->item[ind].line; best_index = ind; @@ -3718,7 +3721,8 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab) /* Don't use line numbers of zero, they mark special entries in the table. See the commentary on symtab.h before the definition of struct linetable. */ - if (item->line > 0 && func_start <= item->pc && item->pc < func_end) + if (item->line != linetable_entry::end_marker + && func_start <= item->pc && item->pc < func_end) return item->pc; } @@ -3946,11 +3950,11 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr) /* Skip any earlier lines, and any end-of-sequence marker from a previous function. */ while (linetable->item[idx].pc != prologue_sal.pc - || linetable->item[idx].line == 0) + || linetable->item[idx].line == linetable_entry::end_marker) idx++; if (idx+1 < linetable->nitems - && linetable->item[idx+1].line != 0 + && linetable->item[idx+1].line != linetable_entry::end_marker && linetable->item[idx+1].pc == start_pc) return start_pc; } diff --git a/gdb/symtab.h b/gdb/symtab.h index 0b186554ea1..83d60d8d64b 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1306,6 +1306,11 @@ struct rust_vtable_symbol : public symbol struct linetable_entry { + /* Special value placed into the LINE field to indicate an end of + sequence in the line table. */ + + static const int end_marker = -1; + /* The line number for this entry. */ int line; @@ -1316,6 +1321,13 @@ struct linetable_entry CORE_ADDR pc; }; +/* Normally line numbers in a program are positive integers greater than + zero. The line number 0 is reserved in DWARF to indicate instructions + that don't have associated source code. The end marker then must be + less than zero. */ + +gdb_static_assert (linetable_entry::end_marker < 0); + /* The order of entries in the linetable is significant. They should be sorted by increasing values of the pc field. If there is more than one entry for a given pc, then I'm not sure what should happen (and diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index a792c0fea2e..4c99c2da3ef 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -435,7 +435,7 @@ arrange_linetable (struct linetable *oldLineTb) if (oldLineTb->item[ii].is_stmt == 0) continue; - if (oldLineTb->item[ii].line == 0) + if (oldLineTb->item[ii].line == linetable_entry::end_marker) { /* Function entry found. */ if (function_count >= fentry_size) { /* Make sure you have room. */ @@ -477,9 +477,11 @@ arrange_linetable (struct linetable *oldLineTb) a function begin. */ newline = 0; - if (oldLineTb->item[0].line != 0) + if (oldLineTb->item[0].line != linetable_entry::end_marker) for (newline = 0; - newline < oldLineTb->nitems && oldLineTb->item[newline].line; ++newline) + newline < oldLineTb->nitems + && oldLineTb->item[newline].line != linetable_entry::end_marker; + ++newline) newLineTb->item[newline] = oldLineTb->item[newline]; /* Now copy function lines one by one. */ @@ -498,7 +500,8 @@ arrange_linetable (struct linetable *oldLineTb) } for (jj = fentry[ii].line + 1; - jj < oldLineTb->nitems && oldLineTb->item[jj].line != 0; + jj < oldLineTb->nitems + && oldLineTb->item[jj].line != linetable_entry::end_marker; ++jj, ++newline) newLineTb->item[newline] = oldLineTb->item[jj]; } -- 2.25.4