You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
piklab/src/coff/base/coff_object.h

323 lines
11 KiB

/***************************************************************************
* Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
* *
* 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 2 of the License, or *
* (at your option) any later version. *
***************************************************************************/
#ifndef COFF_OBJECT_H
#define COFF_OBJECT_H
#include "coff.h"
#include "devices/base/register.h"
namespace Coff
{
//----------------------------------------------------------------------------
extern bool getName(const TQByteArray &data, uint &offset, uint nbChars, uint stringTableOffset, Log::Base &log, TQString &name);
extern int disassemble(long int opcode, long int opcode2, int org, Pic::Architecture architecture, char *buffer, size_t sizeof_buffer);
BEGIN_DECLARE_ENUM(OptHeaderFormat)
OldMicrochip = 0, NewMicrochip, Picc, Ccsc
END_DECLARE_ENUM_STD(OptHeaderFormat)
struct OptHeaderData {
uint magic;
OptHeaderFormat optHeaderFormat;
bool parsed;
};
extern const OptHeaderData OPT_HEADER_DATA[];
class Object;
class Section;
//----------------------------------------------------------------------------
class Element
{
public:
Element(const Object &object) : _object(object) {}
virtual ~Element() {}
protected:
const Object &_object;
};
//----------------------------------------------------------------------------
class BaseSymbol : public Element
{
public:
BaseSymbol(const Object &object) : Element(object) {}
virtual bool isAuxSymbol() const = 0;
};
BEGIN_DECLARE_ENUM(AuxSymbolType)
Direct = 0, File, Identifier, Section
END_DECLARE_ENUM_STD(AuxSymbolType)
class AuxSymbol : public BaseSymbol
{
public:
virtual bool isAuxSymbol() const { return true; }
static AuxSymbol *factory(const Object &object, AuxSymbolType type, const TQByteArray &data,
uint offset, uint stringTableOffset, Log::Base &log);
public:
AuxSymbol(const Object &object) : BaseSymbol(object) {}
virtual AuxSymbolType type() const = 0;
};
class AuxSymbolDirect : public AuxSymbol
{
public:
AuxSymbolDirect(const Object &object, const TQByteArray &data, uint offset, uint stringTableOffset, Log::Base &log);
virtual AuxSymbolType type() const { return AuxSymbolType::Direct; }
private:
uchar _command;
TQString _string;
};
class AuxSymbolFile : public AuxSymbol
{
public:
AuxSymbolFile(const Object &object, const TQByteArray &data, uint offset, uint stringTableOffset, Log::Base &log);
virtual AuxSymbolType type() const { return AuxSymbolType::File; }
TQString filename() const { return _filename; }
uint line() const { return _line; }
private:
uint _line;
TQString _filename;
};
class AuxSymbolIdentifier : public AuxSymbol
{
public:
AuxSymbolIdentifier(const Object &object, const TQByteArray &data, uint offset, uint stringTableOffset, Log::Base &log);
virtual AuxSymbolType type() const { return AuxSymbolType::Identifier; }
TQString string() const { return _string; }
private:
TQString _string;
};
class AuxSymbolSection : public AuxSymbol
{
public:
AuxSymbolSection(const Object &object, const TQByteArray &data, uint offset, uint stringTableOffset, Log::Base &log);
virtual AuxSymbolType type() const { return AuxSymbolType::Section; }
private:
uint _length, _nbRelocations, _nbLineNumbers;
};
class AuxSymbolUnknown : public AuxSymbol
{
public:
AuxSymbolUnknown(const Object &object) : AuxSymbol(object) {}
virtual AuxSymbolType type() const { return AuxSymbolType::Nb_Types; }
};
//----------------------------------------------------------------------------
BEGIN_DECLARE_ENUM(SymbolSectionType)
InsideSection = 0, UndefinedSection, AbsoluteValue, DebugSymbol
END_DECLARE_ENUM_STD(SymbolSectionType)
struct SymbolClassData {
const char *key, *label;
uint id;
};
BEGIN_DECLARE_ENUM(SymbolClass)
Automatic = 0, External, Static, Register, ExternalDefinition,
Label, UndefinedLabel, MemberOfStructure, FunctionArgument, StructureTag,
MemberOfUnion, UnionTag, TypeDefinition, UndefinedStatic, EnumerationTag,
MemberOfEnumeration, RegisterParameter, BitField, AutoArgument, EndOfBlock,
BeginEndOfBlock, BeginEndOfFunction, EndOfStructure, Filename, LineNumber,
DuplicateTag, Section
END_DECLARE_ENUM(SymbolClass, SymbolClassData)
struct SymbolTypeData {
const char *key, *label;
uint id;
};
BEGIN_DECLARE_ENUM(SymbolType)
Void = 0, Char, Short, Int, Long, Float, Double, Struct, Union,
Enum, MemberOfEnum, UChar, UShort, UInt, ULong, LongDouble
END_DECLARE_ENUM(SymbolType, SymbolTypeData)
struct SymbolDerivedTypeData {
const char *key, *label;
uint id;
};
BEGIN_DECLARE_ENUM(SymbolDerivedType)
Pointer = 0, Function, Array
END_DECLARE_ENUM(SymbolDerivedType, SymbolDerivedTypeData)
class Symbol : public BaseSymbol
{
public:
Symbol(const Object &object, const TQByteArray &data, uint offset, uint stringTableOffset,
const TQString &lastFilename, Log::Base &log);
virtual bool isAuxSymbol() const { return false; }
TQString name() const { return _name; }
TQString filename() const { return _filename; }
const TQValueVector<AuxSymbol *> &auxSymbols() const { return _aux; }
SymbolClass symbolClass() const { return _sclass; }
SymbolSectionType sectionType() const;
SymbolType type() const { return _type; }
SymbolDerivedType derivedType() const { return _dtype; }
uint value() const { return _value; }
uint section() const { Q_ASSERT( sectionType()==SymbolSectionType::InsideSection ); return _section; }
private:
TQString _name, _filename;
uint _value, _section;
SymbolClass _sclass;
SymbolType _type;
SymbolDerivedType _dtype;
TQValueVector<AuxSymbol *> _aux;
};
//----------------------------------------------------------------------------
class Relocation : public Element
{
public:
Relocation(const Object &object, const Section &section, const TQByteArray &data,
uint offset, Log::Base &log);
private:
ulong _address, _type;
short _offset;
const Symbol *_symbol;
};
//----------------------------------------------------------------------------
class CodeLine : public Element
{
public:
CodeLine(const Object &object, const Section &section, const TQByteArray &data,
uint offset, const TQString &lastFilename, Log::Base &log);
const Section &section() const { return _section; }
TQString filename() const { return _filename; }
uint line() const { return _line; }
Address address() const { return _address; }
const Symbol *symbol() const { return _symbol; }
private:
const Section &_section;
uint _line;
Address _address;
TQString _filename;
const Symbol *_symbol;
};
//----------------------------------------------------------------------------
BEGIN_DECLARE_ENUM(SectionType)
Config = 0, DeviceId, UserIds, UninitializedData, InitializedData, DataRom, Code
END_DECLARE_ENUM_STD(SectionType)
class Section : public Element
{
public:
class InstructionData {
public:
BitValue value;
TQString opcode, disasm;
};
public:
Section(const Device::Data &device, const Object &object, const TQByteArray &data, uint offset,
uint stringTableOffset, Log::Base &log);
~Section();
SectionType type() const;
TQString name() const { return _name; }
Address address() const { return _address; }
uint size() const { return _size; }
uint flags() const { return _flags; }
const TQMap<Address, InstructionData> &instructions() const { return _instructions; }
const TQValueVector<Relocation *> &relocations() const { return _relocations; }
const TQValueVector<CodeLine *> &lines() const { return _lines; }
private:
TQString _name;
Address _address;
uint _size, _flags;
TQMap<Address, InstructionData> _instructions;
TQValueVector<Relocation *> _relocations;
TQValueVector<CodeLine *> _lines;
enum Flag { FText = 0x00020, FData = 0x00040, FBSS = 0x00080, FDataRom = 0x00100,
FAbs = 0x01000, FShared = 0x02000, FOverlay = 0x04000, FAccess = 0x08000,
FActivationRecord = 0x10000 };
};
//----------------------------------------------------------------------------
class Object : public Base
{
public:
Object(const Device::Data *device, const PURL::Url &url);
virtual ~Object();
virtual bool parse(Log::Base &log);
Format format() const { return _format; }
const Device::Data *device() const { return _device; }
uint size(SizeType stype) const { return _format.data().sizes[stype]; }
OptHeaderFormat optHeaderFormat() const { return _optHeaderFormat; }
uint optHeaderMagic() const { return _optHeaderMagic; }
uint nbSymbols() const { return _symbols.count(); }
const BaseSymbol *symbol(uint i) const { return _symbols[i]; }
const Symbol *symbol(const TQString &name) const { return (_msymbols.contains(name) ? _msymbols[name] : 0); }
uint nbSections() const { return _sections.count(); }
const Section *section(uint i) const { return _sections[i]; }
const TQStringList &filenames() const { return _filenames; }
const TQMap<TQString, Address> &variables() const { return _variables; }
TQString variableName(Address address) const;
enum Flag { RelocationStripped = 0x0001, Executable = 0x0002, LineNumberStripped = 0x0004,
SymbolStripped = 0x0080, Extended18 = 0x4000, Generic = 0x8000 };
TQ_DECLARE_FLAGS(Flags, Flag)
protected:
TQ_UINT32 _optHeaderMagic;
OptHeaderFormat _optHeaderFormat;
const Device::Data *_device;
uint _nbSections, _nbSymbols, _symbolOffset;
Flags _flags;
TQValueVector<BaseSymbol *> _symbols;
TQMap<TQString, Symbol *> _msymbols; // name -> Symbol *
TQValueVector<Section *> _sections;
TQStringList _filenames;
TQMap<TQString, Address> _variables; // name -> address
virtual bool parseHeader(const TQByteArray &data, uint &offset, Log::Base &log);
virtual bool parseOptionnalHeader(const TQByteArray &data, uint &offset, Log::Base &log);
};
TQ_DECLARE_OPERATORS_FOR_FLAGS(Object::Flags)
} // namespace
//----------------------------------------------------------------------------
namespace Pic
{
class RegisterNameData
{
public:
RegisterNameData() {}
RegisterNameData(const TQString &label, const Register::TypeData &data) : _label(label), _data(data) {}
TQString label() const { return _label; }
const Register::TypeData &data() const { return _data; }
bool operator <(const RegisterNameData &rnd) const { return _label<rnd._label; };
private:
TQString _label;
Register::TypeData _data;
};
extern TQValueVector<RegisterNameData> sfrList(const Pic::Data &data);
extern TQValueVector<RegisterNameData> gprList(const Pic::Data &data, const Coff::Object *coff);
extern TQValueVector<RegisterNameData> variableList(const Pic::Data &data, const Coff::Object &coff);
} // namespace
#endif