ELF Common symbols!

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
MrLolthe1st
Member
Member
Posts: 90
Joined: Sat Sep 24, 2016 12:06 am

ELF Common symbols!

Post by MrLolthe1st »

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: Select all

                //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: Select all

		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: Select all

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
nullplan
Member
Member
Posts: 1801
Joined: Wed Aug 30, 2017 8:24 am

Re: ELF Common symbols!

Post by nullplan »

I am not certain what you're doing there... if you are talking about completely linked ELF files, you should not deal with section headers at all. You should instead look at segments in the program header. The common symbol section is then generally included in the difference between the file size and memory size of the data segment.

If you are talking about dynamically linked programs, the same thing applies. The interpreter is named in the PT_INTERP program header, so you load and run that in addition to the program (remember to set AT_ENTRY, AT_PHDR and AT_BASE correctly). Once again no looping over symbols.

If you are writing a dynamic interpreter, then the dynamic section tells you where the symbols are that you need to relocate. And I don't think, dynamic modules can share common symbols.

So, are you writing a linker? Only in that case does your code make sense, but why would you start that undertaking?

Ciao,
Markus
Carpe diem!
Post Reply