Separate the job of reading the line number info statement program
header (...expialidocious) out into its own function. * dwarf2read.c (struct line_head, struct filenames, struct directories): Replace with... (struct line_header): New structure, containing the full contents of the statement program header, including the include directory and file name tables. (read_file_scope): If we have line number info, instead of just calling dwarf_decode_lines to do all the work, call dwarf_decode_line_header first to get a `struct line_header' containing the data in the statement program header, and then pass that to dwarf_decode_lines, which will pick up where that left off. Be sure to clean up the `struct line_header' object. (dwarf_decode_line_header, free_line_header, add_include_dir, add_file_name): New functions. (dwarf_decode_lines): Move all the code to read the statement program header into dwarf_decode_line_header. Take the line header it built as the first argument, instead of the offset to the compilation unit's line number info. Use the new `struct line_header' type instead of the old structures. No need to do cleanups here now, since we don't allocate anything. (dwarf2_statement_list_fits_in_line_number_section, dwarf2_line_header_too_long): New complaints.
This commit is contained in:
parent
ac3aafc7a6
commit
debd256d71
|
@ -1,3 +1,29 @@
|
|||
2002-05-06 Jim Blandy <jimb@redhat.com>
|
||||
|
||||
Separate the job of reading the line number info statement program
|
||||
header (...expialidocious) out into its own function.
|
||||
* dwarf2read.c (struct line_head, struct filenames, struct
|
||||
directories): Replace with...
|
||||
(struct line_header): New structure, containing the full
|
||||
contents of the statement program header, including the
|
||||
include directory and file name tables.
|
||||
(read_file_scope): If we have line number info, instead of just
|
||||
calling dwarf_decode_lines to do all the work, call
|
||||
dwarf_decode_line_header first to get a `struct line_header'
|
||||
containing the data in the statement program header, and then
|
||||
pass that to dwarf_decode_lines, which will pick up where that
|
||||
left off. Be sure to clean up the `struct line_header' object.
|
||||
(dwarf_decode_line_header, free_line_header, add_include_dir,
|
||||
add_file_name): New functions.
|
||||
(dwarf_decode_lines): Move all the code to read the statement
|
||||
program header into dwarf_decode_line_header. Take the line
|
||||
header it built as the first argument, instead of the offset to
|
||||
the compilation unit's line number info. Use the new `struct
|
||||
line_header' type instead of the old structures. No need to do
|
||||
cleanups here now, since we don't allocate anything.
|
||||
(dwarf2_statement_list_fits_in_line_number_section,
|
||||
dwarf2_line_header_too_long): New complaints.
|
||||
|
||||
2002-05-06 Elena Zannoni <ezannoni@redhat.com>
|
||||
|
||||
* gdbtypes.c (init_vector_type): New function.
|
||||
|
|
493
gdb/dwarf2read.c
493
gdb/dwarf2read.c
|
@ -175,19 +175,49 @@ struct comp_unit_head
|
|||
4 or 12 */
|
||||
};
|
||||
|
||||
/* The data in the .debug_line statement prologue looks like this. */
|
||||
struct line_head
|
||||
/* The line number information for a compilation unit (found in the
|
||||
.debug_line section) begins with a "statement program header",
|
||||
which contains the following information. */
|
||||
struct line_header
|
||||
{
|
||||
unsigned int total_length;
|
||||
unsigned short version;
|
||||
unsigned int header_length;
|
||||
unsigned char minimum_instruction_length;
|
||||
unsigned char default_is_stmt;
|
||||
int line_base;
|
||||
unsigned char line_range;
|
||||
unsigned char opcode_base;
|
||||
|
||||
/* standard_opcode_lengths[i] is the number of operands for the
|
||||
standard opcode whose value is i. This means that
|
||||
standard_opcode_lengths[0] is unused, and the last meaningful
|
||||
element is standard_opcode_lengths[opcode_base - 1]. */
|
||||
unsigned char *standard_opcode_lengths;
|
||||
|
||||
/* The include_directories table. NOTE! These strings are not
|
||||
allocated with xmalloc; instead, they are pointers into
|
||||
debug_line_buffer. If you try to free them, `free' will get
|
||||
indigestion. */
|
||||
unsigned int num_include_dirs, include_dirs_size;
|
||||
char **include_dirs;
|
||||
|
||||
/* The file_names table. NOTE! These strings are not allocated
|
||||
with xmalloc; instead, they are pointers into debug_line_buffer.
|
||||
Don't try to free them directly. */
|
||||
unsigned int num_file_names, file_names_size;
|
||||
struct file_entry
|
||||
{
|
||||
unsigned int total_length;
|
||||
unsigned short version;
|
||||
unsigned int prologue_length;
|
||||
unsigned char minimum_instruction_length;
|
||||
unsigned char default_is_stmt;
|
||||
int line_base;
|
||||
unsigned char line_range;
|
||||
unsigned char opcode_base;
|
||||
unsigned char *standard_opcode_lengths;
|
||||
};
|
||||
char *name;
|
||||
unsigned int dir_index;
|
||||
unsigned int mod_time;
|
||||
unsigned int length;
|
||||
} *file_names;
|
||||
|
||||
/* The start and end of the statement program following this
|
||||
header. These point into dwarf_line_buffer. */
|
||||
char *statement_program_start, *statement_program_end;
|
||||
};
|
||||
|
||||
/* When we construct a partial symbol table entry we only
|
||||
need this much information. */
|
||||
|
@ -502,6 +532,10 @@ static struct complaint dwarf2_missing_line_number_section =
|
|||
{
|
||||
"missing .debug_line section", 0, 0
|
||||
};
|
||||
static struct complaint dwarf2_statement_list_fits_in_line_number_section =
|
||||
{
|
||||
"statement list doesn't fit in .debug_line section", 0, 0
|
||||
};
|
||||
static struct complaint dwarf2_mangled_line_number_section =
|
||||
{
|
||||
"mangled .debug_line section", 0, 0
|
||||
|
@ -574,6 +608,10 @@ static struct complaint dwarf2_misplaced_line_number =
|
|||
{
|
||||
"misplaced first line number at 0x%lx for '%s'", 0, 0
|
||||
};
|
||||
static struct complaint dwarf2_line_header_too_long =
|
||||
{
|
||||
"line number info header doesn't fit in `.debug_line' section", 0, 0
|
||||
};
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
|
@ -653,7 +691,14 @@ static struct attribute *dwarf_attr (struct die_info *, unsigned int);
|
|||
|
||||
static int die_is_declaration (struct die_info *);
|
||||
|
||||
static void dwarf_decode_lines (unsigned int, char *, bfd *,
|
||||
static void free_line_header (struct line_header *lh);
|
||||
|
||||
static struct line_header *(dwarf_decode_line_header
|
||||
(unsigned int offset,
|
||||
bfd *abfd,
|
||||
const struct comp_unit_head *cu_header));
|
||||
|
||||
static void dwarf_decode_lines (struct line_header *, char *, bfd *,
|
||||
const struct comp_unit_head *);
|
||||
|
||||
static void dwarf2_start_subfile (char *, char *);
|
||||
|
@ -1569,7 +1614,7 @@ static void
|
|||
read_file_scope (struct die_info *die, struct objfile *objfile,
|
||||
const struct comp_unit_head *cu_header)
|
||||
{
|
||||
unsigned int line_offset = 0;
|
||||
struct cleanup *back_to = make_cleanup (null_cleanup, 0);
|
||||
CORE_ADDR lowpc = ((CORE_ADDR) -1);
|
||||
CORE_ADDR highpc = ((CORE_ADDR) 0);
|
||||
struct attribute *attr;
|
||||
|
@ -1577,6 +1622,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
|
|||
char *comp_dir = NULL;
|
||||
struct die_info *child_die;
|
||||
bfd *abfd = objfile->obfd;
|
||||
struct line_header *line_header = 0;
|
||||
|
||||
if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
|
||||
{
|
||||
|
@ -1674,9 +1720,18 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
|
|||
attr = dwarf_attr (die, DW_AT_stmt_list);
|
||||
if (attr)
|
||||
{
|
||||
line_offset = DW_UNSND (attr);
|
||||
dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header);
|
||||
unsigned int line_offset = DW_UNSND (attr);
|
||||
line_header = dwarf_decode_line_header (line_offset,
|
||||
abfd, cu_header);
|
||||
if (line_header)
|
||||
{
|
||||
make_cleanup ((make_cleanup_ftype *) free_line_header,
|
||||
(void *) line_header);
|
||||
dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
|
||||
}
|
||||
}
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3945,28 +4000,188 @@ die_is_declaration (struct die_info *die)
|
|||
&& ! dwarf_attr (die, DW_AT_specification));
|
||||
}
|
||||
|
||||
/* Decode the line number information for the compilation unit whose
|
||||
line number info is at OFFSET in the .debug_line section.
|
||||
The compilation directory of the file is passed in COMP_DIR. */
|
||||
|
||||
struct filenames
|
||||
/* Free the line_header structure *LH, and any arrays and strings it
|
||||
refers to. */
|
||||
static void
|
||||
free_line_header (struct line_header *lh)
|
||||
{
|
||||
unsigned int num_files;
|
||||
struct fileinfo
|
||||
{
|
||||
char *name;
|
||||
unsigned int dir;
|
||||
unsigned int time;
|
||||
unsigned int size;
|
||||
}
|
||||
*files;
|
||||
};
|
||||
if (lh->standard_opcode_lengths)
|
||||
free (lh->standard_opcode_lengths);
|
||||
|
||||
struct directories
|
||||
{
|
||||
unsigned int num_dirs;
|
||||
char **dirs;
|
||||
};
|
||||
/* Remember that all the lh->file_names[i].name pointers are
|
||||
pointers into debug_line_buffer, and don't need to be freed. */
|
||||
if (lh->file_names)
|
||||
free (lh->file_names);
|
||||
|
||||
/* Similarly for the include directory names. */
|
||||
if (lh->include_dirs)
|
||||
free (lh->include_dirs);
|
||||
|
||||
free (lh);
|
||||
}
|
||||
|
||||
|
||||
/* Add an entry to LH's include directory table. */
|
||||
static void
|
||||
add_include_dir (struct line_header *lh, char *include_dir)
|
||||
{
|
||||
/* Grow the array if necessary. */
|
||||
if (lh->include_dirs_size == 0)
|
||||
{
|
||||
lh->include_dirs_size = 1; /* for testing */
|
||||
lh->include_dirs = xmalloc (lh->include_dirs_size
|
||||
* sizeof (*lh->include_dirs));
|
||||
}
|
||||
else if (lh->num_include_dirs >= lh->include_dirs_size)
|
||||
{
|
||||
lh->include_dirs_size *= 2;
|
||||
lh->include_dirs = xrealloc (lh->include_dirs,
|
||||
(lh->include_dirs_size
|
||||
* sizeof (*lh->include_dirs)));
|
||||
}
|
||||
|
||||
lh->include_dirs[lh->num_include_dirs++] = include_dir;
|
||||
}
|
||||
|
||||
|
||||
/* Add an entry to LH's file name table. */
|
||||
static void
|
||||
add_file_name (struct line_header *lh,
|
||||
char *name,
|
||||
unsigned int dir_index,
|
||||
unsigned int mod_time,
|
||||
unsigned int length)
|
||||
{
|
||||
struct file_entry *fe;
|
||||
|
||||
/* Grow the array if necessary. */
|
||||
if (lh->file_names_size == 0)
|
||||
{
|
||||
lh->file_names_size = 1; /* for testing */
|
||||
lh->file_names = xmalloc (lh->file_names_size
|
||||
* sizeof (*lh->file_names));
|
||||
}
|
||||
else if (lh->num_file_names >= lh->file_names_size)
|
||||
{
|
||||
lh->file_names_size *= 2;
|
||||
lh->file_names = xrealloc (lh->file_names,
|
||||
(lh->file_names_size
|
||||
* sizeof (*lh->file_names)));
|
||||
}
|
||||
|
||||
fe = &lh->file_names[lh->num_file_names++];
|
||||
fe->name = name;
|
||||
fe->dir_index = dir_index;
|
||||
fe->mod_time = mod_time;
|
||||
fe->length = length;
|
||||
}
|
||||
|
||||
|
||||
/* Read the statement program header starting at OFFSET in
|
||||
dwarf_line_buffer, according to the endianness of ABFD. Return a
|
||||
pointer to a struct line_header, allocated using xmalloc.
|
||||
|
||||
NOTE: the strings in the include directory and file name tables of
|
||||
the returned object point into debug_line_buffer, and must not be
|
||||
freed. */
|
||||
static struct line_header *
|
||||
dwarf_decode_line_header (unsigned int offset, bfd *abfd,
|
||||
const struct comp_unit_head *cu_header)
|
||||
{
|
||||
struct cleanup *back_to;
|
||||
struct line_header *lh;
|
||||
char *line_ptr;
|
||||
int bytes_read;
|
||||
int i;
|
||||
char *cur_dir, *cur_file;
|
||||
|
||||
if (dwarf_line_buffer == NULL)
|
||||
{
|
||||
complain (&dwarf2_missing_line_number_section);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make sure that at least there's room for the total_length field. That
|
||||
could be 12 bytes long, but we're just going to fudge that. */
|
||||
if (offset + 4 >= dwarf_line_size)
|
||||
{
|
||||
complain (&dwarf2_statement_list_fits_in_line_number_section);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lh = xmalloc (sizeof (*lh));
|
||||
memset (lh, 0, sizeof (*lh));
|
||||
back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
|
||||
(void *) lh);
|
||||
|
||||
line_ptr = dwarf_line_buffer + offset;
|
||||
|
||||
/* read in the header */
|
||||
lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size)
|
||||
{
|
||||
complain (&dwarf2_statement_list_fits_in_line_number_section);
|
||||
return 0;
|
||||
}
|
||||
lh->statement_program_end = line_ptr + lh->total_length;
|
||||
lh->version = read_2_bytes (abfd, line_ptr);
|
||||
line_ptr += 2;
|
||||
lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh->default_is_stmt = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh->line_base = read_1_signed_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh->line_range = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh->opcode_base = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh->standard_opcode_lengths
|
||||
= (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char));
|
||||
|
||||
lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
|
||||
for (i = 1; i < lh->opcode_base; ++i)
|
||||
{
|
||||
lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
}
|
||||
|
||||
/* Read directory table */
|
||||
while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
|
||||
{
|
||||
line_ptr += bytes_read;
|
||||
add_include_dir (lh, cur_dir);
|
||||
}
|
||||
line_ptr += bytes_read;
|
||||
|
||||
/* Read file name table */
|
||||
while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
|
||||
{
|
||||
unsigned int dir_index, mod_time, length;
|
||||
|
||||
line_ptr += bytes_read;
|
||||
dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
|
||||
add_file_name (lh, cur_file, dir_index, mod_time, length);
|
||||
}
|
||||
line_ptr += bytes_read;
|
||||
lh->statement_program_start = line_ptr;
|
||||
|
||||
if (line_ptr > dwarf_line_buffer + dwarf_line_size)
|
||||
complain (&dwarf2_line_header_too_long);
|
||||
|
||||
discard_cleanups (back_to);
|
||||
return lh;
|
||||
}
|
||||
|
||||
/* This function exists to work around a bug in certain compilers
|
||||
(particularly GCC 2.95), in which the first line number marker of a
|
||||
|
@ -4013,109 +4228,22 @@ check_cu_functions (CORE_ADDR address)
|
|||
return fn->lowpc;
|
||||
}
|
||||
|
||||
/* Decode the line number information for the compilation unit whose
|
||||
line number info is at OFFSET in the .debug_line section.
|
||||
The compilation directory of the file is passed in COMP_DIR. */
|
||||
|
||||
static void
|
||||
dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
||||
dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
|
||||
const struct comp_unit_head *cu_header)
|
||||
{
|
||||
char *line_ptr;
|
||||
char *line_end;
|
||||
struct line_head lh;
|
||||
struct cleanup *back_to;
|
||||
unsigned int i, bytes_read;
|
||||
char *cur_file, *cur_dir;
|
||||
char *cur_dir;
|
||||
unsigned char op_code, extended_op, adj_opcode;
|
||||
|
||||
#define FILE_ALLOC_CHUNK 5
|
||||
#define DIR_ALLOC_CHUNK 5
|
||||
|
||||
struct filenames files;
|
||||
struct directories dirs;
|
||||
|
||||
if (dwarf_line_buffer == NULL)
|
||||
{
|
||||
complain (&dwarf2_missing_line_number_section);
|
||||
return;
|
||||
}
|
||||
|
||||
files.num_files = 0;
|
||||
files.files = NULL;
|
||||
|
||||
dirs.num_dirs = 0;
|
||||
dirs.dirs = NULL;
|
||||
|
||||
line_ptr = dwarf_line_buffer + offset;
|
||||
|
||||
/* read in the prologue */
|
||||
lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
line_end = line_ptr + lh.total_length;
|
||||
lh.version = read_2_bytes (abfd, line_ptr);
|
||||
line_ptr += 2;
|
||||
lh.prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh.default_is_stmt = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh.line_base = read_1_signed_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh.line_range = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh.opcode_base = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
lh.standard_opcode_lengths = (unsigned char *)
|
||||
xmalloc (lh.opcode_base * sizeof (unsigned char));
|
||||
back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths);
|
||||
|
||||
lh.standard_opcode_lengths[0] = 1;
|
||||
for (i = 1; i < lh.opcode_base; ++i)
|
||||
{
|
||||
lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
}
|
||||
|
||||
/* Read directory table */
|
||||
while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
|
||||
{
|
||||
line_ptr += bytes_read;
|
||||
if ((dirs.num_dirs % DIR_ALLOC_CHUNK) == 0)
|
||||
{
|
||||
dirs.dirs = (char **)
|
||||
xrealloc (dirs.dirs,
|
||||
(dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
|
||||
if (dirs.num_dirs == 0)
|
||||
make_cleanup (free_current_contents, &dirs.dirs);
|
||||
}
|
||||
dirs.dirs[dirs.num_dirs++] = cur_dir;
|
||||
}
|
||||
line_ptr += bytes_read;
|
||||
|
||||
/* Read file name table */
|
||||
while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
|
||||
{
|
||||
line_ptr += bytes_read;
|
||||
if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
|
||||
{
|
||||
files.files = (struct fileinfo *)
|
||||
xrealloc (files.files,
|
||||
(files.num_files + FILE_ALLOC_CHUNK)
|
||||
* sizeof (struct fileinfo));
|
||||
if (files.num_files == 0)
|
||||
make_cleanup (free_current_contents, &files.files);
|
||||
}
|
||||
files.files[files.num_files].name = cur_file;
|
||||
files.files[files.num_files].dir =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
files.files[files.num_files].time =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
files.files[files.num_files].size =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
files.num_files++;
|
||||
}
|
||||
line_ptr += bytes_read;
|
||||
line_ptr = lh->statement_program_start;
|
||||
line_end = lh->statement_program_end;
|
||||
|
||||
/* Read the statement sequences until there's nothing left. */
|
||||
while (line_ptr < line_end)
|
||||
|
@ -4125,19 +4253,23 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
unsigned int file = 1;
|
||||
unsigned int line = 1;
|
||||
unsigned int column = 0;
|
||||
int is_stmt = lh.default_is_stmt;
|
||||
int is_stmt = lh->default_is_stmt;
|
||||
int basic_block = 0;
|
||||
int end_sequence = 0;
|
||||
|
||||
/* Start a subfile for the current file of the state machine. */
|
||||
if (files.num_files >= file)
|
||||
if (lh->num_file_names >= file)
|
||||
{
|
||||
/* The file and directory tables are 0 based, the references
|
||||
are 1 based. */
|
||||
dwarf2_start_subfile (files.files[file - 1].name,
|
||||
(files.files[file - 1].dir
|
||||
? dirs.dirs[files.files[file - 1].dir - 1]
|
||||
: comp_dir));
|
||||
/* lh->include_dirs and lh->file_names are 0-based, but the
|
||||
directory and file name numbers in the statement program
|
||||
are 1-based. */
|
||||
struct file_entry *fe = &lh->file_names[file - 1];
|
||||
char *dir;
|
||||
if (fe->dir_index)
|
||||
dir = lh->include_dirs[fe->dir_index - 1];
|
||||
else
|
||||
dir = comp_dir;
|
||||
dwarf2_start_subfile (fe->name, dir);
|
||||
}
|
||||
|
||||
/* Decode the table. */
|
||||
|
@ -4146,12 +4278,12 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
op_code = read_1_byte (abfd, line_ptr);
|
||||
line_ptr += 1;
|
||||
|
||||
if (op_code >= lh.opcode_base)
|
||||
if (op_code >= lh->opcode_base)
|
||||
{ /* Special operand. */
|
||||
adj_opcode = op_code - lh.opcode_base;
|
||||
address += (adj_opcode / lh.line_range)
|
||||
* lh.minimum_instruction_length;
|
||||
line += lh.line_base + (adj_opcode % lh.line_range);
|
||||
adj_opcode = op_code - lh->opcode_base;
|
||||
address += (adj_opcode / lh->line_range)
|
||||
* lh->minimum_instruction_length;
|
||||
line += lh->line_base + (adj_opcode % lh->line_range);
|
||||
/* append row to matrix using current values */
|
||||
address = check_cu_functions (address);
|
||||
record_line (current_subfile, line, address);
|
||||
|
@ -4175,32 +4307,27 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
address += baseaddr;
|
||||
break;
|
||||
case DW_LNE_define_file:
|
||||
cur_file = read_string (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
|
||||
{
|
||||
files.files = (struct fileinfo *)
|
||||
xrealloc (files.files,
|
||||
(files.num_files + FILE_ALLOC_CHUNK)
|
||||
* sizeof (struct fileinfo));
|
||||
if (files.num_files == 0)
|
||||
make_cleanup (free_current_contents, &files.files);
|
||||
}
|
||||
files.files[files.num_files].name = cur_file;
|
||||
files.files[files.num_files].dir =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
files.files[files.num_files].time =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
files.files[files.num_files].size =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
files.num_files++;
|
||||
{
|
||||
char *cur_file;
|
||||
unsigned int dir_index, mod_time, length;
|
||||
|
||||
cur_file = read_string (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
dir_index =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
mod_time =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
length =
|
||||
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
add_file_name (lh, cur_file, dir_index, mod_time, length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
complain (&dwarf2_mangled_line_number_section);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case DW_LNS_copy:
|
||||
|
@ -4209,7 +4336,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
basic_block = 0;
|
||||
break;
|
||||
case DW_LNS_advance_pc:
|
||||
address += lh.minimum_instruction_length
|
||||
address += lh->minimum_instruction_length
|
||||
* read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
break;
|
||||
|
@ -4218,15 +4345,21 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
line_ptr += bytes_read;
|
||||
break;
|
||||
case DW_LNS_set_file:
|
||||
/* The file and directory tables are 0 based, the references
|
||||
are 1 based. */
|
||||
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
dwarf2_start_subfile
|
||||
(files.files[file - 1].name,
|
||||
(files.files[file - 1].dir
|
||||
? dirs.dirs[files.files[file - 1].dir - 1]
|
||||
: comp_dir));
|
||||
{
|
||||
/* lh->include_dirs and lh->file_names are 0-based,
|
||||
but the directory and file name numbers in the
|
||||
statement program are 1-based. */
|
||||
struct file_entry *fe;
|
||||
char *dir;
|
||||
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
fe = &lh->file_names[file - 1];
|
||||
if (fe->dir_index)
|
||||
dir = lh->include_dirs[fe->dir_index - 1];
|
||||
else
|
||||
dir = comp_dir;
|
||||
dwarf2_start_subfile (fe->name, dir);
|
||||
}
|
||||
break;
|
||||
case DW_LNS_set_column:
|
||||
column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
|
@ -4244,8 +4377,8 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
length since special opcode 255 would have scaled the
|
||||
the increment. */
|
||||
case DW_LNS_const_add_pc:
|
||||
address += (lh.minimum_instruction_length
|
||||
* ((255 - lh.opcode_base) / lh.line_range));
|
||||
address += (lh->minimum_instruction_length
|
||||
* ((255 - lh->opcode_base) / lh->line_range));
|
||||
break;
|
||||
case DW_LNS_fixed_advance_pc:
|
||||
address += read_2_bytes (abfd, line_ptr);
|
||||
|
@ -4254,7 +4387,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
default:
|
||||
{ /* Unknown standard opcode, ignore it. */
|
||||
int i;
|
||||
for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
|
||||
for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++)
|
||||
{
|
||||
(void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
|
||||
line_ptr += bytes_read;
|
||||
|
@ -4263,8 +4396,6 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
|
|||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
/* Start a subfile for DWARF. FILENAME is the name of the file and
|
||||
|
|
Loading…
Reference in New Issue