Blame src/reader/pe_read_coff_symbol.c

edaa40
/***************************************************************/
edaa40
/*  perk: PE Resource Kit                                      */
edaa40
/*  Copyright (C) 2015--2016  Z. Gilboa                        */
edaa40
/*  Released under GPLv2 and GPLv3; see COPYING.PERK.          */
edaa40
/***************************************************************/
edaa40
edaa40
#include <string.h>
edaa40
edaa40
#include <perk/perk.h>
edaa40
#include "perk_endian_impl.h"
edaa40
#include "perk_reader_impl.h"
edaa40
edaa40
int pe_read_coff_symbol(
edaa40
	const struct pe_coff_symbol *		p,
edaa40
	struct pe_meta_coff_symbol *		m,
edaa40
	const struct pe_meta_coff_file_hdr *	coff,
edaa40
	void *					base)
edaa40
{
edaa40
	uint32_t	roffset;
edaa40
	char *		mark;
edaa40
	unsigned	bias = 0;
edaa40
edaa40
	m->long_name		= 0;
edaa40
	m->value		= pe_read_long(p->value);
edaa40
	m->section_number	= pe_read_short(p->section_number);
edaa40
	m->type			= pe_read_short(p->type);
edaa40
	m->storage_class	= p->storage_class[0];
edaa40
	m->num_of_aux_symbols	= p->num_of_aux_symbols[0];
edaa40
edaa40
	memset(m->name,0,sizeof(m->name));
edaa40
edaa40
	if (p->storage_class[0] == PE_IMAGE_SYM_CLASS_FILE)
edaa40
		if (p->num_of_aux_symbols[0])
edaa40
			if (!p[1].value[0])
edaa40
				bias = 1;
edaa40
edaa40
	p += bias;
edaa40
edaa40
	if (!bias && (p->storage_class[0] == PE_IMAGE_SYM_CLASS_FILE)
edaa40
			&& p->num_of_aux_symbols[0]) {
edaa40
		memcpy(m->name,p[1].name,sizeof(*p));
edaa40
edaa40
	} else if (p->name[0]) {
edaa40
		memcpy(m->name,p->name,sizeof(p->name));
edaa40
edaa40
	} else if (!p->name[1] && !p->name[2] && !p->name[3]) {
edaa40
		mark	= (char *)base;
edaa40
		roffset	= pe_read_long(&p->name[4]);
edaa40
edaa40
		if (roffset < coff->size_of_string_tbl)
edaa40
			m->long_name = mark + coff->ptr_to_string_tbl + roffset;
edaa40
	}
edaa40
edaa40
	return 0;
edaa40
}