149d3bc9Richard Lowe/*
249d3bc9Richard Lowe
307dc194Richard Lowe  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
449d3bc9Richard Lowe
549d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
649d3bc9Richard Lowe  under the terms of version 2.1 of the GNU Lesser General Public License
749d3bc9Richard Lowe  as published by the Free Software Foundation.
849d3bc9Richard Lowe
949d3bc9Richard Lowe  This program is distributed in the hope that it would be useful, but
1049d3bc9Richard Lowe  WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc9Richard Lowe
1349d3bc9Richard Lowe  Further, this software is distributed without any warranty that it is
1449d3bc9Richard Lowe  free of the rightful claim of any third person regarding infringement
1549d3bc9Richard Lowe  or the like.  Any license provided herein, whether implied or
1649d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
1749d3bc9Richard Lowe  any, provided herein do not apply to combinations of this program with
1849d3bc9Richard Lowe  other software, or any other product whatsoever.
1949d3bc9Richard Lowe
2049d3bc9Richard Lowe  You should have received a copy of the GNU Lesser General Public
2149d3bc9Richard Lowe  License along with this program; if not, write the Free Software
2207dc194Richard Lowe  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2349d3bc9Richard Lowe  USA.
2449d3bc9Richard Lowe
2507dc194Richard Lowe  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2649d3bc9Richard Lowe  Mountain View, CA 94043, or:
2749d3bc9Richard Lowe
2849d3bc9Richard Lowe  http://www.sgi.com
2949d3bc9Richard Lowe
3049d3bc9Richard Lowe  For further information regarding this notice, see:
3149d3bc9Richard Lowe
3249d3bc9Richard Lowe  http://oss.sgi.com/projects/GenInfo/NoticeExplan
3349d3bc9Richard Lowe
3449d3bc9Richard Lowe*/
3549d3bc9Richard Lowe
3649d3bc9Richard Lowe
3749d3bc9Richard Lowe
3849d3bc9Richard Lowe#include "config.h"
3949d3bc9Richard Lowe#include "libdwarfdefs.h"
4049d3bc9Richard Lowe#include <stdio.h>
4149d3bc9Richard Lowe#include <string.h>
4249d3bc9Richard Lowe#ifdef HAVE_ELF_H
4349d3bc9Richard Lowe#include <elf.h>
4449d3bc9Richard Lowe#endif
4549d3bc9Richard Lowe#include "pro_incl.h"
4649d3bc9Richard Lowe#include "pro_line.h"
4749d3bc9Richard Lowe
4849d3bc9Richard LoweDwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug,
4907dc194Richard Lowe                                         Dwarf_Unsigned file_index,
5007dc194Richard Lowe                                         Dwarf_Addr code_address,
5107dc194Richard Lowe                                         Dwarf_Unsigned symidx,
5207dc194Richard Lowe                                         Dwarf_Unsigned line_no,
5307dc194Richard Lowe                                         Dwarf_Signed col_no,
5407dc194Richard Lowe                                         Dwarf_Bool is_stmt_begin,
5507dc194Richard Lowe                                         Dwarf_Bool is_bb_begin,
5607dc194Richard Lowe                                         Dwarf_Ubyte opc,
5707dc194Richard Lowe                                         Dwarf_Error * error);
5849d3bc9Richard Lowe
5949d3bc9Richard Lowe/*-------------------------------------------------------------------------
6007dc194Richard Lowe        Add a entry to the line information section
6107dc194Richard Lowe        file_index: index of file in file entries, obtained from
6207dc194Richard Lowe        add_file_entry() call.
6307dc194Richard Lowe
6407dc194Richard Lowe        This function actually calls _dwarf_pro_add_line_entry(), with
6507dc194Richard Lowe        an extra parameter, the opcode. Done so that interface calls
6607dc194Richard Lowe        dwarf_lne_set_address() and dwarf_lne_end_sequence() can use
6707dc194Richard Lowe        this internal routine.
6849d3bc9Richard Lowe---------------------------------------------------------------------------*/
6949d3bc9Richard LoweDwarf_Unsigned
7049d3bc9Richard Lowedwarf_add_line_entry(Dwarf_P_Debug dbg,
7107dc194Richard Lowe                     Dwarf_Unsigned file_index,
7207dc194Richard Lowe                     Dwarf_Addr code_address,
7307dc194Richard Lowe                     Dwarf_Unsigned line_no,
7407dc194Richard Lowe                     Dwarf_Signed col_no,
7507dc194Richard Lowe                     Dwarf_Bool is_stmt_begin,
7607dc194Richard Lowe                     Dwarf_Bool is_bb_begin, Dwarf_Error * error)
7749d3bc9Richard Lowe{
7849d3bc9Richard Lowe    Dwarf_Unsigned retval;
7949d3bc9Richard Lowe
8049d3bc9Richard Lowe    retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, 0,
8107dc194Richard Lowe                                       line_no, col_no, is_stmt_begin,
8207dc194Richard Lowe                                       is_bb_begin, 0, error);
8349d3bc9Richard Lowe    return retval;
8449d3bc9Richard Lowe}
8549d3bc9Richard Lowe
8649d3bc9Richard Lowe/*------------------------------------------------------------------------
8707dc194Richard Lowe        Ask to emit DW_LNE_set_address opcode explicitly. Used by be
8807dc194Richard Lowe        to emit start of a new .text section, or to force a relocated
8907dc194Richard Lowe        address into debug line information entry.
9049d3bc9Richard Lowe-------------------------------------------------------------------------*/
9149d3bc9Richard LoweDwarf_Unsigned
9249d3bc9Richard Lowedwarf_lne_set_address(Dwarf_P_Debug dbg,
9307dc194Richard Lowe                      Dwarf_Addr offs,
9407dc194Richard Lowe                      Dwarf_Unsigned symidx, Dwarf_Error * error)
9549d3bc9Richard Lowe{
9649d3bc9Richard Lowe    Dwarf_Ubyte opc;
9749d3bc9Richard Lowe    Dwarf_Unsigned retval;
9849d3bc9Richard Lowe
9949d3bc9Richard Lowe    opc = DW_LNE_set_address;
10049d3bc9Richard Lowe    retval =
10107dc194Richard Lowe        _dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc,
10207dc194Richard Lowe                                  error);
10349d3bc9Richard Lowe    return retval;
10449d3bc9Richard Lowe}
10549d3bc9Richard Lowe
10649d3bc9Richard Lowe/*------------------------------------------------------------------------
10707dc194Richard Lowe        Ask to emit end_seqence opcode. Used normally at the end of a
10807dc194Richard Lowe        compilation unit. Can also be used in the middle if there
10907dc194Richard Lowe        are gaps in the region described by the code address.
11049d3bc9Richard Lowe-------------------------------------------------------------------------*/
11149d3bc9Richard LoweDwarf_Unsigned
11249d3bc9Richard Lowedwarf_lne_end_sequence(Dwarf_P_Debug dbg,
11307dc194Richard Lowe                       Dwarf_Addr end_address, Dwarf_Error * error)
11449d3bc9Richard Lowe{
11549d3bc9Richard Lowe    Dwarf_Ubyte opc;
11649d3bc9Richard Lowe    Dwarf_Unsigned retval;
11749d3bc9Richard Lowe
11849d3bc9Richard Lowe    opc = DW_LNE_end_sequence;
11949d3bc9Richard Lowe    retval =
12007dc194Richard Lowe        _dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0,
12107dc194Richard Lowe                                  opc, error);
12249d3bc9Richard Lowe    return retval;
12349d3bc9Richard Lowe}
12449d3bc9Richard Lowe
12549d3bc9Richard Lowe/*----------------------------------------------------------------------------
12607dc194Richard Lowe        Add an entry in the internal list of lines mantained by producer.
12707dc194Richard Lowe        Opc indicates if an opcode needs to be generated, rather than just
12807dc194Richard Lowe        an entry in the matrix. During opcodes generation time, these
12907dc194Richard Lowe        opcodes will be used.
13049d3bc9Richard Lowe-----------------------------------------------------------------------------*/
13149d3bc9Richard LoweDwarf_Unsigned
13249d3bc9Richard Lowe_dwarf_pro_add_line_entry(Dwarf_P_Debug dbg,
13307dc194Richard Lowe                          Dwarf_Unsigned file_index,
13407dc194Richard Lowe                          Dwarf_Addr code_address,
13507dc194Richard Lowe                          Dwarf_Unsigned symidx,
13607dc194Richard Lowe                          Dwarf_Unsigned line_no,
13707dc194Richard Lowe                          Dwarf_Signed col_no,
13807dc194Richard Lowe                          Dwarf_Bool is_stmt_begin,
13907dc194Richard Lowe                          Dwarf_Bool is_bb_begin,
14007dc194Richard Lowe                          Dwarf_Ubyte opc, Dwarf_Error * error)
14149d3bc9Richard Lowe{
14249d3bc9Richard Lowe    if (dbg->de_lines == NULL) {
14307dc194Richard Lowe        dbg->de_lines = (Dwarf_P_Line)
14407dc194Richard Lowe            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
14507dc194Richard Lowe        if (dbg->de_lines == NULL) {
14607dc194Richard Lowe            DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
14707dc194Richard Lowe        }
14807dc194Richard Lowe        dbg->de_last_line = dbg->de_lines;
14907dc194Richard Lowe        _dwarf_pro_reg_init(dbg->de_lines);
15049d3bc9Richard Lowe
15149d3bc9Richard Lowe    } else {
15207dc194Richard Lowe        dbg->de_last_line->dpl_next = (Dwarf_P_Line)
15307dc194Richard Lowe            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
15407dc194Richard Lowe        if (dbg->de_last_line->dpl_next == NULL) {
15507dc194Richard Lowe            DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
15607dc194Richard Lowe        }
15707dc194Richard Lowe        dbg->de_last_line = dbg->de_last_line->dpl_next;
15807dc194Richard Lowe        _dwarf_pro_reg_init(dbg->de_last_line);
15949d3bc9Richard Lowe    }
16049d3bc9Richard Lowe    dbg->de_last_line->dpl_address = code_address;
16149d3bc9Richard Lowe    dbg->de_last_line->dpl_file = (unsigned long) file_index;
16249d3bc9Richard Lowe    dbg->de_last_line->dpl_line = (unsigned long) line_no;
16349d3bc9Richard Lowe    dbg->de_last_line->dpl_column = (unsigned long) col_no;
16449d3bc9Richard Lowe    dbg->de_last_line->dpl_is_stmt = is_stmt_begin;
16549d3bc9Richard Lowe    dbg->de_last_line->dpl_basic_block = is_bb_begin;
16649d3bc9Richard Lowe    dbg->de_last_line->dpl_opc = opc;
16749d3bc9Richard Lowe    dbg->de_last_line->dpl_r_symidx = symidx;
16849d3bc9Richard Lowe
16949d3bc9Richard Lowe    return (0);
17049d3bc9Richard Lowe}
17149d3bc9Richard Lowe
17249d3bc9Richard Lowe/*-----------------------------------------------------------------------
17307dc194Richard Lowe        Add a directory declaration to the debug_line section. Stored
17407dc194Richard Lowe        in linked list.
17549d3bc9Richard Lowe------------------------------------------------------------------------*/
17649d3bc9Richard LoweDwarf_Unsigned
17749d3bc9Richard Lowedwarf_add_directory_decl(Dwarf_P_Debug dbg,
17807dc194Richard Lowe                         char *name, Dwarf_Error * error)
17949d3bc9Richard Lowe{
18049d3bc9Richard Lowe    if (dbg->de_inc_dirs == NULL) {
18107dc194Richard Lowe        dbg->de_inc_dirs = (Dwarf_P_Inc_Dir)
18207dc194Richard Lowe            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
18307dc194Richard Lowe        if (dbg->de_inc_dirs == NULL) {
18407dc194Richard Lowe            DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
18507dc194Richard Lowe        }
18607dc194Richard Lowe        dbg->de_last_inc_dir = dbg->de_inc_dirs;
18707dc194Richard Lowe        dbg->de_n_inc_dirs = 1;
18849d3bc9Richard Lowe    } else {
18907dc194Richard Lowe        dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir)
19007dc194Richard Lowe            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
19107dc194Richard Lowe        if (dbg->de_last_inc_dir->did_next == NULL) {
19207dc194Richard Lowe            DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
19307dc194Richard Lowe        }
19407dc194Richard Lowe        dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next;
19507dc194Richard Lowe        dbg->de_n_inc_dirs++;
19649d3bc9Richard Lowe    }
19749d3bc9Richard Lowe    dbg->de_last_inc_dir->did_name =
19807dc194Richard Lowe        (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
19949d3bc9Richard Lowe    if (dbg->de_last_inc_dir->did_name == NULL) {
20007dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT);
20149d3bc9Richard Lowe    }
20249d3bc9Richard Lowe    strcpy(dbg->de_last_inc_dir->did_name, name);
20349d3bc9Richard Lowe    dbg->de_last_inc_dir->did_next = NULL;
20449d3bc9Richard Lowe
20549d3bc9Richard Lowe    return dbg->de_n_inc_dirs;
20649d3bc9Richard Lowe}
20749d3bc9Richard Lowe
20849d3bc9Richard Lowe/*-----------------------------------------------------------------------
20907dc194Richard Lowe        Add a file entry declaration to the debug_line section. Stored
21007dc194Richard Lowe        in linked list. The data is immediately encodes as leb128
21107dc194Richard Lowe        and stored in Dwarf_P_F_Entry_s struct.
21249d3bc9Richard Lowe------------------------------------------------------------------------*/
21349d3bc9Richard LoweDwarf_Unsigned
21449d3bc9Richard Lowedwarf_add_file_decl(Dwarf_P_Debug dbg,
21507dc194Richard Lowe                    char *name,
21607dc194Richard Lowe                    Dwarf_Unsigned dir_idx,
21707dc194Richard Lowe                    Dwarf_Unsigned time_mod,
21807dc194Richard Lowe                    Dwarf_Unsigned length, Dwarf_Error * error)
21949d3bc9Richard Lowe{
22049d3bc9Richard Lowe    Dwarf_P_F_Entry cur;
22149d3bc9Richard Lowe    char *ptr;
22249d3bc9Richard Lowe    int nbytes_idx, nbytes_time, nbytes_len;
22349d3bc9Richard Lowe    char buffidx[ENCODE_SPACE_NEEDED];
22449d3bc9Richard Lowe    char bufftime[ENCODE_SPACE_NEEDED];
22549d3bc9Richard Lowe    char bufflen[ENCODE_SPACE_NEEDED];
22649d3bc9Richard Lowe    int res;
22749d3bc9Richard Lowe
22849d3bc9Richard Lowe    if (dbg->de_file_entries == NULL) {
22907dc194Richard Lowe        dbg->de_file_entries = (Dwarf_P_F_Entry)
23007dc194Richard Lowe            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
23107dc194Richard Lowe        if (dbg->de_file_entries == NULL) {
23207dc194Richard Lowe            DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
23307dc194Richard Lowe                              DW_DLV_NOCOUNT);
23407dc194Richard Lowe        }
23507dc194Richard Lowe        cur = dbg->de_file_entries;
23607dc194Richard Lowe        dbg->de_last_file_entry = cur;
23707dc194Richard Lowe        dbg->de_n_file_entries = 1;
23849d3bc9Richard Lowe    } else {
23907dc194Richard Lowe        cur = dbg->de_last_file_entry;
24007dc194Richard Lowe        cur->dfe_next = (Dwarf_P_F_Entry)
24107dc194Richard Lowe            _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
24207dc194Richard Lowe        if (cur->dfe_next == NULL) {
24307dc194Richard Lowe            DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
24407dc194Richard Lowe                              DW_DLV_NOCOUNT);
24507dc194Richard Lowe        }
24607dc194Richard Lowe        cur = cur->dfe_next;
24707dc194Richard Lowe        dbg->de_last_file_entry = cur;
24807dc194Richard Lowe        dbg->de_n_file_entries++;
24949d3bc9Richard Lowe    }
25049d3bc9Richard Lowe    cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
25149d3bc9Richard Lowe    if (cur->dfe_name == NULL) {
25207dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
25349d3bc9Richard Lowe    }
25449d3bc9Richard Lowe    strcpy((char *) cur->dfe_name, name);
25549d3bc9Richard Lowe    res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx,
25607dc194Richard Lowe                                      buffidx, sizeof(buffidx));
25749d3bc9Richard Lowe    if (res != DW_DLV_OK) {
25807dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
25949d3bc9Richard Lowe    }
26049d3bc9Richard Lowe    res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time,
26107dc194Richard Lowe                                      bufftime, sizeof(bufftime));
26249d3bc9Richard Lowe    if (res != DW_DLV_OK) {
26307dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
26449d3bc9Richard Lowe    }
26549d3bc9Richard Lowe    res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len,
26607dc194Richard Lowe                                      bufflen, sizeof(bufflen));
26749d3bc9Richard Lowe    cur->dfe_args = (char *)
26807dc194Richard Lowe        _dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len);
26949d3bc9Richard Lowe    if (cur->dfe_args == NULL) {
27007dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
27149d3bc9Richard Lowe    }
27249d3bc9Richard Lowe    ptr = cur->dfe_args;
27349d3bc9Richard Lowe    memcpy((void *) ptr, buffidx, nbytes_idx);
27449d3bc9Richard Lowe    ptr += nbytes_idx;
27549d3bc9Richard Lowe    memcpy((void *) ptr, bufftime, nbytes_time);
27649d3bc9Richard Lowe    ptr += nbytes_time;
27749d3bc9Richard Lowe    memcpy((void *) ptr, bufflen, nbytes_len);
27849d3bc9Richard Lowe    ptr += nbytes_len;
27949d3bc9Richard Lowe    cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len;
28049d3bc9Richard Lowe    cur->dfe_next = NULL;
28149d3bc9Richard Lowe
28249d3bc9Richard Lowe    return dbg->de_n_file_entries;
28349d3bc9Richard Lowe}
28449d3bc9Richard Lowe
28549d3bc9Richard Lowe
28649d3bc9Richard Lowe/*---------------------------------------------------------------------
28707dc194Richard Lowe        Initialize a row of the matrix for line numbers, meaning
28807dc194Richard Lowe        initialize the struct corresponding to it
28949d3bc9Richard Lowe----------------------------------------------------------------------*/
29049d3bc9Richard Lowevoid
29149d3bc9Richard Lowe_dwarf_pro_reg_init(Dwarf_P_Line cur_line)
29249d3bc9Richard Lowe{
29349d3bc9Richard Lowe    cur_line->dpl_address = 0;
29449d3bc9Richard Lowe    cur_line->dpl_file = 1;
29549d3bc9Richard Lowe    cur_line->dpl_line = 1;
29649d3bc9Richard Lowe    cur_line->dpl_column = 0;
29749d3bc9Richard Lowe    cur_line->dpl_is_stmt = DEFAULT_IS_STMT;
29849d3bc9Richard Lowe    cur_line->dpl_basic_block = false;
29949d3bc9Richard Lowe    cur_line->dpl_next = NULL;
30049d3bc9Richard Lowe}