/* OpenIDA - Outil d'analyse de fichiers binaires * info.c - lecture des informations principales du format DWARF * * Copyright (C) 2008 Cyrille Bagard * * This file is part of OpenIDA. * * OpenIDA is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * OpenIDA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "info.h" #include #include "abbrev.h" #include "dwarf-int.h" #include "utils.h" /* Informations utiles d'une unité de compilation */ typedef struct _compil_unit { off_t endpos; /* Position d'unité suivante */ off_t offset; /* Position dans les abréviat° */ uint8_t ptrsize; /* Taille des adresses mémoire */ } compil_unit; /* Procède à la lecture d'une unité de compilation. */ bool read_dwarf_compilation_unit(dwarf_format *, off_t *, compil_unit *); /* Enregistre toutes les déclarations de fonction trouvées. */ bool look_for_dwarf_subprograms(dwarf_format *, off_t *, const compil_unit *); /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * * * Description : Charge les informations trouvées dans un DWARF. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool load_dwarf_information(dwarf_format *format) { bool result; /* Bilan à renvoyer */ off_t offset; off_t start; off_t size; bool test; int i; compil_unit cu; result = true; test = find_exe_section(DBG_FORMAT(format)->e_format, ".debug_info", &start, &size, NULL); offset = start; printf(" -> offset=%d size=%d\n", offset, size); for (i = 0; i < size; i++) { if (i % 25 == 0) printf("\n"); printf("0x%02hhx ", DBG_FORMAT(format)->content[offset + i]); } printf("\n"); while (offset < (start + size) && result) { printf("-------------\n"); result = read_dwarf_compilation_unit(format, &offset, &cu); if (result) look_for_dwarf_subprograms(format, &offset, &cu); //break; } return result; } /****************************************************************************** * * * Paramètres : format = informations de débogage à effacer. * * * * Description : Décharge les informations trouvées dans un DWARF. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void unload_dwarf_information(dwarf_format *format) { } /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * pos = tête de lecture à mettre à jour. [OUT] * * cu = unité de compilation lue. [OUT] * * * * Description : Procède à la lecture d'une unité de compilation. * * * * Retour : true en cas de succès de la lecture, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool read_dwarf_compilation_unit(dwarf_format *format, off_t *pos, compil_unit *cu) { bool result; /* Bilan à retourner */ off_t ulength; /* Taille de l'unité */ uint16_t version; /* Version du format DWARF */ off_t abbrev_pos; /* Position dans les abréviat° */ uint8_t memsize; /* Taille des adresses mémoire */ off_t oldpos; uint8_t index; result = true; if (read_unit_length(format, pos, &ulength)) printf("Unit Length :: %d (0x%x)\n", ulength, ulength); else printf("error ul\n"); cu->endpos = *pos + ulength; oldpos = *pos; if (read_uhalf(format, pos, &version)) printf("version :: %hd\n", version); else printf("error version\n"); if (version > 3) return false; if (read_abbrev_offset(format, pos, &abbrev_pos)) printf("abbrev offset :: %d\n", abbrev_pos); else printf("error abbrev offset\n"); if (read_address_size(format, pos, &memsize)) printf("mem size :: %hhd\n", memsize); else printf("error memsize\n"); cu->offset = abbrev_pos; cu->ptrsize = memsize; printf(" =+> Next :: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx\n", DBG_FORMAT(format)->content[*pos], DBG_FORMAT(format)->content[*pos + 1], DBG_FORMAT(format)->content[*pos + 2], DBG_FORMAT(format)->content[*pos + 3], DBG_FORMAT(format)->content[*pos + 4]); /* *pos = oldpos + ulength; */ return result; } /****************************************************************************** * * * Paramètres : format = informations de débogage à compléter. * * pos = tête de lecture à mettre à jour. [OUT] * * cu = unité de compilation courante. * * * * Description : Enregistre toutes les déclarations de fonction trouvées. * * * * Retour : true en cas de succès de la lecture, false sinon. * * * * Remarques : - * * * ******************************************************************************/ bool look_for_dwarf_subprograms(dwarf_format *format, off_t *pos, const compil_unit *cu) { bool result; /* Bilan à retourner */ uint8_t index; /* Indice de l'abbréviation */ result = true; off_t oldpos; const dw_abbrev *abbrev; uint64_t low_pc; uint64_t high_pc; while (*pos < cu->endpos) { if (read_address_size/*leb128*/(format, pos, &index)) printf("abbrev index :: %hhd\n", index); else printf("abbrev index error\n"); /* Contraintes d'alignement... */ if (index == 0) continue; abbrev = find_dwarf_abbreviations(format, &cu->offset, index); printf(" --> %p\n", abbrev); printf(" == 0x%02x (matched ? %d)\n", abbrev->tag, abbrev->tag == DWT_SUBPROGRAM); oldpos = *pos; if (abbrev->tag == DWT_SUBPROGRAM) { if (read_dwarf_abbrev_attribute(format, &oldpos, abbrev, DWA_LOW_PC, &low_pc)) printf(" ## LOW PC :: 0x%08x\n", low_pc); else printf(" error: no low pc\n"); oldpos = *pos; if (read_dwarf_abbrev_attribute(format, &oldpos, abbrev, DWA_HIGH_PC, &high_pc)) printf(" ## HIGH PC :: 0x%08x\n", high_pc); else printf(" error: no high pc\n"); } if (!skip_dwarf_abbrev(format, pos, abbrev)) printf("error skipping :(\n"); printf(" == progress %d\n", *pos - oldpos); printf(" == %d < %d\n", *pos, cu->endpos); } printf(" =+> Next :: 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx 0x%02hhx\n", DBG_FORMAT(format)->content[*pos], DBG_FORMAT(format)->content[*pos + 1], DBG_FORMAT(format)->content[*pos + 2], DBG_FORMAT(format)->content[*pos + 3], DBG_FORMAT(format)->content[*pos + 4]); return result; }