Drop main() prototype. Syncs with NetBSD-8
[minix.git] / external / bsd / elftoolchain / dist / libdwarf / libdwarf_arange.c
blobebd02b92e108569ded55bfe78e99cbc8654d78b7
1 /* $NetBSD: libdwarf_arange.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
3 /*-
4 * Copyright (c) 2009-2011 Kai Wang
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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
26 * SUCH DAMAGE.
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 ");
34 void
35 _dwarf_arange_cleanup(Dwarf_Debug dbg)
37 Dwarf_ArangeSet as, tas;
38 Dwarf_Arange ar, tar;
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,
43 ar_next);
44 free(ar);
46 STAILQ_REMOVE(&dbg->dbg_aslist, as, _Dwarf_ArangeSet, as_next);
47 free(as);
50 if (dbg->dbg_arange_array)
51 free(dbg->dbg_arange_array);
53 dbg->dbg_arange_array = NULL;
54 dbg->dbg_arange_cnt = 0;
57 int
58 _dwarf_arange_init(Dwarf_Debug dbg, Dwarf_Error *error)
60 Dwarf_CU cu;
61 Dwarf_ArangeSet as;
62 Dwarf_Arange ar;
63 Dwarf_Section *ds;
64 uint64_t offset, dwarf_size, length, addr, range;
65 int i, ret;
67 ret = DW_DLE_NONE;
69 if ((ds = _dwarf_find_section(dbg, ".debug_aranges")) == NULL)
70 return (DW_DLE_NONE);
72 if (!dbg->dbg_info_loaded) {
73 ret = _dwarf_info_load(dbg, 1, error);
74 if (ret != DW_DLE_NONE)
75 return (ret);
78 offset = 0;
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) {
91 dwarf_size = 8;
92 length = dbg->read(ds->ds_data, &offset, 8);
93 } else
94 dwarf_size = 4;
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;
101 goto fail_cleanup;
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)
107 break;
109 if (cu == NULL) {
110 DWARF_SET_ERROR(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
111 ret = DW_DLE_ARANGE_OFFSET_BAD;
112 goto fail_cleanup;
114 as->as_cu = cu;
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)
127 break;
128 if ((ar = calloc(1, sizeof(struct _Dwarf_Arange))) ==
129 NULL) {
130 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
131 goto fail_cleanup;
133 ar->ar_as = as;
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);
146 ret = DW_DLE_MEMORY;
147 goto fail_cleanup;
150 i = 0;
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);
160 fail_cleanup:
162 _dwarf_arange_cleanup(dbg);
164 return (ret);
168 _dwarf_arange_gen(Dwarf_P_Debug dbg, Dwarf_Error *error)
170 Dwarf_P_Section ds;
171 Dwarf_Rel_Section drs;
172 Dwarf_ArangeSet as;
173 Dwarf_Arange ar;
174 uint64_t offset;
175 int ret;
177 as = dbg->dbgp_as;
178 assert(as != NULL);
179 if (STAILQ_EMPTY(&as->as_arlist))
180 return (DW_DLE_NONE);
182 as->as_length = 0;
183 as->as_version = 2;
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)) !=
190 DW_DLE_NONE)
191 goto gen_fail0;
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));
209 /* Write tuples. */
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));
218 else
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;
226 offset = 0;
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);
237 gen_fail:
238 _dwarf_reloc_section_free(dbg, &drs);
240 gen_fail0:
241 _dwarf_section_free(dbg, &ds);
243 return (ret);
246 void
247 _dwarf_arange_pro_cleanup(Dwarf_P_Debug dbg)
249 Dwarf_ArangeSet as;
250 Dwarf_Arange ar, tar;
252 assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE);
253 if (dbg->dbgp_as == NULL)
254 return;
256 as = dbg->dbgp_as;
257 STAILQ_FOREACH_SAFE(ar, &as->as_arlist, ar_next, tar) {
258 STAILQ_REMOVE(&as->as_arlist, ar, _Dwarf_Arange, ar_next);
259 free(ar);
261 free(as);
262 dbg->dbgp_as = NULL;