www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Interesting ELF symbols in dmd-generated binaries

I was trying out a tool called 'maze'; quoting from http://kloobok.com/ 
"a novel testing and debugging environment that removes thread execution 
uncertainty".

The tool reported some symbol problems in dmd-generated binaries:

maze:    WARNING: An invalid symbol in the binary "/home/acehreli/deneme/
d/deneme": { mName = "", mStart = 0x44c3c4, mEnd = 0x48c148 }.

Those warnings have been removed from the recent beta releases of 'maze', 
but I asked the developer to provide a program that would show these 
symbols.

She gave me permission to post the test program here, saying:

<quote>
I created a small program thet reports undefined symbols in the binary.
Yet I am not sure that generation of these symbols is necessarily a
compiler bug. Their addresses are not entirely random, but always fall
on "callq" or "retq" instructions. Perhaps they serve some purpose, for
example they might be used by the linker. I'd consult the writer of the
compiler before filing this as a bug.
[...]
Compile it with "g++ test.cc -o test -lelf" and run with "./test deneme".
</quote>

(Note: 'deneme' is the name of the dmd-generated binary.)

I wanted to get your opinion on whether these symbols in dmd-generated 
binaries really are invalid, or something specific to perhaps D, which 
the tool doesn't understand.

Thank you,
Ali

//-----------------------------------------------------------------------------
// Copyright (c) 2011, Kloobok LLC. All Rights Reserved.
// Author: Roni Simonian
//-----------------------------------------------------------------------------
// test.cc
//-----------------------------------------------------------------------------
// Compile: g++ test.cc -o test -lelf
// Usage: ./test deneme
// 
// Print out the text symbols with no type, and no size, and with name=""
//------------------------------------------------------------------------------

#include <cassert>           // for assert
#include <fcntl.h>           // for open
#include <iostream>          // for std::cerr, std::endl
#include <gelf.h>            // for Elf, GElf_* elf_*()

using namespace std;

////////////////////////////////////////////////////////////////////////////////

int main(int argc,
	 char **argv)
{
  if((argc != 2) || (argv[1] == 0) || (argv[1][0] == '\0'))
    {
      cerr << "Usage: " << argv[0] << " <name of a binary file>" << endl;
      return -1;
    }

  assert(elf_version(EV_CURRENT) != EV_NONE);

  int fd = open(argv[1], O_RDONLY);

  Elf * elf = elf_begin(fd, ELF_C_READ, 0);
  assert(elf != 0);

  // find a text section 
  Elf_Scn * section = 0;
  GElf_Shdr section_header;

  while(((section = elf_nextscn(elf, section)) != 0) &&
	(gelf_getshdr(section, &section_header) == &section_header) &&
	(section_header.sh_type != SHT_SYMTAB));

  assert((section != 0) && (section_header.sh_link > 0));

  // the index of the string table associated with this section
   const Elf64_Word string_table_idx = section_header.sh_link;

  Elf_Data * data = 0;

  while((data = elf_getdata(section, data)) != 0) // read symbol table 
data
    {
      GElf_Sym symbol;
      int i = 0;
      char  * name = 0;

      // scan all symbols and add the symbols with "type" to the vector

      while(gelf_getsym(data, i++, &symbol) == &symbol)
	{
	  if((symbol.st_shndx != SHN_UNDEF) && 
	     (GELF_ST_TYPE(symbol.st_info) == STT_NOTYPE) &&
	     ((section = elf_getscn(elf, symbol.st_shndx)) != 0) &&
	     ((gelf_getshdr(section, &section_header) == 
&section_header)) &&
	     (section_header.sh_type == SHT_PROGBITS) &&
	     ((name = elf_strptr(elf, string_table_idx, symbol.st_name)) !
= 0) &&
	     (*name == '\0'))
	    {
	      cout << "GElf_Sym { st_name = " << symbol.st_name 
		   << ", st_info = " << static_cast<unsigned short>
(symbol.st_info)
		   << ", st_other = " << static_cast<unsigned short>
(symbol.st_other)
		   << ", st_shndx = " << symbol.st_shndx << ", st_value = 
"
		   << hex << symbol.st_value << dec
		   << ", st_size = " << symbol.st_size << " }.\n";
	    }
	}
    }
  
  return 0;
}
Oct 19 2011