Changeset 3794 in CLRX


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

CLRadeonExtender: AsmROCm: Set value of data symbol as file offset. Add GOT symbols support to ROCm reader and ROCm disassembler.

Location:
CLRadeonExtender/trunk
Files:
5 edited

Legend:

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

    r3666 r3794  
    326326    size_t metadataSize;    ///< metadata size
    327327    const char* metadata;   ///< metadata
     328    Array<std::pair<CString, size_t> > gotSymbols; ///< GOT symbols names
    328329};
    329330
  • CLRadeonExtender/trunk/CLRX/amdbin/ROCmBinaries.h

    r3793 r3794  
    217217    std::unique_ptr<ROCmMetadata> metadataInfo;
    218218    RegionMap kernelInfosMap;
     219    Array<size_t> gotSymbols;
    219220    bool newBinFormat;
    220221public:
     
    297298    bool isNewBinaryFormat() const
    298299    { return newBinFormat; }
     300   
     301    /// get GOT symbol index (from elfbin dynsymbols)
     302    size_t getGotSymbolsNum() const
     303    { return gotSymbols.size(); }
     304   
     305    /// get GOT symbols (indices) (from elfbin dynsymbols)
     306    const Array<size_t> getGotSymbols() const
     307    { return gotSymbols; }
     308   
     309    /// get GOT symbol index (from elfbin dynsymbols)
     310    size_t getGotSymbol(size_t index) const
     311    { return gotSymbols[index]; }
    299312   
    300313    /// returns true if kernel map exists
     
    377390    bool useMetadataInfo;   ///< use metadatainfo instead same metadata
    378391    ROCmMetadata metadataInfo; ///< metadata info
    379     std::vector<size_t> gotSymbols; ///< list of indices of symbols to GOT section
     392   
     393    /// list of indices of symbols to GOT section
     394    /**  list of indices of symbols to GOT section.
     395     * If symbol index is lower than symbols.size(), then it refer to symbols
     396     * otherwise it refer to extraSymbols (index - symbols.size())
     397     */
     398    std::vector<size_t> gotSymbols;
    380399    std::vector<BinSection> extraSections;  ///< extra sections
    381400    std::vector<BinSymbol> extraSymbols;    ///< extra symbols
  • CLRadeonExtender/trunk/amdasm/AsmROCmFormat.cpp

    r3790 r3794  
    26022602           
    26032603            output.extraSymbols.push_back({ symEntry.first, symEntry.second.value,
    2604                     symEntry.second.size, binSectId, false,
     2604                    symEntry.second.size, binSectId, true,
    26052605                    info, symEntry.second.other });
    26062606        }
  • CLRadeonExtender/trunk/amdasm/DisasmROCm.cpp

    r3741 r3794  
    5353            size_t(region.offset - codeOffset), region.type };
    5454    }
     55   
     56    const size_t gotSymbolsNum = binary.getGotSymbolsNum();
     57    input->gotSymbols.resize(gotSymbolsNum);
     58   
     59    // get rodata index and offset
     60    cxuint rodataIndex = SHN_UNDEF;
     61    size_t rodataOffset = 0;
     62    try
     63    {
     64        rodataIndex = binary.getSectionIndex(".rodata");
     65        rodataOffset = ULEV(binary.getSectionHeader(rodataIndex).sh_offset);
     66    }
     67    catch(Exception& ex)
     68    { }
     69   
     70    // setup got symbols
     71    for (size_t i = 0; i < gotSymbolsNum; i++)
     72    {
     73        const size_t gotSymIndex = binary.getGotSymbol(i);
     74        const Elf64_Sym& sym = binary.getDynSymbol(gotSymIndex);
     75        size_t offset = SIZE_MAX;
     76        // set offset if symbol refer to some place in globaldata (rodata)
     77        if (rodataIndex != SHN_UNDEF && ULEV(sym.st_shndx) == rodataIndex)
     78            offset = ULEV(sym.st_value) - rodataOffset;
     79        input->gotSymbols[i] = { binary.getDynSymbolName(gotSymIndex), offset };
     80    }
     81   
    5582    // setup code
    5683    input->eflags = ULEV(binary.getHeader().e_flags);
     
    792819    }
    793820   
     821    // print got symbols
     822    for (const auto& gotSymbol: rocmInput->gotSymbols)
     823    {
     824        char buf[24];
     825        if (gotSymbol.second != SIZE_MAX)
     826        {
     827            // print got symbol definition
     828            output.write(".global ", 8);
     829            output.write(gotSymbol.first.c_str(), gotSymbol.first.size());
     830            output.write("\n", 1);
     831            output.write(gotSymbol.first.c_str(), gotSymbol.first.size());
     832            output.write(" = .gdata + ", 12);
     833            size_t numSize = itocstrCStyle(gotSymbol.second, buf, 24);
     834            output.write(buf, numSize);
     835            output.write("\n", 1);
     836        }
     837        output.write(".gotsym ", 8);
     838        output.write(gotSymbol.first.c_str(), gotSymbol.first.size());
     839        output.write("\n", 1);
     840    }
     841   
    794842    if (doDumpData && rocmInput->globalData != nullptr &&
    795843        rocmInput->globalDataSize != 0)
  • CLRadeonExtender/trunk/amdbin/ROCmBinaries.cpp

    r3793 r3794  
    13881388    newBinFormat = (gpuConfigIndex == SHN_UNDEF);
    13891389   
     1390    cxuint relaDynIndex = SHN_UNDEF;
     1391    try
     1392    { relaDynIndex = getSectionIndex(".rela.dyn"); }
     1393    catch(const Exception& ex)
     1394    { } // ignore failed
     1395   
     1396    cxuint gotIndex = SHN_UNDEF;
     1397    try
     1398    { gotIndex = getSectionIndex(".got"); }
     1399    catch(const Exception& ex)
     1400    { } // ignore failed
     1401   
    13901402    // counts regions (symbol or kernel)
    13911403    regionsNum = 0;
     
    14551467        else
    14561468            region.size = std::min(regSize, region.size);
     1469    }
     1470   
     1471    // load got symbols
     1472    if (relaDynIndex != SHN_UNDEF && gotIndex != SHN_UNDEF)
     1473    {
     1474        const Elf64_Shdr& relaShdr = getSectionHeader(relaDynIndex);
     1475        const Elf64_Shdr& gotShdr = getSectionHeader(gotIndex);
     1476       
     1477        size_t relaEntrySize = ULEV(relaShdr.sh_entsize);
     1478        if (relaEntrySize==0)
     1479            relaEntrySize = sizeof(Elf64_Rela);
     1480        const size_t relaEntriesNum = ULEV(relaShdr.sh_size)/relaEntrySize;
     1481        const size_t gotEntriesNum = ULEV(gotShdr.sh_size) >> 3;
     1482        if (gotEntriesNum != relaEntriesNum)
     1483            throw BinException("RelaDyn entries number and GOT entries "
     1484                        "number doesn't match!");
     1485       
     1486        // initialize GOT symbols table
     1487        gotSymbols.resize(gotEntriesNum);
     1488        const cxbyte* relaDyn = getSectionContent(relaDynIndex);
     1489        for (size_t i = 0; i < relaEntriesNum; i++)
     1490        {
     1491            const Elf64_Rela& rela = *reinterpret_cast<const Elf64_Rela*>(
     1492                            relaDyn + relaEntrySize*i);
     1493            // check rela entry fields
     1494            if (ULEV(rela.r_offset) != ULEV(gotShdr.sh_offset) + i*8)
     1495                throw BinException("Wrong dyn relocation offset");
     1496            if (ULEV(rela.r_addend) != 0ULL)
     1497                throw BinException("Wrong dyn relocation addend");
     1498            size_t symIndex = ELF64_R_SYM(ULEV(rela.r_info));
     1499            if (symIndex >= getDynSymbolsNum())
     1500                throw BinException("Dyn relocation symbol index out of range");
     1501            // just set in gotSymbols
     1502            gotSymbols[i] = symIndex;
     1503        }
    14571504    }
    14581505   
     
    19712018            Elf64_Rela rela{};
    19722019            SLEV(rela.r_offset, gotOffset + 8*i);
    1973             SLEV(rela.r_info, ELF64_R_INFO(input->symbols.size() + symIndex + 1, 3));
     2020            SLEV(rela.r_info, ELF64_R_INFO(symIndex + 1, 3));
    19742021            rela.r_addend = 0;
    19752022            fob.writeObject(rela);
Note: See TracChangeset for help on using the changeset viewer.