Changeset 3559 in CLRX


Ignore:
Timestamp:
Dec 24, 2017, 3:54:19 PM (9 months ago)
Author:
matszpk
Message:

CLRadeonExtender: GalliumBin? & GalliumDisasm?: Add support for scratch buffer relocations. Add methods to access to text relocations in inner gallium binary.
Add methods to getting relocation type and symbol (ElfBinary?).

Location:
CLRadeonExtender/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/CLRX/amdasm/Disassembler.h

    r3557 r3559  
    343343    size_t codeSize;    ///< code size
    344344    const cxbyte* code; ///< code
     345    std::vector<GalliumScratchReloc> scratchRelocs; ///< scratch buffer text relocations
    345346};
    346347
  • CLRadeonExtender/trunk/CLRX/amdbin/ElfBinaries.h

    r3457 r3559  
    116116    static const char* bitName;     ///< bitness name
    117117    static const Word nobase = Word(0)-1;   ///< address with zero base
     118    static const cxuint relSymShift = 8;
    118119};
    119120
     
    136137    static const char* bitName;     ///< bitness name
    137138    static const Word nobase = Word(0)-1;   ///< address with zero base
     139    static const cxuint relSymShift = 32;
    138140};
    139141
     
    448450    cxbyte* getSectionContent(const char* name)
    449451    {  return getSectionContent(getSectionIndex(name)); }
    450 };
     452   
     453    static inline uint32_t getElfRelType(typename Types::Word info);
     454    static inline uint32_t getElfRelSym(typename Types::Word info);
     455
     456};
     457
     458template<>
     459inline uint32_t ElfBinaryTemplate<Elf32Types>::getElfRelType(typename Elf32Types::Word info)
     460{ return ELF32_R_TYPE(info); }
     461
     462template<>
     463inline uint32_t ElfBinaryTemplate<Elf32Types>::getElfRelSym(typename Elf32Types::Word info)
     464{ return ELF32_R_SYM(info); }
     465
     466template<>
     467inline uint32_t ElfBinaryTemplate<Elf64Types>::getElfRelType(typename Elf64Types::Word info)
     468{ return ELF64_R_TYPE(info); }
     469
     470template<>
     471inline uint32_t ElfBinaryTemplate<Elf64Types>::getElfRelSym(typename Elf64Types::Word info)
     472{ return ELF64_R_SYM(info); }
     473
    451474
    452475extern template class ElfBinaryTemplate<Elf32Types>;
  • CLRadeonExtender/trunk/CLRX/amdbin/GalliumBinaries.h

    r3336 r3559  
    3131#include <utility>
    3232#include <memory>
     33#include <CLRX/amdbin/Commons.h>
    3334#include <CLRX/amdbin/Elf.h>
    3435#include <CLRX/amdbin/ElfBinaries.h>
     
    136137};
    137138
     139// scratch buffer relocation entry
     140struct GalliumScratchReloc
     141{
     142    size_t offset;  ///< offset
     143    RelocType type; ///< relocation type
     144};
     145
    138146/// Gallium elf binary base (for 32-bit and 64-bit)
    139147class GalliumElfBinaryBase
     
    149157    size_t disasmOffset;    ///< disassembly offset
    150158    bool llvm390;   ///< true if >= LLVM 3.9
     159    Array<GalliumScratchReloc> scratchRelocs;
    151160   
    152161    /// routine to load binary fro internal ELF
     
    192201    bool isLLVM390() const
    193202    { return llvm390; }
     203   
     204    /// return scratch buffer relocations number
     205    size_t getScratchRelocsNum() const
     206    { return scratchRelocs.size(); }
     207   
     208    /// return scratch buffer relocation by index
     209    const GalliumScratchReloc& getScratchReloc(size_t i) const
     210    { return scratchRelocs[i]; }
     211   
     212    /// return all scratch buffer relocations
     213    const Array<GalliumScratchReloc>& getScratchRelocs() const
     214    { return scratchRelocs; }
    194215};
    195216
     
    203224class GalliumElfBinary32: public GalliumElfBinaryBase, public ElfBinary32
    204225{
     226private:
     227    size_t textRelsNum;
     228    size_t textRelEntrySize;
     229    cxbyte* textRel;
    205230public:
    206231    /// empty constructor
     
    219244    const char* getDisassembly() const
    220245    { return reinterpret_cast<const char*>(binaryCode + disasmOffset); }
     246   
     247    /// get text rel entries number
     248    size_t getTextRelEntriesNum() const
     249    { return textRelsNum; }
     250    /// get text rel entry
     251    const Elf32_Rel& getTextRelEntry(size_t index) const
     252    { return *reinterpret_cast<const Elf32_Rel*>(textRel + textRelEntrySize*index); }
     253    /// get text rel entry
     254    Elf32_Rel& getTextRelEntry(size_t index)
     255    { return *reinterpret_cast<Elf32_Rel*>(textRel + textRelEntrySize*index); }
    221256};
    222257
     
    224259class GalliumElfBinary64: public GalliumElfBinaryBase, public ElfBinary64
    225260{
     261private:
     262    size_t textRelsNum;
     263    size_t textRelEntrySize;
     264    cxbyte* textRel;
    226265public:
    227266    /// empty constructor
     
    240279    const char* getDisassembly() const
    241280    { return reinterpret_cast<const char*>(binaryCode + disasmOffset); }
     281    /// get text rel entries number
     282    size_t getTextRelEntriesNum() const
     283    { return textRelsNum; }
     284    /// get text rel entry
     285    const Elf64_Rel& getTextRelEntry(size_t index) const
     286    { return *reinterpret_cast<const Elf64_Rel*>(textRel + textRelEntrySize*index); }
     287    /// get text rel entry
     288    Elf64_Rel& getTextRelEntry(size_t index)
     289    { return *reinterpret_cast<Elf64_Rel*>(textRel + textRelEntrySize*index); }
    242290};
    243291
     
    407455    std::vector<BinSection> extraSections;  ///< extra sections
    408456    std::vector<BinSymbol> extraSymbols;    ///< extra symbols
     457    std::vector<GalliumScratchReloc> scratchRelocs; ///< scratchbuffer relocations
    409458   
    410459    /// add empty kernel with default values
  • CLRadeonExtender/trunk/amdasm/DisasmGallium.cpp

    r3465 r3559  
    8282    input->code = elfBin.getSectionContent(textIndex);
    8383    input->codeSize = ULEV(elfBin.getSectionHeader(textIndex).sh_size);
     84    // scratch relocations
     85    const Array<GalliumScratchReloc>& scratchRelocs = elfBin.getScratchRelocs();
     86    input->scratchRelocs.assign(scratchRelocs.begin(), scratchRelocs.end());
     87    std::sort(input->scratchRelocs.begin(), input->scratchRelocs.end(),
     88              [](const GalliumScratchReloc& r1, const GalliumScratchReloc& r2)
     89              { return r1.offset < r2.offset; });
    8490}
    8591
     
    224230    else if (galliumInput->isLLVM390)
    225231        output.write(".llvm_version 30900\n", 20);
     232   
     233    if (!galliumInput->scratchRelocs.empty())
     234        output.write(".scratchsym .scratchaddr\n", 25);
    226235   
    227236    const GPUArchitecture arch = getGPUArchitectureFromDeviceType(galliumInput->deviceType);
     
    321330            isaDisassembler->addNamedLabel(kinput.offset, kinput.kernelName);
    322331    }
     332   
     333    if (!galliumInput->scratchRelocs.empty())
     334    {
     335        // put scratch relocations and scratch symbol
     336        isaDisassembler->addRelSymbol(".scratchaddr");
     337        for (const GalliumScratchReloc& entry: galliumInput->scratchRelocs)
     338            isaDisassembler->addRelocation(entry.offset, entry.type, 0, 0);
     339    }
     340   
    323341    if (doDumpCode && galliumInput->code != nullptr && galliumInput->codeSize != 0)
    324342    {
  • CLRadeonExtender/trunk/amdbin/GalliumBinaries.cpp

    r3457 r3559  
    122122}
    123123
     124template<typename GalliumElfBinary>
     125static void innerBinaryGetScratchRelocs(const GalliumElfBinary& binary,
     126                    Array<GalliumScratchReloc>& scratchRelocs)
     127{
     128    if (binary.getTextRelEntriesNum() != 0)
     129    {
     130        size_t scratchRSRCDword0Sym = SIZE_MAX;
     131        size_t scratchRSRCDword1Sym = SIZE_MAX;
     132        // parse scratch buffer relocations
     133        scratchRelocs.resize(binary.getTextRelEntriesNum());
     134        size_t j = 0;
     135        for (size_t i = 0; i < binary.getTextRelEntriesNum(); i++)
     136        {
     137            const auto& rel = binary.getTextRelEntry(i);
     138            const size_t symIndex = GalliumElfBinary::getElfRelSym(ULEV(rel.r_info));
     139            const char* symName = binary.getSymbolName(symIndex);
     140            const auto& sym = binary.getSymbol(symIndex);
     141            // if scratch RSRC symbol is not defined (just set if found)
     142            if (scratchRSRCDword0Sym == SIZE_MAX && ULEV(sym.st_shndx == SHN_UNDEF) &&
     143                    ::strcmp(symName, "SCRATCH_RSRC_DWORD0")==0)
     144                scratchRSRCDword0Sym = symIndex;
     145            else if (scratchRSRCDword1Sym == SIZE_MAX && ULEV(sym.st_shndx == SHN_UNDEF) &&
     146                    ::strcmp(symName, "SCRATCH_RSRC_DWORD1")==0)
     147                scratchRSRCDword1Sym = symIndex;
     148           
     149            if (scratchRSRCDword0Sym == symIndex)
     150                scratchRelocs[j++] = { ULEV(rel.r_offset), RELTYPE_LOW_32BIT };
     151            else if (scratchRSRCDword1Sym == symIndex)
     152                scratchRelocs[j++] = { ULEV(rel.r_offset), RELTYPE_HIGH_32BIT };
     153        }
     154        // final resizing
     155        scratchRelocs.resize(j);
     156    }
     157}
     158
    124159GalliumElfBinaryBase::~GalliumElfBinaryBase()
    125160{ }
    126161
    127162GalliumElfBinary32::GalliumElfBinary32()
     163    : textRelsNum(0), textRelEntrySize(0), textRel(nullptr)
    128164{ }
    129165
     
    133169GalliumElfBinary32::GalliumElfBinary32(size_t binaryCodeSize, cxbyte* binaryCode,
    134170           Flags creationFlags, size_t kernelsNum) :
    135            ElfBinary32(binaryCodeSize, binaryCode, creationFlags|ELF_CREATE_SYMBOLMAP)
    136        
     171           ElfBinary32(binaryCodeSize, binaryCode, creationFlags|ELF_CREATE_SYMBOLMAP),
     172           textRelsNum(0), textRelEntrySize(0), textRel(nullptr)
    137173{
    138174    loadFromElf(static_cast<const ElfBinary32&>(*this), kernelsNum);
     175   
     176    // get relocation section for text
     177    try
     178    {
     179        const Elf32_Shdr& relShdr = getSectionHeader(".rel.text");
     180        textRelEntrySize = ULEV(relShdr.sh_entsize);
     181        if (textRelEntrySize==0)
     182            textRelEntrySize = sizeof(Elf32_Rel);
     183        textRelsNum = ULEV(relShdr.sh_size)/textRelEntrySize;
     184        textRel = binaryCode + ULEV(relShdr.sh_offset);
     185    }
     186    catch(const Exception& ex)
     187    { }
     188   
     189    innerBinaryGetScratchRelocs(*this, scratchRelocs);
    139190}
    140191
    141192GalliumElfBinary64::GalliumElfBinary64()
     193    : textRelsNum(0), textRelEntrySize(0), textRel(nullptr)
    142194{ }
    143195
     
    147199GalliumElfBinary64::GalliumElfBinary64(size_t binaryCodeSize, cxbyte* binaryCode,
    148200           Flags creationFlags, size_t kernelsNum) :
    149            ElfBinary64(binaryCodeSize, binaryCode, creationFlags|ELF_CREATE_SYMBOLMAP)
    150        
     201           ElfBinary64(binaryCodeSize, binaryCode, creationFlags|ELF_CREATE_SYMBOLMAP),
     202           textRelsNum(0), textRelEntrySize(0), textRel(nullptr)
    151203{
    152204    loadFromElf(static_cast<const ElfBinary64&>(*this), kernelsNum);
     205    // get relocation section for text
     206    try
     207    {
     208        const Elf64_Shdr& relShdr = getSectionHeader(".rel.text");
     209        textRelEntrySize = ULEV(relShdr.sh_entsize);
     210        if (textRelEntrySize==0)
     211            textRelEntrySize = sizeof(Elf64_Rel);
     212        textRelsNum = ULEV(relShdr.sh_size)/textRelEntrySize;
     213        textRel = binaryCode + ULEV(relShdr.sh_offset);
     214    }
     215    catch(const Exception& ex)
     216    { }
     217   
     218    innerBinaryGetScratchRelocs(*this, scratchRelocs);
    153219}
    154220
Note: See TracChangeset for help on using the changeset viewer.