mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-19 01:19:41 +08:00
2009-02-05 Thiago Jung Bauermann <bauerman@br.ibm.com>
* language.h (language_dfn): Add la_get_string member. (LA_GET_STRING): New macro. (default_get_string): New prototype. * language.c (default_get_string): New function. (unknown_language_defn, auto_language_defn, local_language_defn): Use default_get_string for la_get_string. * c-lang.c (c_get_string): New function. (c_language_defn, cplus_language_defn, asm_language_defn): Use c_get_string for la_get_string. (minimal_language_defn): Likewise * ada-lang.c (ada_language_defn): Likewise. * f-lang.c (f_language_defn): Use default_get_string for la_get_string. * jv-lang.c (java_language_defn): Likewise. * m2-lang.c (m2_language_defn): Likewise. * objc-lang.c (objc_language_defn): Likewise. * p-lang.c (p_language_defn): Likewise. * scm-lang.c (scm_language_defn): Likewise. * typeprint.c (type_to_string): New function. * value.h (type_to_string): New prototype. * valprint.c (val_print_string): Factor out code for reading string from the inferior into its own function. Put 2 spaces after period in comments. (read_string): New function. * valprint.h (read_string): New prototype.
This commit is contained in:
120
gdb/c-lang.c
120
gdb/c-lang.c
@@ -181,6 +181,122 @@ c_printstr (struct ui_file *stream, const gdb_byte *string,
|
||||
if (force_ellipses || i < length)
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
|
||||
/* Obtain a C string from the inferior storing it in a newly allocated
|
||||
buffer in BUFFER, which should be freed by the caller. The string is
|
||||
read until a null character is found. If VALUE is an array with known
|
||||
length, the function will not read past the end of the array. LENGTH
|
||||
will contain the size of the string in bytes (not counting the null
|
||||
character).
|
||||
|
||||
Assumes strings are terminated by a null character. The size of a character
|
||||
is determined by the length of the target type of the pointer or array.
|
||||
This means that a null byte present in a multi-byte character will not
|
||||
terminate the string unless the whole character is null.
|
||||
|
||||
CHARSET is always set to the target charset. */
|
||||
|
||||
void
|
||||
c_get_string (struct value *value, gdb_byte **buffer, int *length,
|
||||
const char **charset)
|
||||
{
|
||||
int err, width;
|
||||
unsigned int fetchlimit;
|
||||
struct type *type = check_typedef (value_type (value));
|
||||
struct type *element_type = TYPE_TARGET_TYPE (type);
|
||||
|
||||
if (element_type == NULL)
|
||||
goto error;
|
||||
|
||||
if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
|
||||
{
|
||||
/* If we know the size of the array, we can use it as a limit on the
|
||||
number of characters to be fetched. */
|
||||
if (TYPE_NFIELDS (type) == 1
|
||||
&& TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
|
||||
{
|
||||
LONGEST low_bound, high_bound;
|
||||
|
||||
get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
|
||||
&low_bound, &high_bound);
|
||||
fetchlimit = high_bound - low_bound + 1;
|
||||
}
|
||||
else
|
||||
fetchlimit = UINT_MAX;
|
||||
}
|
||||
else if (TYPE_CODE (type) == TYPE_CODE_PTR)
|
||||
fetchlimit = UINT_MAX;
|
||||
else
|
||||
/* We work only with arrays and pointers. */
|
||||
goto error;
|
||||
|
||||
element_type = check_typedef (element_type);
|
||||
if (TYPE_CODE (element_type) != TYPE_CODE_INT
|
||||
&& TYPE_CODE (element_type) != TYPE_CODE_CHAR)
|
||||
/* If the elements are not integers or characters, we don't consider it
|
||||
a string. */
|
||||
goto error;
|
||||
|
||||
width = TYPE_LENGTH (element_type);
|
||||
|
||||
/* If the string lives in GDB's memory intead of the inferior's, then we
|
||||
just need to copy it to BUFFER. Also, since such strings are arrays
|
||||
with known size, FETCHLIMIT will hold the size of the array. */
|
||||
if ((VALUE_LVAL (value) == not_lval
|
||||
|| VALUE_LVAL (value) == lval_internalvar)
|
||||
&& fetchlimit != UINT_MAX)
|
||||
{
|
||||
int i;
|
||||
const gdb_byte *contents = value_contents (value);
|
||||
|
||||
/* Look for a null character. */
|
||||
for (i = 0; i < fetchlimit; i++)
|
||||
if (extract_unsigned_integer (contents + i * width, width) == 0)
|
||||
break;
|
||||
|
||||
/* I is now either the number of non-null characters, or FETCHLIMIT. */
|
||||
*length = i * width;
|
||||
*buffer = xmalloc (*length);
|
||||
memcpy (*buffer, contents, *length);
|
||||
err = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = read_string (value_as_address (value), -1, width, fetchlimit,
|
||||
buffer, length);
|
||||
if (err)
|
||||
{
|
||||
xfree (buffer);
|
||||
error (_("Error reading string from inferior: %s"),
|
||||
safe_strerror (err));
|
||||
}
|
||||
}
|
||||
|
||||
/* If the last character is null, subtract it from LENGTH. */
|
||||
if (*length > 0
|
||||
&& extract_unsigned_integer (*buffer + *length - width, width) == 0)
|
||||
*length -= width;
|
||||
|
||||
*charset = target_charset ();
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
{
|
||||
char *type_str;
|
||||
|
||||
type_str = type_to_string (type);
|
||||
if (type_str)
|
||||
{
|
||||
make_cleanup (xfree, type_str);
|
||||
error (_("Trying to read string with inappropriate type `%s'."),
|
||||
type_str);
|
||||
}
|
||||
else
|
||||
error (_("Trying to read string with inappropriate type."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Preprocessing and parsing C and C++ expressions. */
|
||||
|
||||
@@ -314,6 +430,7 @@ const struct language_defn c_language_defn =
|
||||
c_language_arch_info,
|
||||
default_print_array_index,
|
||||
default_pass_by_reference,
|
||||
c_get_string,
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
@@ -432,6 +549,7 @@ const struct language_defn cplus_language_defn =
|
||||
cplus_language_arch_info,
|
||||
default_print_array_index,
|
||||
cp_pass_by_reference,
|
||||
c_get_string,
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
@@ -469,6 +587,7 @@ const struct language_defn asm_language_defn =
|
||||
c_language_arch_info, /* FIXME: la_language_arch_info. */
|
||||
default_print_array_index,
|
||||
default_pass_by_reference,
|
||||
c_get_string,
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
@@ -511,6 +630,7 @@ const struct language_defn minimal_language_defn =
|
||||
c_language_arch_info,
|
||||
default_print_array_index,
|
||||
default_pass_by_reference,
|
||||
c_get_string,
|
||||
LANG_MAGIC
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user