mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-16 07:11:05 +01:00
Add GDB support. The method and some of the code came from NetBSD's elf
runtime linker.
This commit is contained in:
parent
bbba152305
commit
2001f720ce
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=35529
@ -1,11 +1,11 @@
|
||||
#
|
||||
# $Id: Makefile,v 1.5 1998/03/05 21:05:47 jdp Exp $
|
||||
# $Id: Makefile,v 1.1.1.1 1998/03/07 19:24:35 jdp Exp $
|
||||
#
|
||||
|
||||
PROG= ld-elf.so.1
|
||||
SRCS= rtld_start.S rtld.c map_object.c malloc.c xmalloc.c debug.c
|
||||
NOMAN= true
|
||||
CFLAGS+= -elf -fpic
|
||||
CFLAGS+= -elf -fpic -DFREEBSD_ELF
|
||||
CFLAGS+= -Wall
|
||||
LDFLAGS+= -elf -nostdlib -Wl,-Bshareable,-Bsymbolic
|
||||
LDADD+= -lc_pic
|
||||
|
@ -22,7 +22,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: rtld.c,v 1.18 1998/03/06 22:14:54 jdp Exp $
|
||||
* $Id: rtld.c,v 1.1.1.1 1998/03/07 19:24:35 jdp Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -90,6 +90,9 @@ static char *search_library_path(const char *, const char *);
|
||||
static const Elf32_Sym *symlook_obj(const char *, unsigned long,
|
||||
const Obj_Entry *, bool);
|
||||
static void unref_object_dag(Obj_Entry *);
|
||||
void r_debug_state(void);
|
||||
static void linkmap_add(Obj_Entry *);
|
||||
static void linkmap_delete(Obj_Entry *);
|
||||
|
||||
void xprintf(const char *, ...);
|
||||
|
||||
@ -116,6 +119,7 @@ extern void _rtld_bind_start(void);
|
||||
* Data declarations.
|
||||
*/
|
||||
static char *error_message; /* Message for dlerror(), or NULL */
|
||||
struct r_debug r_debug; /* for GDB; */
|
||||
static bool trust; /* False for setuid and setgid programs */
|
||||
static char *ld_bind_now; /* Environment variable for immediate binding */
|
||||
static char *ld_debug; /* Environment variable for debugging */
|
||||
@ -125,6 +129,8 @@ static Obj_Entry **obj_tail; /* Link field of last object in list */
|
||||
static Obj_Entry *obj_main; /* The main program shared object */
|
||||
static Obj_Entry obj_rtld; /* The dynamic linker shared object */
|
||||
|
||||
#define GDB_STATE(s) r_debug.r_state = s; r_debug_state();
|
||||
|
||||
/*
|
||||
* These are the functions the dynamic linker exports to application
|
||||
* programs. They are the only symbols the dynamic linker is willing
|
||||
@ -248,6 +254,9 @@ _rtld(Elf32_Word *sp, func_ptr_type *exit_proc)
|
||||
obj_main->mainprog = true;
|
||||
digest_dynamic(obj_main);
|
||||
|
||||
linkmap_add(obj_main);
|
||||
linkmap_add(&obj_rtld);
|
||||
|
||||
/* Link the main program into the list of objects. */
|
||||
*obj_tail = obj_main;
|
||||
obj_tail = &obj_main->next;
|
||||
@ -271,6 +280,8 @@ _rtld(Elf32_Word *sp, func_ptr_type *exit_proc)
|
||||
|
||||
dbg("transferring control to program entry point = %p", obj_main->entry);
|
||||
|
||||
r_debug_state(); /* say hello to gdb! */
|
||||
|
||||
/* Return the exit procedure and the program entry point. */
|
||||
*exit_proc = (func_ptr_type) rtld_exit;
|
||||
return (func_ptr_type) obj_main->entry;
|
||||
@ -479,6 +490,8 @@ digest_dynamic(Obj_Entry *obj)
|
||||
|
||||
case DT_DEBUG:
|
||||
/* XXX - not implemented yet */
|
||||
dbg("Filling in DT_DEBUG entry");
|
||||
((Elf32_Dyn*)dynp)->d_un.d_ptr = (Elf32_Addr) &r_debug;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -783,6 +796,9 @@ init_rtld(caddr_t mapbase)
|
||||
/* Make the object list empty again. */
|
||||
obj_list = NULL;
|
||||
obj_tail = &obj_list;
|
||||
|
||||
r_debug.r_brk = r_debug_state;
|
||||
r_debug.r_state = RT_CONSISTENT;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -863,6 +879,7 @@ load_object(char *path)
|
||||
|
||||
*obj_tail = obj;
|
||||
obj_tail = &obj->next;
|
||||
linkmap_add(obj); /* for GDB */
|
||||
|
||||
dbg(" %p .. %p: %s", obj->mapbase,
|
||||
obj->mapbase + obj->mapsize - 1, obj->path);
|
||||
@ -1056,8 +1073,10 @@ relocate_objects(Obj_Entry *first, bool bind_now)
|
||||
obj->version = RTLD_VERSION;
|
||||
|
||||
/* Set the special GOT entries. */
|
||||
obj->got[1] = (Elf32_Addr) obj;
|
||||
obj->got[2] = (Elf32_Addr) &_rtld_bind_start;
|
||||
if (obj->got) {
|
||||
obj->got[1] = (Elf32_Addr) obj;
|
||||
obj->got[2] = (Elf32_Addr) &_rtld_bind_start;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1118,6 +1137,8 @@ dlclose(void *handle)
|
||||
if (root == NULL)
|
||||
return -1;
|
||||
|
||||
GDB_STATE(RT_DELETE);
|
||||
|
||||
root->dl_refcount--;
|
||||
unref_object_dag(root);
|
||||
if (root->refcount == 0) { /* We are finished with some objects. */
|
||||
@ -1140,6 +1161,7 @@ dlclose(void *handle)
|
||||
obj->needed = needed->next;
|
||||
free(needed);
|
||||
}
|
||||
linkmap_delete(obj);
|
||||
*linkp = obj->next;
|
||||
free(obj);
|
||||
} else
|
||||
@ -1147,6 +1169,8 @@ dlclose(void *handle)
|
||||
}
|
||||
}
|
||||
|
||||
GDB_STATE(RT_CONSISTENT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1162,30 +1186,37 @@ void *
|
||||
dlopen(const char *name, int mode)
|
||||
{
|
||||
Obj_Entry **old_obj_tail = obj_tail;
|
||||
Obj_Entry *obj;
|
||||
Obj_Entry *obj = NULL;
|
||||
|
||||
GDB_STATE(RT_ADD);
|
||||
|
||||
if (name == NULL)
|
||||
obj = obj_main;
|
||||
else {
|
||||
char *path = find_library(name, NULL);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
obj = load_object(path);
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
if (path != NULL)
|
||||
obj = load_object(path);
|
||||
}
|
||||
|
||||
obj->dl_refcount++;
|
||||
if (*old_obj_tail != NULL) { /* We loaded something new. */
|
||||
assert(*old_obj_tail == obj);
|
||||
if (obj) {
|
||||
obj->dl_refcount++;
|
||||
if (*old_obj_tail != NULL) { /* We loaded something new. */
|
||||
assert(*old_obj_tail == obj);
|
||||
|
||||
/* XXX - Clean up properly after an error. */
|
||||
if (load_needed_objects(obj) == -1)
|
||||
return NULL;
|
||||
if (relocate_objects(obj, mode == RTLD_NOW) == -1)
|
||||
return NULL;
|
||||
call_init_functions(obj);
|
||||
/* XXX - Clean up properly after an error. */
|
||||
if (load_needed_objects(obj) == -1) {
|
||||
obj->dl_refcount--;
|
||||
obj = NULL;
|
||||
} else if (relocate_objects(obj, mode == RTLD_NOW) == -1) {
|
||||
obj->dl_refcount--;
|
||||
obj = NULL;
|
||||
} else
|
||||
call_init_functions(obj);
|
||||
}
|
||||
}
|
||||
|
||||
GDB_STATE(RT_CONSISTENT);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -1227,6 +1258,7 @@ dlsym(void *handle, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Search the symbol table of a single shared object for a symbol of
|
||||
* the given name. Returns a pointer to the symbol, or NULL if no
|
||||
@ -1289,3 +1321,48 @@ xprintf(const char *fmt, ...)
|
||||
(void)write(1, buf, strlen(buf));
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
r_debug_state(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
linkmap_add(Obj_Entry *obj)
|
||||
{
|
||||
struct link_map *l = &obj->linkmap;
|
||||
struct link_map *prev;
|
||||
|
||||
obj->linkmap.l_name = obj->path;
|
||||
obj->linkmap.l_addr = obj->mapbase;
|
||||
obj->linkmap.l_ld = obj->dynamic;
|
||||
#ifdef __mips__
|
||||
/* GDB needs load offset on MIPS to use the symbols */
|
||||
obj->linkmap.l_offs = obj->relocbase;
|
||||
#endif
|
||||
|
||||
if (r_debug.r_map == NULL) {
|
||||
r_debug.r_map = l;
|
||||
return;
|
||||
}
|
||||
|
||||
for (prev = r_debug.r_map; prev->l_next != NULL; prev = prev->l_next)
|
||||
;
|
||||
l->l_prev = prev;
|
||||
prev->l_next = l;
|
||||
l->l_next = NULL;
|
||||
}
|
||||
|
||||
void linkmap_delete(Obj_Entry *obj)
|
||||
{
|
||||
struct link_map *l = &obj->linkmap;
|
||||
|
||||
if (l->l_prev == NULL) {
|
||||
if ((r_debug.r_map = l->l_next) != NULL)
|
||||
l->l_next->l_prev = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((l->l_prev->l_next = l->l_next) != NULL)
|
||||
l->l_next->l_prev = l->l_prev;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: rtld.h,v 1.3 1998/03/06 14:00:09 jdp Exp $
|
||||
* $Id: rtld.h,v 1.1.1.1 1998/03/07 19:24:35 jdp Exp $
|
||||
*/
|
||||
|
||||
#ifndef RTLD_H /* { */
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <link.h>
|
||||
#include <elf.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@ -108,6 +109,8 @@ typedef struct Struct_Obj_Entry {
|
||||
bool rtld; /* True if this is the dynamic linker */
|
||||
bool textrel; /* True if there are relocations to text seg */
|
||||
bool symbolic; /* True if generated with "-Bsymbolic" */
|
||||
|
||||
struct link_map linkmap; /* for GDB */
|
||||
} Obj_Entry;
|
||||
|
||||
#define RTLD_MAGIC 0xd550b87a
|
||||
|
Loading…
Reference in New Issue
Block a user