tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2001,2004 Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
       
     5 
       
     6   This program is free software; you can redistribute it and/or modify it
       
     7   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     8   as published by the Free Software Foundation.
       
     9 
       
    10   This program is distributed in the hope that it would be useful, but
       
    11   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    13 
       
    14   Further, this software is distributed without any warranty that it is
       
    15   free of the rightful claim of any third person regarding infringement 
       
    16   or the like.  Any license provided herein, whether implied or 
       
    17   otherwise, applies only to this software file.  Patent licenses, if
       
    18   any, provided herein do not apply to combinations of this program with 
       
    19   other software, or any other product whatsoever.  
       
    20 
       
    21   You should have received a copy of the GNU Lesser General Public 
       
    22   License along with this program; if not, write the Free Software 
       
    23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    24   USA.
       
    25 
       
    26   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    27   Mountain View, CA 94043, or:
       
    28 
       
    29   http://www.sgi.com
       
    30 
       
    31   For further information regarding this notice, see:
       
    32 
       
    33   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    34 
       
    35 */
       
    36 
       
    37 
       
    38 
       
    39 #include "config.h"
       
    40 #include "libdwarfdefs.h"
       
    41 #include <stdio.h>
       
    42 #include <string.h>
       
    43 #ifdef HAVE_ELFACCESS_H
       
    44 #include <elfaccess.h>
       
    45 #else
       
    46 /* Set r_info  as defined by ELF generic ABI */
       
    47 #define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t))
       
    48 #define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t))
       
    49 #endif
       
    50 #include "pro_incl.h"
       
    51 #include "pro_section.h"
       
    52 #include "pro_reloc.h"
       
    53 #include "pro_reloc_stream.h"
       
    54 
       
    55 /*
       
    56 	Return DW_DLV_ERROR on malloc error or reltarget_length error.
       
    57 	Return DW_DLV_OK otherwise
       
    58 
       
    59 
       
    60 
       
    61 */
       
    62  /*ARGSUSED*/ int
       
    63 _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg,
       
    64 			       int base_sec_index,
       
    65 			       Dwarf_Unsigned offset,	/* r_offset of reloc */
       
    66 			       Dwarf_Unsigned symidx,
       
    67 			       enum Dwarf_Rel_Type type,
       
    68 			       int reltarget_length)
       
    69 {
       
    70 #if HAVE_ELF64_GETEHDR
       
    71     REL64 *elf64_reloc;
       
    72     void *relrec_to_fill;
       
    73     int res;
       
    74     int rel_type;
       
    75 
       
    76     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
       
    77 				      &relrec_to_fill);
       
    78     if (res != DW_DLV_OK)
       
    79 	return res;
       
    80 
       
    81 
       
    82     if (type == dwarf_drt_data_reloc) {
       
    83 	if (reltarget_length == dbg->de_offset_size) {
       
    84 	    rel_type = dbg->de_offset_reloc;
       
    85 	} else if (reltarget_length == dbg->de_pointer_size) {
       
    86 	    rel_type = dbg->de_ptr_reloc;
       
    87 	} else {
       
    88 	    return DW_DLV_ERROR;
       
    89 	}
       
    90     } else if (type == dwarf_drt_segment_rel) {
       
    91 	rel_type = dbg->de_exc_reloc;
       
    92     } else {
       
    93 	/* We are in trouble: improper use of stream relocations.
       
    94 	   Someone else will diagnose */
       
    95 	rel_type = 0;
       
    96     }
       
    97 
       
    98     elf64_reloc = (REL64 *)relrec_to_fill;
       
    99     elf64_reloc->r_offset = offset;
       
   100     Set_REL64_info(*elf64_reloc, symidx, rel_type);
       
   101     return DW_DLV_OK;
       
   102 #else /* !HAVE_ELF64_GETEHDR */
       
   103     return DW_DLV_ERROR;
       
   104 #endif /* #if HAVE_ELF64_GETEHDR */
       
   105 }
       
   106 
       
   107 /*
       
   108 	Return DW_DLV_ERROR on malloc error or reltarget_length error.
       
   109 	Return DW_DLV_OK otherwise
       
   110 	a binary reloc: 32bit ABI
       
   111 */
       
   112 int
       
   113 _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
       
   114 												   of 
       
   115 												   reloc 
       
   116 												 */
       
   117 			       Dwarf_Unsigned symidx,
       
   118 			       enum Dwarf_Rel_Type type,
       
   119 			       int reltarget_length)
       
   120 {
       
   121     REL32 *elf32_reloc;
       
   122     void *relrec_to_fill;
       
   123     int res;
       
   124     int rel_type;
       
   125 
       
   126     res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
       
   127 				      &relrec_to_fill);
       
   128     if (res != DW_DLV_OK)
       
   129 	return res;
       
   130     if (type == dwarf_drt_data_reloc) {
       
   131 	if (reltarget_length == dbg->de_offset_size) {
       
   132 	    rel_type = dbg->de_offset_reloc;
       
   133 	} else if (reltarget_length == dbg->de_pointer_size) {
       
   134 	    rel_type = dbg->de_ptr_reloc;
       
   135 	} else {
       
   136 	    return DW_DLV_ERROR;
       
   137 	}
       
   138     } else if (type == dwarf_drt_segment_rel) {
       
   139 	rel_type = dbg->de_exc_reloc;
       
   140     } else {
       
   141 	/* We are in trouble: improper use of stream relocations.
       
   142 	   Someone else will diagnose */
       
   143 	rel_type = 0;
       
   144     }
       
   145 
       
   146     elf32_reloc = (REL32*)relrec_to_fill;
       
   147     elf32_reloc->r_offset = (Elf32_Addr) offset;
       
   148     Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type);
       
   149     return DW_DLV_OK;
       
   150 
       
   151     /* get a slot, fill in the slot entry */
       
   152 }
       
   153 
       
   154 
       
   155 
       
   156 /*
       
   157 	Return DW_DLV_OK.
       
   158 	Never can really do anything: lengths cannot
       
   159 	be represented as end-start in a stream.
       
   160 
       
   161 */
       
   162  /*ARGSUSED*/ int
       
   163 _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
       
   164 												   of 
       
   165 												   reloc 
       
   166 												 */
       
   167 			       Dwarf_Unsigned start_symidx,
       
   168 			       Dwarf_Unsigned end_symidx,
       
   169 			       enum Dwarf_Rel_Type type,
       
   170 			       int reltarget_length)
       
   171 {
       
   172     /* get a slot, fill in the slot entry */
       
   173     return DW_DLV_OK;
       
   174 }
       
   175 
       
   176 
       
   177 /* 
       
   178         Ensure each stream is a single buffer and
       
   179         add that single buffer to the set of stream buffers.
       
   180 
       
   181 	By creating a new buffer and copying if necessary.
       
   182 
       
   183         Free the input set of buffers if we consolidate.
       
   184         Return -1 on error (malloc failure)
       
   185 
       
   186 
       
   187         Return DW_DLV_OK on success. Any other return indicates 
       
   188 	malloc failed.
       
   189 	
       
   190 */
       
   191 int
       
   192 _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
       
   193 			     Dwarf_Signed * new_sec_count)
       
   194 {
       
   195     unsigned long total_size = 0;
       
   196     Dwarf_Small *data;
       
   197     int sec_index;
       
   198     unsigned long i;
       
   199     Dwarf_Error err;
       
   200     Dwarf_Error *error = &err;
       
   201 
       
   202     Dwarf_Signed sec_count = 0;
       
   203 
       
   204     Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
       
   205 
       
   206     for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
       
   207 	unsigned long ct = p_reloc->pr_reloc_total_count;
       
   208 	unsigned len;
       
   209 	struct Dwarf_P_Relocation_Block_s *p_blk;
       
   210 	struct Dwarf_P_Relocation_Block_s *p_blk_last;
       
   211 	Dwarf_P_Per_Reloc_Sect prb;
       
   212 
       
   213 	if (ct == 0) {
       
   214 	    continue;
       
   215 	}
       
   216 	prb = &dbg->de_reloc_sect[i];
       
   217 	len = dbg->de_relocation_record_size;
       
   218 	++sec_count;
       
   219 
       
   220 	total_size = ct * len;
       
   221 	sec_index = prb->pr_sect_num_of_reloc_sect;
       
   222 	if (sec_index == 0) {
       
   223 	    /* call de_func or de_func_b, getting section number of
       
   224 	       reloc sec */
       
   225 	    int rel_section_index;
       
   226 	    Dwarf_Unsigned name_idx;
       
   227 	    int int_name;
       
   228 	    int err;
       
   229 
       
   230 	    if (dbg->de_func_b) {
       
   231 		rel_section_index =
       
   232 		    dbg->de_func_b(_dwarf_rel_section_names[i],
       
   233 				   /* size */
       
   234 				   dbg->de_relocation_record_size,
       
   235 				   /* type */ SHT_REL,
       
   236 				   /* flags */ 0,
       
   237 				   /* link to symtab, which we cannot
       
   238 				      know */ 0,
       
   239 				   /* info == link to sec rels apply to 
       
   240 				    */
       
   241 				   dbg->de_elf_sects[i],
       
   242 				   &name_idx, &err);
       
   243 	    } else {
       
   244 		rel_section_index =
       
   245 		    dbg->de_func(_dwarf_rel_section_names[i],
       
   246 				 /* size */
       
   247 				 dbg->de_relocation_record_size,
       
   248 				 /* type */ SHT_REL,
       
   249 				 /* flags */ 0,
       
   250 				 /* link to symtab, which we cannot
       
   251 				    know */ 0,
       
   252 				 /* info == link to sec rels apply to */
       
   253 				 dbg->de_elf_sects[i], &int_name, &err);
       
   254 		name_idx = int_name;
       
   255 	    }
       
   256 	    if (rel_section_index == -1) {
       
   257 		{
       
   258 		    _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR);
       
   259 		    return (DW_DLV_ERROR);
       
   260 		}
       
   261 
       
   262 	    }
       
   263 	    prb->pr_sect_num_of_reloc_sect = rel_section_index;
       
   264 	    sec_index = rel_section_index;
       
   265 	}
       
   266 	GET_CHUNK(dbg, sec_index, data, total_size, &err);
       
   267 	p_blk = p_reloc->pr_first_block;
       
   268 
       
   269 	/* following loop executes at least once. Effects the
       
   270 	   consolidation to a single block or, if already a single
       
   271 	   block, simply copies to the output buffer. And frees the
       
   272 	   input block. The new block is in the de_debug_sects list. */
       
   273 	while (p_blk) {
       
   274 
       
   275 	    unsigned long len =
       
   276 		p_blk->rb_where_to_add_next - p_blk->rb_data;
       
   277 
       
   278 	    memcpy(data, p_blk->rb_data, len);
       
   279 
       
   280 
       
   281 	    data += len;
       
   282 
       
   283 	    p_blk_last = p_blk;
       
   284 	    p_blk = p_blk->rb_next;
       
   285 
       
   286 	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
       
   287 	}
       
   288 	/* ASSERT: sum of len copied == total_size */
       
   289 
       
   290 	/* 
       
   291 	   We have copied the input, now drop the pointers to it. For
       
   292 	   debugging, leave the other data untouched. */
       
   293 	p_reloc->pr_first_block = 0;
       
   294 	p_reloc->pr_last_block = 0;
       
   295     }
       
   296 
       
   297     *new_sec_count = sec_count;
       
   298     return DW_DLV_OK;
       
   299 }