149d3bc9Richard Lowe/*
249d3bc9Richard Lowe
349d3bc9Richard Lowe  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
407dc194Richard Lowe  Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
507dc194Richard Lowe  Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
649d3bc9Richard Lowe
749d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
849d3bc9Richard Lowe  under the terms of version 2.1 of the GNU Lesser General Public License
949d3bc9Richard Lowe  as published by the Free Software Foundation.
1049d3bc9Richard Lowe
1149d3bc9Richard Lowe  This program is distributed in the hope that it would be useful, but
1249d3bc9Richard Lowe  WITHOUT ANY WARRANTY; without even the implied warranty of
1449d3bc9Richard Lowe
1549d3bc9Richard Lowe  Further, this software is distributed without any warranty that it is
1649d3bc9Richard Lowe  free of the rightful claim of any third person regarding infringement
1749d3bc9Richard Lowe  or the like.  Any license provided herein, whether implied or
1849d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
1949d3bc9Richard Lowe  any, provided herein do not apply to combinations of this program with
2049d3bc9Richard Lowe  other software, or any other product whatsoever.
2149d3bc9Richard Lowe
2249d3bc9Richard Lowe  You should have received a copy of the GNU Lesser General Public
2349d3bc9Richard Lowe  License along with this program; if not, write the Free Software
2407dc194Richard Lowe  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2549d3bc9Richard Lowe  USA.
2649d3bc9Richard Lowe
2707dc194Richard Lowe  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2849d3bc9Richard Lowe  Mountain View, CA 94043, or:
2949d3bc9Richard Lowe
3049d3bc9Richard Lowe  http://www.sgi.com
3149d3bc9Richard Lowe
3249d3bc9Richard Lowe  For further information regarding this notice, see:
3349d3bc9Richard Lowe
3449d3bc9Richard Lowe  http://oss.sgi.com/projects/GenInfo/NoticeExplan
3549d3bc9Richard Lowe
3649d3bc9Richard Lowe*/
3749d3bc9Richard Lowe
3849d3bc9Richard Lowe
3949d3bc9Richard Lowe
4049d3bc9Richard Lowe#include "config.h"
4149d3bc9Richard Lowe#include "libdwarfdefs.h"
4249d3bc9Richard Lowe#include <stdio.h>
4349d3bc9Richard Lowe#include <string.h>
4449d3bc9Richard Lowe#include "pro_incl.h"
4507dc194Richard Lowe#include "pro_section.h"        /* for MAGIC_SECT_NO */
4649d3bc9Richard Lowe#include "pro_reloc_symbolic.h"
4749d3bc9Richard Lowe#include "pro_reloc_stream.h"
4849d3bc9Richard Lowe
4949d3bc9Richard Lowe
5049d3bc9Richard Lowestatic void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags);
5149d3bc9Richard Lowe
5249d3bc9Richard Lowevoid *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len);
5349d3bc9Richard Lowe
5449d3bc9Richard Lowe/*--------------------------------------------------------------------
5507dc194Richard Lowe        This function sets up a new dwarf producing region.
5607dc194Richard Lowe        flags: Indicates type of access method, one of DW_DLC* macros
5707dc194Richard Lowe        func(): Used to create a new object file, a call back function
5807dc194Richard Lowe        errhand(): Error Handler provided by user
5907dc194Richard Lowe        errarg: Argument to errhand()
6007dc194Richard Lowe        error: returned error value
6149d3bc9Richard Lowe--------------------------------------------------------------------*/
6249d3bc9Richard Lowe    /* We want the following to have an elf section number that matches
6349d3bc9Richard Lowe       'nothing' */
6449d3bc9Richard Lowestatic struct Dwarf_P_Section_Data_s init_sect = {
6549d3bc9Richard Lowe    MAGIC_SECT_NO, 0, 0, 0, 0
6649d3bc9Richard Lowe};
6749d3bc9Richard Lowe
6849d3bc9Richard LoweDwarf_P_Debug
6949d3bc9Richard Lowedwarf_producer_init_b(Dwarf_Unsigned flags,
7007dc194Richard Lowe                      Dwarf_Callback_Func_b func,
7107dc194Richard Lowe                      Dwarf_Handler errhand,
7207dc194Richard Lowe                      Dwarf_Ptr errarg, Dwarf_Error * error)
7349d3bc9Richard Lowe{
7449d3bc9Richard Lowe    Dwarf_P_Debug dbg;
7549d3bc9Richard Lowe    dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
7607dc194Richard Lowe                                             sizeof(struct
7707dc194Richard Lowe                                                    Dwarf_P_Debug_s));
7849d3bc9Richard Lowe    if (dbg == NULL) {
7907dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
8007dc194Richard Lowe                          (Dwarf_P_Debug) DW_DLV_BADADDR);
8149d3bc9Richard Lowe    }
8207dc194Richard Lowe    memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
8349d3bc9Richard Lowe    /* For the time being */
8449d3bc9Richard Lowe    if (func == NULL) {
8507dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
8607dc194Richard Lowe                          (Dwarf_P_Debug) DW_DLV_BADADDR);
8749d3bc9Richard Lowe    }
8807dc194Richard Lowe    dbg->de_callback_func_b = func;
8949d3bc9Richard Lowe    dbg->de_errhand = errhand;
9049d3bc9Richard Lowe    dbg->de_errarg = errarg;
9149d3bc9Richard Lowe    common_init(dbg, flags);
9249d3bc9Richard Lowe    return dbg;
9349d3bc9Richard Lowe
9449d3bc9Richard Lowe}
9549d3bc9Richard Lowe
9649d3bc9Richard LoweDwarf_P_Debug
9749d3bc9Richard Lowedwarf_producer_init(Dwarf_Unsigned flags,
9807dc194Richard Lowe                    Dwarf_Callback_Func func,
9907dc194Richard Lowe                    Dwarf_Handler errhand,
10007dc194Richard Lowe                    Dwarf_Ptr errarg, Dwarf_Error * error)
10149d3bc9Richard Lowe{
10249d3bc9Richard Lowe
10349d3bc9Richard Lowe    Dwarf_P_Debug dbg;
10449d3bc9Richard Lowe
10549d3bc9Richard Lowe
10649d3bc9Richard Lowe
10749d3bc9Richard Lowe    dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
10807dc194Richard Lowe                                             sizeof(struct
10907dc194Richard Lowe                                                    Dwarf_P_Debug_s));
11049d3bc9Richard Lowe    if (dbg == NULL) {
11107dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
11207dc194Richard Lowe                          (Dwarf_P_Debug) DW_DLV_BADADDR);
11349d3bc9Richard Lowe    }
11407dc194Richard Lowe    memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
11549d3bc9Richard Lowe    /* For the time being */
11649d3bc9Richard Lowe    if (func == NULL) {
11707dc194Richard Lowe        DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
11807dc194Richard Lowe                          (Dwarf_P_Debug) DW_DLV_BADADDR);
11949d3bc9Richard Lowe    }
12007dc194Richard Lowe    dbg->de_callback_func = func;
12149d3bc9Richard Lowe    dbg->de_errhand = errhand;
12249d3bc9Richard Lowe    dbg->de_errarg = errarg;
12349d3bc9Richard Lowe    common_init(dbg, flags);
12449d3bc9Richard Lowe    return dbg;
12549d3bc9Richard Lowe}
12649d3bc9Richard Lowestatic void
12749d3bc9Richard Lowecommon_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags)
12849d3bc9Richard Lowe{
12949d3bc9Richard Lowe    unsigned int k;
13049d3bc9Richard Lowe
13149d3bc9Richard Lowe
13249d3bc9Richard Lowe    dbg->de_version_magic_number = PRO_VERSION_MAGIC;
13349d3bc9Richard Lowe    dbg->de_n_debug_sect = 0;
13449d3bc9Richard Lowe    dbg->de_debug_sects = &init_sect;
13549d3bc9Richard Lowe    dbg->de_current_active_section = &init_sect;
13649d3bc9Richard Lowe    dbg->de_flags = flags;
13749d3bc9Richard Lowe
13849d3bc9Richard Lowe    /* Now, with flags set, can use 64bit tests */
13949d3bc9Richard Lowe
14049d3bc9Richard Lowe
14149d3bc9Richard Lowe
14207dc194Richard Lowe#if defined(HAVE_STRICT_DWARF2_32BIT_OFFSET)
14307dc194Richard Lowe    /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0.
14407dc194Richard Lowe       It is consistent with normal DWARF2/3 generation of always
14507dc194Richard Lowe       generating 32 bit offsets. */
14649d3bc9Richard Lowe    dbg->de_64bit_extension = 0;
14749d3bc9Richard Lowe    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
14849d3bc9Richard Lowe    dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4);
14949d3bc9Richard Lowe    dbg->de_ptr_reloc =
15007dc194Richard Lowe        IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
15149d3bc9Richard Lowe    /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
15249d3bc9Richard Lowe       pointer environments. */
15349d3bc9Richard Lowe    /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure
15449d3bc9Richard Lowe       dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And
15549d3bc9Richard Lowe       pure 32 bit offset dwarf for 32bit pointer apps. */
15649d3bc9Richard Lowe
15749d3bc9Richard Lowe    dbg->de_offset_reloc = Get_REL32_isa(dbg);
15807dc194Richard Lowe#elif defined(HAVE_SGI_IRIX_OFFSETS)
15907dc194Richard Lowe    /* MIPS-SGI-IRIX 32 or 64, where offsets and lengths are both 64 bit for
16007dc194Richard Lowe       64bit pointer objects and both 32 bit for 32bit pointer objects.
16107dc194Richard Lowe       And a dwarf-reader must check elf info to tell which applies. */
16249d3bc9Richard Lowe    dbg->de_64bit_extension = 0;
16349d3bc9Richard Lowe    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
16449d3bc9Richard Lowe    dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
16549d3bc9Richard Lowe    dbg->de_ptr_reloc =
16607dc194Richard Lowe        IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
16749d3bc9Richard Lowe    dbg->de_offset_reloc = dbg->de_ptr_reloc;
16807dc194Richard Lowe#else /* HAVE_DWARF2_99_EXTENSION or default. */
16907dc194Richard Lowe    /* Revised 64 bit output, using distingushed values. Per 1999
17007dc194Richard Lowe       dwarf3.  This allows run-time selection of offset size.  */
17107dc194Richard Lowe    dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0);
17207dc194Richard Lowe    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
17307dc194Richard Lowe    if( flags & DW_DLC_OFFSET_SIZE_64 && (dbg->de_pointer_size == 8)) {
17407dc194Richard Lowe        /* When it's 64 bit address, a 64bit offset is sensible.
17507dc194Richard Lowe           Arguably a 32 bit address with 64 bit offset could be
17607dc194Richard Lowe           sensible, but who would want that? */
17707dc194Richard Lowe        dbg->de_offset_size = 8;
17807dc194Richard Lowe        dbg->de_64bit_extension = 1;
17907dc194Richard Lowe    }  else {
18007dc194Richard Lowe        dbg->de_offset_size = 4;
18107dc194Richard Lowe        dbg->de_64bit_extension = 0;
18207dc194Richard Lowe    }
18307dc194Richard Lowe    dbg->de_ptr_reloc =
18407dc194Richard Lowe        IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
18507dc194Richard Lowe    /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
18607dc194Richard Lowe       pointer environments. */
18707dc194Richard Lowe    /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we
18807dc194Richard Lowe       emit the extension bytes. */
18907dc194Richard Lowe
19007dc194Richard Lowe    dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg)
19107dc194Richard Lowe        : Get_REL32_isa(dbg);
19207dc194Richard Lowe#endif /*  HAVE_DWARF2_99_EXTENSION etc. */
19307dc194Richard Lowe
19449d3bc9Richard Lowe    dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg);
19549d3bc9Richard Lowe
19649d3bc9Richard Lowe    dbg->de_is_64bit = IS_64BIT(dbg);
19749d3bc9Richard Lowe
19849d3bc9Richard Lowe
19949d3bc9Richard Lowe    if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
20007dc194Richard Lowe        dbg->de_relocation_record_size =
20107dc194Richard Lowe            sizeof(struct Dwarf_Relocation_Data_s);
20249d3bc9Richard Lowe    } else {
20307dc194Richard Lowe
20449d3bc9Richard Lowe#if HAVE_ELF64_GETEHDR
20507dc194Richard Lowe        dbg->de_relocation_record_size =
20607dc194Richard Lowe            IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32);
20749d3bc9Richard Lowe#else
20807dc194Richard Lowe        dbg->de_relocation_record_size = sizeof(REL32);
20949d3bc9Richard Lowe#endif
21007dc194Richard Lowe
21149d3bc9Richard Lowe    }
21249d3bc9Richard Lowe
21349d3bc9Richard Lowe    if (dbg->de_offset_size == 8) {
21407dc194Richard Lowe        dbg->de_ar_data_attribute_form = DW_FORM_data8;
21507dc194Richard Lowe        dbg->de_ar_ref_attr_form = DW_FORM_ref8;
21649d3bc9Richard Lowe    } else {
21707dc194Richard Lowe        dbg->de_ar_data_attribute_form = DW_FORM_data4;
21807dc194Richard Lowe        dbg->de_ar_ref_attr_form = DW_FORM_ref4;
21949d3bc9Richard Lowe    }
22049d3bc9Richard Lowe
22149d3bc9Richard Lowe    if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
22207dc194Richard Lowe        dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic;
22307dc194Richard Lowe        dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic;
22407dc194Richard Lowe        dbg->de_transform_relocs_to_disk =
22507dc194Richard Lowe            _dwarf_symbolic_relocs_to_disk;
22649d3bc9Richard Lowe    } else {
22707dc194Richard Lowe        if (IS_64BIT(dbg)) {
22807dc194Richard Lowe            dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64;
22907dc194Richard Lowe        } else {
23007dc194Richard Lowe            dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32;
23107dc194Richard Lowe        }
23207dc194Richard Lowe        dbg->de_reloc_pair = 0;
23307dc194Richard Lowe        dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk;
23449d3bc9Richard Lowe    }
23549d3bc9Richard Lowe    for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) {
23649d3bc9Richard Lowe
23707dc194Richard Lowe        Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k];
23849d3bc9Richard Lowe
23907dc194Richard Lowe        prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK;
24049d3bc9Richard Lowe    }
24149d3bc9Richard Lowe    /* First assume host, target same endianness */
24249d3bc9Richard Lowe    dbg->de_same_endian = 1;
24349d3bc9Richard Lowe    dbg->de_copy_word = memcpy;
24449d3bc9Richard Lowe#ifdef WORDS_BIGENDIAN
24549d3bc9Richard Lowe    /* host is big endian, so what endian is target? */
24649d3bc9Richard Lowe    if (flags & DW_DLC_TARGET_LITTLEENDIAN) {
24707dc194Richard Lowe        dbg->de_same_endian = 0;
24807dc194Richard Lowe        dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
24949d3bc9Richard Lowe    }
25049d3bc9Richard Lowe#else /* little endian */
25149d3bc9Richard Lowe    /* host is little endian, so what endian is target? */
25249d3bc9Richard Lowe    if (flags & DW_DLC_TARGET_BIGENDIAN) {
25307dc194Richard Lowe        dbg->de_same_endian = 0;
25407dc194Richard Lowe        dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
25549d3bc9Richard Lowe    }
25649d3bc9Richard Lowe#endif /* !WORDS_BIGENDIAN */
25749d3bc9Richard Lowe
25849d3bc9Richard Lowe
25949d3bc9Richard Lowe    return;
26049d3bc9Richard Lowe
26149d3bc9Richard Lowe}