summaryrefslogtreecommitdiff
path: root/sys/kern/link_elf_obj.c
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2009-07-14 22:48:30 +0000
committerRobert Watson <rwatson@FreeBSD.org>2009-07-14 22:48:30 +0000
commiteddfbb763ded6b5f6777335142be9a0edab628bb (patch)
tree13848f891fb2f7a396281b31633563d0f764ff65 /sys/kern/link_elf_obj.c
parent2286fe763592aa13d320186bf3e233a560af749b (diff)
Notes
Diffstat (limited to 'sys/kern/link_elf_obj.c')
-rw-r--r--sys/kern/link_elf_obj.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 9d4d70c83f2d..afcdd63a21bd 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include <machine/elf.h>
+#include <net/vnet.h>
+
#include <security/mac/mac_framework.h>
#include <vm/vm.h>
@@ -346,6 +348,21 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
ef->progtab[pb].size);
dpcpu_copy(dpcpu, shdr[i].sh_size);
ef->progtab[pb].addr = dpcpu;
+#ifdef VIMAGE
+ } else if (ef->progtab[pb].name != NULL &&
+ !strcmp(ef->progtab[pb].name, "set_vnet")) {
+ void *vnet_data;
+
+ vnet_data = vnet_data_alloc(shdr[i].sh_size);
+ if (vnet_data == NULL) {
+ error = ENOSPC;
+ goto out;
+ }
+ memcpy(vnet_data, ef->progtab[pb].addr,
+ ef->progtab[pb].size);
+ vnet_data_copy(vnet_data, shdr[i].sh_size);
+ ef->progtab[pb].addr = vnet_data;
+#endif
}
/* Update all symbol values with the offset. */
@@ -737,6 +754,12 @@ link_elf_load_file(linker_class_t cls, const char *filename,
!strcmp(ef->progtab[pb].name, "set_pcpu"))
ef->progtab[pb].addr =
dpcpu_alloc(shdr[i].sh_size);
+#ifdef VIMAGE
+ else if (ef->progtab[pb].name != NULL &&
+ !strcmp(ef->progtab[pb].name, "set_vnet"))
+ ef->progtab[pb].addr =
+ vnet_data_alloc(shdr[i].sh_size);
+#endif
else
ef->progtab[pb].addr =
(void *)(uintptr_t)mapbase;
@@ -758,10 +781,21 @@ link_elf_load_file(linker_class_t cls, const char *filename,
error = EINVAL;
goto out;
}
- /* Initialize the per-cpu area. */
- if (ef->progtab[pb].addr != (void *)mapbase)
+ /* Initialize the per-cpu or vnet area. */
+ if (ef->progtab[pb].addr != (void *)mapbase &&
+ !strcmp(ef->progtab[pb].name, "set_pcpu"))
dpcpu_copy(ef->progtab[pb].addr,
shdr[i].sh_size);
+#ifdef VIMAGE
+ else if (ef->progtab[pb].addr !=
+ (void *)mapbase &&
+ !strcmp(ef->progtab[pb].name, "set_vnet"))
+ vnet_data_copy(ef->progtab[pb].addr,
+ shdr[i].sh_size);
+#endif
+ else
+ panic("link_elf_load_file: unexpected "
+ "progbits type");
} else
bzero(ef->progtab[pb].addr, shdr[i].sh_size);
@@ -877,6 +911,11 @@ link_elf_unload_file(linker_file_t file)
if (!strcmp(ef->progtab[i].name, "set_pcpu"))
dpcpu_free(ef->progtab[i].addr,
ef->progtab[i].size);
+#ifdef VIMAGE
+ else if (!strcmp(ef->progtab[i].name, "set_vnet"))
+ vnet_data_free(ef->progtab[i].addr,
+ ef->progtab[i].size);
+#endif
}
}
if (ef->preloaded) {