summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorPeter Johnson <peter@tortall.net>2008-05-22 09:08:03 +0000
committerPeter Johnson <peter@tortall.net>2008-05-22 09:08:03 +0000
commitb7f2fbc64fcfe8e30650a32e3354613aceaceb0c (patch)
tree785bf9ebd79ce3369af295bfbeea0b75faffa5be /plugins
parent811d7ad566a3e7df758c47d4f11dcf4ea82a403d (diff)
downloadyasm-b7f2fbc64fcfe8e30650a32e3354613aceaceb0c.tar.gz
Add cmake build infrastructure.
Not default nor even distributed in the .tar.gz, the cmake build allows for loadable yasm plugins by building libyasm as a shared library. Example plugins are in the plugins/ directory, and may be loaded into a cmake-built yasm using the -N command line option (non-cmake builds will not have this option). Tested only on Linux so far, but should be relatively painless to port to Windows thanks to the use of cmake rather than libtool to create shared libraries. The only modification to the main source tree is some conditional-compiled additions to yasm.c. svn path=/trunk/yasm/; revision=2098
Diffstat (limited to 'plugins')
-rw-r--r--plugins/README20
-rw-r--r--plugins/dbg/CMakeLists.txt45
-rw-r--r--plugins/dbg/README15
-rw-r--r--plugins/dbg/dbg-objfmt.c175
-rw-r--r--plugins/dbg/init_plugin.c13
-rw-r--r--plugins/x86/CMakeLists.txt117
-rw-r--r--plugins/x86/README10
-rw-r--r--plugins/x86/init_plugin.c13
8 files changed, 408 insertions, 0 deletions
diff --git a/plugins/README b/plugins/README
new file mode 100644
index 00000000..c16a8fd0
--- /dev/null
+++ b/plugins/README
@@ -0,0 +1,20 @@
+These directories contain example yasm plugins.
+Yasm is only capable of loading plugins when it was built using cmake.
+To build yasm with cmake on Unix, from the yasm source tree, do:
+ mkdir objdir
+ cd objdir
+ cmake ..
+ make
+
+The plugins are written to be compiled against an *installed* yasm.
+Plugins may be loaded on the yasm command line using the -N command line
+option, e.g.:
+ yasm -N ./libdbgmod.so
+ yasm -N /usr/local/lib/libx86mod
+(the .so will be automatically appended)
+If no directory path is specified, yasm will search in standard library
+locations (e.g. LD_LIBRARY_PATH, the rpath of the yasm executable, etc) to
+try to load the plugin. Thus the last example could likely be written:
+ yasm -N libx86mod
+
+Plugins may override builtin modules like x86.
diff --git a/plugins/dbg/CMakeLists.txt b/plugins/dbg/CMakeLists.txt
new file mode 100644
index 00000000..fa51498b
--- /dev/null
+++ b/plugins/dbg/CMakeLists.txt
@@ -0,0 +1,45 @@
+FIND_PROGRAM(YASM_PATH yasm)
+
+SET (YASM_POSSIBLE_INCLUDE_PATHS
+ "${YASM_PATH}"
+ "${YASM_PATH}/../include"
+ "$ENV{ProgramFiles}/Yasm/Include"
+ /usr/include
+ /usr/local/include
+ )
+
+FIND_PATH(YASM_INCLUDE_PATH NAMES libyasm.h
+ DOC "The path to the libyasm include files"
+ PATHS ${YASM_POSSIBLE_INCLUDE_PATHS}
+ )
+
+IF (NOT YASM_INCLUDE_PATH)
+ MESSAGE(FATAL_ERROR "Could not find yasm include files")
+ENDIF (NOT YASM_INCLUDE_PATH)
+
+INCLUDE_DIRECTORIES(${YASM_INCLUDE_PATH})
+
+SET (YASM_POSSIBLE_LIB_PATHS
+ "${YASM_PATH}"
+ "${YASM_PATH}/../lib"
+ "${YASM_INCLUDE_PATH}/../lib"
+ "$ENV{ProgramFiles}/Yasm/Lib"
+ /usr/lib
+ /usr/local/lib
+ )
+
+FIND_LIBRARY(YASM_LIBRARY
+ NAMES yasm
+ DOC "The path to the libyasm library"
+ PATHS ${YASM_POSSIBLE_LIB_PATHS}
+ )
+
+IF (NOT YASM_LIBRARY)
+ MESSAGE(FATAL_ERROR "Could not find yasm library")
+ENDIF (NOT YASM_LIBRARY)
+
+ADD_LIBRARY(dbgmod MODULE
+ init_plugin.c
+ dbg-objfmt.c
+ )
+TARGET_LINK_LIBRARIES(dbgmod ${YASM_LIBRARY})
diff --git a/plugins/dbg/README b/plugins/dbg/README
new file mode 100644
index 00000000..3a1f5cb7
--- /dev/null
+++ b/plugins/dbg/README
@@ -0,0 +1,15 @@
+This directory demonstrates how to build a basic plugin.
+It does not need access to the yasm source, only an installed yasm.
+
+To build:
+ mkdir objdir
+ cd objdir
+ cmake ..
+ make
+
+Testing:
+ yasm -N ./libdbgmod.so -f dbg -
+ db 5
+ ^D
+(result lines will have PLUGIN prefixed to the function calls; this
+demonstrates the plugin is being used rather than the builtin dbg module)
diff --git a/plugins/dbg/dbg-objfmt.c b/plugins/dbg/dbg-objfmt.c
new file mode 100644
index 00000000..1aef7c20
--- /dev/null
+++ b/plugins/dbg/dbg-objfmt.c
@@ -0,0 +1,175 @@
+/*
+ * Debugging object format (used to debug object format module interface)
+ *
+ * Copyright (C) 2001-2007 Peter Johnson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <libyasm.h>
+
+#define N_(String) (String)
+
+typedef struct yasm_objfmt_dbg {
+ yasm_objfmt_base objfmt; /* base structure */
+
+ FILE *dbgfile;
+} yasm_objfmt_dbg;
+
+yasm_objfmt_module yasm_dbg_LTX_objfmt;
+
+
+static yasm_objfmt *
+dbg_objfmt_create(yasm_object *object)
+{
+ yasm_objfmt_dbg *objfmt_dbg = yasm_xmalloc(sizeof(yasm_objfmt_dbg));
+
+ objfmt_dbg->objfmt.module = &yasm_dbg_LTX_objfmt;
+
+ objfmt_dbg->dbgfile = tmpfile();
+ if (!objfmt_dbg->dbgfile) {
+ fprintf(stderr, N_("could not open temporary file"));
+ return 0;
+ }
+ fprintf(objfmt_dbg->dbgfile, "PLUGIN create()\n");
+ return (yasm_objfmt *)objfmt_dbg;
+}
+
+static void
+dbg_objfmt_output(yasm_object *object, FILE *f, int all_syms,
+ yasm_errwarns *errwarns)
+{
+ yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
+ char buf[1024];
+ size_t i;
+
+ /* Copy temp file to real output file */
+ rewind(objfmt_dbg->dbgfile);
+ while ((i = fread(buf, 1, 1024, objfmt_dbg->dbgfile))) {
+ if (fwrite(buf, 1, i, f) != i)
+ break;
+ }
+
+ /* Reassign objfmt debug file to output file */
+ fclose(objfmt_dbg->dbgfile);
+ objfmt_dbg->dbgfile = f;
+
+ fprintf(objfmt_dbg->dbgfile, "PLUGIN output(f, object->\n");
+ yasm_object_print(object, objfmt_dbg->dbgfile, 1);
+ fprintf(objfmt_dbg->dbgfile, "%d)\n", all_syms);
+ fprintf(objfmt_dbg->dbgfile, " Symbol Table:\n");
+ yasm_symtab_print(object->symtab, objfmt_dbg->dbgfile, 1);
+}
+
+static void
+dbg_objfmt_destroy(yasm_objfmt *objfmt)
+{
+ yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)objfmt;
+ fprintf(objfmt_dbg->dbgfile, "PLUGIN destroy()\n");
+ yasm_xfree(objfmt);
+}
+
+static yasm_section *
+dbg_objfmt_add_default_section(yasm_object *object)
+{
+ yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
+ yasm_section *retval;
+ int isnew;
+
+ retval = yasm_object_get_general(object, ".text", 0, 0, 0, &isnew, 0);
+ if (isnew) {
+ fprintf(objfmt_dbg->dbgfile, "(new) ");
+ yasm_symtab_define_label(object->symtab, ".text",
+ yasm_section_bcs_first(retval), 1, 0);
+ yasm_section_set_default(retval, 1);
+ }
+ return retval;
+}
+
+static /*@observer@*/ /*@null@*/ yasm_section *
+dbg_objfmt_section_switch(yasm_object *object, yasm_valparamhead *valparams,
+ /*@unused@*/ /*@null@*/
+ yasm_valparamhead *objext_valparams,
+ unsigned long line)
+{
+ yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
+ yasm_valparam *vp;
+ yasm_section *retval;
+ int isnew;
+
+ fprintf(objfmt_dbg->dbgfile, "PLUGIN section_switch(headp, ");
+ yasm_vps_print(valparams, objfmt_dbg->dbgfile);
+ fprintf(objfmt_dbg->dbgfile, ", ");
+ yasm_vps_print(objext_valparams, objfmt_dbg->dbgfile);
+ fprintf(objfmt_dbg->dbgfile, ", %lu), returning ", line);
+
+ vp = yasm_vps_first(valparams);
+ if (!yasm_vp_string(vp)) {
+ fprintf(objfmt_dbg->dbgfile, "NULL\n");
+ return NULL;
+ }
+ retval = yasm_object_get_general(object, yasm_vp_string(vp), 0, 0, 0,
+ &isnew, line);
+ if (isnew) {
+ fprintf(objfmt_dbg->dbgfile, "(new) ");
+ yasm_symtab_define_label(object->symtab, vp->val,
+ yasm_section_bcs_first(retval), 1, line);
+ }
+ yasm_section_set_default(retval, 0);
+ fprintf(objfmt_dbg->dbgfile, "\"%s\" section\n", vp->val);
+ return retval;
+}
+
+static /*@observer@*/ /*@null@*/ yasm_symrec *
+dbg_objfmt_get_special_sym(yasm_object *object, const char *name,
+ const char *parser)
+{
+ yasm_objfmt_dbg *objfmt_dbg = (yasm_objfmt_dbg *)object->objfmt;
+ fprintf(objfmt_dbg->dbgfile,
+ "PLUGIN get_special_sym(object, \"%s\", \"%s\")\n",
+ name, parser);
+ return NULL;
+}
+
+/* Define valid debug formats to use with this object format */
+static const char *dbg_objfmt_dbgfmt_keywords[] = {
+ "null",
+ NULL
+};
+
+/* Define objfmt structure -- see objfmt.h for details */
+yasm_objfmt_module yasm_dbg_LTX_objfmt = {
+ "Trace of all info passed to object format module",
+ "dbg",
+ "dbg",
+ 32,
+ dbg_objfmt_dbgfmt_keywords,
+ "null",
+ NULL, /* no directives */
+ NULL, /* no standard macros */
+ dbg_objfmt_create,
+ dbg_objfmt_output,
+ dbg_objfmt_destroy,
+ dbg_objfmt_add_default_section,
+ dbg_objfmt_section_switch,
+ dbg_objfmt_get_special_sym
+};
diff --git a/plugins/dbg/init_plugin.c b/plugins/dbg/init_plugin.c
new file mode 100644
index 00000000..e8e53dc5
--- /dev/null
+++ b/plugins/dbg/init_plugin.c
@@ -0,0 +1,13 @@
+#include <libyasm.h>
+#include <libyasm/module.h>
+
+extern yasm_arch_module yasm_dbg_LTX_objfmt;
+
+#ifdef _MSC_VER
+__declspec(dllexport)
+#endif
+void
+yasm_init_plugin(void)
+{
+ yasm_register_module(YASM_MODULE_OBJFMT, "dbg", &yasm_dbg_LTX_objfmt);
+}
diff --git a/plugins/x86/CMakeLists.txt b/plugins/x86/CMakeLists.txt
new file mode 100644
index 00000000..55d273d5
--- /dev/null
+++ b/plugins/x86/CMakeLists.txt
@@ -0,0 +1,117 @@
+SET(SOURCE_DIR "${YASM_SOURCE_DIR}/modules/arch/x86")
+
+FIND_PROGRAM(YASM_PATH yasm)
+
+FIND_PROGRAM(GENPERF_PATH genperf
+ DOC "The path to the yasm genperf executable"
+ PATHS ${YASM_SOURCE_DIR}/objdir/tools/genperf
+ )
+
+IF (NOT GENPERF_PATH)
+ MESSAGE(FATAL_ERROR "Could not find genperf executable")
+ENDIF (NOT GENPERF_PATH)
+
+SET (YASM_POSSIBLE_INCLUDE_PATHS
+ "${YASM_PATH}"
+ "${YASM_PATH}/../include"
+ "$ENV{ProgramFiles}/Yasm/Include"
+ /usr/include
+ /usr/local/include
+ )
+
+FIND_PATH(YASM_INCLUDE_PATH NAMES libyasm.h
+ DOC "The path to the libyasm include files"
+ PATHS ${YASM_POSSIBLE_INCLUDE_PATHS}
+ )
+
+IF (NOT YASM_INCLUDE_PATH)
+ MESSAGE(FATAL_ERROR "Could not find yasm include files")
+ENDIF (NOT YASM_INCLUDE_PATH)
+
+INCLUDE_DIRECTORIES(${YASM_INCLUDE_PATH})
+INCLUDE_DIRECTORIES(${YASM_SOURCE_DIR})
+
+SET (YASM_POSSIBLE_LIB_PATHS
+ "${YASM_PATH}"
+ "${YASM_PATH}/../lib"
+ "${YASM_INCLUDE_PATH}/../lib"
+ "$ENV{ProgramFiles}/Yasm/Lib"
+ /usr/lib
+ /usr/local/lib
+ )
+
+FIND_LIBRARY(YASM_LIBRARY
+ NAMES yasm
+ DOC "The path to the libyasm library"
+ PATHS ${YASM_POSSIBLE_LIB_PATHS}
+ )
+
+IF (NOT YASM_LIBRARY)
+ MESSAGE(FATAL_ERROR "Could not find yasm library")
+ENDIF (NOT YASM_LIBRARY)
+
+INCLUDE(FindPythonInterp)
+
+INCLUDE_DIRECTORIES(${SOURCE_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insns.c
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_gas.gperf
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_nasm.gperf
+ COMMAND ${PYTHON_EXECUTABLE} ${SOURCE_DIR}/gen_x86_insn.py
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insns.c
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_gas.gperf
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_nasm.gperf
+ MAIN_DEPENDENCY ${SOURCE_DIR}/gen_x86_insn.py
+ )
+
+macro (YASM_GENPERF _in_NAME _out_NAME)
+ add_custom_command(
+ OUTPUT ${_out_NAME}
+ COMMAND ${GENPERF_PATH} ${_in_NAME} ${_out_NAME}
+ MAIN_DEPENDENCY ${_in_NAME}
+ )
+endmacro (YASM_GENPERF)
+
+YASM_GENPERF(
+ ${SOURCE_DIR}/x86cpu.gperf
+ ${CMAKE_CURRENT_BINARY_DIR}/x86cpu.c
+ )
+
+YASM_GENPERF(
+ ${SOURCE_DIR}/x86regtmod.gperf
+ ${CMAKE_CURRENT_BINARY_DIR}/x86regtmod.c
+ )
+
+YASM_GENPERF(
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_nasm.gperf
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_nasm.c
+ )
+
+YASM_GENPERF(
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_gas.gperf
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_gas.c
+ )
+
+SET(insn_DEPS
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_nasm.c
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insn_gas.c
+ ${CMAKE_CURRENT_BINARY_DIR}/x86insns.c
+ )
+
+SET_SOURCE_FILES_PROPERTIES(${SOURCE_DIR}/x86id.c PROPERTIES
+ OBJECT_DEPENDS "${insn_DEPS}"
+ )
+
+ADD_LIBRARY(x86mod MODULE
+ init_plugin.c
+ ${SOURCE_DIR}/x86arch.c
+ ${SOURCE_DIR}/x86bc.c
+ ${SOURCE_DIR}/x86expr.c
+ ${SOURCE_DIR}/x86id.c
+ x86cpu.c
+ x86regtmod.c
+ )
+TARGET_LINK_LIBRARIES(x86mod ${YASM_LIBRARY})
diff --git a/plugins/x86/README b/plugins/x86/README
new file mode 100644
index 00000000..17346155
--- /dev/null
+++ b/plugins/x86/README
@@ -0,0 +1,10 @@
+This directory demonstrates how to build a yasm builtin module as a plugin.
+This can be useful for integrating custom changes without
+rebuilding/reinstalling yasm.
+It requires access to the yasm source.
+
+The yasm source directory must be defined to cmake, e.g.
+ mkdir objdir
+ cd objdir
+ cmake -DYASM_SOURCE_DIR=/home/foo/yasm ..
+ make
diff --git a/plugins/x86/init_plugin.c b/plugins/x86/init_plugin.c
new file mode 100644
index 00000000..d2698b19
--- /dev/null
+++ b/plugins/x86/init_plugin.c
@@ -0,0 +1,13 @@
+#include <libyasm.h>
+#include <libyasm/module.h>
+
+extern yasm_arch_module yasm_x86_LTX_arch;
+
+#ifdef _MSC_VER
+__declspec(dllexport)
+#endif
+void
+yasm_init_plugin(void)
+{
+ yasm_register_module(YASM_MODULE_ARCH, "x86", &yasm_x86_LTX_arch);
+}