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