Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
markjdb committed Jun 19, 2023
1 parent 45014dd commit 3985ddd
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 167 deletions.
163 changes: 13 additions & 150 deletions sys/ddb/db_ctf.c
Expand Up @@ -39,91 +39,6 @@
#include <ddb/ddb.h>
#include <ddb/db_ctf.h>

struct db_ctf {
linker_ctf_t lc;
char *modname;
LIST_ENTRY(db_ctf) link;
};

static LIST_HEAD(, db_ctf) ctf_table = SLIST_HEAD_INITIALIZER(ctf_table);
static struct mtx db_ctf_mtx;
MTX_SYSINIT(db_ctf, &db_ctf_mtx, "ddb module CTF data registry", MTX_DEF);

static MALLOC_DEFINE(M_DBCTF, "ddb ctf", "ddb module ctf data");

/* Used to register kernel CTF data before SUB_KLD. */
static struct db_ctf kctf;

static struct db_ctf *
db_ctf_lookup(const char *modname)
{
struct db_ctf *dcp;

LIST_FOREACH (dcp, &ctf_table, link) {
if (dcp->modname != NULL && strcmp(modname, dcp->modname) == 0)
break;
}

return (dcp);
}

int
db_ctf_register(linker_file_t mod)
{
struct db_ctf *dcp;
char *modname = mod->filename;

mtx_lock(&db_ctf_mtx);
if (db_ctf_lookup(modname) != NULL) {
mtx_unlock(&db_ctf_mtx);
printf("%s: ddb CTF data for module %s already loaded!\n",
__func__, modname);

return (EINVAL);
}
mtx_unlock(&db_ctf_mtx);

dcp = malloc(sizeof(struct db_ctf), M_DBCTF, M_WAITOK);
if (linker_ctf_get(mod, &dcp->lc) != 0) {
free(dcp, M_DBCTF);
return (EINVAL);
}
dcp->modname = strdup(modname, M_DBCTF);

mtx_lock(&db_ctf_mtx);
LIST_INSERT_HEAD(&ctf_table, dcp, link);
mtx_unlock(&db_ctf_mtx);

return (0);
}

int
db_ctf_unregister(linker_file_t mod)
{
struct db_ctf *dcp;
char *modname = mod->filename;

mtx_lock(&db_ctf_mtx);
dcp = db_ctf_lookup(modname);
if (dcp == NULL) {
mtx_unlock(&db_ctf_mtx);
printf("%s: ddb CTF data for module %s already loaded!\n",
__func__, modname);

return (EINVAL);
}
mtx_unlock(&db_ctf_mtx);

mtx_lock(&db_ctf_mtx);
LIST_REMOVE(dcp, link);
mtx_unlock(&db_ctf_mtx);

free(dcp->modname, M_TEMP);
free(dcp, M_DBCTF);

return (0);
}

