History

Implement function alignment via attributes

which requires being able to emit an arbitrary number of NOP instructions, which is also implemented here. For x86 we could emit other sequences but these are the easiest.

Michael Matz committed 8 years ago

Commit 671dcac1 parent ef668aa8 files · +56 −0Browse files

Unified · Split

8 files
  1. arm-gen.c +10 −0
  2. arm64-gen.c +10 −0
  3. c67-gen.c +10 −0
  4. i386-gen.c +6 −0
  5. tcc.h +1 −0
  6. tccgen.c +7 −0
  7. tests/tcctest.c +6 −0
  8. x86_64-gen.c +6 −0
arm-gen.c+10−0
@@ -1410,6 +1410,16 @@ void gfunc_epilog(void) · 1409 unmodified lines
14101410 }
14111411 }
14121412
1413+ST_FUNC void gen_fill_nops(int bytes)
1414+{
1415+ if ((bytes & 3))
1416+ tcc_error("alignment of code section not multiple of 4");
1417+ while (bytes > 0) {
1418+ o(0xE1A00000);
1419+ bytes -= 4;
1420+ }
1421+}
1422+
14131423 /* generate a jump to a label */
14141424 int gjmp(int t)
14151425 {
arm64-gen.c+10−0
@@ -1276,6 +1276,16 @@ ST_FUNC void gfunc_epilog(void) · 1275 unmodified lines
12761276 o(0xd65f03c0); // ret
12771277 }
12781278
1279+ST_FUNC void gen_fill_nops(int bytes)
1280+{
1281+ if ((bytes & 3))
1282+ tcc_error("alignment of code section not multiple of 4");
1283+ while (bytes > 0) {
1284+ o(0xd503201f); // nop
1285+ bytes -= 4;
1286+ }
1287+}
1288+
12791289 // Generate forward branch to label:
12801290 ST_FUNC int gjmp(int t)
12811291 {
c67-gen.c+10−0
@@ -2035,6 +2035,16 @@ void gfunc_epilog(void) · 2034 unmodified lines
20352035 }
20362036 }
20372037
2038+ST_FUNC void gen_fill_nops(int bytes)
2039+{
2040+ if ((bytes & 3))
2041+ tcc_error("alignment of code section not multiple of 4");
2042+ while (bytes > 0) {
2043+ C67_NOP(4);
2044+ bytes -= 4;
2045+ }
2046+}
2047+
20382048 /* generate a jump to a label */
20392049 int gjmp(int t)
20402050 {
i386-gen.c+6−0
@@ -157,6 +157,12 @@ static int oad(int c, int s) · 156 unmodified lines
157157 return t;
158158 }
159159
160+ST_FUNC void gen_fill_nops(int bytes)
161+{
162+ while (bytes--)
163+ g(0x90);
164+}
165+
160166 /* generate jmp to a label */
161167 #define gjmp2(instr,lbl) oad(instr,lbl)
162168
tcc.h+1−0
@@ -1475,6 +1475,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *reg · 1474 unmodified lines
14751475 ST_FUNC void gfunc_call(int nb_args);
14761476 ST_FUNC void gfunc_prolog(CType *func_type);
14771477 ST_FUNC void gfunc_epilog(void);
1478+ST_FUNC void gen_fill_nops(int);
14781479 ST_FUNC int gjmp(int t);
14791480 ST_FUNC void gjmp_addr(int a);
14801481 ST_FUNC int gtst(int inv, int t);
tccgen.c+7−0
@@ -7088,6 +7088,13 @@ static void gen_function(Sym *sym) · 7087 unmodified lines
70887088 {
70897089 nocode_wanted = 0;
70907090 ind = cur_text_section->data_offset;
7091+ if (sym->a.aligned) {
7092+ size_t newoff = section_add(cur_text_section, 0,
7093+ 1 << (sym->a.aligned - 1));
7094+ if (ind != newoff)
7095+ gen_fill_nops(newoff - ind);
7096+ ind = newoff;
7097+ }
70917098 /* NOTE: we patch the symbol size later */
70927099 put_extern_sym(sym, cur_text_section, ind, 0);
70937100 funcname = get_tok_str(sym->v, NULL);
tests/tcctest.c+6−0
@@ -2270,6 +2270,8 @@ int fib(int n) · 2269 unmodified lines
22702270 return fib(n-1) + fib(n-2);
22712271 }
22722272
2273+void __attribute__((aligned(16))) aligned_function(int i) {}
2274+
22732275 void funcptr_test()
22742276 {
22752277 void (*func)(int);
@@ -2300,6 +2302,10 @@ void funcptr_test() · 24 unmodified lines
23002302 func(42);
23012303 (func + diff)(42);
23022304 (num + a)(43);
2305+
2306+ /* Check that we can align functions */
2307+ func = aligned_function;
2308+ printf("aligned_function (should be zero): %d\n", ((int)func) & 15);
23032309 }
23042310
23052311 void lloptest(long long a, long long b)
x86_64-gen.c+6−0
@@ -1639,6 +1639,12 @@ void gfunc_epilog(void) · 1638 unmodified lines
16391639
16401640 #endif /* not PE */
16411641
1642+ST_FUNC void gen_fill_nops(int bytes)
1643+{
1644+ while (bytes--)
1645+ g(0x90);
1646+}
1647+
16421648 /* generate a jump to a label */
16431649 int gjmp(int t)
16441650 {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t