/*******************************************************************************
 * Copyright (c) 2006-2007 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html 
 *  
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/

/*
 * This module implements low-level functions for reading DWARF debug information.
 *
 * Functions in this module use exceptions to report errors, see exceptions.h
 */
#include "config.h"
#if SERVICE_LineNumbers

#include <assert.h>
#include <string.h>
#include "dwarfio.h"
#include "dwarf.h"
#include "myalloc.h"
#include "exceptions.h"

#define INP_BUF_SIZE            0x1000
#define ABBREV_TABLE_SIZE       1021

struct DIO_Abbreviation {
    U2_T mTag;
    U1_T mChildren;
    U4_T mAttrLen;
    U2_T mAttrs[2];
};

typedef struct DIO_Abbreviation DIO_Abbreviation;

struct DIO_AbbrevSet {
    struct DIO_AbbrevSet * mNext;
    ELF_File * mFile;
    U8_T mOffset;
    DIO_Abbreviation ** mTable;
    U4_T mSize;
};

typedef struct DIO_AbbrevSet DIO_AbbrevSet;

struct DIO_Cache {
    U1_T * mStringTable;
    U4_T mStringTableSize;
    DIO_AbbrevSet ** mAbbrevTable;
};

typedef struct DIO_Cache DIO_Cache;

U4_T dio_gVersion = 0;
U1_T dio_g64bit = 0;
U1_T dio_gAddressSize = 4;
U8_T dio_gUnitPos = 0;
U4_T dio_gUnitSize = 0;
U8_T dio_gEntryPos = 0;

U8_T dio_gFormRef;
U8_T dio_gFormData = 0;
U1_T dio_gFormDataSize = 0;
U4_T dio_gFormBlockSize = 0;
U1_T * dio_gFormBlockBuf = NULL;

static ELF_Section * sSection;
static U1_T sBigEndian;
static DIO_Abbreviation ** sAbbrevTable = NULL;
static U4_T sAbbrevTableSize = 0;
static U1_T * sInpBuf = NULL;
static U4_T sBufPos;
static U4_T sBufLen;
static U8_T sDataPos;

static void dio_CloseELF(ELF_File * File) {
    U4_T n, m;
    DIO_Cache * Cache = (DIO_Cache *)File->dwarf_cache;

    if (Cache == NULL) return;
    for (n = 0; n < ABBREV_TABLE_SIZE; n++) {
        DIO_AbbrevSet * Set = Cache->mAbbrevTable[n];
        while (Set != NULL) {
            DIO_AbbrevSet * Next = Set->mNext;
            for (m = 0; m < Set->mSize; m++) {
                loc_free(Set->mTable[m]);
            }
            loc_free(Set->mTable);
            loc_free(Set);
            Set = Next;
        }
    }
    loc_free(Cache->mAbbrevTable);
    File->dwarf_cache = NULL;
}

static DIO_Cache * dio_GetCache(ELF_File * File) {
    static int Inited = 0;
    DIO_Cache * Cache = (DIO_Cache *)File->dwarf_cache;

    if (!Inited) {
        elf_add_close_listener(dio_CloseELF);
        Inited = 1;
    }
    if (Cache == NULL) {
        Cache = (DIO_Cache *)(File->dwarf_cache = loc_alloc_zero(sizeof(DIO_Cache)));
    }
    return Cache;
}

void dio_EnterSection(ELF_Section * Section, U8_T Offset) {
    sSection = Section;
    sDataPos = Offset;
    sBufPos = 0;
    sBufLen = 0;
    sBigEndian = Section->file->big_endian;

    if (sInpBuf == NULL) {
        sInpBuf = (U1_T *)loc_alloc(INP_BUF_SIZE);
    }
}

void dio_ExitSection() {
    sSection = NULL;
    sDataPos = 0;
    sBufPos = 0;
    sBufLen = 0;
}

U8_T dio_GetPos() {
    return sDataPos;
}

void dio_Skip(U8_T Bytes) {
    sDataPos += Bytes;
    if (sBufPos + Bytes >= sBufLen) {
        sBufPos = 0;
        sBufLen = 0;
    }
    else {
        sBufPos += (U4_T)Bytes;
    }
}

