[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Readefl bug
From: |
Silenzi, Claudio |
Subject: |
Readefl bug |
Date: |
Tue, 30 Sep 2003 11:31:46 +0200 |
The readelf didn't work with my elf object (Sharc micro) because readelf
doesn't follow the elf format specification.
In the get_32bit_section_headers() routine, the way to unpack sections is:
...
for (i = 0, internal = section_headers;
i < num;
i ++, internal ++)
{
internal->sh_name = BYTE_GET (shdrs[i].sh_name);
internal->sh_type = BYTE_GET (shdrs[i].sh_type);
internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
internal->sh_size = BYTE_GET (shdrs[i].sh_size);
internal->sh_link = BYTE_GET (shdrs[i].sh_link);
internal->sh_info = BYTE_GET (shdrs[i].sh_info);
internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
}
...
but it means each section occupies, in the elf file, a space equal to
sizeof(shdrs), that is not true. Each section occupies elf_header.e_shentsize.
The right way to unpack data is, for example:
...
pshdrs = (Elf32_External_Shdr *)&shdrs[0];
for (i = 0, internal = section_headers;
i < num;
i++, internal++)
{
internal->sh_name = BYTE_GET (pshdrs->sh_name);
internal->sh_type = BYTE_GET (pshdrs->sh_type);
internal->sh_flags = BYTE_GET (pshdrs->sh_flags);
internal->sh_addr = BYTE_GET (pshdrs->sh_addr);
internal->sh_offset = BYTE_GET (pshdrs->sh_offset);
internal->sh_size = BYTE_GET (pshdrs->sh_size);
internal->sh_link = BYTE_GET (pshdrs->sh_link);
internal->sh_info = BYTE_GET (pshdrs->sh_info);
internal->sh_addralign = BYTE_GET (pshdrs->sh_addralign);
internal->sh_entsize = BYTE_GET (pshdrs->sh_entsize);
pshdrs = (Elf32_External_Shdr *)((char *)&pshdrs[0] +
elf_header.e_shentsize);
}
...
where pshdrs is: Elf32_External_Shdr *pshdrs;
The same happens in get_32bit_elf_symbols() where each symbol is unpacked with:
...
for (j = 0, psym = isyms;
j < number;
j ++, psym ++)
{
psym->st_name = BYTE_GET (esyms[j].st_name);
psym->st_value = BYTE_GET (esyms[j].st_value);
psym->st_size = BYTE_GET (esyms[j].st_size);
psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
psym->st_shndx
= byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
psym->st_info = BYTE_GET (esyms[j].st_info);
psym->st_other = BYTE_GET (esyms[j].st_other);
}
...
where each symbol occupies sizeof(esyms), that is not true. Each symbol
occupies section->sh_entsize. So, the right way is for example:
...
slice = section->sh_entsize;
pesyms = (Elf32_External_Sym *)&esyms[0];
for (j = 0, psym = isyms;
j < number;
j++, psym++)
{
psym->st_name = BYTE_GET (pesyms->st_name);
psym->st_value = BYTE_GET (pesyms->st_value);
psym->st_size = BYTE_GET (pesyms->st_size);
psym->st_shndx = BYTE_GET (pesyms->st_shndx);
if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
psym->st_shndx
= byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
psym->st_info = BYTE_GET (pesyms->st_info);
psym->st_other = BYTE_GET (pesyms->st_other);
pesyms = (Elf32_External_Sym *)((char *)&pesyms[0] + slice);
}
...
I didn't take care of the 64bit versions of the routines.
In attachment you can find the file.
Best regards
Claudio Silenzi
Ferrari GES
Ufficio Elettronico
via Ascari, 55
Maranello (MO)
off. 0536-949343
mob.349-8449223
mailto:address@hidden
readelf.c
Description: readelf.c
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Readefl bug,
Silenzi, Claudio <=