This is the mail archive of the cygwin@sourceware.cygnus.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

How to find the number of sections in a dll?



Hi, I am currently in the process of changing GDB to allocate
dynamically (instead of statically) the information about sections in
object files.

I ran into a problem in the win32-nat.c file, because I am not sure
how to get this information for a dll.

I browsed around the msdn site and found that there is a function,


PIMAGE_NT_HEADERS ImageNtHeader(
  PVOID ImageBase  
);

That returns a header from which I could retrieve the number of
sections:

typedef struct _IMAGE_NT_HEADERS {
    DWORD Signature;
    IMAGE_FILE_HEADER FileHeader;
    IMAGE_OPTIONAL_HEADER OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;

typedef struct _IMAGE_FILE_HEADER {
    WORD Machine;
    WORD NumberOfSections;
    DWORD TimeDateStamp;
    DWORD PointerToSymbolTable;
    DWORD NumberOfSymbols;
    WORD SizeOfOptionalHeader;
    WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

However I am not sure how to call the ImageNtHeader function, how to
set up the parameter and how to store the return type in a gdb friendly
way.

I couldn't find an example either. 

BTW, this is the function where I would need to know the number of sections:

static int
handle_load_dll (PTR dummy)
{
  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
  DWORD dll_name_ptr;
  DWORD done;
  char dll_buf[MAX_PATH + 1];
  char *p, *dll_name = NULL;
  struct objfile *objfile;
  MEMORY_BASIC_INFORMATION minfo;
  struct section_addr_info section_addrs;

  memset (&section_addrs, 0, sizeof (section_addrs));
  dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';

  if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
    dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';

  dll_name = dll_buf;

  /* Attempt to read the name of the dll that was detected.
     This is documented to work only when actively debugging
     a program.  It will not work for attached processes. */
  if (dll_name == NULL || *dll_name == '\0')
    {
      int size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
      int len = 0;
      char b[2];

      ReadProcessMemory (current_process_handle,
			 (LPCVOID) event->lpImageName,
			 (char *) &dll_name_ptr,
			 sizeof (dll_name_ptr), &done);

      /* See if we could read the address of a string, and that the
         address isn't null. */

      if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
	return 1;

      do
	{
	  ReadProcessMemory (current_process_handle,
			     (LPCVOID) (dll_name_ptr + len * size),
			     &b,
			     size,
			     &done);
	  len++;
	}
      while ((b[0] != 0 || b[size - 1] != 0) && done == size);

      dll_name = alloca (len);

      if (event->fUnicode)
	{
	  WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
	  ReadProcessMemory (current_process_handle,
			     (LPCVOID) dll_name_ptr,
			     unicode_dll_name,
			     len * sizeof (WCHAR),
			     &done);

	  WideCharToMultiByte (CP_ACP, 0,
			       unicode_dll_name, len,
			       dll_name, len, 0, 0);
	}
      else
	{
	  ReadProcessMemory (current_process_handle,
			     (LPCVOID) dll_name_ptr,
			     dll_name,
			     len,
			     &done);
	}
    }

  if (!dll_name)
    return 1;

  while ((p = strchr (dll_name, '\\')))
    *p = '/';

  /* The symbols in a dll are offset by 0x1000, which is the
     the offset from 0 of the first byte in an image - because
     of the file header and the section alignment. */

  section_addrs.other[0].name = ".text";
  section_addrs.other[0].addr = (int) event->lpBaseOfDll + 0x1000;
  safe_symbol_file_add (dll_name, 0, &section_addrs, 0, OBJF_SHARED);
  printf_unfiltered ("%x:%s\n", event->lpBaseOfDll, dll_name);

  return 1;
}


Any help is appreciated.

Thanks
Elena Zannoni
GDB Engineer.


--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]