From patchwork Thu Jun 12 19:48:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 1477 Received: (qmail 19883 invoked by alias); 12 Jun 2014 19:48:28 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 19763 invoked by uid 89); 12 Jun 2014 19:48:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 12 Jun 2014 19:48:19 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5CJmIeW024380 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Thu, 12 Jun 2014 15:48:18 -0400 Received: from barimba.redhat.com (ovpn-113-103.phx2.redhat.com [10.3.113.103]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5CJmGsm007703; Thu, 12 Jun 2014 15:48:17 -0400 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 1/2] make line tables independent of progspace Date: Thu, 12 Jun 2014 13:48:12 -0600 Message-Id: <1402602493-22018-2-git-send-email-tromey@redhat.com> In-Reply-To: <1402602493-22018-1-git-send-email-tromey@redhat.com> References: <1402602493-22018-1-git-send-email-tromey@redhat.com> This changes line tables to be independent of the program space. Ordinarily I would probably have split this patch into several pieces. However, since line tables are used much less frequently than symbols, it seemed ok to have one patch for the whole conversion. This patch first renames the "pc" field of the line table. This made it simple to find all users of the field. It adds accessors and setters for the new field. All the setters of the field are updated not to offset the PC by the section offset. I think I've done this properly but I can't test all the spots, unfortunately. This patch also cleans up xcoffread.c:compare_lte to make it more obviously correct. While this patch is a step forward, it is still using the backlink from the symtab to the objfile. So, more work will be needed in this area in the future. 2014-06-12 Tom Tromey * buildsym.c (record_line, compare_line_numbers): Update. * coffread.c (enter_linenos): Don't add section offset when creating line table. * dbxread.c (process_one_symbol): Remove section offset when creating line table. * disasm.c (do_mixed_source_and_assembly): Update. * dwarf2read.c (dwarf_decode_lines_1): Don't add section offset when creating line table. * jit.c (jit_symtab_line_mapping_add_impl): Update. * mdebugread.c (parse_lines, psymtab_to_symtab_1): Don't add section offset when creating line table. (add_line): Update. * mi/mi-symbol-cmds.c (mi_cmd_symbol_list_lines): Update. * objfiles.c (objfile_relocate1): Don't relocate line tables. * python/py-linetable.c (ltpy_iternext): Update. * symmisc.c (dump_symtab_1): Update. * symtab.c (find_pc_sect_line, find_pcs_for_symtab_line) (skip_prologue_using_lineinfo, skip_prologue_using_sal): Update. * symtab.h (struct linetable_entry) : Rename from "pc". (SET_LINETABLE_ENTRY_ADDRESS, LINETABLE_ENTRY_RAW_ADDRESS) (LINETABLE_ENTRY_ADDRESS): New macros. * xcoffread.c (compare_lte): Update and rewrite. (arrange_linetable): Update. (enter_line_range): Don't add section offset when creating line table. --- gdb/ChangeLog | 28 ++++++++++++++++++++++++ gdb/buildsym.c | 9 ++++---- gdb/coffread.c | 2 -- gdb/dbxread.c | 21 +++++++++++++----- gdb/disasm.c | 22 ++++++++++++------- gdb/dwarf2read.c | 4 ---- gdb/jit.c | 5 ++++- gdb/mdebugread.c | 7 +++--- gdb/mi/mi-symbol-cmds.c | 12 ++++++---- gdb/objfiles.c | 9 -------- gdb/python/py-linetable.c | 4 +++- gdb/symmisc.c | 5 ++++- gdb/symtab.c | 56 +++++++++++++++++++++++++++++++---------------- gdb/symtab.h | 14 +++++++++++- gdb/xcoffread.c | 23 ++++++++++++++----- 15 files changed, 151 insertions(+), 70 deletions(-) diff --git a/gdb/buildsym.c b/gdb/buildsym.c index b367d18..84f698e 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -803,7 +803,8 @@ record_line (struct subfile *subfile, int line, CORE_ADDR pc) if (line == 0 && subfile->line_vector->nitems > 0) { e = subfile->line_vector->item + subfile->line_vector->nitems - 1; - while (subfile->line_vector->nitems > 0 && e->pc == pc) + while (subfile->line_vector->nitems > 0 + && LINETABLE_ENTRY_RAW_ADDRESS (*e) == pc) { e--; subfile->line_vector->nitems--; @@ -812,7 +813,7 @@ record_line (struct subfile *subfile, int line, CORE_ADDR pc) e = subfile->line_vector->item + subfile->line_vector->nitems++; e->line = line; - e->pc = pc; + SET_LINETABLE_ENTRY_ADDRESS (*e, pc); } /* Needed in order to sort line tables from IBM xcoff files. Sigh! */ @@ -825,10 +826,10 @@ compare_line_numbers (const void *ln1p, const void *ln2p) /* Note: this code does not assume that CORE_ADDRs can fit in ints. Please keep it that way. */ - if (ln1->pc < ln2->pc) + if (LINETABLE_ENTRY_RAW_ADDRESS (*ln1) < LINETABLE_ENTRY_RAW_ADDRESS (*ln2)) return -1; - if (ln1->pc > ln2->pc) + if (LINETABLE_ENTRY_RAW_ADDRESS (*ln1) > LINETABLE_ENTRY_RAW_ADDRESS (*ln2)) return 1; /* If pc equal, sort by line. I'm not sure whether this is optimum diff --git a/gdb/coffread.c b/gdb/coffread.c index c650d61..6b59ff2 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -1501,8 +1501,6 @@ enter_linenos (long file_offset, int first_line, if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line) { CORE_ADDR addr = lptr.l_addr.l_paddr; - addr += ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)); record_line (current_subfile, first_line + L_LNNO32 (&lptr), gdbarch_addr_bits_remove (gdbarch, addr)); diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 5171f50..19f29ef 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -2774,8 +2774,9 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, but no N_SLINE stabs. */ if (sline_found_in_function) { - CORE_ADDR addr = last_function_start + valu; - + CORE_ADDR addr = (last_function_start + valu + - ANOFFSET (section_offsets, + SECT_OFF_TEXT (objfile))); record_line (current_subfile, 0, gdbarch_addr_bits_remove (gdbarch, addr)); } @@ -2993,16 +2994,24 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name, if (within_function && sline_found_in_function == 0) { - CORE_ADDR addr = processing_gcc_compilation == 2 ? - last_function_start : valu; + CORE_ADDR addr = ((processing_gcc_compilation == 2 ? + last_function_start : valu) + - ANOFFSET (section_offsets, + SECT_OFF_TEXT (objfile))); record_line (current_subfile, desc, gdbarch_addr_bits_remove (gdbarch, addr)); sline_found_in_function = 1; } else - record_line (current_subfile, desc, - gdbarch_addr_bits_remove (gdbarch, valu)); + { + CORE_ADDR addr = (valu + - ANOFFSET (section_offsets, + SECT_OFF_TEXT (objfile))); + + record_line (current_subfile, desc, + gdbarch_addr_bits_remove (gdbarch, addr)); + } break; case N_BCOMM: diff --git a/gdb/disasm.c b/gdb/disasm.c index d94225b..4cc84c6 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -25,6 +25,7 @@ #include "disasm.h" #include "gdbcore.h" #include "dis-asm.h" +#include "objfiles.h" /* Disassemble functions. FIXME: We should get rid of all the duplicate code in gdb that does @@ -223,13 +224,18 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout, /* First, skip all the preceding functions. */ - for (i = 0; i < nlines - 1 && le[i].pc < low; i++); + for (i = 0; + i < nlines - 1 && LINETABLE_ENTRY_ADDRESS (symtab, le[i]) < low; + i++) + ; /* Now, copy all entries before the end of this function. */ - for (; i < nlines - 1 && le[i].pc < high; i++) + for (; i < nlines - 1 && LINETABLE_ENTRY_ADDRESS (symtab, le[i]) < high; i++) { - if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc) + if (le[i].line == le[i + 1].line + && (LINETABLE_ENTRY_RAW_ADDRESS (le[i]) + == LINETABLE_ENTRY_RAW_ADDRESS (le[i + 1]))) continue; /* Ignore duplicates. */ /* Skip any end-of-function markers. */ @@ -239,19 +245,19 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout, mle[newlines].line = le[i].line; if (le[i].line > le[i + 1].line) out_of_order = 1; - mle[newlines].start_pc = le[i].pc; - mle[newlines].end_pc = le[i + 1].pc; + mle[newlines].start_pc = LINETABLE_ENTRY_ADDRESS (symtab, le[i]); + mle[newlines].end_pc = LINETABLE_ENTRY_ADDRESS (symtab, le[i + 1]); newlines++; } /* If we're on the last line, and it's part of the function, then we need to get the end pc in a special way. */ - if (i == nlines - 1 && le[i].pc < high) + if (i == nlines - 1 && LINETABLE_ENTRY_ADDRESS (symtab, le[i]) < high) { mle[newlines].line = le[i].line; - mle[newlines].start_pc = le[i].pc; - sal = find_pc_line (le[i].pc, 0); + mle[newlines].start_pc = LINETABLE_ENTRY_ADDRESS (symtab, le[i]); + sal = find_pc_line (LINETABLE_ENTRY_ADDRESS (symtab, le[i]), 0); mle[newlines].end_pc = sal.end; newlines++; } diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f078cb4..08254c0 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -17155,7 +17155,6 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, const gdb_byte *line_end; unsigned int bytes_read, extended_len; unsigned char op_code, extended_op, adj_opcode; - CORE_ADDR baseaddr; struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; struct gdbarch *gdbarch = get_objfile_arch (objfile); @@ -17164,8 +17163,6 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc) = record_line; - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - line_ptr = lh->statement_program_start; line_end = lh->statement_program_end; @@ -17277,7 +17274,6 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, op_index = 0; line_ptr += bytes_read; - address += baseaddr; break; case DW_LNE_define_file: { diff --git a/gdb/jit.c b/gdb/jit.c index db6c1b0..411e925 100644 --- a/gdb/jit.c +++ b/gdb/jit.c @@ -612,7 +612,10 @@ jit_symtab_line_mapping_add_impl (struct gdb_symbol_callbacks *cb, stab->linetable->nitems = nlines; for (i = 0; i < nlines; i++) { - stab->linetable->item[i].pc = (CORE_ADDR) map[i].pc; + /* Use the absolute address here, as the offsets will all be + zero. */ + SET_LINETABLE_ENTRY_ADDRESS (stab->linetable->item[i], + (CORE_ADDR) map[i].pc); stab->linetable->item[i].line = map[i].line; } } diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index c03ac67..ac8bd72 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -2205,7 +2205,7 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines, halt = base + fh->cbLine; base += pr->cbLineOffset; - adr = pst->textlow + pr->adr - lowest_pdr_addr; + adr = pr->adr - lowest_pdr_addr; l = adr >> 2; /* in words */ for (lineno = pr->lnLow; base < halt;) @@ -4103,8 +4103,6 @@ psymtab_to_symtab_1 (struct objfile *objfile, else { /* Handle encoded stab line number. */ - valu += ANOFFSET (pst->section_offsets, - SECT_OFF_TEXT (objfile)); record_line (current_subfile, sh.index, gdbarch_addr_bits_remove (gdbarch, valu)); } @@ -4649,7 +4647,8 @@ add_line (struct linetable *lt, int lineno, CORE_ADDR adr, int last) return lineno; lt->item[lt->nitems].line = lineno; - lt->item[lt->nitems++].pc = adr << 2; + SET_LINETABLE_ENTRY_ADDRESS (lt->item[lt->nitems], adr << 2); + ++lt->nitems; return lineno; } diff --git a/gdb/mi/mi-symbol-cmds.c b/gdb/mi/mi-symbol-cmds.c index df008f7..e4e23f2 100644 --- a/gdb/mi/mi-symbol-cmds.c +++ b/gdb/mi/mi-symbol-cmds.c @@ -35,6 +35,7 @@ mi_cmd_symbol_list_lines (char *command, char **argv, int argc) int i; struct cleanup *cleanup_stack, *cleanup_tuple; struct ui_out *uiout = current_uiout; + struct linetable *linetable; if (argc != 1) error (_("-symbol-list-lines: Usage: SOURCE_FILENAME")); @@ -52,12 +53,15 @@ mi_cmd_symbol_list_lines (char *command, char **argv, int argc) gdbarch = get_objfile_arch (s->objfile); cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "lines"); - if (LINETABLE (s) != NULL && LINETABLE (s)->nitems > 0) - for (i = 0; i < LINETABLE (s)->nitems; i++) + linetable = LINETABLE (s); + if (linetable != NULL && linetable->nitems > 0) + for (i = 0; i < linetable->nitems; i++) { cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); - ui_out_field_core_addr (uiout, "pc", gdbarch, LINETABLE (s)->item[i].pc); - ui_out_field_int (uiout, "line", LINETABLE (s)->item[i].line); + ui_out_field_core_addr (uiout, "pc", gdbarch, + LINETABLE_ENTRY_ADDRESS (s, + linetable->item[i])); + ui_out_field_int (uiout, "line", linetable->item[i].line); do_cleanups (cleanup_tuple); } diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 81bbf24..653ac95 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -745,18 +745,9 @@ objfile_relocate1 (struct objfile *objfile, ALL_OBJFILE_SYMTABS (objfile, s) { - struct linetable *l; struct blockvector *bv; int i; - /* First the line table. */ - l = LINETABLE (s); - if (l) - { - for (i = 0; i < l->nitems; ++i) - l->item[i].pc += ANOFFSET (delta, s->block_line_section); - } - /* Don't relocate a shared blockvector more than once. */ if (!s->primary) continue; diff --git a/gdb/python/py-linetable.c b/gdb/python/py-linetable.c index 8b5362b..ce2dd9d 100644 --- a/gdb/python/py-linetable.c +++ b/gdb/python/py-linetable.c @@ -20,6 +20,7 @@ #include "defs.h" #include "python-internal.h" #include "exceptions.h" +#include "objfiles.h" typedef struct { PyObject_HEAD @@ -448,7 +449,8 @@ ltpy_iternext (PyObject *self) item = &(symtab->linetable->item[iter_obj->current_index]); } - obj = build_linetable_entry (item->line, item->pc); + obj = build_linetable_entry (item->line, + LINETABLE_ENTRY_ADDRESS (symtab, *item)); iter_obj->current_index++; return obj; diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 7ea97bd..79d4e82 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -317,7 +317,10 @@ dump_symtab_1 (struct objfile *objfile, struct symtab *symtab, for (i = 0; i < len; i++) { fprintf_filtered (outfile, " line %d at ", l->item[i].line); - fputs_filtered (paddress (gdbarch, l->item[i].pc), outfile); + fputs_filtered (paddress (gdbarch, + LINETABLE_ENTRY_ADDRESS (symtab, + l->item[i])), + outfile); fprintf_filtered (outfile, "\n"); } } diff --git a/gdb/symtab.c b/gdb/symtab.c index 66d1624..900198a 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -2295,6 +2295,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) we will use a line one less than this, with a range from the start of that file to the first line's pc. */ struct linetable_entry *alt = NULL; + struct symtab *alt_symtab = NULL; /* Info on best line seen in this file. */ @@ -2440,14 +2441,19 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) /* Is this file's first line closer than the first lines of other files? If so, record this file, and its first line, as best alternate. */ - if (item->pc > pc && (!alt || item->pc < alt->pc)) - alt = item; + if (LINETABLE_ENTRY_ADDRESS (s, *item) > pc + && (!alt || (LINETABLE_ENTRY_ADDRESS (s, *item) + < LINETABLE_ENTRY_ADDRESS (alt_symtab, *alt)))) + { + alt = item; + alt_symtab = s; + } for (i = 0; i < len; i++, item++) { /* Leave prev pointing to the linetable entry for the last line that started at or before PC. */ - if (item->pc > pc) + if (LINETABLE_ENTRY_ADDRESS (s, *item) > pc) break; prev = item; @@ -2463,22 +2469,26 @@ 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 + && (!best || (LINETABLE_ENTRY_ADDRESS (s, *prev) + > LINETABLE_ENTRY_ADDRESS (best_symtab, *best)))) { best = prev; best_symtab = s; /* Discard BEST_END if it's before the PC of the current BEST. */ - if (best_end <= best->pc) + if (best_end <= LINETABLE_ENTRY_ADDRESS (best_symtab, *best)) best_end = 0; } /* If another line (denoted by ITEM) is in the linetable and its PC is after BEST's PC, but before the current BEST_END, then use ITEM's PC as the new best_end. */ - if (best && i < len && item->pc > best->pc - && (best_end == 0 || best_end > item->pc)) - best_end = item->pc; + if (best && i < len && (LINETABLE_ENTRY_ADDRESS (s, *item) + > LINETABLE_ENTRY_ADDRESS (best_symtab, *best)) + && (best_end == 0 || best_end > LINETABLE_ENTRY_ADDRESS (s, *item))) + best_end = LINETABLE_ENTRY_ADDRESS (s, *item); } if (!best_symtab) @@ -2500,11 +2510,12 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) { val.symtab = best_symtab; val.line = best->line; - val.pc = best->pc; - if (best_end && (!alt || best_end < alt->pc)) + val.pc = LINETABLE_ENTRY_ADDRESS (best_symtab, *best); + if (best_end && (!alt || best_end < LINETABLE_ENTRY_ADDRESS (alt_symtab, + *alt))) val.end = best_end; else if (alt) - val.end = alt->pc; + val.end = LINETABLE_ENTRY_ADDRESS (alt_symtab, *alt); else val.end = BLOCK_END (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)); } @@ -2634,6 +2645,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line, { int start = 0; VEC (CORE_ADDR) *result = NULL; + struct linetable *linetable = LINETABLE (symtab); /* First, collect all the PCs that are at this line. */ while (1) @@ -2641,13 +2653,13 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line, int was_exact; int idx; - idx = find_line_common (LINETABLE (symtab), line, &was_exact, start); + idx = find_line_common (linetable, line, &was_exact, start); if (idx < 0) break; if (!was_exact) { - struct linetable_entry *item = &LINETABLE (symtab)->item[idx]; + struct linetable_entry *item = &linetable->item[idx]; if (*best_item == NULL || item->line < (*best_item)->line) *best_item = item; @@ -2655,7 +2667,8 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line, break; } - VEC_safe_push (CORE_ADDR, result, LINETABLE (symtab)->item[idx].pc); + VEC_safe_push (CORE_ADDR, result, + LINETABLE_ENTRY_ADDRESS (symtab, linetable->item[idx])); start = idx + 1; } @@ -2681,7 +2694,7 @@ find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc) if (symtab != NULL) { l = LINETABLE (symtab); - *pc = l->item[ind].pc; + *pc = LINETABLE_ENTRY_ADDRESS (symtab, l->item[ind]); return 1; } else @@ -2822,8 +2835,10 @@ 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) - return item->pc; + if (item->line > 0 + && func_start <= LINETABLE_ENTRY_ADDRESS (symtab, *item) + && LINETABLE_ENTRY_ADDRESS (symtab, *item) < func_end) + return LINETABLE_ENTRY_ADDRESS (symtab, *item); } return func_addr; @@ -4944,13 +4959,16 @@ 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 + while ((LINETABLE_ENTRY_ADDRESS (prologue_sal.symtab, + linetable->item[idx]) + != prologue_sal.pc) || linetable->item[idx].line == 0) idx++; if (idx+1 < linetable->nitems && linetable->item[idx+1].line != 0 - && linetable->item[idx+1].pc == start_pc) + && LINETABLE_ENTRY_ADDRESS (prologue_sal.symtab, + linetable->item[idx+1]) == start_pc) return start_pc; } diff --git a/gdb/symtab.h b/gdb/symtab.h index fbe5868..fcca53a 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -813,9 +813,21 @@ struct template_symbol struct linetable_entry { int line; - CORE_ADDR pc; + + /* Note that the PC as stored is unrelocated. The appropriate + offset must be applied before it can be used. */ + CORE_ADDR m_pc; }; +#define SET_LINETABLE_ENTRY_ADDRESS(ENTRY, PC) \ + ((ENTRY).m_pc = (PC)) +#define LINETABLE_ENTRY_RAW_ADDRESS(ENTRY) \ + ((ENTRY).m_pc + 0) +#define LINETABLE_ENTRY_ADDRESS(SYMTAB, ENTRY) \ + ((ENTRY).m_pc \ + + ANOFFSET ((SYMTAB)->objfile->section_offsets, \ + (SYMTAB)->block_line_section)) + /* 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 b986dbd..812458e 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -418,7 +418,11 @@ compare_lte (const void *lte1p, const void *lte2p) struct linetable_entry *lte1 = (struct linetable_entry *) lte1p; struct linetable_entry *lte2 = (struct linetable_entry *) lte2p; - return lte1->pc - lte2->pc; + if (LINETABLE_ENTRY_RAW_ADDRESS (*lte1) < LINETABLE_ENTRY_RAW_ADDRESS (*lte2)) + return -1; + if (LINETABLE_ENTRY_RAW_ADDRESS (*lte1) > LINETABLE_ENTRY_RAW_ADDRESS (*lte2)) + return 1; + return 0; } /* Given a line table with function entries are marked, arrange its @@ -457,13 +461,16 @@ arrange_linetable (struct linetable *oldLineTb) fentry_size * sizeof (struct linetable_entry)); } fentry[function_count].line = ii; - fentry[function_count].pc = oldLineTb->item[ii].pc; + SET_LINETABLE_ENTRY_ADDRESS + (fentry[function_count], + LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[ii])); ++function_count; /* If the function was compiled with XLC, we may have to add an extra line entry later. Reserve space for that. */ if (ii + 1 < oldLineTb->nitems - && oldLineTb->item[ii].pc != oldLineTb->item[ii + 1].pc) + && (LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[ii]) + != LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[ii + 1]))) extra_lines++; } } @@ -500,7 +507,8 @@ arrange_linetable (struct linetable *oldLineTb) extra line to cover the function prologue. */ jj = fentry[ii].line; if (jj + 1 < oldLineTb->nitems - && oldLineTb->item[jj].pc != oldLineTb->item[jj + 1].pc) + && (LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[jj]) + != LINETABLE_ENTRY_RAW_ADDRESS (oldLineTb->item[jj + 1]))) { newLineTb->item[newline] = oldLineTb->item[jj]; newLineTb->item[newline].line = oldLineTb->item[jj + 1].line; @@ -878,6 +886,8 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, while (curoffset <= limit_offset) { + CORE_ADDR relocated; + bfd_seek (abfd, curoffset, SEEK_SET); bfd_bread (ext_lnno, linesz, abfd); bfd_coff_swap_lineno_in (abfd, ext_lnno, &int_lnno); @@ -886,9 +896,10 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset, addr = (int_lnno.l_lnno ? int_lnno.l_addr.l_paddr : read_symbol_nvalue (int_lnno.l_addr.l_symndx)); - addr += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (addr < startaddr || (endaddr && addr >= endaddr)) + relocated = (addr + ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile))); + if (relocated < startaddr || (endaddr && relocated >= endaddr)) return; if (int_lnno.l_lnno == 0)