Reduce code duplication by moving the common actions in

link_elf_init(), link_elf_link_preload_finish() and
link_elf_load_file() to link_elf_link_common_finish().
Since link_elf_init() did initializations as a side-effect
of doing the common actions, keep the initialization in
that function. Consequently, link_elf_add_gdb() is now also
called to insert the very first link_map() (ie the kernel).
This commit is contained in:
Marcel Moolenaar 2002-10-19 18:59:33 +00:00
parent 1720979bc5
commit c143d6c24a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=105468
2 changed files with 110 additions and 114 deletions

View File

@ -96,6 +96,7 @@ typedef struct elf_file {
#endif
} *elf_file_t;
static int link_elf_link_common_finish(linker_file_t);
static int link_elf_link_preload(linker_class_t cls,
const char*, linker_file_t*);
static int link_elf_link_preload_finish(linker_file_t);
@ -165,29 +166,33 @@ link_elf_add_gdb(struct link_map *l)
{
struct link_map *prev;
/*
* Scan to the end of the list.
*/
for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
;
l->l_next = NULL;
/* Link in the new entry. */
l->l_prev = prev;
l->l_next = prev->l_next;
prev->l_next = l;
if (r_debug.r_map == NULL) {
/* Add first. */
l->l_prev = NULL;
r_debug.r_map = l;
} else {
/* Append to list. */
for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
;
l->l_prev = prev;
prev->l_next = l;
}
}
static void
link_elf_delete_gdb(struct link_map *l)
{
if (l->l_prev == NULL) {
/* Remove first. */
if ((r_debug.r_map = l->l_next) != NULL)
l->l_next->l_prev = NULL;
return;
} else {
/* Remove any but first. */
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
}
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
}
#endif /* DDB */
@ -206,6 +211,32 @@ link_elf_error(const char *s)
printf("kldload: %s\n", s);
}
/*
* Actions performed after linking/loading both the preloaded kernel and any
* modules; whether preloaded or dynamicly loaded.
*/
static int
link_elf_link_common_finish(linker_file_t lf)
{
#ifdef DDB
elf_file_t ef = (elf_file_t)lf;
char *newfilename;
#endif
#ifdef DDB
GDB_STATE(RT_ADD);
ef->gdb.l_addr = lf->address;
newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, lf->filename);
ef->gdb.l_name = newfilename;
ef->gdb.l_ld = ef->dynamic;
link_elf_add_gdb(&ef->gdb);
GDB_STATE(RT_CONSISTENT);
#endif
return (0);
}
static void
link_elf_init(void* arg)
{
@ -213,9 +244,6 @@ link_elf_init(void* arg)
caddr_t modptr, baseptr, sizeptr;
elf_file_t ef;
char *modname;
#ifdef DDB
char *newfilename;
#endif
linker_add_class(&link_elf_class);
@ -229,7 +257,7 @@ link_elf_init(void* arg)
linker_kernel_file = linker_make_file(modname, &link_elf_class);
if (linker_kernel_file == NULL)
panic("link_elf_init: Can't create linker structures for kernel");
ef = (elf_file_t) linker_kernel_file;
ef->preloaded = 1;
ef->address = 0;
@ -255,20 +283,12 @@ link_elf_init(void* arg)
(void)link_elf_preload_parse_symbols(ef);
#ifdef DDB
ef->gdb.l_addr = linker_kernel_file->address;
newfilename = malloc(strlen(modname) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, modname);
ef->gdb.l_name = newfilename;
ef->gdb.l_ld = dp;
ef->gdb.l_prev = 0;
ef->gdb.l_next = 0;
r_debug.r_map = &ef->gdb;
r_debug.r_map = NULL;
r_debug.r_brk = r_debug_state;
r_debug.r_state = RT_CONSISTENT;
r_debug_state(NULL, NULL); /* say hello to gdb! */
#endif
(void)link_elf_link_common_finish(linker_kernel_file);
}
SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
@ -469,9 +489,6 @@ link_elf_link_preload_finish(linker_file_t lf)
{
elf_file_t ef;
int error;
#ifdef DDB
char *newfilename;
#endif
ef = (elf_file_t) lf;
#if 0 /* this will be more trouble than it's worth for now */
@ -489,22 +506,12 @@ link_elf_link_preload_finish(linker_file_t lf)
return error;
(void)link_elf_preload_parse_symbols(ef);
#ifdef DDB
GDB_STATE(RT_ADD);
ef->gdb.l_addr = lf->address;
newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, lf->filename);
ef->gdb.l_name = newfilename;
ef->gdb.l_ld = ef->dynamic;
link_elf_add_gdb(&ef->gdb);
GDB_STATE(RT_CONSISTENT);
#endif
return (0);
return (link_elf_link_common_finish(lf));
}
static int
link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* result)
link_elf_load_file(linker_class_t cls, const char* filename,
linker_file_t* result)
{
struct nameidata nd;
struct thread* td = curthread; /* XXX */
@ -531,9 +538,6 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
int symstrindex;
int symcnt;
int strcnt;
#ifdef DDB
char *newfilename;
#endif
GIANT_REQUIRED;
@ -799,16 +803,9 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
ef->ddbstrcnt = strcnt;
ef->ddbstrtab = ef->strbase;
#ifdef DDB
GDB_STATE(RT_ADD);
ef->gdb.l_addr = lf->address;
newfilename = malloc(strlen(filename) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, filename);
ef->gdb.l_name = (const char *)newfilename;
ef->gdb.l_ld = ef->dynamic;
link_elf_add_gdb(&ef->gdb);
GDB_STATE(RT_CONSISTENT);
#endif
error = link_elf_link_common_finish(lf);
if (error)
goto out;
nosyms:
@ -845,6 +842,7 @@ link_elf_unload_file(linker_file_t file)
link_elf_unload_preload(file);
return;
}
#ifdef SPARSE_MAPPING
if (ef->object) {
vm_map_remove(kernel_map, (vm_offset_t) ef->address,

View File

@ -96,6 +96,7 @@ typedef struct elf_file {
#endif
} *elf_file_t;
static int link_elf_link_common_finish(linker_file_t);
static int link_elf_link_preload(linker_class_t cls,
const char*, linker_file_t*);
static int link_elf_link_preload_finish(linker_file_t);
@ -165,29 +166,33 @@ link_elf_add_gdb(struct link_map *l)
{
struct link_map *prev;
/*
* Scan to the end of the list.
*/
for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
;
l->l_next = NULL;
/* Link in the new entry. */
l->l_prev = prev;
l->l_next = prev->l_next;
prev->l_next = l;
if (r_debug.r_map == NULL) {
/* Add first. */
l->l_prev = NULL;
r_debug.r_map = l;
} else {
/* Append to list. */
for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
;
l->l_prev = prev;
prev->l_next = l;
}
}
static void
link_elf_delete_gdb(struct link_map *l)
{
if (l->l_prev == NULL) {
/* Remove first. */
if ((r_debug.r_map = l->l_next) != NULL)
l->l_next->l_prev = NULL;
return;
} else {
/* Remove any but first. */
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
}
if ((l->l_prev->l_next = l->l_next) != NULL)
l->l_next->l_prev = l->l_prev;
}
#endif /* DDB */
@ -206,6 +211,32 @@ link_elf_error(const char *s)
printf("kldload: %s\n", s);
}
/*
* Actions performed after linking/loading both the preloaded kernel and any
* modules; whether preloaded or dynamicly loaded.
*/
static int
link_elf_link_common_finish(linker_file_t lf)
{
#ifdef DDB
elf_file_t ef = (elf_file_t)lf;
char *newfilename;
#endif
#ifdef DDB
GDB_STATE(RT_ADD);
ef->gdb.l_addr = lf->address;
newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, lf->filename);
ef->gdb.l_name = newfilename;
ef->gdb.l_ld = ef->dynamic;
link_elf_add_gdb(&ef->gdb);
GDB_STATE(RT_CONSISTENT);
#endif
return (0);
}
static void
link_elf_init(void* arg)
{
@ -213,9 +244,6 @@ link_elf_init(void* arg)
caddr_t modptr, baseptr, sizeptr;
elf_file_t ef;
char *modname;
#ifdef DDB
char *newfilename;
#endif
linker_add_class(&link_elf_class);
@ -229,7 +257,7 @@ link_elf_init(void* arg)
linker_kernel_file = linker_make_file(modname, &link_elf_class);
if (linker_kernel_file == NULL)
panic("link_elf_init: Can't create linker structures for kernel");
ef = (elf_file_t) linker_kernel_file;
ef->preloaded = 1;
ef->address = 0;
@ -255,20 +283,12 @@ link_elf_init(void* arg)
(void)link_elf_preload_parse_symbols(ef);
#ifdef DDB
ef->gdb.l_addr = linker_kernel_file->address;
newfilename = malloc(strlen(modname) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, modname);
ef->gdb.l_name = newfilename;
ef->gdb.l_ld = dp;
ef->gdb.l_prev = 0;
ef->gdb.l_next = 0;
r_debug.r_map = &ef->gdb;
r_debug.r_map = NULL;
r_debug.r_brk = r_debug_state;
r_debug.r_state = RT_CONSISTENT;
r_debug_state(NULL, NULL); /* say hello to gdb! */
#endif
(void)link_elf_link_common_finish(linker_kernel_file);
}
SYSINIT(link_elf, SI_SUB_KLD, SI_ORDER_SECOND, link_elf_init, 0);
@ -469,9 +489,6 @@ link_elf_link_preload_finish(linker_file_t lf)
{
elf_file_t ef;
int error;
#ifdef DDB
char *newfilename;
#endif
ef = (elf_file_t) lf;
#if 0 /* this will be more trouble than it's worth for now */
@ -489,22 +506,12 @@ link_elf_link_preload_finish(linker_file_t lf)
return error;
(void)link_elf_preload_parse_symbols(ef);
#ifdef DDB
GDB_STATE(RT_ADD);
ef->gdb.l_addr = lf->address;
newfilename = malloc(strlen(lf->filename) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, lf->filename);
ef->gdb.l_name = newfilename;
ef->gdb.l_ld = ef->dynamic;
link_elf_add_gdb(&ef->gdb);
GDB_STATE(RT_CONSISTENT);
#endif
return (0);
return (link_elf_link_common_finish(lf));
}
static int
link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* result)
link_elf_load_file(linker_class_t cls, const char* filename,
linker_file_t* result)
{
struct nameidata nd;
struct thread* td = curthread; /* XXX */
@ -531,9 +538,6 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
int symstrindex;
int symcnt;
int strcnt;
#ifdef DDB
char *newfilename;
#endif
GIANT_REQUIRED;
@ -799,16 +803,9 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
ef->ddbstrcnt = strcnt;
ef->ddbstrtab = ef->strbase;
#ifdef DDB
GDB_STATE(RT_ADD);
ef->gdb.l_addr = lf->address;
newfilename = malloc(strlen(filename) + 1, M_LINKER, M_WAITOK);
strcpy(newfilename, filename);
ef->gdb.l_name = (const char *)newfilename;
ef->gdb.l_ld = ef->dynamic;
link_elf_add_gdb(&ef->gdb);
GDB_STATE(RT_CONSISTENT);
#endif
error = link_elf_link_common_finish(lf);
if (error)
goto out;
nosyms:
@ -845,6 +842,7 @@ link_elf_unload_file(linker_file_t file)
link_elf_unload_preload(file);
return;
}
#ifdef SPARSE_MAPPING
if (ef->object) {
vm_map_remove(kernel_map, (vm_offset_t) ef->address,