void dio_Read(U1_T * Buf, U4_T Size) {
    assert(sSection->size >= sDataPos + Size);
    if (sBufPos < sBufLen) {
        U4_T FromBuf = Size < sBufLen - sBufPos ? Size : sBufLen - sBufPos;
        memcpy(Buf, sInpBuf + sBufPos, FromBuf);
        sBufPos += FromBuf;
        Buf += FromBuf;
        Size -= FromBuf;
        sDataPos += FromBuf;
    }
    if (Size > 0) {
        U4_T Rd = 0;
        if (elf_read(sSection, sDataPos, Buf, Size, &Rd) < 0) exception(errno);
        if (Rd < Size) exception(ERR_EOF);
        assert(sBufPos >= sBufLen);
        sDataPos += Size;
    }
}

U1_T dio_ReadU1F(void) {
    U1_T c;
    if (sDataPos >= sSection->size) exception(ERR_EOF);
    if (sBufPos < sBufLen) {
        c = sInpBuf[sBufPos++];
    }
    else if (sBufPos >= sBufLen) {
        U4_T Rd = 0;
        U8_T Size = sSection->size - sDataPos;
        if (Size > INP_BUF_SIZE) Size = INP_BUF_SIZE;
        if (elf_read(sSection, sDataPos, sInpBuf, (U4_T)Size, &Rd) < 0) exception(errno);
        if (Rd == 0) exception(ERR_EOF);
        sBufLen = Rd;
	c = sInpBuf[0];
        sBufPos = 1;
    }
    sDataPos++;
    return c;
}

U1_T dio_ReadU1(void) {
    return sBufPos >= sBufLen ? dio_ReadU1F() : (sDataPos++, sInpBuf[sBufPos++]);
}

#define dio_ReadU1() (sBufPos >= sBufLen ? dio_ReadU1F() : (sDataPos++, sInpBuf[sBufPos++]))

U2_T dio_ReadU2(void) {
    U1_T x0 = dio_ReadU1();
    U1_T x1 = dio_ReadU1();
    return sBigEndian ? (x0 << 8) | x1 : x0 | (x1 << 8);
}
                
U4_T dio_ReadU4(void) {
    U2_T x0 = dio_ReadU2();
    U2_T x1 = dio_ReadU2();
    return sBigEndian ? (x0 << 16) | x1 : x0 | (x1 << 16);
}

U8_T dio_ReadU8(void) {
    U8_T x0 = dio_ReadU4();
    U8_T x1 = dio_ReadU4();
    return sBigEndian ? (x0 << 32) | x1 : x0 | (x1 << 32);
}

U4_T dio_ReadLEB128(void) {
    U4_T res = 0;
    int i = 0;
    for (;; i += 7) {
	U1_T n = dio_ReadU1();
	res |= (n & 0x7Fu) << i;
	if ((n & 0x80) == 0) break;
    }
    return res;
}

U8_T dio_ReadU8LEB128(void) {
    U8_T res = 0;
    int i = 0;
    for (;; i += 7) {
	U1_T n = dio_ReadU1();
	res |= (n & 0x7Fu) << i;
	if ((n & 0x80) == 0) break;
    }
    return res;
}

I8_T dio_ReadI8LEB128(void) {
    U8_T res = 0;
    int i = 0;
    for (;; i += 7) {
	U1_T n = dio_ReadU1();
	res |= (n & 0x7Fu) << i;
        if ((n & 0x80) == 0) {
	    res |= -(n & 0x40) << i;
            break;
        }
    }
    return (I8_T)res;
}

U8_T dio_ReadUX(int Size) {
    switch (Size) {
    case 2:
        return dio_ReadU2();
    case 4:
        return dio_ReadU4();
    case 8:
        return dio_ReadU8();
    default:
        assert(0);
        return 0;
    }
}

U8_T dio_ReadAddress(void) {
    switch (dio_gAddressSize) {
    case 2:
        return dio_ReadU2();
    case 4:
        return dio_ReadU4();
    case 8:
        return dio_ReadU8();
    default:
        assert(0);
        return 0;
    }
}

static void dio_CheckBlockBufCapacity(U4_T Size) {
    static U4_T BufSize = 0;
    if (BufSize < Size) { 
        BufSize = BufSize == 0 ? 0x100 : BufSize * 2;
        dio_gFormBlockBuf = (U1_T *)loc_realloc(dio_gFormBlockBuf, BufSize);
    }
}

char * dio_ReadString(void) {
    char * Res = NULL;
    U4_T Length = 0;
    for (;;) {
        U1_T Char = dio_ReadU1();
        dio_CheckBlockBufCapacity(Length + 1);
        dio_gFormBlockBuf[Length++] = Char;
        if (Char == 0) break;
    }
    if (Length == 1) return NULL;
    Res = (char *)loc_alloc(Length);
    strcpy(Res, (char *)dio_gFormBlockBuf);
    return Res;
}

