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