Changeset 3795 in CLRX


Ignore:
Timestamp:
Feb 14, 2018, 10:29:26 PM (14 months ago)
Author:
matszpk
Message:

CLRadeonExtender: AsmROCm: Tentative (and untested) implementation of the got symbols.

Location:
CLRadeonExtender/trunk
Files:
3 edited

Legend:

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

    r3790 r3795  
    7272    ROCM_CONFIG_CTRL_DIRECTIVE,
    7373    ROCM_METADATA,
     74    ROCM_GOT,
    7475   
    7576    EXTRA_FIRST = 0xfc,
     
    524525    std::vector<cxuint> kcodeSelection; // kcode
    525526    std::stack<std::vector<cxuint> > kcodeSelStack;
     527    std::vector<CString> gotSymbols;
    526528    cxuint currentKcodeKernel;
    527529    SectionMap extraSectionMap;
     
    530532    cxuint metadataSection;
    531533    cxuint dataSection;
     534    cxuint gotSection;
    532535    cxuint savedSection;
    533536    cxuint extraSectionCount;
  • CLRadeonExtender/trunk/amdasm/AsmROCmFormat.cpp

    r3794 r3795  
    4444    "eflags", "exceptions", "fixed_work_group_size",
    4545    "fkernel", "floatmode", "gds_segment_size",
    46     "globaldata", "group_segment_align", "ieeemode", "kcode",
     46    "globaldata", "gotsym", "group_segment_align", "ieeemode", "kcode",
    4747    "kcodeend", "kernarg_segment_align",
    4848    "kernarg_segment_size", "kernel_code_entry_offset",
     
    8282    ROCMOP_DEBUGMODE, ROCMOP_DEFAULT_HSA_FEATURES, ROCMOP_DIMS, ROCMOP_DX10CLAMP,
    8383    ROCMOP_EFLAGS, ROCMOP_EXCEPTIONS, ROCMOP_FIXED_WORK_GROUP_SIZE, ROCMOP_FKERNEL,
    84     ROCMOP_FLOATMODE, ROCMOP_GDS_SEGMENT_SIZE, ROCMOP_GLOBALDATA,
     84    ROCMOP_FLOATMODE, ROCMOP_GDS_SEGMENT_SIZE, ROCMOP_GLOBALDATA, ROCMOP_GOTSYM,
    8585    ROCMOP_GROUP_SEGMENT_ALIGN, ROCMOP_IEEEMODE, ROCMOP_KCODE,
    8686    ROCMOP_KCODEEND, ROCMOP_KERNARG_SEGMENT_ALIGN,
     
    118118AsmROCmHandler::AsmROCmHandler(Assembler& assembler): AsmFormatHandler(assembler),
    119119             output{}, codeSection(0), commentSection(ASMSECT_NONE),
    120              metadataSection(ASMSECT_NONE), dataSection(ASMSECT_NONE), extraSectionCount(0),
     120             metadataSection(ASMSECT_NONE), dataSection(ASMSECT_NONE),
     121             gotSection(ASMSECT_NONE), extraSectionCount(0),
    121122             unresolvedGlobals(false), good(true)
    122123{
     
    277278    if (info.type == AsmSectionType::CODE || info.type == AsmSectionType::DATA)
    278279        info.flags = ASMSECT_ADDRESSABLE | ASMSECT_WRITEABLE;
     280    else if (info.type == AsmSectionType::ROCM_GOT)
     281        info.flags = ASMSECT_ADDRESSABLE;
    279282    // any other section (except config) are absolute addressable and writeable
    280283    else if (info.type != AsmSectionType::CONFIG)
    281284        info.flags = ASMSECT_ADDRESSABLE | ASMSECT_WRITEABLE | ASMSECT_ABS_ADDRESSABLE;
    282285   
    283     if (info.type == AsmSectionType::CODE || info.type == AsmSectionType::DATA)
     286    if (info.type == AsmSectionType::CODE || info.type == AsmSectionType::DATA ||
     287        info.type == AsmSectionType::ROCM_GOT)
    284288        info.relSpace = 0;  // first rel space
    285289   
     
    17511755            (dimMask<<ROCMFLAG_USE_GRID_WORKGROUP_COUNT_BIT);
    17521756}
     1757
     1758void AsmROCmPseudoOps::addGotSymbol(AsmROCmHandler& handler,
     1759                    const char* pseudoOpPlace, const char* linePtr)
     1760{
     1761    Assembler& asmr = handler.assembler;
     1762    const char* end = asmr.line + asmr.lineSize;
     1763    // parse symbol
     1764    skipSpacesToEnd(linePtr, end);
     1765    const char* symNamePlace = linePtr;
     1766    AsmSymbolEntry* entry;
     1767    bool good = true;
     1768    const CString symName = extractScopedSymName(linePtr, end, false);
     1769    if (symName.empty())
     1770        // this is not symbol or a missing symbol
     1771        ASM_NOTGOOD_BY_ERROR(symNamePlace, "Expected symbol")
     1772    else if (symName==".")
     1773        ASM_NOTGOOD_BY_ERROR(symNamePlace, "Illegal symbol '.'")
     1774   
     1775    AsmScope* outScope;
     1776    CString sameSymName;
     1777    if (good)
     1778    {
     1779        entry = asmr.findSymbolInScope(symName, outScope, sameSymName);
     1780        if (outScope != &asmr.globalScope)
     1781            ASM_NOTGOOD_BY_ERROR(symNamePlace, "Symbol must be in global scope")
     1782    }
     1783   
     1784    bool haveComma = false;
     1785    if (skipComma(asmr, haveComma, linePtr))
     1786        return;
     1787   
     1788    CString targetSymName;
     1789    if (haveComma)
     1790    {
     1791        skipSpacesToEnd(linePtr, end);
     1792        symNamePlace = linePtr;
     1793        // parse target symbol (that refer to GOT section
     1794        targetSymName = extractScopedSymName(linePtr, end, false);
     1795        if (targetSymName.empty())
     1796            ASM_RETURN_BY_ERROR(symNamePlace, "Illegal symbol name")
     1797        size_t symNameLength = targetSymName.size();
     1798        // special case for '.' symbol (check whether is in global scope)
     1799        if (symNameLength >= 3 && targetSymName.compare(symNameLength-3, 3, "::.")==0)
     1800            ASM_RETURN_BY_ERROR(symNamePlace, "Symbol '.' can be only in global scope")
     1801        if (!checkGarbagesAtEnd(asmr, linePtr))
     1802            return;
     1803    }
     1804   
     1805    if (!good || !checkGarbagesAtEnd(asmr, linePtr))
     1806        return;
     1807   
     1808    if (entry==nullptr)
     1809    {
     1810        // create unresolved symbol if not found
     1811        std::pair<AsmSymbolMap::iterator, bool> res = outScope->symbolMap.insert(
     1812                        std::make_pair(sameSymName, AsmSymbol()));
     1813        entry = &*res.first;
     1814    }
     1815    // add GOT symbol
     1816    size_t gotSymbolIndex = handler.gotSymbols.size();
     1817    handler.gotSymbols.push_back(sameSymName);
     1818   
     1819    if (handler.gotSection == ASMSECT_NONE)
     1820    {
     1821        // create GOT section
     1822        cxuint thisSection = handler.sections.size();
     1823        handler.sections.push_back({ ASMKERN_GLOBAL,
     1824            AsmSectionType::ROCM_GOT, ROCMSECTID_GOT, nullptr });
     1825        handler.gotSection = thisSection;
     1826        AsmFormatHandler::SectionInfo info = handler.getSectionInfo(thisSection);
     1827        // add to assembler
     1828        asmr.sections.push_back({ info.name, ASMKERN_GLOBAL, info.type, info.flags, 0,
     1829                    0, info.relSpace });
     1830    }
     1831   
     1832    // set up value of GOT symbol
     1833    if (!targetSymName.empty())
     1834    {
     1835        std::pair<AsmSymbolEntry*, bool> res = asmr.insertSymbolInScope(symName,
     1836                    AsmSymbol(handler.gotSection, gotSymbolIndex*8));
     1837        if (!res.second)
     1838        {
     1839            // if symbol found
     1840            if (res.first->second.onceDefined && res.first->second.isDefined()) // if label
     1841                asmr.printError(symNamePlace, (std::string("Symbol '")+symName.c_str()+
     1842                            "' is already defined").c_str());
     1843            else // set value of symbol
     1844                asmr.setSymbol(*res.first, gotSymbolIndex*8, handler.gotSection);
     1845        }
     1846        else // set hasValue (by isResolvableSection
     1847            res.first->second.hasValue = true;
     1848    }
     1849    // set GOT section size
     1850    asmr.sections[handler.gotSection].size = handler.gotSymbols.size()*8;
     1851}
     1852
    17531853
    17541854void AsmROCmPseudoOps::updateKCodeSel(AsmROCmHandler& handler,
     
    19602060            AsmROCmPseudoOps::setConfigValue(*this, stmtPlace, linePtr,
    19612061                             ROCMCVAL_GDS_SEGMENT_SIZE);
     2062            break;
     2063        case ROCMOP_GOTSYM:
     2064            AsmROCmPseudoOps::addGotSymbol(*this, stmtPlace, linePtr);
    19622065            break;
    19632066        case ROCMOP_GROUP_SEGMENT_ALIGN:
     
    25672670{
    25682671    output.extraSymbols.clear();
     2672   
     2673    // prepate got symbols set
     2674    Array<CString> gotSymSet(gotSymbols.begin(), gotSymbols.end());
     2675    std::sort(gotSymSet.begin(), gotSymSet.end());
     2676   
    25692677    // if set adds symbols to binary
    25702678    std::vector<ROCmSymbolInput> dataSymbols;
    2571     if (assembler.getFlags() & ASM_FORCE_ADD_SYMBOLS)
     2679   
     2680    const bool forceAddSymbols = (assembler.getFlags() & ASM_FORCE_ADD_SYMBOLS) != 0;
     2681   
     2682    if (forceAddSymbols || !gotSymbols.empty())
    25722683        for (const AsmSymbolEntry& symEntry: assembler.globalScope.symbolMap)
    25732684        {
     2685            if (!forceAddSymbols &&
     2686                !std::binary_search(gotSymSet.begin(), gotSymSet.end(), symEntry.first))
     2687                // if not forceAddSymbols and if not in got symbols
     2688                continue;
     2689               
    25742690            if (ELF32_ST_BIND(symEntry.second.info) == STB_LOCAL)
    25752691                continue; // local
     
    26272743        binGen->updateSymbols();
    26282744    }
     2745   
     2746    if (gotSymbols.empty())
     2747        return good;
     2748   
     2749    // create map to speedup finding symbol indices
     2750    size_t outputSymsNum = output.symbols.size();
     2751    Array<std::pair<CString, size_t> > outputSymMap(outputSymsNum);
     2752    for (size_t i = 0; i < outputSymsNum; i++)
     2753        outputSymMap[i] = std::make_pair(output.symbols[i].symbolName, i);
     2754    mapSort(outputSymMap.begin(), outputSymMap.end());
     2755   
     2756    size_t extraSymsNum = output.extraSymbols.size();
     2757    Array<std::pair<CString, size_t> > extraSymMap(extraSymsNum);
     2758    for (size_t i = 0; i < extraSymsNum; i++)
     2759        extraSymMap[i] = std::make_pair(output.extraSymbols[i].name, i);
     2760    mapSort(extraSymMap.begin(), extraSymMap.end());
     2761   
     2762    // prepare GOT symbols
     2763    const AsmSymbolMap& symbolMap = assembler.getSymbolMap();
     2764    for (const CString& symName: gotSymbols)
     2765    {
     2766        const AsmSymbolEntry& symEntry = *symbolMap.find(symName);
     2767        if (!symEntry.second.hasValue)
     2768        {
     2769            good = false;
     2770            assembler.printError(nullptr, (std::string(
     2771                    "GOT symbol '")+symName.c_str()+"' is unresolved").c_str());
     2772            continue;
     2773        }
     2774        if (ELF32_ST_BIND(symEntry.second.info) != STB_GLOBAL)
     2775        {
     2776            good = false;
     2777            assembler.printError(nullptr, (std::string(
     2778                    "GOT symbol '")+symName.c_str()+"' is not global symbol").c_str());
     2779            continue;
     2780        }
     2781       
     2782        // put to output got symbols table
     2783        auto it = binaryMapFind(outputSymMap.begin(), outputSymMap.end(), symName);
     2784        if (it != outputSymMap.end())
     2785            output.gotSymbols.push_back(it->second);
     2786        else
     2787        {   // find in extra symbols
     2788            it = binaryMapFind(extraSymMap.begin(), extraSymMap.end(), symName);
     2789            if (it != extraSymMap.end())
     2790                output.gotSymbols.push_back(outputSymsNum + it->second);
     2791            else
     2792            {
     2793                good = false;
     2794                assembler.printError(nullptr, (std::string(
     2795                        "GOT symbol '")+symName.c_str()+"' not found!").c_str());
     2796            }
     2797        }
     2798    }
    26292799    return good;
    26302800}
  • CLRadeonExtender/trunk/amdasm/AsmROCmInternals.h

    r3745 r3795  
    209209                      const char* pseudoOpPlace, const char* linePtr);
    210210   
     211    // .gotsym
     212    static void addGotSymbol(AsmROCmHandler& handler,
     213                    const char* pseudoOpPlace, const char* linePtr);
     214   
    211215    // .kcode (open kernel code)
    212216    static void doKCode(AsmROCmHandler& handler, const char* pseudoOpPlace,
Note: See TracChangeset for help on using the changeset viewer.