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