From 18fa204fad3aa62594e973cbdc77326827b651a1 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Thu, 10 Apr 2014 18:41:25 +0000 Subject: [PATCH] as: add ".type ,@function" support --- as/input.c | 21 +++++++++++++++++++++ as/parse.c | 29 +++++++++++++++++++++++++++++ as/token.def | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/as/input.c b/as/input.c index 9964c11..819f99d 100644 --- a/as/input.c +++ b/as/input.c @@ -90,6 +90,25 @@ static int do_dot_text(struct scan_state *scan_state, struct tunit *tunit, struc return 0; } +static int do_dot_type_function(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt) +{ + struct symbol *symbol; + + symbol = tunit_symbol_enter(tunit, stmt->u.symbol.name); + if (!symbol) + return -1; + + if (ELF_ST_TYPE(symbol->st_info) != STT_NOTYPE) { + fprintf(stderr, "%s: %s line %u: symbol %s already has non-zero type %u\n", + scan_state->progname, scan_state->filename, scan_state->linenr, stmt->u.symbol.name, ELF_ST_TYPE(symbol->st_info)); + return -1; + } + + symbol->st_info = ELF_ST_INFO(ELF_ST_BIND(symbol->st_info), STT_FUNC); + + return 0; +} + static int do_label(struct scan_state *scan_state, struct tunit *tunit, struct stmt *stmt) { struct symbol *symbol; @@ -135,6 +154,8 @@ static int interpret(struct scan_state *scan_state, struct tunit *tunit, struct return do_dot_globl(scan_state, tunit, stmt); case S_DOT_TEXT: return do_dot_text(scan_state, tunit, stmt); + case S_DOT_TYPE_FUNCTION: + return do_dot_type_function(scan_state, tunit, stmt); case S_LABEL: return do_label(scan_state, tunit, stmt); case S_INSN: diff --git a/as/parse.c b/as/parse.c index 3dd9ebb..f7e2eb6 100644 --- a/as/parse.c +++ b/as/parse.c @@ -66,6 +66,33 @@ static int parse_dot_text(struct scan_state *scan_state, struct stmt *stmt) return error(scan_state, "junk after .text directive", token, &token_attr); } +static int parse_dot_type(struct scan_state *scan_state, struct stmt *stmt) +{ + enum token token; + union token_attribute token_attr; + + token = scan_token(scan_state, &token_attr); + if (token == T_SYMBOL) { + stmt->u.symbol.name = token_attr.text; + token = scan_token(scan_state, &token_attr); + if (token == T_COMMA) { + token = scan_token(scan_state, &token_attr); + if (token == T_AT) { + token = scan_token(scan_state, &token_attr); + if (token == T_SYMBOL + && strcmp(token_attr.text, "function") == 0) { + token = scan_token(scan_state, &token_attr); + if (token == T_NEWLINE) { + stmt->tag = S_DOT_TYPE_FUNCTION; + return 1; + } + } + } + } + } + return error(scan_state, "junk after .type directive", token, &token_attr); +} + /* * Recognize: * @@ -353,6 +380,8 @@ int parse_stmt(struct scan_state *scan_state, struct stmt *stmt) return parse_dot_globl(scan_state, stmt); case T_DOT_TEXT: return parse_dot_text(scan_state, stmt); + case T_DOT_TYPE: + return parse_dot_type(scan_state, stmt); /* * other symbols */ diff --git a/as/token.def b/as/token.def index 20f292b..fa778d5 100644 --- a/as/token.def +++ b/as/token.def @@ -8,6 +8,7 @@ TOKEN(T_DOT_FILE, ".file", TAFMT_NONE) TOKEN(T_DOT_GLOBL, ".globl", TAFMT_NONE) TOKEN(T_DOT_TEXT, ".text", TAFMT_NONE) +TOKEN(T_DOT_TYPE, ".type", TAFMT_NONE) /* non-reserved symbols; T_SYMBOL MUST be the first token after the list of reserved symbols */ TOKEN(T_SYMBOL, "", TAFMT_SYMBOL) /* literals */ @@ -52,7 +53,6 @@ TOKEN(T_DOT_SHORT, ".short", TAFMT_NONE) TOKEN(T_DOT_SIZE, ".size", TAFMT_NONE) TOKEN(T_DOT_SUBSECTION, ".subsection", TAFMT_NONE) TOKEN(T_DOT_SYMVER, ".symver", TAFMT_NONE) -TOKEN(T_DOT_TYPE, ".type", TAFMT_NONE) TOKEN(T_DOT_WEAK, ".weak", TAFMT_NONE) TOKEN(T_DOT_WEAKREF, ".weakref", TAFMT_NONE) /* other symbols */