From 13b5a7ff3e21bcde878d7f05ce9fa9f999e5dd82 Mon Sep 17 00:00:00 2001 From: Fred Fish Date: Tue, 14 Apr 1992 04:09:00 +0000 Subject: [PATCH] Extensive changes to replace swapin() function with target_to_host() and fix all usages to be independent of host/target integer size mismatches. However, cross debugging will still not work until the sign extension issue is resolved either by fixing the bfd library or implementing sign extension in the gdb code. --- gdb/ChangeLog | 10 + gdb/dwarfread.c | 879 +++++++++++++++++++++++++++++------------------- 2 files changed, 543 insertions(+), 346 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 615518c2f2..6ec6f61701 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +Mon Apr 13 20:59:21 1992 Fred Fish (fnf@cygnus.com) + + * dwarfread.c (target_to_host): New function similar to previous + swapin function. + * dwarfread.c (SWAPIN, swapin): Remove macro and support function. + Extensive changes to convert all previous usages to use new + target_to_host() function. + * dwarfread.c (struct dieinfo): Change types of most integral + members to be unsigned. + Mon Apr 13 15:59:10 1992 John Gilmore (gnu at cygnus.com) * WHATS.NEW: Revise -mapped doc. diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 77a2bc77fa..161fc7890e 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -26,10 +26,6 @@ execution environment of the target. Remove R_FP kludge FIXME: Add generation of dependencies list to partial symtab code. -FIXME: Currently we ignore host/target byte ordering and integer size -differences. Should remap data from external form to an internal form -before trying to use it. - FIXME: Resolve minor differences between what information we put in the partial symbol table and what dbxread puts in. For example, we don't yet put enum constants there. And dbxread seems to invent a lot of typedefs @@ -39,16 +35,6 @@ contents. FIXME: Figure out a better way to tell gdb about the name of the function contain the user's entry point (I.E. main()) -FIXME: The current DWARF specification has a very strong bias towards -machines with 32-bit integers, as it assumes that many attributes of the -program (such as an address) will fit in such an integer. There are many -references in the spec to things that are 2, 4, or 8 bytes long. Given that -we will probably run into problems on machines where some of these assumptions -are invalid (64-bit ints for example), we don't bother at this time to try to -make this code more flexible and just use shorts, ints, and longs (and their -sizes) where it seems appropriate. I.E. we use a short int to hold DWARF -tags, and assume that the tag size in the file is the same as sizeof(short). - FIXME: See other FIXME's and "ifdef 0" scattered throughout the code for other things to work on, if you get bored. :-) @@ -64,7 +50,7 @@ other things to work on, if you get bored. :-) #include "gdbtypes.h" #include "symfile.h" #include "objfiles.h" -#include "libbfd.h" /* FIXME Secret Internal BFD stuff (bfd_read) */ +#include "libbfd.h" /* FIXME Secret Internal BFD stuff (bfd_read) */ #include "elf/dwarf.h" #include "buildsym.h" @@ -78,7 +64,7 @@ other things to work on, if you get bored. :-) #define R_FP 14 /* Kludge to get frame pointer register number */ #endif -typedef unsigned int DIEREF; /* Reference to a DIE */ +typedef unsigned int DIE_REF; /* Reference to a DIE */ #ifndef GCC_PRODUCER #define GCC_PRODUCER "GNU C " @@ -87,7 +73,45 @@ typedef unsigned int DIEREF; /* Reference to a DIE */ #define STREQ(a,b) (strcmp(a,b)==0) #define STREQN(a,b,n) (strncmp(a,b,n)==0) -#define SWAPIN(to,from,objfile) swapin((char *)&(to),from,sizeof(to),objfile) +/* Flags to target_to_host() that tell whether or not the data object is + expected to be signed. Used, for example, when fetching a signed + integer in the target environment which is used as a signed integer + in the host environment, and the two environments have different sized + ints. In this case, *somebody* has to sign extend the smaller sized + int. */ + +#define GET_UNSIGNED 0 /* No sign extension required */ +#define GET_SIGNED 1 /* Sign extension required */ + +/* Defines for things which are specified in the document "DWARF Debugging + Information Format" published by UNIX International, Programming Languages + SIG. These defines are based on revision 1.0.0, Jan 20, 1992. */ + +#define SIZEOF_DIE_LENGTH 4 +#define SIZEOF_DIE_TAG 2 +#define SIZEOF_ATTRIBUTE 2 +#define SIZEOF_FORMAT_SPECIFIER 1 +#define SIZEOF_FMT_FT 2 +#define SIZEOF_LINETBL_LENGTH 4 +#define SIZEOF_LINETBL_LINENO 4 +#define SIZEOF_LINETBL_STMT 2 +#define SIZEOF_LINETBL_DELTA 4 +#define SIZEOF_LOC_ATOM_CODE 1 + +#define FORM_FROM_ATTR(attr) ((attr) & 0xF) /* Implicitly specified */ + +/* Macros that return the sizes of various types of data in the target + environment. + + FIXME: They currently just return the sizes in the host environment. + They need to be able to get the right size either from the bfd or possibly + from the DWARF info. It would be nice if the DWARF producer inserted DIES + that describe the fundamental types in the target environment into the + DWARF info, similar to the way dbx stabs producers produce information + about their fundamental types. */ + +#define TARGET_FT_POINTER_SIZE(objfile) sizeof (PTR) /* FIXME */ +#define TARGET_FT_LONG_SIZE(objfile) sizeof (long) /* FIXME */ /* The Amiga SVR4 header file defines AT_element_list as a FORM_BLOCK2, and this is the value emitted by the AT&T compiler. @@ -109,7 +133,7 @@ extern char *warning_pre_print; /* From utils.c */ the information for a single DIE, the one currently being processed. In order to make it easier to randomly access the attribute fields - of the current DIE, which are specifically unordered within the DIE + of the current DIE, which are specifically unordered within the DIE, each DIE is scanned and an instance of the "struct dieinfo" structure is initialized. @@ -133,44 +157,44 @@ extern char *warning_pre_print; /* From utils.c */ typedef char BLOCK; struct dieinfo { - char * die; /* Pointer to the raw DIE data */ - long dielength; /* Length of the raw DIE data */ - DIEREF dieref; /* Offset of this DIE */ - short dietag; /* Tag for this DIE */ - long at_padding; - long at_sibling; - BLOCK * at_location; - char * at_name; - unsigned short at_fund_type; - BLOCK * at_mod_fund_type; - long at_user_def_type; - BLOCK * at_mod_u_d_type; - short at_ordering; - BLOCK * at_subscr_data; - long at_byte_size; - short at_bit_offset; - long at_bit_size; - BLOCK * at_element_list; - long at_stmt_list; - long at_low_pc; - long at_high_pc; - long at_language; - long at_member; - long at_discr; - BLOCK * at_discr_value; - short at_visibility; - long at_import; - BLOCK * at_string_length; - char * at_comp_dir; - char * at_producer; - long at_frame_base; - long at_start_scope; - long at_stride_size; - long at_src_info; - short at_prototyped; - unsigned int has_at_low_pc:1; - unsigned int has_at_stmt_list:1; - unsigned int short_element_list:1; + char * die; /* Pointer to the raw DIE data */ + unsigned long die_length; /* Length of the raw DIE data */ + DIE_REF die_ref; /* Offset of this DIE */ + unsigned short die_tag; /* Tag for this DIE */ + unsigned long at_padding; + unsigned long at_sibling; + BLOCK * at_location; + char * at_name; + unsigned short at_fund_type; + BLOCK * at_mod_fund_type; + unsigned long at_user_def_type; + BLOCK * at_mod_u_d_type; + unsigned short at_ordering; + BLOCK * at_subscr_data; + unsigned long at_byte_size; + unsigned short at_bit_offset; + unsigned long at_bit_size; + BLOCK * at_element_list; + unsigned long at_stmt_list; + unsigned long at_low_pc; + unsigned long at_high_pc; + unsigned long at_language; + unsigned long at_member; + unsigned long at_discr; + BLOCK * at_discr_value; + unsigned short at_visibility; + unsigned long at_import; + BLOCK * at_string_length; + char * at_comp_dir; + char * at_producer; + unsigned long at_frame_base; + unsigned long at_start_scope; + unsigned long at_stride_size; + unsigned long at_src_info; + char * at_prototyped; + unsigned int has_at_low_pc:1; + unsigned int has_at_stmt_list:1; + unsigned int short_element_list:1; }; static int diecount; /* Approximate count of dies for compilation unit */ @@ -262,8 +286,11 @@ static int numutypes; /* Max number of user type pointers */ /* Forward declarations of static functions so we don't have to worry about ordering within this file. */ -static void -swapin PARAMS ((char *, char *, int, struct objfile *)); +static int +attribute_size PARAMS ((unsigned int)); + +static unsigned long +target_to_host PARAMS ((char *, int, int, struct objfile *)); static void add_enum_psymbol PARAMS ((struct dieinfo *, struct objfile *)); @@ -362,10 +389,10 @@ static char * create_name PARAMS ((char *, struct obstack *)); static struct type * -lookup_utype PARAMS ((DIEREF)); +lookup_utype PARAMS ((DIE_REF)); static struct type * -alloc_utype PARAMS ((DIEREF, struct type *)); +alloc_utype PARAMS ((DIE_REF, struct type *)); static struct symbol * new_symbol PARAMS ((struct dieinfo *, struct objfile *)); @@ -439,7 +466,8 @@ dwarf_build_psymtabs (desc, filename, addr, mainline, dbfoff, dbsize, Since we have no idea how many DIES we are looking at, we just guess some arbitrary value. */ - if (mainline || objfile->global_psymbols.size == 0 || objfile->static_psymbols.size == 0) + if (mainline || objfile -> global_psymbols.size == 0 || + objfile -> static_psymbols.size == 0) { init_psymbol_list (objfile, 1024); } @@ -530,7 +558,7 @@ dwarfwarn (va_alist) va_start (ap); fmt = va_arg (ap, char *); warning_setup (); - fprintf (stderr, "warning: DWARF ref 0x%x: ", curdie -> dieref); + fprintf (stderr, "warning: DWARF ref 0x%x: ", curdie -> die_ref); if (curdie -> at_name) { fprintf (stderr, "'%s': ", curdie -> at_name); @@ -569,7 +597,7 @@ read_lexical_block_scope (dip, thisdie, enddie, objfile) register struct context_stack *new; (void) push_context (0, dip -> at_low_pc); - process_dies (thisdie + dip -> dielength, enddie, objfile); + process_dies (thisdie + dip -> die_length, enddie, objfile); new = pop_context (); if (local_symbols != NULL) { @@ -587,7 +615,7 @@ LOCAL FUNCTION SYNOPSIS - static type *lookup_utype (DIEREF dieref) + static type *lookup_utype (DIE_REF die_ref) DESCRIPTION @@ -599,16 +627,16 @@ DESCRIPTION */ static struct type * -lookup_utype (dieref) - DIEREF dieref; +lookup_utype (die_ref) + DIE_REF die_ref; { struct type *type = NULL; int utypeidx; - utypeidx = (dieref - dbroff) / 4; + utypeidx = (die_ref - dbroff) / 4; if ((utypeidx < 0) || (utypeidx >= numutypes)) { - dwarfwarn ("reference to DIE (0x%x) outside compilation unit", dieref); + dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref); } else { @@ -626,33 +654,33 @@ LOCAL FUNCTION SYNOPSIS - static type *alloc_utype (DIEREF dieref, struct type *utypep) + static type *alloc_utype (DIE_REF die_ref, struct type *utypep) DESCRIPTION - Given a die reference DIEREF, and a possible pointer to a user + Given a die reference DIE_REF, and a possible pointer to a user defined type UTYPEP, register that this reference has a user defined type and either use the specified type in UTYPEP or make a new empty type that will be filled in later. We should only be called after calling lookup_utype() to verify that - there is not currently a type registered for DIEREF. + there is not currently a type registered for DIE_REF. */ static struct type * -alloc_utype (dieref, utypep) - DIEREF dieref; +alloc_utype (die_ref, utypep) + DIE_REF die_ref; struct type *utypep; { struct type **typep; int utypeidx; - utypeidx = (dieref - dbroff) / 4; + utypeidx = (die_ref - dbroff) / 4; typep = utypes + utypeidx; if ((utypeidx < 0) || (utypeidx >= numutypes)) { utypep = lookup_fundamental_type (current_objfile, FT_INTEGER); - dwarfwarn ("reference to DIE (0x%x) outside compilation unit", dieref); + dwarfwarn ("reference to DIE (0x%x) outside compilation unit", die_ref); } else if (*typep != NULL) { @@ -763,13 +791,13 @@ struct_type (dip, thisdie, enddie, objfile) struct dieinfo mbr; char *nextdie; - if ((type = lookup_utype (dip -> dieref)) == NULL) + if ((type = lookup_utype (dip -> die_ref)) == NULL) { /* No forward references created an empty type, so install one now */ - type = alloc_utype (dip -> dieref, NULL); + type = alloc_utype (dip -> die_ref, NULL); } INIT_CPLUS_SPECIFIC(type); - switch (dip -> dietag) + switch (dip -> die_tag) { case TAG_structure_type: TYPE_CODE (type) = TYPE_CODE_STRUCT; @@ -800,12 +828,12 @@ struct_type (dip, thisdie, enddie, objfile) { TYPE_LENGTH (type) = dip -> at_byte_size; } - thisdie += dip -> dielength; + thisdie += dip -> die_length; while (thisdie < enddie) { basicdieinfo (&mbr, thisdie, objfile); completedieinfo (&mbr, objfile); - if (mbr.dielength <= sizeof (long)) + if (mbr.die_length <= SIZEOF_DIE_LENGTH) { break; } @@ -815,9 +843,9 @@ struct_type (dip, thisdie, enddie, objfile) } else { - nextdie = thisdie + mbr.dielength; + nextdie = thisdie + mbr.die_length; } - switch (mbr.dietag) + switch (mbr.die_tag) { case TAG_member: /* Get space to record the next field's data. */ @@ -939,36 +967,47 @@ decode_array_element_type (scan) char *scan; { struct type *typep; - short attribute; - DIEREF dieref; + DIE_REF die_ref; + unsigned short attribute; unsigned short fundtype; + int nbytes; - /* FIXME, does this confuse the host and target sizeof's? --gnu */ - SWAPIN (attribute, scan, current_objfile); - scan += sizeof (short); - switch (attribute) + attribute = target_to_host (scan, SIZEOF_ATTRIBUTE, GET_UNSIGNED, + current_objfile); + scan += SIZEOF_ATTRIBUTE; + if ((nbytes = attribute_size (attribute)) == -1) { - case AT_fund_type: - SWAPIN (fundtype, scan, current_objfile); - typep = decode_fund_type (fundtype); - break; - case AT_mod_fund_type: - typep = decode_mod_fund_type (scan); - break; - case AT_user_def_type: - SWAPIN (dieref, scan, current_objfile); - if ((typep = lookup_utype (dieref)) == NULL) - { - typep = alloc_utype (dieref, NULL); - } - break; - case AT_mod_u_d_type: - typep = decode_mod_u_d_type (scan); - break; - default: SQUAWK (("bad array element type attribute 0x%x", attribute)); typep = lookup_fundamental_type (current_objfile, FT_INTEGER); - break; + } + else + { + switch (attribute) + { + case AT_fund_type: + fundtype = target_to_host (scan, nbytes, GET_UNSIGNED, + current_objfile); + typep = decode_fund_type (fundtype); + break; + case AT_mod_fund_type: + typep = decode_mod_fund_type (scan); + break; + case AT_user_def_type: + die_ref = target_to_host (scan, nbytes, GET_UNSIGNED, + current_objfile); + if ((typep = lookup_utype (die_ref)) == NULL) + { + typep = alloc_utype (die_ref, NULL); + } + break; + case AT_mod_u_d_type: + typep = decode_mod_u_d_type (scan); + break; + default: + SQUAWK (("bad array element type attribute 0x%x", attribute)); + typep = lookup_fundamental_type (current_objfile, FT_INTEGER); + break; + } } return (typep); } @@ -1012,32 +1051,39 @@ decode_subscr_data (scan, end) { struct type *typep = NULL; struct type *nexttype; - int format; - short fundtype; - long lowbound; - long highbound; + unsigned int format; + unsigned short fundtype; + unsigned long lowbound; + unsigned long highbound; + int nbytes; - format = *scan++; + format = target_to_host (scan, SIZEOF_FORMAT_SPECIFIER, GET_UNSIGNED, + current_objfile); + scan += SIZEOF_FORMAT_SPECIFIER; switch (format) { case FMT_ET: typep = decode_array_element_type (scan); break; case FMT_FT_C_C: - SWAPIN (fundtype, scan, current_objfile); - scan += sizeof (short); + fundtype = target_to_host (scan, SIZEOF_FMT_FT, GET_UNSIGNED, + current_objfile); + scan += SIZEOF_FMT_FT; if (fundtype != FT_integer && fundtype != FT_signed_integer && fundtype != FT_unsigned_integer) { SQUAWK (("array subscripts must be integral types, not type 0x%x", - fundtype)); + fundtype)); } else { - SWAPIN (lowbound, scan, current_objfile); - scan += sizeof (long); - SWAPIN (highbound, scan, current_objfile); - scan += sizeof (long); + nbytes = TARGET_FT_LONG_SIZE (current_objfile); + lowbound = target_to_host (scan, nbytes, GET_UNSIGNED, + current_objfile); + scan += nbytes; + highbound = target_to_host (scan, nbytes, GET_UNSIGNED, + current_objfile); + scan += nbytes; nexttype = decode_subscr_data (scan, end); if (nexttype != NULL) { @@ -1093,7 +1139,8 @@ dwarf_read_array_type (dip) struct type *utype; char *sub; char *subend; - short temp; + unsigned short blocksz; + int nbytes; if (dip -> at_ordering != ORD_row_major) { @@ -1102,15 +1149,16 @@ dwarf_read_array_type (dip) } if ((sub = dip -> at_subscr_data) != NULL) { - SWAPIN (temp, sub, current_objfile); - subend = sub + sizeof (short) + temp; - sub += sizeof (short); + nbytes = attribute_size (AT_subscr_data); + blocksz = target_to_host (sub, nbytes, GET_UNSIGNED, current_objfile); + subend = sub + nbytes + blocksz; + sub += nbytes; type = decode_subscr_data (sub, subend); if (type == NULL) { - if ((utype = lookup_utype (dip -> dieref)) == NULL) + if ((utype = lookup_utype (dip -> die_ref)) == NULL) { - utype = alloc_utype (dip -> dieref, NULL); + utype = alloc_utype (dip -> die_ref, NULL); } TYPE_CODE (utype) = TYPE_CODE_ARRAY; TYPE_TARGET_TYPE (utype) = @@ -1119,9 +1167,9 @@ dwarf_read_array_type (dip) } else { - if ((utype = lookup_utype (dip -> dieref)) == NULL) + if ((utype = lookup_utype (dip -> die_ref)) == NULL) { - (void) alloc_utype (dip -> dieref, type); + (void) alloc_utype (dip -> die_ref, type); } else { @@ -1157,10 +1205,10 @@ read_tag_pointer_type (dip) struct type *utype; type = decode_die_type (dip); - if ((utype = lookup_utype (dip -> dieref)) == NULL) + if ((utype = lookup_utype (dip -> die_ref)) == NULL) { utype = lookup_pointer_type (type); - (void) alloc_utype (dip -> dieref, utype); + (void) alloc_utype (dip -> die_ref, utype); } else { @@ -1219,12 +1267,12 @@ read_subroutine_type (dip, thisdie, enddie) /* Check to see if we already have a partially constructed user defined type for this DIE, from a forward reference. */ - if ((ftype = lookup_utype (dip -> dieref)) == NULL) + if ((ftype = lookup_utype (dip -> die_ref)) == NULL) { /* This is the first reference to one of these types. Make a new one and place it in the user defined types. */ ftype = lookup_function_type (type); - (void) alloc_utype (dip -> dieref, ftype); + (void) alloc_utype (dip -> die_ref, ftype); } else { @@ -1324,14 +1372,14 @@ enum_type (dip, objfile) int n; char *scan; char *listend; - long ltemp; - short stemp; + unsigned short blocksz; struct symbol *sym; + int nbytes; - if ((type = lookup_utype (dip -> dieref)) == NULL) + if ((type = lookup_utype (dip -> die_ref)) == NULL) { /* No forward references created an empty type, so install one now */ - type = alloc_utype (dip -> dieref, NULL); + type = alloc_utype (dip -> die_ref, NULL); } TYPE_CODE (type) = TYPE_CODE_ENUM; /* Some compilers try to be helpful by inventing "fake" names for @@ -1352,16 +1400,15 @@ enum_type (dip, objfile) { if (dip -> short_element_list) { - SWAPIN (stemp, scan, objfile); - listend = scan + stemp + sizeof (stemp); - scan += sizeof (stemp); + nbytes = attribute_size (AT_short_element_list); } else { - SWAPIN (ltemp, scan, objfile); - listend = scan + ltemp + sizeof (ltemp); - scan += sizeof (ltemp); + nbytes = attribute_size (AT_element_list); } + blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile); + listend = scan + nbytes + blocksz; + scan += nbytes; while (scan < listend) { new = (struct nextfield *) alloca (sizeof (struct nextfield)); @@ -1369,8 +1416,10 @@ enum_type (dip, objfile) list = new; list -> field.type = NULL; list -> field.bitsize = 0; - SWAPIN (list -> field.bitpos, scan, objfile); - scan += sizeof (long); + list -> field.bitpos = + target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED, + objfile); + scan += TARGET_FT_LONG_SIZE (objfile); list -> field.name = savestring (scan, strlen (scan)); scan += strlen (scan) + 1; nfields++; @@ -1378,7 +1427,8 @@ enum_type (dip, objfile) sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol)); (void) memset (sym, 0, sizeof (struct symbol)); - SYMBOL_NAME (sym) = create_name (list -> field.name, &objfile->symbol_obstack); + SYMBOL_NAME (sym) = create_name (list -> field.name, + &objfile->symbol_obstack); SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_CONST; SYMBOL_TYPE (sym) = type; @@ -1449,7 +1499,7 @@ read_func_scope (dip, thisdie, enddie, objfile) new = push_context (0, dip -> at_low_pc); new -> name = new_symbol (dip, objfile); list_in_scope = &local_symbols; - process_dies (thisdie + dip -> dielength, enddie, objfile); + process_dies (thisdie + dip -> die_length, enddie, objfile); new = pop_context (); /* Make a block for the local symbols within. */ finish_block (new -> name, &local_symbols, new -> old_blocks, @@ -1506,7 +1556,7 @@ read_file_scope (dip, thisdie, enddie, objfile) (void) memset (utypes, 0, numutypes * sizeof (struct type *)); start_symtab (dip -> at_name, NULL, dip -> at_low_pc); decode_line_numbers (lnbase); - process_dies (thisdie + dip -> dielength, enddie, objfile); + process_dies (thisdie + dip -> die_length, enddie, objfile); symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile); /* FIXME: The following may need to be expanded for other languages */ switch (dip -> at_language) @@ -1555,13 +1605,13 @@ process_dies (thisdie, enddie, objfile) while (thisdie < enddie) { basicdieinfo (&di, thisdie, objfile); - if (di.dielength < sizeof (long)) + if (di.die_length < SIZEOF_DIE_LENGTH) { break; } - else if (di.dietag == TAG_padding) + else if (di.die_tag == TAG_padding) { - nextdie = thisdie + di.dielength; + nextdie = thisdie + di.die_length; } else { @@ -1572,9 +1622,9 @@ process_dies (thisdie, enddie, objfile) } else { - nextdie = thisdie + di.dielength; + nextdie = thisdie + di.die_length; } - switch (di.dietag) + switch (di.die_tag) { case TAG_compile_unit: read_file_scope (&di, thisdie, nextdie, objfile); @@ -1680,28 +1730,32 @@ decode_line_numbers (linetable) { char *tblscan; char *tblend; - long length; - long base; - long line; - long pc; + unsigned long length; + unsigned long base; + unsigned long line; + unsigned long pc; if (linetable != NULL) { tblscan = tblend = linetable; - SWAPIN (length, tblscan, current_objfile); - tblscan += sizeof (long); + length = target_to_host (tblscan, SIZEOF_LINETBL_LENGTH, GET_UNSIGNED, + current_objfile); + tblscan += SIZEOF_LINETBL_LENGTH; tblend += length; - SWAPIN (base, tblscan, current_objfile); + base = target_to_host (tblscan, TARGET_FT_POINTER_SIZE (objfile), + GET_UNSIGNED, current_objfile); + tblscan += TARGET_FT_POINTER_SIZE (objfile); base += baseaddr; - tblscan += sizeof (long); while (tblscan < tblend) { - SWAPIN (line, tblscan, current_objfile); - tblscan += sizeof (long) + sizeof (short); - SWAPIN (pc, tblscan, current_objfile); - tblscan += sizeof (long); + line = target_to_host (tblscan, SIZEOF_LINETBL_LINENO, GET_UNSIGNED, + current_objfile); + tblscan += SIZEOF_LINETBL_LINENO + SIZEOF_LINETBL_STMT; + pc = target_to_host (tblscan, SIZEOF_LINETBL_DELTA, GET_UNSIGNED, + current_objfile); + tblscan += SIZEOF_LINETBL_DELTA; pc += base; - if (line > 0) + if (line != 0) { record_line (current_subfile, line, pc); } @@ -1746,67 +1800,82 @@ locval (loc) char *loc; { unsigned short nbytes; - auto int stack[64]; + unsigned short locsize; + auto long stack[64]; int stacki; char *end; long regno; + int loc_atom_code; + int loc_value_size; - SWAPIN (nbytes, loc, current_objfile); - end = loc + sizeof (short) + nbytes; + nbytes = attribute_size (AT_location); + locsize = target_to_host (loc, nbytes, GET_UNSIGNED, current_objfile); + loc += nbytes; + end = loc + locsize; stacki = 0; stack[stacki] = 0; isreg = 0; offreg = 0; - for (loc += sizeof (short); loc < end; loc += sizeof (long)) + loc_value_size = TARGET_FT_LONG_SIZE (current_objfile); + while (loc < end) { - switch (*loc++) { - case 0: - /* error */ - loc = end; - break; - case OP_REG: - /* push register (number) */ - stacki++; - SWAPIN (stack[stacki], loc, current_objfile); - isreg = 1; - break; - case OP_BASEREG: - /* push value of register (number) */ - /* Actually, we compute the value as if register has 0 */ - offreg = 1; - SWAPIN (regno, loc, current_objfile); - if (regno == R_FP) - { - stack[++stacki] = 0; - } - else - { - stack[++stacki] = 0; - SQUAWK (("BASEREG %d not handled!", regno)); - } - break; - case OP_ADDR: - /* push address (relocated address) */ - stacki++; - SWAPIN (stack[stacki], loc, current_objfile); - break; - case OP_CONST: - /* push constant (number) */ - stacki++; - SWAPIN (stack[stacki], loc, current_objfile); - break; - case OP_DEREF2: - /* pop, deref and push 2 bytes (as a long) */ - SQUAWK (("OP_DEREF2 address %#x not handled", stack[stacki])); - break; - case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */ - SQUAWK (("OP_DEREF4 address %#x not handled", stack[stacki])); - break; - case OP_ADD: /* pop top 2 items, add, push result */ - stack[stacki - 1] += stack[stacki]; - stacki--; - break; - } + loc_atom_code = target_to_host (loc, SIZEOF_LOC_ATOM_CODE, GET_UNSIGNED, + current_objfile); + loc += SIZEOF_LOC_ATOM_CODE; + switch (loc_atom_code) + { + case 0: + /* error */ + loc = end; + break; + case OP_REG: + /* push register (number) */ + stack[++stacki] = target_to_host (loc, loc_value_size, + GET_UNSIGNED, current_objfile); + loc += loc_value_size; + isreg = 1; + break; + case OP_BASEREG: + /* push value of register (number) */ + /* Actually, we compute the value as if register has 0 */ + offreg = 1; + regno = target_to_host (loc, loc_value_size, GET_UNSIGNED, + current_objfile); + loc += loc_value_size; + if (regno == R_FP) + { + stack[++stacki] = 0; + } + else + { + stack[++stacki] = 0; + SQUAWK (("BASEREG %d not handled!", regno)); + } + break; + case OP_ADDR: + /* push address (relocated address) */ + stack[++stacki] = target_to_host (loc, loc_value_size, + GET_UNSIGNED, current_objfile); + loc += loc_value_size; + break; + case OP_CONST: + /* push constant (number) FIXME: signed or unsigned! */ + stack[++stacki] = target_to_host (loc, loc_value_size, + GET_SIGNED, current_objfile); + loc += loc_value_size; + break; + case OP_DEREF2: + /* pop, deref and push 2 bytes (as a long) */ + SQUAWK (("OP_DEREF2 address 0x%x not handled", stack[stacki])); + break; + case OP_DEREF4: /* pop, deref and push 4 bytes (as a long) */ + SQUAWK (("OP_DEREF4 address 0x%x not handled", stack[stacki])); + break; + case OP_ADD: /* pop top 2 items, add, push result */ + stack[stacki - 1] += stack[stacki]; + stacki--; + break; + } } return (stack[stacki]); } @@ -1836,9 +1905,10 @@ read_ofile_symtab (pst) struct partial_symtab *pst; { struct cleanup *back_to; - long lnsize; + unsigned long lnsize; int foffset; bfd *abfd; + char lnsizedata[SIZEOF_LINETBL_LENGTH]; abfd = pst -> objfile -> obfd; current_objfile = pst -> objfile; @@ -1860,20 +1930,21 @@ read_ofile_symtab (pst) back_to = make_cleanup (free, dbbase); /* If there is a line number table associated with this compilation unit - then read the first long word from the line number table fragment, which - contains the size of the fragment in bytes (including the long word - itself). Allocate a buffer for the fragment and read it in for future + then read the size of this fragment in bytes, from the fragment itself. + Allocate a buffer for the fragment and read it in for future processing. */ lnbase = NULL; if (LNFOFF (pst)) { if (bfd_seek (abfd, LNFOFF (pst), 0) || - (bfd_read ((PTR)&lnsize, sizeof(long), 1, abfd) != sizeof(long))) + (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) != + sizeof (lnsizedata))) { error ("can't read DWARF line number table size"); } - lnsize = bfd_h_get_32 (abfd, (unsigned char *) &lnsize); + lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH, + GET_UNSIGNED, pst -> objfile); lnbase = xmalloc (lnsize); if (bfd_seek (abfd, LNFOFF (pst), 0) || (bfd_read (lnbase, lnsize, 1, abfd) != lnsize)) @@ -2091,26 +2162,25 @@ add_enum_psymbol (dip, objfile) { char *scan; char *listend; - long ltemp; - short stemp; + unsigned short blocksz; + int nbytes; if ((scan = dip -> at_element_list) != NULL) { if (dip -> short_element_list) { - SWAPIN (stemp, scan, objfile); - listend = scan + stemp + sizeof (stemp); - scan += sizeof (stemp); + nbytes = attribute_size (AT_short_element_list); } else { - SWAPIN (ltemp, scan, objfile); - listend = scan + ltemp + sizeof (ltemp); - scan += sizeof (ltemp); + nbytes = attribute_size (AT_element_list); } + blocksz = target_to_host (scan, nbytes, GET_UNSIGNED, objfile); + scan += nbytes; + listend = scan + blocksz; while (scan < listend) { - scan += sizeof (long); + scan += TARGET_FT_LONG_SIZE (objfile); ADD_PSYMBOL_TO_LIST (scan, strlen (scan), VAR_NAMESPACE, LOC_CONST, objfile -> static_psymbols, 0); scan += strlen (scan) + 1; @@ -2137,7 +2207,7 @@ add_partial_symbol (dip, objfile) struct dieinfo *dip; struct objfile *objfile; { - switch (dip -> dietag) + switch (dip -> die_tag) { case TAG_global_subroutine: record_minimal_symbol (dip -> at_name, dip -> at_low_pc, mst_text, @@ -2234,16 +2304,16 @@ scan_partial_symbols (thisdie, enddie, objfile) while (thisdie < enddie) { basicdieinfo (&di, thisdie, objfile); - if (di.dielength < sizeof (long)) + if (di.die_length < SIZEOF_DIE_LENGTH) { break; } else { - nextdie = thisdie + di.dielength; + nextdie = thisdie + di.die_length; /* To avoid getting complete die information for every die, we only do it (below) for the cases we are interested in. */ - switch (di.dietag) + switch (di.die_tag) { case TAG_global_subroutine: case TAG_subroutine: @@ -2336,13 +2406,13 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) while (thisdie < enddie) { basicdieinfo (&di, thisdie, objfile); - if (di.dielength < sizeof (long)) + if (di.die_length < SIZEOF_DIE_LENGTH) { break; } - else if (di.dietag != TAG_compile_unit) + else if (di.die_tag != TAG_compile_unit) { - nextdie = thisdie + di.dielength; + nextdie = thisdie + di.die_length; } else { @@ -2353,7 +2423,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) } else { - nextdie = thisdie + di.dielength; + nextdie = thisdie + di.die_length; } curoff = thisdie - dbbase; culength = nextdie - thisdie; @@ -2378,7 +2448,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile) /* Now look for partial symbols */ - scan_partial_symbols (thisdie + di.dielength, nextdie, objfile); + scan_partial_symbols (thisdie + di.die_length, nextdie, objfile); pst -> n_global_syms = objfile -> global_psymbols.next - (objfile -> global_psymbols.list + pst -> globals_offset); @@ -2429,7 +2499,7 @@ new_symbol (dip, objfile) SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_STATIC; SYMBOL_TYPE (sym) = decode_die_type (dip); - switch (dip -> dietag) + switch (dip -> die_tag) { case TAG_label: SYMBOL_VALUE (sym) = dip -> at_low_pc; @@ -2440,7 +2510,7 @@ new_symbol (dip, objfile) SYMBOL_VALUE (sym) = dip -> at_low_pc; SYMBOL_TYPE (sym) = lookup_function_type (SYMBOL_TYPE (sym)); SYMBOL_CLASS (sym) = LOC_BLOCK; - if (dip -> dietag == TAG_global_subroutine) + if (dip -> die_tag == TAG_global_subroutine) { add_symbol_to_list (sym, &global_symbols); } @@ -2533,9 +2603,9 @@ DESCRIPTION Decode a block of data containing a modified fundamental type specification. TYPEDATA is a pointer to the block, - which consists of a two byte length, containing the size - of the rest of the block. At the end of the block is a - two byte value that gives the fundamental type. Everything + which starts with a length containing the size of the rest + of the block. At the end of the block is a fundmental type + code value that gives the fundamental type. Everything in between are type modifiers. We simply compute the number of modifiers and call the general @@ -2548,16 +2618,21 @@ decode_mod_fund_type (typedata) { struct type *typep = NULL; unsigned short modcount; - unsigned char *modifiers; + int nbytes; /* Get the total size of the block, exclusive of the size itself */ - SWAPIN (modcount, typedata, current_objfile); + + nbytes = attribute_size (AT_mod_fund_type); + modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile); + typedata += nbytes; + /* Deduct the size of the fundamental type bytes at the end of the block. */ - modcount -= sizeof (short); - /* Skip over the two size bytes at the beginning of the block. */ - modifiers = (unsigned char *) typedata + sizeof (short); + + modcount -= attribute_size (AT_fund_type); + /* Now do the actual decoding */ - typep = decode_modified_type (modifiers, modcount, AT_mod_fund_type); + + typep = decode_modified_type (typedata, modcount, AT_mod_fund_type); return (typep); } @@ -2590,16 +2665,21 @@ decode_mod_u_d_type (typedata) { struct type *typep = NULL; unsigned short modcount; - unsigned char *modifiers; + int nbytes; /* Get the total size of the block, exclusive of the size itself */ - SWAPIN (modcount, typedata, current_objfile); + + nbytes = attribute_size (AT_mod_u_d_type); + modcount = target_to_host (typedata, nbytes, GET_UNSIGNED, current_objfile); + typedata += nbytes; + /* Deduct the size of the reference type bytes at the end of the block. */ - modcount -= sizeof (long); - /* Skip over the two size bytes at the beginning of the block. */ - modifiers = (unsigned char *) typedata + sizeof (short); + + modcount -= attribute_size (AT_user_def_type); + /* Now do the actual decoding */ - typep = decode_modified_type (modifiers, modcount, AT_mod_u_d_type); + + typep = decode_modified_type (typedata, modcount, AT_mod_u_d_type); return (typep); } @@ -2651,22 +2731,27 @@ decode_modified_type (modifiers, modcount, mtype) { struct type *typep = NULL; unsigned short fundtype; - DIEREF dieref; + DIE_REF die_ref; unsigned char modifier; + int nbytes; if (modcount == 0) { switch (mtype) { case AT_mod_fund_type: - SWAPIN (fundtype, modifiers, current_objfile); + nbytes = attribute_size (AT_fund_type); + fundtype = target_to_host (modifiers, nbytes, GET_UNSIGNED, + current_objfile); typep = decode_fund_type (fundtype); break; case AT_mod_u_d_type: - SWAPIN (dieref, modifiers, current_objfile); - if ((typep = lookup_utype (dieref)) == NULL) + nbytes = attribute_size (AT_user_def_type); + die_ref = target_to_host (modifiers, nbytes, GET_UNSIGNED, + current_objfile); + if ((typep = lookup_utype (die_ref)) == NULL) { - typep = alloc_utype (dieref, NULL); + typep = alloc_utype (die_ref, NULL); } break; default: @@ -2681,24 +2766,24 @@ decode_modified_type (modifiers, modcount, mtype) typep = decode_modified_type (modifiers, --modcount, mtype); switch (modifier) { - case MOD_pointer_to: - typep = lookup_pointer_type (typep); - break; - case MOD_reference_to: - typep = lookup_reference_type (typep); - break; - case MOD_const: - SQUAWK (("type modifier 'const' ignored")); /* FIXME */ - break; - case MOD_volatile: - SQUAWK (("type modifier 'volatile' ignored")); /* FIXME */ - break; - default: - if (!(MOD_lo_user <= modifier && modifier <= MOD_hi_user)) - { - SQUAWK (("unknown type modifier %u", modifier)); - } - break; + case MOD_pointer_to: + typep = lookup_pointer_type (typep); + break; + case MOD_reference_to: + typep = lookup_reference_type (typep); + break; + case MOD_const: + SQUAWK (("type modifier 'const' ignored")); /* FIXME */ + break; + case MOD_volatile: + SQUAWK (("type modifier 'volatile' ignored")); /* FIXME */ + break; + default: + if (!(MOD_lo_user <= modifier && modifier <= MOD_hi_user)) + { + SQUAWK (("unknown type modifier %u", modifier)); + } + break; } } return (typep); @@ -2906,14 +2991,14 @@ DESCRIPTION NOTES All DIE's must have at least a valid length, thus the minimum - DIE size is sizeof (long). In order to have a valid tag, the - DIE size must be at least sizeof (short) larger, otherwise they + DIE size is SIZEOF_DIE_LENGTH. In order to have a valid tag, the + DIE size must be at least SIZEOF_DIE_TAG larger, otherwise they are forced to be TAG_padding DIES. - Padding DIES must be at least sizeof(long) in length, implying that - if a padding DIE is used for alignment and the amount needed is less - than sizeof(long) then the padding DIE has to be big enough to align - to the next alignment boundry. + Padding DIES must be at least SIZEOF_DIE_LENGTH in length, implying + that if a padding DIE is used for alignment and the amount needed is + less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big + enough to align to the next alignment boundry. */ static void @@ -2925,19 +3010,22 @@ basicdieinfo (dip, diep, objfile) curdie = dip; (void) memset (dip, 0, sizeof (struct dieinfo)); dip -> die = diep; - dip -> dieref = dbroff + (diep - dbbase); - SWAPIN (dip -> dielength, diep, objfile); - if (dip -> dielength < sizeof (long)) + dip -> die_ref = dbroff + (diep - dbbase); + dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED, + objfile); + if (dip -> die_length < SIZEOF_DIE_LENGTH) { - dwarfwarn ("malformed DIE, bad length (%d bytes)", dip -> dielength); + dwarfwarn ("malformed DIE, bad length (%d bytes)", dip -> die_length); } - else if (dip -> dielength < (sizeof (long) + sizeof (short))) + else if (dip -> die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG)) { - dip -> dietag = TAG_padding; + dip -> die_tag = TAG_padding; } else { - SWAPIN (dip -> dietag, diep + sizeof (long), objfile); + diep += SIZEOF_DIE_LENGTH; + dip -> die_tag = target_to_host (diep, SIZEOF_DIE_TAG, GET_UNSIGNED, + objfile); } } @@ -2982,67 +3070,87 @@ completedieinfo (dip, objfile) char *end; /* Terminate DIE scan here */ unsigned short attr; /* Current attribute being scanned */ unsigned short form; /* Form of the attribute */ - short block2sz; /* Size of a block2 attribute field */ - long block4sz; /* Size of a block4 attribute field */ + int nbytes; /* Size of next field to read */ diecount++; diep = dip -> die; - end = diep + dip -> dielength; - diep += sizeof (long) + sizeof (short); + end = diep + dip -> die_length; + diep += SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG; while (diep < end) { - SWAPIN (attr, diep, objfile); - diep += sizeof (short); + attr = target_to_host (diep, SIZEOF_ATTRIBUTE, GET_UNSIGNED, objfile); + diep += SIZEOF_ATTRIBUTE; + if ((nbytes = attribute_size (attr)) == -1) + { + SQUAWK (("unknown attribute length, skipped remaining attributes"));; + diep = end; + continue; + } switch (attr) { case AT_fund_type: - SWAPIN (dip -> at_fund_type, diep, objfile); + dip -> at_fund_type = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_ordering: - SWAPIN (dip -> at_ordering, diep, objfile); + dip -> at_ordering = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_bit_offset: - SWAPIN (dip -> at_bit_offset, diep, objfile); + dip -> at_bit_offset = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_visibility: - SWAPIN (dip -> at_visibility, diep, objfile); + dip -> at_visibility = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_sibling: - SWAPIN (dip -> at_sibling, diep, objfile); + dip -> at_sibling = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_stmt_list: - SWAPIN (dip -> at_stmt_list, diep, objfile); + dip -> at_stmt_list = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); dip -> has_at_stmt_list = 1; break; case AT_low_pc: - SWAPIN (dip -> at_low_pc, diep, objfile); + dip -> at_low_pc = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); dip -> at_low_pc += baseaddr; dip -> has_at_low_pc = 1; break; case AT_high_pc: - SWAPIN (dip -> at_high_pc, diep, objfile); + dip -> at_high_pc = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); dip -> at_high_pc += baseaddr; break; case AT_language: - SWAPIN (dip -> at_language, diep, objfile); + dip -> at_language = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_user_def_type: - SWAPIN (dip -> at_user_def_type, diep, objfile); + dip -> at_user_def_type = target_to_host (diep, nbytes, + GET_UNSIGNED, objfile); break; case AT_byte_size: - SWAPIN (dip -> at_byte_size, diep, objfile); + dip -> at_byte_size = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_bit_size: - SWAPIN (dip -> at_bit_size, diep, objfile); + dip -> at_bit_size = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_member: - SWAPIN (dip -> at_member, diep, objfile); + dip -> at_member = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_discr: - SWAPIN (dip -> at_discr, diep, objfile); + dip -> at_discr = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_import: - SWAPIN (dip -> at_import, diep, objfile); + dip -> at_import = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_location: dip -> at_location = diep; @@ -3080,19 +3188,23 @@ completedieinfo (dip, objfile) dip -> at_producer = diep; break; case AT_frame_base: - SWAPIN (dip -> at_frame_base, diep, objfile); + dip -> at_frame_base = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_start_scope: - SWAPIN (dip -> at_start_scope, diep, objfile); + dip -> at_start_scope = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_stride_size: - SWAPIN (dip -> at_stride_size, diep, objfile); + dip -> at_stride_size = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_src_info: - SWAPIN (dip -> at_src_info, diep, objfile); + dip -> at_src_info = target_to_host (diep, nbytes, GET_UNSIGNED, + objfile); break; case AT_prototyped: - SWAPIN (dip -> at_prototyped, diep, objfile); + dip -> at_prototyped = diep; break; default: /* Found an attribute that we are unprepared to handle. However @@ -3102,75 +3214,150 @@ completedieinfo (dip, objfile) we can just ignore the unknown attribute. */ break; } - form = attr & 0xF; + form = FORM_FROM_ATTR (attr); switch (form) { case FORM_DATA2: - diep += sizeof (short); + diep += 2; break; case FORM_DATA4: - diep += sizeof (long); + case FORM_REF: + diep += 4; break; case FORM_DATA8: - diep += 8 * sizeof (char); /* sizeof (long long) ? */ + diep += 8; break; case FORM_ADDR: - case FORM_REF: - diep += sizeof (long); + diep += TARGET_FT_POINTER_SIZE (objfile); break; case FORM_BLOCK2: - SWAPIN (block2sz, diep, objfile); - block2sz += sizeof (short); - diep += block2sz; + diep += 2 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile); break; case FORM_BLOCK4: - SWAPIN (block4sz, diep, objfile); - block4sz += sizeof (long); - diep += block4sz; + diep += 4 + target_to_host (diep, nbytes, GET_UNSIGNED, objfile); break; case FORM_STRING: diep += strlen (diep) + 1; break; default: - SQUAWK (("unknown attribute form (0x%x), skipped rest", form)); + SQUAWK (("unknown attribute form (0x%x)", form)); + SQUAWK (("unknown attribute length, skipped remaining attributes"));; diep = end; break; } } } +/* -static void -swapin (to, from, nbytes, objfile) - char *to; +LOCAL FUNCTION + + target_to_host -- swap in target data to host + +SYNOPSIS + + target_to_host (char *from, int nbytes, int signextend, + struct objfile *objfile) + +DESCRIPTION + + Given pointer to data in target format in FROM, a byte count for + the size of the data in NBYTES, a flag indicating whether or not + the data is signed in SIGNEXTEND, and a pointer to the current + objfile in OBJFILE, convert the data to host format and return + the converted value. + +NOTES + + FIXME: If we read data that is known to be signed, and expect to + use it as signed data, then we need to explicitly sign extend the + result until the bfd library is able to do this for us. + + */ + +static unsigned long +target_to_host (from, nbytes, signextend, objfile) char *from; int nbytes; + int signextend; /* FIXME: Unused */ struct objfile *objfile; { + unsigned long rtnval; switch (nbytes) { -#if defined (LONG_LONG) case 8: - *(long long *)to = - bfd_h_get_64 (objfile -> obfd, (unsigned char *) from); + rtnval = bfd_get_64 (objfile -> obfd, (bfd_byte *) from); break; -#endif case 4: - *(long *)to = bfd_h_get_32 (objfile -> obfd, (unsigned char *) from); + rtnval = bfd_get_32 (objfile -> obfd, (bfd_byte *) from); break; case 2: - *(short *)to = bfd_h_get_16 (objfile -> obfd, (unsigned char *) from); + rtnval = bfd_get_16 (objfile -> obfd, (bfd_byte *) from); break; case 1: - *to = bfd_h_get_8 (objfile -> obfd, (unsigned char *) from); + rtnval = bfd_get_8 (objfile -> obfd, (bfd_byte *) from); break; default: - /* For objects bigger than we know how to swap in, just copy - them without any swapping. We should probably warn about this. - FIXME. */ - (void) memcpy (to, from, nbytes); + dwarfwarn ("no bfd support for %d byte data object", nbytes); + rtnval = 0; break; } + return (rtnval); } +/* + +LOCAL FUNCTION + + attribute_size -- compute size of data for a DWARF attribute + +SYNOPSIS + + static int attribute_size (unsigned int attr) + +DESCRIPTION + + Given a DWARF attribute in ATTR, compute the size of the first + piece of data associated with this attribute and return that + size. + + Returns -1 for unrecognized attributes. + + */ + +static int +attribute_size (attr) + unsigned int attr; +{ + int nbytes; /* Size of next data for this attribute */ + unsigned short form; /* Form of the attribute */ + + form = FORM_FROM_ATTR (attr); + switch (form) + { + case FORM_STRING: /* A variable length field is next */ + nbytes = 0; + break; + case FORM_DATA2: /* Next 2 byte field is the data itself */ + case FORM_BLOCK2: /* Next 2 byte field is a block length */ + nbytes = 2; + break; + case FORM_DATA4: /* Next 4 byte field is the data itself */ + case FORM_BLOCK4: /* Next 4 byte field is a block length */ + case FORM_REF: /* Next 4 byte field is a DIE offset */ + nbytes = 4; + break; + case FORM_DATA8: /* Next 8 byte field is the data itself */ + nbytes = 8; + break; + case FORM_ADDR: /* Next field size is target sizeof(void *) */ + nbytes = TARGET_FT_POINTER_SIZE (objfile); + break; + default: + SQUAWK (("unknown attribute form (0x%x)", form)); + nbytes = -1; + break; + } + return (nbytes); +}