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