U8_T dio_ReadAddrBuf(U1_T * Buf) {
    int i;
    U8_T Addr = 0;
    for (i = 0; i < dio_gAddressSize; i++) {
        U8_T Byte = (U8_T)Buf[i];
        if (sBigEndian) {
            Addr |= Byte << ((dio_gAddressSize - i - 1) * 8);
        }
        else {
            Addr |= Byte << (i * 8);
        }
    }
    return Addr;
}

static U1_T * dio_LoadStringTable(U4_T * StringTableSize) {
    ELF_File * File = sSection->file;
    DIO_Cache * Cache = dio_GetCache(File);

    if (Cache->mStringTable == NULL) {
        U4_T ID;
        ELF_Section * Section = NULL;

        for (ID = 1; ID < File->section_cnt; ID++) {
            if (strcmp(File->sections[ID]->name, ".debug_str") == 0) {
                if (Section != NULL) {
                    str_exception(ERR_DWARF, "more then one .debug_str section in a file");
                }
                Section = File->sections[ID];
                assert(Section->file == File);
            }
        }

        if (Section == NULL) {
            str_exception(ERR_DWARF, "section .debug_str not found");
        }

        Cache->mStringTableSize = (size_t)Section->size;
        if (elf_load(Section, &Cache->mStringTable) < 0) {
            str_exception(ERR_DWARF, "invalid .debug_str section");
        }
    }

    *StringTableSize = Cache->mStringTableSize;
    return Cache->mStringTable;
}

static void dio_ReadFormAddr(void) {
    dio_gFormRef = dio_ReadAddress();
}

static void dio_ReadFormBlock(U2_T Attr, U4_T Size) {
    U1_T * Buf;
    dio_gFormBlockSize = Size;
    dio_CheckBlockBufCapacity(Size);
    Buf = dio_gFormBlockBuf;
    while (Size > 0) {
        *Buf++ = dio_ReadU1();
        Size--;
    }
}

static void dio_ReadFormData(U2_T Attr, U1_T Size, U8_T Data) {
    dio_gFormData = Data;
    dio_gFormDataSize = Size;
}

static void dio_ReadFormFlag(void) {
    dio_gFormData = dio_ReadU1();
    dio_gFormDataSize = 1;
}

static void dio_ReadFormRef(void) {
    dio_gFormRef = dio_ReadU4();
}

static void dio_ReadFormRelRef(U8_T Offset) {
    if (dio_gUnitSize > 0 && Offset >= dio_gUnitSize) {
        str_exception(ERR_DWARF, "invalid REF attribute value");
    }
    dio_gFormRef = dio_gUnitPos + Offset;
}

static void dio_ReadFormRefAddr(void) {
    U4_T Size = dio_gAddressSize;
    if (dio_gVersion >= 3) Size = dio_g64bit ? 8 : 4;
    dio_gFormRef = dio_ReadUX(Size);
}

static void dio_ReadFormString(void) {
    dio_gFormBlockSize = 0;
    for (;;) {
        U1_T Char = dio_ReadU1();
        dio_CheckBlockBufCapacity(dio_gFormBlockSize + 1);
        dio_gFormBlockBuf[dio_gFormBlockSize++] = Char;
        if (Char == 0) break;
    }
}

static void dio_ReadFormStringRef(void) {
    U8_T Offset = dio_ReadUX(dio_g64bit ? 8 : 4);
    U4_T StringTableSize = 0;
    U1_T * StringTable = dio_LoadStringTable(&StringTableSize);
    dio_gFormBlockSize = 0;
    for (;;) {
        U1_T Char;
        if (Offset >= StringTableSize) {
            str_exception(ERR_DWARF, "invalid FORM_STRP attribute");
        }
        dio_CheckBlockBufCapacity(dio_gFormBlockSize + 1);
        Char = StringTable[Offset++];
        dio_gFormBlockBuf[dio_gFormBlockSize++] = Char;
        if (Char == 0) break;
    }
}

