From c82e52d55bd31eea943c616ad780f27e5ab9dc7a Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Tue, 28 Jun 2016 15:11:06 +0200 Subject: [PATCH] tccasm: Implement .pushsection and .popsection --- tcc.h | 4 ++-- tccasm.c | 27 ++++++++++++++++++++++++++- tcctok.h | 2 ++ tests/asmtest.S | 10 ++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/tcc.h b/tcc.h index 1e2b815..4de48e7 100644 --- a/tcc.h +++ b/tcc.h @@ -448,8 +448,8 @@ typedef struct Section { int nb_hashed_syms; /* used to resize the hash table */ struct Section *link; /* link to another section */ struct Section *reloc; /* corresponding section for relocation, if any */ - struct Section *hash; /* hash table for symbols */ - struct Section *next; + struct Section *hash; /* hash table for symbols */ + struct Section *prev; /* previous section on section stack */ char name[1]; /* section name */ } Section; diff --git a/tccasm.c b/tccasm.c index 50fb794..ee14073 100644 --- a/tccasm.c +++ b/tccasm.c @@ -335,6 +335,22 @@ static void use_section(TCCState *s1, const char *name) use_section1(s1, sec); } +static void push_section(TCCState *s1, const char *name) +{ + Section *sec = find_section(s1, name); + sec->prev = cur_text_section; + use_section1(s1, sec); +} + +static void pop_section(TCCState *s1) +{ + Section *prev = cur_text_section->prev; + if (!prev) + tcc_error(".popsection without .pushsection"); + cur_text_section->prev = NULL; + use_section1(s1, prev); +} + static void asm_parse_directive(TCCState *s1) { int n, offset, v, size, tok1; @@ -683,10 +699,12 @@ static void asm_parse_directive(TCCState *s1) next(); } break; + case TOK_ASMDIR_pushsection: case TOK_ASMDIR_section: { char sname[256]; + tok1 = tok; /* XXX: support more options */ next(); sname[0] = '\0'; @@ -711,7 +729,10 @@ static void asm_parse_directive(TCCState *s1) } } last_text_section = cur_text_section; - use_section(s1, sname); + if (tok1 == TOK_ASMDIR_section) + use_section(s1, sname); + else + push_section(s1, sname); } break; case TOK_ASMDIR_previous: @@ -725,6 +746,10 @@ static void asm_parse_directive(TCCState *s1) last_text_section = sec; } break; + case TOK_ASMDIR_popsection: + next(); + pop_section(s1); + break; #ifdef TCC_TARGET_I386 case TOK_ASMDIR_code16: { diff --git a/tcctok.h b/tcctok.h index 7480ac7..6e2a041 100644 --- a/tcctok.h +++ b/tcctok.h @@ -323,6 +323,8 @@ DEF_ASMDIR(data) DEF_ASMDIR(bss) DEF_ASMDIR(previous) + DEF_ASMDIR(pushsection) + DEF_ASMDIR(popsection) DEF_ASMDIR(fill) DEF_ASMDIR(rept) DEF_ASMDIR(endr) diff --git a/tests/asmtest.S b/tests/asmtest.S index 2e634af..2518510 100644 --- a/tests/asmtest.S +++ b/tests/asmtest.S @@ -717,6 +717,16 @@ ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9: .endr .fill 4,1,0x90 +.section .text.one,"ax" +nop +.previous +.pushsection .text.one,"ax" +nop +.pushsection .text.two,"ax" +nop +.popsection +.popsection + movd %esi, %mm1 movd %edi, %xmm2 movd (%ebx), %mm3