Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Jul 2010 17:21:24 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r210424 - head/gnu/usr.bin/gdb/kgdb
Message-ID:  <201007231721.o6NHLOKl063542@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Fri Jul 23 17:21:23 2010
New Revision: 210424
URL: http://svn.freebsd.org/changeset/base/210424

Log:
  kgdb: correctly map sections to addresses in elf object modules (amd64)
  
  Unlike for modules with dso type, in elf object modules all the sections
  have virtual address of zero.  So, it is insufficient to add module base
  address to section virtual address (as recorded in section header) to
  get section address in kernel memory.
  Instead, we should apply the same calculations that are performed by
  kernel loaders (in boot code and in kernel) when they lay out sections
  in memory.
  
  Discussed with:	jhb, np
  MFC after:	3 weeks

Modified:
  head/gnu/usr.bin/gdb/kgdb/kld.c

Modified: head/gnu/usr.bin/gdb/kgdb/kld.c
==============================================================================
--- head/gnu/usr.bin/gdb/kgdb/kld.c	Fri Jul 23 17:07:51 2010	(r210423)
+++ head/gnu/usr.bin/gdb/kgdb/kld.c	Fri Jul 23 17:21:23 2010	(r210424)
@@ -198,12 +198,32 @@ find_kld_address (char *arg, CORE_ADDR *
 }
 
 static void
+adjust_section_address (struct section_table *sec, CORE_ADDR *curr_base)
+{
+	struct bfd_section *asect = sec->the_bfd_section;
+	bfd *abfd = sec->bfd;
+
+	if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) {
+		sec->addr += *curr_base;
+		sec->endaddr += *curr_base;
+		return;
+	}
+
+	*curr_base = align_power(*curr_base,
+	    bfd_get_section_alignment(abfd, asect));
+	sec->addr = *curr_base;
+	sec->endaddr = sec->addr + bfd_section_size(abfd, asect);
+	*curr_base = sec->endaddr;
+}
+
+static void
 load_kld (char *path, CORE_ADDR base_addr, int from_tty)
 {
 	struct section_addr_info *sap;
 	struct section_table *sections = NULL, *sections_end = NULL, *s;
 	struct cleanup *cleanup;
 	bfd *bfd;
+	CORE_ADDR curr_addr;
 	int i;
 
 	/* Open the kld. */
@@ -224,10 +244,9 @@ load_kld (char *path, CORE_ADDR base_add
 	if (build_section_table (bfd, &sections, &sections_end))
 		error("\"%s\": can't find file sections", path);
 	cleanup = make_cleanup(xfree, sections);
-	for (s = sections; s < sections_end; s++) {
-		s->addr += base_addr;
-		s->endaddr += base_addr;
-	}
+	curr_addr = base_addr;
+	for (s = sections; s < sections_end; s++)
+		adjust_section_address(s, &curr_addr);
 
 	/* Build a section addr info to pass to symbol_file_add(). */
 	sap = build_section_addr_info_from_section_table (sections,
@@ -284,9 +303,12 @@ kgdb_add_kld_cmd (char *arg, int from_tt
 static void
 kld_relocate_section_addresses (struct so_list *so, struct section_table *sec)
 {
+	static CORE_ADDR curr_addr;
+
+	if (sec == so->sections)
+		curr_addr = so->lm_info->base_address;
 
-	sec->addr += so->lm_info->base_address;
-	sec->endaddr += so->lm_info->base_address;
+	adjust_section_address(sec, &curr_addr);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201007231721.o6NHLOKl063542>