char * go_demangle (const char *mangled_name, int options) { struct obstack tempbuf; char *result; char *name_buf; const char *package_name; const char *object_name; const char *method_type_package_name; const char *method_type_object_name; int method_type_is_pointer; if (mangled_name == NULL) return NULL; name_buf = unpack_mangled_go_symbol (mangled_name, &package_name, &object_name, &method_type_package_name, &method_type_object_name, &method_type_is_pointer); if (name_buf == NULL) return NULL; obstack_init (&tempbuf); /* Print methods as they appear in "method expressions". */ if (method_type_package_name != NULL) { /* FIXME: Seems like we should include package_name here somewhere. */ if (method_type_is_pointer) obstack_grow_str (&tempbuf, "(*"); obstack_grow_str (&tempbuf, method_type_package_name); obstack_grow_str (&tempbuf, "."); obstack_grow_str (&tempbuf, method_type_object_name); if (method_type_is_pointer) obstack_grow_str (&tempbuf, ")"); obstack_grow_str (&tempbuf, "."); obstack_grow_str (&tempbuf, object_name); } else { obstack_grow_str (&tempbuf, package_name); obstack_grow_str (&tempbuf, "."); obstack_grow_str (&tempbuf, object_name); } obstack_grow_str0 (&tempbuf, ""); result = xstrdup ((const char *) obstack_finish (&tempbuf)); obstack_free (&tempbuf, NULL); xfree (name_buf); return result; }
static LONGEST windows_core_xfer_shared_libraries (struct gdbarch *gdbarch, gdb_byte *readbuf, ULONGEST offset, LONGEST len) { struct obstack obstack; const char *buf; LONGEST len_avail; struct cpms_data data = { gdbarch, &obstack, 0 }; obstack_init (&obstack); obstack_grow_str (&obstack, "<library-list>\n"); bfd_map_over_sections (core_bfd, core_process_module_section, &data); obstack_grow_str0 (&obstack, "</library-list>\n"); buf = obstack_finish (&obstack); len_avail = strlen (buf); if (offset >= len_avail) return 0; if (len > len_avail - offset) len = len_avail - offset; memcpy (readbuf, buf + offset, len); obstack_free (&obstack, NULL); return len; }
void win32_xfer_shared_library (const char* so_name, CORE_ADDR load_addr, struct obstack *obstack) { char *p; obstack_grow_str (obstack, "<library name=\""); p = xml_escape_text (so_name); obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\"><segment address=\"0x"); /* The symbols in a dll are offset by 0x1000, which is the the offset from 0 of the first byte in an image - because of the file header and the section alignment. */ p = paddr_nz (load_addr + 0x1000); obstack_grow_str (obstack, p); obstack_grow_str (obstack, "\"/></library>"); }
/* Extract identifiers from MANGLED_STR and append it to TEMPBUF. Return 1 on success or 0 on failure. */ static int extract_identifiers (const char *mangled_str, struct obstack *tempbuf) { long i = 0; while (isdigit (*mangled_str)) { char *end_ptr; i = strtol (mangled_str, &end_ptr, 10); mangled_str = end_ptr; if (i <= 0 || strlen (mangled_str) < i) return 0; obstack_grow (tempbuf, mangled_str, i); mangled_str += i; obstack_grow_str (tempbuf, "."); } if (*mangled_str == '\0' || i == 0) return 0; obstack_blank (tempbuf, -1); return 1; }
void convert_between_encodings (const char *from, const char *to, const gdb_byte *bytes, unsigned int num_bytes, int width, struct obstack *output, enum transliterations translit) { iconv_t desc; struct cleanup *cleanups; size_t inleft; char *inp; unsigned int space_request; /* Often, the host and target charsets will be the same. */ if (!strcmp (from, to)) { obstack_grow (output, bytes, num_bytes); return; } desc = iconv_open (to, from); if (desc == (iconv_t) -1) perror_with_name (_("Converting character sets")); cleanups = make_cleanup (cleanup_iconv, &desc); inleft = num_bytes; inp = (char *) bytes; space_request = num_bytes; while (inleft > 0) { char *outp; size_t outleft, r; int old_size; old_size = obstack_object_size (output); obstack_blank (output, space_request); outp = obstack_base (output) + old_size; outleft = space_request; r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft); /* Now make sure that the object on the obstack only includes bytes we have converted. */ obstack_blank (output, - (int) outleft); if (r == (size_t) -1) { switch (errno) { case EILSEQ: { int i; /* Invalid input sequence. */ if (translit == translit_none) error (_("Could not convert character " "to `%s' character set"), to); /* We emit escape sequence for the bytes, skip them, and try again. */ for (i = 0; i < width; ++i) { char octal[5]; xsnprintf (octal, sizeof (octal), "\\%.3o", *inp & 0xff); obstack_grow_str (output, octal); ++inp; --inleft; } } break; case E2BIG: /* We ran out of space in the output buffer. Make it bigger next time around. */ space_request *= 2; break; case EINVAL: /* Incomplete input sequence. FIXME: ought to report this to the caller somehow. */ inleft = 0; break; default: perror_with_name (_("Internal error while " "converting character sets")); } } } do_cleanups (cleanups); }
static LONGEST rs6000_xfer_shared_libraries (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { const int arch64 = ARCH64 (); LdInfo *ldi_data; LdInfo *ldi; struct obstack obstack; const char *buf; LONGEST len_avail; if (writebuf) return -1; /* Get the ldinfo raw data: If debugging a live process, we get it using ptrace. Otherwise, the info is stored in the .ldinfo section of the core file. */ if (target_has_execution) ldi_data = rs6000_ptrace_ldinfo (inferior_ptid); else ldi_data = rs6000_core_ldinfo (core_bfd); /* Convert the raw data into an XML representation. */ obstack_init (&obstack); obstack_grow_str (&obstack, "<library-list version=\"1.0\">\n"); ldi = ldi_data; while (1) { /* Close the fd. We cannot use it, because we cannot assume that the user of this descriptor will be in the same process. */ close (LDI_FD (ldi, arch64)); rs6000_xfer_shared_library (ldi, &obstack); if (!LDI_NEXT (ldi, arch64)) break; ldi = (LdInfo *) ((char *) ldi + LDI_NEXT (ldi, arch64)); } xfree (ldi_data); obstack_grow_str0 (&obstack, "</library-list>\n"); buf = obstack_finish (&obstack); len_avail = strlen (buf); if (offset >= len_avail) len= 0; else { if (len > len_avail - offset) len = len_avail - offset; memcpy (readbuf, buf + offset, len); } obstack_free (&obstack, NULL); return len; }
static void rs6000_xfer_shared_library (LdInfo *ldi, struct obstack *obstack) { const int arch64 = ARCH64 (); const char *archive_name = LDI_FILENAME (ldi, arch64); const char *member_name = archive_name + strlen (archive_name) + 1; CORE_ADDR text_addr, data_addr; ULONGEST text_size, data_size; char *p; if (arch64) { text_addr = ldi->l64.ldinfo_textorg; text_size = ldi->l64.ldinfo_textsize; data_addr = ldi->l64.ldinfo_dataorg; data_size = ldi->l64.ldinfo_datasize; } else { /* The text and data addresses are defined as pointers. To avoid sign-extending their value in the assignments below, we cast their value to unsigned long first. */ text_addr = (unsigned long) ldi->l32.ldinfo_textorg; text_size = ldi->l32.ldinfo_textsize; data_addr = (unsigned long) ldi->l32.ldinfo_dataorg; data_size = ldi->l32.ldinfo_datasize; } obstack_grow_str (obstack, "<library name=\""); p = xml_escape_text (archive_name); obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\""); if (member_name[0] != '\0') { obstack_grow_str (obstack, " member=\""); p = xml_escape_text (member_name); obstack_grow_str (obstack, p); xfree (p); obstack_grow_str (obstack, "\""); } obstack_grow_str (obstack, " text_addr=\""); obstack_grow_str (obstack, core_addr_to_string (text_addr)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, " text_size=\""); obstack_grow_str (obstack, pulongest (text_size)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, " data_addr=\""); obstack_grow_str (obstack, core_addr_to_string (data_addr)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, " data_size=\""); obstack_grow_str (obstack, pulongest (data_size)); obstack_grow_str (obstack, "\""); obstack_grow_str (obstack, "></library>"); }
/* Extract and demangle type from MANGLED_STR and append it to TEMPBUF. Return 1 on success or 0 on failure. */ static int extract_type_info (const char *mangled_str, struct obstack *tempbuf) { if (*mangled_str == '\0') return 0; switch (*mangled_str++) { case 'A': /* dynamic array */ case 'G': /* static array */ case 'H': /* associative array */ if (!extract_type_info (mangled_str, tempbuf)) return 0; obstack_grow_str (tempbuf, "[]"); return 1; case 'P': /* pointer */ if (!extract_type_info (mangled_str, tempbuf)) return 0; obstack_grow_str (tempbuf, "*"); return 1; case 'R': /* reference */ if (!extract_type_info (mangled_str, tempbuf)) return 0; obstack_grow_str (tempbuf, "&"); return 1; case 'Z': /* return value */ return extract_type_info (mangled_str, tempbuf); case 'J': /* out */ obstack_grow_str (tempbuf, "out "); return extract_type_info (mangled_str, tempbuf); case 'K': /* inout */ obstack_grow_str (tempbuf, "inout "); return extract_type_info (mangled_str, tempbuf); case 'E': /* enum */ case 'T': /* typedef */ case 'D': /* delegate */ case 'C': /* class */ case 'S': /* struct */ return extract_identifiers (mangled_str, tempbuf); /* basic types: */ case 'n': obstack_grow_str (tempbuf, "none"); return 1; case 'v': obstack_grow_str (tempbuf, "void"); return 1; case 'g': obstack_grow_str (tempbuf, "byte"); return 1; case 'h': obstack_grow_str (tempbuf, "ubyte"); return 1; case 's': obstack_grow_str (tempbuf, "short"); return 1; case 't': obstack_grow_str (tempbuf, "ushort"); return 1; case 'i': obstack_grow_str (tempbuf, "int"); return 1; case 'k': obstack_grow_str (tempbuf, "uint"); return 1; case 'l': obstack_grow_str (tempbuf, "long"); return 1; case 'm': obstack_grow_str (tempbuf, "ulong"); return 1; case 'f': obstack_grow_str (tempbuf, "float"); return 1; case 'd': obstack_grow_str (tempbuf, "double"); return 1; case 'e': obstack_grow_str (tempbuf, "real"); return 1; /* imaginary and complex: */ case 'o': obstack_grow_str (tempbuf, "ifloat"); return 1; case 'p': obstack_grow_str (tempbuf, "idouble"); return 1; case 'j': obstack_grow_str (tempbuf, "ireal"); return 1; case 'q': obstack_grow_str (tempbuf, "cfloat"); return 1; case 'r': obstack_grow_str (tempbuf, "cdouble"); return 1; case 'c': obstack_grow_str (tempbuf, "creal"); return 1; /* other types: */ case 'b': obstack_grow_str (tempbuf, "bit"); return 1; case 'a': obstack_grow_str (tempbuf, "char"); return 1; case 'u': obstack_grow_str (tempbuf, "wchar"); return 1; case 'w': obstack_grow_str (tempbuf, "dchar"); return 1; default: obstack_grow_str (tempbuf, "unknown"); return 1; } }
/* Implements the la_demangle language_defn routine for language D. */ char * d_demangle (const char *symbol, int options) { struct obstack tempbuf; char *out_str; unsigned char is_func = 0; if (symbol == NULL) return NULL; else if (strcmp (symbol, "_Dmain") == 0) return xstrdup ("D main"); obstack_init (&tempbuf); if (symbol[0] == '_' && symbol[1] == 'D') { symbol += 2; is_func = 1; } else if (strncmp (symbol, "__Class_", 8) == 0) symbol += 8; else if (strncmp (symbol, "__init_", 7) == 0) symbol += 7; else if (strncmp (symbol, "__vtbl_", 7) == 0) symbol += 7; else if (strncmp (symbol, "__modctor_", 10) == 0) symbol += 10; else if (strncmp (symbol, "__moddtor_", 10) == 0) symbol += 10; else if (strncmp (symbol, "__ModuleInfo_", 13) == 0) symbol += 13; else { obstack_free (&tempbuf, NULL); return NULL; } if (!extract_identifiers (symbol, &tempbuf)) { obstack_free (&tempbuf, NULL); return NULL; } obstack_grow_str (&tempbuf, "("); if (is_func == 1 && *symbol == 'F') { symbol++; while (*symbol != '\0' && *symbol != 'Z') { if (is_func == 1) is_func++; else obstack_grow_str (&tempbuf, ", "); if (!extract_type_info (symbol, &tempbuf)) { obstack_free (&tempbuf, NULL); return NULL; } } } obstack_grow_str0 (&tempbuf, ")"); /* Doesn't display the return type, but wouldn't be too hard to do. */ out_str = xstrdup (obstack_finish (&tempbuf)); obstack_free (&tempbuf, NULL); return out_str; }