Changeset View
Changeset View
Standalone View
Standalone View
head/devel/gdb/files/kgdb/fbsd-kld.c
Show First 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | |||||
* Try to find the path for a kld by looking in the kernel's directory and | * Try to find the path for a kld by looking in the kernel's directory and | ||||
* in the various paths in the module path. | * in the various paths in the module path. | ||||
*/ | */ | ||||
static int | static int | ||||
find_kld_path (const char *filename, char *path, size_t path_size) | find_kld_path (const char *filename, char *path, size_t path_size) | ||||
{ | { | ||||
struct kld_info *info; | struct kld_info *info; | ||||
struct cleanup *cleanup; | struct cleanup *cleanup; | ||||
char *module_path; | gdb::unique_xmalloc_ptr<char> module_path; | ||||
char *module_dir, *cp; | char *module_dir, *cp; | ||||
int error; | int error; | ||||
info = get_kld_info(); | info = get_kld_info(); | ||||
if (exec_bfd) { | if (exec_bfd) { | ||||
std::string kernel_dir = ldirname(bfd_get_filename(exec_bfd)); | std::string kernel_dir = ldirname(bfd_get_filename(exec_bfd)); | ||||
if (!kernel_dir.empty()) { | if (!kernel_dir.empty()) { | ||||
snprintf(path, path_size, "%s/%s", kernel_dir.c_str(), | snprintf(path, path_size, "%s/%s", kernel_dir.c_str(), | ||||
filename); | filename); | ||||
if (check_kld_path(path, path_size)) | if (check_kld_path(path, path_size)) | ||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
if (info->module_path_addr != 0) { | if (info->module_path_addr != 0) { | ||||
target_read_string(info->module_path_addr, &module_path, | target_read_string(info->module_path_addr, &module_path, | ||||
PATH_MAX, &error); | PATH_MAX, &error); | ||||
if (error == 0) { | if (error == 0) { | ||||
cleanup = make_cleanup(xfree, module_path); | cp = module_path.get(); | ||||
cp = module_path; | |||||
while ((module_dir = strsep(&cp, ";")) != NULL) { | while ((module_dir = strsep(&cp, ";")) != NULL) { | ||||
snprintf(path, path_size, "%s/%s", module_dir, | snprintf(path, path_size, "%s/%s", module_dir, | ||||
filename); | filename); | ||||
if (check_kld_path(path, path_size)) { | if (check_kld_path(path, path_size)) | ||||
do_cleanups(cleanup); | |||||
return (1); | return (1); | ||||
} | } | ||||
} | } | ||||
do_cleanups(cleanup); | |||||
} | } | ||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Read a kernel pointer given a KVA in 'address'. | * Read a kernel pointer given a KVA in 'address'. | ||||
*/ | */ | ||||
static CORE_ADDR | static CORE_ADDR | ||||
read_pointer (CORE_ADDR address) | read_pointer (CORE_ADDR address) | ||||
Show All 14 Lines | |||||
/* | /* | ||||
* Try to find this kld in the kernel linker's list of linker files. | * Try to find this kld in the kernel linker's list of linker files. | ||||
*/ | */ | ||||
static int | static int | ||||
find_kld_address (const char *arg, CORE_ADDR *address) | find_kld_address (const char *arg, CORE_ADDR *address) | ||||
{ | { | ||||
struct kld_info *info; | struct kld_info *info; | ||||
CORE_ADDR kld; | CORE_ADDR kld; | ||||
char *kld_filename; | gdb::unique_xmalloc_ptr<char> kld_filename; | ||||
const char *filename; | const char *filename; | ||||
int error; | int error; | ||||
info = get_kld_info(); | info = get_kld_info(); | ||||
if (info->linker_files_addr == 0 || info->off_address == 0 || | if (info->linker_files_addr == 0 || info->off_address == 0 || | ||||
info->off_filename == 0 || info->off_next == 0) | info->off_filename == 0 || info->off_next == 0) | ||||
return (0); | return (0); | ||||
filename = lbasename(arg); | filename = lbasename(arg); | ||||
for (kld = read_pointer(info->linker_files_addr); kld != 0; | for (kld = read_pointer(info->linker_files_addr); kld != 0; | ||||
kld = read_pointer(kld + info->off_next)) { | kld = read_pointer(kld + info->off_next)) { | ||||
/* Try to read this linker file's filename. */ | /* Try to read this linker file's filename. */ | ||||
target_read_string(read_pointer(kld + info->off_filename), | target_read_string(read_pointer(kld + info->off_filename), | ||||
&kld_filename, PATH_MAX, &error); | &kld_filename, PATH_MAX, &error); | ||||
if (error) | if (error) | ||||
continue; | continue; | ||||
/* Compare this kld's filename against our passed in name. */ | /* Compare this kld's filename against our passed in name. */ | ||||
if (strcmp(kld_filename, filename) != 0) { | if (strcmp(kld_filename.get(), filename) != 0) | ||||
xfree(kld_filename); | |||||
continue; | continue; | ||||
} | |||||
xfree(kld_filename); | |||||
/* | /* | ||||
* We found a match, use its address as the base | * We found a match, use its address as the base | ||||
* address if we can read it. | * address if we can read it. | ||||
*/ | */ | ||||
*address = read_pointer(kld + info->off_address); | *address = read_pointer(kld + info->off_address); | ||||
if (*address == 0) | if (*address == 0) | ||||
return (0); | return (0); | ||||
Show All 19 Lines | adjust_section_address (struct target_section *sec, CORE_ADDR *curr_base) | ||||
sec->addr = *curr_base; | sec->addr = *curr_base; | ||||
sec->endaddr = sec->addr + bfd_section_size(abfd, asect); | sec->endaddr = sec->addr + bfd_section_size(abfd, asect); | ||||
*curr_base = sec->endaddr; | *curr_base = sec->endaddr; | ||||
} | } | ||||
static void | static void | ||||
load_kld (char *path, CORE_ADDR base_addr, int from_tty) | load_kld (char *path, CORE_ADDR base_addr, int from_tty) | ||||
{ | { | ||||
struct section_addr_info *sap; | |||||
struct target_section *sections = NULL, *sections_end = NULL, *s; | struct target_section *sections = NULL, *sections_end = NULL, *s; | ||||
struct cleanup *cleanup; | struct cleanup *cleanup; | ||||
gdb_bfd_ref_ptr bfd; | gdb_bfd_ref_ptr bfd; | ||||
CORE_ADDR curr_addr; | CORE_ADDR curr_addr; | ||||
symfile_add_flags add_flags; | symfile_add_flags add_flags; | ||||
int i; | int i; | ||||
/* Open the kld. */ | /* Open the kld. */ | ||||
Show All 13 Lines | load_kld (char *path, CORE_ADDR base_addr, int from_tty) | ||||
if (build_section_table (bfd.get(), §ions, §ions_end)) | if (build_section_table (bfd.get(), §ions, §ions_end)) | ||||
error("\"%s\": can't find file sections", path); | error("\"%s\": can't find file sections", path); | ||||
cleanup = make_cleanup(xfree, sections); | cleanup = make_cleanup(xfree, sections); | ||||
curr_addr = base_addr; | curr_addr = base_addr; | ||||
for (s = sections; s < sections_end; s++) | for (s = sections; s < sections_end; s++) | ||||
adjust_section_address(s, &curr_addr); | adjust_section_address(s, &curr_addr); | ||||
/* Build a section addr info to pass to symbol_file_add(). */ | /* Build a section addr info to pass to symbol_file_add(). */ | ||||
sap = build_section_addr_info_from_section_table (sections, | section_addr_info sap | ||||
= build_section_addr_info_from_section_table (sections, | |||||
sections_end); | sections_end); | ||||
make_cleanup((make_cleanup_ftype *)free_section_addr_info, sap); | |||||
printf_unfiltered("add symbol table from file \"%s\" at\n", path); | printf_unfiltered("add symbol table from file \"%s\" at\n", path); | ||||
for (i = 0; i < sap->num_sections; i++) | for (i = 0; i < sap.size(); i++) | ||||
printf_unfiltered("\t%s_addr = %s\n", sap->other[i].name, | printf_unfiltered("\t%s_addr = %s\n", sap[i].name.c_str(), | ||||
paddress(target_gdbarch(), sap->other[i].addr)); | paddress(target_gdbarch(), sap[i].addr)); | ||||
if (from_tty && (!query("%s", ""))) | if (from_tty && (!query("%s", ""))) | ||||
error("Not confirmed."); | error("Not confirmed."); | ||||
add_flags = 0; | add_flags = 0; | ||||
if (from_tty) | if (from_tty) | ||||
add_flags |= SYMFILE_VERBOSE; | add_flags |= SYMFILE_VERBOSE; | ||||
symbol_file_add_from_bfd(bfd.get(), path, add_flags, sap, | symbol_file_add_from_bfd(bfd.get(), path, add_flags, &sap, | ||||
OBJF_USERLOADED, NULL); | OBJF_USERLOADED, NULL); | ||||
do_cleanups(cleanup); | do_cleanups(cleanup); | ||||
} | } | ||||
static void | static void | ||||
kgdb_add_kld_cmd (const char *arg, int from_tty) | kgdb_add_kld_cmd (const char *arg, int from_tty) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static struct so_list * | static struct so_list * | ||||
kld_current_sos (void) | kld_current_sos (void) | ||||
{ | { | ||||
struct so_list *head, **prev, *newobj; | struct so_list *head, **prev, *newobj; | ||||
struct kld_info *info; | struct kld_info *info; | ||||
CORE_ADDR kld, kernel; | CORE_ADDR kld, kernel; | ||||
char *path; | gdb::unique_xmalloc_ptr<char> path; | ||||
int error; | int error; | ||||
info = get_kld_info(); | info = get_kld_info(); | ||||
if (info->linker_files_addr == 0 || info->kernel_file_addr == 0 || | if (info->linker_files_addr == 0 || info->kernel_file_addr == 0 || | ||||
info->off_address == 0 || info->off_filename == 0 || | info->off_address == 0 || info->off_filename == 0 || | ||||
info->off_next == 0) | info->off_next == 0) | ||||
return (NULL); | return (NULL); | ||||
Show All 22 Lines | for (kld = read_pointer(info->linker_files_addr); kld != 0; | ||||
target_read_string(read_pointer(kld + info->off_filename), | target_read_string(read_pointer(kld + info->off_filename), | ||||
&path, sizeof(newobj->so_original_name), &error); | &path, sizeof(newobj->so_original_name), &error); | ||||
if (error != 0) { | if (error != 0) { | ||||
warning("kld_current_sos: Can't read filename: %s\n", | warning("kld_current_sos: Can't read filename: %s\n", | ||||
safe_strerror(error)); | safe_strerror(error)); | ||||
free_so(newobj); | free_so(newobj); | ||||
continue; | continue; | ||||
} | } | ||||
strlcpy(newobj->so_original_name, path, | strlcpy(newobj->so_original_name, path.get(), | ||||
sizeof(newobj->so_original_name)); | sizeof(newobj->so_original_name)); | ||||
xfree(path); | |||||
/* | /* | ||||
* Try to read the pathname (if it exists) and store | * Try to read the pathname (if it exists) and store | ||||
* it in so_name. | * it in so_name. | ||||
*/ | */ | ||||
if (find_kld_path(newobj->so_original_name, newobj->so_name, | if (find_kld_path(newobj->so_original_name, newobj->so_name, | ||||
sizeof(newobj->so_name))) { | sizeof(newobj->so_name))) { | ||||
/* we found the kld */; | /* we found the kld */; | ||||
} else if (info->off_pathname != 0) { | } else if (info->off_pathname != 0) { | ||||
target_read_string(read_pointer(kld + | target_read_string(read_pointer(kld + | ||||
info->off_pathname), | info->off_pathname), | ||||
&path, sizeof(newobj->so_name), &error); | &path, sizeof(newobj->so_name), &error); | ||||
if (error != 0) { | if (error != 0) { | ||||
warning( | warning( | ||||
"kld_current_sos: Can't read pathname for \"%s\": %s\n", | "kld_current_sos: Can't read pathname for \"%s\": %s\n", | ||||
newobj->so_original_name, | newobj->so_original_name, | ||||
safe_strerror(error)); | safe_strerror(error)); | ||||
strlcpy(newobj->so_name, newobj->so_original_name, | strlcpy(newobj->so_name, newobj->so_original_name, | ||||
sizeof(newobj->so_name)); | sizeof(newobj->so_name)); | ||||
} else { | } else { | ||||
strlcpy(newobj->so_name, path, | strlcpy(newobj->so_name, path.get(), | ||||
sizeof(newobj->so_name)); | sizeof(newobj->so_name)); | ||||
xfree(path); | |||||
} | } | ||||
} else | } else | ||||
strlcpy(newobj->so_name, newobj->so_original_name, | strlcpy(newobj->so_name, newobj->so_original_name, | ||||
sizeof(newobj->so_name)); | sizeof(newobj->so_name)); | ||||
/* Read this kld's base address. */ | /* Read this kld's base address. */ | ||||
li->base_address = read_pointer(kld + info->off_address); | li->base_address = read_pointer(kld + info->off_address); | ||||
if (li->base_address == 0) { | if (li->base_address == 0) { | ||||
Show All 23 Lines | |||||
kld_in_dynsym_resolve_code (CORE_ADDR pc) | kld_in_dynsym_resolve_code (CORE_ADDR pc) | ||||
{ | { | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
kld_find_and_open_solib (const char *solib, unsigned o_flags, | kld_find_and_open_solib (const char *solib, unsigned o_flags, | ||||
char **temp_pathname) | gdb::unique_xmalloc_ptr<char> *temp_pathname) | ||||
{ | { | ||||
char path[PATH_MAX]; | char path[PATH_MAX]; | ||||
int fd; | int fd; | ||||
*temp_pathname = NULL; | temp_pathname->reset (NULL); | ||||
if (!find_kld_path(solib, path, sizeof(path))) { | if (!find_kld_path(solib, path, sizeof(path))) { | ||||
errno = ENOENT; | errno = ENOENT; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
fd = open(path, o_flags, 0); | fd = open(path, o_flags, 0); | ||||
if (fd >= 0) | if (fd >= 0) | ||||
*temp_pathname = xstrdup(path); | temp_pathname->reset(xstrdup(path)); | ||||
return (fd); | return (fd); | ||||
} | } | ||||
void | void | ||||
_initialize_kld_target(void) | _initialize_kld_target(void) | ||||
{ | { | ||||
struct cmd_list_element *c; | struct cmd_list_element *c; | ||||
Show All 19 Lines |