Hi.

This patch clean up the DWARF code for the next patch.

Thanks
Ken'ichi Ohmichi


diff -puN makedumpfile.org/makedumpfile.c makedumpfile/makedumpfile.c
--- makedumpfile.org/makedumpfile.c     2006-12-07 16:59:10.000000000 +0900
+++ makedumpfile/makedumpfile.c 2006-12-07 17:01:21.000000000 +0900
@@ -836,75 +836,72 @@ is_kvaddr(unsigned long long addr)
 }
 
 static int
-process_attribute(Dwarf_Attribute *attr, void *cb_data)
+get_data_member_location(Dwarf_Die *die)
 {
-       struct dwarf_values *args = cb_data;
-       Dwarf_Op *expr;
        size_t expcnt;
+       Dwarf_Attribute attr;
+       Dwarf_Op *expr;
 
-       switch (attr->code) {
-       case DW_AT_data_member_location:
-               dwarf_getlocation (attr, &expr, &expcnt);
-               if (dwarf_info.member_offset == NOT_FOUND_STRUCTURE)
-                       dwarf_info.member_offset = expr[0].number;
-               *args->found_map |= DWARF_INFO_FOUND_LOCATION;
-               break;
-       default:
-               break;
-       }
+       if (dwarf_attr(die, DW_AT_data_member_location, &attr) == NULL)
+               return FALSE;
+
+       if (dwarf_getlocation(&attr, &expr, &expcnt) < 0)
+               return FALSE;
 
-       return 0;
+       dwarf_info.member_offset = expr[0].number;
+
+       return TRUE;
 }
 
