xref: /titanic_51/usr/src/lib/libdwarf/common/pro_init.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi 
3*7fd79137SRobert Mustacchi   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*7fd79137SRobert Mustacchi   Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved.
5*7fd79137SRobert Mustacchi   Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
6*7fd79137SRobert Mustacchi 
7*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
8*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
9*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
10*7fd79137SRobert Mustacchi 
11*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
12*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
13*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14*7fd79137SRobert Mustacchi 
15*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
16*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
17*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
18*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
19*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
20*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
21*7fd79137SRobert Mustacchi 
22*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
23*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
24*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25*7fd79137SRobert Mustacchi   USA.
26*7fd79137SRobert Mustacchi 
27*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
28*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
29*7fd79137SRobert Mustacchi 
30*7fd79137SRobert Mustacchi   http://www.sgi.com
31*7fd79137SRobert Mustacchi 
32*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
33*7fd79137SRobert Mustacchi 
34*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
35*7fd79137SRobert Mustacchi 
36*7fd79137SRobert Mustacchi */
37*7fd79137SRobert Mustacchi 
38*7fd79137SRobert Mustacchi 
39*7fd79137SRobert Mustacchi 
40*7fd79137SRobert Mustacchi #include "config.h"
41*7fd79137SRobert Mustacchi #include "libdwarfdefs.h"
42*7fd79137SRobert Mustacchi #include <stdio.h>
43*7fd79137SRobert Mustacchi #include <string.h>
44*7fd79137SRobert Mustacchi #include "pro_incl.h"
45*7fd79137SRobert Mustacchi #include "pro_section.h"        /* for MAGIC_SECT_NO */
46*7fd79137SRobert Mustacchi #include "pro_reloc_symbolic.h"
47*7fd79137SRobert Mustacchi #include "pro_reloc_stream.h"
48*7fd79137SRobert Mustacchi 
49*7fd79137SRobert Mustacchi 
50*7fd79137SRobert Mustacchi static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags);
51*7fd79137SRobert Mustacchi 
52*7fd79137SRobert Mustacchi void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len);
53*7fd79137SRobert Mustacchi 
54*7fd79137SRobert Mustacchi /*--------------------------------------------------------------------
55*7fd79137SRobert Mustacchi         This function sets up a new dwarf producing region.
56*7fd79137SRobert Mustacchi         flags: Indicates type of access method, one of DW_DLC* macros
57*7fd79137SRobert Mustacchi         func(): Used to create a new object file, a call back function
58*7fd79137SRobert Mustacchi         errhand(): Error Handler provided by user
59*7fd79137SRobert Mustacchi         errarg: Argument to errhand()
60*7fd79137SRobert Mustacchi         error: returned error value
61*7fd79137SRobert Mustacchi --------------------------------------------------------------------*/
62*7fd79137SRobert Mustacchi     /* We want the following to have an elf section number that matches
63*7fd79137SRobert Mustacchi        'nothing' */
64*7fd79137SRobert Mustacchi static struct Dwarf_P_Section_Data_s init_sect = {
65*7fd79137SRobert Mustacchi     MAGIC_SECT_NO, 0, 0, 0, 0
66*7fd79137SRobert Mustacchi };
67*7fd79137SRobert Mustacchi 
68*7fd79137SRobert Mustacchi Dwarf_P_Debug
69*7fd79137SRobert Mustacchi dwarf_producer_init_b(Dwarf_Unsigned flags,
70*7fd79137SRobert Mustacchi                       Dwarf_Callback_Func_b func,
71*7fd79137SRobert Mustacchi                       Dwarf_Handler errhand,
72*7fd79137SRobert Mustacchi                       Dwarf_Ptr errarg, Dwarf_Error * error)
73*7fd79137SRobert Mustacchi {
74*7fd79137SRobert Mustacchi     Dwarf_P_Debug dbg;
75*7fd79137SRobert Mustacchi     dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
76*7fd79137SRobert Mustacchi                                              sizeof(struct
77*7fd79137SRobert Mustacchi                                                     Dwarf_P_Debug_s));
78*7fd79137SRobert Mustacchi     if (dbg == NULL) {
79*7fd79137SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
80*7fd79137SRobert Mustacchi                           (Dwarf_P_Debug) DW_DLV_BADADDR);
81*7fd79137SRobert Mustacchi     }
82*7fd79137SRobert Mustacchi     memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
83*7fd79137SRobert Mustacchi     /* For the time being */
84*7fd79137SRobert Mustacchi     if (func == NULL) {
85*7fd79137SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
86*7fd79137SRobert Mustacchi                           (Dwarf_P_Debug) DW_DLV_BADADDR);
87*7fd79137SRobert Mustacchi     }
88*7fd79137SRobert Mustacchi     dbg->de_callback_func_b = func;
89*7fd79137SRobert Mustacchi     dbg->de_errhand = errhand;
90*7fd79137SRobert Mustacchi     dbg->de_errarg = errarg;
91*7fd79137SRobert Mustacchi     common_init(dbg, flags);
92*7fd79137SRobert Mustacchi     return dbg;
93*7fd79137SRobert Mustacchi 
94*7fd79137SRobert Mustacchi }
95*7fd79137SRobert Mustacchi 
96*7fd79137SRobert Mustacchi Dwarf_P_Debug
97*7fd79137SRobert Mustacchi dwarf_producer_init(Dwarf_Unsigned flags,
98*7fd79137SRobert Mustacchi                     Dwarf_Callback_Func func,
99*7fd79137SRobert Mustacchi                     Dwarf_Handler errhand,
100*7fd79137SRobert Mustacchi                     Dwarf_Ptr errarg, Dwarf_Error * error)
101*7fd79137SRobert Mustacchi {
102*7fd79137SRobert Mustacchi 
103*7fd79137SRobert Mustacchi     Dwarf_P_Debug dbg;
104*7fd79137SRobert Mustacchi 
105*7fd79137SRobert Mustacchi 
106*7fd79137SRobert Mustacchi 
107*7fd79137SRobert Mustacchi     dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
108*7fd79137SRobert Mustacchi                                              sizeof(struct
109*7fd79137SRobert Mustacchi                                                     Dwarf_P_Debug_s));
110*7fd79137SRobert Mustacchi     if (dbg == NULL) {
111*7fd79137SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
112*7fd79137SRobert Mustacchi                           (Dwarf_P_Debug) DW_DLV_BADADDR);
113*7fd79137SRobert Mustacchi     }
114*7fd79137SRobert Mustacchi     memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
115*7fd79137SRobert Mustacchi     /* For the time being */
116*7fd79137SRobert Mustacchi     if (func == NULL) {
117*7fd79137SRobert Mustacchi         DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
118*7fd79137SRobert Mustacchi                           (Dwarf_P_Debug) DW_DLV_BADADDR);
119*7fd79137SRobert Mustacchi     }
120*7fd79137SRobert Mustacchi     dbg->de_callback_func = func;
121*7fd79137SRobert Mustacchi     dbg->de_errhand = errhand;
122*7fd79137SRobert Mustacchi     dbg->de_errarg = errarg;
123*7fd79137SRobert Mustacchi     common_init(dbg, flags);
124*7fd79137SRobert Mustacchi     return dbg;
125*7fd79137SRobert Mustacchi }
126*7fd79137SRobert Mustacchi static void
127*7fd79137SRobert Mustacchi common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags)
128*7fd79137SRobert Mustacchi {
129*7fd79137SRobert Mustacchi     unsigned int k;
130*7fd79137SRobert Mustacchi 
131*7fd79137SRobert Mustacchi 
132*7fd79137SRobert Mustacchi     dbg->de_version_magic_number = PRO_VERSION_MAGIC;
133*7fd79137SRobert Mustacchi     dbg->de_n_debug_sect = 0;
134*7fd79137SRobert Mustacchi     dbg->de_debug_sects = &init_sect;
135*7fd79137SRobert Mustacchi     dbg->de_current_active_section = &init_sect;
136*7fd79137SRobert Mustacchi     dbg->de_flags = flags;
137*7fd79137SRobert Mustacchi 
138*7fd79137SRobert Mustacchi     /* Now, with flags set, can use 64bit tests */
139*7fd79137SRobert Mustacchi 
140*7fd79137SRobert Mustacchi 
141*7fd79137SRobert Mustacchi 
142*7fd79137SRobert Mustacchi #if defined(HAVE_STRICT_DWARF2_32BIT_OFFSET)
143*7fd79137SRobert Mustacchi     /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0.
144*7fd79137SRobert Mustacchi        It is consistent with normal DWARF2/3 generation of always
145*7fd79137SRobert Mustacchi        generating 32 bit offsets. */
146*7fd79137SRobert Mustacchi     dbg->de_64bit_extension = 0;
147*7fd79137SRobert Mustacchi     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
148*7fd79137SRobert Mustacchi     dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4);
149*7fd79137SRobert Mustacchi     dbg->de_ptr_reloc =
150*7fd79137SRobert Mustacchi         IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
151*7fd79137SRobert Mustacchi     /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
152*7fd79137SRobert Mustacchi        pointer environments. */
153*7fd79137SRobert Mustacchi     /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure
154*7fd79137SRobert Mustacchi        dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And
155*7fd79137SRobert Mustacchi        pure 32 bit offset dwarf for 32bit pointer apps. */
156*7fd79137SRobert Mustacchi 
157*7fd79137SRobert Mustacchi     dbg->de_offset_reloc = Get_REL32_isa(dbg);
158*7fd79137SRobert Mustacchi #elif defined(HAVE_SGI_IRIX_OFFSETS)
159*7fd79137SRobert Mustacchi     /* MIPS-SGI-IRIX 32 or 64, where offsets and lengths are both 64 bit for
160*7fd79137SRobert Mustacchi        64bit pointer objects and both 32 bit for 32bit pointer objects.
161*7fd79137SRobert Mustacchi        And a dwarf-reader must check elf info to tell which applies. */
162*7fd79137SRobert Mustacchi     dbg->de_64bit_extension = 0;
163*7fd79137SRobert Mustacchi     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
164*7fd79137SRobert Mustacchi     dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
165*7fd79137SRobert Mustacchi     dbg->de_ptr_reloc =
166*7fd79137SRobert Mustacchi         IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
167*7fd79137SRobert Mustacchi     dbg->de_offset_reloc = dbg->de_ptr_reloc;
168*7fd79137SRobert Mustacchi #else /* HAVE_DWARF2_99_EXTENSION or default. */
169*7fd79137SRobert Mustacchi     /* Revised 64 bit output, using distingushed values. Per 1999
170*7fd79137SRobert Mustacchi        dwarf3.  This allows run-time selection of offset size.  */
171*7fd79137SRobert Mustacchi     dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0);
172*7fd79137SRobert Mustacchi     dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
173*7fd79137SRobert Mustacchi     if( flags & DW_DLC_OFFSET_SIZE_64 && (dbg->de_pointer_size == 8)) {
174*7fd79137SRobert Mustacchi         /* When it's 64 bit address, a 64bit offset is sensible.
175*7fd79137SRobert Mustacchi            Arguably a 32 bit address with 64 bit offset could be
176*7fd79137SRobert Mustacchi            sensible, but who would want that? */
177*7fd79137SRobert Mustacchi         dbg->de_offset_size = 8;
178*7fd79137SRobert Mustacchi         dbg->de_64bit_extension = 1;
179*7fd79137SRobert Mustacchi     }  else {
180*7fd79137SRobert Mustacchi         dbg->de_offset_size = 4;
181*7fd79137SRobert Mustacchi         dbg->de_64bit_extension = 0;
182*7fd79137SRobert Mustacchi     }
183*7fd79137SRobert Mustacchi     dbg->de_ptr_reloc =
184*7fd79137SRobert Mustacchi         IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
185*7fd79137SRobert Mustacchi     /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
186*7fd79137SRobert Mustacchi        pointer environments. */
187*7fd79137SRobert Mustacchi     /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we
188*7fd79137SRobert Mustacchi        emit the extension bytes. */
189*7fd79137SRobert Mustacchi 
190*7fd79137SRobert Mustacchi     dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg)
191*7fd79137SRobert Mustacchi         : Get_REL32_isa(dbg);
192*7fd79137SRobert Mustacchi #endif /*  HAVE_DWARF2_99_EXTENSION etc. */
193*7fd79137SRobert Mustacchi 
194*7fd79137SRobert Mustacchi     dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg);
195*7fd79137SRobert Mustacchi 
196*7fd79137SRobert Mustacchi     dbg->de_is_64bit = IS_64BIT(dbg);
197*7fd79137SRobert Mustacchi 
198*7fd79137SRobert Mustacchi 
199*7fd79137SRobert Mustacchi     if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
200*7fd79137SRobert Mustacchi         dbg->de_relocation_record_size =
201*7fd79137SRobert Mustacchi             sizeof(struct Dwarf_Relocation_Data_s);
202*7fd79137SRobert Mustacchi     } else {
203*7fd79137SRobert Mustacchi 
204*7fd79137SRobert Mustacchi #if HAVE_ELF64_GETEHDR
205*7fd79137SRobert Mustacchi         dbg->de_relocation_record_size =
206*7fd79137SRobert Mustacchi             IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32);
207*7fd79137SRobert Mustacchi #else
208*7fd79137SRobert Mustacchi         dbg->de_relocation_record_size = sizeof(REL32);
209*7fd79137SRobert Mustacchi #endif
210*7fd79137SRobert Mustacchi 
211*7fd79137SRobert Mustacchi     }
212*7fd79137SRobert Mustacchi 
213*7fd79137SRobert Mustacchi     if (dbg->de_offset_size == 8) {
214*7fd79137SRobert Mustacchi         dbg->de_ar_data_attribute_form = DW_FORM_data8;
215*7fd79137SRobert Mustacchi         dbg->de_ar_ref_attr_form = DW_FORM_ref8;
216*7fd79137SRobert Mustacchi     } else {
217*7fd79137SRobert Mustacchi         dbg->de_ar_data_attribute_form = DW_FORM_data4;
218*7fd79137SRobert Mustacchi         dbg->de_ar_ref_attr_form = DW_FORM_ref4;
219*7fd79137SRobert Mustacchi     }
220*7fd79137SRobert Mustacchi 
221*7fd79137SRobert Mustacchi     if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
222*7fd79137SRobert Mustacchi         dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic;
223*7fd79137SRobert Mustacchi         dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic;
224*7fd79137SRobert Mustacchi         dbg->de_transform_relocs_to_disk =
225*7fd79137SRobert Mustacchi             _dwarf_symbolic_relocs_to_disk;
226*7fd79137SRobert Mustacchi     } else {
227*7fd79137SRobert Mustacchi         if (IS_64BIT(dbg)) {
228*7fd79137SRobert Mustacchi             dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64;
229*7fd79137SRobert Mustacchi         } else {
230*7fd79137SRobert Mustacchi             dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32;
231*7fd79137SRobert Mustacchi         }
232*7fd79137SRobert Mustacchi         dbg->de_reloc_pair = 0;
233*7fd79137SRobert Mustacchi         dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk;
234*7fd79137SRobert Mustacchi     }
235*7fd79137SRobert Mustacchi     for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) {
236*7fd79137SRobert Mustacchi 
237*7fd79137SRobert Mustacchi         Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k];
238*7fd79137SRobert Mustacchi 
239*7fd79137SRobert Mustacchi         prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK;
240*7fd79137SRobert Mustacchi     }
241*7fd79137SRobert Mustacchi     /* First assume host, target same endianness */
242*7fd79137SRobert Mustacchi     dbg->de_same_endian = 1;
243*7fd79137SRobert Mustacchi     dbg->de_copy_word = memcpy;
244*7fd79137SRobert Mustacchi #ifdef WORDS_BIGENDIAN
245*7fd79137SRobert Mustacchi     /* host is big endian, so what endian is target? */
246*7fd79137SRobert Mustacchi     if (flags & DW_DLC_TARGET_LITTLEENDIAN) {
247*7fd79137SRobert Mustacchi         dbg->de_same_endian = 0;
248*7fd79137SRobert Mustacchi         dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
249*7fd79137SRobert Mustacchi     }
250*7fd79137SRobert Mustacchi #else /* little endian */
251*7fd79137SRobert Mustacchi     /* host is little endian, so what endian is target? */
252*7fd79137SRobert Mustacchi     if (flags & DW_DLC_TARGET_BIGENDIAN) {
253*7fd79137SRobert Mustacchi         dbg->de_same_endian = 0;
254*7fd79137SRobert Mustacchi         dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
255*7fd79137SRobert Mustacchi     }
256*7fd79137SRobert Mustacchi #endif /* !WORDS_BIGENDIAN */
257*7fd79137SRobert Mustacchi 
258*7fd79137SRobert Mustacchi 
259*7fd79137SRobert Mustacchi     return;
260*7fd79137SRobert Mustacchi 
261*7fd79137SRobert Mustacchi }
262