00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "config.h"
00043 #include "libdwarfdefs.h"
00044 #include <stdio.h>
00045 #include <string.h>
00046 #ifdef HAVE_ELFACCESS_H
00047 #include <elfaccess.h>
00048 #else
00049
00050 #define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t))
00051 #define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t))
00052 #endif
00053 #include "pro_incl.h"
00054 #include "pro_section.h"
00055 #include "pro_reloc.h"
00056 #include "pro_reloc_stream.h"
00057
00058
00059
00060
00061
00062
00063
00064
00065 int
00066 _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,
00067
00068
00069
00070 Dwarf_Unsigned symidx,
00071 enum Dwarf_Rel_Type type,
00072 int reltarget_length)
00073 {
00074 #if HAVE_ELF64_GETEHDR
00075 Elf64_Rel *elf64_reloc;
00076 void *relrec_to_fill;
00077 int res;
00078 int rel_type;
00079
00080 res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
00081 &relrec_to_fill);
00082 if (res != DW_DLV_OK)
00083 return res;
00084
00085
00086 if (type == dwarf_drt_data_reloc) {
00087 if (reltarget_length == dbg->de_offset_size) {
00088 rel_type = dbg->de_offset_reloc;
00089 } else if (reltarget_length == dbg->de_pointer_size) {
00090 rel_type = dbg->de_ptr_reloc;
00091 } else {
00092 return DW_DLV_ERROR;
00093 }
00094 } else if (type == dwarf_drt_segment_rel) {
00095 rel_type = dbg->de_exc_reloc;
00096 } else {
00097
00098
00099 rel_type = 0;
00100 }
00101
00102 elf64_reloc = (Elf64_Rel *) relrec_to_fill;
00103 elf64_reloc->r_offset = offset;
00104 Set_REL64_info(*elf64_reloc, symidx, rel_type);
00105 return DW_DLV_OK;
00106 #else
00107 return DW_DLV_ERROR;
00108 #endif
00109 }
00110
00111
00112
00113
00114
00115
00116 int
00117 _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,
00118
00119
00120
00121 Dwarf_Unsigned symidx,
00122 enum Dwarf_Rel_Type type,
00123 int reltarget_length)
00124 {
00125 Elf32_Rel *elf32_reloc;
00126 void *relrec_to_fill;
00127 int res;
00128 int rel_type;
00129
00130 res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
00131 &relrec_to_fill);
00132 if (res != DW_DLV_OK)
00133 return res;
00134 if (type == dwarf_drt_data_reloc) {
00135 if (reltarget_length == dbg->de_offset_size) {
00136 rel_type = dbg->de_offset_reloc;
00137 } else if (reltarget_length == dbg->de_pointer_size) {
00138 rel_type = dbg->de_ptr_reloc;
00139 } else {
00140 return DW_DLV_ERROR;
00141 }
00142 } else if (type == dwarf_drt_segment_rel) {
00143 rel_type = dbg->de_exc_reloc;
00144 } else {
00145
00146
00147 rel_type = 0;
00148 }
00149
00150 elf32_reloc = (Elf32_Rel *) relrec_to_fill;
00151 elf32_reloc->r_offset = (Elf32_Addr) offset;
00152 Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type);
00153 return DW_DLV_OK;
00154
00155
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 int
00167 _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,
00168
00169
00170
00171 Dwarf_Unsigned start_symidx,
00172 Dwarf_Unsigned end_symidx,
00173 enum Dwarf_Rel_Type type,
00174 int reltarget_length)
00175 {
00176
00177 return DW_DLV_OK;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 int
00196 _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
00197 Dwarf_Signed * new_sec_count)
00198 {
00199 unsigned long total_size = 0;
00200 Dwarf_Small *data;
00201 int sec_index;
00202 unsigned long i;
00203 Dwarf_Error err;
00204 Dwarf_Error *error = &err;
00205
00206 Dwarf_Signed sec_count = 0;
00207
00208 Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
00209
00210 for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
00211 unsigned long ct = p_reloc->pr_reloc_total_count;
00212 unsigned len;
00213 struct Dwarf_P_Relocation_Block_s *p_blk;
00214 struct Dwarf_P_Relocation_Block_s *p_blk_last;
00215 Dwarf_P_Per_Reloc_Sect prb;
00216
00217 if (ct == 0) {
00218 continue;
00219 }
00220 prb = &dbg->de_reloc_sect[i];
00221 len = dbg->de_relocation_record_size;
00222 ++sec_count;
00223
00224 total_size = ct * len;
00225 sec_index = prb->pr_sect_num_of_reloc_sect;
00226 if (sec_index == 0) {
00227
00228
00229 int rel_section_index;
00230 Dwarf_Unsigned name_idx;
00231 int int_name;
00232 int err;
00233
00234 if (dbg->de_func_b) {
00235 rel_section_index =
00236 dbg->de_func_b(_dwarf_rel_section_names[i],
00237
00238 dbg->de_relocation_record_size,
00239 SHT_REL,
00240 0,
00241
00242 0,
00243
00244 dbg->de_elf_sects[i],
00245 &name_idx, &err);
00246 } else {
00247 rel_section_index =
00248 dbg->de_func(_dwarf_rel_section_names[i],
00249
00250 dbg->de_relocation_record_size,
00251 SHT_REL,
00252 0,
00253
00254 0,
00255
00256 dbg->de_elf_sects[i], &int_name, &err);
00257 name_idx = int_name;
00258 }
00259 if (rel_section_index == -1) {
00260 {
00261 _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR);
00262 return (DW_DLV_ERROR);
00263 }
00264
00265 }
00266 prb->pr_sect_num_of_reloc_sect = rel_section_index;
00267 sec_index = rel_section_index;
00268 }
00269 GET_CHUNK(dbg, sec_index, data, total_size, &err);
00270 p_blk = p_reloc->pr_first_block;
00271
00272
00273
00274
00275
00276 while (p_blk) {
00277
00278 unsigned long len =
00279 p_blk->rb_where_to_add_next - p_blk->rb_data;
00280
00281 memcpy(data, p_blk->rb_data, len);
00282
00283
00284 data += len;
00285
00286 p_blk_last = p_blk;
00287 p_blk = p_blk->rb_next;
00288
00289 _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
00290 }
00291
00292
00293
00294
00295
00296 p_reloc->pr_first_block = 0;
00297 p_reloc->pr_last_block = 0;
00298 }
00299
00300 *new_sec_count = sec_count;
00301 return DW_DLV_OK;
00302 }