mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-07 13:33:06 +00:00
194 lines
5.4 KiB
C++
194 lines
5.4 KiB
C++
/* Copyright (C) 2021 Free Software Foundation, Inc.
|
|
Contributed by Oracle.
|
|
|
|
This file is part of GNU Binutils.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, 51 Franklin Street - Fifth Floor, Boston,
|
|
MA 02110-1301, USA. */
|
|
|
|
#include "config.h"
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include "util.h"
|
|
#include "DbeSession.h"
|
|
#include "Application.h"
|
|
#include "DataObject.h"
|
|
#include "Module.h"
|
|
#include "debug.h"
|
|
|
|
DataObject::DataObject ()
|
|
{
|
|
name = NULL;
|
|
parent = NULL;
|
|
master = NULL;
|
|
_unannotated_name = NULL;
|
|
_typename = NULL;
|
|
_instname = NULL;
|
|
scope = NULL;
|
|
EAs = new Vector<DbeEA*>;
|
|
size = 0;
|
|
offset = (uint64_t) (-1);
|
|
}
|
|
|
|
DataObject::~DataObject ()
|
|
{
|
|
free (_unannotated_name);
|
|
free (_typename);
|
|
free (_instname);
|
|
EAs->destroy ();
|
|
delete EAs;
|
|
}
|
|
|
|
// get_addr() doesn't return an actual address for a DataObject
|
|
// but rather synthesises an address-like identifier tuple.
|
|
// XXXX since an aggregate and its first element have identical tuples
|
|
// may need to arrange for special-purpose sorting "by address"
|
|
uint64_t
|
|
DataObject::get_addr ()
|
|
{
|
|
uint64_t addr;
|
|
if (parent && parent->get_typename ())
|
|
addr = MAKE_ADDRESS (parent->id, offset); // element
|
|
else if (parent)
|
|
addr = MAKE_ADDRESS (parent->id, id) | 0x8000000000000000ULL; // Scalar, Unknown
|
|
else if (id == dbeSession->get_Scalars_DataObject ()->id)
|
|
addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL; // Scalar aggregate
|
|
else if (id == dbeSession->get_Unknown_DataObject ()->id)
|
|
addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL; // Unknown aggregate
|
|
else
|
|
addr = MAKE_ADDRESS (id, 0); // aggregate
|
|
return addr;
|
|
}
|
|
|
|
Histable *
|
|
DataObject::convertto (Histable_type type, Histable *)
|
|
{
|
|
return type == DOBJECT ? this : NULL;
|
|
}
|
|
|
|
char
|
|
DataObject::get_offset_mark ()
|
|
{
|
|
enum
|
|
{
|
|
blocksize = 32
|
|
};
|
|
|
|
if (size == 0 || offset == -1)
|
|
return '?'; // undefined
|
|
if (size > blocksize)
|
|
return '#'; // requires multiple blocks
|
|
if (size == blocksize && (offset % blocksize == 0))
|
|
return '<'; // fits block entirely
|
|
if (offset % blocksize == 0)
|
|
return '/'; // starts block
|
|
if ((offset + size) % blocksize == 0)
|
|
return '\\'; // closes block
|
|
if (offset / blocksize == ((offset + size) / blocksize))
|
|
return '|'; // inside block
|
|
return 'X'; // crosses blocks unnecessarily
|
|
}
|
|
|
|
char *
|
|
DataObject::get_offset_name ()
|
|
{
|
|
char *offset_name;
|
|
if (parent && parent->get_typename ()) // element
|
|
offset_name = dbe_sprintf (GTXT ("%c%+6lld .{%s %s}"),
|
|
get_offset_mark (), (long long) offset,
|
|
_typename ? _typename : GTXT ("NO_TYPE"),
|
|
_instname ? _instname : GTXT ("-")); // "NO_NAME"
|
|
else if ((offset != -1) && (offset > 0)) // filler
|
|
offset_name = dbe_sprintf (GTXT ("%c%+6lld %s"), get_offset_mark (),
|
|
(long long) offset, get_name ());
|
|
else if (parent) // Scalar/Unknown element
|
|
offset_name = dbe_sprintf (GTXT (" .%s"), get_unannotated_name ());
|
|
else // aggregate
|
|
offset_name = dbe_strdup (get_name ());
|
|
return offset_name;
|
|
}
|
|
|
|
void
|
|
DataObject::set_dobjname (char *type_name, char *inst_name)
|
|
{
|
|
_unannotated_name = _typename = _instname = NULL;
|
|
if (inst_name)
|
|
_instname = dbe_strdup (inst_name);
|
|
|
|
char *buf;
|
|
if (parent == dbeSession->get_Scalars_DataObject ())
|
|
{
|
|
if (type_name)
|
|
_typename = dbe_strdup (type_name);
|
|
_unannotated_name = dbe_sprintf (NTXT ("{%s %s}"), type_name,
|
|
inst_name ? inst_name : NTXT ("-"));
|
|
buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
|
|
}
|
|
else if (parent == dbeSession->get_Unknown_DataObject ())
|
|
{
|
|
_unannotated_name = dbe_strdup (type_name);
|
|
buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
|
|
}
|
|
else
|
|
{
|
|
if (type_name)
|
|
_typename = dbe_strdup (type_name);
|
|
if (parent && parent->get_typename ())
|
|
buf = dbe_sprintf (NTXT ("%s.{%s %s}"),
|
|
parent->get_name () ? parent->get_name () : NTXT ("ORPHAN"),
|
|
type_name ? type_name : NTXT ("NO_TYPE"),
|
|
inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
|
|
else
|
|
buf = dbe_sprintf (NTXT ("{%s %s}"),
|
|
type_name ? type_name : NTXT ("NO_TYPE"),
|
|
inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
|
|
}
|
|
name = buf;
|
|
dbeSession->dobj_updateHT (this);
|
|
}
|
|
|
|
void
|
|
DataObject::set_name (char *string)
|
|
{
|
|
name = dbe_strdup (string);
|
|
dbeSession->dobj_updateHT (this);
|
|
}
|
|
|
|
DbeEA *
|
|
DataObject::find_dbeEA (Vaddr EA)
|
|
{
|
|
DbeEA *dbeEA;
|
|
int left = 0;
|
|
int right = EAs->size () - 1;
|
|
while (left <= right)
|
|
{
|
|
int index = (left + right) / 2;
|
|
dbeEA = EAs->fetch (index);
|
|
if (EA < dbeEA->eaddr)
|
|
right = index - 1;
|
|
else if (EA > dbeEA->eaddr)
|
|
left = index + 1;
|
|
else
|
|
return dbeEA;
|
|
}
|
|
|
|
// None found, create a new one
|
|
dbeEA = new DbeEA (this, EA);
|
|
EAs->insert (left, dbeEA);
|
|
return dbeEA;
|
|
}
|