Ignore:
Timestamp:
Nov 1, 2016, 1:38:49 PM (3 years ago)
Author:
matszpk
Message:

CLRadeonExtender: Store kernels and regions in region list together (instead of same kernels).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/amdbin/ROCmBinaries.cpp

    r2516 r2518  
    3030ROCmBinary::ROCmBinary(size_t binaryCodeSize, cxbyte* binaryCode, Flags creationFlags)
    3131        : ElfBinary64(binaryCodeSize, binaryCode, creationFlags),
    32           kernelsNum(0), codeSize(0), code(nullptr)
     32          regionsNum(0), codeSize(0), code(nullptr)
    3333{
    3434    cxuint textIndex = SHN_UNDEF;
     
    4646    }
    4747   
    48     kernelsNum = 0;
    49     size_t symsNum = 0;
     48    regionsNum = 0;
    5049    const size_t symbolsNum = getSymbolsNum();
    5150    for (size_t i = 0; i < symbolsNum; i++)
    5251    {
    5352        const Elf64_Sym& sym = getSymbol(i);
    54         if (sym.st_shndx==textIndex)
    55         {
    56             if (ELF64_ST_TYPE(sym.st_info)==STT_GNU_IFUNC)
    57                 kernelsNum++;
    58             symsNum++;
    59         }
     53        const cxbyte symType = ELF64_ST_TYPE(sym.st_info);
     54        if (sym.st_shndx==textIndex &&
     55            (symType==STT_GNU_IFUNC || symType==STT_OBJECT))
     56            regionsNum++;
    6057    }
    61     if (code==nullptr && kernelsNum!=0)
    62         throw Exception("No code if kernels number is not zero");
    63     kernels.reset(new ROCmKernel[kernelsNum]);
    64     size_t j = 0, k = 0;
    65     typedef std::pair<uint64_t, size_t> KernelOffsetEntry;
    66     std::unique_ptr<KernelOffsetEntry[]> symOffsets(new KernelOffsetEntry[symsNum]);
     58    if (code==nullptr && regionsNum!=0)
     59        throw Exception("No code if regions number is not zero");
     60    regions.reset(new ROCmRegion[regionsNum]);
     61    size_t j = 0;
     62    typedef std::pair<uint64_t, size_t> RegionOffsetEntry;
     63    std::unique_ptr<RegionOffsetEntry[]> symOffsets(new RegionOffsetEntry[regionsNum]);
    6764   
    6865    for (size_t i = 0; i < symbolsNum; i++)
     
    7370        const size_t value = ULEV(sym.st_value);
    7471        if (value < codeOffset)
    75             throw Exception("Kernel offset is too small!");
     72            throw Exception("Region offset is too small!");
    7673        const size_t size = ULEV(sym.st_size);
    77         if (ELF64_ST_TYPE(sym.st_info)!=STT_GNU_IFUNC)
    78         {
    79             symOffsets[k++] = std::make_pair(value, SIZE_MAX);
    80             continue;
    81         }
    82         else // if kernel symbol
    83             symOffsets[k++] = std::make_pair(value, j);
    8474       
    85         if (value+0x100 > codeOffset+codeSize)
     75        const cxbyte symType = ELF64_ST_TYPE(sym.st_info);
     76        const bool isKernel = (symType==STT_GNU_IFUNC);
     77        if (symType==STT_GNU_IFUNC || symType==STT_OBJECT)
     78            symOffsets[j] = std::make_pair(value, j);
     79       
     80        if (isKernel && value+0x100 > codeOffset+codeSize)
    8681            throw Exception("Kernel offset is too big!");
    87         kernels[j++] = { getSymbolName(i), value, (size>=0x100) ? size-0x100 : 0,
    88             value+0x100 };
     82        regions[j++] = { getSymbolName(i), size, value, isKernel };
    8983    }
    90     std::sort(symOffsets.get(), symOffsets.get()+symsNum,
    91             [](const KernelOffsetEntry& a, const KernelOffsetEntry& b)
     84    std::sort(symOffsets.get(), symOffsets.get()+regionsNum,
     85            [](const RegionOffsetEntry& a, const RegionOffsetEntry& b)
    9286            { return a.first < b.first; });
    93     // checking distance between kernels
    94     for (size_t i = 1; i <= symsNum; i++)
     87    // checking distance between regions
     88    for (size_t i = 1; i <= regionsNum; i++)
    9589    {
    96         if (symOffsets[i-1].second==SIZE_MAX)
    97             continue;   // if not kernel symbol
    98         size_t end = (i<symsNum) ? symOffsets[i].first : codeOffset+codeSize;
    99         if (symOffsets[i-1].first+0x100 > end)
     90        size_t end = (i<regionsNum) ? symOffsets[i].first : codeOffset+codeSize;
     91        ROCmRegion& region = regions[symOffsets[i-1].second];
     92        if (region.isKernel && symOffsets[i-1].first+0x100 > end)
    10093            throw Exception("Kernel size is too small!");
    101         ROCmKernel& kernel = kernels[symOffsets[i-1].second];
    102         uint64_t kcodeSize = end - (symOffsets[i-1].first+0x100);
    103         if (kernel.codeSize==0)
    104             kernel.codeSize = kcodeSize;
     94       
     95        const uint64_t regSize = end - symOffsets[i-1].first;
     96        if (region.size==0)
     97            region.size = regSize;
    10598        else
    106             kernel.codeSize = std::min(kcodeSize, kernel.codeSize);
     99            region.size = std::min(regSize, region.size);
    107100    }
    108101   
    109     if (hasKernelMap())
    110     {   // create kernels map
    111         kernelsMap.resize(kernelsNum);
    112         for (size_t i = 0; i < kernelsNum; i++)
    113             kernelsMap[i] = std::make_pair(kernels[i].kernelName, i);
    114         mapSort(kernelsMap.begin(), kernelsMap.end());
     102    if (hasRegionMap())
     103    {   // create region map
     104        regionsMap.resize(regionsNum);
     105        for (size_t i = 0; i < regionsNum; i++)
     106            regionsMap[i] = std::make_pair(regions[i].regionName, i);
     107        mapSort(regionsMap.begin(), regionsMap.end());
    115108    }
    116109}
    117110
    118 const ROCmKernel& ROCmBinary::getKernel(const char* name) const
     111const ROCmRegion& ROCmBinary::getRegion(const char* name) const
    119112{
    120     KernelMap::const_iterator it = binaryMapFind(kernelsMap.begin(),
    121                              kernelsMap.end(), name);
    122     if (it == kernelsMap.end())
    123         throw Exception("Can't find kernel name");
    124     return kernels[it->second];
     113    RegionMap::const_iterator it = binaryMapFind(regionsMap.begin(),
     114                             regionsMap.end(), name);
     115    if (it == regionsMap.end())
     116        throw Exception("Can't find region name");
     117    return regions[it->second];
    125118}
    126119
Note: See TracChangeset for help on using the changeset viewer.