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_ELFACCESS_H
4349d3bc9Richard Lowe#include <elfaccess.h>
4449d3bc9Richard Lowe#endif
4549d3bc9Richard Lowe#include "pro_incl.h"
4649d3bc9Richard Lowe#include "pro_section.h"
4749d3bc9Richard Lowe
4849d3bc9Richard Lowe
4949d3bc9Richard Lowe/*
5049d3bc9Richard Lowe    This function adds another type name to the
5149d3bc9Richard Lowe    list of type names for the given Dwarf_P_Debug.
5249d3bc9Richard Lowe    It returns 0 on error, and 1 otherwise.
5349d3bc9Richard Lowe*/
5449d3bc9Richard LoweDwarf_Unsigned
5549d3bc9Richard Lowedwarf_add_typename(Dwarf_P_Debug dbg,
5607dc194Richard Lowe                   Dwarf_P_Die die,
5707dc194Richard Lowe                   char *type_name, Dwarf_Error * error)
5849d3bc9Richard Lowe{
5949d3bc9Richard Lowe    return
6007dc194Richard Lowe        _dwarf_add_simple_name_entry(dbg, die, type_name,
6107dc194Richard Lowe                                     dwarf_snk_typename, error);
6249d3bc9Richard Lowe}
6349d3bc9Richard Lowe
6449d3bc9Richard Lowe/*
6549d3bc9Richard Lowe  The following is the generic 'add a simple name entry'
6649d3bc9Richard Lowe  for any of the simple name sections.
6749d3bc9Richard Lowe
6849d3bc9Richard Lowe  See enum dwarf_sn_kind in pro_opaque.h
6949d3bc9Richard Lowe
7049d3bc9Richard Lowe*/
7149d3bc9Richard LoweDwarf_Unsigned
7249d3bc9Richard Lowe_dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
7307dc194Richard Lowe                             Dwarf_P_Die die,
7407dc194Richard Lowe                             char *entry_name,
7507dc194Richard Lowe                             enum dwarf_sn_kind entrykind,
7607dc194Richard Lowe                             Dwarf_Error * error)
7749d3bc9Richard Lowe{
7849d3bc9Richard Lowe    Dwarf_P_Simple_nameentry nameentry;
7949d3bc9Richard Lowe    Dwarf_P_Simple_name_header hdr;
8049d3bc9Richard Lowe    char *name;
8149d3bc9Richard Lowe    int uword_size;
8249d3bc9Richard Lowe
8349d3bc9Richard Lowe    if (dbg == NULL) {
8407dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
8507dc194Richard Lowe        return (0);
8649d3bc9Richard Lowe    }
8749d3bc9Richard Lowe
8849d3bc9Richard Lowe    if (die == NULL) {
8907dc194Richard Lowe        _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
9007dc194Richard Lowe        return (0);
9149d3bc9Richard Lowe    }
9249d3bc9Richard Lowe
9349d3bc9Richard Lowe
9449d3bc9Richard Lowe    nameentry = (Dwarf_P_Simple_nameentry)
9507dc194Richard Lowe        _dwarf_p_get_alloc(dbg,
9607dc194Richard Lowe                           sizeof(struct Dwarf_P_Simple_nameentry_s));
9749d3bc9Richard Lowe    if (nameentry == NULL) {
9807dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
9907dc194Richard Lowe        return (0);
10049d3bc9Richard Lowe    }
10149d3bc9Richard Lowe
10249d3bc9Richard Lowe    name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1);
10349d3bc9Richard Lowe    if (name == NULL) {
10407dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
10507dc194Richard Lowe        return (0);
10649d3bc9Richard Lowe    }
10749d3bc9Richard Lowe    strcpy(name, entry_name);
10849d3bc9Richard Lowe
10949d3bc9Richard Lowe    nameentry->sne_die = die;
11049d3bc9Richard Lowe    nameentry->sne_name = name;
11149d3bc9Richard Lowe    nameentry->sne_name_len = strlen(name);
11249d3bc9Richard Lowe    uword_size = dbg->de_offset_size;
11349d3bc9Richard Lowe
11449d3bc9Richard Lowe    hdr = &dbg->de_simple_name_headers[entrykind];
11549d3bc9Richard Lowe    if (hdr->sn_head == NULL)
11607dc194Richard Lowe        hdr->sn_head = hdr->sn_tail = nameentry;
11749d3bc9Richard Lowe    else {
11807dc194Richard Lowe        hdr->sn_tail->sne_next = nameentry;
11907dc194Richard Lowe        hdr->sn_tail = nameentry;
12049d3bc9Richard Lowe    }
12149d3bc9Richard Lowe    hdr->sn_count++;
12249d3bc9Richard Lowe    hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1;
12349d3bc9Richard Lowe
12449d3bc9Richard Lowe    return (1);
12549d3bc9Richard Lowe}
12649d3bc9Richard Lowe
12749d3bc9Richard Lowe
12849d3bc9Richard Lowe
12949d3bc9Richard Lowe/*
13049d3bc9Richard Lowe     _dwarf_transform_simplename_to_disk writes
13149d3bc9Richard Lowe     ".rel.debug_pubnames",
13249d3bc9Richard Lowe     ".rel.debug_funcnames",       sgi extension
13349d3bc9Richard Lowe     ".rel.debug_typenames",       sgi extension
13449d3bc9Richard Lowe     ".rel.debug_varnames",        sgi extension
13549d3bc9Richard Lowe     ".rel.debug_weaknames",       sgi extension
13649d3bc9Richard Lowe     to disk.
13707dc194Richard Lowe        section_index indexes one of those sections.
13807dc194Richard Lowe        entrykind is one of those 'kind's.
13949d3bc9Richard Lowe
14049d3bc9Richard Lowe*/
14149d3bc9Richard Loweint
14207dc194Richard Lowe_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index, /* in
14307dc194Richard Lowe                                                                                                           de_elf_sects
14407dc194Richard Lowe                                                                                                           etc
14507dc194Richard Lowe                                                                                                         */
14607dc194Richard Lowe                                    Dwarf_Error * error)
14749d3bc9Richard Lowe{
14849d3bc9Richard Lowe
14949d3bc9Richard Lowe
15049d3bc9Richard Lowe    /* Used to fill in 0. */
15149d3bc9Richard Lowe    const Dwarf_Signed big_zero = 0;
15249d3bc9Richard Lowe
15349d3bc9Richard Lowe    /* Used to scan the section data buffers. */
15449d3bc9Richard Lowe    Dwarf_P_Section_Data debug_sect;
15549d3bc9Richard Lowe
15649d3bc9Richard Lowe    Dwarf_Signed debug_info_size;
15749d3bc9Richard Lowe
15849d3bc9Richard Lowe    Dwarf_P_Simple_nameentry nameentry_original;
15949d3bc9Richard Lowe    Dwarf_P_Simple_nameentry nameentry;
16049d3bc9Richard Lowe    Dwarf_Small *stream_bytes;
16149d3bc9Richard Lowe    Dwarf_Small *cur_stream_bytes_ptr;
16249d3bc9Richard Lowe    Dwarf_Unsigned stream_bytes_count;
16307dc194Richard Lowe    Dwarf_Unsigned adjusted_length;     /* count excluding length field
16407dc194Richard Lowe                                         */
16549d3bc9Richard Lowe
16649d3bc9Richard Lowe
16749d3bc9Richard Lowe    int uword_size = dbg->de_offset_size;
16849d3bc9Richard Lowe    int extension_size = dbg->de_64bit_extension ? 4 : 0;
16949d3bc9Richard Lowe
17049d3bc9Richard Lowe    Dwarf_P_Simple_name_header hdr;
17149d3bc9Richard Lowe
17249d3bc9Richard Lowe
17349d3bc9Richard Lowe    /* ***** BEGIN CODE ***** */
17449d3bc9Richard Lowe
17549d3bc9Richard Lowe    debug_info_size = 0;
17649d3bc9Richard Lowe    for (debug_sect = dbg->de_debug_sects; debug_sect != NULL;
17707dc194Richard Lowe         debug_sect = debug_sect->ds_next) {
17807dc194Richard Lowe        /* We want the size of the .debug_info section for this CU
17907dc194Richard Lowe           because the dwarf spec requires us to output it below so we
18007dc194Richard Lowe           look for it specifically. */
18107dc194Richard Lowe        if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) {
18207dc194Richard Lowe            debug_info_size += debug_sect->ds_nbytes;
18307dc194Richard Lowe        }
18449d3bc9Richard Lowe    }
18549d3bc9Richard Lowe
18649d3bc9Richard Lowe    hdr = &dbg->de_simple_name_headers[entrykind];
18749d3bc9Richard Lowe    /* Size of the .debug_typenames (or similar) section header. */
18807dc194Richard Lowe    stream_bytes_count = extension_size + uword_size +  /* Size of
18907dc194Richard Lowe                                                           length
19007dc194Richard Lowe                                                           field. */
19107dc194Richard Lowe        sizeof(Dwarf_Half) +    /* Size of version field. */
19207dc194Richard Lowe        uword_size +            /* Size of .debug_info offset. */
19307dc194Richard Lowe        uword_size;             /* Size of .debug_names. */
19449d3bc9Richard Lowe
19549d3bc9Richard Lowe
19649d3bc9Richard Lowe
19749d3bc9Richard Lowe    nameentry_original = hdr->sn_head;
19849d3bc9Richard Lowe    nameentry = nameentry_original;
19949d3bc9Richard Lowe    /* add in the content size */
20049d3bc9Richard Lowe    stream_bytes_count += hdr->sn_net_len;
20149d3bc9Richard Lowe
20249d3bc9Richard Lowe    /* Size of the last 0 offset. */
20349d3bc9Richard Lowe    stream_bytes_count += uword_size;
20449d3bc9Richard Lowe
20549d3bc9Richard Lowe    /* Now we know how long the entire section is */
20649d3bc9Richard Lowe    GET_CHUNK(dbg, dbg->de_elf_sects[section_index],
20707dc194Richard Lowe              stream_bytes, (unsigned long) stream_bytes_count, error);
20849d3bc9Richard Lowe    if (stream_bytes == NULL) {
20907dc194Richard Lowe        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
21007dc194Richard Lowe        return (0);
21149d3bc9Richard Lowe    }
21249d3bc9Richard Lowe    cur_stream_bytes_ptr = stream_bytes;
21349d3bc9Richard Lowe
21449d3bc9Richard Lowe    if (extension_size) {
21507dc194Richard Lowe        Dwarf_Unsigned x = DISTINGUISHED_VALUE;
21649d3bc9Richard Lowe
21707dc194Richard Lowe        WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
21807dc194Richard Lowe                        (const void *) &x, sizeof(x), extension_size);
21907dc194Richard Lowe        cur_stream_bytes_ptr += extension_size;
22049d3bc9Richard Lowe
22149d3bc9Richard Lowe    }
22249d3bc9Richard Lowe    /* Write the adjusted length of .debug_*names section. */
22349d3bc9Richard Lowe    adjusted_length = stream_bytes_count - uword_size - extension_size;
22449d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
22507dc194Richard Lowe                    (const void *) &adjusted_length,
22607dc194Richard Lowe                    sizeof(adjusted_length), uword_size);
22749d3bc9Richard Lowe    cur_stream_bytes_ptr += uword_size;
22849d3bc9Richard Lowe
22949d3bc9Richard Lowe    /* Write the version as 2 bytes. */
23049d3bc9Richard Lowe    {
23107dc194Richard Lowe        Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
23249d3bc9Richard Lowe
23307dc194Richard Lowe        WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
23407dc194Richard Lowe                        (const void *) &verstamp,
23507dc194Richard Lowe                        sizeof(verstamp), sizeof(Dwarf_Half));
23607dc194Richard Lowe        cur_stream_bytes_ptr += sizeof(Dwarf_Half);
23749d3bc9Richard Lowe    }
23849d3bc9Richard Lowe
23949d3bc9Richard Lowe    /* Write the offset of the compile-unit. */
24049d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
24107dc194Richard Lowe                    (const void *) &big_zero,
24207dc194Richard Lowe                    sizeof(big_zero), uword_size);
24349d3bc9Richard Lowe    cur_stream_bytes_ptr += uword_size;
24449d3bc9Richard Lowe
24549d3bc9Richard Lowe    /* now create the relocation for the compile_unit offset */
24649d3bc9Richard Lowe    {
24707dc194Richard Lowe        int res = dbg->de_reloc_name(dbg,
24807dc194Richard Lowe                                     section_index,
24907dc194Richard Lowe                                     extension_size + uword_size +
25007dc194Richard Lowe                                     sizeof(Dwarf_Half)
25107dc194Richard Lowe                                     /* r_offset */
25207dc194Richard Lowe                                     ,
25307dc194Richard Lowe                                     /* debug_info section name symbol */
25407dc194Richard Lowe                                     dbg->de_sect_name_idx[DEBUG_INFO],
25507dc194Richard Lowe                                     dwarf_drt_data_reloc,
25607dc194Richard Lowe                                     uword_size);
25707dc194Richard Lowe
25807dc194Richard Lowe        if (res != DW_DLV_OK) {
25907dc194Richard Lowe            {
26007dc194Richard Lowe                _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
26107dc194Richard Lowe                return (0);
26207dc194Richard Lowe            }
26307dc194Richard Lowe        }
26449d3bc9Richard Lowe    }
26549d3bc9Richard Lowe
26649d3bc9Richard Lowe    /* Write the size of .debug_info section. */
26749d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
26807dc194Richard Lowe                    (const void *) &debug_info_size,
26907dc194Richard Lowe                    sizeof(debug_info_size), uword_size);
27049d3bc9Richard Lowe    cur_stream_bytes_ptr += uword_size;
27149d3bc9Richard Lowe
27249d3bc9Richard Lowe
27349d3bc9Richard Lowe    for (nameentry = nameentry_original;
27407dc194Richard Lowe         nameentry != NULL; nameentry = nameentry->sne_next) {
27507dc194Richard Lowe
27607dc194Richard Lowe        /* Copy offset of die from start of compile-unit. */
27707dc194Richard Lowe        WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
27807dc194Richard Lowe                        (const void *) &nameentry->sne_die->di_offset,
27907dc194Richard Lowe                        sizeof(nameentry->sne_die->di_offset),
28007dc194Richard Lowe                        uword_size);
28107dc194Richard Lowe        cur_stream_bytes_ptr += uword_size;
28207dc194Richard Lowe
28307dc194Richard Lowe        /* Copy the type name. */
28407dc194Richard Lowe        strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name);
28507dc194Richard Lowe        cur_stream_bytes_ptr += nameentry->sne_name_len + 1;
28649d3bc9Richard Lowe    }
28749d3bc9Richard Lowe
28849d3bc9Richard Lowe    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
28907dc194Richard Lowe                    (const void *) &big_zero,
29007dc194Richard Lowe                    sizeof(big_zero), uword_size);
29149d3bc9Richard Lowe
29249d3bc9Richard Lowe
29349d3bc9Richard Lowe
29449d3bc9Richard Lowe
29549d3bc9Richard Lowe    return (int) dbg->de_n_debug_sect;
29649d3bc9Richard Lowe}