1/* ginsn.h - GAS instruction representation. 2 Copyright (C) 2023 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 21#ifndef GINSN_H 22#define GINSN_H 23 24#include "as.h" 25 26/* Maximum number of source operands of a ginsn. */ 27#define GINSN_NUM_SRC_OPNDS 2 28 29/* A ginsn in printed in the following format: 30 "ginsn: OPCD SRC1, SRC2, DST" 31 "<-5-> <--------125------->" 32 where each of SRC1, SRC2, and DST are in the form: 33 "%rNN," (up to 5 chars) 34 "imm," (up to int32_t+1 chars) 35 "[%rNN+-imm]," (up to int32_t+9 chars) 36 Hence a max of 19 chars. */ 37 38#define GINSN_LISTING_OPND_LEN 40 39#define GINSN_LISTING_LEN 156 40 41enum ginsn_gen_mode 42{ 43 GINSN_GEN_NONE, 44 /* Generate ginsns for program validation passes. */ 45 GINSN_GEN_FVAL, 46 /* Generate ginsns for synthesizing DWARF CFI. */ 47 GINSN_GEN_SCFI, 48}; 49 50/* ginsn types. 51 52 GINSN_TYPE_PHANTOM are phantom ginsns. They are used where there is no real 53 machine instruction counterpart, but a ginsn is needed only to carry 54 information to GAS. For example, to carry an SCFI Op. 55 56 Note that, ginsns do not have a push / pop instructions. 57 Instead, following are used: 58 type=GINSN_TYPE_LOAD, src=GINSN_SRC_INDIRECT, REG_SP: Load from stack. 59 type=GINSN_TYPE_STORE, dst=GINSN_DST_INDIRECT, REG_SP: Store to stack. 60*/ 61 62#define _GINSN_TYPES \ 63 _GINSN_TYPE_ITEM (GINSN_TYPE_SYMBOL, "SYM") \ 64 _GINSN_TYPE_ITEM (GINSN_TYPE_PHANTOM, "PHANTOM") \ 65 _GINSN_TYPE_ITEM (GINSN_TYPE_ADD, "ADD") \ 66 _GINSN_TYPE_ITEM (GINSN_TYPE_AND, "AND") \ 67 _GINSN_TYPE_ITEM (GINSN_TYPE_CALL, "CALL") \ 68 _GINSN_TYPE_ITEM (GINSN_TYPE_JUMP, "JMP") \ 69 _GINSN_TYPE_ITEM (GINSN_TYPE_JUMP_COND, "JCC") \ 70 _GINSN_TYPE_ITEM (GINSN_TYPE_MOV, "MOV") \ 71 _GINSN_TYPE_ITEM (GINSN_TYPE_LOAD, "LOAD") \ 72 _GINSN_TYPE_ITEM (GINSN_TYPE_STORE, "STORE") \ 73 _GINSN_TYPE_ITEM (GINSN_TYPE_RETURN, "RET") \ 74 _GINSN_TYPE_ITEM (GINSN_TYPE_SUB, "SUB") \ 75 _GINSN_TYPE_ITEM (GINSN_TYPE_OTHER, "OTH") 76 77enum ginsn_type 78{ 79#define _GINSN_TYPE_ITEM(NAME, STR) NAME, 80 _GINSN_TYPES 81#undef _GINSN_TYPE_ITEM 82}; 83 84enum ginsn_src_type 85{ 86 GINSN_SRC_UNKNOWN, 87 GINSN_SRC_REG, 88 GINSN_SRC_IMM, 89 GINSN_SRC_INDIRECT, 90 GINSN_SRC_SYMBOL, 91}; 92 93/* GAS instruction source operand representation. */ 94 95struct ginsn_src 96{ 97 enum ginsn_src_type type; 98 /* DWARF register number. */ 99 unsigned int reg; 100 /* Immediate or disp for indirect memory access. */ 101 offsetT immdisp; 102 /* Src symbol. May be needed for some control flow instructions. */ 103 const symbolS *sym; 104}; 105 106enum ginsn_dst_type 107{ 108 GINSN_DST_UNKNOWN, 109 GINSN_DST_REG, 110 GINSN_DST_INDIRECT, 111}; 112 113/* GAS instruction destination operand representation. */ 114 115struct ginsn_dst 116{ 117 enum ginsn_dst_type type; 118 /* DWARF register number. */ 119 unsigned int reg; 120 /* Disp for indirect memory access. */ 121 offsetT disp; 122}; 123 124/* Various flags for additional information per GAS instruction. */ 125 126/* Function begin or end symbol. */ 127#define GINSN_F_FUNC_MARKER 0x1 128/* Identify real or implicit GAS insn. 129 Some targets employ CISC-like instructions. Multiple ginsn's may be used 130 for a single machine instruction in some ISAs. For some optimizations, 131 there is need to identify whether a ginsn, e.g., GINSN_TYPE_ADD or 132 GINSN_TYPE_SUB is a result of an user-specified instruction or not. */ 133#define GINSN_F_INSN_REAL 0x2 134/* Identify if the GAS insn of type GINSN_TYPE_SYMBOL is due to a user-defined 135 label. Each user-defined labels in a function will cause addition of a new 136 ginsn. This simplifies control flow graph creation. 137 See htab_t label_ginsn_map usage. */ 138#define GINSN_F_USER_LABEL 0x4 139/* Max bit position for flags (uint32_t). */ 140#define GINSN_F_MAX 0x20 141 142#define GINSN_F_FUNC_BEGIN_P(ginsn) \ 143 ((ginsn != NULL) \ 144 && (ginsn->type == GINSN_TYPE_SYMBOL) \ 145 && (ginsn->flags & GINSN_F_FUNC_MARKER)) 146 147/* PS: For ginsn associated with a user-defined symbol location, 148 GINSN_F_FUNC_MARKER is unset, but GINSN_F_USER_LABEL is set. */ 149#define GINSN_F_FUNC_END_P(ginsn) \ 150 ((ginsn != NULL) \ 151 && (ginsn->type == GINSN_TYPE_SYMBOL) \ 152 && !(ginsn->flags & GINSN_F_FUNC_MARKER) \ 153 && !(ginsn->flags & GINSN_F_USER_LABEL)) 154 155#define GINSN_F_INSN_REAL_P(ginsn) \ 156 ((ginsn != NULL) \ 157 && (ginsn->flags & GINSN_F_INSN_REAL)) 158 159#define GINSN_F_USER_LABEL_P(ginsn) \ 160 ((ginsn != NULL) \ 161 && (ginsn->type == GINSN_TYPE_SYMBOL) \ 162 && !(ginsn->flags & GINSN_F_FUNC_MARKER) \ 163 && (ginsn->flags & GINSN_F_USER_LABEL)) 164 165typedef struct ginsn ginsnS; 166typedef struct scfi_op scfi_opS; 167typedef struct scfi_state scfi_stateS; 168 169/* GAS generic instruction. 170 171 Generic instructions are used by GAS to abstract out the binary machine 172 instructions. In other words, ginsn is a target/ABI independent internal 173 representation for GAS. Note that, depending on the target, there may be 174 more than one ginsn per binary machine instruction. 175 176 ginsns can be used by GAS to perform validations, or even generate 177 additional information like, sythesizing DWARF CFI for hand-written asm. */ 178 179struct ginsn 180{ 181 enum ginsn_type type; 182 /* GAS instructions are simple instructions with GINSN_NUM_SRC_OPNDS number 183 of source operands and one destination operand at this time. */ 184 struct ginsn_src src[GINSN_NUM_SRC_OPNDS]; 185 struct ginsn_dst dst; 186 /* Additional information per instruction. */ 187 uint32_t flags; 188 /* Symbol. For ginsn of type other than GINSN_TYPE_SYMBOL, this identifies 189 the end of the corresponding machine instruction in the .text segment. 190 These symbols are created anew by the targets and are not used elsewhere 191 in GAS. The only exception is some ginsns of type GINSN_TYPE_SYMBOL, when 192 generated for the user-defined labels. See ginsn_frob_label. */ 193 const symbolS *sym; 194 /* Identifier (linearly increasing natural number) for each ginsn. Used as 195 a proxy for program order of ginsns. */ 196 uint64_t id; 197 /* Location information for user-interfacing messaging. Only ginsns with 198 GINSN_F_FUNC_BEGIN_P and GINSN_F_FUNC_END_P may present themselves with no 199 file or line information. */ 200 const char *file; 201 unsigned int line; 202 203 /* Information needed for synthesizing CFI. */ 204 scfi_opS **scfi_ops; 205 uint32_t num_scfi_ops; 206 207 /* Flag to keep track of visited instructions for CFG creation. */ 208 bool visited; 209 210 ginsnS *next; /* A linked list. */ 211}; 212 213struct ginsn_src *ginsn_get_src1 (ginsnS *ginsn); 214struct ginsn_src *ginsn_get_src2 (ginsnS *ginsn); 215struct ginsn_dst *ginsn_get_dst (ginsnS *ginsn); 216 217unsigned int ginsn_get_src_reg (struct ginsn_src *src); 218enum ginsn_src_type ginsn_get_src_type (struct ginsn_src *src); 219offsetT ginsn_get_src_disp (struct ginsn_src *src); 220offsetT ginsn_get_src_imm (struct ginsn_src *src); 221 222unsigned int ginsn_get_dst_reg (struct ginsn_dst *dst); 223enum ginsn_dst_type ginsn_get_dst_type (struct ginsn_dst *dst); 224offsetT ginsn_get_dst_disp (struct ginsn_dst *dst); 225 226/* Data object for book-keeping information related to GAS generic 227 instructions. */ 228struct frch_ginsn_data 229{ 230 /* Mode for GINSN creation. */ 231 enum ginsn_gen_mode mode; 232 /* Head of the list of ginsns. */ 233 ginsnS *gins_rootP; 234 /* Tail of the list of ginsns. */ 235 ginsnS *gins_lastP; 236 /* Function symbol. */ 237 const symbolS *func; 238 /* Start address of the function. */ 239 symbolS *start_addr; 240 /* User-defined label to ginsn mapping. */ 241 htab_t label_ginsn_map; 242 /* Is the list of ginsn apt for creating CFG. */ 243 bool gcfg_apt_p; 244}; 245 246int ginsn_data_begin (const symbolS *func); 247int ginsn_data_end (const symbolS *label); 248const symbolS *ginsn_data_func_symbol (void); 249void ginsn_frob_label (const symbolS *sym); 250 251void frch_ginsn_data_init (const symbolS *func, symbolS *start_addr, 252 enum ginsn_gen_mode gmode); 253void frch_ginsn_data_cleanup (void); 254int frch_ginsn_data_append (ginsnS *ginsn); 255enum ginsn_gen_mode frch_ginsn_gen_mode (void); 256 257void label_ginsn_map_insert (const symbolS *label, ginsnS *ginsn); 258ginsnS *label_ginsn_map_find (const symbolS *label); 259 260ginsnS *ginsn_new_symbol_func_begin (const symbolS *sym); 261ginsnS *ginsn_new_symbol_func_end (const symbolS *sym); 262ginsnS *ginsn_new_symbol_user_label (const symbolS *sym); 263 264ginsnS *ginsn_new_phantom (const symbolS *sym); 265ginsnS *ginsn_new_symbol (const symbolS *sym, bool real_p); 266ginsnS *ginsn_new_add (const symbolS *sym, bool real_p, 267 enum ginsn_src_type src1_type, unsigned int src1_reg, offsetT src1_disp, 268 enum ginsn_src_type src2_type, unsigned int src2_reg, offsetT src2_disp, 269 enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp); 270ginsnS *ginsn_new_and (const symbolS *sym, bool real_p, 271 enum ginsn_src_type src1_type, unsigned int src1_reg, offsetT src1_disp, 272 enum ginsn_src_type src2_type, unsigned int src2_reg, offsetT src2_disp, 273 enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp); 274ginsnS *ginsn_new_call (const symbolS *sym, bool real_p, 275 enum ginsn_src_type src_type, unsigned int src_reg, 276 const symbolS *src_text_sym); 277ginsnS *ginsn_new_jump (const symbolS *sym, bool real_p, 278 enum ginsn_src_type src_type, unsigned int src_reg, 279 const symbolS *src_ginsn_sym); 280ginsnS *ginsn_new_jump_cond (const symbolS *sym, bool real_p, 281 enum ginsn_src_type src_type, unsigned int src_reg, 282 const symbolS *src_ginsn_sym); 283ginsnS *ginsn_new_mov (const symbolS *sym, bool real_p, 284 enum ginsn_src_type src_type, unsigned int src_reg, offsetT src_disp, 285 enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp); 286ginsnS *ginsn_new_store (const symbolS *sym, bool real_p, 287 enum ginsn_src_type src_type, unsigned int src_reg, 288 enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp); 289ginsnS *ginsn_new_load (const symbolS *sym, bool real_p, 290 enum ginsn_src_type src_type, unsigned int src_reg, offsetT src_disp, 291 enum ginsn_dst_type dst_type, unsigned int dst_reg); 292ginsnS *ginsn_new_sub (const symbolS *sym, bool real_p, 293 enum ginsn_src_type src1_type, unsigned int src1_reg, offsetT src1_disp, 294 enum ginsn_src_type src2_type, unsigned int src2_reg, offsetT src2_disp, 295 enum ginsn_dst_type dst_type, unsigned int dst_reg, offsetT dst_disp); 296ginsnS *ginsn_new_other (const symbolS *sym, bool real_p, 297 enum ginsn_src_type src1_type, unsigned int src1_val, 298 enum ginsn_src_type src2_type, unsigned int src2_val, 299 enum ginsn_dst_type dst_type, unsigned int dst_reg); 300ginsnS *ginsn_new_return (const symbolS *sym, bool real_p); 301 302void ginsn_set_where (ginsnS *ginsn); 303 304bool ginsn_track_reg_p (unsigned int dw2reg, enum ginsn_gen_mode); 305 306int ginsn_link_next (ginsnS *ginsn, ginsnS *next); 307 308enum gcfg_err_code 309{ 310 GCFG_OK = 0, 311 GCFG_JLABEL_NOT_PRESENT = 1, /* Warning-level code. */ 312}; 313 314typedef struct gbb gbbS; 315typedef struct gedge gedgeS; 316 317/* GBB - Basic block of generic GAS instructions. */ 318 319struct gbb 320{ 321 ginsnS *first_ginsn; 322 ginsnS *last_ginsn; 323 uint64_t num_ginsns; 324 325 /* Identifier (linearly increasing natural number) for each gbb. Added for 326 debugging purpose only. */ 327 uint64_t id; 328 329 bool visited; 330 331 uint32_t num_out_gedges; 332 gedgeS *out_gedges; 333 334 /* Members for SCFI purposes. */ 335 /* SCFI state at the entry of basic block. */ 336 scfi_stateS *entry_state; 337 /* SCFI state at the exit of basic block. */ 338 scfi_stateS *exit_state; 339 340 /* A linked list. In order of addition. */ 341 gbbS *next; 342}; 343 344struct gedge 345{ 346 gbbS *dst_bb; 347 /* A linked list. In order of addition. */ 348 gedgeS *next; 349 bool visited; 350}; 351 352/* Control flow graph of generic GAS instructions. */ 353 354struct gcfg 355{ 356 uint64_t num_gbbs; 357 gbbS *root_bb; 358}; 359 360typedef struct gcfg gcfgS; 361 362#define bb_for_each_insn(bb, ginsn) \ 363 for (ginsn = bb->first_ginsn; ginsn; \ 364 ginsn = (ginsn != bb->last_ginsn) ? ginsn->next : NULL) 365 366#define bb_for_each_edge(bb, edge) \ 367 for (edge = (edge == NULL) ? bb->out_gedges : edge; edge; edge = edge->next) 368 369#define cfg_for_each_bb(cfg, bb) \ 370 for (bb = cfg->root_bb; bb; bb = bb->next) 371 372#define bb_get_first_ginsn(bb) \ 373 (bb->first_ginsn) 374 375#define bb_get_last_ginsn(bb) \ 376 (bb->last_ginsn) 377 378gcfgS *gcfg_build (const symbolS *func, int *errp); 379void gcfg_cleanup (gcfgS **gcfg); 380void gcfg_print (const gcfgS *gcfg, FILE *outfile); 381gbbS *gcfg_get_rootbb (gcfgS *gcfg); 382void gcfg_get_bbs_in_prog_order (gcfgS *gcfg, gbbS **prog_order_bbs); 383 384#endif /* GINSN_H. */ 385