xref: /titanic_44/usr/src/tools/ctf/dwarf/common/pro_init.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
349d3bc91SRichard Lowe   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5*07dc1947SRichard Lowe   Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
649d3bc91SRichard Lowe 
749d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
849d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
949d3bc91SRichard Lowe   as published by the Free Software Foundation.
1049d3bc91SRichard Lowe 
1149d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1249d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1349d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1449d3bc91SRichard Lowe 
1549d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1649d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1749d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1849d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1949d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
2049d3bc91SRichard Lowe   other software, or any other product whatsoever.
2149d3bc91SRichard Lowe 
2249d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2349d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
24*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2549d3bc91SRichard Lowe   USA.
2649d3bc91SRichard Lowe 
27*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2849d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2949d3bc91SRichard Lowe 
3049d3bc91SRichard Lowe   http://www.sgi.com
3149d3bc91SRichard Lowe 
3249d3bc91SRichard Lowe   For further information regarding this notice, see:
3349d3bc91SRichard Lowe 
3449d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3549d3bc91SRichard Lowe 
3649d3bc91SRichard Lowe */
3749d3bc91SRichard Lowe 
3849d3bc91SRichard Lowe 
3949d3bc91SRichard Lowe 
4049d3bc91SRichard Lowe #include "config.h"
4149d3bc91SRichard Lowe #include "libdwarfdefs.h"
4249d3bc91SRichard Lowe #include <stdio.h>
4349d3bc91SRichard Lowe #include <string.h>
4449d3bc91SRichard Lowe #include "pro_incl.h"
4549d3bc91SRichard Lowe #include "pro_section.h"        /* for MAGIC_SECT_NO */
4649d3bc91SRichard Lowe #include "pro_reloc_symbolic.h"
4749d3bc91SRichard Lowe #include "pro_reloc_stream.h"
4849d3bc91SRichard Lowe 
4949d3bc91SRichard Lowe 
5049d3bc91SRichard Lowe static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags);
5149d3bc91SRichard Lowe 
5249d3bc91SRichard Lowe void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len);
5349d3bc91SRichard Lowe 
5449d3bc91SRichard Lowe /*--------------------------------------------------------------------
5549d3bc91SRichard Lowe         This function sets up a new dwarf producing region.
5649d3bc91SRichard Lowe         flags: Indicates type of access method, one of DW_DLC* macros
5749d3bc91SRichard Lowe         func(): Used to create a new object file, a call back function
5849d3bc91SRichard Lowe         errhand(): Error Handler provided by user
5949d3bc91SRichard Lowe         errarg: Argument to errhand()
6049d3bc91SRichard Lowe         error: returned error value
6149d3bc91SRichard Lowe --------------------------------------------------------------------*/
6249d3bc91SRichard Lowe     /* We want the following to have an elf section number that matches
6349d3bc91SRichard Lowe        'nothing' */
6449d3bc91SRichard Lowe static struct Dwarf_P_Section_Data_s init_sect = {
6549d3bc91SRichard Lowe     MAGIC_SECT_NO, 0, 0, 0, 0
6649d3bc91SRichard Lowe };
6749d3bc91SRichard Lowe 
6849d3bc91SRichard Lowe Dwarf_P_Debug
dwarf_producer_init_b(Dwarf_Unsigned flags,Dwarf_Callback_Func_b func,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Error * error)6949d3bc91SRichard Lowe dwarf_producer_init_b(Dwarf_Unsigned flags,
7049d3bc91SRichard Lowe                       Dwarf_Callback_Func_b func,
7149d3bc91SRichard Lowe                       Dwarf_Handler errhand,
7249d3bc91SRichard Lowe                       Dwarf_Ptr errarg, Dwarf_Error * error)
7349d3bc91SRichard Lowe {
7449d3bc91SRichard Lowe     Dwarf_P_Debug dbg;
7549d3bc91SRichard Lowe     dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
7649d3bc91SRichard Lowe                                              sizeof(struct
7749d3bc91SRichard Lowe                                                     Dwarf_P_Debug_s));
7849d3bc91SRichard Lowe     if (dbg == NULL) {
7949d3bc91SRichard Lowe         DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
8049d3bc91SRichard Lowe                           (Dwarf_P_Debug) DW_DLV_BADADDR);
8149d3bc91SRichard Lowe     }
8249d3bc91SRichard Lowe     memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
8349d3bc91SRichard Lowe     /* For the time being */
8449d3bc91SRichard Lowe     if (func == NULL) {
8549d3bc91SRichard Lowe         DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
8649d3bc91SRichard Lowe                           (Dwarf_P_Debug) DW_DLV_BADADDR);
8749d3bc91SRichard Lowe     }
88*07dc1947SRichard Lowe     dbg->de_callback_func_b = func;
8949d3bc91SRichard Lowe     dbg->de_errhand = errhand;
9049d3bc91SRichard Lowe     dbg->de_errarg = errarg;
9149d3bc91SRichard Lowe     common_init(dbg, flags);
9249d3bc91SRichard Lowe     return dbg;
9349d3bc91SRichard Lowe 
9449d3bc91SRichard Lowe }
9549d3bc91SRichard Lowe 
9649d3bc91SRichard Lowe Dwarf_P_Debug
dwarf_producer_init(Dwarf_Unsigned flags,Dwarf_Callback_Func func,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Error * error)9749d3bc91SRichard Lowe dwarf_producer_init(Dwarf_Unsigned flags,
9849d3bc91SRichard Lowe                     Dwarf_Callback_Func func,
9949d3bc91SRichard Lowe                     Dwarf_Handler errhand,
10049d3bc91SRichard Lowe                     Dwarf_Ptr errarg, Dwarf_Error * error)
10149d3bc91SRichard Lowe {
10249d3bc91SRichard Lowe 
10349d3bc91SRichard Lowe     Dwarf_P_Debug dbg;
10449d3bc91SRichard Lowe 
10549d3bc91SRichard Lowe 
10649d3bc91SRichard Lowe 
10749d3bc91SRichard Lowe     dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
10849d3bc91SRichard Lowe                                              sizeof(struct
10949d3bc91SRichard Lowe                                                     Dwarf_P_Debug_s));
11049d3bc91SRichard Lowe     if (dbg == NULL) {
11149d3bc91SRichard Lowe         DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
11249d3bc91SRichard Lowe                           (Dwarf_P_Debug) DW_DLV_BADADDR);
11349d3bc91SRichard Lowe     }
11449d3bc91SRichard Lowe     memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
11549d3bc91SRichard Lowe     /* For the time being */
11649d3bc91SRichard Lowe     if (func == NULL) {
11749d3bc91SRichard Lowe         DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
11849d3bc91SRichard Lowe                           (Dwarf_P_Debug) DW_DLV_BADADDR);
11949d3bc91SRichard Lowe     }
120*07dc1947SRichard Lowe     dbg->de_callback_func = func;
12149d3bc91SRichard Lowe     dbg->de_errhand = errhand;
12249d3bc91SRichard Lowe     dbg->de_errarg = errarg;
12349d3bc91SRichard Lowe     common_init(dbg, flags);
12449d3bc91SRichard Lowe     return dbg;
12549d3bc91SRichard Lowe }
12649d3bc91SRichard Lowe static void
common_init(Dwarf_P_Debug dbg,Dwarf_Unsigned flags)12749d3bc91SRichard Lowe common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags)
12849d3bc91SRichard Lowe {
12949d3bc91SRichard Lowe     unsigned int k;
13049d3bc91SRichard Lowe 
13149d3bc91SRichard Lowe 
13249d3bc91SRichard Lowe     dbg->de_version_magic_number = PRO_VERSION_MAGIC;
13349d3bc91SRichard Lowe     dbg->de_n_debug_sect = 0;
13449d3bc91SRichard Lowe     dbg->de_debug_sects = &init_sect;
13549d3bc91SRichard Lowe     dbg->de_current_active_section = &init_sect;
13649d3bc91SRichard Lowe     dbg->de_flags = flags;
13749d3bc91SRichard Lowe 
13849d3bc91SRichard Lowe     /* Now, with flags set, can use 64bit tests */
13949d3bc91SRichard Lowe 
14049d3bc91SRichard Lowe 
14149d3bc91SRichard Lowe 
142*07dc1947SRichard Lowe #if defined(HAVE_STRICT_DWARF2_32BIT_OFFSET)
143*07dc1947SRichard Lowe     /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0.
144*07dc1947SRichard Lowe        It is consistent with normal DWARF2/3 generation of always
145*07dc1947SRichard Lowe        generating 32 bit offsets. */
14649d3bc91SRichard Lowe     dbg->de_64bit_extension = 0;
14749d3bc91SRichard Lowe     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
14849d3bc91SRichard Lowe     dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4);
14949d3bc91SRichard Lowe     dbg->de_ptr_reloc =
15049d3bc91SRichard Lowe         IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
15149d3bc91SRichard Lowe     /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
15249d3bc91SRichard Lowe        pointer environments. */
15349d3bc91SRichard Lowe     /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure
15449d3bc91SRichard Lowe        dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And
15549d3bc91SRichard Lowe        pure 32 bit offset dwarf for 32bit pointer apps. */
15649d3bc91SRichard Lowe 
15749d3bc91SRichard Lowe     dbg->de_offset_reloc = Get_REL32_isa(dbg);
158*07dc1947SRichard Lowe #elif defined(HAVE_SGI_IRIX_OFFSETS)
159*07dc1947SRichard Lowe     /* MIPS-SGI-IRIX 32 or 64, where offsets and lengths are both 64 bit for
160*07dc1947SRichard Lowe        64bit pointer objects and both 32 bit for 32bit pointer objects.
161*07dc1947SRichard Lowe        And a dwarf-reader must check elf info to tell which applies. */
16249d3bc91SRichard Lowe     dbg->de_64bit_extension = 0;
16349d3bc91SRichard Lowe     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
16449d3bc91SRichard Lowe     dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
16549d3bc91SRichard Lowe     dbg->de_ptr_reloc =
16649d3bc91SRichard Lowe         IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
16749d3bc91SRichard Lowe     dbg->de_offset_reloc = dbg->de_ptr_reloc;
168*07dc1947SRichard Lowe #else /* HAVE_DWARF2_99_EXTENSION or default. */
169*07dc1947SRichard Lowe     /* Revised 64 bit output, using distingushed values. Per 1999
170*07dc1947SRichard Lowe        dwarf3.  This allows run-time selection of offset size.  */
171*07dc1947SRichard Lowe     dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0);
172*07dc1947SRichard Lowe     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
173*07dc1947SRichard Lowe     if( flags & DW_DLC_OFFSET_SIZE_64 && (dbg->de_pointer_size == 8)) {
174*07dc1947SRichard Lowe         /* When it's 64 bit address, a 64bit offset is sensible.
175*07dc1947SRichard Lowe            Arguably a 32 bit address with 64 bit offset could be
176*07dc1947SRichard Lowe            sensible, but who would want that? */
177*07dc1947SRichard Lowe         dbg->de_offset_size = 8;
178*07dc1947SRichard Lowe         dbg->de_64bit_extension = 1;
179*07dc1947SRichard Lowe     }  else {
180*07dc1947SRichard Lowe         dbg->de_offset_size = 4;
181*07dc1947SRichard Lowe         dbg->de_64bit_extension = 0;
182*07dc1947SRichard Lowe     }
183*07dc1947SRichard Lowe     dbg->de_ptr_reloc =
184*07dc1947SRichard Lowe         IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
185*07dc1947SRichard Lowe     /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
186*07dc1947SRichard Lowe        pointer environments. */
187*07dc1947SRichard Lowe     /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we
188*07dc1947SRichard Lowe        emit the extension bytes. */
189*07dc1947SRichard Lowe 
190*07dc1947SRichard Lowe     dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg)
191*07dc1947SRichard Lowe         : Get_REL32_isa(dbg);
192*07dc1947SRichard Lowe #endif /*  HAVE_DWARF2_99_EXTENSION etc. */
193*07dc1947SRichard Lowe 
19449d3bc91SRichard Lowe     dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg);
19549d3bc91SRichard Lowe 
19649d3bc91SRichard Lowe     dbg->de_is_64bit = IS_64BIT(dbg);
19749d3bc91SRichard Lowe 
19849d3bc91SRichard Lowe 
19949d3bc91SRichard Lowe     if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
20049d3bc91SRichard Lowe         dbg->de_relocation_record_size =
20149d3bc91SRichard Lowe             sizeof(struct Dwarf_Relocation_Data_s);
20249d3bc91SRichard Lowe     } else {
203*07dc1947SRichard Lowe 
20449d3bc91SRichard Lowe #if HAVE_ELF64_GETEHDR
20549d3bc91SRichard Lowe         dbg->de_relocation_record_size =
206*07dc1947SRichard Lowe             IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32);
20749d3bc91SRichard Lowe #else
208*07dc1947SRichard Lowe         dbg->de_relocation_record_size = sizeof(REL32);
20949d3bc91SRichard Lowe #endif
210*07dc1947SRichard Lowe 
21149d3bc91SRichard Lowe     }
21249d3bc91SRichard Lowe 
21349d3bc91SRichard Lowe     if (dbg->de_offset_size == 8) {
21449d3bc91SRichard Lowe         dbg->de_ar_data_attribute_form = DW_FORM_data8;
21549d3bc91SRichard Lowe         dbg->de_ar_ref_attr_form = DW_FORM_ref8;
21649d3bc91SRichard Lowe     } else {
21749d3bc91SRichard Lowe         dbg->de_ar_data_attribute_form = DW_FORM_data4;
21849d3bc91SRichard Lowe         dbg->de_ar_ref_attr_form = DW_FORM_ref4;
21949d3bc91SRichard Lowe     }
22049d3bc91SRichard Lowe 
22149d3bc91SRichard Lowe     if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
22249d3bc91SRichard Lowe         dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic;
22349d3bc91SRichard Lowe         dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic;
22449d3bc91SRichard Lowe         dbg->de_transform_relocs_to_disk =
22549d3bc91SRichard Lowe             _dwarf_symbolic_relocs_to_disk;
22649d3bc91SRichard Lowe     } else {
22749d3bc91SRichard Lowe         if (IS_64BIT(dbg)) {
22849d3bc91SRichard Lowe             dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64;
22949d3bc91SRichard Lowe         } else {
23049d3bc91SRichard Lowe             dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32;
23149d3bc91SRichard Lowe         }
23249d3bc91SRichard Lowe         dbg->de_reloc_pair = 0;
23349d3bc91SRichard Lowe         dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk;
23449d3bc91SRichard Lowe     }
23549d3bc91SRichard Lowe     for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) {
23649d3bc91SRichard Lowe 
23749d3bc91SRichard Lowe         Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k];
23849d3bc91SRichard Lowe 
23949d3bc91SRichard Lowe         prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK;
24049d3bc91SRichard Lowe     }
24149d3bc91SRichard Lowe     /* First assume host, target same endianness */
24249d3bc91SRichard Lowe     dbg->de_same_endian = 1;
24349d3bc91SRichard Lowe     dbg->de_copy_word = memcpy;
24449d3bc91SRichard Lowe #ifdef WORDS_BIGENDIAN
24549d3bc91SRichard Lowe     /* host is big endian, so what endian is target? */
24649d3bc91SRichard Lowe     if (flags & DW_DLC_TARGET_LITTLEENDIAN) {
24749d3bc91SRichard Lowe         dbg->de_same_endian = 0;
24849d3bc91SRichard Lowe         dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
24949d3bc91SRichard Lowe     }
25049d3bc91SRichard Lowe #else /* little endian */
25149d3bc91SRichard Lowe     /* host is little endian, so what endian is target? */
25249d3bc91SRichard Lowe     if (flags & DW_DLC_TARGET_BIGENDIAN) {
25349d3bc91SRichard Lowe         dbg->de_same_endian = 0;
25449d3bc91SRichard Lowe         dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
25549d3bc91SRichard Lowe     }
25649d3bc91SRichard Lowe #endif /* !WORDS_BIGENDIAN */
25749d3bc91SRichard Lowe 
25849d3bc91SRichard Lowe 
25949d3bc91SRichard Lowe     return;
26049d3bc91SRichard Lowe 
26149d3bc91SRichard Lowe }
262