-static int
-process_children(Dwarf_Die *die, uint32_t *found_map)
+static void
+process_children(Dwarf_Die *die)
 {
-       Dwarf_Die child;
-       Dwarf_Die *walker;
-       int rc;
+       int tag;
        const char *name;
-       struct dwarf_values args;
+       Dwarf_Die child, *walker;
+
+       if (dwarf_child(die, &child) != 0)
+               return;
 
-       rc = dwarf_child(die, &child);
        walker = &child;
        
-       while (rc == 0) {
+       do {
+               tag  = dwarf_tag(walker);
                name = dwarf_diename(walker);
-               if ((dwarf_info.cmd == DWARF_INFO_GET_MEMBER_OFFSET)
-                   && (dwarf_tag(walker) == DW_TAG_member)
-                   && (name) && (!strcmp(name, dwarf_info.member_name))) {
+
+               if (tag != DW_TAG_member)
+                       continue;
+
+               switch (dwarf_info.cmd) {
+               case DWARF_INFO_GET_MEMBER_OFFSET:
+                       if ((!name) || strcmp(name, dwarf_info.member_name))
+                               continue;
                        /*
-                        * get the attirbutes of this die to record the
-                        * location of the symbol
+                        * Get the member offset.
                         */
-                       *found_map |= DWARF_INFO_FOUND_MEMBER;
-               }
-               if ((dwarf_info.cmd == DWARF_INFO_GET_NOT_NAMED_UNION_OFFSET)
-                   && (dwarf_tag(walker) == DW_TAG_member)
-                   && (!name)) {
-                       *found_map |= DWARF_INFO_FOUND_MEMBER;
-               }
-               if (*found_map & DWARF_INFO_FOUND_MEMBER) {
-                       args.die = walker;
-                       args.found_map = found_map;
-                       dwarf_getattrs(walker, process_attribute, &args, 0);
-                       if ((*found_map & DWARF_INFO_FOUND_ALL)
-                           == DWARF_INFO_FOUND_ALL)
-                               return TRUE;
+                       if (!get_data_member_location(walker))
+                               continue;
+                       return;
+               case DWARF_INFO_GET_NOT_NAMED_UNION_OFFSET:
+                       if (name)
+                               continue;
+                       /*
+                        * Get the member offset.
+                        */
+                       if (!get_data_member_location(walker))
+                               continue;
+                       return;
                }
-
-               rc = dwarf_siblingof(walker, walker); 
-       }
+       } while (!dwarf_siblingof(walker, walker)); 
 
        /*
-        * Return TRUE even if not found. Return FALSE if I/O error
-        * in the future.
+        * Return even if not found.
         */
-       return TRUE;
+       return;
 }
 
 static void
-search_die_tree(Dwarf *dwarfd, Dwarf_Die *die, uint32_t *found_map)
+search_die_tree(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 {
        Dwarf_Die child; 
        int tag;
@@ -914,58 +911,65 @@ search_die_tree(Dwarf *dwarfd, Dwarf_Die
         * start by looking at the children
         */
        if (dwarf_child(die, &child) == 0)
-               search_die_tree(dwarfd, &child, found_map);
+               search_die_tree(dwarfd, &child, found);
+
+       if (*found)
+               return;
 
        /*
         * If we get to here then we don't have any more
         * children, check to see if this is a relevant tag
         */
-next_tag:
-       tag = dwarf_tag(die);
-       name = dwarf_diename(die);
-       if ((tag == DW_TAG_structure_type)
-           && (name) && (!strcmp(name, dwarf_info.struct_name))) {
+       do {
+               tag  = dwarf_tag(die);
+               name = dwarf_diename(die);
+               if ((tag != DW_TAG_structure_type) || (!name)
+                   || strcmp(name, dwarf_info.struct_name))
+                       continue;
                /*
-                * this is our structure
-                * process the children
+                * Skip if DW_AT_byte_size is not included.
                 */
                dwarf_info.struct_size = dwarf_bytesize(die);
-               if (dwarf_info.struct_size > 0) {
-                       *found_map |= DWARF_INFO_FOUND_STRUCT;
-                       if (dwarf_info.cmd == DWARF_INFO_GET_STRUCT_SIZE)
-                               return;
-                       if (process_children(die, found_map) == TRUE)
-                               return;
-               }
+
+               if (dwarf_info.struct_size > 0)
+                       break;
+
+       } while (!dwarf_siblingof(die, die));
+
+       if (dwarf_info.struct_size <= 0) {
                /*
-                * Skip if DW_AT_byte_size is not included.
+                * Not found the demanded structure.
                 */
+               return;
        }
 
-       if (dwarf_siblingof(die, die) == 0)
-               goto next_tag;
-
+       /*
+        * Found the demanded structure.
+        */
+       *found = TRUE;
+       switch (dwarf_info.cmd) {
+       case DWARF_INFO_GET_STRUCT_SIZE:
+               break;
+       case DWARF_INFO_GET_MEMBER_OFFSET:
+       case DWARF_INFO_GET_NOT_NAMED_UNION_OFFSET:
+               process_children(die);
+               break;
+       }
 }
 
-
 int
 get_debug_info(void)
 {
+       int found = FALSE;
+       char *name = NULL;
+       size_t shstrndx, header_size;
+       uint8_t address_size, offset_size;
        Dwarf *dwarfd = NULL;
        Elf *elfd = NULL;
-       Dwarf_Off off = 0;
-       Dwarf_Off next_off = 0;
+       Dwarf_Off off = 0, next_off = 0, abbrev_offset = 0;
        Elf_Scn *scn = NULL;
-       GElf_Shdr scnhdr_mem;
-       GElf_Shdr *scnhdr = NULL;
-       size_t header_size;
-       Dwarf_Off abbrev_offset = 0;
+       GElf_Shdr scnhdr_mem, *scnhdr = NULL;
        Dwarf_Die cu_die;
-       uint8_t address_size;
-       uint8_t offset_size;
-       uint32_t found_map = 0;
-       char *name = NULL;
-       size_t shstrndx;
        const off_t failed = (off_t)-1;
 
        int ret = FALSE;
@@ -980,39 +984,43 @@ get_debug_info(void)
                    dwarf_info.vmlinux_name);
                return FALSE;
        }
-
        if (!(dwarfd = dwarf_begin_elf(elfd, DWARF_C_READ, NULL))) {
                ERRMSG("Can't create a handle for a new debug session.\n");
                goto out;
        }
-
        if (elf_getshstrndx(elfd, &shstrndx) < 0) {
                ERRMSG("Can't get the section index of the string table.\n");
                goto out;
        }
-       while ((scn = elf_nextscn(elfd, scn)) != NULL) {
 
+       /*
+        * Search for ".debug_info" section.
+        */
+       while ((scn = elf_nextscn(elfd, scn)) != NULL) {
                scnhdr = gelf_getshdr(scn, &scnhdr_mem);
-
                name = elf_strptr(elfd, shstrndx, scnhdr->sh_name);
-
                if (strcmp(name, ".debug_info"))
                        continue;
+       }
+       if (!strcmp(name, ".debug_info")) {
+               ERRMSG("Can't get .debug_info section.\n");
+               goto out;
+       }
 
-               while (dwarf_nextcu(dwarfd, off, &next_off, &header_size,
-                   &abbrev_offset, &address_size, &offset_size) == 0) {
-                       off += header_size;
-                       if (dwarf_offdie(dwarfd, off, &cu_die) == NULL) {
-                               ERRMSG("Can't get CU die.\n");
-                               goto out;
-                       }
-                       search_die_tree(dwarfd, &cu_die, &found_map);
-                       if (found_map & DWARF_INFO_FOUND_STRUCT)
-                               break;
-                       off = next_off;
+       /*
+        * Search by each CompileUnit.
+        */
+       while (dwarf_nextcu(dwarfd, off, &next_off, &header_size,
+           &abbrev_offset, &address_size, &offset_size) == 0) {
+               off += header_size;
+               if (dwarf_offdie(dwarfd, off, &cu_die) == NULL) {
+                       ERRMSG("Can't get CU die.\n");
+                       goto out;
                }
-               if (found_map & DWARF_INFO_FOUND_STRUCT)
+               search_die_tree(dwarfd, &cu_die, &found);
+               if (found)
                        break;
+               off = next_off;
        }
        ret = TRUE;
 out:
@@ -1020,7 +1028,6 @@ out:
                dwarf_end(dwarfd);
        if (elfd != NULL)
                elf_end(elfd);
-       dwarf_info.status = found_map;
 
        return ret;
 }
@@ -1032,7 +1039,6 @@ long
 get_structure_size(char *structname)
 {
        dwarf_info.cmd = DWARF_INFO_GET_STRUCT_SIZE;
-       dwarf_info.status = 0;
        dwarf_info.struct_name = structname;
        dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
 
@@ -1049,7 +1055,6 @@ long
 get_member_offset(char *structname, char *membername, int cmd)
 {
        dwarf_info.cmd = cmd;
-       dwarf_info.status = 0;
        dwarf_info.struct_name = structname;
        dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
        dwarf_info.member_name = membername;
diff -puN makedumpfile.org/makedumpfile.h makedumpfile/makedumpfile.h
--- makedumpfile.org/makedumpfile.h     2006-12-07 16:59:10.000000000 +0900
+++ makedumpfile/makedumpfile.h 2006-12-07 16:56:21.000000000 +0900
@@ -540,13 +540,8 @@ extern struct offset_table offset_table;
 #define DWARF_INFO_GET_STRUCT_SIZE             1
 #define DWARF_INFO_GET_MEMBER_OFFSET           2
 #define DWARF_INFO_GET_NOT_NAMED_UNION_OFFSET  3
-#define DWARF_INFO_FOUND_STRUCT                        1
-#define DWARF_INFO_FOUND_MEMBER                        2
-#define DWARF_INFO_FOUND_LOCATION              4
-#define DWARF_INFO_FOUND_ALL   
(DWARF_INFO_FOUND_STRUCT|DWARF_INFO_FOUND_MEMBER|DWARF_INFO_FOUND_LOCATION)
 
 struct dwarf_info {
-       uint32_t        status;         /* TEMP */
        unsigned int    cmd;            /* IN */
        char    *vmlinux_name;          /* IN */
        char    *struct_name;           /* IN */
_______________________________________________
fastboot mailing list
[email protected]
https://lists.osdl.org/mailman/listinfo/fastboot

Reply via email to