Changeset 3560 in CLRX


Ignore:
Timestamp:
Dec 24, 2017, 11:05:09 PM (6 months ago)
Author:
matszpk
Message:

CLRadeonExtender: AsmGallium?&GalliumBinGen?: Add support for scratch relocations (not fully tested).

Location:
CLRadeonExtender/trunk
Files:
6 edited

Legend:

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

    r3328 r3560  
    6666    GALLIUM_COMMENT = LAST_COMMON+1,    ///< gallium comment section
    6767    GALLIUM_CONFIG_CTRL_DIRECTIVE,
     68    GALLIUM_SCRATCH,    ///< empty section for scratch symbol
    6869   
    6970    ROCM_COMMENT = LAST_COMMON+1,        ///< ROCm comment section
     
    423424    cxuint dataSection;
    424425    cxuint commentSection;
     426    cxuint scratchSection;
    425427    cxuint savedSection;
    426428    Inside inside;
     
    456458    void handleLabel(const CString& label);
    457459   
     460    bool resolveSymbol(const AsmSymbol& symbol, uint64_t& value, cxuint& sectionId);
     461    bool resolveRelocation(const AsmExpression* expr, uint64_t& value, cxuint& sectionId);
    458462    bool prepareBinary();
    459463    void writeBinary(std::ostream& os) const;
  • CLRadeonExtender/trunk/CLRX/amdbin/ElfBinaries.h

    r3559 r3560  
    451451    {  return getSectionContent(getSectionIndex(name)); }
    452452   
    453     static inline uint32_t getElfRelType(typename Types::Word info);
    454     static inline uint32_t getElfRelSym(typename Types::Word info);
    455 
     453    static uint32_t getElfRelType(typename Types::Word info);
     454    static uint32_t getElfRelSym(typename Types::Word info);
    456455};
    457456
     
    896895        generate(fob);
    897896    }
    898 };
     897   
     898    static typename Types::Word getRelInfo(size_t symbolIndex, uint32_t rtype);
     899};
     900
     901template<>
     902inline uint32_t ElfBinaryGenTemplate<Elf32Types>::getRelInfo(
     903            size_t symbolIndex, uint32_t rtype)
     904{ return ELF32_R_INFO(symbolIndex, rtype); }
     905
     906template<>
     907inline uint64_t ElfBinaryGenTemplate<Elf64Types>::getRelInfo(
     908            size_t symbolIndex, uint32_t rtype)
     909{ return ELF64_R_INFO(symbolIndex, rtype); }
    899910
    900911extern template class ElfBinaryGenTemplate<Elf32Types>;
  • CLRadeonExtender/trunk/CLRX/amdbin/GalliumBinaries.h

    r3559 r3560  
    398398    GALLIUMSECTID_GPUCONFIG = ELFSECTID_OTHER_BUILTIN,
    399399    GALLIUMSECTID_NOTEGNUSTACK,
    400     GALLIUMSECTID_MAX = GALLIUMSECTID_NOTEGNUSTACK
     400    GALLIUMSECTID_RELTEXT,
     401    GALLIUMSECTID_MAX = GALLIUMSECTID_RELTEXT
    401402};
    402403
  • CLRadeonExtender/trunk/amdasm/AsmGalliumFormat.cpp

    r3553 r3560  
    6565    "privmode", "proginfo", "reserved_sgprs", "reserved_vgprs",
    6666    "runtime_loader_kernel_symbol",
    67     "scratchbuffer", "sgprsnum",
     67    "scratchbuffer", "scratchsym", "sgprsnum",
    6868    "spilledsgprs", "spilledvgprs", "tgsize",
    6969    "use_debug_enabled", "use_dispatch_id",
     
    111111    GALLIUMOP_RESERVED_SGPRS, GALLIUMOP_RESERVED_VGPRS,
    112112    GALLIUMOP_RUNTIME_LOADER_KERNEL_SYMBOL,
    113     GALLIUMOP_SCRATCHBUFFER, GALLIUMOP_SGPRSNUM,
     113    GALLIUMOP_SCRATCHBUFFER, GALLIUMOP_SCRATCHSYM, GALLIUMOP_SGPRSNUM,
    114114    GALLIUMOP_SPILLEDSGPRS, GALLIUMOP_SPILLEDVGPRS, GALLIUMOP_TGSIZE,
    115115    GALLIUMOP_USE_DEBUG_ENABLED, GALLIUMOP_USE_DISPATCH_ID,
     
    141141AsmGalliumHandler::AsmGalliumHandler(Assembler& assembler): AsmFormatHandler(assembler),
    142142             output{}, codeSection(0), dataSection(ASMSECT_NONE),
    143              commentSection(ASMSECT_NONE), extraSectionCount(0),
    144              archMinor(BINGEN_DEFAULT), archStepping(BINGEN_DEFAULT)
     143             commentSection(ASMSECT_NONE), scratchSection(ASMSECT_NONE),
     144             extraSectionCount(0), archMinor(BINGEN_DEFAULT), archStepping(BINGEN_DEFAULT)
    145145{
    146146    assembler.currentKernel = ASMKERN_GLOBAL;
     
    314314    if (info.type == AsmSectionType::CODE)
    315315        info.flags = ASMSECT_ADDRESSABLE | ASMSECT_WRITEABLE;
     316    else if (info.type == AsmSectionType::GALLIUM_SCRATCH)
     317        // scratch is unresolvable (for relocation)
     318        info.flags = ASMSECT_UNRESOLVABLE;
    316319    // any other section (except config) are absolute addressable and writeable
    317320    else if (info.type != AsmSectionType::CONFIG)
     
    12931296}
    12941297
     1298void AsmGalliumPseudoOps::scratchSymbol(AsmGalliumHandler& handler, const char* linePtr)
     1299{
     1300    Assembler& asmr = handler.assembler;
     1301    const char* end = asmr.line + asmr.lineSize;
     1302    skipSpacesToEnd(linePtr, end);
     1303   
     1304    const char* symNamePlace = linePtr;
     1305    const CString symName = extractScopedSymName(linePtr, end, false);
     1306    if (symName.empty())
     1307        ASM_RETURN_BY_ERROR(symNamePlace, "Illegal symbol name")
     1308    size_t symNameLength = symName.size();
     1309    // special case for '.' symbol (check whether is in global scope)
     1310    if (symNameLength >= 3 && symName.compare(symNameLength-3, 3, "::.")==0)
     1311        ASM_RETURN_BY_ERROR(symNamePlace, "Symbol '.' can be only in global scope")
     1312    if (!checkGarbagesAtEnd(asmr, linePtr))
     1313        return;
     1314   
     1315    if (handler.scratchSection == ASMSECT_NONE)
     1316    {
     1317        // add scratch section if not added
     1318        cxuint thisSection = handler.sections.size();
     1319        handler.sections.push_back({ ASMKERN_GLOBAL,
     1320                AsmSectionType::GALLIUM_SCRATCH, ELFSECTID_UNDEF, nullptr });
     1321        handler.scratchSection = thisSection;
     1322        asmr.sections.push_back({ "", ASMKERN_GLOBAL, AsmSectionType::GALLIUM_SCRATCH,
     1323            ASMSECT_UNRESOLVABLE, 0 });
     1324    }
     1325   
     1326    std::pair<AsmSymbolEntry*, bool> res = asmr.insertSymbolInScope(symName,
     1327                AsmSymbol(handler.scratchSection, 0));
     1328    if (!res.second)
     1329    {
     1330        // if symbol found,
     1331        if (res.first->second.onceDefined && res.first->second.isDefined()) // if label
     1332            asmr.printError(symNamePlace, (std::string("Symbol '")+symName.c_str()+
     1333                        "' is already defined").c_str());
     1334        else
     1335            asmr.setSymbol(*res.first, 0, handler.scratchSection);
     1336    }
     1337    else
     1338        res.first->second.hasValue = false; // make
     1339}
     1340
    12951341}
    12961342
     
    15301576                                    GALLIUMCVAL_SCRATCHBUFFER);
    15311577            break;
     1578        case GALLIUMOP_SCRATCHSYM:
     1579            AsmGalliumPseudoOps::scratchSymbol(*this, linePtr);
     1580            break;
    15321581        case GALLIUMOP_SGPRSNUM:
    15331582            AsmGalliumPseudoOps::setConfigValue(*this, stmtPlace, linePtr,
     
    16331682    }
    16341683    return true;
     1684}
     1685
     1686bool AsmGalliumHandler::resolveSymbol(const AsmSymbol& symbol,
     1687                    uint64_t& value, cxuint& sectionId)
     1688{
     1689    if (!assembler.isResolvableSection(symbol.sectionId))
     1690    {
     1691        value = symbol.value;
     1692        sectionId = symbol.sectionId;
     1693        return true;
     1694    }
     1695    return false;
     1696}
     1697
     1698bool AsmGalliumHandler::resolveRelocation(const AsmExpression* expr, uint64_t& outValue,
     1699                    cxuint& outSectionId)
     1700{
     1701    const AsmExprTarget& target = expr->getTarget();
     1702    const AsmExprTargetType tgtType = target.type;
     1703    if ((tgtType!=ASMXTGT_DATA32 &&
     1704        !assembler.isaAssembler->relocationIsFit(32, tgtType)))
     1705    {
     1706        assembler.printError(expr->getSourcePos(),
     1707                        "Can't resolve expression for non 32-bit integer");
     1708        return false;
     1709    }
     1710    if (target.sectionId==ASMSECT_ABS ||
     1711        assembler.sections[target.sectionId].type!=AsmSectionType::CODE)
     1712    {
     1713        assembler.printError(expr->getSourcePos(), "Can't resolve expression outside "
     1714                "code section");
     1715        return false;
     1716    }
     1717    const Array<AsmExprOp>& ops = expr->getOps();
     1718   
     1719    size_t relOpStart = 0;
     1720    size_t relOpEnd = ops.size();
     1721    RelocType relType = RELTYPE_LOW_32BIT;
     1722    // checking what is expression
     1723    // get () OP () - operator between two parts
     1724    AsmExprOp lastOp = ops.back();
     1725    if (lastOp==AsmExprOp::BIT_AND || lastOp==AsmExprOp::MODULO ||
     1726        lastOp==AsmExprOp::SIGNED_MODULO || lastOp==AsmExprOp::DIVISION ||
     1727        lastOp==AsmExprOp::SIGNED_DIVISION || lastOp==AsmExprOp::SHIFT_RIGHT)
     1728    {
     1729        // check low or high relocation
     1730        relOpStart = 0;
     1731        relOpEnd = expr->toTop(ops.size()-2);
     1732        /// evaluate second argument
     1733        cxuint tmpSectionId;
     1734        uint64_t secondArg;
     1735        if (!expr->evaluate(assembler, relOpEnd, ops.size()-1, secondArg, tmpSectionId))
     1736            return false;
     1737        if (tmpSectionId!=ASMSECT_ABS)
     1738        {
     1739            // must be absolute
     1740            assembler.printError(expr->getSourcePos(),
     1741                        "Second argument for relocation operand must be absolute");
     1742            return false;
     1743        }
     1744        bool good = true;
     1745        switch (lastOp)
     1746        {
     1747            case AsmExprOp::BIT_AND:
     1748                // handle (x&0xffffffff)
     1749                relType = RELTYPE_LOW_32BIT;
     1750                good = ((secondArg & 0xffffffffULL) == 0xffffffffULL);
     1751                break;
     1752            case AsmExprOp::MODULO:
     1753            case AsmExprOp::SIGNED_MODULO:
     1754                // handle (x%0x100000000)
     1755                relType = RELTYPE_LOW_32BIT;
     1756                good = ((secondArg>>32)!=0 && (secondArg & 0xffffffffULL) == 0);
     1757                break;
     1758            case AsmExprOp::DIVISION:
     1759            case AsmExprOp::SIGNED_DIVISION:
     1760                // handle (x/0x100000000)
     1761                relType = RELTYPE_HIGH_32BIT;
     1762                good = (secondArg == 0x100000000ULL);
     1763                break;
     1764            case AsmExprOp::SHIFT_RIGHT:
     1765                // handle (x>>32)
     1766                relType = RELTYPE_HIGH_32BIT;
     1767                good = (secondArg == 32);
     1768                break;
     1769            default:
     1770                break;
     1771        }
     1772        if (!good)
     1773        {
     1774            assembler.printError(expr->getSourcePos(),
     1775                        "Can't resolve relocation for this expression");
     1776            return false;
     1777        }
     1778    }
     1779    //
     1780    cxuint relSectionId = 0;
     1781    uint64_t relValue = 0;
     1782    if (expr->evaluate(assembler, relOpStart, relOpEnd, relValue, relSectionId))
     1783    {
     1784        // relocation only for rodata, data and bss section
     1785        if (relSectionId!=scratchSection)
     1786        {
     1787            assembler.printError(expr->getSourcePos(),
     1788                     "Section of this expression must be a scratch");
     1789            return false;
     1790        }
     1791        if (relValue != 0)
     1792        {
     1793            assembler.printError(expr->getSourcePos(),
     1794                     "Expression must point to start of section");
     1795            return false;
     1796        }
     1797        outSectionId = ASMSECT_ABS;   // for filling values in code
     1798        outValue = 4U; // for filling values in code
     1799        size_t extraOffset = (tgtType!=ASMXTGT_DATA32) ? 4 : 0;
     1800        AsmRelocation reloc = { target.sectionId, target.offset+extraOffset, relType };
     1801        // set up relocation (relSectionId, addend)
     1802        reloc.relSectionId = relSectionId;
     1803        reloc.addend = 0;
     1804        assembler.relocations.push_back(reloc);
     1805        return true;
     1806    }
     1807    return false;
    16351808}
    16361809
     
    17951968            config.usedVGPRsNum = std::max(minRegsNum[1], kernelStates[i]->allocRegs[1]);
    17961969    }
     1970   
     1971    // put scratch relocations
     1972    for (const AsmRelocation& reloc: assembler.relocations)
     1973        output.scratchRelocs.push_back({reloc.offset, reloc.type});
    17971974   
    17981975    // if set adds symbols to binary
  • CLRadeonExtender/trunk/amdasm/AsmGalliumInternals.h

    r3426 r3560  
    177177    static void updateKCodeSel(AsmGalliumHandler& handler,
    178178          const std::vector<cxuint>& oldset);
     179   
     180    static void scratchSymbol(AsmGalliumHandler& handler, const char* linePtr);
    179181};
    180182
  • CLRadeonExtender/trunk/amdbin/GalliumBinaries.cpp

    r3559 r3560  
    507507    6, // ELFSECTID_COMMENT
    508508    4, // GALLIUMSECTID_GPUCONFIG
    509     7  // GALLIUMSECTID_NOTEGNUSTACK
     509    7, // GALLIUMSECTID_NOTEGNUSTACK
     510    SHN_UNDEF // GALLIUMSECTID_RELTEXT
    510511};
    511512
     
    524525    5, // ELFSECTID_COMMENT
    525526    4, // GALLIUMSECTID_GPUCONFIG
    526     6  // GALLIUMSECTID_NOTEGNUSTACK
     527    6, // GALLIUMSECTID_NOTEGNUSTACK
     528    SHN_UNDEF // GALLIUMSECTID_RELTEXT
     529};
     530
     531// section index for symbol binding
     532static const uint16_t mainBuiltinSectionTableRel[] =
     533{
     534    9, // ELFSECTID_SHSTRTAB
     535    11, // ELFSECTID_STRTAB
     536    10, // ELFSECTID_SYMTAB
     537    SHN_UNDEF, // ELFSECTID_DYNSTR
     538    SHN_UNDEF, // ELFSECTID_DYNSYM
     539    1, // ELFSECTID_TEXT
     540    6, // ELFSECTID_RODATA
     541    3, // ELFSECTID_DATA
     542    4, // ELFSECTID_BSS
     543    7, // ELFSECTID_COMMENT
     544    5, // GALLIUMSECTID_GPUCONFIG
     545    8, // GALLIUMSECTID_NOTEGNUSTACK
     546    2 // GALLIUMSECTID_RELTEXT
     547};
     548
     549// section index for symbol binding
     550static const uint16_t mainBuiltinSectionTable2Rel[] =
     551{
     552    8, // ELFSECTID_SHSTRTAB
     553    10, // ELFSECTID_STRTAB
     554    9, // ELFSECTID_SYMTAB
     555    SHN_UNDEF, // ELFSECTID_DYNSTR
     556    SHN_UNDEF, // ELFSECTID_DYNSYM
     557    1, // ELFSECTID_TEXT
     558    SHN_UNDEF, // ELFSECTID_RODATA
     559    3, // ELFSECTID_DATA
     560    4, // ELFSECTID_BSS
     561    6, // ELFSECTID_COMMENT
     562    5, // GALLIUMSECTID_GPUCONFIG
     563    7, // GALLIUMSECTID_NOTEGNUSTACK
     564    2  // GALLIUMSECTID_RELTEXT
    527565};
    528566
     
    593631};
    594632
     633// helper to writing AMDGPU configuration content
     634template<typename Types>
     635class CLRX_INTERNAL GalliumRelTextContent: public ElfRegionContent
     636{
     637private:
     638    const GalliumInput& input;
     639public:
     640    GalliumRelTextContent(const GalliumInput& inInput) : input(inInput)
     641    { }
     642   
     643    void operator()(FastOutputBuffer& fob) const
     644    {
     645        const size_t symIndex = 8 + (input.globalData!=nullptr) +
     646                    (!input.scratchRelocs.empty());
     647        for (const GalliumScratchReloc& reloc: input.scratchRelocs)
     648        {
     649            typename Types::Rel outReloc{};
     650            SLEV(outReloc.r_offset, reloc.offset);
     651            SLEV(outReloc.r_info, ElfBinaryGenTemplate<Types>::getRelInfo(
     652                    symIndex + (reloc.type == RELTYPE_HIGH_32BIT), 0x81));
     653            fob.writeObject(outReloc);
     654        }
     655    }
     656};
     657
    595658template<typename Types>
    596659static void putSectionsAndSymbols(ElfBinaryGenTemplate<Types>& elfBinGen,
    597660      const GalliumInput* input, const Array<uint32_t>& kernelsOrder,
    598       const AmdGpuConfigContent& amdGpuConfigContent)
     661      const AmdGpuConfigContent& amdGpuConfigContent,
     662      const GalliumRelTextContent<Types>& relTextContent)
    599663{
    600664    const char* comment = "CLRX GalliumBinGenerator " CLRX_VERSION;
    601665    uint32_t commentSize = ::strlen(comment);
     666   
     667    /* choose builtin section table and extraSectionStartIndex */
     668    const uint16_t* curMainBuiltinSections = nullptr;
     669    if (input->scratchRelocs.empty())
     670        curMainBuiltinSections = (input->globalData!=nullptr) ?
     671            mainBuiltinSectionTable : mainBuiltinSectionTable2;
     672    else // if relocations
     673        curMainBuiltinSections = (input->globalData!=nullptr) ?
     674            mainBuiltinSectionTableRel : mainBuiltinSectionTable2Rel;
     675    cxuint startSectionIndex = 10 + (input->globalData!=nullptr) +
     676                (!input->scratchRelocs.empty());
    602677   
    603678    typedef ElfRegionTemplate<Types> ElfRegion;
     
    606681    elfBinGen.addRegion(ElfRegion(input->codeSize, input->code, 256, ".text",
    607682            SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR));
     683    if (!input->scratchRelocs.empty())
     684        // .rel.text section
     685        elfBinGen.addRegion(ElfRegion(input->scratchRelocs.size()*
     686                sizeof(typename Types::Rel), &relTextContent,
     687                sizeof(typename Types::Word), ".rel.text", SHT_REL, 0,
     688                curMainBuiltinSections[ELFSECTID_SYMTAB-ELFSECTID_START], 1, 0,
     689                sizeof(typename Types::Rel), false, sizeof(typename Types::Word)));
     690   
    608691    elfBinGen.addRegion(ElfRegion(0, (const cxbyte*)nullptr, 4, ".data",
    609692            SHT_PROGBITS, SHF_ALLOC|SHF_WRITE));
     
    639722    elfBinGen.addSymbol({"EndOfTextLabel", 1, ELF32_ST_INFO(STB_LOCAL, STT_NOTYPE),
    640723            0, false, uint32_t(input->codeSize), 0});
    641     const cxuint sectSymsNum = 6 + (input->globalData!=nullptr);
     724    const cxuint sectSymsNum = 6 + (input->globalData!=nullptr) +
     725            (!input->scratchRelocs.empty());
    642726    // local symbols for sections
    643727    for (cxuint i = 0; i < sectSymsNum; i++)
    644728        elfBinGen.addSymbol({"", uint16_t(i+1), ELF32_ST_INFO(STB_LOCAL, STT_SECTION),
    645729                0, false, 0, 0});
     730    if (!input->scratchRelocs.empty())
     731    {
     732        // put scratch rsrc symbols
     733        elfBinGen.addSymbol({"SCRATCH_RSRC_DWORD0", SHN_UNDEF,
     734                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, false, 0, 0});
     735        elfBinGen.addSymbol({"SCRATCH_RSRC_DWORD1", SHN_UNDEF,
     736                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, false, 0, 0});
     737    }
    646738    for (uint32_t korder: kernelsOrder)
    647739    {
     
    650742                ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, false, kernel.offset, 0});
    651743    }
    652    
    653     /* choose builtin section table and extraSectionStartIndex */
    654     const uint16_t* curMainBuiltinSections = (input->globalData!=nullptr) ?
    655             mainBuiltinSectionTable : mainBuiltinSectionTable2;
    656     cxuint startSectionIndex = (input->globalData!=nullptr) ? 11 : 10;
    657744   
    658745    /* extra sections */
     
    708795   
    709796    AmdGpuConfigContent amdGpuConfigContent(kernelsOrder, *input);
     797    GalliumRelTextContent<Elf32Types> relTextContent32(*input);
     798    GalliumRelTextContent<Elf64Types> relTextContent64(*input);
    710799    if (!input->is64BitElf)
    711800    {
     
    713802        elfBinGen32.reset(new ElfBinaryGen32({ 0, 0, ELFOSABI_SYSV, 0,  ET_REL, 0,
    714803                    EV_CURRENT, UINT_MAX, 0, 0 }));
    715         putSectionsAndSymbols(*elfBinGen32, input, kernelsOrder, amdGpuConfigContent);
     804        putSectionsAndSymbols(*elfBinGen32, input, kernelsOrder, amdGpuConfigContent,
     805                        relTextContent32);
    716806        elfSize = elfBinGen32->countSize();
    717807    }
     
    721811        elfBinGen64.reset(new ElfBinaryGen64({ 0, 0, ELFOSABI_SYSV, 0,  ET_REL, 0,
    722812                    EV_CURRENT, UINT_MAX, 0, 0 }));
    723         putSectionsAndSymbols(*elfBinGen64, input, kernelsOrder, amdGpuConfigContent);
     813        putSectionsAndSymbols(*elfBinGen64, input, kernelsOrder, amdGpuConfigContent,
     814                        relTextContent64);
    724815        elfSize = elfBinGen64->countSize();
    725816    }
Note: See TracChangeset for help on using the changeset viewer.