/* obj_file.h object file support Copyright (C) 2002 Bill Currie Author: Bill Currie Date: 2002/6/16 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifndef __obj_file_h #define __obj_file_h /** \defgroup qfcc_qfo Object file functions \ingroup qfcc */ ///@{ #include "QF/progs/pr_comp.h" #include "QF/progs/pr_debug.h" #include "QF/quakeio.h" /** Identifier string for qfo object files (includes terminating nul) \hideinitializer */ #define QFO "QFO" /** QFO object file format version (MMmmmRRR 0.001.006 (hex)) \hideinitializer */ #define QFO_VERSION 0x00001007 /** Header block of QFO object files. The sections of the object file come immediately after the header, and are always in the order given by the struct. All indices to records are 0-based from the beginning of the relevant section. */ typedef struct qfo_header_s { int8_t qfo[4]; ///< identifier string (includes nul) (#QFO) pr_uint_t version; ///< QFO format version (#QFO_VERSION) pr_uint_t num_spaces; pr_uint_t num_relocs; ///< number of relocation records pr_uint_t num_defs; ///< number of def records pr_uint_t num_funcs; ///< number of function records pr_uint_t num_lines; ///< number of line records pr_uint_t num_loose_relocs; ///< number of loose relocation records ///< (included in num_relocs) pr_uint_t progs_version; ///< version of compatible VM pr_uint_t reserved[3]; } qfo_header_t; typedef enum qfos_type_e { qfos_null, ///< null space. no data or defs. first in qfo qfos_code, ///< progs code. dstatement_t data qfos_data, ///< progs data. pr_type_t data qfos_string, ///< strings. char data qfos_entity, ///< entity field defs. no data qfos_type, ///< type encodings qfos_debug, ///< debug data } qfos_type_t; /** Representation of a space in the object file. */ typedef struct qfo_space_s { pr_int_t type; ///< code, string, data, entity... pr_uint_t defs; ///< index of first def pr_uint_t num_defs; ///< zero for code or string spaces pr_uint_t data; ///< byte offset in qfo pr_uint_t data_size; ///< in elements. zero for entity spaces pr_uint_t id; pr_uint_t alignment; ///< min alignment for space (1<spaces[s].data[o]) /** Access a double variable in the object file. Can be assigned to. \par QC type: \c double \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return double lvalue \hideinitializer */ #define QFO_DOUBLE(q, s, o) (*(double *) ((q)->spaces[s].data + o)) /** Access a float variable in the object file. Can be assigned to. \par QC type: \c float \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return float lvalue \hideinitializer */ #define QFO_FLOAT(q, s, o) QFO_var (q, s, float, o) /** Access a int variable in the object file. Can be assigned to. \par QC type: \c int \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return int lvalue \hideinitializer */ #define QFO_INT(q, s, o) QFO_var (q, s, int, o) /** Access a vector variable in the object file. Can be assigned to. \par QC type: \c vector \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return vec3_t lvalue \hideinitializer */ #define QFO_VECTOR(q, s, o) QFO_var (q, s, vector, o) /** Access a string index variable in the object file. Can be assigned to. \par QC type: \c string \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return pr_string_t lvalue \hideinitializer */ #define QFO_STRING(q, s, o) QFO_var (q, s, string, o) /** Retrieve a string from the object file, converting it to a C string. \param q pointer to ::qfo_t struct \param s space index \return (char *) \hideinitializer */ #define QFO_GETSTR(q, s) ((q)->spaces[qfo_strings_space].strings + (s)) #define QFO_TYPE(q, t) ((qfot_type_t *) (char *) \ ((q)->spaces[qfo_type_space].data + (t))) /** Retrieve a type string from the object file, converting it to a C string. \param q pointer to ::qfo_t struct \param t offset to type encoding \return (char *) \note Assumes standard space order. \hideinitializer */ #define QFO_TYPESTR(q, t) QFO_GSTRING (q, qfo_type_space, (t) + 2) #define QFO_TYPEMETA(q, t) QFO_INT (q, qfo_type_space, (t) + 0) #define QFO_TYPETYPE(q, t) QFO_INT (q, qfo_type_space, (t) + 3) #define QFO_STATEMENT(q, s) ((q)->spaces[qfo_code_space].code + (s)) /** Access a string global, converting it to a C string. \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return (char *) \hideinitializer */ #define QFO_GSTRING(q, s, o) (QFO_GETSTR (q, QFO_STRING (q, s, o))) /** Access a function variable in the object file. Can be assigned to. \par QC type: \c void () \param q pointer to ::qfo_t struct \param s space index \param o offset into object file data space \return pr_func_t lvalue \hideinitializer */ #define QFO_FUNCTION(q, s, o) QFO_var (q, s, func, o) /** Access a block of memory in the object file as a C struct. \par QC type: \c void [] \param q pointer to ::qfo_t struct \param s space index \param t C type of the structure \param o offset into object file data space \return C pointer to the struct at space:offset \hideinitializer */ #define QFO_POINTER(q, s, t, o) ((t *)(char *)&QFO_var (q, s, int, o)) /** Access a structure variable in the object file. Can be assigned to. \par QC type: \c void [](?) \param q pointer to ::qfo_t struct \param s space index \param t C type of the structure \param o offset into object file data space \return structure lvalue. use & to make a pointer of the appropriate type. \hideinitializer */ #define QFO_STRUCT(q, s, t, o) (*QFO_POINTER (q, s, t, o)) ///@} /** \addtogroup qfcc_qfo */ ///@{ struct pr_info_s; /** Convert ::pr_info_t structure to ::qfo_t. \param pr pointer to ::pr_info_t struct \return pointer to new ::qfo_t struct, or 0 on error. */ qfo_t *qfo_from_progs (struct pr_info_s *pr); /** Write a ::qfo_t struct to the named file. \param qfo pointer to ::qfo_t struct to write \param filename name of the file to write \return 0 for success, -1 for error. */ int qfo_write (qfo_t *qfo, const char *filename); /** Read a ::qfo_t strcut from a ::QFile stream. \param file ::QFile stream to read from \return pointer to new ::qfo_t struct, or 0 on error. */ qfo_t *qfo_read (QFile *file); /** Wrapper around qfo_read() to allow reading from a named file. \param filename name of the file to read \return pointer to new ::qfo_t struct, or 0 on error. */ qfo_t *qfo_open (const char *filename); dprograms_t *qfo_to_progs (qfo_t *in_qfo, int *size); pr_debug_header_t *qfo_to_sym (qfo_t *qfo, int *size); /** Create a new ::qfo_t struct \return pointer to new ::qfo_t struct, or 0 on error. */ qfo_t *qfo_new (void); /** Delete a ::qfo_t struct, as well as any substructure data. \param qfo ::qfo_t struct to delete */ void qfo_delete (qfo_t *qfo); __attribute__((const)) int qfo_log2 (pr_uint_t x); ///@} #endif//__obj_file_h