1#!/usr/bin/env python3 2 3# Architecture commands for GDB, the GNU debugger. 4# 5# Copyright (C) 1998-2023 Free Software Foundation, Inc. 6# 7# This file is part of GDB. 8# 9# This program is free software; you can redistribute it and/or modify 10# it under the terms of the GNU General Public License as published by 11# the Free Software Foundation; either version 3 of the License, or 12# (at your option) any later version. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22import textwrap 23import gdbcopyright 24 25# All the components created in gdbarch-components.py. 26components = [] 27 28 29def indentation(n_columns): 30 """Return string with tabs and spaces to indent line to N_COLUMNS.""" 31 return "\t" * (n_columns // 8) + " " * (n_columns % 8) 32 33 34def join_type_and_name(t, n): 35 "Combine the type T and the name N into a C declaration." 36 if t.endswith("*") or t.endswith("&"): 37 return t + n 38 else: 39 return t + " " + n 40 41 42def join_params(params): 43 """Given a sequence of (TYPE, NAME) pairs, generate a comma-separated 44 list of declarations.""" 45 params = [join_type_and_name(p[0], p[1]) for p in params] 46 return ", ".join(params) 47 48 49class _Component: 50 "Base class for all components." 51 52 def __init__(self, **kwargs): 53 for key in kwargs: 54 setattr(self, key, kwargs[key]) 55 components.append(self) 56 57 # It doesn't make sense to have a check of the result value 58 # for a function or method with void return type. 59 if self.type == "void" and self.result_checks: 60 raise Exception("can't have result checks with a void return type") 61 62 def get_predicate(self): 63 "Return the expression used for validity checking." 64 assert self.predicate and not isinstance(self.invalid, str) 65 if self.predefault: 66 predicate = f"gdbarch->{self.name} != {self.predefault}" 67 elif isinstance(c, Value): 68 predicate = f"gdbarch->{self.name} != 0" 69 else: 70 predicate = f"gdbarch->{self.name} != NULL" 71 return predicate 72 73 74class Info(_Component): 75 "An Info component is copied from the gdbarch_info." 76 77 def __init__(self, *, name, type, printer=None): 78 super().__init__(name=name, type=type, printer=printer) 79 # This little hack makes the generator a bit simpler. 80 self.predicate = None 81 82 83class Value(_Component): 84 "A Value component is just a data member." 85 86 def __init__( 87 self, 88 *, 89 name, 90 type, 91 comment=None, 92 predicate=None, 93 predefault=None, 94 postdefault=None, 95 invalid=None, 96 printer=None, 97 ): 98 super().__init__( 99 comment=comment, 100 name=name, 101 type=type, 102 predicate=predicate, 103 predefault=predefault, 104 postdefault=postdefault, 105 invalid=invalid, 106 printer=printer, 107 ) 108 109 110class Function(_Component): 111 "A Function component is a function pointer member." 112 113 def __init__( 114 self, 115 *, 116 name, 117 type, 118 params, 119 comment=None, 120 predicate=None, 121 predefault=None, 122 postdefault=None, 123 invalid=None, 124 printer=None, 125 param_checks=None, 126 result_checks=None, 127 ): 128 super().__init__( 129 comment=comment, 130 name=name, 131 type=type, 132 predicate=predicate, 133 predefault=predefault, 134 postdefault=postdefault, 135 invalid=invalid, 136 printer=printer, 137 params=params, 138 param_checks=param_checks, 139 result_checks=result_checks, 140 ) 141 142 def ftype(self): 143 "Return the name of the function typedef to use." 144 return f"gdbarch_{self.name}_ftype" 145 146 def param_list(self): 147 "Return the formal parameter list as a string." 148 return join_params(self.params) 149 150 def set_list(self): 151 """Return the formal parameter list of the caller function, 152 as a string. This list includes the gdbarch.""" 153 arch_arg = ("struct gdbarch *", "gdbarch") 154 arch_tuple = [arch_arg] 155 return join_params(arch_tuple + list(self.params)) 156 157 def actuals(self): 158 "Return the actual parameters to forward, as a string." 159 return ", ".join([p[1] for p in self.params]) 160 161 162class Method(Function): 163 "A Method is like a Function but passes the gdbarch through." 164 165 def param_list(self): 166 "See superclass." 167 return self.set_list() 168 169 def actuals(self): 170 "See superclass." 171 result = ["gdbarch"] + [p[1] for p in self.params] 172 return ", ".join(result) 173 174 175# Read the components. 176with open("gdbarch-components.py") as fd: 177 exec(fd.read()) 178 179copyright = gdbcopyright.copyright( 180 "gdbarch.py", "Dynamic architecture support for GDB, the GNU debugger." 181) 182 183 184def info(c): 185 "Filter function to only allow Info components." 186 return type(c) is Info 187 188 189def not_info(c): 190 "Filter function to omit Info components." 191 return type(c) is not Info 192 193 194with open("gdbarch-gen.h", "w") as f: 195 print(copyright, file=f) 196 print(file=f) 197 print(file=f) 198 print("/* The following are pre-initialized by GDBARCH. */", file=f) 199 200 # Do Info components first. 201 for c in filter(info, components): 202 print(file=f) 203 print( 204 f"""extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch); 205/* set_gdbarch_{c.name}() - not applicable - pre-initialized. */""", 206 file=f, 207 ) 208 209 print(file=f) 210 print(file=f) 211 print("/* The following are initialized by the target dependent code. */", file=f) 212 213 # Generate decls for accessors, setters, and predicates for all 214 # non-Info components. 215 for c in filter(not_info, components): 216 if c.comment: 217 print(file=f) 218 comment = c.comment.split("\n") 219 if comment[0] == "": 220 comment = comment[1:] 221 if comment[-1] == "": 222 comment = comment[:-1] 223 print("/* ", file=f, end="") 224 print(comment[0], file=f, end="") 225 if len(comment) > 1: 226 print(file=f) 227 print( 228 textwrap.indent("\n".join(comment[1:]), prefix=" "), 229 end="", 230 file=f, 231 ) 232 print(" */", file=f) 233 234 if c.predicate: 235 print(file=f) 236 print(f"extern bool gdbarch_{c.name}_p (struct gdbarch *gdbarch);", file=f) 237 238 print(file=f) 239 if isinstance(c, Value): 240 print( 241 f"extern {c.type} gdbarch_{c.name} (struct gdbarch *gdbarch);", 242 file=f, 243 ) 244 print( 245 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.type} {c.name});", 246 file=f, 247 ) 248 else: 249 assert isinstance(c, Function) 250 print( 251 f"typedef {c.type} ({c.ftype()}) ({c.param_list()});", 252 file=f, 253 ) 254 print( 255 f"extern {c.type} gdbarch_{c.name} ({c.set_list()});", 256 file=f, 257 ) 258 print( 259 f"extern void set_gdbarch_{c.name} (struct gdbarch *gdbarch, {c.ftype()} *{c.name});", 260 file=f, 261 ) 262 263with open("gdbarch.c", "w") as f: 264 print(copyright, file=f) 265 print(file=f) 266 print("/* Maintain the struct gdbarch object. */", file=f) 267 print(file=f) 268 # 269 # The struct definition body. 270 # 271 print("struct gdbarch", file=f) 272 print("{", file=f) 273 print(" /* Has this architecture been fully initialized? */", file=f) 274 print(" bool initialized_p = false;", file=f) 275 print(file=f) 276 print(" /* An obstack bound to the lifetime of the architecture. */", file=f) 277 print(" auto_obstack obstack;", file=f) 278 print(" /* Registry. */", file=f) 279 print(" registry<gdbarch> registry_fields;", file=f) 280 print(file=f) 281 print(" /* basic architectural information. */", file=f) 282 for c in filter(info, components): 283 print(f" {c.type} {c.name};", file=f) 284 print(file=f) 285 print(" /* target specific vector. */", file=f) 286 print(" struct gdbarch_tdep_base *tdep = nullptr;", file=f) 287 print(" gdbarch_dump_tdep_ftype *dump_tdep = nullptr;", file=f) 288 print(file=f) 289 print(" /* per-architecture data-pointers. */", file=f) 290 print(" unsigned nr_data = 0;", file=f) 291 print(" void **data = nullptr;", file=f) 292 print(file=f) 293 for c in filter(not_info, components): 294 if isinstance(c, Function): 295 print(f" gdbarch_{c.name}_ftype *", file=f, end="") 296 else: 297 print(f" {c.type} ", file=f, end="") 298 print(f"{c.name} = ", file=f, end="") 299 if c.predefault is not None: 300 print(f"{c.predefault};", file=f) 301 elif isinstance(c, Value): 302 print("0;", file=f) 303 else: 304 assert isinstance(c, Function) 305 print("nullptr;", file=f) 306 print("};", file=f) 307 print(file=f) 308 # 309 # Initialization. 310 # 311 print("/* Create a new ``struct gdbarch'' based on information provided by", file=f) 312 print(" ``struct gdbarch_info''. */", file=f) 313 print(file=f) 314 print("struct gdbarch *", file=f) 315 print("gdbarch_alloc (const struct gdbarch_info *info,", file=f) 316 print(" struct gdbarch_tdep_base *tdep)", file=f) 317 print("{", file=f) 318 print(" struct gdbarch *gdbarch;", file=f) 319 print("", file=f) 320 print(" gdbarch = new struct gdbarch;", file=f) 321 print(file=f) 322 print(" gdbarch->tdep = tdep;", file=f) 323 print(file=f) 324 for c in filter(info, components): 325 print(f" gdbarch->{c.name} = info->{c.name};", file=f) 326 print(file=f) 327 print(" return gdbarch;", file=f) 328 print("}", file=f) 329 print(file=f) 330 print(file=f) 331 print(file=f) 332 # 333 # Post-initialization validation and updating 334 # 335 print("/* Ensure that all values in a GDBARCH are reasonable. */", file=f) 336 print(file=f) 337 print("static void", file=f) 338 print("verify_gdbarch (struct gdbarch *gdbarch)", file=f) 339 print("{", file=f) 340 print(" string_file log;", file=f) 341 print(file=f) 342 print(" /* fundamental */", file=f) 343 print(" if (gdbarch->byte_order == BFD_ENDIAN_UNKNOWN)", file=f) 344 print(""" log.puts ("\\n\\tbyte-order");""", file=f) 345 print(" if (gdbarch->bfd_arch_info == NULL)", file=f) 346 print(""" log.puts ("\\n\\tbfd_arch_info");""", file=f) 347 print( 348 " /* Check those that need to be defined for the given multi-arch level. */", 349 file=f, 350 ) 351 for c in filter(not_info, components): 352 if c.invalid is False: 353 print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f) 354 elif c.predicate: 355 print(f" /* Skip verify of {c.name}, has predicate. */", file=f) 356 elif isinstance(c.invalid, str) and c.postdefault is not None: 357 print(f" if ({c.invalid})", file=f) 358 print(f" gdbarch->{c.name} = {c.postdefault};", file=f) 359 elif c.predefault is not None and c.postdefault is not None: 360 print(f" if (gdbarch->{c.name} == {c.predefault})", file=f) 361 print(f" gdbarch->{c.name} = {c.postdefault};", file=f) 362 elif c.postdefault is not None: 363 print(f" if (gdbarch->{c.name} == 0)", file=f) 364 print(f" gdbarch->{c.name} = {c.postdefault};", file=f) 365 elif isinstance(c.invalid, str): 366 print(f" if ({c.invalid})", file=f) 367 print(f""" log.puts ("\\n\\t{c.name}");""", file=f) 368 elif c.predefault is not None: 369 print(f" if (gdbarch->{c.name} == {c.predefault})", file=f) 370 print(f""" log.puts ("\\n\\t{c.name}");""", file=f) 371 elif c.invalid is True: 372 print(f" if (gdbarch->{c.name} == 0)", file=f) 373 print(f""" log.puts ("\\n\\t{c.name}");""", file=f) 374 else: 375 # We should not allow ourselves to simply do nothing here 376 # because no other case applies. If we end up here then 377 # either the input data needs adjusting so one of the 378 # above cases matches, or we need additional cases adding 379 # here. 380 raise Exception("unhandled case when generating gdbarch validation") 381 print(" if (!log.empty ())", file=f) 382 print( 383 """ internal_error (_("verify_gdbarch: the following are invalid ...%s"),""", 384 file=f, 385 ) 386 print(" log.c_str ());", file=f) 387 print("}", file=f) 388 print(file=f) 389 print(file=f) 390 # 391 # Dumping. 392 # 393 print("/* Print out the details of the current architecture. */", file=f) 394 print(file=f) 395 print("void", file=f) 396 print("gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)", file=f) 397 print("{", file=f) 398 print(""" const char *gdb_nm_file = "<not-defined>";""", file=f) 399 print(file=f) 400 print("#if defined (GDB_NM_FILE)", file=f) 401 print(" gdb_nm_file = GDB_NM_FILE;", file=f) 402 print("#endif", file=f) 403 print(" gdb_printf (file,", file=f) 404 print(""" "gdbarch_dump: GDB_NM_FILE = %s\\n",""", file=f) 405 print(" gdb_nm_file);", file=f) 406 for c in components: 407 if c.predicate: 408 print(" gdb_printf (file,", file=f) 409 print( 410 f""" "gdbarch_dump: gdbarch_{c.name}_p() = %d\\n",""", 411 file=f, 412 ) 413 print(f" gdbarch_{c.name}_p (gdbarch));", file=f) 414 if isinstance(c, Function): 415 print(" gdb_printf (file,", file=f) 416 print(f""" "gdbarch_dump: {c.name} = <%s>\\n",""", file=f) 417 print( 418 f" host_address_to_string (gdbarch->{c.name}));", 419 file=f, 420 ) 421 else: 422 if c.printer: 423 printer = c.printer 424 elif c.type == "CORE_ADDR": 425 printer = f"core_addr_to_string_nz (gdbarch->{c.name})" 426 else: 427 printer = f"plongest (gdbarch->{c.name})" 428 print(" gdb_printf (file,", file=f) 429 print(f""" "gdbarch_dump: {c.name} = %s\\n",""", file=f) 430 print(f" {printer});", file=f) 431 print(" if (gdbarch->dump_tdep != NULL)", file=f) 432 print(" gdbarch->dump_tdep (gdbarch, file);", file=f) 433 print("}", file=f) 434 print(file=f) 435 # 436 # Bodies of setter, accessor, and predicate functions. 437 # 438 for c in components: 439 if c.predicate: 440 print(file=f) 441 print("bool", file=f) 442 print(f"gdbarch_{c.name}_p (struct gdbarch *gdbarch)", file=f) 443 print("{", file=f) 444 print(" gdb_assert (gdbarch != NULL);", file=f) 445 print(f" return {c.get_predicate()};", file=f) 446 print("}", file=f) 447 if isinstance(c, Function): 448 print(file=f) 449 print(f"{c.type}", file=f) 450 print(f"gdbarch_{c.name} ({c.set_list()})", file=f) 451 print("{", file=f) 452 print(" gdb_assert (gdbarch != NULL);", file=f) 453 print(f" gdb_assert (gdbarch->{c.name} != NULL);", file=f) 454 if c.predicate and c.predefault: 455 # Allow a call to a function with a predicate. 456 print( 457 f" /* Do not check predicate: {c.get_predicate()}, allow call. */", 458 file=f, 459 ) 460 if c.param_checks: 461 for rule in c.param_checks: 462 print(f" gdb_assert ({rule});", file=f) 463 print(" if (gdbarch_debug >= 2)", file=f) 464 print( 465 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""", 466 file=f, 467 ) 468 print(" ", file=f, end="") 469 if c.type != "void": 470 if c.result_checks: 471 print("auto result = ", file=f, end="") 472 else: 473 print("return ", file=f, end="") 474 print(f"gdbarch->{c.name} ({c.actuals()});", file=f) 475 if c.type != "void" and c.result_checks: 476 for rule in c.result_checks: 477 print(f" gdb_assert ({rule});", file=f) 478 print(" return result;", file=f) 479 print("}", file=f) 480 print(file=f) 481 print("void", file=f) 482 setter_name = f"set_gdbarch_{c.name}" 483 ftype_name = f"gdbarch_{c.name}_ftype" 484 print(f"{setter_name} (struct gdbarch *gdbarch,", file=f) 485 indent_columns = len(f"{setter_name} (") 486 print(f"{indentation(indent_columns)}{ftype_name} {c.name})", file=f) 487 print("{", file=f) 488 print(f" gdbarch->{c.name} = {c.name};", file=f) 489 print("}", file=f) 490 elif isinstance(c, Value): 491 print(file=f) 492 print(f"{c.type}", file=f) 493 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f) 494 print("{", file=f) 495 print(" gdb_assert (gdbarch != NULL);", file=f) 496 if c.invalid is False: 497 print(f" /* Skip verify of {c.name}, invalid_p == 0 */", file=f) 498 elif isinstance(c.invalid, str): 499 print(" /* Check variable is valid. */", file=f) 500 print(f" gdb_assert (!({c.invalid}));", file=f) 501 elif c.predefault: 502 print(" /* Check variable changed from pre-default. */", file=f) 503 print(f" gdb_assert (gdbarch->{c.name} != {c.predefault});", file=f) 504 print(" if (gdbarch_debug >= 2)", file=f) 505 print( 506 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""", 507 file=f, 508 ) 509 print(f" return gdbarch->{c.name};", file=f) 510 print("}", file=f) 511 print(file=f) 512 print("void", file=f) 513 setter_name = f"set_gdbarch_{c.name}" 514 print(f"{setter_name} (struct gdbarch *gdbarch,", file=f) 515 indent_columns = len(f"{setter_name} (") 516 print(f"{indentation(indent_columns)}{c.type} {c.name})", file=f) 517 print("{", file=f) 518 print(f" gdbarch->{c.name} = {c.name};", file=f) 519 print("}", file=f) 520 else: 521 assert isinstance(c, Info) 522 print(file=f) 523 print(f"{c.type}", file=f) 524 print(f"gdbarch_{c.name} (struct gdbarch *gdbarch)", file=f) 525 print("{", file=f) 526 print(" gdb_assert (gdbarch != NULL);", file=f) 527 print(" if (gdbarch_debug >= 2)", file=f) 528 print( 529 f""" gdb_printf (gdb_stdlog, "gdbarch_{c.name} called\\n");""", 530 file=f, 531 ) 532 print(f" return gdbarch->{c.name};", file=f) 533 print("}", file=f) 534