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