#include "config.h"
#ifdef HAVE_UNUSED_ATTRIBUTE
#define UNUSEDARG __attribute__ ((unused))
#else
#define UNUSEDARG
#endif
#if defined(_WIN32) && defined(HAVE_STDAFX_H)
#include "stdafx.h"
#endif /* HAVE_STDAFX_H */
#ifdef HAVE_UNITSTD_H
#include <unistd.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h> /* for exit() */
#endif /* HAVE_STDLIB_H */
#include <iostream>
#include <string>
#include <list>
#include <map>
#include <vector>
#include <string.h> // For memset etc
#include "strtabdata.h"
#include "dwarf.h"
#include "libdwarf.h"
#include "irepresentation.h"
#include "createirepfrombinary.h"
using
std::string;
using
std::cout;
using
std::cerr;
using
std::endl;
using
std::vector;
using
std::list;
class
IRFormInterface {
public
:
IRFormInterface(Dwarf_Debug dbg,
Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr):
dbg_(dbg),attr_(attr),cudata_(cudata),irattr_(irattr) {};
~IRFormInterface() {};
Dwarf_Debug dbg_;
Dwarf_Attribute attr_;
IRCUdata &cudata_;
IRAttr &irattr_;
private
:
IRFormInterface();
IRFormInterface& operator= (
const
IRFormInterface &ir);
};
IRForm *formFactory(Dwarf_Debug dbg,
Dwarf_Attribute attr,IRCUdata &cudata,IRAttr & irattr)
{
IRFormInterface interface(dbg,attr,cudata,irattr);
enum
Dwarf_Form_Class cl = irattr.getFormClass();
switch
(cl) {
case
DW_FORM_CLASS_UNKNOWN:
break
;
case
DW_FORM_CLASS_ADDRESS:
{
IRFormAddress *f =
new
IRFormAddress(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_BLOCK:
{
IRFormBlock *f =
new
IRFormBlock(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_CONSTANT:
{
IRFormConstant *f =
new
IRFormConstant(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_EXPRLOC:
{
IRFormExprloc *f =
new
IRFormExprloc(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_FLAG:
{
IRFormFlag *f =
new
IRFormFlag(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_LINEPTR:
{
IRFormLinePtr *f =
new
IRFormLinePtr(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_LOCLISTPTR:
{
IRFormLoclistPtr *f =
new
IRFormLoclistPtr(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_MACPTR:
{
IRFormMacPtr *f =
new
IRFormMacPtr(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_RANGELISTPTR:
{
IRFormRangelistPtr *f =
new
IRFormRangelistPtr(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_REFERENCE:
{
IRFormReference *f =
new
IRFormReference(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_STRING:
{
IRFormString *f =
new
IRFormString(&interface);
return
f;
}
break
;
case
DW_FORM_CLASS_FRAMEPTR:
{
IRFormFramePtr *f =
new
IRFormFramePtr(&interface);
return
f;
}
break
;
default
:
break
;
}
return
new
IRFormUnknown();
}
static
void
extractInterafaceForms(IRFormInterface *interface,
Dwarf_Half *finalform,
Dwarf_Half *initialform)
{
Dwarf_Error error = 0;
int
res = dwarf_whatform(interface->attr_,finalform,&error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to get attr form "
<< endl;
exit
(1);
}
res = dwarf_whatform_direct(interface->attr_,initialform,&error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to get attr direct form "
<< endl;
exit
(1);
}
}
IRFormAddress::IRFormAddress(IRFormInterface * interface)
{
Dwarf_Addr val = 0;
Dwarf_Error error = 0;
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_ = DW_FORM_CLASS_ADDRESS;
address_ = 0;
int
res = dwarf_formaddr(interface->attr_,&val, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read flag value. Impossible error.\n"
<< endl;
exit
(1);
}
address_ = val;
}
IRFormBlock::IRFormBlock(IRFormInterface * interface)
{
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_BLOCK;
fromloclist_= 0;
sectionoffset_=0;
Dwarf_Block *blockptr = 0;
Dwarf_Error error = 0;
int
res = dwarf_formblock(interface->attr_,&blockptr, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read flag value. Impossible error.\n"
<< endl;
exit
(1);
}
insertBlock(blockptr);
dwarf_dealloc(interface->dbg_,blockptr,DW_DLA_BLOCK);
}
IRFormConstant::IRFormConstant(IRFormInterface * interface)
{
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_CONSTANT;
signedness_=SIGN_NOT_SET;
uval_=0;
sval_=0;
Dwarf_Error error = 0;
if
(finalform == DW_FORM_data16) {
Dwarf_Form_Data16 data16;
int
rd16 = dwarf_formdata16(interface->attr_,&data16,
&error);
if
(rd16 != DW_DLV_OK) {
cerr <<
"Unable to read constant data16 value. "
"Impossible error.\n"
<< endl;
exit
(1);
}
setValues16(&data16, SIGN_UNKNOWN);
return
;
}
enum
Signedness oursign = SIGN_NOT_SET;
Dwarf_Unsigned uval = 0;
Dwarf_Signed sval = 0;
int
ress = dwarf_formsdata(interface->attr_, &sval,&error);
int
resu = dwarf_formudata(interface->attr_, &uval,&error);
if
(resu == DW_DLV_OK ) {
if
(ress == DW_DLV_OK) {
oursign = SIGN_UNKNOWN;
}
else
{
oursign = UNSIGNED;
sval =
static_cast
<Dwarf_Signed>(uval);
}
}
else
{
if
(ress == DW_DLV_OK) {
oursign = SIGNED;
uval =
static_cast
<Dwarf_Unsigned>(sval);
}
else
{
cerr <<
"Unable to read constant value. Impossible error.\n"
<< endl;
exit
(1);
}
}
setValues(sval, uval, oursign);
}
IRFormExprloc::IRFormExprloc(IRFormInterface * interface)
{
Dwarf_Unsigned len = 0;
Dwarf_Ptr data = 0;
Dwarf_Error error = 0;
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_EXPRLOC;
int
res = dwarf_formexprloc(interface->attr_,&len, &data, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read flag value. Impossible error.\n"
<< endl;
exit
(1);
}
insertBlock(len,data);
}
IRFormFlag::IRFormFlag(IRFormInterface * interface)
{
Dwarf_Bool flagval = 0;
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_FLAG;
flagval_=0;
Dwarf_Error error = 0;
int
res = dwarf_formflag(interface->attr_,&flagval, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read flag value. Impossible error.\n"
<< endl;
exit
(1);
}
setFlagVal(flagval);
setFinalForm(finalform);
setInitialForm(initialform);
}
static
Dwarf_Unsigned
get_section_offset(IRFormInterface * interface)
{
Dwarf_Unsigned uval = 0;
Dwarf_Signed sval = 0;
Dwarf_Error error = 0;
Dwarf_Off sectionoffset = 0;
int
resu = 0;
int
resgf = dwarf_global_formref(interface->attr_,
§ionoffset, &error);
if
(resgf == DW_DLV_OK ) {
return
sectionoffset;
}
resu = dwarf_formudata(interface->attr_, &uval,&error);
if
(resu != DW_DLV_OK ) {
int
ress = dwarf_formsdata(interface->attr_, &sval,&error);
if
(ress == DW_DLV_OK) {
uval =
static_cast
<Dwarf_Unsigned>(sval);
}
else
{
cerr <<
"Unable to read constant offset value. Impossible error.\n"
<< endl;
exit
(1);
}
}
return
uval;
}
IRFormLoclistPtr::IRFormLoclistPtr(IRFormInterface * interface)
{
Dwarf_Unsigned uval = get_section_offset(interface);
setOffset(uval);
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_LOCLISTPTR;
loclist_offset_=0;
}
IRFormLinePtr::IRFormLinePtr(IRFormInterface * interface)
{
Dwarf_Unsigned uval = get_section_offset(interface);
setOffset(uval);
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
}
IRFormMacPtr::IRFormMacPtr(IRFormInterface * interface)
{
Dwarf_Unsigned uval = get_section_offset(interface);
setOffset(uval);
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_MACPTR;
macro_offset_=0;
}
IRFormRangelistPtr::IRFormRangelistPtr(IRFormInterface * interface)
{
Dwarf_Unsigned uval = get_section_offset(interface);
setOffset(uval);
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_RANGELISTPTR;
rangelist_offset_=0;
}
IRFormFramePtr::IRFormFramePtr(IRFormInterface * interface)
{
Dwarf_Unsigned uval = get_section_offset(interface);
setOffset(uval);
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_FRAMEPTR;
frame_offset_=0;
}
IRFormReference::IRFormReference(IRFormInterface * interface)
{
Dwarf_Off val = 0;
Dwarf_Error error = 0;
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
formclass_ = DW_FORM_CLASS_REFERENCE;
reftype_ = RT_NONE;
globalOffset_ = 0;
cuRelativeOffset_ = 0;
targetInputDie_= 0;
target_die_= 0;
initSig8();
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
IRCUdata &cudata = interface->cudata_;
if
(finalform == DW_FORM_ref_sig8) {
Dwarf_Sig8 val8;
int
res = dwarf_formsig8(interface->attr_,&val8, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read sig8 reference. Impossible error.\n"
<< endl;
exit
(1);
}
setSignature(&val8);
return
;
}
if
(finalform == DW_FORM_ref_addr ||
finalform == DW_FORM_data4 ||
finalform == DW_FORM_data8) {
int
res = dwarf_global_formref(interface->attr_,&val, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read reference. Impossible error.\n"
<< endl;
exit
(1);
}
setOffset(val);
return
;
}
int
res = dwarf_formref(interface->attr_,&val, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read reference.. Impossible error. finalform "
<<
finalform << endl;
exit
(1);
}
setCUOffset(val);
cudata.insertLocalReferenceAttrTargetRef(val,
this
);
IRDie *targdie = cudata.getLocalDie(val);
if
(targdie) {
setTargetInDie(targdie);
}
}
static
Dwarf_Sig8 zero_sig8;
void
IRFormReference::initSig8()
{
typeSig8_ = zero_sig8;
}
IRFormString::IRFormString(IRFormInterface * interface)
{
char
*str = 0;
Dwarf_Error error = 0;
Dwarf_Half finalform = 0;
Dwarf_Half initialform = 0;
extractInterafaceForms(interface,&finalform,&initialform);
setFinalForm(finalform);
setInitialForm(initialform);
formclass_=DW_FORM_CLASS_STRING;
strpoffset_=0;
int
res = dwarf_formstring(interface->attr_,&str, &error);
if
(res != DW_DLV_OK) {
cerr <<
"Unable to read string. Impossible error.\n"
<< endl;
exit
(1);
}
setString(str);
}