Back to index

enigmail  1.4.3
Public Member Functions | Protected Attributes | Private Attributes
ElfDynamic_Section Class Reference

#include <elfxx.h>

Inheritance diagram for ElfDynamic_Section:
Inheritance graph
[legend]
Collaboration diagram for ElfDynamic_Section:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ElfDynamic_Section (Elf_Shdr &s, std::ifstream *file, Elf *parent)
 ~ElfDynamic_Section ()
void serialize (std::ofstream &file, char ei_class, char ei_data)
ElfValuegetValueForType (unsigned int tag)
ElfSectiongetSectionForType (unsigned int tag)
void setValueForType (unsigned int tag, ElfValue *val)
const char * getName ()
unsigned int getType ()
unsigned int getFlags ()
unsigned int getAddr ()
unsigned int getSize ()
unsigned int getAddrAlign ()
unsigned int getEntSize ()
const char * getData ()
ElfSectiongetLink ()
SectionInfo getInfo ()
void shrink (unsigned int newsize)
unsigned int getOffset ()
int getIndex ()
Elf_ShdrgetShdr ()
ElfSectiongetNext ()
ElfSectiongetPrevious ()
virtual bool isRelocatable ()
void insertAfter (ElfSection *section, bool dirty=true)
void markDirty ()

Protected Attributes

Elf_Shdr shdr
char * data
const char * name

Private Attributes

std::vector< Elf_DynValuedyns

Detailed Description

Definition at line 515 of file elfxx.h.


Constructor & Destructor Documentation

ElfDynamic_Section::ElfDynamic_Section ( Elf_Shdr s,
std::ifstream *  file,
Elf parent 
)

Definition at line 708 of file elf.cpp.

: ElfSection(s, file, parent)
{
    int pos = file->tellg();
    dyns.resize(s.sh_size / s.sh_entsize);
    file->seekg(shdr.sh_offset);
    // Here we assume tags refer to only one section (e.g. DT_RELSZ accounts
    // for .rel.dyn size)
    for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++) {
        Elf_Dyn dyn(*file, parent->getClass(), parent->getData());
        dyns[i].tag = dyn.d_tag;
        switch (dyn.d_tag) {
        case DT_NULL:
        case DT_SYMBOLIC:
        case DT_TEXTREL:
        case DT_BIND_NOW:
            dyns[i].value = new ElfValue();
            break;
        case DT_NEEDED:
        case DT_SONAME:
        case DT_RPATH:
        case DT_PLTREL:
        case DT_RUNPATH:
        case DT_FLAGS:
        case DT_RELACOUNT:
        case DT_RELCOUNT:
        case DT_VERDEFNUM:
        case DT_VERNEEDNUM:
            dyns[i].value = new ElfPlainValue(dyn.d_un.d_val);
            break;
        case DT_PLTGOT:
        case DT_HASH:
        case DT_STRTAB:
        case DT_SYMTAB:
        case DT_RELA:
        case DT_INIT:
        case DT_FINI:
        case DT_REL:
        case DT_JMPREL:
        case DT_INIT_ARRAY:
        case DT_FINI_ARRAY:
        case DT_GNU_HASH:
        case DT_VERSYM:
        case DT_VERNEED:
        case DT_VERDEF:
            dyns[i].value = new ElfLocation(dyn.d_un.d_ptr, parent);
            break;
        default:
            dyns[i].value = NULL;
        }
    }
    // Another loop to get the section sizes
    for (unsigned int i = 0; i < s.sh_size / s.sh_entsize; i++)
        switch (dyns[i].tag) {
        case DT_PLTRELSZ:
            dyns[i].value = new ElfSize(getSectionForType(DT_JMPREL));
            break;
        case DT_RELASZ:
            dyns[i].value = new ElfSize(getSectionForType(DT_RELA));
            break;
        case DT_STRSZ:
            dyns[i].value = new ElfSize(getSectionForType(DT_STRTAB));
            break;
        case DT_RELSZ:
            dyns[i].value = new ElfSize(getSectionForType(DT_REL));
            break;
        case DT_INIT_ARRAYSZ:
            dyns[i].value = new ElfSize(getSectionForType(DT_INIT_ARRAY));
            break;
        case DT_FINI_ARRAYSZ:
            dyns[i].value = new ElfSize(getSectionForType(DT_FINI_ARRAY));
            break;
        case DT_RELAENT:
            dyns[i].value = new ElfEntSize(getSectionForType(DT_RELA));
            break;
        case DT_SYMENT:
            dyns[i].value = new ElfEntSize(getSectionForType(DT_SYMTAB));
            break;
        case DT_RELENT:
            dyns[i].value = new ElfEntSize(getSectionForType(DT_REL));
            break;
        }

    file->seekg(pos);
}

Here is the call graph for this function:

Definition at line 794 of file elf.cpp.

{
    for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++)
        delete dyns[i].value;
}

Member Function Documentation