static void dio_ReadAttribute(U2_T Attr, U2_T Form) {
    switch (Form) {
    case FORM_ADDR      : dio_ReadFormAddr(); break;
    case FORM_REF       : dio_ReadFormRef(); break;
    case FORM_BLOCK1    : dio_ReadFormBlock(Attr, dio_ReadU1()); break;
    case FORM_BLOCK2    : dio_ReadFormBlock(Attr, dio_ReadU2()); break;
    case FORM_BLOCK4    : dio_ReadFormBlock(Attr, dio_ReadU4()); break;
    case FORM_BLOCK     : dio_ReadFormBlock(Attr, dio_ReadLEB128()); break;
    case FORM_DATA1     : dio_ReadFormData(Attr, 1, dio_ReadU1()); break;
    case FORM_DATA2     : dio_ReadFormData(Attr, 2, dio_ReadU2()); break;
    case FORM_DATA4     : dio_ReadFormData(Attr, 4, dio_ReadU4()); break;
    case FORM_DATA8     : dio_ReadFormData(Attr, 8, dio_ReadU8()); break;
    case FORM_SDATA     : dio_ReadFormData(Attr, 8, dio_ReadI8LEB128()); break;
    case FORM_UDATA     : dio_ReadFormData(Attr, 8, dio_ReadU8LEB128()); break;
    case FORM_FLAG      : dio_ReadFormFlag(); break;
    case FORM_STRING    : dio_ReadFormString(); break;
    case FORM_STRP      : dio_ReadFormStringRef(); break;
    case FORM_REF_ADDR  : dio_ReadFormRefAddr(); break;
    case FORM_REF1      : dio_ReadFormRelRef(dio_ReadU1()); break;
    case FORM_REF2      : dio_ReadFormRelRef(dio_ReadU2()); break;
    case FORM_REF4      : dio_ReadFormRelRef(dio_ReadU4()); break;
    case FORM_REF8      : dio_ReadFormRelRef(dio_ReadU8()); break;
    case FORM_REF_UDATA : dio_ReadFormRelRef(dio_ReadLEB128()); break;
    default: str_exception(ERR_DWARF, "invalid FORM");
    }
}

static void dio_ReadEntry(DIO_EntryCallBack CallBack) {
    DIO_Abbreviation * Abbr = NULL;
    U2_T Tag = 0;
    U4_T AttrPos = 0;
    U4_T EntrySize = 0;
    int Init = 1;
    dio_gEntryPos = dio_GetPos();
    if (dio_gVersion >= 2) {
        U4_T AbbrCode = dio_ReadLEB128();
        if (AbbrCode == 0) return;
        if (AbbrCode >= sAbbrevTableSize || sAbbrevTable[AbbrCode] == NULL) {
            str_exception(ERR_DWARF, "invalid abbreviation table");
        }
        Abbr =  sAbbrevTable[AbbrCode];
        Tag = Abbr->mTag;
    }
    else {
        EntrySize = dio_ReadU4();
        if (EntrySize < 8) {
            while (EntrySize > 4) {
                dio_ReadU1();
                EntrySize--;
            }
            return;
        }
        Tag = dio_ReadU2();
    }
    for (;;) {
	U2_T Attr = 0;
	U2_T Form = 0;
        if (Init) {
            Form = 1;
            Init = 0;
        }
	else if (Abbr != NULL) {
            if (AttrPos < Abbr->mAttrLen) {
		Attr = Abbr->mAttrs[AttrPos++];
		Form = Abbr->mAttrs[AttrPos++];
		if (Form == FORM_INDIRECT) Form = (U2_T)dio_ReadLEB128();
            }
	}
	else {
            if (dio_GetPos() < dio_gEntryPos + EntrySize) {
		Attr = dio_ReadU2();
		Form = Attr & 0xF;
		Attr = (Attr & 0xfff0) >> 4;
            }
	}
        if (Attr != 0 && Form != 0) dio_ReadAttribute(Attr, Form);
        if (Tag == TAG_compile_unit) {
            if (Attr == AT_sibling && dio_gUnitSize == 0) {
                dio_ChkRef(Form);
                assert(dio_gVersion == 1);
                dio_gUnitSize = (U4_T)(dio_gFormRef - dio_gUnitPos);
                assert(dio_gUnitPos < dio_GetPos());
                assert(dio_gUnitPos + dio_gUnitSize >= dio_GetPos());
            }
            else if (Attr == 0 && Form == 0) {
                if (dio_gUnitSize == 0) str_exception(ERR_DWARF, "missing compilation unit sibling attribute");
            }
        }
        CallBack(Tag, Attr, Form);
        if (Attr == 0 && Form == 0) break;
    }
}

static void dio_FindAbbrevTable(U4_T Offset, DIO_Abbreviation *** AbbrevTable, U4_T * AbbrevTableSize);

