Page MenuHomeFreeBSD

D37898.id114782.diff
No OneTemporary

D37898.id114782.diff

diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -771,6 +771,8 @@
ddb/db_variables.c optional ddb
ddb/db_watch.c optional ddb
ddb/db_write_cmd.c optional ddb
+ddb/db_pprint.c optional ddb
+ddb/db_ctf.c optional ddb
dev/aac/aac.c optional aac
dev/aac/aac_cam.c optional aacp aac
dev/aac/aac_debug.c optional aac
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -201,7 +201,37 @@
.if ${MK_CTF} != "no"
@echo ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ...
@${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
+.if defined(SUNW_LOADABLE)
+ @echo "Integrating .SUNW_ctf into the kernel"
+# Dump merged ctf data
+ @${OBJCOPY} --set-section-flags .SUNW_ctf=alloc,load,readonly ${.TARGET}
+ @${OBJCOPY} -O binary -j ".SUNW_ctf" ${.TARGET} ctf.raw
+
+# Create a temporary file to hold ctf data
+ @touch ctf.c
+ @${CC} -c ctf.c
+ @${OBJCOPY} --add-section .SUNW_ctf=ctf.raw ctf.o
+ @${OBJCOPY} --set-section-flags .SUNW_ctf=alloc,load,readonly ctf.o
+
+# Re-link the kernel
+ @echo Re-linking ${.TARGET}
+ ${SYSTEM_LD} ctf.o
+
+.if !empty(MD_ROOT_SIZE_CONFIGURED) && defined(MFS_IMAGE)
+ @sh ${S}/tools/embed_mfs.sh ${.TARGET} ${MFS_IMAGE}
.endif
+
+# Remove "old" .SUNW_ctf
+ @${OBJCOPY} -R ".SUNW_ctf" ${.TARGET}
+# Rename loadable ctf section
+ @objcopy --rename-section .kern_SUNW_ctf=.SUNW_ctf ${.TARGET}
+# Cleanup
+ @rm ctf.raw
+ @rm ctf.o
+ @rm ctf.c
+.endif
+.endif
+
.if !defined(DEBUG)
${OBJCOPY} --strip-debug ${.TARGET}
.endif
diff --git a/sys/conf/ldscript.amd64 b/sys/conf/ldscript.amd64
--- a/sys/conf/ldscript.amd64
+++ b/sys/conf/ldscript.amd64
@@ -176,6 +176,8 @@
This way it can be mapped using non-executable large pages. */
. = ALIGN(0x200000);
}
+ _ctf = .;
+ .kern_SUNW_ctf : { ctf.o(.SUNW_ctf) }
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
diff --git a/sys/kern/kern_ctf.c b/sys/kern/kern_ctf.c
--- a/sys/kern/kern_ctf.c
+++ b/sys/kern/kern_ctf.c
@@ -290,3 +290,32 @@
return (error);
}
+
+static int
+link_elf_ctf_get_ddb(linker_file_t lf, linker_ctf_t *lc)
+{
+#ifdef DDB_CTF
+ elf_file_t ef = (elf_file_t) lf;
+
+ if (lf == NULL || lc == NULL)
+ return (EINVAL);
+
+ if (ef->ctftab == 0 || ef->ctfcnt == 0){
+ return (EINVAL);
+ }
+
+ bzero(lc, sizeof(*lc));
+
+ lc->ctftab = ef->ctftab;
+ lc->ctfcnt = ef->ctfcnt;
+ lc->symtab = ef->ddbsymtab;
+ lc->nsym = ef->ddbsymcnt;
+ lc->strtab = ef->ddbstrtab;
+ lc->strcnt = ef->ddbstrcnt;
+
+ return (0);
+
+#else
+ return (EOPNOTSUPP);
+#endif
+}
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -778,6 +778,12 @@
return (LINKER_CTF_GET(file, lc));
}
+int
+linker_ctf_get_ddb(linker_file_t file, linker_ctf_t *lc)
+{
+ return (LINKER_CTF_GET_DDB(file, lc));
+}
+
static int
linker_file_add_dependency(linker_file_t file, linker_file_t dep)
{
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -73,6 +73,11 @@
#include "linker_if.h"
+#ifdef DDB_CTF
+#include <sys/ctf.h>
+#include <contrib/zlib/zlib.h>
+#endif
+
#define MAXSEGS 4
typedef struct elf_file {
@@ -180,6 +185,7 @@
KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
KOBJMETHOD(linker_ctf_get, link_elf_ctf_get),
+ KOBJMETHOD(linker_ctf_get_ddb, link_elf_ctf_get_ddb),
KOBJMETHOD(linker_symtab_get, link_elf_symtab_get),
KOBJMETHOD(linker_strtab_get, link_elf_strtab_get),
KOBJMETHOD_END
@@ -334,6 +340,76 @@
}
#endif /* GDB */
+#ifdef DDB_CTF
+static void
+link_elf_init_kernel_ctf(elf_file_t ef)
+{
+ extern uint8_t _ctf;
+ vm_offset_t sunw_addr =
+ (vm_offset_t)&_ctf; /* kernel sunw_ctf ldscript symbol */
+ vm_offset_t data_end_addr =
+ (vm_offset_t)&_end; /* data segment end ldscript symbol */
+ ctf_header_t *hp;
+ uint8_t *ctftab;
+ size_t ctfcnt;
+ int error;
+
+ ef->ctftab = 0;
+ ef->ctfcnt = 0;
+
+ /* Check if .SUNW_ctf was loaded */
+ if (sunw_addr == data_end_addr) {
+ printf("%s: %s: .SUNW_ctf was not loaded\n", __func__,
+ "kernel");
+ return;
+ }
+
+ printf("%s: %s: .SUNW_ctf at %p\n", __func__, "kernel",
+ (void *)sunw_addr);
+
+ hp = (ctf_header_t *)sunw_addr;
+
+ /* Sanity check. */
+ if (hp->cth_magic != CTF_MAGIC) {
+ printf("%s: bad kernel CTF magic value\n", __func__);
+ return;
+ }
+
+ if (hp->cth_version != CTF_VERSION_3) {
+ printf("%s: CTF V2 data encountered\n", __func__);
+ return;
+ }
+
+ ctfcnt = data_end_addr - sunw_addr;
+ /* Uncompress if necessary */
+ if (hp->cth_flags & CTF_F_COMPRESS) {
+ size_t decomp_size = hp->cth_stroff + hp->cth_strlen;
+
+ /* Allocate memory for the CTF header + decompressed data */
+ ctftab = malloc(decomp_size + sizeof(ctf_header_t), M_LINKER,
+ M_WAITOK);
+
+ /* Copy the ctf header into the buffer */
+ bcopy(hp, ctftab, sizeof(ctf_header_t));
+
+ /* Decompress rest of CTF data */
+ error = uncompress(ctftab + sizeof(ctf_header_t), &decomp_size,
+ (uint8_t *)sunw_addr + sizeof(ctf_header_t),
+ ctfcnt - sizeof(ctf_header_t));
+ if (error != Z_OK) {
+ printf("%s(%d): zlib uncompress returned %d\n",
+ __func__, __LINE__, error);
+ return;
+ }
+ } else {
+ ctftab = (uint8_t *)sunw_addr;
+ }
+
+ ef->ctftab = ctftab;
+ ef->ctfcnt = ctfcnt;
+}
+#endif
+
/*
* The kernel symbol table starts here.
*/
@@ -493,6 +569,10 @@
}
(void)link_elf_preload_parse_symbols(ef);
+#ifdef DDB_CTF
+ link_elf_init_kernel_ctf(ef);
+#endif
+
#ifdef GDB
r_debug.r_map = NULL;
r_debug.r_brk = r_debug_state;
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -170,6 +170,7 @@
KOBJMETHOD(linker_each_function_name, link_elf_each_function_name),
KOBJMETHOD(linker_each_function_nameval, link_elf_each_function_nameval),
KOBJMETHOD(linker_ctf_get, link_elf_ctf_get),
+ KOBJMETHOD(linker_ctf_get_ddb, link_elf_ctf_get_ddb),
KOBJMETHOD(linker_symtab_get, link_elf_symtab_get),
KOBJMETHOD(linker_strtab_get, link_elf_strtab_get),
KOBJMETHOD_END
diff --git a/sys/kern/linker_if.m b/sys/kern/linker_if.m
--- a/sys/kern/linker_if.m
+++ b/sys/kern/linker_if.m
@@ -116,6 +116,11 @@
linker_ctf_t *lc;
};
+METHOD int ctf_get_ddb {
+ linker_file_t file;
+ linker_ctf_t *lc;
+};
+
#
# Get the symbol table, returning it in **symtab. Return the
# number of symbols, otherwise zero.
diff --git a/sys/sys/linker.h b/sys/sys/linker.h
--- a/sys/sys/linker.h
+++ b/sys/sys/linker.h
@@ -321,6 +321,7 @@
} linker_ctf_t;
int linker_ctf_get(linker_file_t, linker_ctf_t *);
+int linker_ctf_get_ddb(linker_file_t, linker_ctf_t *);
int elf_cpu_load_file(linker_file_t);
int elf_cpu_unload_file(linker_file_t);

File Metadata

Mime Type
text/plain
Expires
Fri, Aug 21, 7:54 AM (6 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37025272
Default Alt Text
D37898.id114782.diff (6 KB)

Event Timeline