preliminary hack for running linux-flash under native firefox
Simon 'corecode' Schubert
corecode at fs.ei.tum.de
Wed Oct 25 00:39:53 PDT 2006
hey,
i have a patch for rtld which enables wrapping of linux shared objects. i'd appreciate review and comments. if wanted, i can post the diffs to the linuxpluginwrapper so that people can try flash.
cheers
simon
--
Serve - BSD +++ RENT this banner advert +++ ASCII Ribbon /"\
Work - Mac +++ space for low â¬â¬â¬ NOW!1 +++ Campaign \ /
Party Enjoy Relax | http://dragonflybsd.org Against HTML \
Dude 2c 2 the max ! http://golden-apple.biz Mail + News / \
Index: Makefile
===================================================================
RCS file: /home/dcvs/src/libexec/rtld-elf/Makefile,v
retrieving revision 1.12
diff -u -r1.12 Makefile
--- Makefile 19 Nov 2005 22:00:20 -0000 1.12
+++ Makefile 25 Oct 2006 07:19:58 -0000
@@ -14,6 +14,8 @@
MLINKS= rtld.1 ld-elf.so.1.1
MLINKS+= rtld.1 ld-elf.so.2.1
+INCS+= rtld_wrap.h
+
.if exists(${.CURDIR}/${MACHINE_ARCH}/Makefile.inc)
.include "${.CURDIR}/${MACHINE_ARCH}/Makefile.inc"
.endif
Index: rtld.c
===================================================================
RCS file: /home/dcvs/src/libexec/rtld-elf/rtld.c,v
retrieving revision 1.24
diff -u -r1.24 rtld.c
--- rtld.c 16 Jul 2006 22:15:38 -0000 1.24
+++ rtld.c 22 Oct 2006 12:08:27 -0000
@@ -771,7 +771,8 @@
break;
default:
- dbg("Ignoring d_tag %d = %#x", dynp->d_tag, dynp->d_tag);
+ if (obj != &obj_rtld)
+ dbg("Ignoring d_tag %d = %#x", dynp->d_tag, dynp->d_tag);
break;
}
}
@@ -943,6 +944,9 @@
return xstrdup(name);
}
+ if (refobj && refobj->wrapper_func)
+ name = refobj->wrapper_func(WRAP_OP_SONAME, refobj->path, name);
+
dbg(" Searching for \"%s\"", name);
if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
@@ -993,6 +997,11 @@
hash = elf_hash(name);
defobj = NULL;
+ if (refobj->wrapper_func != NULL) {
+ name = refobj->wrapper_func(WRAP_OP_SYMNAME, refobj->path, name);
+ hash = elf_hash(name);
+ }
+
def = symlook_default(name, hash, refobj, &defobj, in_plt);
/*
@@ -1301,6 +1310,49 @@
return(obj);
}
+static void
+load_wrapper_object(Obj_Entry *obj)
+{
+ char *wrapper_path;
+ Obj_Entry *wrapper_obj = NULL;
+ Obj_Entry **old_objtail;
+ const Elf_Sym *wrap_func_sym;
+ const char *wrap_func_name = "__wrapper_func";
+ unsigned long hash = elf_hash(wrap_func_name);
+ int result;
+
+ /* Save the tail so that we can remove the wrapper from the list */
+ old_objtail = obj_tail;
+
+ wrapper_path = xmalloc(strlen(obj->path) + strlen(".wrapper") + 1);
+ strcpy(wrapper_path, obj->path);
+ strcat(wrapper_path, ".wrapper");
+
+ wrapper_obj = load_object(wrapper_path);
+ if (wrapper_obj == NULL) {
+ free(wrapper_path);
+ return;
+ }
+
+ result = load_needed_objects(obj);
+
+ if (result == -1 ||
+ (init_dag(wrapper_obj), relocate_objects(wrapper_obj, true)) == -1) {
+ unref_dag(wrapper_obj);
+ if (wrapper_obj->refcount == 0)
+ unload_object(wrapper_obj);
+ return;
+ }
+
+ wrap_func_sym = symlook_obj(wrap_func_name, hash, wrapper_obj, true);
+ if (wrap_func_sym != NULL)
+ obj->wrapper_func = (wrapper_func)(wrapper_obj->relocbase + wrap_func_sym->st_value);
+
+ /* Hide the wrapper object from the list */
+ obj_tail = old_objtail;
+ obj->wrapper_obj = wrapper_obj;
+}
+
/*
* Load a shared object into memory, if it is not already loaded. The
* argument must be a string allocated on the heap. This function assumes
@@ -1334,6 +1386,7 @@
}
dbg("loading \"%s\"", path);
+
obj = map_object(fd, path, &sb);
close(fd);
if (obj == NULL) {
@@ -1342,6 +1395,9 @@
}
obj->path = path;
+
+ load_wrapper_object(obj);
+
digest_dynamic(obj);
*obj_tail = obj;
@@ -1816,25 +1872,34 @@
dlsym(void *handle, const char *name)
{
const Obj_Entry *obj;
+ const Obj_Entry *callobj;
unsigned long hash;
const Elf_Sym *def;
const Obj_Entry *defobj;
+ void *retaddr;
hash = elf_hash(name);
def = NULL;
defobj = NULL;
rlock_acquire();
+ retaddr = __builtin_return_address(0); /* __GNUC__ only */
+ if ((callobj = obj_from_addr(retaddr)) != NULL &&
+ callobj->wrapper_func != NULL) {
+ handle = callobj->wrapper_func(WRAP_OP_HANDLE, callobj->path, handle);
+ name = callobj->wrapper_func(WRAP_OP_SYMNAME, callobj->path, name);
+ hash = elf_hash(name);
+ }
+
if (handle == NULL || handle == RTLD_NEXT ||
handle == RTLD_DEFAULT || handle == RTLD_SELF) {
- void *retaddr;
- retaddr = __builtin_return_address(0); /* __GNUC__ only */
- if ((obj = obj_from_addr(retaddr)) == NULL) {
+ if (callobj == NULL) {
_rtld_error("Cannot determine caller's shared object");
rlock_release();
return NULL;
}
+ obj = callobj;
if (handle == NULL) { /* Just the caller's shared object. */
def = symlook_obj(name, hash, obj, true);
defobj = obj;
@@ -2279,6 +2344,16 @@
}
}
+ /* Search the wrapper */
+ if (refobj->wrapper_obj != NULL &&
+ (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK)) {
+ symp = symlook_obj(name, hash, refobj->wrapper_obj, in_plt);
+ if (symp != NULL) {
+ def = symp;
+ defobj = refobj->wrapper_obj;
+ }
+ }
+
/* Search all objects loaded at program start up. */
if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
symp = symlook_list(name, hash, &list_main, &obj, in_plt, &donelist);
Index: rtld.h
===================================================================
RCS file: /home/dcvs/src/libexec/rtld-elf/rtld.h,v
retrieving revision 1.11
diff -u -r1.11 rtld.h
--- rtld.h 11 May 2005 19:47:06 -0000 1.11
+++ rtld.h 22 Oct 2006 11:05:54 -0000
@@ -38,6 +38,7 @@
#include <stddef.h>
#include "rtld_machdep.h"
+#include "rtld_wrap.h"
#ifndef STANDARD_LIBRARY_PATH
#define STANDARD_LIBRARY_PATH "/usr/lib"
@@ -181,6 +182,9 @@
Objlist dagmembers; /* DAG has these members (%) */
dev_t dev; /* Object's filesystem's device */
ino_t ino; /* Object's inode number */
+
+ struct Struct_Obj_Entry *wrapper_obj; /* Object's wrapper DSO */
+ wrapper_func wrapper_func; /* Object's translator func */
} Obj_Entry;
#define RTLD_MAGIC 0xd550b87a
Index: rtld_wrap.h
===================================================================
RCS file: rtld_wrap.h
diff -N rtld_wrap.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ rtld_wrap.h 22 Oct 2006 12:08:24 -0000
@@ -0,0 +1,5 @@
+#define WRAP_OP_SONAME 1
+#define WRAP_OP_SYMNAME 2
+#define WRAP_OP_HANDLE 3
+
+typedef void *(*wrapper_func)(int, const char *, const void *);
Attachment:
signature.asc
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pgp00004.pgp
Type: application/octet-stream
Size: 252 bytes
Desc: "Description: OpenPGP digital signature"
URL: <http://lists.dragonflybsd.org/pipermail/kernel/attachments/20061025/96021340/attachment-0019.obj>
More information about the Kernel
mailing list