From: Roland McGrath Date: Sat, 19 Jun 2010 00:01:05 +0000 (-0700) Subject: Record new line table fields, export APIs to fetch them. X-Git-Tag: elfutils-0.148~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c70cf4e5e5a463b64673c4e80bcf60c938b437b4;p=thirdparty%2Felfutils.git Record new line table fields, export APIs to fetch them. --- diff --git a/NEWS b/NEWS index 9fc203e89..01a33db94 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,8 @@ Version 0.148: -libdw: Accept DWARF 4 format. - -libdw: New function dwarf_cfi_validate_fde. +libdw: Accept DWARF 4 formats. + New functions dwarf_lineisa, dwarf_linediscriminator, dwarf_lineop_index. + New function dwarf_cfi_validate_fde. libdwfl: Fixes in core-file handling, support cores from PIEs. When working from build IDs, don't open a named file that mismatches. diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 5672082e7..277966bae 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,17 @@ +2010-06-17 Roland McGrath + + * libdwP.h (struct Dwarf_Line_s): Add members isa, discriminator, and + op_index. + * dwarf_getsrclines.c (dwarf_getsrclines): Move NEW_FILE macro guts + into an inner inline function. Set new fields. Check all fields for + overflow when setting. + * dwarf_lineisa.c: New file. + * dwarf_linediscriminator.c: New file. + * dwarf_lineop_index.c: New file. + * Makefile.am (libdw_a_SOURCES): Add them. + * libdw.map (ELFUTILS_0.148): Add them. + * libdw.h: Declare them. + 2010-06-16 Roland McGrath * dwarf_next_cfi.c: Fix version 4 return_address_register decoding. diff --git a/libdw/Makefile.am b/libdw/Makefile.am index 4bd0f2a8d..0604ac28e 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -63,6 +63,8 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_linecol.c dwarf_linebeginstatement.c \ dwarf_lineendsequence.c dwarf_lineblock.c \ dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \ + dwarf_lineisa.c dwarf_linediscriminator.c \ + dwarf_lineop_index.c \ dwarf_onesrcline.c dwarf_formblock.c \ dwarf_getsrcfiles.c dwarf_filesrc.c dwarf_getsrcdirs.c \ dwarf_getlocation.c dwarf_getstring.c dwarf_offabbrev.c \ diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index c3ba837bb..afdf9dba7 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -86,34 +86,6 @@ compare_lines (const void *a, const void *b) return (*p1)->addr - (*p2)->addr; } - -/* Adds a new line to the matrix. We cannot define a function because - we want to use alloca. */ -#define NEW_LINE(end_seq) \ - do { \ - /* Add the new line. */ \ - new_line = (struct linelist *) alloca (sizeof (struct linelist)); \ - \ - /* Set the line information. */ \ - new_line->line.addr = address; \ - /* new_line->line.op_index = op_index; */ \ - new_line->line.file = file; \ - new_line->line.line = line; \ - new_line->line.column = column; \ - new_line->line.is_stmt = is_stmt; \ - new_line->line.basic_block = basic_block; \ - new_line->line.end_sequence = end_seq; \ - new_line->line.prologue_end = prologue_end; \ - new_line->line.epilogue_begin = epilogue_begin; \ - /* new_line->line.isa = isa; */ \ - /* new_line->line.discriminator = discriminator; */ \ - \ - new_line->next = linelist; \ - linelist = new_line; \ - ++nlinelist; \ - } while (0) - - int dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) { @@ -351,11 +323,11 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) /* We are about to process the statement program. Initialize the state machine registers (see 6.2.2 in the v2.1 specification). */ - Dwarf_Word address = 0; + Dwarf_Word addr = 0; unsigned int op_index = 0; - size_t file = 1; - size_t line = 1; - size_t column = 0; + unsigned int file = 1; + int line = 1; + unsigned int column = 0; uint_fast8_t is_stmt = default_is_stmt; bool basic_block = false; bool prologue_end = false; @@ -367,17 +339,61 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ inline void advance_pc (unsigned int op_advance) { - address += minimum_instr_len * ((op_index + op_advance) - / max_ops_per_instr); + addr += minimum_instr_len * ((op_index + op_advance) + / max_ops_per_instr); op_index = (op_index + op_advance) % max_ops_per_instr; } /* Process the instructions. */ struct linelist *linelist = NULL; unsigned int nlinelist = 0; + + /* Adds a new line to the matrix. + We cannot simply define a function because we want to use alloca. */ +#define NEW_LINE(end_seq) \ + do { \ + if (unlikely (add_new_line (alloca (sizeof (struct linelist)), \ + end_seq))) \ + goto invalid_data; \ + } while (0) + + inline bool add_new_line (struct linelist *new_line, bool end_sequence) + { + /* Set the line information. For some fields we use bitfields, + so we would lose information if the encoded values are too large. + Check just for paranoia, and call the data "invalid" if it + violates our assumptions on reasonable limits for the values. */ +#define SET(field) \ + do { \ + new_line->line.field = field; \ + if (unlikely (new_line->line.field != field)) \ + return true; \ + } while (0) + + SET (addr); + SET (op_index); + SET (file); + SET (line); + SET (column); + SET (is_stmt); + SET (basic_block); + SET (end_sequence); + SET (prologue_end); + SET (epilogue_begin); + SET (isa); + SET (discriminator); + +#undef SET + + new_line->next = linelist; + linelist = new_line; + ++nlinelist; + + return false; + } + while (linep < lineendp) { - struct linelist *new_line; unsigned int opcode; unsigned int u128; int s128; @@ -433,7 +449,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) NEW_LINE (1); /* Reset the registers. */ - address = 0; + addr = 0; op_index = 0; file = 1; line = 1; @@ -454,7 +470,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) if (unlikely (lineendp - linep < cu->address_size)) goto invalid_data; if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep, - cu->address_size, &address)) + cu->address_size, &addr)) goto out; break; @@ -609,7 +625,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) || unlikely (lineendp - linep < 2)) goto invalid_data; - address += read_2ubyte_unaligned_inc (dbg, linep); + addr += read_2ubyte_unaligned_inc (dbg, linep); op_index = 0; break; diff --git a/libdw/dwarf_linediscriminator.c b/libdw/dwarf_linediscriminator.c new file mode 100644 index 000000000..d17a99f2b --- /dev/null +++ b/libdw/dwarf_linediscriminator.c @@ -0,0 +1,66 @@ +/* Return code path discriminator in line record. + Copyright (C) 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp) +{ + if (line == NULL) + return -1; + + *discp = line->discriminator; + + return 0; +} diff --git a/libdw/dwarf_lineisa.c b/libdw/dwarf_lineisa.c new file mode 100644 index 000000000..064761e0a --- /dev/null +++ b/libdw/dwarf_lineisa.c @@ -0,0 +1,66 @@ +/* Return ISA in line. + Copyright (C) 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineisa (Dwarf_Line *line, unsigned int *isap) +{ + if (line == NULL) + return -1; + + *isap = line->isa; + + return 0; +} diff --git a/libdw/dwarf_lineop_index.c b/libdw/dwarf_lineop_index.c new file mode 100644 index 000000000..3b433104d --- /dev/null +++ b/libdw/dwarf_lineop_index.c @@ -0,0 +1,66 @@ +/* Return line VLIW operation index. + Copyright (C) 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" + + +int +dwarf_lineop_index (Dwarf_Line *line, unsigned int *idxp) +{ + if (line == NULL) + return -1; + + *idxp = line->op_index; + + return 0; +} diff --git a/libdw/libdw.h b/libdw/libdw.h index 75998e1a0..766aa7bae 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -563,6 +563,9 @@ extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col, /* Return line address. */ extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp); +/* Return line VLIW operation index. */ +extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp); + /* Return line number. */ extern int dwarf_lineno (Dwarf_Line *line, int *linep) __nonnull_attribute__ (2); @@ -591,6 +594,14 @@ extern int dwarf_lineprologueend (Dwarf_Line *line, bool *flagp) extern int dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp) __nonnull_attribute__ (2); +/* Return instruction-set architecture in this record. */ +extern int dwarf_lineisa (Dwarf_Line *line, unsigned int *isap) + __nonnull_attribute__ (2); + +/* Return code path discriminator in this record. */ +extern int dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp) + __nonnull_attribute__ (2); + /* Find line information for address. */ extern const char *dwarf_linesrc (Dwarf_Line *line, diff --git a/libdw/libdw.map b/libdw/libdw.map index 89897acdc..d1f486615 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -241,4 +241,8 @@ ELFUTILS_0.146 { ELFUTILS_0.148 { global: dwarf_cfi_validate_fde; + + dwarf_lineisa; + dwarf_linediscriminator; + dwarf_lineop_index; } ELFUTILS_0.146; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index bfa8a4265..ee4d368b9 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -240,6 +240,12 @@ struct Dwarf_Line_s unsigned int end_sequence:1; unsigned int prologue_end:1; unsigned int epilogue_begin:1; + /* The remaining bit fields are not flags, but hold values presumed to be + small. All the flags and other bit fields should add up to 48 bits + to give the whole struct a nice round size. */ + unsigned int op_index:8; + unsigned int isa:8; + unsigned int discriminator:24; }; struct Dwarf_Lines_s