diff options
| author | Andrew Chambers <[email protected]> | 2021-10-09 22:05:15 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-09 22:05:15 +1300 |
| commit | c726740a3882ebdc85c0d06c922dfaf5c6532c69 (patch) | |
| tree | 78e74a25dd09238ef4967cea29c150af2215d6dd | |
| parent | a439d4004379cc73dd6b2bf330130733396f9d61 (diff) | |
Add section directive.
| -rw-r--r-- | asm.peg | 22 | ||||
| -rw-r--r-- | main.c | 39 | ||||
| -rw-r--r-- | minias.h | 12 |
3 files changed, 70 insertions, 3 deletions
@@ -8,11 +8,11 @@ ws = [ \t]+ eol = ws? "\n" stmt = - d:directive {$$ = d;} + '.' d:directive {$$ = d;} | i:instr { $$ = i; } | l:label { $$ = l; } -directive = '.' ( +directive = "glob" 'o'? 'l' ws i:ident { $$.globl = (Globl){.kind = ASM_DIR_GLOBL, .name = i.ident.name }; } | "ascii" <'z'?> ws s:string @@ -25,7 +25,23 @@ directive = '.' ( { $$.balign = (Balign){.kind = ASM_DIR_BALIGN, .align = n.number.v }; } | "byte" ws n:number { $$.byte = (Byte){.kind = ASM_DIR_BYTE, .b = (uint8_t)n.number.v }; } -) + | sd:section-directive { $$ = sd; } + +section-directive = + "section" ws? n:section-name ( + ws? ',' ws? f:section-flags ws? ',' ws? t:section-type + {$$.section = (DirSection){.kind=ASM_DIR_SECTION, .name=n.charptr, .flags=f.charptr, .type=t.i64}; } + | ws? ',' ws? f:section-flags + {$$.section = (DirSection){.kind=ASM_DIR_SECTION, .name=n.charptr, .flags=f.charptr, .type=SHT_PROGBITS}; } + | + {$$.section = (DirSection){.kind=ASM_DIR_SECTION, .name=n.charptr, .flags="", .type=SHT_PROGBITS}; } + ) + +section-name = <[.a-zA-Z0-9\-]+> { $$.charptr = xstrdup(yytext); } +section-flags = '"' <[awx]*> '"' { $$.charptr = xstrdup(yytext); } +section-type = + "@nobits" { $$.i64 = SHT_NOBITS; } + | "@progbits" { $$.i64 = SHT_PROGBITS; } label = i:ident ':' @@ -78,6 +78,19 @@ static Section *newsection() { return s; } +static Section *getsection(const char *name) { + size_t i; + Section *s; + + for (i = 0; i < nsections; i++) { + if (strcmp(secname(§ions[i]), name) == 0) + return §ions[i]; + } + s = newsection(); + s->hdr.sh_name = elfstr(shstrtab, name); + return s; +} + static void initsections(void) { Elf64_Sym elfsym; @@ -530,6 +543,32 @@ static void assemble(void) { sym = getsym(v->globl.name); sym->global = 1; break; + case ASM_DIR_SECTION: { + size_t i; + const char *fp; + Section *s; + + s = getsection(v->section.name); + s->hdr.sh_type = v->section.type; + fp = v->section.flags; + while (fp && *fp) { + switch (*(fp++)) { + case 'a': + s->hdr.sh_flags |= SHF_ALLOC; + break; + case 'w': + s->hdr.sh_flags |= SHF_WRITE; + break; + case 'x': + s->hdr.sh_flags |= SHF_EXECINSTR; + break; + default: + unreachable(); + } + } + cursection = s; + break; + } case ASM_DIR_DATA: cursection = data; break; @@ -49,6 +49,7 @@ typedef enum { ASM_MEMARG, // Directives ASM_DIR_GLOBL, + ASM_DIR_SECTION, ASM_DIR_ASCII, ASM_DIR_ASCIIZ, ASM_DIR_DATA, @@ -164,6 +165,13 @@ typedef struct { typedef struct { AsmKind kind; + const char *name; + const char *flags; + int type; +} DirSection; + +typedef struct { + AsmKind kind; uint8_t b; } Byte; @@ -231,6 +239,7 @@ union Parsev { AsmKind kind; Label label; Globl globl; + DirSection section; Balign balign; Ascii ascii; Asciiz asciiz; @@ -244,6 +253,9 @@ union Parsev { Ident ident; Number number; String string; + // Temporary values. + const char *charptr; + int64_t i64; }; typedef struct AsmLine AsmLine; |
