Esempio n. 1
0
Section*
BinObject::AppendSection(llvm::StringRef name,
                         SourceLocation source,
                         Diagnostic& diags)
{
    bool bss = (name == ".bss");
    bool code = (name == ".text");
    Section* section = new Section(name, code, bss, source);
    m_object.AppendSection(std::auto_ptr<Section>(section));

    // Initialize section data and symbols.
    std::auto_ptr<BinSection> bsd(new BinSection());

    SymbolRef start = m_object.getSymbol(("section."+name+".start").str());
    if (start->okToDeclare(Symbol::EXTERN))
    {
        start->Declare(Symbol::EXTERN);
        start->setDeclSource(source);
    }
    start->AddAssocData(std::auto_ptr<BinSymbol>
        (new BinSymbol(*section, *bsd, BinSymbol::START)));

    SymbolRef vstart = m_object.getSymbol(("section."+name+".vstart").str());
    if (vstart->okToDeclare(Symbol::EXTERN))
    {
        vstart->Declare(Symbol::EXTERN);
        vstart->setDeclSource(source);
    }
    vstart->AddAssocData(std::auto_ptr<BinSymbol>
        (new BinSymbol(*section, *bsd, BinSymbol::VSTART)));

    SymbolRef length = m_object.getSymbol(("section."+name+".length").str());
    if (length->okToDeclare(Symbol::EXTERN))
    {
        length->Declare(Symbol::EXTERN);
        length->setDeclSource(source);
    }
    length->AddAssocData(std::auto_ptr<BinSymbol>
        (new BinSymbol(*section, *bsd, BinSymbol::LENGTH)));

    section->AddAssocData(std::auto_ptr<BinSection>(bsd.release()));

    return section;
}
Esempio n. 2
0
bool
ElfConfig::ReadSymbolTable(const MemoryBuffer&  in,
                           const ElfSection&    symtab_sect,
                           ElfSymtab&           symtab,
                           Object&              object,
                           const StringTable&   strtab,
                           Section*             sections[],
                           DiagnosticsEngine&   diags) const
{
    ElfSize symsize = symtab_sect.getEntSize();
    if (symsize == 0)
    {
        diags.Report(SourceLocation(), diag::err_symbol_entity_size_zero);
        return false;
    }

    unsigned long size = symtab_sect.getSize().getUInt();

    // Symbol table always starts with null entry
    symtab.push_back(SymbolRef(0));

    ElfSymbolIndex index = 1;
    for (unsigned long pos=symsize; pos<size; pos += symsize, ++index)
    {
        std::auto_ptr<ElfSymbol> elfsym(
            new ElfSymbol(*this, in, symtab_sect, index, sections, diags));
        if (diags.hasErrorOccurred())
            return false;

        SymbolRef sym = elfsym->CreateSymbol(object, strtab);
        symtab.push_back(sym);

        if (sym)
            sym->AddAssocData(elfsym);  // Associate symbol data with symbol
    }
    return true;
}
Esempio n. 3
0
bool
XdfObject::Read(SourceManager& sm, Diagnostic& diags)
{
    const llvm::MemoryBuffer& in = *sm.getBuffer(sm.getMainFileID());
    InputBuffer inbuf(in);
    inbuf.setLittleEndian();

    // Read object header
    if (inbuf.getReadableSize() < FILEHEAD_SIZE)
    {
        diags.Report(SourceLocation(), diag::err_object_header_unreadable);
        return false;
    }
    unsigned long magic = ReadU32(inbuf);
    if (magic != XDF_MAGIC)
    {
        diags.Report(SourceLocation(), diag::err_not_file_type) << "XDF";
        return false;
    }
    unsigned long scnum = ReadU32(inbuf);
    unsigned long symnum = ReadU32(inbuf);
    unsigned long headers_len = ReadU32(inbuf);
    if (inbuf.getReadableSize() < headers_len)
    {
        diags.Report(SourceLocation(), diag::err_xdf_headers_unreadable);
        return false;
    }

    unsigned long section_offset = FILEHEAD_SIZE;
    unsigned long symtab_offset = section_offset + SECTHEAD_SIZE*scnum;
    unsigned long strtab_offset = symtab_offset + SYMBOL_SIZE*symnum;
    ReadString read_string(in, strtab_offset,
                           FILEHEAD_SIZE+headers_len-strtab_offset,
                           diags);

    // Storage for nrelocs, indexed by section number
    std::vector<unsigned long> sects_nrelocs;
    sects_nrelocs.reserve(scnum);

    // Create sections
    for (unsigned long i=0; i<scnum; ++i)
    {
        // Start with symbol=0 as it's not created yet; updated later.
        std::auto_ptr<XdfSection> xsect(new XdfSection(SymbolRef(0)));
        unsigned long name_sym_index;
        IntNum lma, vma;
        unsigned long align;
        bool bss;
        unsigned long filepos;
        unsigned long nrelocs;
        xsect->Read(in, section_offset+SECTHEAD_SIZE*i, &name_sym_index, &lma,
                    &vma, &align, &bss, &filepos, &nrelocs);
        xsect->scnum = i;

        // get section name from section symbol entry
        inbuf.setPosition(symtab_offset+name_sym_index*SYMBOL_SIZE+8);
        llvm::StringRef sectname = read_string(ReadU32(inbuf));

        std::auto_ptr<Section> section(
            new Section(sectname, xsect->bits != 0, bss, SourceLocation()));

        section->setFilePos(filepos);
        section->setVMA(vma);
        section->setLMA(lma);

        if (bss)
        {
            Bytecode& gap =
                section->AppendGap(xsect->size, SourceLocation());
            Diagnostic nodiags(0);
            gap.CalcLen(0, nodiags);    // force length calculation of gap
        }
        else
        {
            // Read section data
            inbuf.setPosition(filepos);
            if (inbuf.getReadableSize() < xsect->size)
            {
                diags.Report(SourceLocation(),
                             diag::err_section_data_unreadable) << sectname;
                return false;
            }

            section->bytecodes_front().getFixed().Write(inbuf.Read(xsect->size),
                                                        xsect->size);
        }

        // Associate section data with section
        section->AddAssocData(xsect);

        // Add section to object
        m_object.AppendSection(section);

        sects_nrelocs.push_back(nrelocs);
    }

    // Create symbols
    inbuf.setPosition(symtab_offset);
    for (unsigned long i=0; i<symnum; ++i)
    {
        unsigned long sym_scnum = ReadU32(inbuf);           // section number
        unsigned long value = ReadU32(inbuf);               // value
        llvm::StringRef symname = read_string(ReadU32(inbuf));// name
        unsigned long flags = ReadU32(inbuf);               // flags

        SymbolRef sym = m_object.getSymbol(symname);
        if ((flags & XdfSymbol::XDF_GLOBAL) != 0)
            sym->Declare(Symbol::GLOBAL);
        else if ((flags & XdfSymbol::XDF_EXTERN) != 0)
            sym->Declare(Symbol::EXTERN);

        if ((flags & XdfSymbol::XDF_EQU) != 0)
            sym->DefineEqu(Expr(value));
        else if (sym_scnum < scnum)
        {
            Section& sect = m_object.getSection(sym_scnum);
            Location loc = {&sect.bytecodes_front(), value};
            sym->DefineLabel(loc);
        }

        // Save index in symrec data
        sym->AddAssocData(std::auto_ptr<XdfSymbol>(new XdfSymbol(i)));
    }

    // Update section symbol info, and create section relocations
    std::vector<unsigned long>::iterator nrelocsi = sects_nrelocs.begin();
    for (Object::section_iterator sect=m_object.sections_begin(),
         end=m_object.sections_end(); sect != end; ++sect, ++nrelocsi)
    {
        XdfSection* xsect = sect->getAssocData<XdfSection>();
        assert(xsect != 0);

        // Read relocations
        inbuf.setPosition(xsect->relptr);
        if (inbuf.getReadableSize() < (*nrelocsi) * RELOC_SIZE)
        {
            diags.Report(SourceLocation(), diag::err_section_relocs_unreadable)
                << sect->getName();
            return false;
        }

        for (unsigned long i=0; i<(*nrelocsi); ++i)
        {
            unsigned long addr = ReadU32(inbuf);
            unsigned long sym_index = ReadU32(inbuf);
            unsigned long basesym_index = ReadU32(inbuf);
            XdfReloc::Type type = static_cast<XdfReloc::Type>(ReadU8(inbuf));
            XdfReloc::Size size = static_cast<XdfReloc::Size>(ReadU8(inbuf));
            unsigned char shift = ReadU8(inbuf);
            ReadU8(inbuf);      // flags; ignored
            SymbolRef sym = m_object.getSymbol(sym_index);
            SymbolRef basesym(0);
            if (type == XdfReloc::XDF_WRT)
                basesym = m_object.getSymbol(basesym_index);
            sect->AddReloc(std::auto_ptr<Reloc>(
                new XdfReloc(addr, sym, basesym, type, size, shift)));
        }
    }
    if (diags.hasErrorOccurred())
        return false;
    return true;
}