1 /* src/vm/jit/powerpc64/patcher.c - PowerPC64 code patching functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: patcher.c 8268 2007-08-07 13:24:43Z twisti $
37 #include "mm/memory.h"
39 #include "native/native.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
43 #include "vm/initialize.h"
45 #include "vm/jit/asmpart.h"
46 #include "vm/jit/md.h"
47 #include "vm/jit/methodheader.h"
48 #include "vm/jit/patcher.h"
49 #include "vm/jit/stacktrace.h"
51 #include "vmcore/class.h"
52 #include "vmcore/field.h"
53 #include "vmcore/options.h"
54 #include "vmcore/references.h"
55 #include "vm/resolve.h"
58 /* patcher_wrapper *************************************************************
60 Wrapper for all patchers. It also creates the stackframe info
63 If the return value of the patcher function is false, it gets the
64 exception object, clears the exception pointer and returns the
67 *******************************************************************************/
69 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
78 /* define the patcher function */
80 bool (*patcher_function)(u1 *);
84 /* get stuff from the stack */
86 xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
87 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
88 f = (functionptr) *((ptrint *) (sp + 0 * 8));
90 /* store PV into the patcher function position */
92 *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
94 /* cast the passed function to a patcher function */
96 patcher_function = (bool (*)(u1 *)) (ptrint) f;
98 /* enter a monitor on the patching position */
100 PATCHER_MONITORENTER;
102 /* create the stackframeinfo */
104 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 8, ra, xpc);
106 /* call the proper patcher function */
108 result = (patcher_function)(sp);
110 /* remove the stackframeinfo */
112 stacktrace_remove_stackframeinfo(&sfi);
114 /* check for return value and exit accordingly */
116 if (result == false) {
117 e = exceptions_get_and_clear_exception();
124 PATCHER_MARK_PATCHED_MONITOREXIT;
130 /* patcher_get_putstatic *******************************************************
134 <patched call position>
135 816dffc8 lwz r11,-56(r13)
136 80ab0000 lwz r5,0(r11)
138 *******************************************************************************/
140 bool patcher_get_putstatic(u1 *sp)
144 unresolved_field *uf;
149 /* get stuff from the stack */
151 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
152 mcode = *((u4 *) (sp + 3 * 8));
153 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
154 disp = *((s4 *) (sp + 1 * 8));
155 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
157 /* get the fieldinfo */
159 if (!(fi = resolve_field_eager(uf)))
162 /* check if the field's class is initialized */
164 if (!(fi->class->state & CLASS_INITIALIZED))
165 if (!initialize_class(fi->class))
168 /* patch back original code */
170 *((u4 *) ra) = mcode;
172 /* synchronize instruction cache */
174 md_icacheflush(ra, 4);
176 /* patch the field value's address */
178 *((intptr_t *) (pv + disp)) = (intptr_t) fi->value;
180 /* synchronize data cache */
182 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
188 /* patcher_get_putfield ********************************************************
192 <patched call position>
193 811f0014 lwz r8,20(r31)
195 *******************************************************************************/
197 bool patcher_get_putfield(u1 *sp)
201 unresolved_field *uf;
205 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
206 mcode = *((u4 *) (sp + 3 * 8));
207 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
208 pv = (u1 *) *((ptrint *) (sp + 1 * 8));
210 /* get the fieldinfo */
212 if (!(fi = resolve_field_eager(uf)))
215 /* patch back original code */
217 *((u4 *) ra) = mcode;
219 /* if we show disassembly, we have to skip the nop */
224 /* patch the field's offset */
226 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
228 /* synchronize instruction cache */
230 md_icacheflush(ra, 8);
236 /* patcher_aconst **************************************************************
240 <patched call postition>
241 -------- ld r3,-64(r14)
242 -------- ld r14,-72(r14)
246 *******************************************************************************/
248 bool patcher_aconst(u1 *sp)
252 constant_classref *cr;
257 /* get stuff from the stack */
259 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
260 mcode = *((u4 *) (sp + 3 * 8));
261 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
262 disp = *((s4 *) (sp + 1 * 8));
263 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
265 /* get the classinfo */
267 if (!(c = resolve_classref_eager(cr)))
270 /* patch back original code */
272 *((u4 *) ra) = mcode;
274 /* synchronize instruction cache */
276 md_icacheflush(ra, 4);
278 /* patch the classinfo pointer */
280 *((ptrint *) (pv + disp)) = (ptrint) c;
282 /* synchronize data cache */
284 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
290 /* patcher_builtin_multianewarray **********************************************
294 <patched call position>
295 808dffc0 lwz r4,-64(r13)
296 38a10038 addi r5,r1,56
297 81adffbc lwz r13,-68(r13)
301 *******************************************************************************/
303 bool patcher_builtin_multianewarray(u1 *sp)
307 constant_classref *cr;
312 /* get stuff from the stack */
314 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
315 mcode = *((u4 *) (sp + 3 * 8));
316 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
317 disp = *((s4 *) (sp + 1 * 8));
318 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
320 /* get the classinfo */
322 if (!(c = resolve_classref_eager(cr)))
325 /* patch back original code */
327 *((u4 *) ra) = mcode;
329 /* synchronize instruction cache */
331 md_icacheflush(ra, 4);
333 /* patch the classinfo pointer */
335 *((ptrint *) (pv + disp)) = (ptrint) c;
337 /* synchronize data cache */
339 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
345 /* patcher_builtin_arraycheckcast **********************************************
349 <patched call position>
350 808dffd8 lwz r4,-40(r13)
351 81adffd4 lwz r13,-44(r13)
355 *******************************************************************************/
357 bool patcher_builtin_arraycheckcast(u1 *sp)
361 constant_classref *cr;
366 /* get stuff from the stack */
368 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
369 mcode = *((u4 *) (sp + 3 * 8));
370 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
371 disp = *((s4 *) (sp + 1 * 8));
372 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
374 /* get the classinfo */
376 if (!(c = resolve_classref_eager(cr)))
379 /* patch back original code */
381 *((u4 *) ra) = mcode;
383 /* synchronize instruction cache */
385 md_icacheflush(ra, 4);
387 /* patch the classinfo pointer */
389 *((ptrint *) (pv + disp)) = (ptrint) c;
391 /* synchronize data cache */
393 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
399 /* patcher_invokestatic_special ************************************************
403 <patched call position>
404 81adffd8 lwz r13,-40(r13)
408 ******************************************************************************/
410 bool patcher_invokestatic_special(u1 *sp)
414 unresolved_method *um;
419 /* get stuff from the stack */
421 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
422 mcode = *((u4 *) (sp + 3 * 8));
423 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
424 disp = *((s4 *) (sp + 1 * 8));
425 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
427 /* get the fieldinfo */
429 if (!(m = resolve_method_eager(um)))
432 /* patch back original code */
434 *((u4 *) ra) = mcode;
436 /* synchronize instruction cache */
438 md_icacheflush(ra, 4);
440 /* patch stubroutine */
442 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
444 /* synchronize data cache */
446 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
452 /* patcher_invokevirtual *******************************************************
456 <patched call position>
457 81830000 lwz r12,0(r3)
458 81ac0088 lwz r13,136(r12)
462 *******************************************************************************/
464 bool patcher_invokevirtual(u1 *sp)
468 unresolved_method *um;
472 /* get stuff from the stack */
474 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
475 mcode = *((u4 *) (sp + 3 * 8));
476 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
478 /* get the fieldinfo */
480 if (!(m = resolve_method_eager(um)))
483 /* patch back original code */
485 *((u4 *) ra) = mcode;
487 /* if we show disassembly, we have to skip the nop */
492 /* patch vftbl index */
494 disp = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
496 *((s4 *) (ra + 4)) |= (disp & 0x0000ffff);
498 /* synchronize instruction cache */
500 md_icacheflush(ra, 2 * 4);
506 /* patcher_invokeinterface *****************************************************
510 <patched call position>
511 81830000 lwz r12,0(r3)
512 818cffd0 lwz r12,-48(r12)
513 81ac000c lwz r13,12(r12)
517 *******************************************************************************/
519 bool patcher_invokeinterface(u1 *sp)
523 unresolved_method *um;
527 /* get stuff from the stack */
529 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
530 mcode = *((u4 *) (sp + 3 * 8));
531 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
533 /* get the fieldinfo */
535 if (!(m = resolve_method_eager(um)))
538 /* patch back original code */
540 *((u4 *) ra) = mcode;
542 /* if we show disassembly, we have to skip the nop */
547 /* patch interfacetable index */
549 disp = OFFSET(vftbl_t, interfacetable[0]) -
550 sizeof(methodptr*) * m->class->index;
552 /* XXX TWISTI: check displacement */
554 *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff);
556 /* patch method offset */
558 disp = sizeof(methodptr) * (m - m->class->methods);
560 /* XXX TWISTI: check displacement */
562 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
564 /* synchronize instruction cache */
566 md_icacheflush(ra, 3 * 4);
572 /* patcher_checkcast_instanceof_flags ******************************************
576 <patched call position>
577 818dff7c lwz r12,-132(r13)
579 *******************************************************************************/
581 bool patcher_checkcast_instanceof_flags(u1 *sp)
585 constant_classref *cr;
590 /* get stuff from the stack */
592 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
593 mcode = *((u4 *) (sp + 3 * 8));
594 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
595 disp = *((s4 *) (sp + 1 * 8));
596 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
598 /* get the fieldinfo */
600 if (!(c = resolve_classref_eager(cr)))
603 /* patch back original code */
605 *((u4 *) ra) = mcode;
607 /* synchronize instruction cache */
609 md_icacheflush(ra, 4);
611 /* patch class flags */
613 *((s4 *) (pv + disp)) = (s4) c->flags;
615 /* synchronize data cache */
617 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
621 /* patcher_checkcast_interface **************************************
625 <patched call position>
626 81870000 lwz r12,0(r7)
627 800c0010 lwz r0,16(r12)
628 34000000 addic. r0,r0,0
629 408101fc bgt- 0x3002e518 FIXME
630 83c00003 lwz r30,3(0) FIXME
631 800c0000 lwz r0,0(r12)
633 *******************************************************************************/
634 bool patcher_checkcast_interface(u1 *sp)
637 constant_classref *cr;
642 /* get stuff from stack */
643 ra = (u1*) *((ptrint *)(sp + 5*8));
644 mcode = *((u4*) (sp + 3*8));
645 cr = (constant_classref*) *((ptrint*)(sp+2*8));
647 /* get the fieldinfo */
648 if (!(c = resolve_classref_eager(cr))) {
652 /* patch back original code */
653 *((u4 *) ra) = mcode;
655 /* if we show NOPs, we have to skip them */
660 /* patch super class index */
663 *((s4*)(ra + 2*4)) |= (disp & 0x0000ffff);
665 disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
667 *((s4 *)(ra + 5*4)) |= (disp & 0x0000ffff);
669 /* sync instruction cache */
670 md_icacheflush(ra, 6*4);
676 /* patcher_instanceof_interface **************************************
680 <patched call position>
681 81870000 lwz r12,0(r7)
682 800c0010 lwz r0,16(r12)
683 34000000 addic. r0,r0,0
684 408101fc ble- 0x3002e518
685 800c0000 lwz r0,0(r12)
687 *******************************************************************************/
689 bool patcher_instanceof_interface(u1 *sp)
693 constant_classref *cr;
697 /* get stuff from the stack */
699 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
700 mcode = *((u4 *) (sp + 3 * 8));
701 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
703 /* get the fieldinfo */
705 if (!(c = resolve_classref_eager(cr)))
708 /* patch back original code */
710 *((u4 *) ra) = mcode;
712 /* if we show disassembly, we have to skip the nop */
717 /* patch super class index */
721 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
723 disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
725 *((s4 *) (ra + 4 * 4)) |= (disp & 0x0000ffff);
727 /* synchronize instruction cache */
729 md_icacheflush(ra, 5 * 4);
735 /* patcher_checkcast_class *****************************************************
739 <patched call position>
740 81870000 lwz r12,0(r7)
741 800c0014 lwz r0,20(r12)
742 818dff78 lwz r12,-136(r13)
744 *******************************************************************************/
746 bool patcher_checkcast_class(u1 *sp)
750 constant_classref *cr;
755 /* get stuff from the stack */
757 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
758 mcode = *((u4 *) (sp + 3 * 8));
759 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
760 disp = *((s4 *) (sp + 1 * 8));
761 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
763 /* get the fieldinfo */
765 if (!(c = resolve_classref_eager(cr)))
768 /* patch back original code */
770 *((u4 *) ra) = mcode;
772 /* synchronize instruction cache */
774 md_icacheflush(ra, 4);
776 /* patch super class' vftbl */
778 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
780 /* synchronize data cache */
782 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
787 /* patcher_resolve_classref_to_classinfo ***************************************
791 <patched call postition>
792 806dffc4 lwz r3,-60(r13)
793 81adffc0 lwz r13,-64(r13)
800 <patched call position>
801 808dffc0 lwz r4,-64(r13)
802 38a10038 addi r5,r1,56
803 81adffbc lwz r13,-68(r13)
810 <patched call position>
811 808dffd8 lwz r4,-40(r13)
812 81adffd4 lwz r13,-44(r13)
816 *******************************************************************************/
818 bool patcher_resolve_classref_to_classinfo(u1 *sp)
820 constant_classref *cr;
826 /* get stuff from the stack */
828 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
829 mcode = *((u4 *) (sp + 3 * 8));
830 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
831 disp = *((s4 *) (sp + 1 * 8));
832 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
834 /* get the classinfo */
836 if (!(c = resolve_classref_eager(cr)))
839 /* patch back original code */
841 *((u4 *) ra) = mcode;
843 /* synchronize instruction cache */
845 md_icacheflush(ra, 4);
847 /* patch the classinfo pointer */
849 *((ptrint *) (pv + disp)) = (ptrint) c;
851 /* synchronize data cache */
853 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
860 /* patcher_instanceof_class ****************************************************
864 <patched call position>
865 817d0000 lwz r11,0(r29)
866 818dff8c lwz r12,-116(r13)
868 *******************************************************************************/
870 bool patcher_instanceof_class(u1 *sp)
874 constant_classref *cr;
879 /* get stuff from the stack */
881 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
882 mcode = *((u4 *) (sp + 3 * 8));
883 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
884 disp = *((s4 *) (sp + 1 * 8));
885 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
887 /* get the fieldinfo */
889 if (!(c = resolve_classref_eager(cr)))
892 /* patch back original code */
894 *((u4 *) ra) = mcode;
896 /* synchronize instruction cache */
898 md_icacheflush(ra, 4);
900 /* patch super class' vftbl */
902 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
904 /* synchronize data cache */
906 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
911 /* patcher_resolve_classref_to_vftbl *******************************************
915 <patched call position>
916 81870000 lwz r12,0(r7)
917 800c0014 lwz r0,20(r12)
918 818dff78 lwz r12,-136(r13)
923 <patched call position>
924 817d0000 lwz r11,0(r29)
925 818dff8c lwz r12,-116(r13)
927 *******************************************************************************/
929 bool patcher_resolve_classref_to_vftbl(u1 *sp)
931 constant_classref *cr;
937 /* get stuff from the stack */
939 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
940 mcode = *((u4 *) (sp + 3 * 8));
941 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
942 disp = *((s4 *) (sp + 1 * 8));
943 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
945 /* get the fieldinfo */
947 if (!(c = resolve_classref_eager(cr)))
950 /* patch back original code */
952 *((u4 *) ra) = mcode;
954 /* synchronize instruction cache */
956 md_icacheflush(ra, 4);
958 /* patch super class' vftbl */
960 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
962 /* synchronize data cache */
964 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
969 /* patcher_resolve_classref_to_flags *******************************************
971 CHECKCAST/INSTANCEOF:
973 <patched call position>
974 818dff7c lwz r12,-132(r13)
976 *******************************************************************************/
978 bool patcher_resolve_classref_to_flags(u1 *sp)
980 constant_classref *cr;
986 /* get stuff from the stack */
988 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
989 mcode = *((u4 *) (sp + 3 * 8));
990 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
991 disp = *((s4 *) (sp + 1 * 8));
992 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
994 /* get the fieldinfo */
996 if (!(c = resolve_classref_eager(cr)))
999 /* patch back original code */
1001 *((u4 *) ra) = mcode;
1003 /* synchronize instruction cache */
1005 md_icacheflush(ra, 4);
1007 /* patch class flags */
1009 *((s4 *) (pv + disp)) = (s4) c->flags;
1011 /* synchronize data cache */
1013 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
1018 /* patcher_clinit **************************************************************
1022 *******************************************************************************/
1024 bool patcher_clinit(u1 *sp)
1030 /* get stuff from the stack */
1032 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1033 mcode = *((u4 *) (sp + 3 * 8));
1034 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
1036 /* check if the class is initialized */
1038 if (!(c->state & CLASS_INITIALIZED))
1039 if (!initialize_class(c))
1042 /* patch back original code */
1044 *((u4 *) ra) = mcode;
1046 /* synchronize instruction cache */
1048 md_icacheflush(ra, 4);
1054 /* patcher_athrow_areturn ******************************************************
1058 <patched call position>
1060 *******************************************************************************/
1062 #ifdef ENABLE_VERIFIER
1063 bool patcher_athrow_areturn(u1 *sp)
1067 unresolved_class *uc;
1069 /* get stuff from the stack */
1071 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1072 mcode = *((u4 *) (sp + 3 * 8));
1073 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
1075 /* resolve the class and check subtype constraints */
1077 if (!resolve_class_eager_no_access_check(uc))
1080 /* patch back original code */
1082 *((u4 *) ra) = mcode;
1084 /* synchronize instruction cache */
1086 md_icacheflush(ra, 4);
1090 #endif /* ENABLE_VERIFIER */
1093 /* patcher_resolve_native ******************************************************
1097 *******************************************************************************/
1099 #if !defined(WITH_STATIC_CLASSPATH)
1100 bool patcher_resolve_native(u1 *sp)
1109 /* get stuff from the stack */
1111 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1112 mcode = *((u4 *) (sp + 3 * 8));
1113 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1114 disp = *((s4 *) (sp + 1 * 8));
1115 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1117 /* resolve native function */
1119 if (!(f = native_resolve_function(m)))
1122 /* patch back original code */
1124 *((u4 *) ra) = mcode;
1126 /* synchronize instruction cache */
1128 md_icacheflush(ra, 4);
1130 /* patch native function pointer */
1132 *((ptrint *) (pv + disp)) = (ptrint) f;
1134 /* synchronize data cache */
1136 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
1140 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1144 * These are local overrides for various environment variables in Emacs.
1145 * Please do not remove this and leave it at the end of the file, where
1146 * Emacs will automagically detect them.
1147 * ---------------------------------------------------------------------
1150 * indent-tabs-mode: t
1154 * vim:noexpandtab:sw=4:ts=4: