summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2010-07-23 17:21:23 +0000
committeravg <avg@FreeBSD.org>2010-07-23 17:21:23 +0000
commite702b156d5207a8b61360c3cc17e5805301f7b52 (patch)
tree527f0802b5d188afc6170acf6b250304436125de /gnu
parentb44b5ccee0f75a8542e6952669892eea0b6cca77 (diff)
downloadFreeBSD-src-e702b156d5207a8b61360c3cc17e5805301f7b52.zip
FreeBSD-src-e702b156d5207a8b61360c3cc17e5805301f7b52.tar.gz
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
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gdb/kgdb/kld.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/kld.c b/gnu/usr.bin/gdb/kgdb/kld.c
index 716a67c..d5ba20a 100644
--- a/gnu/usr.bin/gdb/kgdb/kld.c
+++ b/gnu/usr.bin/gdb/kgdb/kld.c
@@ -198,12 +198,32 @@ find_kld_address (char *arg, CORE_ADDR *address)
}
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_addr, int from_tty)
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_tty)
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
OpenPOWER on IntegriCloud