unsigned int ElfSection::getAddr ( ) [inherited]

Definition at line 483 of file elf.cpp.

{
    if (shdr.sh_addr != (Elf32_Word)-1)
        return shdr.sh_addr;

    // It should be safe to adjust sh_addr for all allocated sections that
    // are neither SHT_NOBITS nor SHT_PROGBITS
    if ((previous != NULL) && isRelocatable()) {
        unsigned int addr = previous->getAddr();
        if (previous->getType() != SHT_NOBITS)
            addr += previous->getSize();

        if (addr & (getAddrAlign() - 1))
            addr = (addr | (getAddrAlign() - 1)) + 1;

        return (shdr.sh_addr = addr);
    }
    return shdr.sh_addr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned int ElfSection::getAddrAlign ( ) [inline, inherited]

Definition at line 342 of file elfxx.h.

{ return shdr.sh_addralign; }

Here is the caller graph for this function:

const char* ElfSection::getData ( ) [inline, inherited]

Definition at line 344 of file elfxx.h.

{ return data; }

Here is the caller graph for this function:

unsigned int ElfSection::getEntSize ( ) [inline, inherited]

Definition at line 343 of file elfxx.h.

{ return shdr.sh_entsize; }

Here is the caller graph for this function:

unsigned int ElfSection::getFlags ( ) [inline, inherited]

Definition at line 339 of file elfxx.h.

{ return shdr.sh_flags; }

Here is the caller graph for this function:

int ElfSection::getIndex ( ) [inherited]

Definition at line 541 of file elf.cpp.

{
    if (index != -1)
        return index;
    if (getType() == SHT_NULL)
        return (index = 0);
    ElfSection *reference;
    for (reference = previous; (reference != NULL) && (reference->getType() == SHT_NULL); reference = reference->getPrevious());
    if (reference == NULL)
        return (index = 1);
    return (index = reference->getIndex() + 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SectionInfo ElfSection::getInfo ( ) [inline, inherited]

Definition at line 346 of file elfxx.h.

{ return info; }

Here is the caller graph for this function:

ElfSection* ElfSection::getLink ( ) [inline, inherited]

Definition at line 345 of file elfxx.h.

{ return link; }

Here is the caller graph for this function:

const char* ElfSection::getName ( ) [inline, inherited]

Definition at line 337 of file elfxx.h.

{ return name; }

Here is the caller graph for this function:

ElfSection* ElfSection::getNext ( ) [inline, inherited]

Definition at line 360 of file elfxx.h.

{ return next; }

Here is the caller graph for this function:

unsigned int ElfSection::getOffset ( ) [inherited]

Definition at line 503 of file elf.cpp.

{
    if (shdr.sh_offset != (Elf32_Word)-1)
        return shdr.sh_offset;

    if (previous == NULL)
        return (shdr.sh_offset = 0);

    unsigned int offset = previous->getOffset();
    if (previous->getType() != SHT_NOBITS)
        offset += previous->getSize();

    Elf32_Word align = 0x1000;
    for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
        align = std::max(align, (*seg)->getAlign());

    Elf32_Word mask = align - 1;
    // SHF_TLS is used for .tbss which is some kind of special case.
    if (((getType() != SHT_NOBITS) || (getFlags() & SHF_TLS)) && (getFlags() & SHF_ALLOC)) {
        if ((getAddr() & mask) < (offset & mask))
            offset = (offset | mask) + (getAddr() & mask) + 1;
        else
            offset = (offset & ~mask) + (getAddr() & mask);
    }
    if ((getType() != SHT_NOBITS) && (offset & (getAddrAlign() - 1)))
        offset = (offset | (getAddrAlign() - 1)) + 1;

    // Two subsequent sections can't be mapped in the same page in memory
    // if they aren't in the same 4K block on disk.
    if ((getType() != SHT_NOBITS) && getAddr()) {
        if (((offset >> 12) != (previous->getOffset() >> 12)) &&
            ((getAddr() >> 12) == (previous->getAddr() >> 12)))
            throw std::runtime_error("Moving section would require overlapping segments");
    }

    return (shdr.sh_offset = offset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

ElfSection* ElfSection::getPrevious ( ) [inline, inherited]

Definition at line 361 of file elfxx.h.

{ return previous; }

Here is the caller graph for this function:

Definition at line 672 of file elf.cpp.

{
    ElfValue *value = getValueForType(tag);
    return value ? value->getSection() : NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Elf_Shdr & ElfSection::getShdr ( ) [inherited]

Definition at line 554 of file elf.cpp.

{
    getOffset();
    if (shdr.sh_link == (Elf32_Word)-1)
        shdr.sh_link = getLink() ? getLink()->getIndex() : 0;
    if (shdr.sh_info == (Elf32_Word)-1)
        shdr.sh_info = ((getType() == SHT_REL) || (getType() == SHT_RELA)) ?
                       (getInfo().section ? getInfo().section->getIndex() : 0) :
                       getInfo().index;

    return shdr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned int ElfSection::getSize ( ) [inline, inherited]

Definition at line 341 of file elfxx.h.

{ return shdr.sh_size; }

Here is the caller graph for this function:

unsigned int ElfSection::getType ( ) [inline, inherited]

Definition at line 338 of file elfxx.h.

{ return shdr.sh_type; }

Here is the caller graph for this function:

Definition at line 663 of file elf.cpp.

{
    for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++)
        if (dyns[i].tag == tag)
            return dyns[i].value;

    return NULL;
}

Here is the caller graph for this function:

void ElfSection::insertAfter ( ElfSection section,
bool  dirty = true 
) [inline, inherited]

Definition at line 379 of file elfxx.h.

                                                             {
        if (previous != NULL)
            previous->next = next;
        if (next != NULL)
            next->previous = previous;
        previous = section;
        if (section != NULL) {
            next = section->next;
            section->next = this;
        } else
            next = NULL;
        if (next != NULL)
            next->previous = this;
        if (dirty)
            markDirty();
    }

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool ElfSection::isRelocatable ( ) [inline, virtual, inherited]

Reimplemented in ElfRelHackCode_Section, and ElfRelHack_Section.

Definition at line 363 of file elfxx.h.

                                 {
        return ((getType() == SHT_SYMTAB) ||
                (getType() == SHT_STRTAB) ||
                (getType() == SHT_RELA) ||
                (getType() == SHT_HASH) ||
                (getType() == SHT_NOTE) ||
                (getType() == SHT_REL) ||
                (getType() == SHT_DYNSYM) ||
                (getType() == SHT_GNU_HASH) ||
                (getType() == SHT_GNU_verdef) ||
                (getType() == SHT_GNU_verneed) ||
                (getType() == SHT_GNU_versym) ||
                isInSegmentType(PT_INTERP)) &&
                (getFlags() & SHF_ALLOC);
    }

Here is the call graph for this function:

Here is the caller graph for this function:

void ElfSection::markDirty ( ) [inline, inherited]

Definition at line 396 of file elfxx.h.

                     {
        if (link != NULL)
            shdr.sh_link = -1;
        if (info.index)
            shdr.sh_info = -1;
        shdr.sh_offset = -1;
        if (isRelocatable())
            shdr.sh_addr = -1;
        if (next)
            next->markDirty();
    }

Here is the call graph for this function:

Here is the caller graph for this function:

void ElfDynamic_Section::serialize ( std::ofstream &  file,
char  ei_class,
char  ei_data 
) [virtual]

Reimplemented from ElfSection.

Definition at line 800 of file elf.cpp.

{
    for (unsigned int i = 0; i < shdr.sh_size / shdr.sh_entsize; i++) {
        Elf_Dyn dyn;
        dyn.d_tag = dyns[i].tag;
        dyn.d_un.d_val = (dyns[i].value != NULL) ? dyns[i].value->getValue() : 0;
        dyn.serialize(file, ei_class, ei_data);
    }
}

Here is the call graph for this function:

void ElfDynamic_Section::setValueForType ( unsigned int  tag,
ElfValue val 
)

Definition at line 678 of file elf.cpp.

{
    unsigned int i;
    for (i = 0; (i < shdr.sh_size / shdr.sh_entsize) && (dyns[i].tag != DT_NULL); i++)
        if (dyns[i].tag == tag) {
            delete dyns[i].value;
            dyns[i].value = val;
            return;
        }
    // This should never happen, as the last entry is always tagged DT_NULL
    assert(i < shdr.sh_size / shdr.sh_entsize);
    // If we get here, this means we didn't match for the given tag
    dyns[i].tag = tag;
    dyns[i++].value = val;

    // If we were on the last entry, we need to grow the section.
    // Most of the time, though, there are a few DT_NULL entries.
    if (i < shdr.sh_size / shdr.sh_entsize)
        return;

    Elf_DynValue value;
    value.tag = DT_NULL;
    value.value = NULL;
    dyns.push_back(value);
    // Resize the section accordingly
    shdr.sh_size += shdr.sh_entsize;
    if (getNext() != NULL)
        getNext()->markDirty();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ElfSection::shrink ( unsigned int  newsize) [inline, inherited]

Definition at line 348 of file elfxx.h.

                                      {
        if (newsize < shdr.sh_size) {
            shdr.sh_size = newsize;
            if (next)
                next->markDirty();
        }
    }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

char* ElfSection::data [protected, inherited]

Definition at line 431 of file elfxx.h.

std::vector<Elf_DynValue> ElfDynamic_Section::dyns [private]

Definition at line 526 of file elfxx.h.

const char* ElfSection::name [protected, inherited]

Definition at line 432 of file elfxx.h.

Elf_Shdr ElfSection::shdr [protected, inherited]

Definition at line 430 of file elfxx.h.


The documentation for this class was generated from the following files: