1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi
3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4*7fd79137SRobert Mustacchi
5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it
6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
7*7fd79137SRobert Mustacchi as published by the Free Software Foundation.
8*7fd79137SRobert Mustacchi
9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but
10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of
11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*7fd79137SRobert Mustacchi
13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is
14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement
15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or
16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if
17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with
18*7fd79137SRobert Mustacchi other software, or any other product whatsoever.
19*7fd79137SRobert Mustacchi
20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software
22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*7fd79137SRobert Mustacchi USA.
24*7fd79137SRobert Mustacchi
25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or:
27*7fd79137SRobert Mustacchi
28*7fd79137SRobert Mustacchi http://www.sgi.com
29*7fd79137SRobert Mustacchi
30*7fd79137SRobert Mustacchi For further information regarding this notice, see:
31*7fd79137SRobert Mustacchi
32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan
33*7fd79137SRobert Mustacchi
34*7fd79137SRobert Mustacchi */
35*7fd79137SRobert Mustacchi
36*7fd79137SRobert Mustacchi
37*7fd79137SRobert Mustacchi
38*7fd79137SRobert Mustacchi #include "config.h"
39*7fd79137SRobert Mustacchi #include "libdwarfdefs.h"
40*7fd79137SRobert Mustacchi #include <stdio.h>
41*7fd79137SRobert Mustacchi #include <string.h>
42*7fd79137SRobert Mustacchi /*#include <elfaccess.h> */
43*7fd79137SRobert Mustacchi #include "pro_incl.h"
44*7fd79137SRobert Mustacchi #include "pro_section.h"
45*7fd79137SRobert Mustacchi #include "pro_reloc.h"
46*7fd79137SRobert Mustacchi #include "pro_reloc_symbolic.h"
47*7fd79137SRobert Mustacchi
48*7fd79137SRobert Mustacchi /*
49*7fd79137SRobert Mustacchi Return DW_DLV_ERROR on malloc error.
50*7fd79137SRobert Mustacchi Return DW_DLV_OK otherwise
51*7fd79137SRobert Mustacchi */
52*7fd79137SRobert Mustacchi
53*7fd79137SRobert Mustacchi int
_dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg,int base_sec_index,Dwarf_Unsigned offset,Dwarf_Unsigned symidx,enum Dwarf_Rel_Type type,int reltarget_length)54*7fd79137SRobert Mustacchi _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg,
55*7fd79137SRobert Mustacchi int base_sec_index,
56*7fd79137SRobert Mustacchi Dwarf_Unsigned offset, /* r_offset of reloc */
57*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx,
58*7fd79137SRobert Mustacchi enum Dwarf_Rel_Type type,
59*7fd79137SRobert Mustacchi int reltarget_length)
60*7fd79137SRobert Mustacchi {
61*7fd79137SRobert Mustacchi /* get a slot, fill in the slot entry */
62*7fd79137SRobert Mustacchi void *relrec_to_fill = 0;
63*7fd79137SRobert Mustacchi int res = 0;
64*7fd79137SRobert Mustacchi struct Dwarf_Relocation_Data_s *slotp;
65*7fd79137SRobert Mustacchi
66*7fd79137SRobert Mustacchi res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
67*7fd79137SRobert Mustacchi &relrec_to_fill);
68*7fd79137SRobert Mustacchi if (res != DW_DLV_OK)
69*7fd79137SRobert Mustacchi return res;
70*7fd79137SRobert Mustacchi slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
71*7fd79137SRobert Mustacchi slotp->drd_type = type;
72*7fd79137SRobert Mustacchi slotp->drd_length = reltarget_length;
73*7fd79137SRobert Mustacchi slotp->drd_offset = offset;
74*7fd79137SRobert Mustacchi slotp->drd_symbol_index = symidx;
75*7fd79137SRobert Mustacchi return DW_DLV_OK;
76*7fd79137SRobert Mustacchi }
77*7fd79137SRobert Mustacchi
78*7fd79137SRobert Mustacchi
79*7fd79137SRobert Mustacchi
80*7fd79137SRobert Mustacchi /*
81*7fd79137SRobert Mustacchi Return DW_DLV_ERROR on malloc error.
82*7fd79137SRobert Mustacchi Return DW_DLV_OK otherwise
83*7fd79137SRobert Mustacchi */
84*7fd79137SRobert Mustacchi int
_dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg,int base_sec_index,Dwarf_Unsigned offset,Dwarf_Unsigned start_symidx,Dwarf_Unsigned end_symidx,enum Dwarf_Rel_Type type,int reltarget_length)85*7fd79137SRobert Mustacchi _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg,
86*7fd79137SRobert Mustacchi int base_sec_index,
87*7fd79137SRobert Mustacchi Dwarf_Unsigned offset, /* r_offset of reloc */
88*7fd79137SRobert Mustacchi Dwarf_Unsigned start_symidx,
89*7fd79137SRobert Mustacchi Dwarf_Unsigned end_symidx,
90*7fd79137SRobert Mustacchi enum Dwarf_Rel_Type type,
91*7fd79137SRobert Mustacchi int reltarget_length)
92*7fd79137SRobert Mustacchi {
93*7fd79137SRobert Mustacchi /* get a slot, fill in the slot entry */
94*7fd79137SRobert Mustacchi void *relrec_to_fill = 0;
95*7fd79137SRobert Mustacchi int res = 0;
96*7fd79137SRobert Mustacchi struct Dwarf_Relocation_Data_s *slotp1 = 0;
97*7fd79137SRobert Mustacchi struct Dwarf_Relocation_Data_s *slotp2 = 0;
98*7fd79137SRobert Mustacchi
99*7fd79137SRobert Mustacchi res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
100*7fd79137SRobert Mustacchi &relrec_to_fill);
101*7fd79137SRobert Mustacchi if (res != DW_DLV_OK)
102*7fd79137SRobert Mustacchi return res;
103*7fd79137SRobert Mustacchi slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
104*7fd79137SRobert Mustacchi res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
105*7fd79137SRobert Mustacchi &relrec_to_fill);
106*7fd79137SRobert Mustacchi if (res != DW_DLV_OK)
107*7fd79137SRobert Mustacchi return res;
108*7fd79137SRobert Mustacchi slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
109*7fd79137SRobert Mustacchi
110*7fd79137SRobert Mustacchi /* ASSERT: type == dwarf_drt_first_of_length_type_pair */
111*7fd79137SRobert Mustacchi slotp1->drd_type = type;
112*7fd79137SRobert Mustacchi slotp1->drd_length = reltarget_length;
113*7fd79137SRobert Mustacchi slotp1->drd_offset = offset;
114*7fd79137SRobert Mustacchi slotp1->drd_symbol_index = start_symidx;
115*7fd79137SRobert Mustacchi
116*7fd79137SRobert Mustacchi slotp2->drd_type = dwarf_drt_second_of_length_pair;
117*7fd79137SRobert Mustacchi slotp2->drd_length = reltarget_length;
118*7fd79137SRobert Mustacchi slotp2->drd_offset = offset;
119*7fd79137SRobert Mustacchi slotp2->drd_symbol_index = end_symidx;
120*7fd79137SRobert Mustacchi return DW_DLV_OK;
121*7fd79137SRobert Mustacchi }
122*7fd79137SRobert Mustacchi
123*7fd79137SRobert Mustacchi /*
124*7fd79137SRobert Mustacchi Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s
125*7fd79137SRobert Mustacchi we must to allow adding a fresh new single
126*7fd79137SRobert Mustacchi block easily (block consolidation use only).
127*7fd79137SRobert Mustacchi
128*7fd79137SRobert Mustacchi */
129*7fd79137SRobert Mustacchi static void
_dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s * pblk,unsigned long ct)130*7fd79137SRobert Mustacchi _dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk,
131*7fd79137SRobert Mustacchi unsigned long ct)
132*7fd79137SRobert Mustacchi {
133*7fd79137SRobert Mustacchi
134*7fd79137SRobert Mustacchi
135*7fd79137SRobert Mustacchi /* Do not zero pr_sect_num_of_reloc_sect */
136*7fd79137SRobert Mustacchi pblk->pr_reloc_total_count = 0;
137*7fd79137SRobert Mustacchi pblk->pr_first_block = 0;
138*7fd79137SRobert Mustacchi pblk->pr_last_block = 0;
139*7fd79137SRobert Mustacchi pblk->pr_block_count = 0;
140*7fd79137SRobert Mustacchi pblk->pr_slots_per_block_to_alloc = ct;
141*7fd79137SRobert Mustacchi }
142*7fd79137SRobert Mustacchi
143*7fd79137SRobert Mustacchi /*
144*7fd79137SRobert Mustacchi Ensure each stream is a single buffer and
145*7fd79137SRobert Mustacchi add that single buffer to the set of stream buffers.
146*7fd79137SRobert Mustacchi
147*7fd79137SRobert Mustacchi By creating a new buffer and copying if necessary.
148*7fd79137SRobert Mustacchi (If > 1 block, reduce to 1 block)
149*7fd79137SRobert Mustacchi
150*7fd79137SRobert Mustacchi Free the input set of buffers if we consolidate.
151*7fd79137SRobert Mustacchi
152*7fd79137SRobert Mustacchi We pass back *new_sec_count as zero because we
153*7fd79137SRobert Mustacchi are not creating normal sections for a .o, but
154*7fd79137SRobert Mustacchi symbolic relocations, separately counted.
155*7fd79137SRobert Mustacchi
156*7fd79137SRobert Mustacchi Return -1 on error (malloc failure)
157*7fd79137SRobert Mustacchi
158*7fd79137SRobert Mustacchi Return DW_DLV_OK on success. Any other return indicates
159*7fd79137SRobert Mustacchi malloc failed.
160*7fd79137SRobert Mustacchi */
161*7fd79137SRobert Mustacchi int
_dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,Dwarf_Signed * new_sec_count)162*7fd79137SRobert Mustacchi _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
163*7fd79137SRobert Mustacchi Dwarf_Signed * new_sec_count)
164*7fd79137SRobert Mustacchi {
165*7fd79137SRobert Mustacchi /* unsigned long total_size =0; */
166*7fd79137SRobert Mustacchi Dwarf_Small *data = 0;
167*7fd79137SRobert Mustacchi int sec_index = 0;
168*7fd79137SRobert Mustacchi int res = 0;
169*7fd79137SRobert Mustacchi unsigned long i = 0;
170*7fd79137SRobert Mustacchi Dwarf_Error error = 0;
171*7fd79137SRobert Mustacchi Dwarf_Signed sec_count = 0;
172*7fd79137SRobert Mustacchi Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
173*7fd79137SRobert Mustacchi
174*7fd79137SRobert Mustacchi for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
175*7fd79137SRobert Mustacchi unsigned long ct = p_reloc->pr_reloc_total_count;
176*7fd79137SRobert Mustacchi struct Dwarf_P_Relocation_Block_s *p_blk;
177*7fd79137SRobert Mustacchi struct Dwarf_P_Relocation_Block_s *p_blk_last;
178*7fd79137SRobert Mustacchi int err;
179*7fd79137SRobert Mustacchi if (ct == 0) {
180*7fd79137SRobert Mustacchi continue;
181*7fd79137SRobert Mustacchi }
182*7fd79137SRobert Mustacchi
183*7fd79137SRobert Mustacchi /* len = dbg->de_relocation_record_size; */
184*7fd79137SRobert Mustacchi ++sec_count;
185*7fd79137SRobert Mustacchi
186*7fd79137SRobert Mustacchi /* total_size = ct *len; */
187*7fd79137SRobert Mustacchi sec_index = p_reloc->pr_sect_num_of_reloc_sect;
188*7fd79137SRobert Mustacchi if (sec_index == 0) {
189*7fd79137SRobert Mustacchi /* Call de_callback_func or de_callback_func_b,
190*7fd79137SRobert Mustacchi getting section number of reloc section. */
191*7fd79137SRobert Mustacchi int rel_section_index = 0;
192*7fd79137SRobert Mustacchi int int_name = 0;
193*7fd79137SRobert Mustacchi Dwarf_Unsigned name_idx = 0;
194*7fd79137SRobert Mustacchi
195*7fd79137SRobert Mustacchi /*
196*7fd79137SRobert Mustacchi This is a bit of a fake, as we do not really have true
197*7fd79137SRobert Mustacchi elf sections at all. Just the data such might contain.
198*7fd79137SRobert Mustacchi But this lets the caller eventually link things
199*7fd79137SRobert Mustacchi together: without this call we would not know what rel
200*7fd79137SRobert Mustacchi data goes with what section when we are asked for the
201*7fd79137SRobert Mustacchi real arrays. */
202*7fd79137SRobert Mustacchi
203*7fd79137SRobert Mustacchi if (dbg->de_callback_func_b) {
204*7fd79137SRobert Mustacchi rel_section_index =
205*7fd79137SRobert Mustacchi dbg->de_callback_func_b(_dwarf_rel_section_names[i],
206*7fd79137SRobert Mustacchi dbg->de_relocation_record_size,
207*7fd79137SRobert Mustacchi /* type */ SHT_REL,
208*7fd79137SRobert Mustacchi /* flags */ 0,
209*7fd79137SRobert Mustacchi /* link to symtab, which we cannot
210*7fd79137SRobert Mustacchi know */ SHN_UNDEF,
211*7fd79137SRobert Mustacchi /* sec rels apply to */
212*7fd79137SRobert Mustacchi dbg->de_elf_sects[i],
213*7fd79137SRobert Mustacchi &name_idx, &err);
214*7fd79137SRobert Mustacchi } else {
215*7fd79137SRobert Mustacchi rel_section_index =
216*7fd79137SRobert Mustacchi dbg->de_callback_func(_dwarf_rel_section_names[i],
217*7fd79137SRobert Mustacchi dbg->de_relocation_record_size,
218*7fd79137SRobert Mustacchi /* type */ SHT_REL,
219*7fd79137SRobert Mustacchi /* flags */ 0,
220*7fd79137SRobert Mustacchi /* link to symtab, which we cannot
221*7fd79137SRobert Mustacchi know */ SHN_UNDEF,
222*7fd79137SRobert Mustacchi /* sec rels apply to, in elf, sh_info */
223*7fd79137SRobert Mustacchi dbg->de_elf_sects[i], &int_name, &err);
224*7fd79137SRobert Mustacchi name_idx = int_name;
225*7fd79137SRobert Mustacchi }
226*7fd79137SRobert Mustacchi if (rel_section_index == -1) {
227*7fd79137SRobert Mustacchi {
228*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR);
229*7fd79137SRobert Mustacchi return (DW_DLV_ERROR);
230*7fd79137SRobert Mustacchi }
231*7fd79137SRobert Mustacchi }
232*7fd79137SRobert Mustacchi p_reloc->pr_sect_num_of_reloc_sect = rel_section_index;
233*7fd79137SRobert Mustacchi sec_index = rel_section_index;
234*7fd79137SRobert Mustacchi }
235*7fd79137SRobert Mustacchi
236*7fd79137SRobert Mustacchi p_blk = p_reloc->pr_first_block;
237*7fd79137SRobert Mustacchi
238*7fd79137SRobert Mustacchi if (p_reloc->pr_block_count > 1) {
239*7fd79137SRobert Mustacchi struct Dwarf_P_Relocation_Block_s *new_blk;
240*7fd79137SRobert Mustacchi
241*7fd79137SRobert Mustacchi /* HACK , not normal interfaces, trashing p_reloc current
242*7fd79137SRobert Mustacchi contents! */
243*7fd79137SRobert Mustacchi _dwarf_reset_reloc_sect_info(p_reloc, ct);
244*7fd79137SRobert Mustacchi
245*7fd79137SRobert Mustacchi /* Creating new single block for all 'ct' entries */
246*7fd79137SRobert Mustacchi res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct);
247*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) {
248*7fd79137SRobert Mustacchi return res;
249*7fd79137SRobert Mustacchi }
250*7fd79137SRobert Mustacchi new_blk = p_reloc->pr_first_block;
251*7fd79137SRobert Mustacchi
252*7fd79137SRobert Mustacchi data = (Dwarf_Small *) new_blk->rb_data;
253*7fd79137SRobert Mustacchi
254*7fd79137SRobert Mustacchi /* The following loop does the consolidation to a single
255*7fd79137SRobert Mustacchi block and frees the input block(s). */
256*7fd79137SRobert Mustacchi do {
257*7fd79137SRobert Mustacchi unsigned long len =
258*7fd79137SRobert Mustacchi p_blk->rb_where_to_add_next - p_blk->rb_data;
259*7fd79137SRobert Mustacchi memcpy(data, p_blk->rb_data, len);
260*7fd79137SRobert Mustacchi data += len;
261*7fd79137SRobert Mustacchi p_blk_last = p_blk;
262*7fd79137SRobert Mustacchi p_blk = p_blk->rb_next;
263*7fd79137SRobert Mustacchi _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
264*7fd79137SRobert Mustacchi } while (p_blk);
265*7fd79137SRobert Mustacchi /* ASSERT: sum of len copied == total_size */
266*7fd79137SRobert Mustacchi new_blk->rb_next_slot_to_use = ct;
267*7fd79137SRobert Mustacchi new_blk->rb_where_to_add_next = (char *) data;
268*7fd79137SRobert Mustacchi p_reloc->pr_reloc_total_count = ct;
269*7fd79137SRobert Mustacchi
270*7fd79137SRobert Mustacchi /* have now created a single block, but no change in slots
271*7fd79137SRobert Mustacchi used (pr_reloc_total_count) */
272*7fd79137SRobert Mustacchi }
273*7fd79137SRobert Mustacchi }
274*7fd79137SRobert Mustacchi *new_sec_count = 0;
275*7fd79137SRobert Mustacchi return DW_DLV_OK;
276*7fd79137SRobert Mustacchi }
277