void dio_ReadUnit(DIO_EntryCallBack CallBack) {
    dio_gUnitPos = dio_GetPos();
    dio_g64bit = 0;
    if (dio_gVersion >= 2) {
        dio_gUnitSize = dio_ReadU4();
        if (dio_gUnitSize == 0xffffffffu) {
            dio_g64bit = 1;
            str_exception(ERR_DWARF, "64-bit DWARF is not supported yet");
        }
        else {
            dio_gUnitSize += 4;
        }
        dio_gVersion = dio_ReadU2();
        dio_FindAbbrevTable(dio_ReadU4(), &sAbbrevTable, &sAbbrevTableSize);
        dio_gAddressSize = dio_ReadU1();
    }
    else {
        dio_gUnitSize = 0;
        dio_gVersion = 1;
        dio_gAddressSize = 4;
        sAbbrevTable = NULL;
        sAbbrevTableSize = 0;
    }
    while (dio_gUnitSize == 0 || dio_GetPos() < dio_gUnitPos + dio_gUnitSize) {
        dio_ReadEntry(CallBack);
    }
}

#define dio_AbbrevTableHash(File, Offset) (((int)(File) + (int)(Offset)) / 4 % ABBREV_TABLE_SIZE)

static int dio_IsAbbrevSectionLoaded(ELF_File * File) {
    DIO_Cache * Cache = dio_GetCache(File);
    
    if (Cache->mAbbrevTable != NULL) {
        U4_T Hash = dio_AbbrevTableHash(File, 0);
        DIO_AbbrevSet * AbbrevSet = Cache->mAbbrevTable[Hash];
        while (AbbrevSet != NULL) {
            if (AbbrevSet->mFile == File) return 1;
            AbbrevSet = AbbrevSet->mNext;
        }
    }
    return 0;
}

void dio_LoadAbbrevTable(ELF_File * File) {
    U4_T ID;
    U8_T TableOffset = 0;
    ELF_Section * Section = NULL;
    static U2_T * AttrBuf = NULL;
    static U4_T AttrBufSize = 0;
    DIO_Abbreviation ** AbbrevTable = NULL;
    U4_T AbbrevTableSize = 0;
    DIO_Cache * Cache = dio_GetCache(File);

    if (dio_IsAbbrevSectionLoaded(File)) return;

    assert(sSection == NULL);
    for (ID = 1; ID < File->section_cnt; ID++) {
        if (strcmp(File->sections[ID]->name, ".debug_abbrev") == 0) {
            if (Section != NULL) {
                str_exception(ERR_DWARF, "more then one .debug_abbrev section in a file");
            }
            Section = File->sections[ID];
        }
    }
    if (Section == NULL) return;
    dio_EnterSection(Section, 0);
    for (;;) {
	U4_T AttrPos = 0;
        U2_T Tag = 0;
        U1_T Children = 0;
	U4_T ID = dio_ReadLEB128();
        if (ID == 0) {
            /* End of compilation unit */
            U4_T Hash = dio_AbbrevTableHash(File, TableOffset);
            DIO_AbbrevSet * AbbrevSet = (DIO_AbbrevSet *)loc_alloc_zero(sizeof(DIO_AbbrevSet));
            AbbrevSet->mFile = File;
            AbbrevSet->mOffset = TableOffset;
            AbbrevSet->mTable = AbbrevTable;
            AbbrevSet->mSize = AbbrevTableSize;
            if (Cache->mAbbrevTable == NULL) {
                Cache->mAbbrevTable = (DIO_AbbrevSet **)loc_alloc_zero(sizeof(DIO_AbbrevSet *) * ABBREV_TABLE_SIZE);
            }
            AbbrevSet->mNext = Cache->mAbbrevTable[Hash];
            Cache->mAbbrevTable[Hash] = AbbrevSet;
            AbbrevTable = NULL;
            AbbrevTableSize = 0;
            if (dio_GetPos() >= Section->size) break;
            TableOffset = dio_GetPos();
            continue;
        }
	if (ID >= 0x1000000) str_exception(ERR_DWARF, "invalid abbreviation table");
	if (ID >= AbbrevTableSize) {
            U4_T Size = AbbrevTableSize;
	    AbbrevTableSize = ID + 1024u;
	    AbbrevTable = (DIO_Abbreviation **)loc_realloc(AbbrevTable, sizeof(DIO_Abbreviation *) * AbbrevTableSize);
            memset(AbbrevTable + Size, 0, sizeof(DIO_Abbreviation *) * (AbbrevTableSize - Size));
	}
	Tag = (U2_T)dio_ReadLEB128();
	Children = (U2_T)dio_ReadU1() != 0;
	for (;;) {
	    U4_T Attr = dio_ReadLEB128();
	    U4_T Form = dio_ReadLEB128();
            if (Attr >= 0x10000 || Form >= 0x10000) str_exception(ERR_DWARF, "invalid abbreviation table");
	    if (Attr == 0 && Form == 0) {
                DIO_Abbreviation * Abbr = AbbrevTable[ID];
                assert(Abbr == NULL);
                Abbr = (DIO_Abbreviation *)loc_alloc_zero(sizeof(DIO_Abbreviation) + sizeof(U2_T) * (AttrPos - 2));
                Abbr->mTag = Tag;
                Abbr->mChildren = Children;
                Abbr->mAttrLen = AttrPos;
                memcpy(Abbr->mAttrs, AttrBuf, sizeof(U2_T) * AttrPos);
                AbbrevTable[ID] = Abbr;
		break;
	    }
	    if (AttrBufSize < AttrPos + 2) {
		AttrBufSize = AttrPos + 256;
		AttrBuf = (U2_T *)loc_realloc(AttrBuf, sizeof(U2_T) * AttrBufSize);
	    }
	    AttrBuf[AttrPos++] = (U2_T)Attr;
	    AttrBuf[AttrPos++] = (U2_T)Form;
	}
    }
    assert(AbbrevTable == NULL);
    assert(AbbrevTableSize == 0);
    dio_ExitSection();
}

