aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tcc.h4
-rw-r--r--tccasm.c27
-rw-r--r--tcctok.h2
-rw-r--r--tests/asmtest.S10
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