static const ctf_header_t *
db_ctf_fetch_cth(linker_ctf_t *lc)
{
Expand Down Expand Up @@ -181,7 +96,7 @@ sym_to_objtoff(linker_ctf_t *lc, const Elf_Sym *sym, const Elf_Sym *symtab,
struct ctf_type_v3 *
db_ctf_typeid_to_type(db_ctf_sym_data_t sd, uint32_t typeid)
{
const ctf_header_t *hp = db_ctf_fetch_cth(sd->lc);
const ctf_header_t *hp = db_ctf_fetch_cth(&sd->lc);
const uint8_t *ctfstart = (const uint8_t *)hp + sizeof(ctf_header_t);

uint32_t typeoff = hp->cth_typeoff;
Expand Down Expand Up @@ -260,7 +175,7 @@ db_ctf_typeid_to_type(db_ctf_sym_data_t sd, uint32_t typeid)
const char *
db_ctf_stroff_to_str(db_ctf_sym_data_t sd, uint32_t off)
{
const ctf_header_t *hp = db_ctf_fetch_cth(sd->lc);
const ctf_header_t *hp = db_ctf_fetch_cth(&sd->lc);
uint32_t stroff = hp->cth_stroff + off;

if (stroff >= (hp->cth_stroff + hp->cth_strlen)) {
Expand All @@ -285,18 +200,18 @@ db_ctf_sym_to_type(db_ctf_sym_data_t sd)
return (NULL);
}

symtab = sd->lc->symtab;
symtab_end = symtab + sd->lc->nsym;
symtab = sd->lc.symtab;
symtab_end = symtab + sd->lc.nsym;

objtoff = sym_to_objtoff(sd->lc, sd->sym, symtab, symtab_end);
objtoff = sym_to_objtoff(&sd->lc, sd->sym, symtab, symtab_end);
/* Sanity check - should not happen */
if (objtoff == DB_CTF_OBJTOFF_INVALID) {
db_printf("Could not find CTF object offset.");
db_printf("Could not find CTF object offset.\n");
return (NULL);
}

typeid = *(
const uint32_t *)(sd->lc->ctftab + sizeof(ctf_header_t) + objtoff);
const uint32_t *)(sd->lc.ctftab + sizeof(ctf_header_t) + objtoff);

return db_ctf_typeid_to_type(sd, typeid);
}
Expand All @@ -305,72 +220,20 @@ int
db_ctf_find_symbol(db_expr_t addr, db_ctf_sym_data_t sd)
{
db_expr_t off;
struct db_ctf *dcp;
int error;

sd->sym = __DECONST(Elf_Sym *,
db_search_symbol(addr, DB_STGY_ANY, &off));
if (sd->sym == NULL) {
return (ENOENT);
}

dcp = db_ctf_lookup(linker_kernel_file->filename);
if (dcp == NULL) {
return (ENOENT);
/* XXX-MJ what if the address belongs to a KLD? */
error = linker_ctf_get(linker_kernel_file, &sd->lc);
if (error != 0) {
db_printf("failed to look up CTF info\n");
return (error);
}

sd->lc = &dcp->lc;

return (0);
}

void
db_ctf_init_kctf(vm_offset_t ksymtab, vm_offset_t kstrtab,
vm_offset_t ksymtab_size)
{
const ctf_header_t *hp;
uint8_t *ctf_start;
size_t size;
void *mod;

mod = preload_search_by_type("ddb_kctf");
if (mod == NULL) {
return;
}

ctf_start = preload_fetch_addr(mod);
size = preload_fetch_size(mod);
bzero(&kctf.lc, sizeof(kctf.lc));
hp = (const ctf_header_t *)ctf_start;

/* 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;
}

/* We only deal with uncompressed data */
if (hp->cth_flags & CTF_F_COMPRESS) {
printf("%s: kernel CTF data is compressed\n", __func__);
return;
}

kctf.lc.ctftab = ctf_start;
kctf.lc.ctfcnt = size;
kctf.lc.symtab = (const Elf_Sym *)ksymtab;
kctf.lc.nsym = ksymtab_size / sizeof(Elf_Sym);
kctf.lc.strtab = (const char *)kstrtab;
kctf.modname = "kernel";

LIST_INSERT_HEAD(&ctf_table, &kctf, link);
}

linker_ctf_t *
db_ctf_fetch_kctf(void)
{
return (kctf.modname != NULL ? &kctf.lc : NULL);
}
8 changes: 3 additions & 5 deletions sys/ddb/db_ctf.h
Expand Up @@ -32,28 +32,26 @@
#include <sys/ctf.h>
#include <sys/linker.h>

#include <ddb/db_sym.h>
#include <ddb/ddb.h>
#include <ddb/db_sym.h>

#define DB_CTF_OBJTOFF_INVALID 0xffffffff

int db_ctf_register(linker_file_t module);
int db_ctf_unregister(linker_file_t module);

struct db_ctf_sym_data {
linker_ctf_t *lc;
linker_ctf_t lc;
Elf_Sym *sym;
};

struct db_ctf_sym_data;
typedef struct db_ctf_sym_data *db_ctf_sym_data_t;

struct ctf_type_v3 *db_ctf_sym_to_type(db_ctf_sym_data_t sd);
struct ctf_type_v3 *db_ctf_typeid_to_type(db_ctf_sym_data_t sd,
uint32_t typeid);
const char *db_ctf_stroff_to_str(db_ctf_sym_data_t sd, uint32_t off);
int db_ctf_find_symbol(db_expr_t addr, db_ctf_sym_data_t sd);
void db_ctf_init_kctf(vm_offset_t ksymtab, vm_offset_t kstrtab,
vm_offset_t ksymtab_size);
linker_ctf_t *db_ctf_fetch_kctf(void);

#endif /* !_DDB_DB_CTF_H_ */
2 changes: 0 additions & 2 deletions sys/ddb/db_main.c
Expand Up @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");

#include <ddb/ddb.h>
#include <ddb/db_command.h>
#include <ddb/db_ctf.h>
#include <ddb/db_sym.h>

struct db_private {
Expand Down Expand Up @@ -229,7 +228,6 @@ db_init(void)
ksymtab_private.relbase = ksymtab_relbase;
db_add_symbol_table((char *)ksymtab,
(char *)(ksymtab + ksymtab_size), "elf", (char *)&ksymtab_private);
db_ctf_init_kctf(ksymtab, kstrtab, ksymtab_size);
}
db_add_symbol_table(NULL, NULL, "kld", NULL);
return (1); /* We're the default debugger. */
Expand Down
4 changes: 4 additions & 0 deletions sys/kern/kern_ctf.c
Expand Up @@ -29,6 +29,7 @@
*/

#include <sys/ctf.h>
#include <sys/kdb.h>

/*
* Note this file is included by both link_elf.c and link_elf_obj.c.
Expand Down Expand Up @@ -88,6 +89,9 @@ link_elf_ctf_get(linker_file_t lf, linker_ctf_t *lc)
return (0);
}

if (panicstr != NULL || kdb_active)
return (ENXIO);

/*
* We need to try reading the CTF data. Flag no CTF data present
* by default and if we actually succeed in reading it, we'll
Expand Down
40 changes: 39 additions & 1 deletion sys/kern/kern_linker.c
Expand Up @@ -330,6 +330,27 @@ linker_file_register_sysctls(linker_file_t lf, bool enable)
sx_xlock(&kld_sx);
}

/*
* Invoke the LINKER_CTF_GET implementation for this file. Existing
* implementations will load CTF info from the filesystem upon the first call
* and cache it in the kernel thereafter.
*/
static void
linker_ctf_load_file(linker_file_t file)
{
linker_ctf_t lc;
int error;

printf("%s:%d %s\n", __func__, __LINE__, file->filename);
error = linker_ctf_get(file, &lc);
if (error == 0)
return;
if (bootverbose) {
printf("failed to load CTF for %s: %d\n",
file->filename, error);
}
}

static void
linker_file_enable_sysctls(linker_file_t lf)
{
Expand Down Expand Up @@ -486,6 +507,11 @@ linker_load_file(const char *filename, linker_file_t *result)
return (ENOEXEC);
}
linker_file_enable_sysctls(lf);

/*
* Ask the linker to load CTF data for this file.
*/
linker_ctf_load_file(lf);
EVENTHANDLER_INVOKE(kld_load, lf);
*result = lf;
return (0);
Expand Down Expand Up @@ -1777,9 +1803,21 @@ linker_preload(void *arg)
sx_xunlock(&kld_sx);
/* woohoo! we made it! */
}

SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, NULL);

static void
linker_mountroot(void *arg __unused)
{
linker_file_t lf;

sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link) {
linker_ctf_load_file(lf);
}
sx_xunlock(&kld_sx);
}
EVENTHANDLER_DEFINE(mountroot, linker_mountroot, NULL, 0);

/*
* Handle preload files that failed to load any modules.
*/
Expand Down
9 changes: 0 additions & 9 deletions sys/kern/link_elf.c
Expand Up @@ -504,15 +504,6 @@ link_elf_init(void* arg)
(void)link_elf_link_common_finish(linker_kernel_file);
linker_kernel_file->flags |= LINKER_FILE_LINKED;

#ifdef DDB_CTF
/* Check if ddb already loaded kernel CTF data. */
linker_ctf_t *lc = db_ctf_fetch_kctf();
if (lc != NULL) {
ef->ctftab = __DECONST(uint8_t *, lc->ctftab);
ef->ctfcnt = lc->ctfcnt;
}
#endif

TAILQ_INIT(&set_pcpu_list);
#ifdef VIMAGE
TAILQ_INIT(&set_vnet_list);
Expand Down

0 comments on commit 3985ddd

Please sign in to comment.