xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_arange.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi 
3bc1f688bSRobert Mustacchi   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2011-2019 David Anderson.  All Rights Reserved.
5bc1f688bSRobert Mustacchi 
6bc1f688bSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7bc1f688bSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8bc1f688bSRobert Mustacchi   as published by the Free Software Foundation.
9bc1f688bSRobert Mustacchi 
10bc1f688bSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11bc1f688bSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12bc1f688bSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13bc1f688bSRobert Mustacchi 
14bc1f688bSRobert Mustacchi   Further, this software is distributed without any warranty that it is
15bc1f688bSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16bc1f688bSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17bc1f688bSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18bc1f688bSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19bc1f688bSRobert Mustacchi   other software, or any other product whatsoever.
20bc1f688bSRobert Mustacchi 
21bc1f688bSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22bc1f688bSRobert Mustacchi   License along with this program; if not, write the Free Software
23bc1f688bSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24bc1f688bSRobert Mustacchi   USA.
25bc1f688bSRobert Mustacchi 
26bc1f688bSRobert Mustacchi */
27bc1f688bSRobert Mustacchi 
28bc1f688bSRobert Mustacchi #include "config.h"
29bc1f688bSRobert Mustacchi #include "libdwarfdefs.h"
30bc1f688bSRobert Mustacchi #include <stdio.h>
31bc1f688bSRobert Mustacchi #include <string.h>
32bc1f688bSRobert Mustacchi #ifdef HAVE_ELFACCESS_H
33bc1f688bSRobert Mustacchi #include <elfaccess.h>
34bc1f688bSRobert Mustacchi #endif
35bc1f688bSRobert Mustacchi #include "pro_incl.h"
36*4d9fdb46SRobert Mustacchi #include <stddef.h>
37*4d9fdb46SRobert Mustacchi #include "dwarf.h"
38*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
39*4d9fdb46SRobert Mustacchi #include "pro_opaque.h"
40*4d9fdb46SRobert Mustacchi #include "pro_error.h"
41*4d9fdb46SRobert Mustacchi #include "pro_alloc.h"
42bc1f688bSRobert Mustacchi #include "pro_arange.h"
43bc1f688bSRobert Mustacchi #include "pro_section.h"
44bc1f688bSRobert Mustacchi #include "pro_reloc.h"
45bc1f688bSRobert Mustacchi 
46bc1f688bSRobert Mustacchi 
47*4d9fdb46SRobert Mustacchi #define SIZEOFT32 4
48bc1f688bSRobert Mustacchi 
49*4d9fdb46SRobert Mustacchi /*  This function adds another address range
50bc1f688bSRobert Mustacchi     to the list of address ranges for the
51bc1f688bSRobert Mustacchi     given Dwarf_P_Debug.  It returns 0 on error,
52*4d9fdb46SRobert Mustacchi     and 1 otherwise.  */
53bc1f688bSRobert Mustacchi Dwarf_Unsigned
dwarf_add_arange(Dwarf_P_Debug dbg,Dwarf_Addr begin_address,Dwarf_Unsigned length,Dwarf_Signed symbol_index,Dwarf_Error * error)54bc1f688bSRobert Mustacchi dwarf_add_arange(Dwarf_P_Debug dbg,
55bc1f688bSRobert Mustacchi     Dwarf_Addr begin_address,
56bc1f688bSRobert Mustacchi     Dwarf_Unsigned length,
57bc1f688bSRobert Mustacchi     Dwarf_Signed symbol_index, Dwarf_Error * error)
58bc1f688bSRobert Mustacchi {
59*4d9fdb46SRobert Mustacchi     int res = 0;
60*4d9fdb46SRobert Mustacchi 
61*4d9fdb46SRobert Mustacchi     res = dwarf_add_arange_b(dbg, begin_address, length, symbol_index,
62bc1f688bSRobert Mustacchi         /* end_symbol_index */ 0,
63bc1f688bSRobert Mustacchi         /* offset_from_end_sym */ 0,
64bc1f688bSRobert Mustacchi         error);
65*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
66*4d9fdb46SRobert Mustacchi         return 0;
67*4d9fdb46SRobert Mustacchi     }
68*4d9fdb46SRobert Mustacchi     return 1;
69*4d9fdb46SRobert Mustacchi 
70bc1f688bSRobert Mustacchi }
71bc1f688bSRobert Mustacchi 
72*4d9fdb46SRobert Mustacchi /*  This function adds another address range
73bc1f688bSRobert Mustacchi     to the list of address ranges for the
74*4d9fdb46SRobert Mustacchi     given Dwarf_P_Debug.  It returns DW_DLV_ERROR on error,
75*4d9fdb46SRobert Mustacchi     and DW_DLV_OK otherwise.  */
76bc1f688bSRobert Mustacchi Dwarf_Unsigned
dwarf_add_arange_b(Dwarf_P_Debug dbg,Dwarf_Addr begin_address,Dwarf_Unsigned length,Dwarf_Unsigned symbol_index,Dwarf_Unsigned end_symbol_index,Dwarf_Addr offset_from_end_sym,Dwarf_Error * error)77bc1f688bSRobert Mustacchi dwarf_add_arange_b(Dwarf_P_Debug dbg,
78bc1f688bSRobert Mustacchi     Dwarf_Addr begin_address,
79bc1f688bSRobert Mustacchi     Dwarf_Unsigned length,
80bc1f688bSRobert Mustacchi     Dwarf_Unsigned symbol_index,
81bc1f688bSRobert Mustacchi     Dwarf_Unsigned end_symbol_index,
82*4d9fdb46SRobert Mustacchi     Dwarf_Addr offset_from_end_sym,
83*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
84*4d9fdb46SRobert Mustacchi {
85*4d9fdb46SRobert Mustacchi     int res = 0;
86*4d9fdb46SRobert Mustacchi 
87*4d9fdb46SRobert Mustacchi     res = dwarf_add_arange_c(dbg,begin_address,length,
88*4d9fdb46SRobert Mustacchi         symbol_index, end_symbol_index,
89*4d9fdb46SRobert Mustacchi         offset_from_end_sym,error);
90*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
91*4d9fdb46SRobert Mustacchi         return 0;
92*4d9fdb46SRobert Mustacchi     }
93*4d9fdb46SRobert Mustacchi     return 1;
94*4d9fdb46SRobert Mustacchi }
95*4d9fdb46SRobert Mustacchi int
dwarf_add_arange_c(Dwarf_P_Debug dbg,Dwarf_Addr begin_address,Dwarf_Unsigned length,Dwarf_Unsigned symbol_index,Dwarf_Unsigned end_symbol_index,Dwarf_Addr offset_from_end_sym,Dwarf_Error * error)96*4d9fdb46SRobert Mustacchi dwarf_add_arange_c(Dwarf_P_Debug dbg,
97*4d9fdb46SRobert Mustacchi     Dwarf_Addr begin_address,
98*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned length,
99*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned symbol_index,
100*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned end_symbol_index,
101*4d9fdb46SRobert Mustacchi     Dwarf_Addr offset_from_end_sym,
102*4d9fdb46SRobert Mustacchi     Dwarf_Error * error)
103bc1f688bSRobert Mustacchi {
104bc1f688bSRobert Mustacchi     Dwarf_P_Arange arange;
105bc1f688bSRobert Mustacchi 
106bc1f688bSRobert Mustacchi     if (dbg == NULL) {
107bc1f688bSRobert Mustacchi         _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
108*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
109bc1f688bSRobert Mustacchi     }
110bc1f688bSRobert Mustacchi 
111bc1f688bSRobert Mustacchi     arange = (Dwarf_P_Arange)
112bc1f688bSRobert Mustacchi         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s));
113bc1f688bSRobert Mustacchi     if (arange == NULL) {
114bc1f688bSRobert Mustacchi         _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
115*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
116bc1f688bSRobert Mustacchi     }
117bc1f688bSRobert Mustacchi 
118bc1f688bSRobert Mustacchi     arange->ag_begin_address = begin_address;
119bc1f688bSRobert Mustacchi     arange->ag_length = length;
120bc1f688bSRobert Mustacchi     arange->ag_symbol_index = symbol_index;
121bc1f688bSRobert Mustacchi     arange->ag_end_symbol_index = end_symbol_index;
122bc1f688bSRobert Mustacchi     arange->ag_end_symbol_offset = offset_from_end_sym;
123bc1f688bSRobert Mustacchi 
124bc1f688bSRobert Mustacchi     if (dbg->de_arange == NULL)
125bc1f688bSRobert Mustacchi         dbg->de_arange = dbg->de_last_arange = arange;
126bc1f688bSRobert Mustacchi     else {
127bc1f688bSRobert Mustacchi         dbg->de_last_arange->ag_next = arange;
128bc1f688bSRobert Mustacchi         dbg->de_last_arange = arange;
129bc1f688bSRobert Mustacchi     }
130bc1f688bSRobert Mustacchi     dbg->de_arange_count++;
131*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
132bc1f688bSRobert Mustacchi }
133bc1f688bSRobert Mustacchi 
134bc1f688bSRobert Mustacchi 
135bc1f688bSRobert Mustacchi int
_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg,Dwarf_Signed * nbufs,Dwarf_Error * error)136*4d9fdb46SRobert Mustacchi _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg,
137*4d9fdb46SRobert Mustacchi     Dwarf_Signed *nbufs, Dwarf_Error * error)
138bc1f688bSRobert Mustacchi {
139bc1f688bSRobert Mustacchi     /* Total num of bytes in .debug_aranges section. */
140*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned arange_num_bytes = 0;
141bc1f688bSRobert Mustacchi 
142*4d9fdb46SRobert Mustacchi     /*  Adjustment to align the start of the actual address ranges on a
143bc1f688bSRobert Mustacchi         boundary aligned with twice the address size. */
144*4d9fdb46SRobert Mustacchi     Dwarf_Small remainder = 0;
145bc1f688bSRobert Mustacchi 
146bc1f688bSRobert Mustacchi     /*  Total number of bytes excluding the length field. */
147*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned adjusted_length = 0;
148bc1f688bSRobert Mustacchi 
149bc1f688bSRobert Mustacchi     /*  Points to first byte of .debug_aranges buffer. */
150*4d9fdb46SRobert Mustacchi     Dwarf_Small *arange = 0;
151bc1f688bSRobert Mustacchi 
152bc1f688bSRobert Mustacchi     /*  Fills in the .debug_aranges buffer. */
153*4d9fdb46SRobert Mustacchi     Dwarf_Small *arange_ptr = 0;
154bc1f688bSRobert Mustacchi 
155bc1f688bSRobert Mustacchi     /*  Scans the list of address ranges provided by user. */
156*4d9fdb46SRobert Mustacchi     Dwarf_P_Arange given_arange = 0;
157bc1f688bSRobert Mustacchi 
158bc1f688bSRobert Mustacchi     /*  Used to fill in 0. */
159bc1f688bSRobert Mustacchi     const Dwarf_Signed big_zero = 0;
160bc1f688bSRobert Mustacchi 
161bc1f688bSRobert Mustacchi     int extension_word_size = dbg->de_64bit_extension ? 4 : 0;
162*4d9fdb46SRobert Mustacchi     int offset_size = dbg->de_dwarf_offset_size;
163bc1f688bSRobert Mustacchi     int upointer_size = dbg->de_pointer_size;
164*4d9fdb46SRobert Mustacchi 
165*4d9fdb46SRobert Mustacchi     /*  All dwarf versions so far use 2 here. */
166*4d9fdb46SRobert Mustacchi     Dwarf_Half version = 2;
167*4d9fdb46SRobert Mustacchi     int res = 0;
168bc1f688bSRobert Mustacchi 
169bc1f688bSRobert Mustacchi 
170bc1f688bSRobert Mustacchi     /* ***** BEGIN CODE ***** */
171bc1f688bSRobert Mustacchi 
172bc1f688bSRobert Mustacchi     /* Size of the .debug_aranges section header. */
173*4d9fdb46SRobert Mustacchi     arange_num_bytes = extension_word_size +
174*4d9fdb46SRobert Mustacchi         offset_size +       /* Size of length field.  */
175*4d9fdb46SRobert Mustacchi         DWARF_HALF_SIZE +    /* Size of version field. */
176*4d9fdb46SRobert Mustacchi         offset_size +            /* Size of .debug_info offset. */
177bc1f688bSRobert Mustacchi         sizeof(Dwarf_Small) +   /* Size of address size field. */
178bc1f688bSRobert Mustacchi         sizeof(Dwarf_Small);    /* Size of segment size field. */
179bc1f688bSRobert Mustacchi 
180*4d9fdb46SRobert Mustacchi     /*  Adjust the size so that the set of aranges begins on a boundary
181bc1f688bSRobert Mustacchi         that aligned with twice the address size.  This is a Libdwarf
182bc1f688bSRobert Mustacchi         requirement. */
183bc1f688bSRobert Mustacchi     remainder = arange_num_bytes % (2 * upointer_size);
184bc1f688bSRobert Mustacchi     if (remainder != 0)
185bc1f688bSRobert Mustacchi         arange_num_bytes += (2 * upointer_size) - remainder;
186bc1f688bSRobert Mustacchi 
187bc1f688bSRobert Mustacchi 
188bc1f688bSRobert Mustacchi     /* Add the bytes for the actual address ranges. */
189bc1f688bSRobert Mustacchi     arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1);
190bc1f688bSRobert Mustacchi 
191bc1f688bSRobert Mustacchi     GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES],
192bc1f688bSRobert Mustacchi         arange, (unsigned long) arange_num_bytes, error);
193bc1f688bSRobert Mustacchi     arange_ptr = arange;
194bc1f688bSRobert Mustacchi     if (extension_word_size) {
195*4d9fdb46SRobert Mustacchi         DISTINGUISHED_VALUE_ARRAY(v4);
196bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) arange_ptr,
197*4d9fdb46SRobert Mustacchi             (const void *)&v4[0] ,
198*4d9fdb46SRobert Mustacchi             SIZEOFT32, extension_word_size);
199bc1f688bSRobert Mustacchi         arange_ptr += extension_word_size;
200bc1f688bSRobert Mustacchi     }
201bc1f688bSRobert Mustacchi 
202bc1f688bSRobert Mustacchi     /* Write the total length of .debug_aranges section. */
203*4d9fdb46SRobert Mustacchi     adjusted_length = arange_num_bytes - offset_size
204bc1f688bSRobert Mustacchi         - extension_word_size;
205bc1f688bSRobert Mustacchi     {
206bc1f688bSRobert Mustacchi         Dwarf_Unsigned du = adjusted_length;
207bc1f688bSRobert Mustacchi 
208bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) arange_ptr,
209*4d9fdb46SRobert Mustacchi             (const void *) &du, sizeof(du), offset_size);
210*4d9fdb46SRobert Mustacchi         arange_ptr += offset_size;
211bc1f688bSRobert Mustacchi     }
212bc1f688bSRobert Mustacchi 
213bc1f688bSRobert Mustacchi     /* Write the version as 2 bytes. */
214bc1f688bSRobert Mustacchi     {
215*4d9fdb46SRobert Mustacchi         Dwarf_Half verstamp = version;
216bc1f688bSRobert Mustacchi 
217bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) arange_ptr,
218bc1f688bSRobert Mustacchi             (const void *) &verstamp,
219*4d9fdb46SRobert Mustacchi             sizeof(verstamp), DWARF_HALF_SIZE);
220*4d9fdb46SRobert Mustacchi         arange_ptr += DWARF_HALF_SIZE;
221bc1f688bSRobert Mustacchi     }
222bc1f688bSRobert Mustacchi 
223bc1f688bSRobert Mustacchi 
224bc1f688bSRobert Mustacchi     /* Write the .debug_info offset.  This is always 0. */
225bc1f688bSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) arange_ptr,
226bc1f688bSRobert Mustacchi         (const void *) &big_zero,
227*4d9fdb46SRobert Mustacchi         sizeof(big_zero), offset_size);
228*4d9fdb46SRobert Mustacchi     arange_ptr += offset_size;
229bc1f688bSRobert Mustacchi 
230bc1f688bSRobert Mustacchi     {
231bc1f688bSRobert Mustacchi         unsigned long count = dbg->de_arange_count + 1;
232*4d9fdb46SRobert Mustacchi         int res2 = 0;
233*4d9fdb46SRobert Mustacchi         Dwarf_P_Per_Reloc_Sect p_reloc =
234*4d9fdb46SRobert Mustacchi             &dbg->de_reloc_sect[DEBUG_ARANGES];
235bc1f688bSRobert Mustacchi 
236*4d9fdb46SRobert Mustacchi         if (dbg->de_relocate_pair_by_symbol) {
237bc1f688bSRobert Mustacchi             count = (3 * dbg->de_arange_count) + 1;
238bc1f688bSRobert Mustacchi         }
239*4d9fdb46SRobert Mustacchi         /*  The following is a small optimization: not needed for
240*4d9fdb46SRobert Mustacchi             correctness.  Does nothing if
241*4d9fdb46SRobert Mustacchi             preloc->pr_first_block is non-null */
242*4d9fdb46SRobert Mustacchi         res2 = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg,
243*4d9fdb46SRobert Mustacchi             p_reloc, count);
244*4d9fdb46SRobert Mustacchi         if (res2 != DW_DLV_OK) {
245bc1f688bSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
246*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
247bc1f688bSRobert Mustacchi         }
248bc1f688bSRobert Mustacchi     }
249bc1f688bSRobert Mustacchi 
250bc1f688bSRobert Mustacchi     /* reloc for .debug_info */
251*4d9fdb46SRobert Mustacchi     res = dbg->de_relocate_by_name_symbol(dbg,
252bc1f688bSRobert Mustacchi         DEBUG_ARANGES,
253bc1f688bSRobert Mustacchi         extension_word_size +
254*4d9fdb46SRobert Mustacchi         offset_size + DWARF_HALF_SIZE,
255bc1f688bSRobert Mustacchi         dbg->de_sect_name_idx[DEBUG_INFO],
256*4d9fdb46SRobert Mustacchi         dwarf_drt_data_reloc, offset_size);
257*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY) {
258*4d9fdb46SRobert Mustacchi         return res;
259*4d9fdb46SRobert Mustacchi     }
260*4d9fdb46SRobert Mustacchi     if (res == DW_DLV_ERROR) {
261*4d9fdb46SRobert Mustacchi         _dwarf_p_error(dbg, error,DW_DLE_RELOCS_ERROR);
262*4d9fdb46SRobert Mustacchi         return res;
263*4d9fdb46SRobert Mustacchi     }
264bc1f688bSRobert Mustacchi 
265bc1f688bSRobert Mustacchi     /* Write the size of addresses. */
266bc1f688bSRobert Mustacchi     *arange_ptr = dbg->de_pointer_size;
267bc1f688bSRobert Mustacchi     arange_ptr++;
268bc1f688bSRobert Mustacchi 
269*4d9fdb46SRobert Mustacchi     /*  Write the size of segment addresses. This is zero for MIPS
270bc1f688bSRobert Mustacchi         architectures. */
271bc1f688bSRobert Mustacchi     *arange_ptr = 0;
272bc1f688bSRobert Mustacchi     arange_ptr++;
273bc1f688bSRobert Mustacchi 
274*4d9fdb46SRobert Mustacchi     /*  Skip over the padding to align the start of the actual address
275bc1f688bSRobert Mustacchi         ranges to twice the address size. */
276bc1f688bSRobert Mustacchi     if (remainder != 0)
277bc1f688bSRobert Mustacchi         arange_ptr += (2 * upointer_size) - remainder;
278bc1f688bSRobert Mustacchi 
279bc1f688bSRobert Mustacchi 
280bc1f688bSRobert Mustacchi 
281bc1f688bSRobert Mustacchi 
282bc1f688bSRobert Mustacchi 
283bc1f688bSRobert Mustacchi     /*  The arange address, length are pointer-size fields of the target
284bc1f688bSRobert Mustacchi         machine. */
285bc1f688bSRobert Mustacchi     for (given_arange = dbg->de_arange; given_arange != NULL;
286bc1f688bSRobert Mustacchi         given_arange = given_arange->ag_next) {
287bc1f688bSRobert Mustacchi 
288bc1f688bSRobert Mustacchi         /* Write relocation record for beginning of address range. */
289*4d9fdb46SRobert Mustacchi         res = dbg->de_relocate_by_name_symbol(dbg, DEBUG_ARANGES,
290*4d9fdb46SRobert Mustacchi             arange_ptr - arange,       /* r_offset */
291bc1f688bSRobert Mustacchi             (long) given_arange->ag_symbol_index,
292bc1f688bSRobert Mustacchi             dwarf_drt_data_reloc, upointer_size);
293bc1f688bSRobert Mustacchi         if (res != DW_DLV_OK) {
294bc1f688bSRobert Mustacchi             _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
295*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
296bc1f688bSRobert Mustacchi         }
297bc1f688bSRobert Mustacchi 
298bc1f688bSRobert Mustacchi         /* Copy beginning address of range. */
299bc1f688bSRobert Mustacchi         WRITE_UNALIGNED(dbg, (void *) arange_ptr,
300bc1f688bSRobert Mustacchi             (const void *) &given_arange->ag_begin_address,
301bc1f688bSRobert Mustacchi             sizeof(given_arange->ag_begin_address),
302bc1f688bSRobert Mustacchi             upointer_size);
303bc1f688bSRobert Mustacchi         arange_ptr += upointer_size;
304bc1f688bSRobert Mustacchi 
305*4d9fdb46SRobert Mustacchi         if (dbg->de_relocate_pair_by_symbol &&
306bc1f688bSRobert Mustacchi             given_arange->ag_end_symbol_index != 0 &&
307bc1f688bSRobert Mustacchi             given_arange->ag_length == 0) {
308bc1f688bSRobert Mustacchi             /*  symbolic reloc, need reloc for length What if we really
309bc1f688bSRobert Mustacchi                 know the length? If so, should use the other part of
310bc1f688bSRobert Mustacchi                 'if'. */
311bc1f688bSRobert Mustacchi             Dwarf_Unsigned val;
312bc1f688bSRobert Mustacchi 
313*4d9fdb46SRobert Mustacchi             res = dbg->de_relocate_pair_by_symbol(dbg,
314*4d9fdb46SRobert Mustacchi                 DEBUG_ARANGES,
315*4d9fdb46SRobert Mustacchi                 arange_ptr - arange,   /* r_offset */
316bc1f688bSRobert Mustacchi                 given_arange->ag_symbol_index,
317bc1f688bSRobert Mustacchi                 given_arange->ag_end_symbol_index,
318bc1f688bSRobert Mustacchi                 dwarf_drt_first_of_length_pair,
319bc1f688bSRobert Mustacchi                 upointer_size);
320bc1f688bSRobert Mustacchi             if (res != DW_DLV_OK) {
321bc1f688bSRobert Mustacchi                 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
322*4d9fdb46SRobert Mustacchi                 return DW_DLV_ERROR;
323bc1f688bSRobert Mustacchi             }
324bc1f688bSRobert Mustacchi 
325*4d9fdb46SRobert Mustacchi             /*  arange pre-calc so assem text can do .word end - begin
326bc1f688bSRobert Mustacchi                 + val (gets val from stream) */
327bc1f688bSRobert Mustacchi             val = given_arange->ag_end_symbol_offset -
328bc1f688bSRobert Mustacchi                 given_arange->ag_begin_address;
329bc1f688bSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) arange_ptr,
330bc1f688bSRobert Mustacchi                 (const void *) &val,
331bc1f688bSRobert Mustacchi                 sizeof(val), upointer_size);
332bc1f688bSRobert Mustacchi             arange_ptr += upointer_size;
333bc1f688bSRobert Mustacchi 
334bc1f688bSRobert Mustacchi         } else {
335bc1f688bSRobert Mustacchi             /* plain old length to copy, no relocation at all */
336bc1f688bSRobert Mustacchi             WRITE_UNALIGNED(dbg, (void *) arange_ptr,
337bc1f688bSRobert Mustacchi                 (const void *) &given_arange->ag_length,
338bc1f688bSRobert Mustacchi                 sizeof(given_arange->ag_length),
339bc1f688bSRobert Mustacchi                 upointer_size);
340bc1f688bSRobert Mustacchi             arange_ptr += upointer_size;
341bc1f688bSRobert Mustacchi         }
342bc1f688bSRobert Mustacchi     }
343bc1f688bSRobert Mustacchi 
344bc1f688bSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) arange_ptr,
345bc1f688bSRobert Mustacchi         (const void *) &big_zero,
346bc1f688bSRobert Mustacchi         sizeof(big_zero), upointer_size);
347bc1f688bSRobert Mustacchi 
348bc1f688bSRobert Mustacchi     arange_ptr += upointer_size;
349bc1f688bSRobert Mustacchi     WRITE_UNALIGNED(dbg, (void *) arange_ptr,
350bc1f688bSRobert Mustacchi         (const void *) &big_zero,
351bc1f688bSRobert Mustacchi         sizeof(big_zero), upointer_size);
352*4d9fdb46SRobert Mustacchi     *nbufs =  dbg->de_n_debug_sect;
353*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
354bc1f688bSRobert Mustacchi }
355