1 /* $NetBSD: libdwarf_arange.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2009-2011 Kai Wang
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include "_libdwarf.h"
31 __RCSID("$NetBSD: libdwarf_arange.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32 ELFTC_VCSID("Id: libdwarf_arange.c 2070 2011-10-27 03:05:32Z jkoshy ");
35 _dwarf_arange_cleanup(Dwarf_Debug dbg
)
37 Dwarf_ArangeSet as
, tas
;
40 STAILQ_FOREACH_SAFE(as
, &dbg
->dbg_aslist
, as_next
, tas
) {
41 STAILQ_FOREACH_SAFE(ar
, &as
->as_arlist
, ar_next
, tar
) {
42 STAILQ_REMOVE(&as
->as_arlist
, ar
, _Dwarf_Arange
,
46 STAILQ_REMOVE(&dbg
->dbg_aslist
, as
, _Dwarf_ArangeSet
, as_next
);
50 if (dbg
->dbg_arange_array
)
51 free(dbg
->dbg_arange_array
);
53 dbg
->dbg_arange_array
= NULL
;
54 dbg
->dbg_arange_cnt
= 0;
58 _dwarf_arange_init(Dwarf_Debug dbg
, Dwarf_Error
*error
)
64 uint64_t offset
, dwarf_size
, length
, addr
, range
;
69 if ((ds
= _dwarf_find_section(dbg
, ".debug_aranges")) == NULL
)
72 if (!dbg
->dbg_info_loaded
) {
73 ret
= _dwarf_info_load(dbg
, 1, error
);
74 if (ret
!= DW_DLE_NONE
)
79 while (offset
< ds
->ds_size
) {
81 if ((as
= malloc(sizeof(struct _Dwarf_ArangeSet
))) == NULL
) {
82 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
83 return (DW_DLE_MEMORY
);
85 STAILQ_INIT(&as
->as_arlist
);
86 STAILQ_INSERT_TAIL(&dbg
->dbg_aslist
, as
, as_next
);
88 /* Read in the table header. */
89 length
= dbg
->read(ds
->ds_data
, &offset
, 4);
90 if (length
== 0xffffffff) {
92 length
= dbg
->read(ds
->ds_data
, &offset
, 8);
96 as
->as_length
= length
;
97 as
->as_version
= dbg
->read(ds
->ds_data
, &offset
, 2);
98 if (as
->as_version
!= 2) {
99 DWARF_SET_ERROR(dbg
, error
, DW_DLE_VERSION_STAMP_ERROR
);
100 ret
= DW_DLE_VERSION_STAMP_ERROR
;
104 as
->as_cu_offset
= dbg
->read(ds
->ds_data
, &offset
, dwarf_size
);
105 STAILQ_FOREACH(cu
, &dbg
->dbg_cu
, cu_next
) {
106 if (cu
->cu_offset
== as
->as_cu_offset
)
110 DWARF_SET_ERROR(dbg
, error
, DW_DLE_ARANGE_OFFSET_BAD
);
111 ret
= DW_DLE_ARANGE_OFFSET_BAD
;
116 as
->as_addrsz
= dbg
->read(ds
->ds_data
, &offset
, 1);
117 as
->as_segsz
= dbg
->read(ds
->ds_data
, &offset
, 1);
119 /* Skip the padding bytes. */
120 offset
= roundup(offset
, 2 * as
->as_addrsz
);
122 /* Read in address range descriptors. */
123 while (offset
< ds
->ds_size
) {
124 addr
= dbg
->read(ds
->ds_data
, &offset
, as
->as_addrsz
);
125 range
= dbg
->read(ds
->ds_data
, &offset
, as
->as_addrsz
);
126 if (addr
== 0 && range
== 0)
128 if ((ar
= calloc(1, sizeof(struct _Dwarf_Arange
))) ==
130 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
134 ar
->ar_address
= addr
;
135 ar
->ar_range
= range
;
136 STAILQ_INSERT_TAIL(&as
->as_arlist
, ar
, ar_next
);
137 dbg
->dbg_arange_cnt
++;
141 /* Build arange array. */
142 if (dbg
->dbg_arange_cnt
> 0) {
143 if ((dbg
->dbg_arange_array
= malloc(dbg
->dbg_arange_cnt
*
144 sizeof(struct _Dwarf_Arange
))) == NULL
) {
145 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
151 STAILQ_FOREACH(as
, &dbg
->dbg_aslist
, as_next
) {
152 STAILQ_FOREACH(ar
, &as
->as_arlist
, ar_next
)
153 dbg
->dbg_arange_array
[i
++] = ar
;
155 assert((Dwarf_Unsigned
)i
== dbg
->dbg_arange_cnt
);
158 return (DW_DLE_NONE
);
162 _dwarf_arange_cleanup(dbg
);
168 _dwarf_arange_gen(Dwarf_P_Debug dbg
, Dwarf_Error
*error
)
171 Dwarf_Rel_Section drs
;
179 if (STAILQ_EMPTY(&as
->as_arlist
))
180 return (DW_DLE_NONE
);
184 as
->as_cu_offset
= 0; /* We have only one CU. */
185 as
->as_addrsz
= dbg
->dbg_pointer_size
;
186 as
->as_segsz
= 0; /* XXX */
188 /* Create .debug_arange section. */
189 if ((ret
= _dwarf_section_init(dbg
, &ds
, ".debug_aranges", 0, error
)) !=
193 /* Create relocation section for .debug_aranges */
194 RCHECK(_dwarf_reloc_section_init(dbg
, &drs
, ds
, error
));
196 /* Write section header. */
197 RCHECK(WRITE_VALUE(as
->as_length
, 4));
198 RCHECK(WRITE_VALUE(as
->as_version
, 2));
199 RCHECK(_dwarf_reloc_entry_add(dbg
, drs
, ds
, dwarf_drt_data_reloc
, 4,
200 ds
->ds_size
, 0, as
->as_cu_offset
, ".debug_info", error
));
201 RCHECK(WRITE_VALUE(as
->as_addrsz
, 1));
202 RCHECK(WRITE_VALUE(as
->as_segsz
, 1));
204 /* Pad to (2 * address_size) */
205 offset
= roundup(ds
->ds_size
, 2 * as
->as_addrsz
);
206 if (offset
> ds
->ds_size
)
207 RCHECK(WRITE_PADDING(0, offset
- ds
->ds_size
));
210 STAILQ_FOREACH(ar
, &as
->as_arlist
, ar_next
) {
211 RCHECK(_dwarf_reloc_entry_add(dbg
, drs
, ds
,
212 dwarf_drt_data_reloc
, dbg
->dbg_pointer_size
, ds
->ds_size
,
213 ar
->ar_symndx
, ar
->ar_address
, NULL
, error
));
214 if (ar
->ar_esymndx
> 0)
215 RCHECK(_dwarf_reloc_entry_add_pair(dbg
, drs
, ds
,
216 dbg
->dbg_pointer_size
, ds
->ds_size
, ar
->ar_symndx
,
217 ar
->ar_esymndx
, ar
->ar_address
, ar
->ar_eoff
, error
));
219 RCHECK(WRITE_VALUE(ar
->ar_range
, dbg
->dbg_pointer_size
));
221 RCHECK(WRITE_VALUE(0, dbg
->dbg_pointer_size
));
222 RCHECK(WRITE_VALUE(0, dbg
->dbg_pointer_size
));
224 /* Fill in the length field. */
225 as
->as_length
= ds
->ds_size
- 4;
227 dbg
->write(ds
->ds_data
, &offset
, as
->as_length
, 4);
229 /* Inform application the creation of .debug_aranges ELF section. */
230 RCHECK(_dwarf_section_callback(dbg
, ds
, SHT_PROGBITS
, 0, 0, 0, error
));
232 /* Finalize relocation section for .debug_aranges */
233 RCHECK(_dwarf_reloc_section_finalize(dbg
, drs
, error
));
235 return (DW_DLE_NONE
);
238 _dwarf_reloc_section_free(dbg
, &drs
);
241 _dwarf_section_free(dbg
, &ds
);
247 _dwarf_arange_pro_cleanup(Dwarf_P_Debug dbg
)
250 Dwarf_Arange ar
, tar
;
252 assert(dbg
!= NULL
&& dbg
->dbg_mode
== DW_DLC_WRITE
);
253 if (dbg
->dbgp_as
== NULL
)
257 STAILQ_FOREACH_SAFE(ar
, &as
->as_arlist
, ar_next
, tar
) {
258 STAILQ_REMOVE(&as
->as_arlist
, ar
, _Dwarf_Arange
, ar_next
);