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