Blame libdwarf/dwarf_line_table_reader_common.c

Packit cdaae3
/*
Packit cdaae3
   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
Packit cdaae3
   Portions Copyright (C) 2007-2017 David Anderson. All Rights Reserved.
Packit cdaae3
   Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
Packit cdaae3
   Portions Copyright (C) 2015-2015 Google, Inc. All Rights Reserved.
Packit cdaae3
Packit cdaae3
   This program is free software; you can redistribute it and/or modify it
Packit cdaae3
   under the terms of version 2.1 of the GNU Lesser General Public License
Packit cdaae3
   as published by the Free Software Foundation.
Packit cdaae3
Packit cdaae3
   This program is distributed in the hope that it would be useful, but
Packit cdaae3
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit cdaae3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit cdaae3
Packit cdaae3
   Further, this software is distributed without any warranty that it is
Packit cdaae3
   free of the rightful claim of any third person regarding infringement
Packit cdaae3
   or the like.  Any license provided herein, whether implied or
Packit cdaae3
   otherwise, applies only to this software file.  Patent licenses, if
Packit cdaae3
   any, provided herein do not apply to combinations of this program with
Packit cdaae3
   other software, or any other product whatsoever.
Packit cdaae3
Packit cdaae3
   You should have received a copy of the GNU Lesser General Public
Packit cdaae3
   License along with this program; if not, write the Free Software
Packit cdaae3
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
Packit cdaae3
   USA.
Packit cdaae3
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
/*  This is #included twice. Once for
Packit cdaae3
    libdwarf callers and one for dwarfdump which prints
Packit cdaae3
    the internals.
Packit cdaae3
Packit cdaae3
    This way we have just one blob of code that reads
Packit cdaae3
    the table operations.  */
Packit cdaae3
Packit cdaae3
#define TRUE 1
Packit cdaae3
#define FALSE 0
Packit cdaae3
Packit cdaae3
static unsigned char
Packit cdaae3
dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_TWO_LEVEL] = {
Packit cdaae3
    /* DWARF2 */
Packit cdaae3
    0,
Packit cdaae3
    1, 1, 1, 1,
Packit cdaae3
    0, 0, 0,
Packit cdaae3
    1,
Packit cdaae3
    /* Following are new for DWARF3. */
Packit cdaae3
    0, 0, 1,
Packit cdaae3
    /* Experimental opcodes. */
Packit cdaae3
    1, 2, 0,
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
/* We have a normal standard opcode base, but
Packit cdaae3
   an arm compiler emitted a non-standard table!
Packit cdaae3
   This could lead to problems...
Packit cdaae3
   ARM C/C++ Compiler, RVCT4.0 [Build 4
Packit cdaae3
   00] seems to get the table wrong .  */
Packit cdaae3
static unsigned char
Packit cdaae3
dwarf_arm_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
Packit cdaae3
    /* DWARF2 */
Packit cdaae3
    0,
Packit cdaae3
    1, 1, 1, 1,
Packit cdaae3
    0, 0, 0,
Packit cdaae3
    0,  /* <<< --- this is wrong */
Packit cdaae3
    /* Following are new for DWARF3. */
Packit cdaae3
    0, 0, 1
Packit cdaae3
};
Packit cdaae3
Packit cdaae3
/* Rather like memcmp but identifies which value pair
Packit cdaae3
    mismatches (the return value is non-zero if mismatch,
Packit cdaae3
    zero if match)..
Packit cdaae3
    mismatch_entry returns the table index that mismatches.
Packit cdaae3
    tabval returns the table byte value.
Packit cdaae3
    lineval returns the value from the line table header.  */
Packit cdaae3
static int
Packit cdaae3
operandmismatch(unsigned char * table,unsigned table_length,
Packit cdaae3
    unsigned char *linetable,
Packit cdaae3
    unsigned check_count,
Packit cdaae3
    unsigned * mismatch_entry, unsigned * tabval,unsigned *lineval)
