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