void free_format_pieces_cleanup (void *ptr) { void **location = ptr; if (location == NULL) return; if (*location != NULL) { free_format_pieces (*location); *location = NULL; } }
static void ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format, int nargs, ULONGEST *args) { const char *f = format; struct format_piece *fpieces; int i, fp; char *current_substring; int nargs_wanted; ax_debug ("Printf of \"%s\" with %d args", format, nargs); fpieces = parse_format_string (&f); nargs_wanted = 0; for (fp = 0; fpieces[fp].string != NULL; fp++) if (fpieces[fp].argclass != literal_piece) ++nargs_wanted; if (nargs != nargs_wanted) error (_("Wrong number of arguments for specified format-string")); i = 0; for (fp = 0; fpieces[fp].string != NULL; fp++) { current_substring = fpieces[fp].string; ax_debug ("current substring is '%s', class is %d", current_substring, fpieces[fp].argclass); switch (fpieces[fp].argclass) { case string_arg: { gdb_byte *str; CORE_ADDR tem; int j; tem = args[i]; /* This is a %s argument. Find the length of the string. */ for (j = 0;; j++) { gdb_byte c; read_inferior_memory (tem + j, &c, 1); if (c == 0) break; } /* Copy the string contents into a string inside GDB. */ str = (gdb_byte *) alloca (j + 1); if (j != 0) read_inferior_memory (tem, str, j); str[j] = 0; printf (current_substring, (char *) str); } break; case long_long_arg: #if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG) { long long val = args[i]; printf (current_substring, val); break; } #else error (_("long long not supported in agent printf")); #endif case int_arg: { int val = args[i]; printf (current_substring, val); break; } case long_arg: { long val = args[i]; printf (current_substring, val); break; } case literal_piece: /* Print a portion of the format string that has no directives. Note that this will not include any ordinary %-specs, but it might include "%%". That is why we use printf_filtered and not puts_filtered here. Also, we pass a dummy argument because some platforms have modified GCC to include -Wformat-security by default, which will warn here if there is no argument. */ printf (current_substring, 0); break; default: error (_("Format directive in '%s' not supported in agent printf"), current_substring); } /* Maybe advance to the next argument. */ if (fpieces[fp].argclass != literal_piece) ++i; } free_format_pieces (fpieces); fflush (stdout); }