Packit cdaae3
{
Packit cdaae3
    unsigned i = 0;
Packit cdaae3
Packit cdaae3
    /* check_count better be <= table_length */
Packit cdaae3
    for (i = 0; i
Packit cdaae3
        if (i > table_length) {
Packit cdaae3
            *mismatch_entry = i;
Packit cdaae3
            *lineval = linetable[i];
Packit cdaae3
            *tabval = 0; /* No entry present. */
Packit cdaae3
            /* A kind of mismatch */
Packit cdaae3
            return  TRUE;
Packit cdaae3
        }
Packit cdaae3
        if (table[i] == linetable[i]) {
Packit cdaae3
            continue;
Packit cdaae3
        }
Packit cdaae3
        *mismatch_entry = i;
Packit cdaae3
        *tabval = table[i];
Packit cdaae3
        *lineval = linetable[i];
Packit cdaae3
        return  TRUE;
Packit cdaae3
    }
Packit cdaae3
    /* Matches. */
Packit cdaae3
    return FALSE;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
/* Common line table header reading code.
Packit cdaae3
   Returns DW_DLV_OK, DW_DLV_ERROR.
Packit cdaae3
   DW_DLV_NO_ENTRY cannot be returned, but callers should
Packit cdaae3
   assume it is possible.
Packit cdaae3
Packit cdaae3
   The line_context area must be initialized properly before calling this.
Packit cdaae3
Packit cdaae3
   Has the side effect of allocating arrays which
Packit cdaae3
   must be freed (see the Line_Table_Context which
Packit cdaae3
   holds the pointers to space we allocate here).
Packit cdaae3
Packit cdaae3
   bogus_bytes_ptr and bogus_bytes are output values which
Packit cdaae3
   let a print-program notify the user of some surprising bytes
Packit cdaae3
   after a line table header and before the line table instructions.
Packit cdaae3
   These can be ignored unless one is printing.
Packit cdaae3
   And are ignored if NULL passed as the pointer.
Packit cdaae3
Packit cdaae3
   err_count_out may be NULL, in which case we
Packit cdaae3
   make no attempt to count checking-type errors.
Packit cdaae3
   Checking-type errors do not stop us, we just report them.
Packit cdaae3
Packit cdaae3
   See dw-linetableheader.txt for the ordering of text fields
Packit cdaae3
   across the various dwarf versions. The code
Packit cdaae3
   follows this ordering closely.
Packit cdaae3
Packit cdaae3
   Some of the arguments remaining are in line_context
Packit cdaae3
   so can be deleted from the
Packit cdaae3
   argument list (after a close look for correctness).
Packit cdaae3
*/
Packit cdaae3
static int
Packit cdaae3
_dwarf_read_line_table_header(Dwarf_Debug dbg,
Packit cdaae3
    Dwarf_CU_Context cu_context,
Packit cdaae3
    Dwarf_Small * section_start,
Packit cdaae3
    Dwarf_Small * data_start,
Packit cdaae3
    Dwarf_Unsigned section_length,
Packit cdaae3
    Dwarf_Small ** updated_data_start_out,
Packit cdaae3
    Dwarf_Line_Context  line_context,
Packit cdaae3
    Dwarf_Small ** bogus_bytes_ptr,
Packit cdaae3
    Dwarf_Unsigned *bogus_bytes,
Packit cdaae3
    Dwarf_Error * err,
Packit cdaae3
    int *err_count_out)
Packit cdaae3
{
Packit cdaae3
    Dwarf_Small *line_ptr = data_start;
Packit cdaae3
    Dwarf_Small *starting_line_ptr = data_start;
Packit cdaae3
    Dwarf_Unsigned total_length = 0;
Packit cdaae3
    int local_length_size = 0;
Packit cdaae3
    int local_extension_size = 0;
Packit cdaae3
    Dwarf_Unsigned prologue_length = 0;
Packit cdaae3
    Dwarf_Half version = 0;
Packit cdaae3
    Dwarf_Small *section_end = section_start + section_length;
Packit cdaae3
    Dwarf_Small *line_ptr_end = 0;
Packit cdaae3
    Dwarf_Small *lp_begin = 0;
Packit cdaae3
    int res = 0;
Packit cdaae3
Packit cdaae3
    if (bogus_bytes_ptr) *bogus_bytes_ptr = 0;
Packit cdaae3
    if (bogus_bytes) *bogus_bytes= 0;
Packit cdaae3
Packit cdaae3
    line_context->lc_line_ptr_start = starting_line_ptr;
Packit cdaae3
    /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
Packit cdaae3
    READ_AREA_LENGTH_CK(dbg, total_length, Dwarf_Unsigned,
Packit cdaae3
        line_ptr, local_length_size, local_extension_size,
Packit cdaae3
        err, section_length,section_end);
Packit cdaae3
Packit cdaae3
    line_ptr_end = line_ptr + total_length;
Packit cdaae3
    line_context->lc_line_ptr_end = line_ptr_end;
Packit cdaae3
    line_context->lc_length_field_length = local_length_size +
Packit cdaae3
        local_extension_size;
Packit cdaae3
    line_context->lc_section_offset = starting_line_ptr -
Packit cdaae3
        dbg->de_debug_line.dss_data;
Packit cdaae3
    /*  ASSERT: line_context->lc_length_field_length == line_ptr
Packit cdaae3
        -line_context->lc_line_ptr_start; */
Packit cdaae3
    if (line_ptr_end > section_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_total_length = total_length;
Packit cdaae3
Packit cdaae3
    READ_UNALIGNED_CK(dbg, version, Dwarf_Half,
Packit cdaae3
        line_ptr, sizeof(Dwarf_Half),
Packit cdaae3
        err,line_ptr_end);
Packit cdaae3
    line_context->lc_version_number = version;
Packit cdaae3
    line_ptr += sizeof(Dwarf_Half);
Packit cdaae3
    if (version != DW_LINE_VERSION2 &&
Packit cdaae3
        version != DW_LINE_VERSION3 &&
Packit cdaae3
        version != DW_LINE_VERSION4 &&
Packit cdaae3
        version != DW_LINE_VERSION5 &&
Packit cdaae3
        version != EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    if (version == DW_LINE_VERSION5) {
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        line_context->lc_address_size = *(unsigned char *) line_ptr;
Packit cdaae3
        line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        line_context->lc_segment_selector_size =
Packit cdaae3
            *(unsigned char *) line_ptr;
Packit cdaae3
        line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
    } else {
Packit cdaae3
        line_context->lc_address_size = cu_context->cc_address_size;
Packit cdaae3
        line_context->lc_segment_selector_size =
Packit cdaae3
            cu_context->cc_segment_selector_size;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    READ_UNALIGNED_CK(dbg, prologue_length, Dwarf_Unsigned,
Packit cdaae3
        line_ptr, local_length_size,
Packit cdaae3
        err,line_ptr_end);
Packit cdaae3
    line_context->lc_prologue_length = prologue_length;
Packit cdaae3
    line_ptr += local_length_size;
Packit cdaae3
    line_context->lc_line_prologue_start = line_ptr;
Packit cdaae3
    if (line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_minimum_instruction_length =
Packit cdaae3
        *(unsigned char *) line_ptr;
Packit cdaae3
    line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
Packit cdaae3
    if (version == DW_LINE_VERSION4 ||
Packit cdaae3
        version == DW_LINE_VERSION5 ||
Packit cdaae3
        version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        line_context->lc_maximum_ops_per_instruction =
Packit cdaae3
            *(unsigned char *) line_ptr;
Packit cdaae3
        line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
    }
Packit cdaae3
    if (line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_default_is_stmt = *(unsigned char *) line_ptr;
Packit cdaae3
    line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
Packit cdaae3
    if (line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_line_base = *(signed char *) line_ptr;
Packit cdaae3
    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
Packit cdaae3
    if(line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_line_range = *(unsigned char *) line_ptr;
Packit cdaae3
    if (!line_context->lc_line_range) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_RANGE_ZERO);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
    if(line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_opcode_base = *(unsigned char *) line_ptr;
Packit cdaae3
    line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
    /*  Set up the array of standard opcode lengths. */
Packit cdaae3
    /*  We think this works ok even for cross-endian processing of
Packit cdaae3
        objects.  It might be wrong, we might need to specially process
Packit cdaae3
        the array of ubyte into host order.  */
Packit cdaae3
    line_context->lc_opcode_length_table = line_ptr;
Packit cdaae3
Packit cdaae3
    /*  lc_opcode_base is one greater than the size of the array. */
Packit cdaae3
    line_ptr += line_context->lc_opcode_base - 1;
Packit cdaae3
    line_context->lc_std_op_count = line_context->lc_opcode_base -1;
Packit cdaae3
    if(line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    {
Packit cdaae3
        /*  Determine (as best we can) whether the
Packit cdaae3
            lc_opcode_length_table holds 9 or 12 standard-conforming
Packit cdaae3
            entries.  gcc4 upped to DWARF3's 12 without updating the
Packit cdaae3
            version number.
Packit cdaae3
            EXPERIMENTAL_LINE_TABLES_VERSION upped to 15.  */
Packit cdaae3
        unsigned check_count = line_context->lc_std_op_count;
Packit cdaae3
        unsigned tab_count = sizeof(dwarf_standard_opcode_operand_count);
Packit cdaae3
Packit cdaae3
        int operand_ck_fail = true;
Packit cdaae3
        if (line_context->lc_std_op_count > tab_count) {
Packit cdaae3
            _dwarf_print_header_issue(dbg,
Packit cdaae3
                "Too many standard operands in linetable header: ",
Packit cdaae3
                data_start,
Packit cdaae3
                line_context->lc_std_op_count,
Packit cdaae3
                0,0,0,
Packit cdaae3
                err_count_out);
Packit cdaae3
            check_count = tab_count;
Packit cdaae3
        }
Packit cdaae3
        {
Packit cdaae3
            unsigned entrynum = 0;
Packit cdaae3
            unsigned tabv     = 0;
Packit cdaae3
            unsigned linetabv     = 0;
Packit cdaae3
Packit cdaae3
            int mismatch = operandmismatch(
Packit cdaae3
                dwarf_standard_opcode_operand_count,
Packit cdaae3
                tab_count,
Packit cdaae3
                line_context->lc_opcode_length_table,
Packit cdaae3
                check_count,&entrynum,&tabv,&linetabv);
Packit cdaae3
            if (mismatch) {
Packit cdaae3
                if (err_count_out) {
Packit cdaae3
                    _dwarf_print_header_issue(dbg,
Packit cdaae3
                        "standard-operands did not match, checked",
Packit cdaae3
                        data_start,
Packit cdaae3
                        check_count,
Packit cdaae3
                        entrynum,tabv,linetabv,err_count_out);
Packit cdaae3
                }
Packit cdaae3
                if (check_count >
Packit cdaae3
                    sizeof(dwarf_arm_standard_opcode_operand_count)) {
Packit cdaae3
                    check_count =
Packit cdaae3
                        sizeof(dwarf_arm_standard_opcode_operand_count);
Packit cdaae3
                }
Packit cdaae3
                mismatch = operandmismatch(
Packit cdaae3
                    dwarf_arm_standard_opcode_operand_count,
Packit cdaae3
                    sizeof(dwarf_arm_standard_opcode_operand_count),
Packit cdaae3
                    line_context->lc_opcode_length_table,
Packit cdaae3
                    check_count,&entrynum,&tabv,&linetabv);
Packit cdaae3
                if (!mismatch && err_count_out) {
Packit cdaae3
                    _dwarf_print_header_issue(dbg,
Packit cdaae3
                        "arm (incorrect) operands in use: ",
Packit cdaae3
                        data_start,
Packit cdaae3
                        check_count,
Packit cdaae3
                        entrynum,tabv,linetabv,err_count_out);
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
            if (!mismatch) {
Packit cdaae3
                if (version == 2) {
Packit cdaae3
                    if (line_context->lc_std_op_count ==
Packit cdaae3
                        STANDARD_OPERAND_COUNT_DWARF3) {
Packit cdaae3
                        _dwarf_print_header_issue(dbg,
Packit cdaae3
                            "standard DWARF3 operands matched,"
Packit cdaae3
                            " but is DWARF2 linetable: count",
Packit cdaae3
                            data_start,
Packit cdaae3
                            check_count,
Packit cdaae3
                            0,0,0, err_count_out);
Packit cdaae3
                    }
Packit cdaae3
                }
Packit cdaae3
                operand_ck_fail = false;
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        if (operand_ck_fail) {
Packit cdaae3
            /* Here we are not sure what the lc_std_op_count is. */
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    /*  At this point we no longer need to check operand counts. */
Packit cdaae3
    if(line_ptr >= line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (version < DW_LINE_VERSION5){
Packit cdaae3
        Dwarf_Unsigned directories_count = 0;
Packit cdaae3
        Dwarf_Unsigned directories_malloc = 5;
Packit cdaae3
        line_context->lc_include_directories = malloc(sizeof(Dwarf_Small *) *
Packit cdaae3
            directories_malloc);
Packit cdaae3
        if (line_context->lc_include_directories == NULL) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        memset(line_context->lc_include_directories, 0,
Packit cdaae3
            sizeof(Dwarf_Small *) * directories_malloc);
Packit cdaae3
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        while ((*(char *) line_ptr) != '\0') {
Packit cdaae3
            if (directories_count >= directories_malloc) {
Packit cdaae3
                Dwarf_Unsigned expand = 2 * directories_malloc;
Packit cdaae3
                Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand;
Packit cdaae3
                Dwarf_Small **newdirs =
Packit cdaae3
                    realloc(line_context->lc_include_directories,
Packit cdaae3
                        bytesalloc);
Packit cdaae3
Packit cdaae3
                if (!newdirs) {
Packit cdaae3
                    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
                /* Doubled size, zero out second half. */
Packit cdaae3
                memset(newdirs + directories_malloc, 0,
Packit cdaae3
                    sizeof(Dwarf_Small *) * directories_malloc);
Packit cdaae3
                directories_malloc = expand;
Packit cdaae3
                line_context->lc_include_directories = newdirs;
Packit cdaae3
            }
Packit cdaae3
            line_context->lc_include_directories[directories_count] =
Packit cdaae3
                line_ptr;
Packit cdaae3
            res = _dwarf_check_string_valid(dbg,
Packit cdaae3
                data_start,line_ptr,line_ptr_end,
Packit cdaae3
                DW_DLE_LINE_STRING_BAD,err);
Packit cdaae3
            if (res != DW_DLV_OK) {
Packit cdaae3
                return res;
Packit cdaae3
            }
Packit cdaae3
            line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
Packit cdaae3
            directories_count++;
Packit cdaae3
            if (line_ptr >= line_ptr_end) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        line_ptr++;
Packit cdaae3
        line_context->lc_include_directories_count = directories_count;
Packit cdaae3
    } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        /* Empty old style dir entry list. */
Packit cdaae3
        line_ptr++;
Packit cdaae3
    } else if (version == 5) {
Packit cdaae3
        /* handled below */
Packit cdaae3
    } else {
Packit cdaae3
        /* No old style directory entries. */
Packit cdaae3
    }
Packit cdaae3
    if(line_ptr > line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    if (version < DW_LINE_VERSION5) {
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        while (*(char *) line_ptr != '\0') {
Packit cdaae3
            Dwarf_Unsigned utmp;
Packit cdaae3
            Dwarf_Unsigned dir_index = 0;
Packit cdaae3
            Dwarf_Unsigned lastmod = 0;
Packit cdaae3
            Dwarf_Unsigned file_length = 0;
Packit cdaae3
            int resl = 0;
Packit cdaae3
            Dwarf_File_Entry currfile  = 0;
Packit cdaae3
Packit cdaae3
            currfile = (Dwarf_File_Entry)
Packit cdaae3
                malloc(sizeof(struct Dwarf_File_Entry_s));
Packit cdaae3
            if (currfile == NULL) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            memset(currfile,0,sizeof(struct Dwarf_File_Entry_s));
Packit cdaae3
            /*  Insert early so in case of error we can find
Packit cdaae3
                and free the record. */
Packit cdaae3
            _dwarf_add_to_files_list(line_context,currfile);
Packit cdaae3
Packit cdaae3
            currfile->fi_file_name = line_ptr;
Packit cdaae3
            resl = _dwarf_check_string_valid(dbg,
Packit cdaae3
                data_start,line_ptr,line_ptr_end,
Packit cdaae3
                DW_DLE_LINE_STRING_BAD,err);
Packit cdaae3
            if (resl != DW_DLV_OK) {
Packit cdaae3
                return resl;
Packit cdaae3
            }
Packit cdaae3
            line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr, utmp,dbg,err,line_ptr_end);
Packit cdaae3
            dir_index = (Dwarf_Word) utmp;
Packit cdaae3
            if (dir_index > line_context->lc_include_directories_count) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            currfile->fi_dir_index = dir_index;
Packit cdaae3
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr,lastmod,
Packit cdaae3
                dbg,err, line_ptr_end);
Packit cdaae3
            currfile->fi_time_last_mod = lastmod;
Packit cdaae3
Packit cdaae3
            /* Skip over file length. */
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr,file_length,
Packit cdaae3
                dbg,err, line_ptr_end);
Packit cdaae3
            currfile->fi_file_length = file_length;
Packit cdaae3
            if (line_ptr >= line_ptr_end) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        /* Skip trailing nul byte */
Packit cdaae3
        ++line_ptr;
Packit cdaae3
    } else if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        if (*line_ptr != 0) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        line_ptr++;
Packit cdaae3
    } else if (version == 5) {
Packit cdaae3
        /* handled below */
Packit cdaae3
    } else {
Packit cdaae3
        /* No old style filenames entries. */
Packit cdaae3
    }
Packit cdaae3
    if(line_ptr > line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        static unsigned char expbytes[5] = {0,0xff,0xff,0x7f, 0x7f };
Packit cdaae3
        Dwarf_Unsigned logicals_table_offset = 0;
Packit cdaae3
        Dwarf_Unsigned actuals_table_offset = 0;
Packit cdaae3
        unsigned i = 0;
Packit cdaae3
Packit cdaae3
        for ( ; i < 5; ++i) {
Packit cdaae3
            if (line_ptr >= line_ptr_end) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            if (*line_ptr != expbytes[i]) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            line_ptr++;
Packit cdaae3
        }
Packit cdaae3
        READ_UNALIGNED_CK(dbg, logicals_table_offset, Dwarf_Unsigned,
Packit cdaae3
            line_ptr, local_length_size,err,line_ptr_end);
Packit cdaae3
        line_context->lc_logicals_table_offset = logicals_table_offset;
Packit cdaae3
        line_ptr += local_length_size;
Packit cdaae3
        READ_UNALIGNED_CK(dbg, actuals_table_offset, Dwarf_Unsigned,
Packit cdaae3
            line_ptr, local_length_size,err,line_ptr_end);
Packit cdaae3
        line_context->lc_actuals_table_offset = actuals_table_offset;
Packit cdaae3
        line_ptr += local_length_size;
Packit cdaae3
        if(line_ptr > line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
            return DW_DLV_ERROR;
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (version == DW_LINE_VERSION5 ||
Packit cdaae3
        version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        /* DWARF 5.  directory names.*/
Packit cdaae3
        Dwarf_Unsigned directory_format_count = 0;
Packit cdaae3
        Dwarf_Unsigned *directory_entry_types = 0;
Packit cdaae3
        Dwarf_Unsigned *directory_entry_forms = 0;
Packit cdaae3
        Dwarf_Unsigned directories_count = 0;
Packit cdaae3
        Dwarf_Unsigned i = 0;
Packit cdaae3
        Dwarf_Unsigned j = 0;
Packit cdaae3
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        directory_format_count = *(unsigned char *) line_ptr;
Packit cdaae3
        line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
        if (directory_format_count > 0) {
Packit cdaae3
            directory_entry_types = malloc(sizeof(Dwarf_Unsigned) *
Packit cdaae3
                directory_format_count);
Packit cdaae3
            if (directory_entry_types == NULL) {
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            directory_entry_forms = malloc(sizeof(Dwarf_Unsigned) *
Packit cdaae3
                directory_format_count);
Packit cdaae3
            if (directory_entry_forms == NULL) {
Packit cdaae3
                free(directory_entry_types);
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            for (i = 0; i < directory_format_count; i++) {
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, directory_entry_types[i],
Packit cdaae3
                    dbg,err,line_ptr_end);
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, directory_entry_forms[i],
Packit cdaae3
                    dbg,err,line_ptr_end);
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        DECODE_LEB128_UWORD_CK(line_ptr, directories_count,
Packit cdaae3
            dbg,err,line_ptr_end);
Packit cdaae3
        line_context->lc_include_directories =
Packit cdaae3
            malloc(sizeof(Dwarf_Small *) * directories_count);
Packit cdaae3
        if (line_context->lc_include_directories == NULL) {
Packit cdaae3
            free(directory_entry_types);
Packit cdaae3
            free(directory_entry_forms);
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        if (directory_format_count ==0 &&
Packit cdaae3
            directories_count > 0) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_DIRECTORY_FORMAT_COUNT_VS_DIRECTORIES_MISMATCH);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        memset(line_context->lc_include_directories, 0,
Packit cdaae3
            sizeof(Dwarf_Small *) * directories_count);
Packit cdaae3
Packit cdaae3
        for(i = 0; i < directories_count; i++) {
Packit cdaae3
            for (j = 0; j < directory_format_count; j++) {
Packit cdaae3
Packit cdaae3
                switch (directory_entry_types[j]) {
Packit cdaae3
                case DW_LNCT_path: {
Packit cdaae3
                    char *inc_dir_ptr = 0;
Packit cdaae3
                    res = _dwarf_decode_line_string_form(dbg,
Packit cdaae3
                        directory_entry_forms[j],
Packit cdaae3
                        local_length_size,
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        &inc_dir_ptr,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(directory_entry_types);
Packit cdaae3
                        free(directory_entry_forms);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    line_context->lc_include_directories[i] =
Packit cdaae3
                        (unsigned char *)inc_dir_ptr;
Packit cdaae3
                    break;
Packit cdaae3
                }
Packit cdaae3
                default:
Packit cdaae3
                    free(directory_entry_types);
Packit cdaae3
                    free(directory_entry_forms);
Packit cdaae3
                    _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
            if (line_ptr > line_ptr_end) {
Packit cdaae3
                free(directory_entry_types);
Packit cdaae3
                free(directory_entry_forms);
Packit cdaae3
                _dwarf_error(dbg, err,
Packit cdaae3
                    DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        free(directory_entry_types);
Packit cdaae3
        free(directory_entry_forms);
Packit cdaae3
        line_context->lc_include_directories_count = directories_count;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (version == DW_LINE_VERSION5 ||
Packit cdaae3
        version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        /* DWARF 5.  file names.*/
Packit cdaae3
        Dwarf_Unsigned filename_format_count = 0;
Packit cdaae3
        Dwarf_Unsigned *filename_entry_types = 0;
Packit cdaae3
        Dwarf_Unsigned *filename_entry_forms = 0;
Packit cdaae3
        Dwarf_Unsigned files_count = 0;
Packit cdaae3
        Dwarf_Unsigned i = 0;
Packit cdaae3
        Dwarf_Unsigned j = 0;
Packit cdaae3
Packit cdaae3
        if (line_ptr >= line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        filename_format_count = *(unsigned char *) line_ptr;
Packit cdaae3
        line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
        filename_entry_types = malloc(sizeof(Dwarf_Unsigned) *
Packit cdaae3
            filename_format_count);
Packit cdaae3
        if (filename_entry_types == NULL) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        filename_entry_forms = malloc(sizeof(Dwarf_Unsigned) *
Packit cdaae3
            filename_format_count);
Packit cdaae3
        if (filename_entry_forms == NULL) {
Packit cdaae3
            free(filename_entry_types);
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        for (i = 0; i < filename_format_count; i++) {
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_types[i],
Packit cdaae3
                dbg,err,line_ptr_end);
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr, filename_entry_forms[i],
Packit cdaae3
                dbg,err,line_ptr_end);
Packit cdaae3
        }
Packit cdaae3
        DECODE_LEB128_UWORD_CK(line_ptr, files_count,
Packit cdaae3
            dbg,err,line_ptr_end);
Packit cdaae3
Packit cdaae3
        for (i = 0; i < files_count; i++) {
Packit cdaae3
            Dwarf_File_Entry curline = 0;
Packit cdaae3
            curline = (Dwarf_File_Entry)
Packit cdaae3
                malloc(sizeof(struct Dwarf_File_Entry_s));
Packit cdaae3
            if (curline == NULL) {
Packit cdaae3
                free(filename_entry_types);
Packit cdaae3
                _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                return (DW_DLV_ERROR);
Packit cdaae3
            }
Packit cdaae3
            memset(curline,0,sizeof(*curline));
Packit cdaae3
            _dwarf_add_to_files_list(line_context,curline);
Packit cdaae3
            for(j = 0; j < filename_format_count; j++) {
Packit cdaae3
                Dwarf_Unsigned dirindex = 0;
Packit cdaae3
                switch (filename_entry_types[j]) {
Packit cdaae3
                case DW_LNCT_path:
Packit cdaae3
                    res = _dwarf_decode_line_string_form(dbg,
Packit cdaae3
                        filename_entry_forms[j],
Packit cdaae3
                        local_length_size,
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        (char **)&curline->fi_file_name,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(filename_entry_types);
Packit cdaae3
                        free(filename_entry_forms);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    break;
Packit cdaae3
                case DW_LNCT_directory_index:
Packit cdaae3
                    res = _dwarf_decode_line_udata_form(dbg,
Packit cdaae3
                        filename_entry_forms[j],
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        &dirindex,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(filename_entry_types);
Packit cdaae3
                        free(filename_entry_forms);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    curline->fi_dir_index = dirindex;
Packit cdaae3
                    break;
Packit cdaae3
                case DW_LNCT_timestamp:
Packit cdaae3
                    res = _dwarf_decode_line_udata_form(dbg,
Packit cdaae3
                        filename_entry_forms[j],
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        &curline->fi_time_last_mod,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(filename_entry_types);
Packit cdaae3
                        free(filename_entry_forms);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    break;
Packit cdaae3
                case DW_LNCT_size:
Packit cdaae3
                    res = _dwarf_decode_line_udata_form(dbg,
Packit cdaae3
                        filename_entry_forms[j],
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        &curline->fi_file_length,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(filename_entry_types);
Packit cdaae3
                        free(filename_entry_forms);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    break;
Packit cdaae3
                case DW_LNCT_MD5: /* Not yet implemented */
Packit cdaae3
                default:
Packit cdaae3
                    free(filename_entry_types);
Packit cdaae3
                    free(filename_entry_forms);
Packit cdaae3
                    _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
                if (line_ptr > line_ptr_end) {
Packit cdaae3
                    free(filename_entry_types);
Packit cdaae3
                    free(filename_entry_forms);
Packit cdaae3
                    _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        free(filename_entry_types);
Packit cdaae3
        free(filename_entry_forms);
Packit cdaae3
    }
Packit cdaae3
    /* For two-level line tables, read the subprograms table. */
Packit cdaae3
    if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        Dwarf_Unsigned subprog_format_count = 0;
Packit cdaae3
        Dwarf_Unsigned *subprog_entry_types = 0;
Packit cdaae3
        Dwarf_Unsigned *subprog_entry_forms = 0;
Packit cdaae3
        Dwarf_Unsigned subprogs_count = 0;
Packit cdaae3
        Dwarf_Unsigned i = 0;
Packit cdaae3
        Dwarf_Unsigned j = 0;
Packit cdaae3
Packit cdaae3
        if (line_ptr > line_ptr_end) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        subprog_format_count = *(unsigned char *) line_ptr;
Packit cdaae3
        line_ptr = line_ptr + sizeof(Dwarf_Small);
Packit cdaae3
        subprog_entry_types = malloc(sizeof(Dwarf_Unsigned) *
Packit cdaae3
            subprog_format_count);
Packit cdaae3
        if (subprog_entry_types == NULL) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        subprog_entry_forms = malloc(sizeof(Dwarf_Unsigned) *
Packit cdaae3
            subprog_format_count);
Packit cdaae3
        if (subprog_entry_forms == NULL) {
Packit cdaae3
            free(subprog_entry_types);
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
Packit cdaae3
        for (i = 0; i < subprog_format_count; i++) {
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_types[i],
Packit cdaae3
                dbg,err,line_ptr_end);
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr, subprog_entry_forms[i],
Packit cdaae3
                dbg,err,line_ptr_end);
Packit cdaae3
        }
Packit cdaae3
        DECODE_LEB128_UWORD_CK(line_ptr, subprogs_count,
Packit cdaae3
            dbg,err,line_ptr_end);
Packit cdaae3
        line_context->lc_subprogs =
Packit cdaae3
            malloc(sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count);
Packit cdaae3
        if (line_context->lc_subprogs == NULL) {
Packit cdaae3
            free(subprog_entry_types);
Packit cdaae3
            free(subprog_entry_forms);
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        }
Packit cdaae3
        memset(line_context->lc_subprogs, 0,
Packit cdaae3
            sizeof(struct Dwarf_Subprog_Entry_s) * subprogs_count);
Packit cdaae3
        for (i = 0; i < subprogs_count; i++) {
Packit cdaae3
            struct Dwarf_Subprog_Entry_s *curline =
Packit cdaae3
                line_context->lc_subprogs + i;
Packit cdaae3
            for (j = 0; j < subprog_format_count; j++) {
Packit cdaae3
                switch (subprog_entry_types[j]) {
Packit cdaae3
                case DW_LNCT_GNU_subprogram_name:
Packit cdaae3
                    res = _dwarf_decode_line_string_form(dbg,
Packit cdaae3
                        subprog_entry_forms[j],
Packit cdaae3
                        local_length_size,
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        (char **)&curline->ds_subprog_name,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(subprog_entry_types);
Packit cdaae3
                        free(subprog_entry_forms);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    break;
Packit cdaae3
                case DW_LNCT_GNU_decl_file:
Packit cdaae3
                    res = _dwarf_decode_line_udata_form(dbg,
Packit cdaae3
                        subprog_entry_forms[j],
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        &curline->ds_decl_file,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(subprog_entry_forms);
Packit cdaae3
                        free(subprog_entry_types);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    break;
Packit cdaae3
                case DW_LNCT_GNU_decl_line:
Packit cdaae3
                    res = _dwarf_decode_line_udata_form(dbg,
Packit cdaae3
                        subprog_entry_forms[j],
Packit cdaae3
                        &line_ptr,
Packit cdaae3
                        &curline->ds_decl_line,
Packit cdaae3
                        line_ptr_end,
Packit cdaae3
                        err);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        free(subprog_entry_forms);
Packit cdaae3
                        free(subprog_entry_types);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    break;
Packit cdaae3
                default:
Packit cdaae3
                    free(subprog_entry_forms);
Packit cdaae3
                    free(subprog_entry_types);
Packit cdaae3
                    _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
                if (line_ptr >= line_ptr_end) {
Packit cdaae3
                    free(subprog_entry_types);
Packit cdaae3
                    free(subprog_entry_forms);
Packit cdaae3
                    _dwarf_error(dbg, err, DW_DLE_LINE_NUMBER_HEADER_ERROR);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
Packit cdaae3
        free(subprog_entry_types);
Packit cdaae3
        free(subprog_entry_forms);
Packit cdaae3
        line_context->lc_subprogs_count = subprogs_count;
Packit cdaae3
    }
Packit cdaae3
    if (version == EXPERIMENTAL_LINE_TABLES_VERSION) {
Packit cdaae3
        lp_begin = line_context->lc_line_prologue_start +
Packit cdaae3
            line_context->lc_logicals_table_offset;
Packit cdaae3
    } else {
Packit cdaae3
        lp_begin = line_context->lc_line_prologue_start +
Packit cdaae3
            line_context->lc_prologue_length;
Packit cdaae3
    }
Packit cdaae3
    if(line_ptr > line_ptr_end) {
Packit cdaae3
        _dwarf_error(dbg, err, DW_DLE_LINE_OFFSET_BAD);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    if (line_ptr != lp_begin) {
Packit cdaae3
        if (line_ptr > lp_begin) {
Packit cdaae3
            _dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD);
Packit cdaae3
            return (DW_DLV_ERROR);
Packit cdaae3
        } else {
Packit cdaae3
            /*  Bug in compiler. These
Packit cdaae3
                bytes are really part of the instruction
Packit cdaae3
                stream.  The line_context->lc_prologue_length is
Packit cdaae3
                wrong (12 too high).  */
Packit cdaae3
            if (bogus_bytes_ptr) {
Packit cdaae3
                *bogus_bytes_ptr = line_ptr;
Packit cdaae3
            }
Packit cdaae3
            if (bogus_bytes) {
Packit cdaae3
                /*  How far off things are. We expect the
Packit cdaae3
                    value 12 ! */
Packit cdaae3
                *bogus_bytes = (lp_begin - line_ptr);
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        /*  Ignore the lp_begin calc. Assume line_ptr right.
Packit cdaae3
            Making up for compiler bug. */
Packit cdaae3
        lp_begin = line_ptr;
Packit cdaae3
    }
Packit cdaae3
    line_context->lc_line_ptr_start = lp_begin;
Packit cdaae3
    if (line_context->lc_actuals_table_offset) {
Packit cdaae3
        /* This means two tables. */
Packit cdaae3
        line_context->lc_table_count = 2;
Packit cdaae3
    } else {
Packit cdaae3
        if (line_context->lc_line_ptr_end > lp_begin) {
Packit cdaae3
            line_context->lc_table_count = 1;
Packit cdaae3
        } else {
Packit cdaae3
            line_context->lc_table_count = 0;
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    *updated_data_start_out = lp_begin;
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
/*  Read one line table program. For two-level line tables, this
Packit cdaae3
    function is called once for each table. */
Packit cdaae3
static int
Packit cdaae3
read_line_table_program(Dwarf_Debug dbg,
Packit cdaae3
    Dwarf_Small *line_ptr,
Packit cdaae3
    Dwarf_Small *line_ptr_end,
Packit cdaae3
    UNUSEDARG Dwarf_Small *orig_line_ptr,
Packit cdaae3
    UNUSEDARG Dwarf_Small *section_start,
Packit cdaae3
    Dwarf_Line_Context line_context,
Packit cdaae3
    Dwarf_Half address_size,
Packit cdaae3
    Dwarf_Bool doaddrs, /* Only true if SGI IRIX rqs calling. */
Packit cdaae3
    Dwarf_Bool dolines,
Packit cdaae3
    Dwarf_Bool is_single_table,
Packit cdaae3
    Dwarf_Bool is_actuals_table,
Packit cdaae3
    Dwarf_Error *error,
Packit cdaae3
    UNUSEDARG int *err_count_out)
Packit cdaae3
{
Packit cdaae3
    Dwarf_Word i = 0;
Packit cdaae3
    Dwarf_File_Entry cur_file_entry = 0;
Packit cdaae3
    Dwarf_Line *logicals = line_context->lc_linebuf_logicals;
Packit cdaae3
    Dwarf_Unsigned logicals_count = line_context->lc_linecount_logicals;
Packit cdaae3
Packit cdaae3
    struct Dwarf_Line_Registers_s regs;
Packit cdaae3
Packit cdaae3
    /*  This is a pointer to the current line being added to the line
Packit cdaae3
        matrix. */
Packit cdaae3
    Dwarf_Line curr_line = 0;
Packit cdaae3
Packit cdaae3
    /*  These variables are used to decode leb128 numbers. Leb128_num
Packit cdaae3
        holds the decoded number, and leb128_length is its length in
Packit cdaae3
        bytes. */
Packit cdaae3
    Dwarf_Word leb128_num = 0;
Packit cdaae3
    Dwarf_Sword advance_line = 0;
Packit cdaae3
Packit cdaae3
    /*  This is the operand of the latest fixed_advance_pc extended
Packit cdaae3
        opcode. */
Packit cdaae3
    Dwarf_Half fixed_advance_pc = 0;
Packit cdaae3
Packit cdaae3
    /*  Counts the number of lines in the line matrix. */
Packit cdaae3
    Dwarf_Word line_count = 0;
Packit cdaae3
Packit cdaae3
    /*  This is the length of an extended opcode instr.  */
Packit cdaae3
    Dwarf_Word instr_length = 0;
Packit cdaae3
Packit cdaae3
Packit cdaae3
    /*  Used to chain together pointers to line table entries that are
Packit cdaae3
        later used to create a block of Dwarf_Line entries. */
Packit cdaae3
    Dwarf_Chain chain_line = NULL;
Packit cdaae3
    Dwarf_Chain head_chain = NULL;
Packit cdaae3
    Dwarf_Chain curr_chain = NULL;
Packit cdaae3
Packit cdaae3
    /*  This points to a block of Dwarf_Lines, a pointer to which is
Packit cdaae3
        returned in linebuf. */
Packit cdaae3
    Dwarf_Line *block_line = 0;
Packit cdaae3
Packit cdaae3
    /*  Mark a line record as being DW_LNS_set_address */
Packit cdaae3
    Dwarf_Bool is_addr_set = false;
Packit cdaae3
Packit cdaae3
    /*  Initialize the one state machine variable that depends on the
Packit cdaae3
        prefix.  */
Packit cdaae3
    _dwarf_set_line_table_regs_default_values(&regs,
Packit cdaae3
        line_context->lc_default_is_stmt);
Packit cdaae3
Packit cdaae3
    /* Start of statement program.  */
Packit cdaae3
    while (line_ptr < line_ptr_end) {
Packit cdaae3
        int type = 0;
Packit cdaae3
        Dwarf_Small opcode = 0;
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
        dwarf_printf(dbg,
Packit cdaae3
            " [0x%06" DW_PR_DSx "] ",
Packit cdaae3
            (Dwarf_Signed) (line_ptr - section_start));
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
        opcode = *(Dwarf_Small *) line_ptr;
Packit cdaae3
        line_ptr++;
Packit cdaae3
        /* 'type' is the output */
Packit cdaae3
        WHAT_IS_OPCODE(type, opcode, line_context->lc_opcode_base,
Packit cdaae3
            line_context->lc_opcode_length_table, line_ptr,
Packit cdaae3
            line_context->lc_std_op_count);
Packit cdaae3
Packit cdaae3
        if (type == LOP_DISCARD) {
Packit cdaae3
            int oc = 0;
Packit cdaae3
            int opcnt = line_context->lc_opcode_length_table[opcode];
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
            dwarf_printf(dbg,
Packit cdaae3
                "*** DWARF CHECK: DISCARD standard opcode %d "
Packit cdaae3
                "with %d operands: "
Packit cdaae3
                "not understood.", opcode, opcnt);
Packit cdaae3
            *err_count_out += 1;
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
            for (oc = 0; oc < opcnt; oc++) {
Packit cdaae3
                /*  Read and discard operands we don't
Packit cdaae3
                    understand.
Packit cdaae3
                    arbitrary choice of unsigned read.
Packit cdaae3
                    signed read would work as well.    */
Packit cdaae3
                UNUSEDARG Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    " %" DW_PR_DUu
Packit cdaae3
                    " (0x%" DW_PR_XZEROS DW_PR_DUx ")",
Packit cdaae3
                    (Dwarf_Unsigned) utmp2,
Packit cdaae3
                    (Dwarf_Unsigned) utmp2);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
            }
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
            dwarf_printf(dbg,"***\n");
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
        } else if (type == LOP_SPECIAL) {
Packit cdaae3
            /*  This op code is a special op in the object, no matter
Packit cdaae3
                that it might fall into the standard op range in this
Packit cdaae3
                compile. That is, these are special opcodes between
Packit cdaae3
                opcode_base and MAX_LINE_OP_CODE.  (including
Packit cdaae3
                opcode_base and MAX_LINE_OP_CODE) */
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
            char special[50];
Packit cdaae3
            unsigned origop = opcode;
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
            Dwarf_Unsigned operation_advance = 0;
Packit cdaae3
Packit cdaae3
            opcode = opcode - line_context->lc_opcode_base;
Packit cdaae3
            operation_advance = (opcode / line_context->lc_line_range);
Packit cdaae3
Packit cdaae3
            if (line_context->lc_maximum_ops_per_instruction < 2) {
Packit cdaae3
                regs.lr_address = regs.lr_address + (operation_advance *
Packit cdaae3
                    line_context->lc_minimum_instruction_length);
Packit cdaae3
            } else {
Packit cdaae3
                regs.lr_address = regs.lr_address +
Packit cdaae3
                    (line_context->lc_minimum_instruction_length *
Packit cdaae3
                    ((regs.lr_op_index + operation_advance)/
Packit cdaae3
                    line_context->lc_maximum_ops_per_instruction));
Packit cdaae3
                regs.lr_op_index = (regs.lr_op_index +operation_advance)%
Packit cdaae3
                    line_context->lc_maximum_ops_per_instruction;
Packit cdaae3
            }
Packit cdaae3
Packit cdaae3
            regs.lr_line = regs.lr_line + line_context->lc_line_base +
Packit cdaae3
                opcode % line_context->lc_line_range;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
            sprintf(special, "Specialop %3u", origop);
Packit cdaae3
            print_line_detail(dbg,special,
Packit cdaae3
                opcode,line_count+1, &regs,is_single_table, is_actuals_table);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
Packit cdaae3
            if (dolines) {
Packit cdaae3
                curr_line =
Packit cdaae3
                    (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
Packit cdaae3
                if (curr_line == NULL) {
Packit cdaae3
                    _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
Packit cdaae3
                /* Mark a line record as being DW_LNS_set_address */
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_is_addr_set = is_addr_set;
Packit cdaae3
                is_addr_set = false;
Packit cdaae3
Packit cdaae3
                curr_line->li_address = regs.lr_address;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_file =
Packit cdaae3
                    (Dwarf_Sword) regs.lr_file;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_line =
Packit cdaae3
                    (Dwarf_Sword) regs.lr_line;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_column =
Packit cdaae3
                    (Dwarf_Half) regs.lr_column;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_is_stmt =
Packit cdaae3
                    regs.lr_is_stmt;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_basic_block =
Packit cdaae3
                    regs.lr_basic_block;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_end_sequence =
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                    li_epilogue_begin = regs.lr_epilogue_begin;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_prologue_end =
Packit cdaae3
                    regs.lr_prologue_end;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_discriminator =
Packit cdaae3
                    regs.lr_discriminator;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_call_context =
Packit cdaae3
                    regs.lr_call_context;
Packit cdaae3
                curr_line->li_addr_line.li_l_data.li_subprogram =
Packit cdaae3
                    regs.lr_subprogram;
Packit cdaae3
                curr_line->li_context = line_context;
Packit cdaae3
                curr_line->li_is_actuals_table = is_actuals_table;
Packit cdaae3
                line_count++;
Packit cdaae3
Packit cdaae3
                chain_line = (Dwarf_Chain)
Packit cdaae3
                    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
Packit cdaae3
                if (chain_line == NULL) {
Packit cdaae3
                    _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
                chain_line->ch_item = curr_line;
Packit cdaae3
                _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain);
Packit cdaae3
            }
Packit cdaae3
Packit cdaae3
            regs.lr_basic_block = false;
Packit cdaae3
            regs.lr_prologue_end = false;
Packit cdaae3
            regs.lr_epilogue_begin = false;
Packit cdaae3
            regs.lr_discriminator = 0;
Packit cdaae3
        } else if (type == LOP_STANDARD) {
Packit cdaae3
            switch (opcode) {
Packit cdaae3
Packit cdaae3
            case DW_LNS_copy:{
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                print_line_detail(dbg,"DW_LNS_copy",
Packit cdaae3
                    opcode,line_count+1, &regs,is_single_table, is_actuals_table);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                if (dolines) {
Packit cdaae3
                    curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg,
Packit cdaae3
                        DW_DLA_LINE, 1);
Packit cdaae3
                    if (curr_line == NULL) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
Packit cdaae3
                    /* Mark a line record as being DW_LNS_set_address */
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_is_addr_set =
Packit cdaae3
                        is_addr_set;
Packit cdaae3
                    is_addr_set = false;
Packit cdaae3
Packit cdaae3
                    curr_line->li_address = regs.lr_address;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_file =
Packit cdaae3
                        (Dwarf_Sword) regs.lr_file;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_line =
Packit cdaae3
                        (Dwarf_Sword) regs.lr_line;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_column =
Packit cdaae3
                        (Dwarf_Half) regs.lr_column;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_is_stmt =
Packit cdaae3
                        regs.lr_is_stmt;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_basic_block = regs.lr_basic_block;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_end_sequence = regs.lr_end_sequence;
Packit cdaae3
                    curr_line->li_context = line_context;
Packit cdaae3
                    curr_line->li_is_actuals_table = is_actuals_table;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_epilogue_begin = regs.lr_epilogue_begin;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_prologue_end = regs.lr_prologue_end;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_discriminator =
Packit cdaae3
                        regs.lr_discriminator;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_call_context =
Packit cdaae3
                        regs.lr_call_context;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_subprogram =
Packit cdaae3
                        regs.lr_subprogram;
Packit cdaae3
                    line_count++;
Packit cdaae3
Packit cdaae3
                    chain_line = (Dwarf_Chain)
Packit cdaae3
                        _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
Packit cdaae3
                    if (chain_line == NULL) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
                    chain_line->ch_item = curr_line;
Packit cdaae3
                    _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain);
Packit cdaae3
                }
Packit cdaae3
Packit cdaae3
                regs.lr_basic_block = false;
Packit cdaae3
                regs.lr_prologue_end = false;
Packit cdaae3
                regs.lr_epilogue_begin = false;
Packit cdaae3
                regs.lr_discriminator = 0;
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_advance_pc:{
Packit cdaae3
                Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_advance_pc val %"
Packit cdaae3
                    DW_PR_DSd " 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DUx "\n",
Packit cdaae3
                    (Dwarf_Signed) (Dwarf_Word) utmp2,
Packit cdaae3
                    (Dwarf_Unsigned) (Dwarf_Word) utmp2);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                leb128_num = (Dwarf_Word) utmp2;
Packit cdaae3
                regs.lr_address = regs.lr_address +
Packit cdaae3
                    line_context->lc_minimum_instruction_length *
Packit cdaae3
                    leb128_num;
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_advance_line:{
Packit cdaae3
                Dwarf_Signed stmp = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_SWORD_CK(line_ptr, stmp,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
                advance_line = (Dwarf_Sword) stmp;
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_advance_line val %" DW_PR_DSd " 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DSx "\n",
Packit cdaae3
                    (Dwarf_Signed) advance_line,
Packit cdaae3
                    (Dwarf_Signed) advance_line);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                regs.lr_line = regs.lr_line + advance_line;
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_set_file:{
Packit cdaae3
                Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
                regs.lr_file = (Dwarf_Word) utmp2;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_set_file  %ld\n", (long) regs.lr_file);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_set_column:{
Packit cdaae3
                Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
                regs.lr_column = (Dwarf_Word) utmp2;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_set_column val %" DW_PR_DSd " 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DSx "\n",
Packit cdaae3
                    (Dwarf_Signed) regs.lr_column,
Packit cdaae3
                    (Dwarf_Signed) regs.lr_column);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_negate_stmt:{
Packit cdaae3
                regs.lr_is_stmt = !regs.lr_is_stmt;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_negate_stmt\n");
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_set_basic_block:{
Packit cdaae3
                regs.lr_basic_block = true;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_set_basic_block\n");
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
            case DW_LNS_const_add_pc:{
Packit cdaae3
                opcode = MAX_LINE_OP_CODE - line_context->lc_opcode_base;
Packit cdaae3
                if (line_context->lc_maximum_ops_per_instruction < 2) {
Packit cdaae3
                    Dwarf_Unsigned operation_advance =
Packit cdaae3
                        (opcode / line_context->lc_line_range);
Packit cdaae3
                    regs.lr_address = regs.lr_address +
Packit cdaae3
                        line_context->lc_minimum_instruction_length *
Packit cdaae3
                            operation_advance;
Packit cdaae3
                } else {
Packit cdaae3
                    Dwarf_Unsigned operation_advance =
Packit cdaae3
                        (opcode / line_context->lc_line_range);
Packit cdaae3
                    regs.lr_address = regs.lr_address +
Packit cdaae3
                        line_context->lc_minimum_instruction_length *
Packit cdaae3
                        ((regs.lr_op_index + operation_advance)/
Packit cdaae3
                        line_context->lc_maximum_ops_per_instruction);
Packit cdaae3
                    regs.lr_op_index = (regs.lr_op_index +operation_advance)%
Packit cdaae3
                        line_context->lc_maximum_ops_per_instruction;
Packit cdaae3
                }
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_const_add_pc new address 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DSx "\n",
Packit cdaae3
                    (Dwarf_Signed) regs.lr_address);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNS_fixed_advance_pc:{
Packit cdaae3
                READ_UNALIGNED_CK(dbg, fixed_advance_pc, Dwarf_Half,
Packit cdaae3
                    line_ptr, sizeof(Dwarf_Half),error,line_ptr_end);
Packit cdaae3
                line_ptr += sizeof(Dwarf_Half);
Packit cdaae3
                if (line_ptr > line_ptr_end) {
Packit cdaae3
                    _dwarf_error(dbg, error,
Packit cdaae3
                        DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                    return DW_DLV_ERROR;
Packit cdaae3
                }
Packit cdaae3
                regs.lr_address = regs.lr_address + fixed_advance_pc;
Packit cdaae3
                regs.lr_op_index = 0;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_fixed_advance_pc val %" DW_PR_DSd
Packit cdaae3
                    " 0x%" DW_PR_XZEROS DW_PR_DSx
Packit cdaae3
                    " new address 0x%" DW_PR_XZEROS DW_PR_DSx "\n",
Packit cdaae3
                    (Dwarf_Signed) fixed_advance_pc,
Packit cdaae3
                    (Dwarf_Signed) fixed_advance_pc,
Packit cdaae3
                    (Dwarf_Signed) regs.lr_address);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
                /* New in DWARF3 */
Packit cdaae3
            case DW_LNS_set_prologue_end:{
Packit cdaae3
                regs.lr_prologue_end = true;
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
                /* New in DWARF3 */
Packit cdaae3
            case DW_LNS_set_epilogue_begin:{
Packit cdaae3
                regs.lr_epilogue_begin = true;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_set_prologue_end set true.\n");
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
                /* New in DWARF3 */
Packit cdaae3
            case DW_LNS_set_isa:{
Packit cdaae3
                Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
                regs.lr_isa = utmp2;
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNS_set_isa new value 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DUx ".\n",
Packit cdaae3
                    (Dwarf_Unsigned) utmp2);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                if (regs.lr_isa != utmp2) {
Packit cdaae3
                    /*  The value of the isa did not fit in our
Packit cdaae3
                        local so we record it wrong. declare an
Packit cdaae3
                        error. */
Packit cdaae3
                    _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                    _dwarf_error(dbg, error,
Packit cdaae3
                        DW_DLE_LINE_NUM_OPERANDS_BAD);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
                /*  Experimental two-level line tables */
Packit cdaae3
                /*  DW_LNS_set_address_from_logical and
Packit cdaae3
                    DW_LNS_set_subprogram
Packit cdaae3
                    share the same opcode. Disambiguate by checking
Packit cdaae3
                    is_actuals_table. */
Packit cdaae3
            case DW_LNS_set_subprogram:
Packit cdaae3
                if (is_actuals_table) {
Packit cdaae3
                    /* DW_LNS_set_address_from_logical */
Packit cdaae3
                    Dwarf_Signed stmp = 0;
Packit cdaae3
Packit cdaae3
                    DECODE_LEB128_SWORD_CK(line_ptr, stmp,
Packit cdaae3
                        dbg,error,line_ptr_end);
Packit cdaae3
                    advance_line = (Dwarf_Sword) stmp;
Packit cdaae3
                    regs.lr_line = regs.lr_line + advance_line;
Packit cdaae3
                    if (regs.lr_line >= 1 &&
Packit cdaae3
                        regs.lr_line - 1 < logicals_count) {
Packit cdaae3
                        regs.lr_address =
Packit cdaae3
                            logicals[regs.lr_line - 1]->li_address;
Packit cdaae3
                        regs.lr_op_index = 0;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                        dwarf_printf(dbg,"DW_LNS_set_address_from_logical "
Packit cdaae3
                            "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx,
Packit cdaae3
                            stmp,stmp);
Packit cdaae3
                        dwarf_printf(dbg,"  newaddr="
Packit cdaae3
                            " 0x%" DW_PR_XZEROS DW_PR_DUx ".\n",
Packit cdaae3
                            regs.lr_address);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                    } else {
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                        dwarf_printf(dbg,"DW_LNS_set_address_from_logical line is "
Packit cdaae3
                            "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx ".\n",
Packit cdaae3
                            (Dwarf_Signed)regs.lr_line,
Packit cdaae3
                            (Dwarf_Signed)regs.lr_line);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                    }
Packit cdaae3
                } else {
Packit cdaae3
                    /* DW_LNS_set_subprogram, building logicals table.  */
Packit cdaae3
                    Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                    regs.lr_call_context = 0;
Packit cdaae3
                    DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                        dbg,error,line_ptr_end);
Packit cdaae3
                    regs.lr_subprogram = (Dwarf_Word) utmp2;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                    dwarf_printf(dbg,"DW_LNS_set_subprogram "
Packit cdaae3
                        "%" DW_PR_DSd " 0x%" DW_PR_XZEROS DW_PR_DSx "\n",
Packit cdaae3
                        (Dwarf_Signed)utmp2,(Dwarf_Signed)utmp2);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
                /* Experimental two-level line tables */
Packit cdaae3
            case DW_LNS_inlined_call: {
Packit cdaae3
                Dwarf_Signed stmp = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_SWORD_CK(line_ptr, stmp,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
                regs.lr_call_context = line_count + stmp;
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, regs.lr_subprogram,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,"DW_LNS_inlined_call "
Packit cdaae3
                    "%" DW_PR_DSd " (0x%" DW_PR_XZEROS DW_PR_DSx "),"
Packit cdaae3
                    "%" DW_PR_DSd " (0x%" DW_PR_XZEROS DW_PR_DSx ")",
Packit cdaae3
                    stmp,stmp,
Packit cdaae3
                    (Dwarf_Signed)regs.lr_subprogram,
Packit cdaae3
                    (Dwarf_Signed)regs.lr_subprogram);
Packit cdaae3
                dwarf_printf(dbg,"  callcontext="
Packit cdaae3
                    "%" DW_PR_DSd " (0x%" DW_PR_XZEROS DW_PR_DSx ")\n",
Packit cdaae3
                    (Dwarf_Signed)regs.lr_call_context,
Packit cdaae3
                    (Dwarf_Signed)regs.lr_call_context);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
                /* Experimental two-level line tables */
Packit cdaae3
            case DW_LNS_pop_context: {
Packit cdaae3
                Dwarf_Unsigned logical_num = regs.lr_call_context;
Packit cdaae3
                Dwarf_Chain logical_chain = head_chain;
Packit cdaae3
                Dwarf_Line logical_line = 0;
Packit cdaae3
Packit cdaae3
                if (logical_num > 0 && logical_num <= line_count) {
Packit cdaae3
                    for (i = 1; i < logical_num; i++) {
Packit cdaae3
                        logical_chain = logical_chain->ch_next;
Packit cdaae3
                    }
Packit cdaae3
                    logical_line = (Dwarf_Line) logical_chain->ch_item;
Packit cdaae3
                    regs.lr_file =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_file;
Packit cdaae3
                    regs.lr_line =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_line;
Packit cdaae3
                    regs.lr_column =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_column;
Packit cdaae3
                    regs.lr_discriminator =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_discriminator;
Packit cdaae3
                    regs.lr_is_stmt =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_is_stmt;
Packit cdaae3
                    regs.lr_call_context =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_call_context;
Packit cdaae3
                    regs.lr_subprogram =
Packit cdaae3
                        logical_line->li_addr_line.li_l_data.li_subprogram;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                    dwarf_printf(dbg,"DW_LNS_pop_context set from logical "
Packit cdaae3
                        "%" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n",
Packit cdaae3
                        logical_num,logical_num);
Packit cdaae3
                } else {
Packit cdaae3
                    dwarf_printf(dbg,"DW_LNS_pop_context does nothing, logical"
Packit cdaae3
                        "%" DW_PR_DUu " (0x%" DW_PR_XZEROS DW_PR_DUx ")\n",
Packit cdaae3
                        logical_num,logical_num);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            } /* End switch (opcode) */
Packit cdaae3
Packit cdaae3
        } else if (type == LOP_EXTENDED) {
Packit cdaae3
            Dwarf_Unsigned utmp3 = 0;
Packit cdaae3
            Dwarf_Small ext_opcode = 0;
Packit cdaae3
Packit cdaae3
            DECODE_LEB128_UWORD_CK(line_ptr, utmp3,
Packit cdaae3
                dbg,error,line_ptr_end);
Packit cdaae3
            instr_length = (Dwarf_Word) utmp3;
Packit cdaae3
            /*  Dwarf_Small is a ubyte and the extended opcode is a
Packit cdaae3
                ubyte, though not stated as clearly in the 2.0.0 spec as
Packit cdaae3
                one might hope. */
Packit cdaae3
            if (line_ptr >= line_ptr_end) {
Packit cdaae3
                _dwarf_error(dbg, error,
Packit cdaae3
                    DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                return DW_DLV_ERROR;
Packit cdaae3
            }
Packit cdaae3
            ext_opcode = *(Dwarf_Small *) line_ptr;
Packit cdaae3
            line_ptr++;
Packit cdaae3
            if (line_ptr > line_ptr_end) {
Packit cdaae3
                _dwarf_error(dbg, error,
Packit cdaae3
                    DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                return DW_DLV_ERROR;
Packit cdaae3
            }
Packit cdaae3
            switch (ext_opcode) {
Packit cdaae3
Packit cdaae3
            case DW_LNE_end_sequence:{
Packit cdaae3
                regs.lr_end_sequence = true;
Packit cdaae3
                if (dolines) {
Packit cdaae3
                    curr_line = (Dwarf_Line)
Packit cdaae3
                        _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
Packit cdaae3
                    if (curr_line == NULL) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                    print_line_detail(dbg,"DW_LNE_end_sequence extended",
Packit cdaae3
                        ext_opcode, line_count+1,&regs,
Packit cdaae3
                        is_single_table, is_actuals_table);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                    curr_line->li_address = regs.lr_address;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_file =
Packit cdaae3
                        (Dwarf_Sword) regs.lr_file;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_line =
Packit cdaae3
                        (Dwarf_Sword) regs.lr_line;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_column =
Packit cdaae3
                        (Dwarf_Half) regs.lr_column;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_is_stmt =
Packit cdaae3
                        regs.lr_is_stmt;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_basic_block = regs.lr_basic_block;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_end_sequence = regs.lr_end_sequence;
Packit cdaae3
                    curr_line->li_context = line_context;
Packit cdaae3
                    curr_line->li_is_actuals_table = is_actuals_table;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_epilogue_begin = regs.lr_epilogue_begin;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.
Packit cdaae3
                        li_prologue_end = regs.lr_prologue_end;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_isa = regs.lr_isa;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_discriminator =
Packit cdaae3
                        regs.lr_discriminator;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_call_context =
Packit cdaae3
                        regs.lr_call_context;
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_subprogram =
Packit cdaae3
                        regs.lr_subprogram;
Packit cdaae3
                    line_count++;
Packit cdaae3
                    chain_line = (Dwarf_Chain)
Packit cdaae3
                        _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
Packit cdaae3
                    if (chain_line == NULL) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
                    chain_line->ch_item = curr_line;
Packit cdaae3
                    _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain);
Packit cdaae3
                }
Packit cdaae3
                _dwarf_set_line_table_regs_default_values(&regs,
Packit cdaae3
                    line_context->lc_default_is_stmt);
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
            case DW_LNE_set_address:{
Packit cdaae3
                READ_UNALIGNED_CK(dbg, regs.lr_address, Dwarf_Addr,
Packit cdaae3
                    line_ptr, address_size,error,line_ptr_end);
Packit cdaae3
                /* Mark a line record as being DW_LNS_set_address */
Packit cdaae3
                is_addr_set = true;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNE_set_address address 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DUx "\n",
Packit cdaae3
                    (Dwarf_Unsigned) regs.lr_address);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                if (doaddrs) {
Packit cdaae3
                    /* SGI IRIX rqs processing only. */
Packit cdaae3
                    curr_line = (Dwarf_Line) _dwarf_get_alloc(dbg,
Packit cdaae3
                        DW_DLA_LINE, 1);
Packit cdaae3
                    if (curr_line == NULL) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
Packit cdaae3
                    /* Mark a line record as being DW_LNS_set_address */
Packit cdaae3
                    curr_line->li_addr_line.li_l_data.li_is_addr_set =
Packit cdaae3
                        is_addr_set;
Packit cdaae3
                    is_addr_set = false;
Packit cdaae3
                    curr_line->li_address = regs.lr_address;
Packit cdaae3
#ifdef __sgi /* SGI IRIX ONLY */
Packit cdaae3
                    curr_line->li_addr_line.li_offset =
Packit cdaae3
                        line_ptr - dbg->de_debug_line.dss_data;
Packit cdaae3
#endif /* __sgi */
Packit cdaae3
                    line_count++;
Packit cdaae3
                    chain_line = (Dwarf_Chain)
Packit cdaae3
                        _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
Packit cdaae3
                    if (chain_line == NULL) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
                    chain_line->ch_item = curr_line;
Packit cdaae3
Packit cdaae3
                    _dwarf_update_chain_list(chain_line,&head_chain,&curr_chain);
Packit cdaae3
                }
Packit cdaae3
                regs.lr_op_index = 0;
Packit cdaae3
                line_ptr += address_size;
Packit cdaae3
                if (line_ptr > line_ptr_end) {
Packit cdaae3
                    _dwarf_error(dbg, error,
Packit cdaae3
                        DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                    return DW_DLV_ERROR;
Packit cdaae3
                }
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
Packit cdaae3
            case DW_LNE_define_file:
Packit cdaae3
                if (dolines) {
Packit cdaae3
                    int res = 0;
Packit cdaae3
                    Dwarf_Unsigned value = 0;
Packit cdaae3
                    cur_file_entry = (Dwarf_File_Entry)
Packit cdaae3
                        malloc(sizeof(struct Dwarf_File_Entry_s));
Packit cdaae3
                    if (cur_file_entry == NULL) {
Packit cdaae3
                        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
                        return (DW_DLV_ERROR);
Packit cdaae3
                    }
Packit cdaae3
                    memset(cur_file_entry,0,sizeof(struct Dwarf_File_Entry_s));
Packit cdaae3
                    _dwarf_add_to_files_list(line_context,cur_file_entry);
Packit cdaae3
                    cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr;
Packit cdaae3
                    res = _dwarf_check_string_valid(dbg,
Packit cdaae3
                        line_ptr,line_ptr,line_ptr_end,
Packit cdaae3
                        DW_DLE_DEFINE_FILE_STRING_BAD,error);
Packit cdaae3
                    if (res != DW_DLV_OK) {
Packit cdaae3
                        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                        return res;
Packit cdaae3
                    }
Packit cdaae3
                    line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
Packit cdaae3
                    DECODE_LEB128_UWORD_CK(line_ptr,value,
Packit cdaae3
                        dbg,error,line_ptr_end);
Packit cdaae3
                    cur_file_entry->fi_dir_index = (Dwarf_Sword)value;
Packit cdaae3
                    DECODE_LEB128_UWORD_CK(line_ptr,value,
Packit cdaae3
                        dbg,error,line_ptr_end);
Packit cdaae3
                    cur_file_entry->fi_time_last_mod = value;
Packit cdaae3
                    DECODE_LEB128_UWORD_CK(line_ptr,value,
Packit cdaae3
                        dbg,error,line_ptr_end);
Packit cdaae3
                    cur_file_entry->fi_file_length = value;
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                    dwarf_printf(dbg,
Packit cdaae3
                        "DW_LNE_define_file %s \n", cur_file_entry->fi_file_name);
Packit cdaae3
                    dwarf_printf(dbg,
Packit cdaae3
                        "    dir index %d\n", (int) cur_file_entry->fi_dir_index);
Packit cdaae3
                    {
Packit cdaae3
                        time_t tt3 = (time_t) cur_file_entry->fi_time_last_mod;
Packit cdaae3
Packit cdaae3
                        /* ctime supplies newline */
Packit cdaae3
                        dwarf_printf(dbg,
Packit cdaae3
                            "    last time 0x%x %s",
Packit cdaae3
                            (unsigned)tt3, ctime(&tt3));
Packit cdaae3
                    }
Packit cdaae3
                    dwarf_printf(dbg,
Packit cdaae3
                        "    file length %ld 0x%lx\n",
Packit cdaae3
                        (long) cur_file_entry->fi_file_length,
Packit cdaae3
                        (unsigned long) cur_file_entry->fi_file_length);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            case DW_LNE_set_discriminator:{
Packit cdaae3
                /* New in DWARF4 */
Packit cdaae3
                Dwarf_Unsigned utmp2 = 0;
Packit cdaae3
Packit cdaae3
                DECODE_LEB128_UWORD_CK(line_ptr, utmp2,
Packit cdaae3
                    dbg,error,line_ptr_end);
Packit cdaae3
                regs.lr_discriminator = (Dwarf_Word) utmp2;
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNE_set_discriminator 0x%"
Packit cdaae3
                    DW_PR_XZEROS DW_PR_DUx "\n",utmp2);
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            default:{
Packit cdaae3
                /*  This is an extended op code we do not know about,
Packit cdaae3
                    other than we know now many bytes it is
Packit cdaae3
                    and the op code and the bytes of operand. */
Packit cdaae3
                Dwarf_Unsigned remaining_bytes = instr_length -1;
Packit cdaae3
                if (instr_length < 1 || remaining_bytes > DW_LNE_LEN_MAX) {
Packit cdaae3
                    _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
                    _dwarf_error(dbg, error,
Packit cdaae3
                        DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "DW_LNE extended op 0x%x ",ext_opcode);
Packit cdaae3
                dwarf_printf(dbg,
Packit cdaae3
                    "Bytecount: %" DW_PR_DUu , (Dwarf_Unsigned)instr_length);
Packit cdaae3
                if (remaining_bytes > 0) {
Packit cdaae3
                    dwarf_printf(dbg,
Packit cdaae3
                        " linedata: 0x");
Packit cdaae3
                    while (remaining_bytes > 0) {
Packit cdaae3
                        dwarf_printf(dbg,
Packit cdaae3
                            "%02x",(unsigned char)(*(line_ptr)));
Packit cdaae3
                        line_ptr++;
Packit cdaae3
                        if (line_ptr > line_ptr_end) {
Packit cdaae3
                            _dwarf_error(dbg, error,
Packit cdaae3
                                DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                            return (DW_DLV_ERROR);
Packit cdaae3
                        }
Packit cdaae3
                        remaining_bytes--;
Packit cdaae3
                    }
Packit cdaae3
                }
Packit cdaae3
#else /* ! PRINTING_DETAILS */
Packit cdaae3
                line_ptr += remaining_bytes;
Packit cdaae3
                if (line_ptr > line_ptr_end) {
Packit cdaae3
                    _dwarf_error(dbg, error, DW_DLE_LINE_TABLE_BAD);
Packit cdaae3
                    return (DW_DLV_ERROR);
Packit cdaae3
                }
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
                dwarf_printf(dbg,"\n");
Packit cdaae3
                }
Packit cdaae3
                break;
Packit cdaae3
            } /* End switch. */
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    block_line = (Dwarf_Line *)
Packit cdaae3
        _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
Packit cdaae3
    if (block_line == NULL) {
Packit cdaae3
        curr_chain = head_chain;
Packit cdaae3
        /*  FIXME: chain cleanup should be a function and called at
Packit cdaae3
            more places in this function.  */
Packit cdaae3
        _dwarf_free_chain_entries(dbg,head_chain,line_count);
Packit cdaae3
        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    curr_chain = head_chain;
Packit cdaae3
    for (i = 0; i < line_count; i++) {
Packit cdaae3
        Dwarf_Chain t = 0;
Packit cdaae3
        *(block_line + i) = curr_chain->ch_item;
Packit cdaae3
        t = curr_chain;
Packit cdaae3
        curr_chain = curr_chain->ch_next;
Packit cdaae3
        dwarf_dealloc(dbg, t, DW_DLA_CHAIN);
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (is_single_table || !is_actuals_table) {
Packit cdaae3
        line_context->lc_linebuf_logicals = block_line;
Packit cdaae3
        line_context->lc_linecount_logicals = line_count;
Packit cdaae3
    } else {
Packit cdaae3
        line_context->lc_linebuf_actuals = block_line;
Packit cdaae3
        line_context->lc_linecount_actuals = line_count;
Packit cdaae3
    }
Packit cdaae3
#ifdef PRINTING_DETAILS
Packit cdaae3
    if (is_single_table) {
Packit cdaae3
        if(!line_count) {
Packit cdaae3
            dwarf_printf(dbg," Line table is present (offset 0x%"
Packit cdaae3
                DW_PR_XZEROS DW_PR_DUx
Packit cdaae3
                ") but no lines present\n",
Packit cdaae3
                line_context->lc_section_offset);
Packit cdaae3
        }
Packit cdaae3
    } else if (is_actuals_table) {
Packit cdaae3
        if(!line_count) {
Packit cdaae3
            dwarf_printf(dbg," Line table present (offset 0x%"
Packit cdaae3
                DW_PR_XZEROS DW_PR_DUx
Packit cdaae3
                ") but no actuals lines present\n",
Packit cdaae3
                line_context->lc_section_offset);
Packit cdaae3
        }
Packit cdaae3
    } else {
Packit cdaae3
        if(!line_count) {
Packit cdaae3
            dwarf_printf(dbg," Line table present (offset 0x%"
Packit cdaae3
                DW_PR_XZEROS DW_PR_DUx
Packit cdaae3
                ") but no logicals lines present\n",
Packit cdaae3
                line_context->lc_section_offset);
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
#endif /* PRINTING_DETAILS */
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}