Hi, i'm have already wrote ELF file loader and relocation. But on wiki there aren't any information about common symbols. Common symbols have 0xFFF2 at property 'SectionHeaderIndex(shndx)'. That symbols have filled field 'size' and in field 'value' stores aligment for that section. GCC makes all variables(no strings) in symbol table are common.To use that common symbols you need to calc they size. Just iterate throgh all symbols and find any common, then add to some variable their size.
Code:
//Calculate common section length
unsigned int commonSectionLength = 0;
for(int i=0;i<elf->e_shnum;i++)
{
ESHeader *sh = 0x28 * i + (int)elf + elf->e_shoff;
if(sh->sh_type == 2)
{
ESymbol * st = sh->sh_offset + (int)elf;
for(int i=0;i<sh->sh_size/0x10;i++)
if(st[i].st_shndx==0xFFF2)
commonSectionLength+=st[i].st_size;
}
}
Then you need to allocate some memory for them. And set their field 'value' to allocated address plus offset from start from that; And say, that it have absolute address(Set shndx to 0xFFF1).
Code:
unsigned int commonSectionPtr = malloc(commonSectionLength);//Allocate common section
unsigned int comId = 0;
for(int i=0;i<elf->e_shnum;i++)
{
ESHeader *sh = 0x28 * i + (int)elf + elf->e_shoff;
if(sh->sh_type == 2)
{
ESymbol * st = sh->sh_offset + (int)elf;
for(int i=0;i<sh->sh_size/0x10;i++)
{
if(st[i].st_shndx==0xFFF2)
{
*((unsigned short*)(sh->sh_offset + (int)elf + 0x10 * i + 0xE)) = 0xFFF1; //Absolute offset
*((unsigned int*)(sh->sh_offset + (int)elf + 0x10 * i + 0x4)) = commonSectionPtr + comId; //Set offset
// printTextToWindow(7, mywin, "Common: %x %x\n", i, comId);
comId+=st[i].st_size;
}
}
}
}
Then make relocation: (getSymAddr now have 3 variants of answer for you, that have described in wiki-page topic 'ELF Tutorial')
Code:
for(int i=0;i<elf->e_shnum;i++)
{
ESHeader *section = 0x28 * i + (int)elf + elf->e_shoff;
if(section->sh_type == 0x09)
{
RelTab * relocTable= section->sh_offset + (int)elf;
unsigned int RelocationCount = section->sh_size / 0x08;
unsigned int sectionForId = section->sh_info;
ESHeader *relocSection = 0x28 * sectionForId + (int)elf + elf->e_shoff;
unsigned int relocSectionOffset = relocSection->sh_offset +(int)elf;
for(int j=0;j< RelocationCount; j++)
{
unsigned int relocationSymbol = relocTable[j].r_info>>8;
unsigned int sectionOffset = relocTable[j].r_offset;
unsigned int additional = getSymAdr(elf, section->sh_link, relocationSymbol);
if(relocTable[j].r_info&1)
*((unsigned int*)(sectionOffset + (int)relocSectionOffset)) = *((unsigned int*)(sectionOffset + (int)relocSectionOffset)) + additional;
else if(relocTable[j].r_info&2)
*((int*)(sectionOffset + (int)relocSectionOffset)) = *((int*)(sectionOffset + (int)relocSectionOffset)) + additional - (sectionOffset + (int)relocSectionOffset)-4;
//printTextToWindow(7, mywin, "Reloc: %x \n", *((unsigned int*)(sectionOffset + (int)relocSectionOffset)));
}
}
}
That all!
Have a good day!
Cheers,
Aleksandr