bug-gnu-utils
[Top][All Lists]
Advanced

[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

Attachment: readelf.c
Description: readelf.c


reply via email to

[Prev in Thread] Current Thread [Next in Thread]