1 /* $NetBSD: libdwarf_nametbl.c,v 1.2 2014/03/09 16:58:04 christos Exp $ */
4 * Copyright (c) 2009,2010 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_nametbl.c,v 1.2 2014/03/09 16:58:04 christos Exp $");
32 ELFTC_VCSID("Id: libdwarf_nametbl.c 2070 2011-10-27 03:05:32Z jkoshy ");
35 _dwarf_nametbl_cleanup(Dwarf_NameSec
*nsp
)
38 Dwarf_NameTbl nt
, tnt
;
39 Dwarf_NamePair np
, tnp
;
42 if ((ns
= *nsp
) == NULL
)
45 STAILQ_FOREACH_SAFE(nt
, &ns
->ns_ntlist
, nt_next
, tnt
) {
46 STAILQ_FOREACH_SAFE(np
, &nt
->nt_nplist
, np_next
, tnp
) {
47 STAILQ_REMOVE(&nt
->nt_nplist
, np
, _Dwarf_NamePair
,
51 STAILQ_REMOVE(&ns
->ns_ntlist
, nt
, _Dwarf_NameTbl
, nt_next
);
61 _dwarf_nametbl_init(Dwarf_Debug dbg
, Dwarf_NameSec
*namesec
, Dwarf_Section
*ds
,
68 uint64_t offset
, dwarf_size
, length
, cuoff
;
72 assert(*namesec
== NULL
);
74 if ((ns
= malloc(sizeof(struct _Dwarf_NameSec
))) == NULL
) {
75 DWARF_SET_ERROR(dbg
, error
, DW_DLE_MEMORY
);
76 return (DW_DLE_MEMORY
);
78 STAILQ_INIT(&ns
->ns_ntlist
);
83 while (offset
< ds
->ds_size
) {
85 /* Allocate a new name table. */
86 if ((nt
= malloc(sizeof(struct _Dwarf_NameTbl
))) == NULL
) {
88 DWARF_SET_ERROR(dbg
, error
, ret
);
91 STAILQ_INIT(&nt
->nt_nplist
);
92 STAILQ_INSERT_TAIL(&ns
->ns_ntlist
, nt
, nt_next
);
94 /* Read in the table header. */
95 length
= dbg
->read(ds
->ds_data
, &offset
, 4);
96 if (length
== 0xffffffff) {
98 length
= dbg
->read(ds
->ds_data
, &offset
, 8);
102 nt
->nt_length
= length
;
103 /* FIXME: verify version */
104 nt
->nt_version
= dbg
->read(ds
->ds_data
, &offset
, 2);
105 nt
->nt_cu_offset
= dbg
->read(ds
->ds_data
, &offset
, dwarf_size
);
106 nt
->nt_cu_length
= dbg
->read(ds
->ds_data
, &offset
, dwarf_size
);
108 if (!dbg
->dbg_info_loaded
) {
109 ret
= _dwarf_info_load(dbg
, 1, error
);
110 if (ret
!= DW_DLE_NONE
)
114 /* Find the referenced CU. */
115 STAILQ_FOREACH(cu
, &dbg
->dbg_cu
, cu_next
) {
116 if (cu
->cu_offset
== nt
->nt_cu_offset
)
119 nt
->nt_cu
= cu
; /* FIXME: Check if NULL here */
121 /* Add name pairs. */
122 while (offset
< ds
->ds_size
) {
123 cuoff
= dbg
->read(ds
->ds_data
, &offset
, dwarf_size
);
126 if ((np
= malloc(sizeof(struct _Dwarf_NamePair
))) ==
129 DWARF_SET_ERROR(dbg
, error
, ret
);
133 np
->np_offset
= cuoff
;
134 p
= (char *) ds
->ds_data
;
135 np
->np_name
= &p
[offset
];
136 while (p
[offset
++] != '\0')
138 STAILQ_INSERT_TAIL(&nt
->nt_nplist
, np
, np_next
);
143 /* Build array of name pairs from all tables. */
144 if (ns
->ns_len
> 0) {
145 if ((ns
->ns_array
= malloc(sizeof(Dwarf_NamePair
) *
146 ns
->ns_len
)) == NULL
) {
148 DWARF_SET_ERROR(dbg
, error
, ret
);
153 STAILQ_FOREACH(nt
, &ns
->ns_ntlist
, nt_next
) {
154 STAILQ_FOREACH(np
, &nt
->nt_nplist
, np_next
)
155 ns
->ns_array
[i
++] = np
;
157 assert((Dwarf_Unsigned
)i
== ns
->ns_len
);
162 return (DW_DLE_NONE
);
166 _dwarf_nametbl_cleanup(&ns
);
172 _dwarf_nametbl_gen(Dwarf_P_Debug dbg
, const char *name
, Dwarf_NameTbl nt
,
176 Dwarf_Rel_Section drs
;
181 assert(dbg
!= NULL
&& name
!= NULL
);
182 if (nt
== NULL
|| STAILQ_EMPTY(&nt
->nt_nplist
))
183 return (DW_DLE_NONE
);
187 nt
->nt_cu
= STAILQ_FIRST(&dbg
->dbg_cu
);
188 assert(nt
->nt_cu
!= NULL
);
189 nt
->nt_cu_offset
= nt
->nt_cu
->cu_offset
;
190 nt
->nt_cu_length
= nt
->nt_cu
->cu_length
;
192 /* Create name lookup section. */
193 if ((ret
= _dwarf_section_init(dbg
, &ds
, name
, 0, error
)) !=
197 /* Create relocation section for the name lookup section. */
198 RCHECK(_dwarf_reloc_section_init(dbg
, &drs
, ds
, error
));
200 /* Write table header. */
201 RCHECK(WRITE_VALUE(nt
->nt_length
, 4));
202 RCHECK(WRITE_VALUE(nt
->nt_version
, 2));
203 RCHECK(_dwarf_reloc_entry_add(dbg
, drs
, ds
, dwarf_drt_data_reloc
, 4,
204 ds
->ds_size
, 0, nt
->nt_cu_offset
, ".debug_info", error
));
205 RCHECK(WRITE_VALUE(nt
->nt_cu_length
, 4));
208 STAILQ_FOREACH(np
, &nt
->nt_nplist
, np_next
) {
209 assert(np
->np_die
!= NULL
);
210 np
->np_offset
= np
->np_die
->die_offset
;
211 RCHECK(WRITE_VALUE(np
->np_offset
, 4));
212 RCHECK(WRITE_STRING(np
->np_name
));
214 RCHECK(WRITE_VALUE(0, 4));
216 /* Fill in the length field. */
217 nt
->nt_length
= ds
->ds_size
- 4;
219 dbg
->write(ds
->ds_data
, &offset
, nt
->nt_length
, 4);
221 /* Inform application the creation of name lookup ELF section. */
222 RCHECK(_dwarf_section_callback(dbg
, ds
, SHT_PROGBITS
, 0, 0, 0, error
));
224 /* Finalize relocation section for the name lookup section. */
225 RCHECK(_dwarf_reloc_section_finalize(dbg
, drs
, error
));
227 return (DW_DLE_NONE
);
230 _dwarf_reloc_section_free(dbg
, &drs
);
233 _dwarf_section_free(dbg
, &ds
);
239 _dwarf_nametbl_pro_cleanup(Dwarf_NameTbl
*ntp
)
242 Dwarf_NamePair np
, tnp
;
245 if ((nt
= *ntp
) == NULL
)
248 STAILQ_FOREACH_SAFE(np
, &nt
->nt_nplist
, np_next
, tnp
) {
249 STAILQ_REMOVE(&nt
->nt_nplist
, np
, _Dwarf_NamePair
, np_next
);