|
Packit |
cdaae3 |
/*
|
|
Packit |
cdaae3 |
Copyright (C) 2010-2013 David Anderson. All rights reserved.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
Redistribution and use in source and binary forms, with or without
|
|
Packit |
cdaae3 |
modification, are permitted provided that the following conditions are met:
|
|
Packit |
cdaae3 |
* Redistributions of source code must retain the above copyright
|
|
Packit |
cdaae3 |
notice, this list of conditions and the following disclaimer.
|
|
Packit |
cdaae3 |
* Redistributions in binary form must reproduce the above copyright
|
|
Packit |
cdaae3 |
notice, this list of conditions and the following disclaimer in the
|
|
Packit |
cdaae3 |
documentation and/or other materials provided with the distribution.
|
|
Packit |
cdaae3 |
* Neither the name of the example nor the
|
|
Packit |
cdaae3 |
names of its contributors may be used to endorse or promote products
|
|
Packit |
cdaae3 |
derived from this software without specific prior written permission.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY
|
|
Packit |
cdaae3 |
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
Packit |
cdaae3 |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
Packit |
cdaae3 |
DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY
|
|
Packit |
cdaae3 |
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
Packit |
cdaae3 |
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
Packit |
cdaae3 |
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
Packit |
cdaae3 |
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
cdaae3 |
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit |
cdaae3 |
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
*/
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
// irepattrtodbg.cc
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
#include "config.h"
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
/* Windows specific header files */
|
|
Packit |
cdaae3 |
#ifdef HAVE_STDAFX_H
|
|
Packit |
cdaae3 |
#include "stdafx.h"
|
|
Packit |
cdaae3 |
#endif /* HAVE_STDAFX_H */
|
|
Packit |
cdaae3 |
#if HAVE_UNISTD_H
|
|
Packit |
cdaae3 |
#include <unistd.h>
|
|
Packit |
cdaae3 |
#endif
|
|
Packit |
cdaae3 |
#include <stdlib.h> // for exit
|
|
Packit |
cdaae3 |
#include <iostream>
|
|
Packit |
cdaae3 |
#include <sstream> // For BldName
|
|
Packit |
cdaae3 |
#include <iomanip> // iomanp for setw etc
|
|
Packit |
cdaae3 |
#include <string>
|
|
Packit |
cdaae3 |
#include <list>
|
|
Packit |
cdaae3 |
#include <map>
|
|
Packit |
cdaae3 |
#include <vector>
|
|
Packit |
cdaae3 |
#include <string.h> // For memset etc
|
|
Packit |
cdaae3 |
#include <sys/stat.h> //open
|
|
Packit |
cdaae3 |
#include <fcntl.h> //open
|
|
Packit |
cdaae3 |
#include "general.h"
|
|
Packit |
cdaae3 |
// gelf.h is a GNU-only elf header. FIXME
|
|
Packit |
cdaae3 |
#include "gelf.h"
|
|
Packit |
cdaae3 |
#include "strtabdata.h"
|
|
Packit |
cdaae3 |
#include "dwarf.h"
|
|
Packit |
cdaae3 |
#include "libdwarf.h"
|
|
Packit |
cdaae3 |
#include "irepresentation.h"
|
|
Packit |
cdaae3 |
#include "ireptodbg.h"
|
|
Packit |
cdaae3 |
#include "irepattrtodbg.h"
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
#ifdef HAVE_INTPTR_T
|
|
Packit |
cdaae3 |
#include <stdint.h>
|
|
Packit |
cdaae3 |
typedef intptr_t myintfromp; // intptr_t is from C99.
|
|
Packit |
cdaae3 |
#else
|
|
Packit |
cdaae3 |
// We want an integer that is big enough for a pointer so the
|
|
Packit |
cdaae3 |
// pointer return value from the libdwarf producer can be
|
|
Packit |
cdaae3 |
// tested for -1. Ugly overloading of integer and pointer in libdwarf.
|
|
Packit |
cdaae3 |
// We just hope it will compile for you.
|
|
Packit |
cdaae3 |
typedef long myintfromp;
|
|
Packit |
cdaae3 |
#endif
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
using std::string;
|
|
Packit |
cdaae3 |
using std::cout;
|
|
Packit |
cdaae3 |
using std::cerr;
|
|
Packit |
cdaae3 |
using std::endl;
|
|
Packit |
cdaae3 |
using std::vector;
|
|
Packit |
cdaae3 |
using std::list;
|
|
Packit |
cdaae3 |
using std::map;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
static Dwarf_Error error;
|
|
Packit |
cdaae3 |
static unsigned fakeaddrnum;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
// We are not going to 'validate' the FORM for this Attribute.
|
|
Packit |
cdaae3 |
// or this Die. We just assume that what we are handed is
|
|
Packit |
cdaae3 |
// what we are to produce. We do test the attribute
|
|
Packit |
cdaae3 |
// at times, partly to ensure we use as many of the dwarf_add_AT*
|
|
Packit |
cdaae3 |
// functions as possible.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
// Correctness/appropriateness must be evaluated elsewhere.
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
void
|
|
Packit |
cdaae3 |
AddAttrToDie(Dwarf_P_Debug dbg,
|
|
Packit |
cdaae3 |
IRepresentation & Irep,
|
|
Packit |
cdaae3 |
IRCUdata &cu,
|
|
Packit |
cdaae3 |
Dwarf_P_Die outdie,
|
|
Packit |
cdaae3 |
IRDie & irdie,IRAttr &irattr)
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
int attrnum = irattr.getAttrNum();
|
|
Packit |
cdaae3 |
enum Dwarf_Form_Class formclass = irattr.getFormClass();
|
|
Packit |
cdaae3 |
// IRForm is an abstract base class.
|
|
Packit |
cdaae3 |
IRForm *form = irattr.getFormData();
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
switch(formclass) {
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_UNKNOWN:
|
|
Packit |
cdaae3 |
cerr << "ERROR AddAttrToDie: Impossible DW_FORM_CLASS_UNKNOWN, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_ADDRESS:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
IRFormAddress *f = dynamic_cast<IRFormAddress *>(form);
|
|
Packit |
cdaae3 |
if (!f) {
|
|
Packit |
cdaae3 |
cerr << "ERROR Impossible DW_FORM_CLASS_ADDRESS cast fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
// FIXME: do better creating a symbol: try to match original
|
|
Packit |
cdaae3 |
// or specified input.
|
|
Packit |
cdaae3 |
Dwarf_Addr addr = f->getAddress();
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
string symname = BldName("addrsym",fakeaddrnum++);
|
|
Packit |
cdaae3 |
Dwarf_Addr pcval = addr;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
ElfSymbols& es = Irep.getElfSymbols();
|
|
Packit |
cdaae3 |
ElfSymIndex esi = es.addElfSymbol(pcval,symname);
|
|
Packit |
cdaae3 |
Dwarf_Unsigned sym_index = esi.getSymIndex();
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
// FIXME: we should allow for DW_FORM_indirect here.
|
|
Packit |
cdaae3 |
// Relocation later will fix value.
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a = dwarf_add_AT_targ_address_b(dbg,
|
|
Packit |
cdaae3 |
outdie,attrnum,0,sym_index,&error);
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_targ_address fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_BLOCK:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
//FIXME
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_CONSTANT:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
IRFormConstant *f = dynamic_cast<IRFormConstant *>(form);
|
|
Packit |
cdaae3 |
Dwarf_Half form = f->getFinalForm();
|
|
Packit |
cdaae3 |
// FIXME: Handle form indirect
|
|
Packit |
cdaae3 |
IRFormConstant::Signedness sn = f->getSignedness();
|
|
Packit |
cdaae3 |
Dwarf_Unsigned uval = 0;
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a = 0;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
if (form == DW_FORM_data16) {
|
|
Packit |
cdaae3 |
Dwarf_Form_Data16 val = f->getData16Val();
|
|
Packit |
cdaae3 |
int res = dwarf_add_AT_data16(outdie,
|
|
Packit |
cdaae3 |
attrnum,&val,&a,&error);
|
|
Packit |
cdaae3 |
if (res != DW_DLV_OK) {
|
|
Packit |
cdaae3 |
cerr <<
|
|
Packit |
cdaae3 |
"ERROR AddAttrToDie: "
|
|
Packit |
cdaae3 |
"dwarf_add_AT_ data16 class constant fails,"
|
|
Packit |
cdaae3 |
" attrnum " << attrnum <<
|
|
Packit |
cdaae3 |
" res "<
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if (sn == IRFormConstant::SIGNED) {
|
|
Packit |
cdaae3 |
Dwarf_Signed sval = f->getSignedVal();
|
|
Packit |
cdaae3 |
if (form == DW_FORM_sdata) {
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_any_value_sleb(
|
|
Packit |
cdaae3 |
outdie,attrnum,
|
|
Packit |
cdaae3 |
sval,&error);
|
|
Packit |
cdaae3 |
} else {
|
|
Packit |
cdaae3 |
//cerr << "ERROR how can we know "
|
|
Packit |
cdaae3 |
// "a non-sdata const is signed?, attrnum " <<
|
|
Packit |
cdaae3 |
// attrnum <
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_signed_const(dbg,
|
|
Packit |
cdaae3 |
outdie,attrnum,
|
|
Packit |
cdaae3 |
sval,&error);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
} else {
|
|
Packit |
cdaae3 |
Dwarf_Unsigned uval = f->getUnsignedVal();
|
|
Packit |
cdaae3 |
if (form == DW_FORM_udata) {
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_any_value_uleb(
|
|
Packit |
cdaae3 |
outdie,attrnum,
|
|
Packit |
cdaae3 |
uval,&error);
|
|
Packit |
cdaae3 |
} else {
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_unsigned_const(dbg,
|
|
Packit |
cdaae3 |
outdie,attrnum,
|
|
Packit |
cdaae3 |
uval,&error);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_ class constant fails,"
|
|
Packit |
cdaae3 |
" BADATTR on attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_EXPRLOC:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
//FIXME
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_FLAG:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
IRFormFlag *f = dynamic_cast<IRFormFlag *>(form);
|
|
Packit |
cdaae3 |
if (!f) {
|
|
Packit |
cdaae3 |
cerr << "ERROR Impossible DW_FORM_CLASS_FLAG cast fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
// FIXME: handle indirect form (libdwarf needs feature).
|
|
Packit |
cdaae3 |
// FIXME: handle implicit flag (libdwarf needs feature).
|
|
Packit |
cdaae3 |
// FIXME: rel type ok?
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a =
|
|
Packit |
cdaae3 |
dwarf_add_AT_flag(dbg,outdie,attrnum,f->getFlagVal(),&error);
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_flag fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_LINEPTR:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
// The DW_AT_stmt_list attribute is generated
|
|
Packit |
cdaae3 |
// as a side effect of dwarf_transform_to_disk_form
|
|
Packit |
cdaae3 |
// if producer line-info-creating functions were called.
|
|
Packit |
cdaae3 |
// So we ignore this attribute here, it is
|
|
Packit |
cdaae3 |
// automatic.
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_LOCLISTPTR:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
//FIXME. Needs support in dwarf producer(libdwarf)
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_MACPTR:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
// The DW_AT_macro_info attribute is generated
|
|
Packit |
cdaae3 |
// as a side effect of dwarf_transform_to_disk_form
|
|
Packit |
cdaae3 |
// if producer macro-creating functions were called.
|
|
Packit |
cdaae3 |
// So we ignore this attribute here, it is
|
|
Packit |
cdaae3 |
// automatic.
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_RANGELISTPTR:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
//FIXME. Needs support in dwarf producer(libdwarf)
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_REFERENCE:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
// Can be a local CU reference to a DIE, or a
|
|
Packit |
cdaae3 |
// global DIE reference or a
|
|
Packit |
cdaae3 |
// sig8 reference.
|
|
Packit |
cdaae3 |
//FIXME
|
|
Packit |
cdaae3 |
IRFormReference *r = dynamic_cast<IRFormReference *>(form);
|
|
Packit |
cdaae3 |
if (!r) {
|
|
Packit |
cdaae3 |
cerr << "ERROR Impossible DW_FORM_CLASS_REFERENCE cast fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
Dwarf_Half finalform = r->getFinalForm();
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
IRFormReference::RefType reftype = r->getReferenceType();
|
|
Packit |
cdaae3 |
switch (reftype) {
|
|
Packit |
cdaae3 |
case IRFormReference::RT_NONE:
|
|
Packit |
cdaae3 |
cerr << "ERROR CLASS REFERENCE unknown reftype "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case IRFormReference::RT_GLOBAL:
|
|
Packit |
cdaae3 |
// FIXME. Not handled.
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case IRFormReference::RT_CUREL:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
IRDie *targetofref = r->getTargetInDie();
|
|
Packit |
cdaae3 |
Dwarf_P_Die targetoutdie = 0;
|
|
Packit |
cdaae3 |
if(targetofref) {
|
|
Packit |
cdaae3 |
targetoutdie = targetofref->getGeneratedDie();
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if(!targetoutdie) {
|
|
Packit |
cdaae3 |
if(!targetofref) {
|
|
Packit |
cdaae3 |
cerr << "ERROR CLASS REFERENCE targetdie of reference unknown"
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
// We must add the attribute when we have the
|
|
Packit |
cdaae3 |
// target Dwarf_P_Die, which should get set shortly.
|
|
Packit |
cdaae3 |
// And do the dwarf_add_AT_reference() then.
|
|
Packit |
cdaae3 |
// Before transform_to_disk_form.
|
|
Packit |
cdaae3 |
// NULL targetoutdie allowed here.
|
|
Packit |
cdaae3 |
// Arranging DIE order so there were no forward-refs
|
|
Packit |
cdaae3 |
// could be difficult.
|
|
Packit |
cdaae3 |
// Another option would be two-pass: first create
|
|
Packit |
cdaae3 |
// all the DIEs then all the attributes for each.
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a =
|
|
Packit |
cdaae3 |
dwarf_add_AT_reference_b(dbg,outdie,attrnum,
|
|
Packit |
cdaae3 |
/*targetoutdie */NULL,&error);
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_reference fails, "
|
|
Packit |
cdaae3 |
"attrnum with not yet known targetoutdie "
|
|
Packit |
cdaae3 |
<< IToHex(attrnum) << endl;
|
|
Packit |
cdaae3 |
} else {
|
|
Packit |
cdaae3 |
ClassReferenceFixupData x(dbg,attrnum,outdie,targetofref);
|
|
Packit |
cdaae3 |
cu.insertClassReferenceFixupData(x);
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a =
|
|
Packit |
cdaae3 |
dwarf_add_AT_reference(dbg,outdie,attrnum,
|
|
Packit |
cdaae3 |
targetoutdie,&error);
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_reference fails, "
|
|
Packit |
cdaae3 |
"attrnum with known targetoutdie "
|
|
Packit |
cdaae3 |
<< IToHex(attrnum) << endl;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case IRFormReference::RT_SIG:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a =
|
|
Packit |
cdaae3 |
dwarf_add_AT_with_ref_sig8(outdie,attrnum,
|
|
Packit |
cdaae3 |
r->getSignature(),&error);
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_ref_sig8 fails, attrnum "
|
|
Packit |
cdaae3 |
<< IToHex(attrnum) << endl;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_STRING:
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
IRFormString *f = dynamic_cast<IRFormString *>(form);
|
|
Packit |
cdaae3 |
if (!f) {
|
|
Packit |
cdaae3 |
cerr << "ERROR Impossible DW_FORM_CLASS_STRING cast fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
Dwarf_P_Attribute a = 0;
|
|
Packit |
cdaae3 |
// We know libdwarf does not change the string. Historical mistake
|
|
Packit |
cdaae3 |
// not making it a const char * argument.
|
|
Packit |
cdaae3 |
// Ugly cast.
|
|
Packit |
cdaae3 |
// FIXME: handle indirect form (libdwarf needs feature).
|
|
Packit |
cdaae3 |
// FIXME: rel type ok?
|
|
Packit |
cdaae3 |
char *mystr = const_cast<char *>(f->getString().c_str());
|
|
Packit |
cdaae3 |
switch(attrnum) {
|
|
Packit |
cdaae3 |
case DW_AT_name:
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_name(outdie,mystr,&error);
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_AT_producer:
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_producer(outdie,mystr,&error);
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_AT_comp_dir:
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_comp_dir(outdie,mystr,&error);
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
default:
|
|
Packit |
cdaae3 |
a = dwarf_add_AT_string(dbg,outdie,attrnum,mystr,
|
|
Packit |
cdaae3 |
&error);
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
if( reinterpret_cast<myintfromp>(a) == DW_DLV_BADADDR) {
|
|
Packit |
cdaae3 |
cerr << "ERROR dwarf_add_AT_string fails, attrnum "
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
case DW_FORM_CLASS_FRAMEPTR: // SGI/MIPS/IRIX only.
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
//FIXME
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
break;
|
|
Packit |
cdaae3 |
default:
|
|
Packit |
cdaae3 |
cerr << "ERROR Impossible DW_FORM_CLASS "<<
|
|
Packit |
cdaae3 |
static_cast<int>(formclass)
|
|
Packit |
cdaae3 |
<
|
|
Packit |
cdaae3 |
//FIXME
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
return;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
|
|
Packit |
cdaae3 |
void
|
|
Packit |
cdaae3 |
IRCUdata::updateClassReferenceTargets()
|
|
Packit |
cdaae3 |
{
|
|
Packit |
cdaae3 |
for(std::list<ClassReferenceFixupData>::iterator it =
|
|
Packit |
cdaae3 |
classReferenceFixupList_.begin();
|
|
Packit |
cdaae3 |
it != classReferenceFixupList_.end();
|
|
Packit |
cdaae3 |
++it) {
|
|
Packit |
cdaae3 |
IRDie* d = it->target_;
|
|
Packit |
cdaae3 |
Dwarf_P_Die sourcedie = it->sourcedie_;
|
|
Packit |
cdaae3 |
Dwarf_P_Die targetdie = d->getGeneratedDie();
|
|
Packit |
cdaae3 |
Dwarf_Error error = 0;
|
|
Packit |
cdaae3 |
int res = dwarf_fixup_AT_reference_die(it->dbg_,
|
|
Packit |
cdaae3 |
it->attrnum_,sourcedie,targetdie,&error);
|
|
Packit |
cdaae3 |
if(res != DW_DLV_OK) {
|
|
Packit |
cdaae3 |
cerr << "Improper dwarf_fixup_AT_reference_die call"
|
|
Packit |
cdaae3 |
<< endl;
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
}
|
|
Packit |
cdaae3 |
|