static void dio_FindAbbrevTable(U4_T Offset, DIO_Abbreviation *** AbbrevTable, U4_T * AbbrevTableSize) {
    DIO_Cache * Cache = dio_GetCache(sSection->file);
    if (Cache->mAbbrevTable != NULL) {
        U4_T Hash = dio_AbbrevTableHash(sSection->file, Offset);
        DIO_AbbrevSet * AbbrevSet = Cache->mAbbrevTable[Hash];
        while (AbbrevSet != NULL) {
            if (AbbrevSet->mFile == sSection->file && AbbrevSet->mOffset == Offset) {
                *AbbrevTable = AbbrevSet->mTable;
                *AbbrevTableSize = AbbrevSet->mSize;
                return;
            }
            AbbrevSet = AbbrevSet->mNext;
        }
    }
    str_exception(ERR_DWARF, "invalid abbreviation table offset");
    *AbbrevTable = NULL;
    *AbbrevTableSize = 0;
}

void dio_ChkFlag(U2_T Form) {
    switch (Form) {
    case FORM_FLAG      :
	return;
    }
    str_exception(ERR_DWARF, "FORM_FLAG expected");
}

void dio_ChkRef(U2_T Form) {
    switch (Form) {
    case FORM_REF       :
    case FORM_REF_ADDR  :
    case FORM_REF1      :
    case FORM_REF2      :
    case FORM_REF4      :
    case FORM_REF8      :
    case FORM_REF_UDATA :
	return;
    }
    str_exception(ERR_DWARF, "FORM_REF* expected");
}

void dio_ChkAddr(U2_T Form) {
    switch (Form) {
    case FORM_ADDR      :
	return;
    }
    str_exception(ERR_DWARF, "FORM_ADDR expected");
}

void dio_ChkData(U2_T Form) {
    switch (Form) {
    case FORM_DATA1     :
    case FORM_DATA2     :
    case FORM_DATA4     :
    case FORM_DATA8     :
    case FORM_SDATA     :
    case FORM_UDATA     :
	return;
    }
    str_exception(ERR_DWARF, "FORM_DATA* expected");
}

void dio_ChkBlock(U2_T Form, U1_T ** Buf, U4_T * Size) {
    switch (Form) {
    case FORM_BLOCK1    :
    case FORM_BLOCK2    :
    case FORM_BLOCK4    :
    case FORM_BLOCK     :
        *Size = dio_gFormBlockSize;
        *Buf = dio_gFormBlockBuf;
        break;
    case FORM_DATA1     :
    case FORM_DATA2     :
    case FORM_DATA4     :
    case FORM_DATA8     :
    case FORM_SDATA     :
    case FORM_UDATA     :
        *Size = dio_gFormDataSize;
        *Buf = (U1_T *)&dio_gFormData;
        break;
    default:
        str_exception(ERR_DWARF, "FORM_BLOCK expected");
    }
}

void dio_ChkString(U2_T Form) {
    if (Form == FORM_STRING) return;
    if (Form == FORM_STRP) return;
    str_exception(ERR_DWARF, "FORM_STRING expected");
}

#endif
