1*f3e7f55eSRobert Mustacchi /*
2*f3e7f55eSRobert Mustacchi
3*f3e7f55eSRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4*f3e7f55eSRobert Mustacchi Portions Copyright 2008-2010 David Anderson, Inc. All rights reserved.
5*f3e7f55eSRobert Mustacchi
6*f3e7f55eSRobert Mustacchi This program is free software; you can redistribute it and/or modify it
7*f3e7f55eSRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
8*f3e7f55eSRobert Mustacchi as published by the Free Software Foundation.
9*f3e7f55eSRobert Mustacchi
10*f3e7f55eSRobert Mustacchi This program is distributed in the hope that it would be useful, but
11*f3e7f55eSRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
12*f3e7f55eSRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*f3e7f55eSRobert Mustacchi
14*f3e7f55eSRobert Mustacchi Further, this software is distributed without any warranty that it is
15*f3e7f55eSRobert Mustacchi free of the rightful claim of any third person regarding infringement
16*f3e7f55eSRobert Mustacchi or the like. Any license provided herein, whether implied or
17*f3e7f55eSRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
18*f3e7f55eSRobert Mustacchi any, provided herein do not apply to combinations of this program with
19*f3e7f55eSRobert Mustacchi other software, or any other product whatsoever.
20*f3e7f55eSRobert Mustacchi
21*f3e7f55eSRobert Mustacchi You should have received a copy of the GNU Lesser General Public
22*f3e7f55eSRobert Mustacchi License along with this program; if not, write the Free Software
23*f3e7f55eSRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*f3e7f55eSRobert Mustacchi USA.
25*f3e7f55eSRobert Mustacchi
26*f3e7f55eSRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27*f3e7f55eSRobert Mustacchi Mountain View, CA 94043, or:
28*f3e7f55eSRobert Mustacchi
29*f3e7f55eSRobert Mustacchi http://www.sgi.com
30*f3e7f55eSRobert Mustacchi
31*f3e7f55eSRobert Mustacchi For further information regarding this notice, see:
32*f3e7f55eSRobert Mustacchi
33*f3e7f55eSRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*f3e7f55eSRobert Mustacchi
35*f3e7f55eSRobert Mustacchi */
36*f3e7f55eSRobert Mustacchi
37*f3e7f55eSRobert Mustacchi
38*f3e7f55eSRobert Mustacchi
39*f3e7f55eSRobert Mustacchi #include "config.h"
40*f3e7f55eSRobert Mustacchi #include "libdwarfdefs.h"
41*f3e7f55eSRobert Mustacchi #include <stdio.h>
42*f3e7f55eSRobert Mustacchi #include <string.h>
43*f3e7f55eSRobert Mustacchi /*#include <elfaccess.h> */
44*f3e7f55eSRobert Mustacchi #include "pro_incl.h"
45*f3e7f55eSRobert Mustacchi
46*f3e7f55eSRobert Mustacchi
47*f3e7f55eSRobert Mustacchi /*Do initial alloc of newslots slots.
48*f3e7f55eSRobert Mustacchi Fails only if malloc fails.
49*f3e7f55eSRobert Mustacchi
50*f3e7f55eSRobert Mustacchi Supposed to be called before any relocs allocated.
51*f3e7f55eSRobert Mustacchi Ignored if after any allocated.
52*f3e7f55eSRobert Mustacchi
53*f3e7f55eSRobert Mustacchi Part of an optimization, so that for a known 'newslots'
54*f3e7f55eSRobert Mustacchi relocations count we can preallocate the right size block.
55*f3e7f55eSRobert Mustacchi Called from just 2 places.
56*f3e7f55eSRobert Mustacchi
57*f3e7f55eSRobert Mustacchi returns DW_DLV_OK or DW_DLV_ERROR
58*f3e7f55eSRobert Mustacchi */
59*f3e7f55eSRobert Mustacchi int
_dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg,int rel_sec_index,Dwarf_Unsigned newslots)60*f3e7f55eSRobert Mustacchi _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg,
61*f3e7f55eSRobert Mustacchi int rel_sec_index,
62*f3e7f55eSRobert Mustacchi Dwarf_Unsigned newslots)
63*f3e7f55eSRobert Mustacchi {
64*f3e7f55eSRobert Mustacchi unsigned long len = 0;
65*f3e7f55eSRobert Mustacchi struct Dwarf_P_Relocation_Block_s *data = 0;
66*f3e7f55eSRobert Mustacchi Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
67*f3e7f55eSRobert Mustacchi unsigned long slots_in_blk = (unsigned long) newslots;
68*f3e7f55eSRobert Mustacchi unsigned long rel_rec_size = dbg->de_relocation_record_size;
69*f3e7f55eSRobert Mustacchi
70*f3e7f55eSRobert Mustacchi if (prel->pr_first_block)
71*f3e7f55eSRobert Mustacchi return DW_DLV_OK; /* do nothing */
72*f3e7f55eSRobert Mustacchi
73*f3e7f55eSRobert Mustacchi len = sizeof(struct Dwarf_P_Relocation_Block_s) +
74*f3e7f55eSRobert Mustacchi slots_in_blk * rel_rec_size;
75*f3e7f55eSRobert Mustacchi
76*f3e7f55eSRobert Mustacchi
77*f3e7f55eSRobert Mustacchi data = (struct Dwarf_P_Relocation_Block_s *)
78*f3e7f55eSRobert Mustacchi _dwarf_p_get_alloc(dbg, len);
79*f3e7f55eSRobert Mustacchi if (!data) {
80*f3e7f55eSRobert Mustacchi return DW_DLV_ERROR;
81*f3e7f55eSRobert Mustacchi }
82*f3e7f55eSRobert Mustacchi data->rb_slots_in_block = slots_in_blk; /* could use default
83*f3e7f55eSRobert Mustacchi here, as fallback in
84*f3e7f55eSRobert Mustacchi case our origininal
85*f3e7f55eSRobert Mustacchi estimate wrong. When
86*f3e7f55eSRobert Mustacchi we call this we
87*f3e7f55eSRobert Mustacchi presumably know what
88*f3e7f55eSRobert Mustacchi we are doing, so
89*f3e7f55eSRobert Mustacchi keep this count for
90*f3e7f55eSRobert Mustacchi now */
91*f3e7f55eSRobert Mustacchi data->rb_next_slot_to_use = 0;
92*f3e7f55eSRobert Mustacchi data->rb_where_to_add_next =
93*f3e7f55eSRobert Mustacchi ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
94*f3e7f55eSRobert Mustacchi data->rb_data = data->rb_where_to_add_next;
95*f3e7f55eSRobert Mustacchi
96*f3e7f55eSRobert Mustacchi prel->pr_first_block = data;
97*f3e7f55eSRobert Mustacchi prel->pr_last_block = data;
98*f3e7f55eSRobert Mustacchi prel->pr_block_count = 1;
99*f3e7f55eSRobert Mustacchi
100*f3e7f55eSRobert Mustacchi
101*f3e7f55eSRobert Mustacchi return DW_DLV_OK;
102*f3e7f55eSRobert Mustacchi }
103*f3e7f55eSRobert Mustacchi
104*f3e7f55eSRobert Mustacchi
105*f3e7f55eSRobert Mustacchi /*Do alloc of slots.
106*f3e7f55eSRobert Mustacchi Fails only if malloc fails.
107*f3e7f55eSRobert Mustacchi
108*f3e7f55eSRobert Mustacchi Only allocator used.
109*f3e7f55eSRobert Mustacchi
110*f3e7f55eSRobert Mustacchi returns DW_DLV_OK or DW_DLV_ERROR
111*f3e7f55eSRobert Mustacchi */
112*f3e7f55eSRobert Mustacchi int
_dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg,int rel_sec_index)113*f3e7f55eSRobert Mustacchi _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index)
114*f3e7f55eSRobert Mustacchi {
115*f3e7f55eSRobert Mustacchi unsigned long len = 0;
116*f3e7f55eSRobert Mustacchi struct Dwarf_P_Relocation_Block_s *data = 0;
117*f3e7f55eSRobert Mustacchi Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
118*f3e7f55eSRobert Mustacchi unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc;
119*f3e7f55eSRobert Mustacchi unsigned long rel_rec_size = dbg->de_relocation_record_size;
120*f3e7f55eSRobert Mustacchi
121*f3e7f55eSRobert Mustacchi len = sizeof(struct Dwarf_P_Relocation_Block_s) +
122*f3e7f55eSRobert Mustacchi slots_in_blk * rel_rec_size;
123*f3e7f55eSRobert Mustacchi
124*f3e7f55eSRobert Mustacchi data = (struct Dwarf_P_Relocation_Block_s *)
125*f3e7f55eSRobert Mustacchi _dwarf_p_get_alloc(dbg, len);
126*f3e7f55eSRobert Mustacchi if (!data) {
127*f3e7f55eSRobert Mustacchi return DW_DLV_ERROR;
128*f3e7f55eSRobert Mustacchi }
129*f3e7f55eSRobert Mustacchi
130*f3e7f55eSRobert Mustacchi if (prel->pr_first_block) {
131*f3e7f55eSRobert Mustacchi prel->pr_last_block->rb_next = data;
132*f3e7f55eSRobert Mustacchi prel->pr_last_block = data;
133*f3e7f55eSRobert Mustacchi prel->pr_block_count += 1;
134*f3e7f55eSRobert Mustacchi
135*f3e7f55eSRobert Mustacchi } else {
136*f3e7f55eSRobert Mustacchi
137*f3e7f55eSRobert Mustacchi prel->pr_first_block = data;
138*f3e7f55eSRobert Mustacchi prel->pr_last_block = data;
139*f3e7f55eSRobert Mustacchi prel->pr_block_count = 1;
140*f3e7f55eSRobert Mustacchi }
141*f3e7f55eSRobert Mustacchi
142*f3e7f55eSRobert Mustacchi data->rb_slots_in_block = slots_in_blk;
143*f3e7f55eSRobert Mustacchi data->rb_next_slot_to_use = 0;
144*f3e7f55eSRobert Mustacchi data->rb_where_to_add_next =
145*f3e7f55eSRobert Mustacchi ((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
146*f3e7f55eSRobert Mustacchi data->rb_data = data->rb_where_to_add_next;
147*f3e7f55eSRobert Mustacchi
148*f3e7f55eSRobert Mustacchi return DW_DLV_OK;
149*f3e7f55eSRobert Mustacchi
150*f3e7f55eSRobert Mustacchi }
151*f3e7f55eSRobert Mustacchi
152*f3e7f55eSRobert Mustacchi /*
153*f3e7f55eSRobert Mustacchi Reserve a slot. return DW_DLV_OK if succeeds.
154*f3e7f55eSRobert Mustacchi
155*f3e7f55eSRobert Mustacchi Return DW_DLV_ERROR if fails (malloc error).
156*f3e7f55eSRobert Mustacchi
157*f3e7f55eSRobert Mustacchi Use the relrec_to_fill to pass back a pointer to
158*f3e7f55eSRobert Mustacchi a slot space to use.
159*f3e7f55eSRobert Mustacchi */
160*f3e7f55eSRobert Mustacchi int
_dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg,int base_sec_index,void ** relrec_to_fill)161*f3e7f55eSRobert Mustacchi _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg,
162*f3e7f55eSRobert Mustacchi int base_sec_index, void **relrec_to_fill)
163*f3e7f55eSRobert Mustacchi {
164*f3e7f55eSRobert Mustacchi struct Dwarf_P_Relocation_Block_s *data = 0;
165*f3e7f55eSRobert Mustacchi Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index];
166*f3e7f55eSRobert Mustacchi unsigned long rel_rec_size = dbg->de_relocation_record_size;
167*f3e7f55eSRobert Mustacchi
168*f3e7f55eSRobert Mustacchi char *ret_addr = 0;
169*f3e7f55eSRobert Mustacchi
170*f3e7f55eSRobert Mustacchi data = prel->pr_last_block;
171*f3e7f55eSRobert Mustacchi if ((data == 0) ||
172*f3e7f55eSRobert Mustacchi (data->rb_next_slot_to_use >= data->rb_slots_in_block)) {
173*f3e7f55eSRobert Mustacchi int res;
174*f3e7f55eSRobert Mustacchi
175*f3e7f55eSRobert Mustacchi res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index);
176*f3e7f55eSRobert Mustacchi if (res != DW_DLV_OK) {
177*f3e7f55eSRobert Mustacchi return res;
178*f3e7f55eSRobert Mustacchi }
179*f3e7f55eSRobert Mustacchi }
180*f3e7f55eSRobert Mustacchi
181*f3e7f55eSRobert Mustacchi data = prel->pr_last_block;
182*f3e7f55eSRobert Mustacchi /* now we have an empty slot */
183*f3e7f55eSRobert Mustacchi ret_addr = data->rb_where_to_add_next;
184*f3e7f55eSRobert Mustacchi
185*f3e7f55eSRobert Mustacchi data->rb_where_to_add_next += rel_rec_size;
186*f3e7f55eSRobert Mustacchi data->rb_next_slot_to_use += 1;
187*f3e7f55eSRobert Mustacchi
188*f3e7f55eSRobert Mustacchi prel->pr_reloc_total_count += 1;
189*f3e7f55eSRobert Mustacchi
190*f3e7f55eSRobert Mustacchi *relrec_to_fill = (void *) ret_addr;
191*f3e7f55eSRobert Mustacchi
192*f3e7f55eSRobert Mustacchi return DW_DLV_OK;
193*f3e7f55eSRobert Mustacchi
194*f3e7f55eSRobert Mustacchi }
195*f3e7f55eSRobert Mustacchi
196*f3e7f55eSRobert Mustacchi /*
197*f3e7f55eSRobert Mustacchi On success returns count of
198*f3e7f55eSRobert Mustacchi .rel.* sections that are symbolic
199*f3e7f55eSRobert Mustacchi thru count_of_relocation_sections.
200*f3e7f55eSRobert Mustacchi
201*f3e7f55eSRobert Mustacchi On success, returns DW_DLV_OK.
202*f3e7f55eSRobert Mustacchi
203*f3e7f55eSRobert Mustacchi If this is not a 'symbolic' run, returns
204*f3e7f55eSRobert Mustacchi DW_DLV_NO_ENTRY.
205*f3e7f55eSRobert Mustacchi
206*f3e7f55eSRobert Mustacchi No errors are possible.
207*f3e7f55eSRobert Mustacchi
208*f3e7f55eSRobert Mustacchi
209*f3e7f55eSRobert Mustacchi
210*f3e7f55eSRobert Mustacchi
211*f3e7f55eSRobert Mustacchi */
212*f3e7f55eSRobert Mustacchi
213*f3e7f55eSRobert Mustacchi /*ARGSUSED*/ int
dwarf_get_relocation_info_count(Dwarf_P_Debug dbg,Dwarf_Unsigned * count_of_relocation_sections,int * drd_buffer_version,Dwarf_Error * error)214*f3e7f55eSRobert Mustacchi dwarf_get_relocation_info_count(Dwarf_P_Debug dbg,
215*f3e7f55eSRobert Mustacchi Dwarf_Unsigned *
216*f3e7f55eSRobert Mustacchi count_of_relocation_sections,
217*f3e7f55eSRobert Mustacchi int *drd_buffer_version,
218*f3e7f55eSRobert Mustacchi Dwarf_Error * error)
219*f3e7f55eSRobert Mustacchi {
220*f3e7f55eSRobert Mustacchi if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
221*f3e7f55eSRobert Mustacchi int i;
222*f3e7f55eSRobert Mustacchi unsigned int count = 0;
223*f3e7f55eSRobert Mustacchi
224*f3e7f55eSRobert Mustacchi for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
225*f3e7f55eSRobert Mustacchi if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) {
226*f3e7f55eSRobert Mustacchi ++count;
227*f3e7f55eSRobert Mustacchi }
228*f3e7f55eSRobert Mustacchi }
229*f3e7f55eSRobert Mustacchi *count_of_relocation_sections = (Dwarf_Unsigned) count;
230*f3e7f55eSRobert Mustacchi *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
231*f3e7f55eSRobert Mustacchi return DW_DLV_OK;
232*f3e7f55eSRobert Mustacchi }
233*f3e7f55eSRobert Mustacchi return DW_DLV_NO_ENTRY;
234*f3e7f55eSRobert Mustacchi }
235*f3e7f55eSRobert Mustacchi
236*f3e7f55eSRobert Mustacchi int
dwarf_get_relocation_info(Dwarf_P_Debug dbg,Dwarf_Signed * elf_section_index,Dwarf_Signed * elf_section_index_link,Dwarf_Unsigned * relocation_buffer_count,Dwarf_Relocation_Data * reldata_buffer,Dwarf_Error * error)237*f3e7f55eSRobert Mustacchi dwarf_get_relocation_info(Dwarf_P_Debug dbg,
238*f3e7f55eSRobert Mustacchi Dwarf_Signed * elf_section_index,
239*f3e7f55eSRobert Mustacchi Dwarf_Signed * elf_section_index_link,
240*f3e7f55eSRobert Mustacchi Dwarf_Unsigned * relocation_buffer_count,
241*f3e7f55eSRobert Mustacchi Dwarf_Relocation_Data * reldata_buffer,
242*f3e7f55eSRobert Mustacchi Dwarf_Error * error)
243*f3e7f55eSRobert Mustacchi {
244*f3e7f55eSRobert Mustacchi int next = dbg->de_reloc_next_to_return;
245*f3e7f55eSRobert Mustacchi
246*f3e7f55eSRobert Mustacchi if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
247*f3e7f55eSRobert Mustacchi int i;
248*f3e7f55eSRobert Mustacchi
249*f3e7f55eSRobert Mustacchi for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
250*f3e7f55eSRobert Mustacchi Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i];
251*f3e7f55eSRobert Mustacchi
252*f3e7f55eSRobert Mustacchi if (prel->pr_reloc_total_count > 0) {
253*f3e7f55eSRobert Mustacchi dbg->de_reloc_next_to_return = i + 1;
254*f3e7f55eSRobert Mustacchi
255*f3e7f55eSRobert Mustacchi
256*f3e7f55eSRobert Mustacchi /* ASSERT: prel->.pr_block_count == 1 */
257*f3e7f55eSRobert Mustacchi
258*f3e7f55eSRobert Mustacchi *elf_section_index = prel->pr_sect_num_of_reloc_sect;
259*f3e7f55eSRobert Mustacchi *elf_section_index_link = dbg->de_elf_sects[i];
260*f3e7f55eSRobert Mustacchi *relocation_buffer_count = prel->pr_reloc_total_count;
261*f3e7f55eSRobert Mustacchi *reldata_buffer = (Dwarf_Relocation_Data)
262*f3e7f55eSRobert Mustacchi (prel->pr_first_block->rb_data);
263*f3e7f55eSRobert Mustacchi return DW_DLV_OK;
264*f3e7f55eSRobert Mustacchi }
265*f3e7f55eSRobert Mustacchi }
266*f3e7f55eSRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
267*f3e7f55eSRobert Mustacchi }
268*f3e7f55eSRobert Mustacchi return DW_DLV_NO_ENTRY;
269*f3e7f55eSRobert Mustacchi }
270