Home | History | Annotate | Line # | Download | only in libdwarf
libdwarf_str.c revision 1.1
      1 /*-
      2  * Copyright (c) 2009,2010 Kai Wang
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     24  * SUCH DAMAGE.
     25  */
     26 
     27 #include "_libdwarf.h"
     28 
     29 ELFTC_VCSID("Id: libdwarf_str.c 2070 2011-10-27 03:05:32Z jkoshy ");
     30 
     31 #define	_INIT_DWARF_STRTAB_SIZE 1024
     32 
     33 int
     34 _dwarf_strtab_add(Dwarf_Debug dbg, char *string, uint64_t *off,
     35     Dwarf_Error *error)
     36 {
     37 	size_t len;
     38 
     39 	assert(dbg != NULL && string != NULL);
     40 
     41 	len = strlen(string) + 1;
     42 	while (dbg->dbg_strtab_size + len > dbg->dbg_strtab_cap) {
     43 		dbg->dbg_strtab_cap *= 2;
     44 		dbg->dbg_strtab = realloc(dbg->dbg_strtab,
     45 		    (size_t) dbg->dbg_strtab_cap);
     46 		if (dbg->dbg_strtab == NULL) {
     47 			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
     48 			return (DW_DLE_MEMORY);
     49 		}
     50 	}
     51 
     52 	if (off != NULL)
     53 		*off = dbg->dbg_strtab_size;
     54 
     55 	strncpy(&dbg->dbg_strtab[dbg->dbg_strtab_size], string, len - 1);
     56 	dbg->dbg_strtab_size += len;
     57 	dbg->dbg_strtab[dbg->dbg_strtab_size - 1] = '\0';
     58 
     59 	return (DW_DLE_NONE);
     60 }
     61 
     62 char *
     63 _dwarf_strtab_get_table(Dwarf_Debug dbg)
     64 {
     65 
     66 	assert(dbg != NULL);
     67 
     68 	return (dbg->dbg_strtab);
     69 }
     70 
     71 int
     72 _dwarf_strtab_init(Dwarf_Debug dbg, Dwarf_Error *error)
     73 {
     74 	Dwarf_Section *ds;
     75 
     76 	assert(dbg != NULL);
     77 
     78 	if (dbg->dbg_mode == DW_DLC_READ || dbg->dbg_mode == DW_DLC_RDWR) {
     79 		ds = _dwarf_find_section(dbg, ".debug_str");
     80 		if (ds == NULL) {
     81 			dbg->dbg_strtab = NULL;
     82 			dbg->dbg_strtab_cap = dbg->dbg_strtab_size = 0;
     83 			return (DW_DLE_NONE);
     84 		}
     85 
     86 		dbg->dbg_strtab_cap = dbg->dbg_strtab_size = ds->ds_size;
     87 
     88 		if (dbg->dbg_mode == DW_DLC_RDWR) {
     89 			if ((dbg->dbg_strtab = malloc((size_t) ds->ds_size)) ==
     90 			    NULL) {
     91 				DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
     92 				return (DW_DLE_MEMORY);
     93 			}
     94 			memcpy(dbg->dbg_strtab, ds->ds_data, ds->ds_size);
     95 		} else
     96 			dbg->dbg_strtab = (char *) ds->ds_data;
     97 	} else {
     98 		/* DW_DLC_WRITE */
     99 
    100 		dbg->dbg_strtab_cap = _INIT_DWARF_STRTAB_SIZE;
    101 		dbg->dbg_strtab_size = 0;
    102 
    103 		if ((dbg->dbg_strtab = malloc((size_t) dbg->dbg_strtab_cap)) ==
    104 		    NULL) {
    105 			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    106 			return (DW_DLE_MEMORY);
    107 		}
    108 
    109 		dbg->dbg_strtab[0] = '\0';
    110 	}
    111 
    112 	return (DW_DLE_NONE);
    113 }
    114 
    115 void
    116 _dwarf_strtab_cleanup(Dwarf_Debug dbg)
    117 {
    118 
    119 	assert(dbg != NULL);
    120 
    121 	if (dbg->dbg_mode == DW_DLC_RDWR || dbg->dbg_mode == DW_DLC_WRITE)
    122 		free(dbg->dbg_strtab);
    123 }
    124 
    125 int
    126 _dwarf_strtab_gen(Dwarf_P_Debug dbg, Dwarf_Error *error)
    127 {
    128 	Dwarf_P_Section ds;
    129 	int ret;
    130 
    131 	assert(dbg != NULL);
    132 
    133 	if ((ret = _dwarf_section_init(dbg, &ds, ".debug_str", 0, error)) !=
    134 	    DW_DLE_NONE)
    135 		return (ret);
    136 
    137 	if (dbg->dbg_strtab_size > ds->ds_cap) {
    138 		ds->ds_data = realloc(ds->ds_data,
    139 		    (size_t) dbg->dbg_strtab_size);
    140 		if (ds->ds_data == NULL) {
    141 			_dwarf_section_free(dbg, &ds);
    142 			DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
    143 			return (DW_DLE_MEMORY);
    144 		}
    145 		ds->ds_cap = dbg->dbg_strtab_size;
    146 	}
    147 
    148 	memcpy(ds->ds_data, dbg->dbg_strtab, dbg->dbg_strtab_size);
    149 	ds->ds_size = dbg->dbg_strtab_size;
    150 
    151 	/*
    152 	 * Inform application the creation of .debug_str ELF section.
    153 	 * Note that .debug_str use a different format than usual ELF
    154 	 * string table, so it should not have SHT_STRTAB as its type.
    155 	 */
    156 	ret = _dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error);
    157 
    158 	return (ret);
    159 }
    160