#include "config.h"
#include "libdwarfdefs.h"
#include <stdio.h>
#include <string.h>
#ifdef HAVE_ELFACCESS_H
#include <elfaccess.h>
#endif
#include "pro_incl.h"
#include "pro_section.h"
Dwarf_Unsigned
dwarf_add_typename(Dwarf_P_Debug dbg,
Dwarf_P_Die die,
char *type_name, Dwarf_Error * error)
{
return
_dwarf_add_simple_name_entry(dbg, die, type_name,
dwarf_snk_typename, error);
}
Dwarf_Unsigned
_dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
Dwarf_P_Die die,
char *entry_name,
enum dwarf_sn_kind entrykind,
Dwarf_Error * error)
{
Dwarf_P_Simple_nameentry nameentry;
Dwarf_P_Simple_name_header hdr;
char *name;
int uword_size;
if (dbg == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
return (0);
}
if (die == NULL) {
_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
return (0);
}
nameentry = (Dwarf_P_Simple_nameentry)
_dwarf_p_get_alloc(dbg,
sizeof(struct Dwarf_P_Simple_nameentry_s));
if (nameentry == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1);
if (name == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
strcpy(name, entry_name);
nameentry->sne_die = die;
nameentry->sne_name = name;
nameentry->sne_name_len = strlen(name);
uword_size = dbg->de_offset_size;
hdr = &dbg->de_simple_name_headers[entrykind];
if (hdr->sn_head == NULL)
hdr->sn_head = hdr->sn_tail = nameentry;
else {
hdr->sn_tail->sne_next = nameentry;
hdr->sn_tail = nameentry;
}
hdr->sn_count++;
hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1;
return (1);
}
int
_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index,
Dwarf_Error * error)
{
const Dwarf_Signed big_zero = 0;
Dwarf_P_Section_Data debug_sect;
Dwarf_Signed debug_info_size;
Dwarf_P_Simple_nameentry nameentry_original;
Dwarf_P_Simple_nameentry nameentry;
Dwarf_Small *stream_bytes;
Dwarf_Small *cur_stream_bytes_ptr;
Dwarf_Unsigned stream_bytes_count;
Dwarf_Unsigned adjusted_length;
int uword_size = dbg->de_offset_size;
int extension_size = dbg->de_64bit_extension ? 4 : 0;
Dwarf_P_Simple_name_header hdr;
debug_info_size = 0;
for (debug_sect = dbg->de_debug_sects; debug_sect != NULL;
debug_sect = debug_sect->ds_next) {
if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) {
debug_info_size += debug_sect->ds_nbytes;
}
}
hdr = &dbg->de_simple_name_headers[entrykind];
stream_bytes_count = extension_size + uword_size +
sizeof(Dwarf_Half) +
uword_size +
uword_size;
nameentry_original = hdr->sn_head;
nameentry = nameentry_original;
stream_bytes_count += hdr->sn_net_len;
stream_bytes_count += uword_size;
GET_CHUNK(dbg, dbg->de_elf_sects[section_index],
stream_bytes, (unsigned long) stream_bytes_count, error);
if (stream_bytes == NULL) {
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
cur_stream_bytes_ptr = stream_bytes;
if (extension_size) {
Dwarf_Unsigned x = DISTINGUISHED_VALUE;
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &x, sizeof(x), extension_size);
cur_stream_bytes_ptr += extension_size;
}
adjusted_length = stream_bytes_count - uword_size - extension_size;
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &adjusted_length,
sizeof(adjusted_length), uword_size);
cur_stream_bytes_ptr += uword_size;
{
Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &verstamp,
sizeof(verstamp), sizeof(Dwarf_Half));
cur_stream_bytes_ptr += sizeof(Dwarf_Half);
}
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &big_zero,
sizeof(big_zero), uword_size);
cur_stream_bytes_ptr += uword_size;
{
int res = dbg->de_reloc_name(dbg,
section_index,
extension_size + uword_size +
sizeof(Dwarf_Half)
,
dbg->de_sect_name_idx[DEBUG_INFO],
dwarf_drt_data_reloc,
uword_size);
if (res != DW_DLV_OK) {
{
_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
return (0);
}
}
}
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &debug_info_size,
sizeof(debug_info_size), uword_size);
cur_stream_bytes_ptr += uword_size;
for (nameentry = nameentry_original;
nameentry != NULL; nameentry = nameentry->sne_next) {
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &nameentry->sne_die->di_offset,
sizeof(nameentry->sne_die->di_offset),
uword_size);
cur_stream_bytes_ptr += uword_size;
strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name);
cur_stream_bytes_ptr += nameentry->sne_name_len + 1;
}
WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
(const void *) &big_zero,
sizeof(big_zero), uword_size);
return (int) dbg->de_n_debug_sect;
}