xref: /aosp_15_r20/external/oj-libjdwp/src/share/back/SDE.c (revision e82f7db8c62aed3c168547abe4f9f4aeceaebfc7)
1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker  * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
3*e82f7db8SAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*e82f7db8SAndroid Build Coastguard Worker  *
5*e82f7db8SAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
6*e82f7db8SAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
7*e82f7db8SAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
8*e82f7db8SAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
9*e82f7db8SAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
10*e82f7db8SAndroid Build Coastguard Worker  *
11*e82f7db8SAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
12*e82f7db8SAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e82f7db8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*e82f7db8SAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
15*e82f7db8SAndroid Build Coastguard Worker  * accompanied this code).
16*e82f7db8SAndroid Build Coastguard Worker  *
17*e82f7db8SAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
18*e82f7db8SAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
19*e82f7db8SAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*e82f7db8SAndroid Build Coastguard Worker  *
21*e82f7db8SAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22*e82f7db8SAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
23*e82f7db8SAndroid Build Coastguard Worker  * questions.
24*e82f7db8SAndroid Build Coastguard Worker  */
25*e82f7db8SAndroid Build Coastguard Worker 
26*e82f7db8SAndroid Build Coastguard Worker #include <setjmp.h>
27*e82f7db8SAndroid Build Coastguard Worker 
28*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
29*e82f7db8SAndroid Build Coastguard Worker #include "SDE.h"
30*e82f7db8SAndroid Build Coastguard Worker 
31*e82f7db8SAndroid Build Coastguard Worker #ifdef __APPLE__
32*e82f7db8SAndroid Build Coastguard Worker /* use setjmp/longjmp versions that do not save/restore the signal mask */
33*e82f7db8SAndroid Build Coastguard Worker #define setjmp _setjmp
34*e82f7db8SAndroid Build Coastguard Worker #define longjmp _longjmp
35*e82f7db8SAndroid Build Coastguard Worker #endif
36*e82f7db8SAndroid Build Coastguard Worker 
37*e82f7db8SAndroid Build Coastguard Worker /**
38*e82f7db8SAndroid Build Coastguard Worker  * This SourceDebugExtension code does not
39*e82f7db8SAndroid Build Coastguard Worker  * allow concurrent translation - due to caching method.
40*e82f7db8SAndroid Build Coastguard Worker  * A separate thread setting the default stratum ID
41*e82f7db8SAndroid Build Coastguard Worker  * is, however, fine.
42*e82f7db8SAndroid Build Coastguard Worker  */
43*e82f7db8SAndroid Build Coastguard Worker 
44*e82f7db8SAndroid Build Coastguard Worker #define INIT_SIZE_FILE 10
45*e82f7db8SAndroid Build Coastguard Worker #define INIT_SIZE_LINE 100
46*e82f7db8SAndroid Build Coastguard Worker #define INIT_SIZE_STRATUM 3
47*e82f7db8SAndroid Build Coastguard Worker 
48*e82f7db8SAndroid Build Coastguard Worker #define BASE_STRATUM_NAME "Java"
49*e82f7db8SAndroid Build Coastguard Worker 
50*e82f7db8SAndroid Build Coastguard Worker #define null NULL
51*e82f7db8SAndroid Build Coastguard Worker #define true JNI_TRUE
52*e82f7db8SAndroid Build Coastguard Worker #define false JNI_FALSE
53*e82f7db8SAndroid Build Coastguard Worker #define String char *
54*e82f7db8SAndroid Build Coastguard Worker #define private static
55*e82f7db8SAndroid Build Coastguard Worker 
56*e82f7db8SAndroid Build Coastguard Worker typedef struct {
57*e82f7db8SAndroid Build Coastguard Worker   int fileId;
58*e82f7db8SAndroid Build Coastguard Worker   String sourceName;
59*e82f7db8SAndroid Build Coastguard Worker   String sourcePath; // do not read - use accessor
60*e82f7db8SAndroid Build Coastguard Worker   int isConverted;
61*e82f7db8SAndroid Build Coastguard Worker } FileTableRecord;
62*e82f7db8SAndroid Build Coastguard Worker 
63*e82f7db8SAndroid Build Coastguard Worker typedef struct {
64*e82f7db8SAndroid Build Coastguard Worker     int jplsStart;
65*e82f7db8SAndroid Build Coastguard Worker     int jplsEnd;
66*e82f7db8SAndroid Build Coastguard Worker     int jplsLineInc;
67*e82f7db8SAndroid Build Coastguard Worker     int njplsStart;
68*e82f7db8SAndroid Build Coastguard Worker     int njplsEnd;
69*e82f7db8SAndroid Build Coastguard Worker     int fileId;
70*e82f7db8SAndroid Build Coastguard Worker } LineTableRecord;
71*e82f7db8SAndroid Build Coastguard Worker 
72*e82f7db8SAndroid Build Coastguard Worker typedef struct {
73*e82f7db8SAndroid Build Coastguard Worker     String id;
74*e82f7db8SAndroid Build Coastguard Worker     int fileIndex;
75*e82f7db8SAndroid Build Coastguard Worker     int lineIndex;
76*e82f7db8SAndroid Build Coastguard Worker } StratumTableRecord;
77*e82f7db8SAndroid Build Coastguard Worker 
78*e82f7db8SAndroid Build Coastguard Worker /* back-end wide value for default stratum */
79*e82f7db8SAndroid Build Coastguard Worker private String globalDefaultStratumId = null;
80*e82f7db8SAndroid Build Coastguard Worker 
81*e82f7db8SAndroid Build Coastguard Worker /* reference type default */
82*e82f7db8SAndroid Build Coastguard Worker private String defaultStratumId = null;
83*e82f7db8SAndroid Build Coastguard Worker 
84*e82f7db8SAndroid Build Coastguard Worker private jclass cachedClass = NULL;
85*e82f7db8SAndroid Build Coastguard Worker 
86*e82f7db8SAndroid Build Coastguard Worker private FileTableRecord* fileTable;
87*e82f7db8SAndroid Build Coastguard Worker private LineTableRecord* lineTable;
88*e82f7db8SAndroid Build Coastguard Worker private StratumTableRecord* stratumTable;
89*e82f7db8SAndroid Build Coastguard Worker 
90*e82f7db8SAndroid Build Coastguard Worker private int fileTableSize;
91*e82f7db8SAndroid Build Coastguard Worker private int lineTableSize;
92*e82f7db8SAndroid Build Coastguard Worker private int stratumTableSize;
93*e82f7db8SAndroid Build Coastguard Worker 
94*e82f7db8SAndroid Build Coastguard Worker private int fileIndex;
95*e82f7db8SAndroid Build Coastguard Worker private int lineIndex;
96*e82f7db8SAndroid Build Coastguard Worker private int stratumIndex = 0;
97*e82f7db8SAndroid Build Coastguard Worker private int currentFileId;
98*e82f7db8SAndroid Build Coastguard Worker 
99*e82f7db8SAndroid Build Coastguard Worker private int defaultStratumIndex;
100*e82f7db8SAndroid Build Coastguard Worker private int baseStratumIndex;
101*e82f7db8SAndroid Build Coastguard Worker private char* sdePos;
102*e82f7db8SAndroid Build Coastguard Worker 
103*e82f7db8SAndroid Build Coastguard Worker private char* jplsFilename = null;
104*e82f7db8SAndroid Build Coastguard Worker private char* NullString = null;
105*e82f7db8SAndroid Build Coastguard Worker 
106*e82f7db8SAndroid Build Coastguard Worker /* mangled in parse, cannot be parsed.  Must be kept. */
107*e82f7db8SAndroid Build Coastguard Worker private String sourceDebugExtension;
108*e82f7db8SAndroid Build Coastguard Worker 
109*e82f7db8SAndroid Build Coastguard Worker private jboolean sourceMapIsValid;
110*e82f7db8SAndroid Build Coastguard Worker 
111*e82f7db8SAndroid Build Coastguard Worker private jmp_buf jmp_buf_env;
112*e82f7db8SAndroid Build Coastguard Worker 
113*e82f7db8SAndroid Build Coastguard Worker private int stratumTableIndex(String stratumId);
114*e82f7db8SAndroid Build Coastguard Worker private int stiLineTableIndex(int sti, int jplsLine);
115*e82f7db8SAndroid Build Coastguard Worker private int stiLineNumber(int sti, int lti, int jplsLine);
116*e82f7db8SAndroid Build Coastguard Worker private void decode(void);
117*e82f7db8SAndroid Build Coastguard Worker private void ignoreWhite(void);
118*e82f7db8SAndroid Build Coastguard Worker private jboolean isValid(void);
119*e82f7db8SAndroid Build Coastguard Worker 
120*e82f7db8SAndroid Build Coastguard Worker     private void
loadDebugInfo(JNIEnv * env,jclass clazz)121*e82f7db8SAndroid Build Coastguard Worker     loadDebugInfo(JNIEnv *env, jclass clazz) {
122*e82f7db8SAndroid Build Coastguard Worker 
123*e82f7db8SAndroid Build Coastguard Worker         if (!isSameObject(env, clazz, cachedClass)) {
124*e82f7db8SAndroid Build Coastguard Worker             /* Not the same - swap out the info */
125*e82f7db8SAndroid Build Coastguard Worker 
126*e82f7db8SAndroid Build Coastguard Worker             /* Delete existing info */
127*e82f7db8SAndroid Build Coastguard Worker             if ( cachedClass != null ) {
128*e82f7db8SAndroid Build Coastguard Worker                 tossGlobalRef(env, &cachedClass);
129*e82f7db8SAndroid Build Coastguard Worker                 cachedClass = null;
130*e82f7db8SAndroid Build Coastguard Worker             }
131*e82f7db8SAndroid Build Coastguard Worker             if ( sourceDebugExtension!=null ) {
132*e82f7db8SAndroid Build Coastguard Worker                 jvmtiDeallocate(sourceDebugExtension);
133*e82f7db8SAndroid Build Coastguard Worker             }
134*e82f7db8SAndroid Build Coastguard Worker             sourceDebugExtension = null;
135*e82f7db8SAndroid Build Coastguard Worker 
136*e82f7db8SAndroid Build Coastguard Worker             /* Init info */
137*e82f7db8SAndroid Build Coastguard Worker             lineTable = null;
138*e82f7db8SAndroid Build Coastguard Worker             fileTable = null;
139*e82f7db8SAndroid Build Coastguard Worker             stratumTable = null;
140*e82f7db8SAndroid Build Coastguard Worker             lineTableSize = 0;
141*e82f7db8SAndroid Build Coastguard Worker             fileTableSize = 0;
142*e82f7db8SAndroid Build Coastguard Worker             stratumTableSize = 0;
143*e82f7db8SAndroid Build Coastguard Worker             fileIndex = 0;
144*e82f7db8SAndroid Build Coastguard Worker             lineIndex = 0;
145*e82f7db8SAndroid Build Coastguard Worker             stratumIndex = 0;
146*e82f7db8SAndroid Build Coastguard Worker             currentFileId = 0;
147*e82f7db8SAndroid Build Coastguard Worker             defaultStratumId = null;
148*e82f7db8SAndroid Build Coastguard Worker             defaultStratumIndex = -1;
149*e82f7db8SAndroid Build Coastguard Worker             baseStratumIndex = -2; /* so as not to match -1 above */
150*e82f7db8SAndroid Build Coastguard Worker             sourceMapIsValid = false;
151*e82f7db8SAndroid Build Coastguard Worker 
152*e82f7db8SAndroid Build Coastguard Worker             if (getSourceDebugExtension(clazz, &sourceDebugExtension) ==
153*e82f7db8SAndroid Build Coastguard Worker                 JVMTI_ERROR_NONE) {
154*e82f7db8SAndroid Build Coastguard Worker                 sdePos = sourceDebugExtension;
155*e82f7db8SAndroid Build Coastguard Worker                 if (setjmp(jmp_buf_env) == 0) {
156*e82f7db8SAndroid Build Coastguard Worker                     /* this is the initial (non-error) case, do parse */
157*e82f7db8SAndroid Build Coastguard Worker                     decode();
158*e82f7db8SAndroid Build Coastguard Worker                 }
159*e82f7db8SAndroid Build Coastguard Worker             }
160*e82f7db8SAndroid Build Coastguard Worker 
161*e82f7db8SAndroid Build Coastguard Worker             cachedClass = null;
162*e82f7db8SAndroid Build Coastguard Worker             saveGlobalRef(env, clazz, &cachedClass);
163*e82f7db8SAndroid Build Coastguard Worker         }
164*e82f7db8SAndroid Build Coastguard Worker     }
165*e82f7db8SAndroid Build Coastguard Worker 
166*e82f7db8SAndroid Build Coastguard Worker     /* Return 1 if match, 0 if no match */
167*e82f7db8SAndroid Build Coastguard Worker     private int
patternMatch(char * classname,const char * pattern)168*e82f7db8SAndroid Build Coastguard Worker     patternMatch(char *classname, const char *pattern) {
169*e82f7db8SAndroid Build Coastguard Worker         int pattLen;
170*e82f7db8SAndroid Build Coastguard Worker         int compLen;
171*e82f7db8SAndroid Build Coastguard Worker         char *start;
172*e82f7db8SAndroid Build Coastguard Worker         int offset;
173*e82f7db8SAndroid Build Coastguard Worker 
174*e82f7db8SAndroid Build Coastguard Worker         if (pattern == NULL || classname == NULL) {
175*e82f7db8SAndroid Build Coastguard Worker             return 0;
176*e82f7db8SAndroid Build Coastguard Worker         }
177*e82f7db8SAndroid Build Coastguard Worker         pattLen = (int)strlen(pattern);
178*e82f7db8SAndroid Build Coastguard Worker 
179*e82f7db8SAndroid Build Coastguard Worker         if ((pattern[0] != '*') && (pattern[pattLen-1] != '*')) {
180*e82f7db8SAndroid Build Coastguard Worker             return strcmp(pattern, classname) == 0;
181*e82f7db8SAndroid Build Coastguard Worker         }
182*e82f7db8SAndroid Build Coastguard Worker 
183*e82f7db8SAndroid Build Coastguard Worker         compLen = pattLen - 1;
184*e82f7db8SAndroid Build Coastguard Worker         offset = (int)strlen(classname) - compLen;
185*e82f7db8SAndroid Build Coastguard Worker         if (offset < 0) {
186*e82f7db8SAndroid Build Coastguard Worker             return 0;
187*e82f7db8SAndroid Build Coastguard Worker         }
188*e82f7db8SAndroid Build Coastguard Worker         if (pattern[0] == '*') {
189*e82f7db8SAndroid Build Coastguard Worker             pattern++;
190*e82f7db8SAndroid Build Coastguard Worker             start = classname + offset;
191*e82f7db8SAndroid Build Coastguard Worker         }  else {
192*e82f7db8SAndroid Build Coastguard Worker             start = classname;
193*e82f7db8SAndroid Build Coastguard Worker         }
194*e82f7db8SAndroid Build Coastguard Worker         return strncmp(pattern, start, compLen) == 0;
195*e82f7db8SAndroid Build Coastguard Worker     }
196*e82f7db8SAndroid Build Coastguard Worker 
197*e82f7db8SAndroid Build Coastguard Worker     /**
198*e82f7db8SAndroid Build Coastguard Worker      * Return 1 if p1 is a SourceName for stratum sti,
199*e82f7db8SAndroid Build Coastguard Worker      * else, return 0.
200*e82f7db8SAndroid Build Coastguard Worker      */
201*e82f7db8SAndroid Build Coastguard Worker     private int
searchOneSourceName(int sti,char * p1)202*e82f7db8SAndroid Build Coastguard Worker     searchOneSourceName(int sti, char *p1) {
203*e82f7db8SAndroid Build Coastguard Worker         int fileIndexStart = stratumTable[sti].fileIndex;
204*e82f7db8SAndroid Build Coastguard Worker         /* one past end */
205*e82f7db8SAndroid Build Coastguard Worker         int fileIndexEnd = stratumTable[sti+1].fileIndex;
206*e82f7db8SAndroid Build Coastguard Worker         int ii;
207*e82f7db8SAndroid Build Coastguard Worker         for (ii = fileIndexStart; ii < fileIndexEnd; ++ii) {
208*e82f7db8SAndroid Build Coastguard Worker             if (patternMatch(fileTable[ii].sourceName, p1)) {
209*e82f7db8SAndroid Build Coastguard Worker               return 1;
210*e82f7db8SAndroid Build Coastguard Worker             }
211*e82f7db8SAndroid Build Coastguard Worker         }
212*e82f7db8SAndroid Build Coastguard Worker         return 0;
213*e82f7db8SAndroid Build Coastguard Worker     }
214*e82f7db8SAndroid Build Coastguard Worker 
215*e82f7db8SAndroid Build Coastguard Worker     /**
216*e82f7db8SAndroid Build Coastguard Worker      * Return 1 if p1 is a SourceName for any stratum
217*e82f7db8SAndroid Build Coastguard Worker      * else, return 0.
218*e82f7db8SAndroid Build Coastguard Worker      */
searchAllSourceNames(JNIEnv * env,jclass clazz,char * p1)219*e82f7db8SAndroid Build Coastguard Worker     int searchAllSourceNames(JNIEnv *env,
220*e82f7db8SAndroid Build Coastguard Worker                              jclass clazz,
221*e82f7db8SAndroid Build Coastguard Worker                              char *p1) {
222*e82f7db8SAndroid Build Coastguard Worker         int ii;
223*e82f7db8SAndroid Build Coastguard Worker         loadDebugInfo(env, clazz);
224*e82f7db8SAndroid Build Coastguard Worker         if (!isValid()) {
225*e82f7db8SAndroid Build Coastguard Worker           return 0; /* no SDE or not SourceMap */
226*e82f7db8SAndroid Build Coastguard Worker         }
227*e82f7db8SAndroid Build Coastguard Worker 
228*e82f7db8SAndroid Build Coastguard Worker         for (ii = 0; ii < stratumIndex - 1; ++ii) {
229*e82f7db8SAndroid Build Coastguard Worker             if (searchOneSourceName(ii, p1) == 1) {
230*e82f7db8SAndroid Build Coastguard Worker                 return 1;
231*e82f7db8SAndroid Build Coastguard Worker             }
232*e82f7db8SAndroid Build Coastguard Worker         }
233*e82f7db8SAndroid Build Coastguard Worker         return 0;
234*e82f7db8SAndroid Build Coastguard Worker     }
235*e82f7db8SAndroid Build Coastguard Worker 
236*e82f7db8SAndroid Build Coastguard Worker     /**
237*e82f7db8SAndroid Build Coastguard Worker      * Convert a line number table, as returned by the JVMTI
238*e82f7db8SAndroid Build Coastguard Worker      * function GetLineNumberTable, to one for another stratum.
239*e82f7db8SAndroid Build Coastguard Worker      * Conversion is by overwrite.
240*e82f7db8SAndroid Build Coastguard Worker      * Actual line numbers are not returned - just a unique
241*e82f7db8SAndroid Build Coastguard Worker      * number (file ID in top 16 bits, line number in
242*e82f7db8SAndroid Build Coastguard Worker      * bottom 16 bits) - this is all stepping needs.
243*e82f7db8SAndroid Build Coastguard Worker      */
244*e82f7db8SAndroid Build Coastguard Worker     void
convertLineNumberTable(JNIEnv * env,jclass clazz,jint * entryCountPtr,jvmtiLineNumberEntry ** tablePtr)245*e82f7db8SAndroid Build Coastguard Worker     convertLineNumberTable(JNIEnv *env, jclass clazz,
246*e82f7db8SAndroid Build Coastguard Worker                            jint *entryCountPtr,
247*e82f7db8SAndroid Build Coastguard Worker                            jvmtiLineNumberEntry **tablePtr) {
248*e82f7db8SAndroid Build Coastguard Worker         jvmtiLineNumberEntry *fromEntry = *tablePtr;
249*e82f7db8SAndroid Build Coastguard Worker         jvmtiLineNumberEntry *toEntry = *tablePtr;
250*e82f7db8SAndroid Build Coastguard Worker         int cnt = *entryCountPtr;
251*e82f7db8SAndroid Build Coastguard Worker         int lastLn = 0;
252*e82f7db8SAndroid Build Coastguard Worker         int sti;
253*e82f7db8SAndroid Build Coastguard Worker 
254*e82f7db8SAndroid Build Coastguard Worker         loadDebugInfo(env, clazz);
255*e82f7db8SAndroid Build Coastguard Worker         if (!isValid()) {
256*e82f7db8SAndroid Build Coastguard Worker             return; /* no SDE or not SourceMap - return unchanged */
257*e82f7db8SAndroid Build Coastguard Worker         }
258*e82f7db8SAndroid Build Coastguard Worker         sti = stratumTableIndex(globalDefaultStratumId);
259*e82f7db8SAndroid Build Coastguard Worker         if (sti == baseStratumIndex) {
260*e82f7db8SAndroid Build Coastguard Worker             return; /* Java stratum - return unchanged */
261*e82f7db8SAndroid Build Coastguard Worker         }
262*e82f7db8SAndroid Build Coastguard Worker         LOG_MISC(("SDE is re-ordering the line table"));
263*e82f7db8SAndroid Build Coastguard Worker         for (; cnt-->0; ++fromEntry) {
264*e82f7db8SAndroid Build Coastguard Worker             int jplsLine = fromEntry->line_number;
265*e82f7db8SAndroid Build Coastguard Worker             int lti = stiLineTableIndex(sti, jplsLine);
266*e82f7db8SAndroid Build Coastguard Worker             if (lti >= 0) {
267*e82f7db8SAndroid Build Coastguard Worker                 int fileId = lineTable[lti].fileId;
268*e82f7db8SAndroid Build Coastguard Worker                 int ln = stiLineNumber(sti, lti, jplsLine);
269*e82f7db8SAndroid Build Coastguard Worker                 ln += (fileId << 16); /* create line hash */
270*e82f7db8SAndroid Build Coastguard Worker                 if (ln != lastLn) {
271*e82f7db8SAndroid Build Coastguard Worker                     lastLn = ln;
272*e82f7db8SAndroid Build Coastguard Worker                     toEntry->start_location = fromEntry->start_location;
273*e82f7db8SAndroid Build Coastguard Worker                     toEntry->line_number = ln;
274*e82f7db8SAndroid Build Coastguard Worker                     ++toEntry;
275*e82f7db8SAndroid Build Coastguard Worker                 }
276*e82f7db8SAndroid Build Coastguard Worker             }
277*e82f7db8SAndroid Build Coastguard Worker         }
278*e82f7db8SAndroid Build Coastguard Worker         /*LINTED*/
279*e82f7db8SAndroid Build Coastguard Worker         *entryCountPtr = (int)(toEntry - *tablePtr);
280*e82f7db8SAndroid Build Coastguard Worker     }
281*e82f7db8SAndroid Build Coastguard Worker 
282*e82f7db8SAndroid Build Coastguard Worker     /**
283*e82f7db8SAndroid Build Coastguard Worker      * Set back-end wide default stratum ID .
284*e82f7db8SAndroid Build Coastguard Worker      */
285*e82f7db8SAndroid Build Coastguard Worker     void
setGlobalStratumId(char * id)286*e82f7db8SAndroid Build Coastguard Worker     setGlobalStratumId(char *id) {
287*e82f7db8SAndroid Build Coastguard Worker         globalDefaultStratumId = id;
288*e82f7db8SAndroid Build Coastguard Worker     }
289*e82f7db8SAndroid Build Coastguard Worker 
290*e82f7db8SAndroid Build Coastguard Worker 
syntax(String msg)291*e82f7db8SAndroid Build Coastguard Worker     private void syntax(String msg) {
292*e82f7db8SAndroid Build Coastguard Worker         char buf[200];
293*e82f7db8SAndroid Build Coastguard Worker         (void)snprintf(buf, sizeof(buf),
294*e82f7db8SAndroid Build Coastguard Worker                 "bad SourceDebugExtension syntax - position %d - %s\n",
295*e82f7db8SAndroid Build Coastguard Worker                 /*LINTED*/
296*e82f7db8SAndroid Build Coastguard Worker                 (int)(sdePos-sourceDebugExtension),
297*e82f7db8SAndroid Build Coastguard Worker                 msg);
298*e82f7db8SAndroid Build Coastguard Worker         JDI_ASSERT_FAILED(buf);
299*e82f7db8SAndroid Build Coastguard Worker 
300*e82f7db8SAndroid Build Coastguard Worker         longjmp(jmp_buf_env, 1);  /* abort parse */
301*e82f7db8SAndroid Build Coastguard Worker     }
302*e82f7db8SAndroid Build Coastguard Worker 
sdePeek(void)303*e82f7db8SAndroid Build Coastguard Worker     private char sdePeek(void) {
304*e82f7db8SAndroid Build Coastguard Worker         if (*sdePos == 0) {
305*e82f7db8SAndroid Build Coastguard Worker             syntax("unexpected EOF");
306*e82f7db8SAndroid Build Coastguard Worker         }
307*e82f7db8SAndroid Build Coastguard Worker         return *sdePos;
308*e82f7db8SAndroid Build Coastguard Worker     }
309*e82f7db8SAndroid Build Coastguard Worker 
sdeRead(void)310*e82f7db8SAndroid Build Coastguard Worker     private char sdeRead(void) {
311*e82f7db8SAndroid Build Coastguard Worker         if (*sdePos == 0) {
312*e82f7db8SAndroid Build Coastguard Worker             syntax("unexpected EOF");
313*e82f7db8SAndroid Build Coastguard Worker         }
314*e82f7db8SAndroid Build Coastguard Worker         return *sdePos++;
315*e82f7db8SAndroid Build Coastguard Worker     }
316*e82f7db8SAndroid Build Coastguard Worker 
sdeAdvance(void)317*e82f7db8SAndroid Build Coastguard Worker     private void sdeAdvance(void) {
318*e82f7db8SAndroid Build Coastguard Worker         sdePos++;
319*e82f7db8SAndroid Build Coastguard Worker     }
320*e82f7db8SAndroid Build Coastguard Worker 
assureLineTableSize(void)321*e82f7db8SAndroid Build Coastguard Worker     private void assureLineTableSize(void) {
322*e82f7db8SAndroid Build Coastguard Worker         if (lineIndex >= lineTableSize) {
323*e82f7db8SAndroid Build Coastguard Worker             size_t allocSize;
324*e82f7db8SAndroid Build Coastguard Worker             LineTableRecord* new_lineTable;
325*e82f7db8SAndroid Build Coastguard Worker             int new_lineTableSize;
326*e82f7db8SAndroid Build Coastguard Worker 
327*e82f7db8SAndroid Build Coastguard Worker             new_lineTableSize = lineTableSize == 0?
328*e82f7db8SAndroid Build Coastguard Worker                                   INIT_SIZE_LINE :
329*e82f7db8SAndroid Build Coastguard Worker                                   lineTableSize * 2;
330*e82f7db8SAndroid Build Coastguard Worker             allocSize = new_lineTableSize * (int)sizeof(LineTableRecord);
331*e82f7db8SAndroid Build Coastguard Worker             new_lineTable = jvmtiAllocate((jint)allocSize);
332*e82f7db8SAndroid Build Coastguard Worker             if ( new_lineTable == NULL ) {
333*e82f7db8SAndroid Build Coastguard Worker                 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE line table");
334*e82f7db8SAndroid Build Coastguard Worker             }
335*e82f7db8SAndroid Build Coastguard Worker             if ( lineTable!=NULL ) {
336*e82f7db8SAndroid Build Coastguard Worker                 (void)memcpy(new_lineTable, lineTable,
337*e82f7db8SAndroid Build Coastguard Worker                         lineTableSize * (int)sizeof(LineTableRecord));
338*e82f7db8SAndroid Build Coastguard Worker                 jvmtiDeallocate(lineTable);
339*e82f7db8SAndroid Build Coastguard Worker             }
340*e82f7db8SAndroid Build Coastguard Worker             lineTable     = new_lineTable;
341*e82f7db8SAndroid Build Coastguard Worker             lineTableSize = new_lineTableSize;
342*e82f7db8SAndroid Build Coastguard Worker         }
343*e82f7db8SAndroid Build Coastguard Worker     }
344*e82f7db8SAndroid Build Coastguard Worker 
assureFileTableSize(void)345*e82f7db8SAndroid Build Coastguard Worker     private void assureFileTableSize(void) {
346*e82f7db8SAndroid Build Coastguard Worker         if (fileIndex >= fileTableSize) {
347*e82f7db8SAndroid Build Coastguard Worker             size_t allocSize;
348*e82f7db8SAndroid Build Coastguard Worker             FileTableRecord* new_fileTable;
349*e82f7db8SAndroid Build Coastguard Worker             int new_fileTableSize;
350*e82f7db8SAndroid Build Coastguard Worker 
351*e82f7db8SAndroid Build Coastguard Worker             new_fileTableSize = fileTableSize == 0?
352*e82f7db8SAndroid Build Coastguard Worker                                   INIT_SIZE_FILE :
353*e82f7db8SAndroid Build Coastguard Worker                                   fileTableSize * 2;
354*e82f7db8SAndroid Build Coastguard Worker             allocSize = new_fileTableSize * (int)sizeof(FileTableRecord);
355*e82f7db8SAndroid Build Coastguard Worker             new_fileTable = jvmtiAllocate((jint)allocSize);
356*e82f7db8SAndroid Build Coastguard Worker             if ( new_fileTable == NULL ) {
357*e82f7db8SAndroid Build Coastguard Worker                 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE file table");
358*e82f7db8SAndroid Build Coastguard Worker             }
359*e82f7db8SAndroid Build Coastguard Worker             if ( fileTable!=NULL ) {
360*e82f7db8SAndroid Build Coastguard Worker                 (void)memcpy(new_fileTable, fileTable,
361*e82f7db8SAndroid Build Coastguard Worker                         fileTableSize * (int)sizeof(FileTableRecord));
362*e82f7db8SAndroid Build Coastguard Worker                 jvmtiDeallocate(fileTable);
363*e82f7db8SAndroid Build Coastguard Worker             }
364*e82f7db8SAndroid Build Coastguard Worker             fileTable     = new_fileTable;
365*e82f7db8SAndroid Build Coastguard Worker             fileTableSize = new_fileTableSize;
366*e82f7db8SAndroid Build Coastguard Worker         }
367*e82f7db8SAndroid Build Coastguard Worker     }
368*e82f7db8SAndroid Build Coastguard Worker 
assureStratumTableSize(void)369*e82f7db8SAndroid Build Coastguard Worker     private void assureStratumTableSize(void) {
370*e82f7db8SAndroid Build Coastguard Worker         if (stratumIndex >= stratumTableSize) {
371*e82f7db8SAndroid Build Coastguard Worker             size_t allocSize;
372*e82f7db8SAndroid Build Coastguard Worker             StratumTableRecord* new_stratumTable;
373*e82f7db8SAndroid Build Coastguard Worker             int new_stratumTableSize;
374*e82f7db8SAndroid Build Coastguard Worker 
375*e82f7db8SAndroid Build Coastguard Worker             new_stratumTableSize = stratumTableSize == 0?
376*e82f7db8SAndroid Build Coastguard Worker                                   INIT_SIZE_STRATUM :
377*e82f7db8SAndroid Build Coastguard Worker                                   stratumTableSize * 2;
378*e82f7db8SAndroid Build Coastguard Worker             allocSize = new_stratumTableSize * (int)sizeof(StratumTableRecord);
379*e82f7db8SAndroid Build Coastguard Worker             new_stratumTable = jvmtiAllocate((jint)allocSize);
380*e82f7db8SAndroid Build Coastguard Worker             if ( new_stratumTable == NULL ) {
381*e82f7db8SAndroid Build Coastguard Worker                 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY, "SDE stratum table");
382*e82f7db8SAndroid Build Coastguard Worker             }
383*e82f7db8SAndroid Build Coastguard Worker             if ( stratumTable!=NULL ) {
384*e82f7db8SAndroid Build Coastguard Worker                 (void)memcpy(new_stratumTable, stratumTable,
385*e82f7db8SAndroid Build Coastguard Worker                         stratumTableSize * (int)sizeof(StratumTableRecord));
386*e82f7db8SAndroid Build Coastguard Worker                 jvmtiDeallocate(stratumTable);
387*e82f7db8SAndroid Build Coastguard Worker             }
388*e82f7db8SAndroid Build Coastguard Worker             stratumTable     = new_stratumTable;
389*e82f7db8SAndroid Build Coastguard Worker             stratumTableSize = new_stratumTableSize;
390*e82f7db8SAndroid Build Coastguard Worker         }
391*e82f7db8SAndroid Build Coastguard Worker     }
392*e82f7db8SAndroid Build Coastguard Worker 
readLine(void)393*e82f7db8SAndroid Build Coastguard Worker     private String readLine(void) {
394*e82f7db8SAndroid Build Coastguard Worker         char *initialPos;
395*e82f7db8SAndroid Build Coastguard Worker         char ch;
396*e82f7db8SAndroid Build Coastguard Worker 
397*e82f7db8SAndroid Build Coastguard Worker         ignoreWhite();
398*e82f7db8SAndroid Build Coastguard Worker         initialPos = sdePos;
399*e82f7db8SAndroid Build Coastguard Worker         while (((ch = *sdePos) != '\n') && (ch != '\r')) {
400*e82f7db8SAndroid Build Coastguard Worker             if (ch == 0) {
401*e82f7db8SAndroid Build Coastguard Worker                 syntax("unexpected EOF");
402*e82f7db8SAndroid Build Coastguard Worker             }
403*e82f7db8SAndroid Build Coastguard Worker             ++sdePos;
404*e82f7db8SAndroid Build Coastguard Worker         }
405*e82f7db8SAndroid Build Coastguard Worker         *sdePos++ = 0; /* null terminate string - mangles SDE */
406*e82f7db8SAndroid Build Coastguard Worker 
407*e82f7db8SAndroid Build Coastguard Worker         /* check for CR LF */
408*e82f7db8SAndroid Build Coastguard Worker         if ((ch == '\r') && (*sdePos == '\n')) {
409*e82f7db8SAndroid Build Coastguard Worker             ++sdePos;
410*e82f7db8SAndroid Build Coastguard Worker         }
411*e82f7db8SAndroid Build Coastguard Worker         ignoreWhite(); /* leading white */
412*e82f7db8SAndroid Build Coastguard Worker         return initialPos;
413*e82f7db8SAndroid Build Coastguard Worker     }
414*e82f7db8SAndroid Build Coastguard Worker 
defaultStratumTableIndex(void)415*e82f7db8SAndroid Build Coastguard Worker     private int defaultStratumTableIndex(void) {
416*e82f7db8SAndroid Build Coastguard Worker         if ((defaultStratumIndex == -1) && (defaultStratumId != null)) {
417*e82f7db8SAndroid Build Coastguard Worker             defaultStratumIndex =
418*e82f7db8SAndroid Build Coastguard Worker                 stratumTableIndex(defaultStratumId);
419*e82f7db8SAndroid Build Coastguard Worker         }
420*e82f7db8SAndroid Build Coastguard Worker         return defaultStratumIndex;
421*e82f7db8SAndroid Build Coastguard Worker     }
422*e82f7db8SAndroid Build Coastguard Worker 
stratumTableIndex(String stratumId)423*e82f7db8SAndroid Build Coastguard Worker     private int stratumTableIndex(String stratumId) {
424*e82f7db8SAndroid Build Coastguard Worker         int i;
425*e82f7db8SAndroid Build Coastguard Worker 
426*e82f7db8SAndroid Build Coastguard Worker         if (stratumId == null) {
427*e82f7db8SAndroid Build Coastguard Worker             return defaultStratumTableIndex();
428*e82f7db8SAndroid Build Coastguard Worker         }
429*e82f7db8SAndroid Build Coastguard Worker         for (i = 0; i < (stratumIndex-1); ++i) {
430*e82f7db8SAndroid Build Coastguard Worker             if (strcmp(stratumTable[i].id, stratumId) == 0) {
431*e82f7db8SAndroid Build Coastguard Worker                 return i;
432*e82f7db8SAndroid Build Coastguard Worker             }
433*e82f7db8SAndroid Build Coastguard Worker         }
434*e82f7db8SAndroid Build Coastguard Worker         return defaultStratumTableIndex();
435*e82f7db8SAndroid Build Coastguard Worker     }
436*e82f7db8SAndroid Build Coastguard Worker 
437*e82f7db8SAndroid Build Coastguard Worker 
438*e82f7db8SAndroid Build Coastguard Worker /*****************************
439*e82f7db8SAndroid Build Coastguard Worker  * below functions/methods are written to compile under either Java or C
440*e82f7db8SAndroid Build Coastguard Worker  *
441*e82f7db8SAndroid Build Coastguard Worker  * Needed support functions:
442*e82f7db8SAndroid Build Coastguard Worker  *   sdePeek()
443*e82f7db8SAndroid Build Coastguard Worker  *   sdeRead()
444*e82f7db8SAndroid Build Coastguard Worker  *   sdeAdvance()
445*e82f7db8SAndroid Build Coastguard Worker  *   readLine()
446*e82f7db8SAndroid Build Coastguard Worker  *   assureLineTableSize()
447*e82f7db8SAndroid Build Coastguard Worker  *   assureFileTableSize()
448*e82f7db8SAndroid Build Coastguard Worker  *   assureStratumTableSize()
449*e82f7db8SAndroid Build Coastguard Worker  *   syntax(String)
450*e82f7db8SAndroid Build Coastguard Worker  *
451*e82f7db8SAndroid Build Coastguard Worker  *   stratumTableIndex(String)
452*e82f7db8SAndroid Build Coastguard Worker  *
453*e82f7db8SAndroid Build Coastguard Worker  * Needed support variables:
454*e82f7db8SAndroid Build Coastguard Worker  *   lineTable
455*e82f7db8SAndroid Build Coastguard Worker  *   lineIndex
456*e82f7db8SAndroid Build Coastguard Worker  *   fileTable
457*e82f7db8SAndroid Build Coastguard Worker  *   fileIndex
458*e82f7db8SAndroid Build Coastguard Worker  *   currentFileId
459*e82f7db8SAndroid Build Coastguard Worker  *
460*e82f7db8SAndroid Build Coastguard Worker  * Needed types:
461*e82f7db8SAndroid Build Coastguard Worker  *   String
462*e82f7db8SAndroid Build Coastguard Worker  *
463*e82f7db8SAndroid Build Coastguard Worker  * Needed constants:
464*e82f7db8SAndroid Build Coastguard Worker  *   NullString
465*e82f7db8SAndroid Build Coastguard Worker  */
466*e82f7db8SAndroid Build Coastguard Worker 
ignoreWhite(void)467*e82f7db8SAndroid Build Coastguard Worker     private void ignoreWhite(void) {
468*e82f7db8SAndroid Build Coastguard Worker         char ch;
469*e82f7db8SAndroid Build Coastguard Worker 
470*e82f7db8SAndroid Build Coastguard Worker         while (((ch = sdePeek()) == ' ') || (ch == '\t')) {
471*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
472*e82f7db8SAndroid Build Coastguard Worker         }
473*e82f7db8SAndroid Build Coastguard Worker     }
474*e82f7db8SAndroid Build Coastguard Worker 
ignoreLine(void)475*e82f7db8SAndroid Build Coastguard Worker     private void ignoreLine(void) {
476*e82f7db8SAndroid Build Coastguard Worker         char ch;
477*e82f7db8SAndroid Build Coastguard Worker 
478*e82f7db8SAndroid Build Coastguard Worker         do {
479*e82f7db8SAndroid Build Coastguard Worker            ch = sdeRead();
480*e82f7db8SAndroid Build Coastguard Worker         } while ((ch != '\n') && (ch != '\r'));
481*e82f7db8SAndroid Build Coastguard Worker 
482*e82f7db8SAndroid Build Coastguard Worker         /* check for CR LF */
483*e82f7db8SAndroid Build Coastguard Worker         if ((ch == '\r') && (sdePeek() == '\n')) {
484*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
485*e82f7db8SAndroid Build Coastguard Worker         }
486*e82f7db8SAndroid Build Coastguard Worker         ignoreWhite(); /* leading white */
487*e82f7db8SAndroid Build Coastguard Worker     }
488*e82f7db8SAndroid Build Coastguard Worker 
readNumber(void)489*e82f7db8SAndroid Build Coastguard Worker     private int readNumber(void) {
490*e82f7db8SAndroid Build Coastguard Worker         int value = 0;
491*e82f7db8SAndroid Build Coastguard Worker         char ch;
492*e82f7db8SAndroid Build Coastguard Worker 
493*e82f7db8SAndroid Build Coastguard Worker         ignoreWhite();
494*e82f7db8SAndroid Build Coastguard Worker         while (((ch = sdePeek()) >= '0') && (ch <= '9')) {
495*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
496*e82f7db8SAndroid Build Coastguard Worker             value = (value * 10) + ch - '0';
497*e82f7db8SAndroid Build Coastguard Worker         }
498*e82f7db8SAndroid Build Coastguard Worker         ignoreWhite();
499*e82f7db8SAndroid Build Coastguard Worker         return value;
500*e82f7db8SAndroid Build Coastguard Worker     }
501*e82f7db8SAndroid Build Coastguard Worker 
storeFile(int fileId,String sourceName,String sourcePath)502*e82f7db8SAndroid Build Coastguard Worker     private void storeFile(int fileId, String sourceName, String sourcePath) {
503*e82f7db8SAndroid Build Coastguard Worker         assureFileTableSize();
504*e82f7db8SAndroid Build Coastguard Worker         fileTable[fileIndex].fileId = fileId;
505*e82f7db8SAndroid Build Coastguard Worker         fileTable[fileIndex].sourceName = sourceName;
506*e82f7db8SAndroid Build Coastguard Worker         fileTable[fileIndex].sourcePath = sourcePath;
507*e82f7db8SAndroid Build Coastguard Worker         ++fileIndex;
508*e82f7db8SAndroid Build Coastguard Worker     }
509*e82f7db8SAndroid Build Coastguard Worker 
fileLine(void)510*e82f7db8SAndroid Build Coastguard Worker     private void fileLine(void) {
511*e82f7db8SAndroid Build Coastguard Worker         int hasAbsolute = 0; /* acts as boolean */
512*e82f7db8SAndroid Build Coastguard Worker         int fileId;
513*e82f7db8SAndroid Build Coastguard Worker         String sourceName;
514*e82f7db8SAndroid Build Coastguard Worker         String sourcePath = null;
515*e82f7db8SAndroid Build Coastguard Worker 
516*e82f7db8SAndroid Build Coastguard Worker         /* is there an absolute filename? */
517*e82f7db8SAndroid Build Coastguard Worker         if (sdePeek() == '+') {
518*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
519*e82f7db8SAndroid Build Coastguard Worker             hasAbsolute = 1;
520*e82f7db8SAndroid Build Coastguard Worker         }
521*e82f7db8SAndroid Build Coastguard Worker         fileId = readNumber();
522*e82f7db8SAndroid Build Coastguard Worker         sourceName = readLine();
523*e82f7db8SAndroid Build Coastguard Worker         if (hasAbsolute == 1) {
524*e82f7db8SAndroid Build Coastguard Worker             sourcePath = readLine();
525*e82f7db8SAndroid Build Coastguard Worker         }
526*e82f7db8SAndroid Build Coastguard Worker         storeFile(fileId, sourceName, sourcePath);
527*e82f7db8SAndroid Build Coastguard Worker     }
528*e82f7db8SAndroid Build Coastguard Worker 
storeLine(int jplsStart,int jplsEnd,int jplsLineInc,int njplsStart,int njplsEnd,int fileId)529*e82f7db8SAndroid Build Coastguard Worker     private void storeLine(int jplsStart, int jplsEnd, int jplsLineInc,
530*e82f7db8SAndroid Build Coastguard Worker                   int njplsStart, int njplsEnd, int fileId) {
531*e82f7db8SAndroid Build Coastguard Worker         assureLineTableSize();
532*e82f7db8SAndroid Build Coastguard Worker         lineTable[lineIndex].jplsStart = jplsStart;
533*e82f7db8SAndroid Build Coastguard Worker         lineTable[lineIndex].jplsEnd = jplsEnd;
534*e82f7db8SAndroid Build Coastguard Worker         lineTable[lineIndex].jplsLineInc = jplsLineInc;
535*e82f7db8SAndroid Build Coastguard Worker         lineTable[lineIndex].njplsStart = njplsStart;
536*e82f7db8SAndroid Build Coastguard Worker         lineTable[lineIndex].njplsEnd = njplsEnd;
537*e82f7db8SAndroid Build Coastguard Worker         lineTable[lineIndex].fileId = fileId;
538*e82f7db8SAndroid Build Coastguard Worker         ++lineIndex;
539*e82f7db8SAndroid Build Coastguard Worker     }
540*e82f7db8SAndroid Build Coastguard Worker 
541*e82f7db8SAndroid Build Coastguard Worker     /**
542*e82f7db8SAndroid Build Coastguard Worker      * Parse line translation info.  Syntax is
543*e82f7db8SAndroid Build Coastguard Worker      *     <NJ-start-line> [ # <file-id> ] [ , <line-count> ] :
544*e82f7db8SAndroid Build Coastguard Worker      *                 <J-start-line> [ , <line-increment> ] CR
545*e82f7db8SAndroid Build Coastguard Worker      */
lineLine(void)546*e82f7db8SAndroid Build Coastguard Worker     private void lineLine(void) {
547*e82f7db8SAndroid Build Coastguard Worker         int lineCount = 1;
548*e82f7db8SAndroid Build Coastguard Worker         int lineIncrement = 1;
549*e82f7db8SAndroid Build Coastguard Worker         int njplsStart;
550*e82f7db8SAndroid Build Coastguard Worker         int jplsStart;
551*e82f7db8SAndroid Build Coastguard Worker 
552*e82f7db8SAndroid Build Coastguard Worker         njplsStart = readNumber();
553*e82f7db8SAndroid Build Coastguard Worker 
554*e82f7db8SAndroid Build Coastguard Worker         /* is there a fileID? */
555*e82f7db8SAndroid Build Coastguard Worker         if (sdePeek() == '#') {
556*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
557*e82f7db8SAndroid Build Coastguard Worker             currentFileId = readNumber();
558*e82f7db8SAndroid Build Coastguard Worker         }
559*e82f7db8SAndroid Build Coastguard Worker 
560*e82f7db8SAndroid Build Coastguard Worker         /* is there a line count? */
561*e82f7db8SAndroid Build Coastguard Worker         if (sdePeek() == ',') {
562*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
563*e82f7db8SAndroid Build Coastguard Worker             lineCount = readNumber();
564*e82f7db8SAndroid Build Coastguard Worker         }
565*e82f7db8SAndroid Build Coastguard Worker 
566*e82f7db8SAndroid Build Coastguard Worker         if (sdeRead() != ':') {
567*e82f7db8SAndroid Build Coastguard Worker             syntax("expected ':'");
568*e82f7db8SAndroid Build Coastguard Worker         }
569*e82f7db8SAndroid Build Coastguard Worker         jplsStart = readNumber();
570*e82f7db8SAndroid Build Coastguard Worker         if (sdePeek() == ',') {
571*e82f7db8SAndroid Build Coastguard Worker             sdeAdvance();
572*e82f7db8SAndroid Build Coastguard Worker             lineIncrement = readNumber();
573*e82f7db8SAndroid Build Coastguard Worker         }
574*e82f7db8SAndroid Build Coastguard Worker         ignoreLine(); /* flush the rest */
575*e82f7db8SAndroid Build Coastguard Worker 
576*e82f7db8SAndroid Build Coastguard Worker         storeLine(jplsStart,
577*e82f7db8SAndroid Build Coastguard Worker                   jplsStart + (lineCount * lineIncrement) -1,
578*e82f7db8SAndroid Build Coastguard Worker                   lineIncrement,
579*e82f7db8SAndroid Build Coastguard Worker                   njplsStart,
580*e82f7db8SAndroid Build Coastguard Worker                   njplsStart + lineCount -1,
581*e82f7db8SAndroid Build Coastguard Worker                   currentFileId);
582*e82f7db8SAndroid Build Coastguard Worker     }
583*e82f7db8SAndroid Build Coastguard Worker 
584*e82f7db8SAndroid Build Coastguard Worker     /**
585*e82f7db8SAndroid Build Coastguard Worker      * Until the next stratum section, everything after this
586*e82f7db8SAndroid Build Coastguard Worker      * is in stratumId - so, store the current indicies.
587*e82f7db8SAndroid Build Coastguard Worker      */
storeStratum(String stratumId)588*e82f7db8SAndroid Build Coastguard Worker     private void storeStratum(String stratumId) {
589*e82f7db8SAndroid Build Coastguard Worker         /* remove redundant strata */
590*e82f7db8SAndroid Build Coastguard Worker         if (stratumIndex > 0) {
591*e82f7db8SAndroid Build Coastguard Worker             if ((stratumTable[stratumIndex-1].fileIndex
592*e82f7db8SAndroid Build Coastguard Worker                                             == fileIndex) &&
593*e82f7db8SAndroid Build Coastguard Worker                 (stratumTable[stratumIndex-1].lineIndex
594*e82f7db8SAndroid Build Coastguard Worker                                             == lineIndex)) {
595*e82f7db8SAndroid Build Coastguard Worker                 /* nothing changed overwrite it */
596*e82f7db8SAndroid Build Coastguard Worker                 --stratumIndex;
597*e82f7db8SAndroid Build Coastguard Worker             }
598*e82f7db8SAndroid Build Coastguard Worker         }
599*e82f7db8SAndroid Build Coastguard Worker         /* store the results */
600*e82f7db8SAndroid Build Coastguard Worker         assureStratumTableSize();
601*e82f7db8SAndroid Build Coastguard Worker         stratumTable[stratumIndex].id = stratumId;
602*e82f7db8SAndroid Build Coastguard Worker         stratumTable[stratumIndex].fileIndex = fileIndex;
603*e82f7db8SAndroid Build Coastguard Worker         stratumTable[stratumIndex].lineIndex = lineIndex;
604*e82f7db8SAndroid Build Coastguard Worker         ++stratumIndex;
605*e82f7db8SAndroid Build Coastguard Worker         currentFileId = 0;
606*e82f7db8SAndroid Build Coastguard Worker     }
607*e82f7db8SAndroid Build Coastguard Worker 
608*e82f7db8SAndroid Build Coastguard Worker     /**
609*e82f7db8SAndroid Build Coastguard Worker      * The beginning of a stratum's info
610*e82f7db8SAndroid Build Coastguard Worker      */
stratumSection(void)611*e82f7db8SAndroid Build Coastguard Worker     private void stratumSection(void) {
612*e82f7db8SAndroid Build Coastguard Worker         storeStratum(readLine());
613*e82f7db8SAndroid Build Coastguard Worker     }
614*e82f7db8SAndroid Build Coastguard Worker 
fileSection(void)615*e82f7db8SAndroid Build Coastguard Worker     private void fileSection(void) {
616*e82f7db8SAndroid Build Coastguard Worker         ignoreLine();
617*e82f7db8SAndroid Build Coastguard Worker         while (sdePeek() != '*') {
618*e82f7db8SAndroid Build Coastguard Worker             fileLine();
619*e82f7db8SAndroid Build Coastguard Worker         }
620*e82f7db8SAndroid Build Coastguard Worker     }
621*e82f7db8SAndroid Build Coastguard Worker 
lineSection(void)622*e82f7db8SAndroid Build Coastguard Worker     private void lineSection(void) {
623*e82f7db8SAndroid Build Coastguard Worker         ignoreLine();
624*e82f7db8SAndroid Build Coastguard Worker         while (sdePeek() != '*') {
625*e82f7db8SAndroid Build Coastguard Worker             lineLine();
626*e82f7db8SAndroid Build Coastguard Worker         }
627*e82f7db8SAndroid Build Coastguard Worker     }
628*e82f7db8SAndroid Build Coastguard Worker 
629*e82f7db8SAndroid Build Coastguard Worker     /**
630*e82f7db8SAndroid Build Coastguard Worker      * Ignore a section we don't know about.
631*e82f7db8SAndroid Build Coastguard Worker      */
ignoreSection(void)632*e82f7db8SAndroid Build Coastguard Worker     private void ignoreSection(void) {
633*e82f7db8SAndroid Build Coastguard Worker         ignoreLine();
634*e82f7db8SAndroid Build Coastguard Worker         while (sdePeek() != '*') {
635*e82f7db8SAndroid Build Coastguard Worker             ignoreLine();
636*e82f7db8SAndroid Build Coastguard Worker         }
637*e82f7db8SAndroid Build Coastguard Worker     }
638*e82f7db8SAndroid Build Coastguard Worker 
639*e82f7db8SAndroid Build Coastguard Worker     /**
640*e82f7db8SAndroid Build Coastguard Worker      * A base "Java" stratum is always available, though
641*e82f7db8SAndroid Build Coastguard Worker      * it is not in the SourceDebugExtension.
642*e82f7db8SAndroid Build Coastguard Worker      * Create the base stratum.
643*e82f7db8SAndroid Build Coastguard Worker      */
createJavaStratum(void)644*e82f7db8SAndroid Build Coastguard Worker     private void createJavaStratum(void) {
645*e82f7db8SAndroid Build Coastguard Worker         baseStratumIndex = stratumIndex;
646*e82f7db8SAndroid Build Coastguard Worker         storeStratum(BASE_STRATUM_NAME);
647*e82f7db8SAndroid Build Coastguard Worker         storeFile(1, jplsFilename, NullString);
648*e82f7db8SAndroid Build Coastguard Worker         /* JPL line numbers cannot exceed 65535 */
649*e82f7db8SAndroid Build Coastguard Worker         storeLine(1, 65536, 1, 1, 65536, 1);
650*e82f7db8SAndroid Build Coastguard Worker         storeStratum("Aux"); /* in case they don't declare */
651*e82f7db8SAndroid Build Coastguard Worker     }
652*e82f7db8SAndroid Build Coastguard Worker 
653*e82f7db8SAndroid Build Coastguard Worker     /**
654*e82f7db8SAndroid Build Coastguard Worker      * Decode a SourceDebugExtension which is in SourceMap format.
655*e82f7db8SAndroid Build Coastguard Worker      * This is the entry point into the recursive descent parser.
656*e82f7db8SAndroid Build Coastguard Worker      */
decode(void)657*e82f7db8SAndroid Build Coastguard Worker     private void decode(void) {
658*e82f7db8SAndroid Build Coastguard Worker         /* check for "SMAP" - allow EOF if not ours */
659*e82f7db8SAndroid Build Coastguard Worker         if (strlen(sourceDebugExtension) <= 4 ||
660*e82f7db8SAndroid Build Coastguard Worker             (sdeRead() != 'S') ||
661*e82f7db8SAndroid Build Coastguard Worker             (sdeRead() != 'M') ||
662*e82f7db8SAndroid Build Coastguard Worker             (sdeRead() != 'A') ||
663*e82f7db8SAndroid Build Coastguard Worker             (sdeRead() != 'P')) {
664*e82f7db8SAndroid Build Coastguard Worker             return; /* not our info */
665*e82f7db8SAndroid Build Coastguard Worker         }
666*e82f7db8SAndroid Build Coastguard Worker         ignoreLine(); /* flush the rest */
667*e82f7db8SAndroid Build Coastguard Worker         jplsFilename = readLine();
668*e82f7db8SAndroid Build Coastguard Worker         defaultStratumId = readLine();
669*e82f7db8SAndroid Build Coastguard Worker         createJavaStratum();
670*e82f7db8SAndroid Build Coastguard Worker         while (true) {
671*e82f7db8SAndroid Build Coastguard Worker             if (sdeRead() != '*') {
672*e82f7db8SAndroid Build Coastguard Worker                 syntax("expected '*'");
673*e82f7db8SAndroid Build Coastguard Worker             }
674*e82f7db8SAndroid Build Coastguard Worker             switch (sdeRead()) {
675*e82f7db8SAndroid Build Coastguard Worker                 case 'S':
676*e82f7db8SAndroid Build Coastguard Worker                     stratumSection();
677*e82f7db8SAndroid Build Coastguard Worker                     break;
678*e82f7db8SAndroid Build Coastguard Worker                 case 'F':
679*e82f7db8SAndroid Build Coastguard Worker                     fileSection();
680*e82f7db8SAndroid Build Coastguard Worker                     break;
681*e82f7db8SAndroid Build Coastguard Worker                 case 'L':
682*e82f7db8SAndroid Build Coastguard Worker                     lineSection();
683*e82f7db8SAndroid Build Coastguard Worker                     break;
684*e82f7db8SAndroid Build Coastguard Worker                 case 'E':
685*e82f7db8SAndroid Build Coastguard Worker                     /* set end points */
686*e82f7db8SAndroid Build Coastguard Worker                     storeStratum("*terminator*");
687*e82f7db8SAndroid Build Coastguard Worker                     sourceMapIsValid = true;
688*e82f7db8SAndroid Build Coastguard Worker                     return;
689*e82f7db8SAndroid Build Coastguard Worker                 default:
690*e82f7db8SAndroid Build Coastguard Worker                     ignoreSection();
691*e82f7db8SAndroid Build Coastguard Worker             }
692*e82f7db8SAndroid Build Coastguard Worker         }
693*e82f7db8SAndroid Build Coastguard Worker     }
694*e82f7db8SAndroid Build Coastguard Worker 
695*e82f7db8SAndroid Build Coastguard Worker     /***************** query functions ***********************/
696*e82f7db8SAndroid Build Coastguard Worker 
stiLineTableIndex(int sti,int jplsLine)697*e82f7db8SAndroid Build Coastguard Worker     private int stiLineTableIndex(int sti, int jplsLine) {
698*e82f7db8SAndroid Build Coastguard Worker         int i;
699*e82f7db8SAndroid Build Coastguard Worker         int lineIndexStart;
700*e82f7db8SAndroid Build Coastguard Worker         int lineIndexEnd;
701*e82f7db8SAndroid Build Coastguard Worker 
702*e82f7db8SAndroid Build Coastguard Worker         lineIndexStart = stratumTable[sti].lineIndex;
703*e82f7db8SAndroid Build Coastguard Worker         /* one past end */
704*e82f7db8SAndroid Build Coastguard Worker         lineIndexEnd = stratumTable[sti+1].lineIndex;
705*e82f7db8SAndroid Build Coastguard Worker         for (i = lineIndexStart; i < lineIndexEnd; ++i) {
706*e82f7db8SAndroid Build Coastguard Worker             if ((jplsLine >= lineTable[i].jplsStart) &&
707*e82f7db8SAndroid Build Coastguard Worker                             (jplsLine <= lineTable[i].jplsEnd)) {
708*e82f7db8SAndroid Build Coastguard Worker                 return i;
709*e82f7db8SAndroid Build Coastguard Worker             }
710*e82f7db8SAndroid Build Coastguard Worker         }
711*e82f7db8SAndroid Build Coastguard Worker         return -1;
712*e82f7db8SAndroid Build Coastguard Worker     }
713*e82f7db8SAndroid Build Coastguard Worker 
stiLineNumber(int sti,int lti,int jplsLine)714*e82f7db8SAndroid Build Coastguard Worker     private int stiLineNumber(int sti, int lti, int jplsLine) {
715*e82f7db8SAndroid Build Coastguard Worker         return lineTable[lti].njplsStart +
716*e82f7db8SAndroid Build Coastguard Worker                 (((jplsLine - lineTable[lti].jplsStart) /
717*e82f7db8SAndroid Build Coastguard Worker                                    lineTable[lti].jplsLineInc));
718*e82f7db8SAndroid Build Coastguard Worker     }
719*e82f7db8SAndroid Build Coastguard Worker 
fileTableIndex(int sti,int fileId)720*e82f7db8SAndroid Build Coastguard Worker     private int fileTableIndex(int sti, int fileId) {
721*e82f7db8SAndroid Build Coastguard Worker         int i;
722*e82f7db8SAndroid Build Coastguard Worker         int fileIndexStart = stratumTable[sti].fileIndex;
723*e82f7db8SAndroid Build Coastguard Worker         /* one past end */
724*e82f7db8SAndroid Build Coastguard Worker         int fileIndexEnd = stratumTable[sti+1].fileIndex;
725*e82f7db8SAndroid Build Coastguard Worker         for (i = fileIndexStart; i < fileIndexEnd; ++i) {
726*e82f7db8SAndroid Build Coastguard Worker             if (fileTable[i].fileId == fileId) {
727*e82f7db8SAndroid Build Coastguard Worker                 return i;
728*e82f7db8SAndroid Build Coastguard Worker             }
729*e82f7db8SAndroid Build Coastguard Worker         }
730*e82f7db8SAndroid Build Coastguard Worker         return -1;
731*e82f7db8SAndroid Build Coastguard Worker     }
732*e82f7db8SAndroid Build Coastguard Worker 
stiFileTableIndex(int sti,int lti)733*e82f7db8SAndroid Build Coastguard Worker     private int stiFileTableIndex(int sti, int lti) {
734*e82f7db8SAndroid Build Coastguard Worker         return fileTableIndex(sti, lineTable[lti].fileId);
735*e82f7db8SAndroid Build Coastguard Worker     }
736*e82f7db8SAndroid Build Coastguard Worker 
isValid(void)737*e82f7db8SAndroid Build Coastguard Worker     private jboolean isValid(void) {
738*e82f7db8SAndroid Build Coastguard Worker         return sourceMapIsValid;
739*e82f7db8SAndroid Build Coastguard Worker     }
740