2 * Copyright (c) 1996 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * This license is for research uses. For such uses, there is no
12 * charge. We define "research use" to mean you may freely use it
13 * inside your organization for whatever purposes you see fit. But you
14 * may not re-distribute Paradyn or parts of Paradyn, in any form
15 * source or binary (including derivatives), electronic or otherwise,
16 * to any other organization or entity without our permission.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
24 * By your use of Paradyn, you understand and agree that we (or any
25 * other person or entity with proprietary rights in Paradyn) are
26 * under no obligation to provide either maintenance services,
27 * update services, notices of latent defects, or correction of
28 * defects for Paradyn.
30 * Even if advised of the possibility of such damages, under no
31 * circumstances shall we (or any other person or entity with
32 * proprietary rights in the software licensed hereunder) be liable
33 * to you or any third party for direct, indirect, or consequential
34 * damages of any character regardless of type of action, including,
35 * without limitation, loss of profits, loss of use, loss of good
36 * will, or computer failure or malfunction. You agree to indemnify
37 * us (and any other person or entity with proprietary rights in the
38 * software licensed hereunder) for any and all liability it may
39 * incur to third parties resulting from your use of Paradyn.
42 // $Id: BPatch.C,v 1.36 2001/07/11 21:19:57 gurari Exp $
50 #include "BPatch_libInfo.h"
52 #include "BPatch_collections.h"
53 #include "common/h/timing.h"
55 #ifdef i386_unknown_nt4_0
56 #include "nt_signal_emul.h"
59 extern bool dyninstAPI_init();
60 extern int handleSigChild(int pid, int status);
63 BPatch *BPatch::bpatch = NULL;
68 * Constructor for BPatch. Performs one-time initialization needed by the
74 dynLibraryCallback(NULL),
78 trampRecursiveOn(false),
79 forceRelocation_NP(false),
87 // Save a pointer to the one-and-only bpatch object.
91 * (indicate an error somehow)
94 // XXX dyninstAPI_init returns success/failure -- should pass on somehow
96 initCyclesPerSecond();
99 * Create the library private info object.
101 info = new BPatch_libInfo;
104 * Create the "error" and "untyped" types.
106 type_Error = new BPatch_type("<error>", true);
107 type_Untyped = new BPatch_type("<no type>", true);
110 * Initialize hash table of standard types.
112 stdTypes = new BPatch_typeCollection;
113 stdTypes->addType(new BPatch_type("int",-1, BPatch_scalar, sizeof(int)));
114 stdTypes->addType(new BPatch_type("char *",-3, BPatch_scalar, sizeof(char*)));
115 BPatch_type *voidType = new BPatch_type("void",-11, BPatch_scalar, 0);
116 stdTypes->addType(voidType);
117 stdTypes->addType(new BPatch_type("void *",-4, BPatch_pointer, voidType));
118 stdTypes->addType(new BPatch_type("float",-12, BPatch_scalar, sizeof(float)));
121 * Initialize hash table of API types.
123 APITypes = new BPatch_typeCollection;
126 * Initialize hash table of Built-in types.
127 * Negative type numbers defined in the gdb stab-docs
130 builtInTypes = new BPatch_builtInTypeCollection;
132 // NOTE: integral type mean twos-complement
133 // -1 int, 32 bit signed integral type
134 // in stab document, size specified in bits, system size is in bytes
135 builtInTypes->addBuiltInType(new BPatch_type("int",-1, BPatch_built_inType,
137 // -2 char, 8 bit type holding a character. GDB & dbx(AIX) treat as signed
138 builtInTypes->addBuiltInType(new BPatch_type("char",-2,
139 BPatch_built_inType, 1));
140 // -3 short, 16 bit signed integral type
141 builtInTypes->addBuiltInType(new BPatch_type("short",-3,
142 BPatch_built_inType, 2));
143 // -4 long, 32/64 bit signed integral type
144 builtInTypes->addBuiltInType(new BPatch_type("long",-4,
147 // -5 unsigned char, 8 bit unsigned integral type
148 builtInTypes->addBuiltInType(new BPatch_type("unsigned char",-5,
149 BPatch_built_inType, 1));
150 // -6 signed char, 8 bit signed integral type
151 builtInTypes->addBuiltInType(new BPatch_type("signed char",-6,
152 BPatch_built_inType, 1));
153 // -7 unsigned short, 16 bit unsigned integral type
154 builtInTypes->addBuiltInType(new BPatch_type("unsigned short",-7,
155 BPatch_built_inType, 2));
156 // -8 unsigned int, 32 bit unsigned integral type
157 builtInTypes->addBuiltInType(new BPatch_type("unsigned int",-8,
158 BPatch_built_inType, 4));
159 // -9 unsigned, 32 bit unsigned integral type
160 builtInTypes->addBuiltInType(new BPatch_type("unsigned",-9,
161 BPatch_built_inType,4));
162 // -10 unsigned long, 32 bit unsigned integral type
163 builtInTypes->addBuiltInType(new BPatch_type("unsigned long",-10,
165 sizeof(unsigned long)));
166 // -11 void, type indicating the lack of a value
167 // XXX-size may not be correct jdd 4/22/99
168 builtInTypes->addBuiltInType(new BPatch_type("void",-11,
171 // -12 float, IEEE single precision
172 builtInTypes->addBuiltInType(new BPatch_type("float",-12,
175 // -13 double, IEEE double precision
176 builtInTypes->addBuiltInType(new BPatch_type("double",-13,
179 // -14 long double, IEEE double precision, size may increase in future
180 builtInTypes->addBuiltInType(new BPatch_type("long double",-14,
182 sizeof(long double)));
183 // -15 integer, 32 bit signed integral type
184 builtInTypes->addBuiltInType(new BPatch_type("integer",-15,
185 BPatch_built_inType, 4));
186 // -16 boolean, 32 bit type. GDB/GCC 0=False, 1=True, all other values
187 // have unspecified meaning
188 builtInTypes->addBuiltInType(new BPatch_type("boolean",-16,
189 BPatch_built_inType, 4));
190 // -17 short real, IEEE single precision
191 // XXX-size may not be correct jdd 4/22/99
192 builtInTypes->addBuiltInType(new BPatch_type("short real",-17,
195 // -18 real, IEEE double precision XXX-size may not be correct jdd 4/22/99
196 builtInTypes->addBuiltInType(new BPatch_type("real",-18,
199 // -19 stringptr XXX- size of void * -- jdd 4/22/99
200 builtInTypes->addBuiltInType(new BPatch_type("stringptr",-19,
203 // -20 character, 8 bit unsigned character type
204 builtInTypes->addBuiltInType(new BPatch_type("character",-20,
205 BPatch_built_inType, 1));
206 // -21 logical*1, 8 bit type (Fortran, used for boolean or unsigned int)
207 builtInTypes->addBuiltInType(new BPatch_type("logical*1",-21,
208 BPatch_built_inType, 1));
209 // -22 logical*2, 16 bit type (Fortran, some for boolean or unsigned int)
210 builtInTypes->addBuiltInType(new BPatch_type("logical*2",-22,
211 BPatch_built_inType, 2));
212 // -23 logical*4, 32 bit type (Fortran, some for boolean or unsigned int)
213 builtInTypes->addBuiltInType(new BPatch_type("logical*4",-23,
214 BPatch_built_inType, 4));
215 // -24 logical, 32 bit type (Fortran, some for boolean or unsigned int)
216 builtInTypes->addBuiltInType(new BPatch_type("logical",-24,
217 BPatch_built_inType, 4));
218 // -25 complex, consists of 2 IEEE single-precision floating point values
219 builtInTypes->addBuiltInType(new BPatch_type("complex",-25,
222 // -26 complex, consists of 2 IEEE double-precision floating point values
223 builtInTypes->addBuiltInType(new BPatch_type("complex",-26,
225 (sizeof(double)*2)));
226 // -27 integer*1, 8 bit signed integral type
227 builtInTypes->addBuiltInType(new BPatch_type("integer*1",-27,
228 BPatch_built_inType, 1));
229 // -28 integer*2, 16 bit signed integral type
230 builtInTypes->addBuiltInType(new BPatch_type("integer*2",-28,
231 BPatch_built_inType, 2));
232 // -29 integer*4, 32 bit signed integral type
233 builtInTypes->addBuiltInType(new BPatch_type("integer*4",-29,
234 BPatch_built_inType, 4));
235 // -30 wchar, Wide character, 16 bits wide, unsigned (unknown format)
236 builtInTypes->addBuiltInType(new BPatch_type("wchar",-30,
237 BPatch_built_inType, 2));
238 // -31 long long, 64 bit signed integral type
239 builtInTypes->addBuiltInType(new BPatch_type("long long",-31,
240 BPatch_built_inType, 8));
241 // -32 unsigned long long, 64 bit unsigned integral type
242 builtInTypes->addBuiltInType(new BPatch_type("unsigned long long", -32,
243 BPatch_built_inType, 8));
244 // -33 logical*8, 64 bit unsigned integral type
245 builtInTypes->addBuiltInType(new BPatch_type("logical*8",-33,
246 BPatch_built_inType, 8));
247 // -34 integer*8, 64 bit signed integral type
248 builtInTypes->addBuiltInType(new BPatch_type("integer*8",-34,
249 BPatch_built_inType, 8));
251 // default callbacks are null
252 postForkCallback = NULL;
253 preForkCallback = NULL;
255 dynLibraryCallback = NULL;
259 #ifdef DETACH_ON_THE_FLY
260 // Register handler for notification from detached inferiors
261 extern void initDetachOnTheFly();
262 initDetachOnTheFly();
270 * Destructor for BPatch. Free allocated memory.
286 * BPatch::registerErrorCallback
288 * Registers a function that is to be called by the library when an error
289 * occurs or when there is status to report. Returns the address of the
290 * previously registered error callback function.
292 * function The function to be called.
294 BPatchErrorCallback BPatch::registerErrorCallback(BPatchErrorCallback function)
296 BPatchErrorCallback ret;
299 errorHandler = function;
306 * BPatch::registerPostForkCallback
308 * Registers a function that is to be called by the library when a new
309 * process has been forked off by an mutatee process.
311 * function The function to be called.
313 BPatchForkCallback BPatch::registerPostForkCallback(BPatchForkCallback func)
316 #if !defined(sparc_sun_solaris2_4) && \
317 !defined(i386_unknown_solaris2_5) && \
318 !defined(alpha_dec_osf4_0) && \
319 !defined(mips_sgi_irix6_4)
320 reportError(BPatchWarning, 0,
321 "postfork callbacks not implemented on this platform\n");
324 BPatchForkCallback ret;
326 ret = postForkCallback;
327 postForkCallback = func;
334 * BPatch::registerPreForkCallback
336 * Registers a function that is to be called by the library when a process
337 * is about to fork a new process
339 * function The function to be called.
341 BPatchForkCallback BPatch::registerPreForkCallback(BPatchForkCallback func)
343 #if !defined(sparc_sun_solaris2_4) && \
344 !defined(i386_unknown_solaris2_5) &&\
345 !defined(alpha_dec_osf4_0) && \
346 !defined(mips_sgi_irix6_4)
347 reportError(BPatchWarning, 0,
348 "prefork callbacks not implemented on this platform\n");
351 BPatchForkCallback ret;
353 ret = preForkCallback;
354 preForkCallback = func;
361 * BPatch::registerExecCallback
363 * Registers a function that is to be called by the library when a
364 * process has just completed an exec* call
366 * func The function to be called.
368 BPatchExecCallback BPatch::registerExecCallback(BPatchExecCallback func)
371 #if !defined(sparc_sun_solaris2_4) && \
372 !defined(i386_unknown_solaris2_5) &&\
373 !defined(alpha_dec_osf4_0) && \
374 !defined(mips_sgi_irix6_4)
375 reportError(BPatchWarning, 0,
376 "exec callbacks not implemented on this platform\n");
379 BPatchExecCallback ret;
389 * BPatch::registerExecCallback
391 * Registers a function that is to be called by the library when a
392 * process has just called the exit system call
394 * func The function to be called.
396 BPatchExitCallback BPatch::registerExitCallback(BPatchExitCallback func)
399 #if !defined(sparc_sun_solaris2_4) && \
400 !defined(i386_unknown_solaris2_5) &&\
401 !defined(alpha_dec_osf4_0) && \
402 !defined(mips_sgi_irix6_4)
403 reportError(BPatchWarning, 0,
404 "exit callbacks not implemented on this platform\n");
407 BPatchExitCallback ret;
417 * BPatch::registerDynLibraryCallback
419 * Registers a function that is to be called by the library when a dynamically
420 * loaded library is loaded or unloaded by a process under the API's control.
421 * Returns the address of the previously registered callback function.
423 * function The function to be called.
425 BPatchDynLibraryCallback
426 BPatch::registerDynLibraryCallback(BPatchDynLibraryCallback function)
428 BPatchDynLibraryCallback ret;
430 ret = dynLibraryCallback;
431 dynLibraryCallback = function;
438 * BPatch::getEnglishErrorString
440 * Returns the descriptive error string for the passed error number.
442 * number The number that identifies the error.
444 const char *BPatch::getEnglishErrorString(int /* number */)
451 * BPatch::reportError
453 * Report an error using the callback mechanism.
455 * severity The severity level of the error.
456 * number Identifies the error.
457 * str A string to pass as the first element of the list of strings
458 * given to the callback function.
460 void BPatch::reportError(BPatchErrorLevel severity, int number, const char *str)
462 assert(bpatch != NULL);
464 // don't log BPatchWarning or BPatchInfo messages as "errors"
465 if ((severity == BPatchFatal) || (severity == BPatchSerious))
466 bpatch->lastError = number;
468 if (bpatch->errorHandler != NULL) {
469 bpatch->errorHandler(severity, number, &str);
475 * BPatch::formatErrorString
477 * Takes a format string with an error message (obtained from
478 * getEnglishErrorString) and an array of parameters that were passed to an
479 * error callback function, and creates a string with the parameters
480 * substituted into it.
482 * dst The address into which the formatted string should be copied.
483 * size If the formatted string is equal to or longer than this number
484 * of characters, then it will be truncated to size-1 characters
485 * and terminated with a nul ('\0').
486 * fmt The format string (returned by a function such as
487 * getEnglishErrorString).
488 * params The array of parameters that were passed to an error callback
491 void BPatch::formatErrorString(char *dst, int size,
492 const char *fmt, const char **params)
496 while (size > 1 && *fmt) {
498 if (fmt[1] == '\0') {
500 } else if (fmt[1] == '%') {
503 } else if (fmt[1] == 's') {
504 char *p = const_cast<char *>(params[cur_param++]);
505 while (size > 1 && *p) {
527 * BPatch::getThreadByPid
529 * Given a process ID, this function returns a pointer to the associated
530 * BPatch_thread object (or NULL if there is none). Since a process may be
531 * registered provisionally with a thread object pointer of NULL, the boolean
532 * pointed to by the parameter "exists" is set to true if the pid exists in
533 * the table of processes, and false if it does not.
535 * pid The pid to look up.
536 * exists A pointer to a boolean to fill in with true if the pid exists
537 * in the table and false if it does not. NULL may be passed in
538 * if this information is not required.
540 BPatch_thread *BPatch::getThreadByPid(int pid, bool *exists)
542 if (info->threadsByPid.defines(pid)) {
543 if (exists) *exists = true;
544 return info->threadsByPid[pid];
546 if (exists) *exists = false;
555 * Returns a vector of all threads that are currently defined. Includes
556 * threads created directly using the library and those created with UNIX fork
557 * or Windows NT spawn system calls. The caller is responsible for deleting
558 * the vector when it is no longer needed.
560 BPatch_Vector<BPatch_thread *> *BPatch::getThreads()
562 BPatch_Vector<BPatch_thread *> *result = new BPatch_Vector<BPatch_thread *>;
564 dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
567 BPatch_thread *thread;
569 while (ti.next(pid, thread))
570 result->push_back(thread);
577 * BPatch::registerProvisionalThread
579 * Register a new process that is not yet associated with a thread.
580 * (this function is called only by createProcess).
582 * pid The pid of the process to register.
584 void BPatch::registerProvisionalThread(int pid)
586 assert(!info->threadsByPid.defines(pid));
587 info->threadsByPid[pid] = NULL;
592 * BPatch::registerForkedThread
594 * Register a new process that is not yet associated with a thread.
595 * (this function is an upcall when a new process is created).
597 * parentPid the pid of the parent process.
598 * childPid The pid of the process to register.
599 * proc lower lever handle to process specific stuff
602 void BPatch::registerForkedThread(int parentPid, int childPid, process *proc)
604 assert(!info->threadsByPid.defines(childPid));
606 BPatch_thread *parent = info->threadsByPid[parentPid];
609 info->threadsByPid[childPid] = new BPatch_thread(childPid, proc);
611 if (postForkCallback) {
612 postForkCallback(parent, info->threadsByPid[childPid]);
618 * BPatch::registerExec
620 * Register a process that has just done an exec call.
622 * thread thread that has just performed the exec
625 void BPatch::registerExec(BPatch_thread *thread)
627 // build a new BPatch_image for this one
628 thread->image = new BPatch_image(thread->proc);
631 execCallback(thread);
637 * BPatch::registerExit
639 * Register a process that has just done an exit call.
641 * thread thread that has just performed the exec
642 * code the exit status code
645 void BPatch::registerExit(BPatch_thread *thread, int code)
648 exitCallback(thread, code);
654 * BPatch::registerThread
656 * Register a new BPatch_thread object with the BPatch library (this function
657 * is called only by the constructor for BPatch_thread).
659 * thread A pointer to the thread to register.
661 void BPatch::registerThread(BPatch_thread *thread)
663 assert(!info->threadsByPid.defines(thread->getPid()) ||
664 info->threadsByPid[thread->getPid()] == NULL);
665 info->threadsByPid[thread->getPid()] = thread;
670 * BPatch::unRegisterThread
672 * Remove the BPatch_thread associated with a given pid from the list of
673 * threads being managed by the library.
675 * pid The pid of the thread to be removed.
677 void BPatch::unRegisterThread(int pid)
679 assert(info->threadsByPid.defines(pid));
680 info->threadsByPid.undef(pid);
685 * BPatch::createProcess
687 * Create a process and return a BPatch_thread representing it.
688 * Returns NULL upon failure.
690 * path The pathname of the executable for the new process.
691 * argv A list of the arguments for the new process, terminated by a
693 * envp A list of values that make up the environment for the new
694 * process, terminated by a NULL. If envp is NULL, the new
695 * new process will inherit the environemnt of the parent.
696 * stdin_fd file descriptor to use for stdin for the application
697 * stdout_fd file descriptor to use for stdout for the application
698 * stderr_fd file descriptor to use for stderr for the application
701 BPatch_thread *BPatch::createProcess(char *path, char *argv[],
702 char *envp[], int stdin_fd, int stdout_fd, int stderr_fd)
707 new BPatch_thread(path, argv, envp, stdin_fd, stdout_fd, stderr_fd);
710 (ret->proc->status() != stopped) ||
711 !ret->proc->isBootstrappedYet()) {
721 * BPatch::attachProcess
723 * Attach to a running process and return a BPatch_thread representing it.
724 * Returns NULL upon failure.
726 * path The pathname of the executable for the process.
727 * pid The id of the process to attach to.
729 BPatch_thread *BPatch::attachProcess(char *path, int pid)
733 BPatch_thread *ret = new BPatch_thread(path, pid);
736 (ret->proc->status() != stopped) ||
737 !ret->proc->isBootstrappedYet()) {
738 // It would be considerate to (attempt to) leave the process running
739 // at this point (*before* deleting the BPatch_thread handle for it!),
740 // even though it might be in bad shape after the attempted attach.
742 sprintf(msg,"attachProcess failed: process %d may now be killed!",pid);
743 reportError(BPatchWarning, 26, msg);
755 * Checks for changes in any child process, and optionally blocks until such a
756 * change has occurred. Also updates the process object representing each
757 * process for which a change is detected. The return value is true if a
758 * change was detected, otherwise it is false.
760 * block Set this parameter to true to block waiting for a change,
761 * set to false to poll and return immediately, whether or not a
764 bool BPatch::getThreadEvent(bool block)
769 // while ((pid = process::waitProcs(&status, block)) > 0) {
770 if ((pid = process::waitProcs(&status, block)) > 0) {
771 // There's been a change in a child process
773 // Since we found something, we don't want to block anymore
777 BPatch_thread *thread = getThreadByPid(pid, &exists);
778 if (thread == NULL) {
780 if (WIFSIGNALED(status) || WIFEXITED(status))
781 unRegisterThread(pid);
783 fprintf(stderr, "Warning - wait returned status of an unknown process (%d)\n", pid);
786 if (thread != NULL) {
787 if (WIFSTOPPED(status)) {
788 thread->lastSignal = WSTOPSIG(status);
789 thread->setUnreportedStop(true);
790 } else if (WIFSIGNALED(status)) {
791 thread->lastSignal = WTERMSIG(status);
792 thread->setUnreportedTermination(true);
793 } else if (WIFEXITED(status)) {
794 #ifndef i386_unknown_nt4_0
795 thread->proc->exitCode_ = WEXITSTATUS(status);
797 thread->exitCode = thread->proc->exitCode();
798 thread->lastSignal = 0; /* XXX Make into some constant */
799 thread->setUnreportedTermination(true);
802 #ifndef i386_unknown_nt4_0
803 handleSigChild(pid, status);
805 if (thread->lastSignal == SIGSTOP) {
806 // need to continue process after initial sigstop
807 // thread->continueExecution();
808 printf("BPatch past handleSigChild for SIGSTOP\n");
809 if (thread->proc->wasCreatedViaFork()) {
810 printf("marking forked process stopped\n");
811 thread->proc->status_ = stopped;
812 // thread->lastSignal = SIGSTOP;
813 // thread->setUnreportedStop(true);
814 // thread->proc->continueProc();
828 * Returns true if any thread has stopped or terminated and that fact hasn't
829 * been reported to the user of the library. Otherwise, returns false.
831 bool BPatch::havePendingEvent()
833 #ifdef i386_unknown_nt4_0
834 // On NT, we need to poll for events as often as possible, so that we can
836 if (getThreadEvent(false))
840 // For now, we'll do it by iterating over the threads and checking them,
841 // and we'll change it to something more efficient later on.
842 dictionary_hash_iter<int, BPatch_thread *> ti(info->threadsByPid);
845 BPatch_thread *thread;
847 while (ti.next(pid, thread)) {
848 if (thread != NULL &&
849 (thread->pendingUnreportedStop() ||
850 thread->pendingUnreportedTermination())) {
860 * pollForStatusChange
862 * Checks for unreported changes to the status of any child process, and
863 * returns true if any are detected. Returns false otherwise.
865 * This function is declared as a friend of BPatch_thread so that it can use
866 * the BPatch_thread::getThreadEvent call to check for status changes.
868 bool BPatch::pollForStatusChange()
870 if (havePendingEvent())
873 // No changes were previously detected, so check for new changes
874 return getThreadEvent(false);
879 * waitForStatusChange
881 * Blocks waiting for a change to occur in the running status of a child
882 * process. Returns true upon success, false upon failure.
884 * This function is declared as a friend of BPatch_thread so that it can use
885 * the BPatch_thread::getThreadEvent call to check for status changes.
887 bool BPatch::waitForStatusChange()
889 if (havePendingEvent())
892 // No changes were previously detected, so wait for a new change
893 return getThreadEvent(true);
899 * This function is a wrapper for the BPatch_type constructors for API/User
902 * It returns a pointer to a BPatch_type that was added to the APITypes
905 BPatch_type * BPatch::createEnum( const char * name,
906 BPatch_Vector<char *> elementNames,
907 BPatch_Vector<int> elementIds)
910 if (elementNames.size() != elementIds.size()) {
914 BPatch_type * newType = new BPatch_type( name, BPatch_enumerated );
915 if (!newType) return NULL;
917 APITypes->addType(newType);
919 // ADD components to type
920 for (int i=0; i < elementNames.size(); i++) {
921 newType->addField(elementNames[i], BPatch_scalar, elementIds[i]);
931 * This function is a wrapper for the BPatch_type constructors for API/User
932 * created types. The user has left element id specification to us
934 * It returns a pointer to a BPatch_type that was added to the APITypes
937 BPatch_type * BPatch::createEnum( const char * name,
938 BPatch_Vector<char *> elementNames)
940 BPatch_type * newType = new BPatch_type( name, BPatch_enumerated );
942 if (!newType) return NULL;
944 APITypes->addType(newType);
946 // ADD components to type
947 for (int i=0; i < elementNames.size(); i++) {
948 newType->addField(elementNames[i], BPatch_scalar, i);
957 * This function is a wrapper for the BPatch_type constructors for API/User
960 * It returns a pointer to a BPatch_type that was added to the APITypes
964 BPatch_type * BPatch::createStruct( const char * name,
965 BPatch_Vector<char *> fieldNames,
966 BPatch_Vector<BPatch_type *> fieldTypes)
972 if (fieldNames.size() != fieldTypes.size()) {
976 //Compute the size of the struct
977 for (i=0; i < fieldNames.size(); i++) {
978 BPatch_type *type = fieldTypes[i];
979 size = type->getSize();
983 BPatch_type *newType = new BPatch_type(name, BPatch_structure, size);
984 if (!newType) return NULL;
986 APITypes->addType(newType);
988 // ADD components to type
990 for (i=0; i < fieldNames.size(); i++) {
991 BPatch_type *type = fieldTypes[i];
992 size = type->getSize();
993 newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
995 // Calculate next offset (in bits) into the struct
996 offset += (size * 8);
1005 * This function is a wrapper for the BPatch_type constructors for API/User
1008 * It returns a pointer to a BPatch_type that was added to the APITypes
1012 BPatch_type * BPatch::createUnion( const char * name,
1013 BPatch_Vector<char *> fieldNames,
1014 BPatch_Vector<BPatch_type *> fieldTypes)
1017 int offset, size, newsize;
1018 offset = size = newsize = 0;
1020 if (fieldNames.size() != fieldTypes.size()) {
1024 // Compute the size of the union
1025 for (i=0; i < fieldTypes.size(); i++) {
1026 BPatch_type *type = fieldTypes[i];
1027 newsize = type->getSize();
1028 if(size < newsize) size = newsize;
1031 BPatch_type * newType = new BPatch_type(name, BPatch_union, size);
1032 if (!newType) return NULL;
1034 APITypes->addType(newType);
1036 // ADD components to type
1037 for (i=0; i < fieldNames.size(); i++) {
1038 BPatch_type *type = fieldTypes[i];
1039 size = type->getSize();
1040 newType->addField(fieldNames[i], type->getDataClass(), type, offset, size);
1047 * createArray for Arrays and SymTypeRanges
1049 * This function is a wrapper for the BPatch_type constructors for API/User
1052 * It returns a pointer to a BPatch_type that was added to the APITypes
1055 BPatch_type * BPatch::createArray( const char * name, BPatch_type * ptr,
1056 unsigned int low, unsigned int hi)
1059 BPatch_type * newType;
1064 newType = new BPatch_type(name, BPatch_array , ptr, low, hi);
1065 if (!newType) return NULL;
1068 APITypes->addType(newType);
1074 * createPointer for BPatch_pointers
1076 * This function is a wrapper for the BPatch_type constructors for API/User
1079 * It returns a pointer to a BPatch_type that was added to the APITypes
1082 BPatch_type * BPatch::createPointer(const char * name, BPatch_type * ptr,
1086 BPatch_type * newType = new BPatch_type(name, ptr, size);
1087 if(!newType) return NULL;
1089 APITypes->addType(newType);
1095 * createScalar for scalars with a size and no range
1097 * This function is a wrapper for the BPatch_type constructors for API/User
1100 * It returns a pointer to a BPatch_type that was added to the APITypes
1104 BPatch_type * BPatch::createScalar( const char * name, int size)
1106 BPatch_type * newType = new BPatch_type(name, BPatch_scalar, size);
1107 if (!newType) return NULL;
1109 APITypes->addType(newType);
1115 * createType for typedefs
1117 * This function is a wrapper for the BPatch_type constructors for API/User
1120 * It returns a pointer to a BPatch_type that was added to the APITypes
1123 BPatch_type * BPatch::createTypedef( const char * name, BPatch_type * ptr)
1125 BPatch_type * newType = new BPatch_type(name, ptr);
1127 if (!newType) return NULL;
1129 APITypes->addType(newType);