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 7909 2007-05-15 10:32:16Z tbfg $
36 #include "mm/memory.h"
38 #include "native/native.h"
40 #include "vm/builtin.h"
41 #include "vm/exceptions.h"
42 #include "vm/initialize.h"
44 #include "vm/jit/asmpart.h"
45 #include "vm/jit/md.h"
46 #include "vm/jit/methodheader.h"
47 #include "vm/jit/patcher.h"
48 #include "vm/jit/stacktrace.h"
50 #include "vmcore/class.h"
51 #include "vmcore/field.h"
52 #include "vmcore/options.h"
53 #include "vmcore/references.h"
54 #include "vm/resolve.h"
57 /* patcher_wrapper *************************************************************
59 Wrapper for all patchers. It also creates the stackframe info
62 If the return value of the patcher function is false, it gets the
63 exception object, clears the exception pointer and returns the
66 *******************************************************************************/
68 java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
77 /* define the patcher function */
79 bool (*patcher_function)(u1 *);
83 /* get stuff from the stack */
85 xpc = (u1 *) *((ptrint *) (sp + 5 * 8));
86 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
87 f = (functionptr) *((ptrint *) (sp + 0 * 8));
89 /* store PV into the patcher function position */
91 *((ptrint *) (sp + 0 * 8)) = (ptrint) pv;
93 /* cast the passed function to a patcher function */
95 patcher_function = (bool (*)(u1 *)) (ptrint) f;
97 /* enter a monitor on the patching position */
101 /* create the stackframeinfo */
103 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 8, ra, xpc);
105 /* call the proper patcher function */
107 result = (patcher_function)(sp);
109 /* remove the stackframeinfo */
111 stacktrace_remove_stackframeinfo(&sfi);
113 /* check for return value and exit accordingly */
115 if (result == false) {
116 e = exceptions_get_and_clear_exception();
123 PATCHER_MARK_PATCHED_MONITOREXIT;
129 /* patcher_get_putstatic *******************************************************
133 <patched call position>
134 816dffc8 lwz r11,-56(r13)
135 80ab0000 lwz r5,0(r11)
137 *******************************************************************************/
139 bool patcher_get_putstatic(u1 *sp)
143 unresolved_field *uf;
148 /* get stuff from the stack */
150 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
151 mcode = *((u4 *) (sp + 3 * 8));
152 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
153 disp = *((s4 *) (sp + 1 * 8));
154 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
156 /* get the fieldinfo */
158 if (!(fi = resolve_field_eager(uf)))
161 /* check if the field's class is initialized */
163 if (!(fi->class->state & CLASS_INITIALIZED))
164 if (!initialize_class(fi->class))
167 /* patch back original code */
169 *((u4 *) ra) = mcode;
171 /* synchronize instruction cache */
173 md_icacheflush(ra, 4);
175 /* patch the field value's address */
177 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
179 /* synchronize data cache */
181 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
187 /* patcher_get_putfield ********************************************************
191 <patched call position>
192 811f0014 lwz r8,20(r31)
194 *******************************************************************************/
196 bool patcher_get_putfield(u1 *sp)
200 unresolved_field *uf;
204 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
205 mcode = *((u4 *) (sp + 3 * 8));
206 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
207 pv = (u1 *) *((ptrint *) (sp + 1 * 8));
209 /* get the fieldinfo */
211 if (!(fi = resolve_field_eager(uf)))
214 /* patch back original code */
216 *((u4 *) ra) = mcode;
218 /* if we show disassembly, we have to skip the nop */
223 /* patch the field's offset */
225 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
227 /* synchronize instruction cache */
229 md_icacheflush(ra, 8);
235 /* patcher_aconst **************************************************************
239 <patched call postition>
240 -------- ld r3,-64(r14)
241 -------- ld r14,-72(r14)
245 *******************************************************************************/
247 bool patcher_aconst(u1 *sp)
251 constant_classref *cr;
256 /* get stuff from the stack */
258 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
259 mcode = *((u4 *) (sp + 3 * 8));
260 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
261 disp = *((s4 *) (sp + 1 * 8));
262 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
264 /* get the classinfo */
266 if (!(c = resolve_classref_eager(cr)))
269 /* patch back original code */
271 *((u4 *) ra) = mcode;
273 /* synchronize instruction cache */
275 md_icacheflush(ra, 4);
277 /* patch the classinfo pointer */
279 *((ptrint *) (pv + disp)) = (ptrint) c;
281 /* synchronize data cache */
283 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
289 /* patcher_builtin_multianewarray **********************************************
293 <patched call position>
294 808dffc0 lwz r4,-64(r13)
295 38a10038 addi r5,r1,56
296 81adffbc lwz r13,-68(r13)
300 *******************************************************************************/
302 bool patcher_builtin_multianewarray(u1 *sp)
306 constant_classref *cr;
311 /* get stuff from the stack */
313 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
314 mcode = *((u4 *) (sp + 3 * 8));
315 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
316 disp = *((s4 *) (sp + 1 * 8));
317 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
319 /* get the classinfo */
321 if (!(c = resolve_classref_eager(cr)))
324 /* patch back original code */
326 *((u4 *) ra) = mcode;
328 /* synchronize instruction cache */
330 md_icacheflush(ra, 4);
332 /* patch the classinfo pointer */
334 *((ptrint *) (pv + disp)) = (ptrint) c;
336 /* synchronize data cache */
338 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
344 /* patcher_builtin_arraycheckcast **********************************************
348 <patched call position>
349 808dffd8 lwz r4,-40(r13)
350 81adffd4 lwz r13,-44(r13)
354 *******************************************************************************/
356 bool patcher_builtin_arraycheckcast(u1 *sp)
360 constant_classref *cr;
365 /* get stuff from the stack */
367 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
368 mcode = *((u4 *) (sp + 3 * 8));
369 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
370 disp = *((s4 *) (sp + 1 * 8));
371 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
373 /* get the classinfo */
375 if (!(c = resolve_classref_eager(cr)))
378 /* patch back original code */
380 *((u4 *) ra) = mcode;
382 /* synchronize instruction cache */
384 md_icacheflush(ra, 4);
386 /* patch the classinfo pointer */
388 *((ptrint *) (pv + disp)) = (ptrint) c;
390 /* synchronize data cache */
392 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
398 /* patcher_invokestatic_special ************************************************
402 <patched call position>
403 81adffd8 lwz r13,-40(r13)
407 ******************************************************************************/
409 bool patcher_invokestatic_special(u1 *sp)
413 unresolved_method *um;
418 /* get stuff from the stack */
420 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
421 mcode = *((u4 *) (sp + 3 * 8));
422 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
423 disp = *((s4 *) (sp + 1 * 8));
424 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
426 /* get the fieldinfo */
428 if (!(m = resolve_method_eager(um)))
431 /* patch back original code */
433 *((u4 *) ra) = mcode;
435 /* synchronize instruction cache */
437 md_icacheflush(ra, 4);
439 /* patch stubroutine */
441 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
443 /* synchronize data cache */
445 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
451 /* patcher_invokevirtual *******************************************************
455 <patched call position>
456 81830000 lwz r12,0(r3)
457 81ac0088 lwz r13,136(r12)
461 *******************************************************************************/
463 bool patcher_invokevirtual(u1 *sp)
467 unresolved_method *um;
471 /* get stuff from the stack */
473 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
474 mcode = *((u4 *) (sp + 3 * 8));
475 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
477 /* get the fieldinfo */
479 if (!(m = resolve_method_eager(um)))
482 /* patch back original code */
484 *((u4 *) ra) = mcode;
486 /* if we show disassembly, we have to skip the nop */
491 /* patch vftbl index */
493 disp = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
495 *((s4 *) (ra + 4)) |= (disp & 0x0000ffff);
497 /* synchronize instruction cache */
499 md_icacheflush(ra, 2 * 4);
505 /* patcher_invokeinterface *****************************************************
509 <patched call position>
510 81830000 lwz r12,0(r3)
511 818cffd0 lwz r12,-48(r12)
512 81ac000c lwz r13,12(r12)
516 *******************************************************************************/
518 bool patcher_invokeinterface(u1 *sp)
522 unresolved_method *um;
526 /* get stuff from the stack */
528 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
529 mcode = *((u4 *) (sp + 3 * 8));
530 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
532 /* get the fieldinfo */
534 if (!(m = resolve_method_eager(um)))
537 /* patch back original code */
539 *((u4 *) ra) = mcode;
541 /* if we show disassembly, we have to skip the nop */
546 /* patch interfacetable index */
548 disp = OFFSET(vftbl_t, interfacetable[0]) -
549 sizeof(methodptr*) * m->class->index;
551 /* XXX TWISTI: check displacement */
553 *((s4 *) (ra + 1 * 4)) |= (disp & 0x0000ffff);
555 /* patch method offset */
557 disp = sizeof(methodptr) * (m - m->class->methods);
559 /* XXX TWISTI: check displacement */
561 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
563 /* synchronize instruction cache */
565 md_icacheflush(ra, 3 * 4);
571 /* patcher_checkcast_instanceof_flags ******************************************
575 <patched call position>
576 818dff7c lwz r12,-132(r13)
578 *******************************************************************************/
580 bool patcher_checkcast_instanceof_flags(u1 *sp)
584 constant_classref *cr;
589 /* get stuff from the stack */
591 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
592 mcode = *((u4 *) (sp + 3 * 8));
593 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
594 disp = *((s4 *) (sp + 1 * 8));
595 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
597 /* get the fieldinfo */
599 if (!(c = resolve_classref_eager(cr)))
602 /* patch back original code */
604 *((u4 *) ra) = mcode;
606 /* synchronize instruction cache */
608 md_icacheflush(ra, 4);
610 /* patch class flags */
612 *((s4 *) (pv + disp)) = (s4) c->flags;
614 /* synchronize data cache */
616 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
620 /* patcher_checkcast_interface **************************************
624 <patched call position>
625 81870000 lwz r12,0(r7)
626 800c0010 lwz r0,16(r12)
627 34000000 addic. r0,r0,0
628 408101fc bgt- 0x3002e518 FIXME
629 83c00003 lwz r30,3(0) FIXME
630 800c0000 lwz r0,0(r12)
632 *******************************************************************************/
633 bool patcher_checkcast_interface(u1 *sp)
636 constant_classref *cr;
641 /* get stuff from stack */
642 ra = (u1*) *((ptrint *)(sp + 5*8));
643 mcode = *((u4*) (sp + 3*8));
644 cr = (constant_classref*) *((ptrint*)(sp+2*8));
646 /* get the fieldinfo */
647 if (!(c = resolve_classref_eager(cr))) {
651 /* patch back original code */
652 *((u4 *) ra) = mcode;
654 /* if we show NOPs, we have to skip them */
659 /* patch super class index */
662 *((s4*)(ra + 2*4)) |= (disp & 0x0000ffff);
664 disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
666 *((s4 *)(ra + 5*4)) |= (disp & 0x0000ffff);
668 /* sync instruction cache */
669 md_icacheflush(ra, 6*4);
675 /* patcher_instanceof_interface **************************************
679 <patched call position>
680 81870000 lwz r12,0(r7)
681 800c0010 lwz r0,16(r12)
682 34000000 addic. r0,r0,0
683 408101fc ble- 0x3002e518
684 800c0000 lwz r0,0(r12)
686 *******************************************************************************/
688 bool patcher_instanceof_interface(u1 *sp)
692 constant_classref *cr;
696 /* get stuff from the stack */
698 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
699 mcode = *((u4 *) (sp + 3 * 8));
700 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
702 /* get the fieldinfo */
704 if (!(c = resolve_classref_eager(cr)))
707 /* patch back original code */
709 *((u4 *) ra) = mcode;
711 /* if we show disassembly, we have to skip the nop */
716 /* patch super class index */
720 *((s4 *) (ra + 2 * 4)) |= (disp & 0x0000ffff);
722 disp = OFFSET(vftbl_t, interfacetable[0]) - c->index * sizeof(methodptr*);
724 *((s4 *) (ra + 4 * 4)) |= (disp & 0x0000ffff);
726 /* synchronize instruction cache */
728 md_icacheflush(ra, 5 * 4);
734 /* patcher_checkcast_class *****************************************************
738 <patched call position>
739 81870000 lwz r12,0(r7)
740 800c0014 lwz r0,20(r12)
741 818dff78 lwz r12,-136(r13)
743 *******************************************************************************/
745 bool patcher_checkcast_class(u1 *sp)
749 constant_classref *cr;
754 /* get stuff from the stack */
756 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
757 mcode = *((u4 *) (sp + 3 * 8));
758 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
759 disp = *((s4 *) (sp + 1 * 8));
760 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
762 /* get the fieldinfo */
764 if (!(c = resolve_classref_eager(cr)))
767 /* patch back original code */
769 *((u4 *) ra) = mcode;
771 /* synchronize instruction cache */
773 md_icacheflush(ra, 4);
775 /* patch super class' vftbl */
777 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
779 /* synchronize data cache */
781 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
786 /* patcher_resolve_classref_to_classinfo ***************************************
790 <patched call postition>
791 806dffc4 lwz r3,-60(r13)
792 81adffc0 lwz r13,-64(r13)
799 <patched call position>
800 808dffc0 lwz r4,-64(r13)
801 38a10038 addi r5,r1,56
802 81adffbc lwz r13,-68(r13)
809 <patched call position>
810 808dffd8 lwz r4,-40(r13)
811 81adffd4 lwz r13,-44(r13)
815 *******************************************************************************/
817 bool patcher_resolve_classref_to_classinfo(u1 *sp)
819 constant_classref *cr;
825 /* get stuff from the stack */
827 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
828 mcode = *((u4 *) (sp + 3 * 8));
829 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
830 disp = *((s4 *) (sp + 1 * 8));
831 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
833 /* get the classinfo */
835 if (!(c = resolve_classref_eager(cr)))
838 /* patch back original code */
840 *((u4 *) ra) = mcode;
842 /* synchronize instruction cache */
844 md_icacheflush(ra, 4);
846 /* patch the classinfo pointer */
848 *((ptrint *) (pv + disp)) = (ptrint) c;
850 /* synchronize data cache */
852 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
859 /* patcher_instanceof_class ****************************************************
863 <patched call position>
864 817d0000 lwz r11,0(r29)
865 818dff8c lwz r12,-116(r13)
867 *******************************************************************************/
869 bool patcher_instanceof_class(u1 *sp)
873 constant_classref *cr;
878 /* get stuff from the stack */
880 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
881 mcode = *((u4 *) (sp + 3 * 8));
882 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
883 disp = *((s4 *) (sp + 1 * 8));
884 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
886 /* get the fieldinfo */
888 if (!(c = resolve_classref_eager(cr)))
891 /* patch back original code */
893 *((u4 *) ra) = mcode;
895 /* synchronize instruction cache */
897 md_icacheflush(ra, 4);
899 /* patch super class' vftbl */
901 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
903 /* synchronize data cache */
905 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
910 /* patcher_resolve_classref_to_vftbl *******************************************
914 <patched call position>
915 81870000 lwz r12,0(r7)
916 800c0014 lwz r0,20(r12)
917 818dff78 lwz r12,-136(r13)
922 <patched call position>
923 817d0000 lwz r11,0(r29)
924 818dff8c lwz r12,-116(r13)
926 *******************************************************************************/
928 bool patcher_resolve_classref_to_vftbl(u1 *sp)
930 constant_classref *cr;
936 /* get stuff from the stack */
938 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
939 mcode = *((u4 *) (sp + 3 * 8));
940 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
941 disp = *((s4 *) (sp + 1 * 8));
942 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
944 /* get the fieldinfo */
946 if (!(c = resolve_classref_eager(cr)))
949 /* patch back original code */
951 *((u4 *) ra) = mcode;
953 /* synchronize instruction cache */
955 md_icacheflush(ra, 4);
957 /* patch super class' vftbl */
959 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
961 /* synchronize data cache */
963 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
968 /* patcher_resolve_classref_to_flags *******************************************
970 CHECKCAST/INSTANCEOF:
972 <patched call position>
973 818dff7c lwz r12,-132(r13)
975 *******************************************************************************/
977 bool patcher_resolve_classref_to_flags(u1 *sp)
979 constant_classref *cr;
985 /* get stuff from the stack */
987 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
988 mcode = *((u4 *) (sp + 3 * 8));
989 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
990 disp = *((s4 *) (sp + 1 * 8));
991 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
993 /* get the fieldinfo */
995 if (!(c = resolve_classref_eager(cr)))
998 /* patch back original code */
1000 *((u4 *) ra) = mcode;
1002 /* synchronize instruction cache */
1004 md_icacheflush(ra, 4);
1006 /* patch class flags */
1008 *((s4 *) (pv + disp)) = (s4) c->flags;
1010 /* synchronize data cache */
1012 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
1017 /* patcher_clinit **************************************************************
1021 *******************************************************************************/
1023 bool patcher_clinit(u1 *sp)
1029 /* get stuff from the stack */
1031 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1032 mcode = *((u4 *) (sp + 3 * 8));
1033 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
1035 /* check if the class is initialized */
1037 if (!(c->state & CLASS_INITIALIZED))
1038 if (!initialize_class(c))
1041 /* patch back original code */
1043 *((u4 *) ra) = mcode;
1045 /* synchronize instruction cache */
1047 md_icacheflush(ra, 4);
1053 /* patcher_athrow_areturn ******************************************************
1057 <patched call position>
1059 *******************************************************************************/
1061 #ifdef ENABLE_VERIFIER
1062 bool patcher_athrow_areturn(u1 *sp)
1066 unresolved_class *uc;
1068 /* get stuff from the stack */
1070 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1071 mcode = *((u4 *) (sp + 3 * 8));
1072 uc = (unresolved_class *) *((ptrint *) (sp + 2 * 8));
1074 /* resolve the class and check subtype constraints */
1076 if (!resolve_class_eager_no_access_check(uc))
1079 /* patch back original code */
1081 *((u4 *) ra) = mcode;
1083 /* synchronize instruction cache */
1085 md_icacheflush(ra, 4);
1089 #endif /* ENABLE_VERIFIER */
1092 /* patcher_resolve_native ******************************************************
1096 *******************************************************************************/
1098 #if !defined(WITH_STATIC_CLASSPATH)
1099 bool patcher_resolve_native(u1 *sp)
1108 /* get stuff from the stack */
1110 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1111 mcode = *((u4 *) (sp + 3 * 8));
1112 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1113 disp = *((s4 *) (sp + 1 * 8));
1114 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1116 /* resolve native function */
1118 if (!(f = native_resolve_function(m)))
1121 /* patch back original code */
1123 *((u4 *) ra) = mcode;
1125 /* synchronize instruction cache */
1127 md_icacheflush(ra, 4);
1129 /* patch native function pointer */
1131 *((ptrint *) (pv + disp)) = (ptrint) f;
1133 /* synchronize data cache */
1135 md_dcacheflush(pv + disp, SIZEOF_VOID_P);
1139 #endif /* !defined(WITH_STATIC_CLASSPATH) */
1143 * These are local overrides for various environment variables in Emacs.
1144 * Please do not remove this and leave it at the end of the file, where
1145 * Emacs will automagically detect them.
1146 * ---------------------------------------------------------------------
1149 * indent-tabs-mode: t
1153 * vim:noexpandtab:sw=4:ts=4: