xref: /titanic_50/usr/src/lib/libdwarf/common/pro_reloc_symbolic.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
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