summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominique Martinet <dominique.martinet@cea.fr>2017-10-03 04:14:58 +0000
committerDominique Martinet <dominique.martinet@cea.fr>2017-10-03 04:14:58 +0000
commit21e4dcb88141aefc7a05d35f687793415a81cd15 (patch)
tree9f48ef7520a90027f77fbf41214b7d8aa6c8e624
init ripoff from https://raw.githubusercontent.com/WolfgangSt/libdwarf/master/dwarfexample/simplereader.c
-rw-r--r--dwarf.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/dwarf.c b/dwarf.c
new file mode 100644
index 0000000..7d305fe
--- /dev/null
+++ b/dwarf.c
@@ -0,0 +1,198 @@
+/*
+ Copyright (c) 2009, David Anderson.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the example nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY David Anderson ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL David Anderson BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+/* simplereader.c
+ This is an example of code reading dwarf .debug_info.
+ It is kept as simple as possible to expose essential features.
+ It does not do all possible error reporting or error handling.
+
+ To use, try
+ make
+ ./simplereader simplereader
+*/
+#include <sys/types.h> /* For open() */
+#include <sys/stat.h> /* For open() */
+#include <fcntl.h> /* For open() */
+#include <stdlib.h> /* For exit() */
+#include <unistd.h> /* For close() */
+#include <stdio.h>
+#include <errno.h>
+#include "dwarf.h"
+#include "libdwarf.h"
+
+
+static void read_cu_list(Dwarf_Debug dbg);
+static void print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me,int level);
+static void get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level);
+
+int
+main(int argc, char **argv)
+{
+
+ Dwarf_Debug dbg = 0;
+ int fd = -1;
+ const char *filepath = "<stdin>";
+ int res = DW_DLV_ERROR;
+ Dwarf_Error error;
+ Dwarf_Handler errhand = 0;
+ Dwarf_Ptr errarg = 0;
+
+ if(argc < 2) {
+ fd = 0; /* stdin */
+ } else {
+ filepath = argv[1];
+ fd = open(filepath,O_RDONLY);
+ }
+ if(fd < 0) {
+ printf("Failure attempting to open %s\n",filepath);
+ }
+ res = dwarf_init(fd,DW_DLC_READ,errhand,errarg, &dbg,&error);
+ if(res != DW_DLV_OK) {
+ printf("Giving up, cannot do DWARF processing\n");
+ exit(1);
+ }
+
+ read_cu_list(dbg);
+ res = dwarf_finish(dbg,&error);
+ if(res != DW_DLV_OK) {
+ printf("dwarf_finish failed!\n");
+ }
+ close(fd);
+ return 0;
+}
+
+static void
+read_cu_list(Dwarf_Debug dbg)
+{
+ Dwarf_Unsigned cu_header_length = 0;
+ Dwarf_Half version_stamp = 0;
+ Dwarf_Unsigned abbrev_offset = 0;
+ Dwarf_Half address_size = 0;
+ Dwarf_Unsigned next_cu_header = 0;
+ Dwarf_Error error;
+ int cu_number = 0;
+
+ for(;;++cu_number) {
+ Dwarf_Die no_die = 0;
+ Dwarf_Die cu_die = 0;
+ int res = DW_DLV_ERROR;
+ res = dwarf_next_cu_header(dbg,&cu_header_length,
+ &version_stamp, &abbrev_offset, &address_size,
+ &next_cu_header, &error);
+ if(res == DW_DLV_ERROR) {
+ printf("Error in dwarf_next_cu_header\n");
+ exit(1);
+ }
+ if(res == DW_DLV_NO_ENTRY) {
+ /* Done. */
+ return;
+ }
+ /* The CU will have a single sibling, a cu_die. */
+ res = dwarf_siblingof(dbg,no_die,&cu_die,&error);
+ if(res == DW_DLV_ERROR) {
+ printf("Error in dwarf_siblingof on CU die \n");
+ exit(1);
+ }
+ if(res == DW_DLV_NO_ENTRY) {
+ /* Impossible case. */
+ printf("no entry! in dwarf_siblingof on CU die \n");
+ exit(1);
+ }
+ get_die_and_siblings(dbg,cu_die,0);
+ dwarf_dealloc(dbg,cu_die,DW_DLA_DIE);
+ }
+}
+
+static void
+get_die_and_siblings(Dwarf_Debug dbg, Dwarf_Die in_die,int in_level)
+{
+ int res = DW_DLV_ERROR;
+ Dwarf_Die cur_die=in_die;
+ Dwarf_Die child = 0;
+ Dwarf_Error error;
+ print_die_data(dbg,in_die,in_level);
+
+ for(;;) {
+ Dwarf_Die sib_die = 0;
+ res = dwarf_child(cur_die,&child,&error);
+ if(res == DW_DLV_ERROR) {
+ printf("Error in dwarf_child , level %d \n",in_level);
+ exit(1);
+ }
+ if(res == DW_DLV_OK) {
+ get_die_and_siblings(dbg,child,in_level+1);
+ }
+ /* res == DW_DLV_NO_ENTRY */
+ res = dwarf_siblingof(dbg,cur_die,&sib_die,&error);
+ if(res == DW_DLV_ERROR) {
+ printf("Error in dwarf_siblingof , level %d \n",in_level);
+ exit(1);
+ }
+ if(res == DW_DLV_NO_ENTRY) {
+ /* Done at this level. */
+ break;
+ }
+ /* res == DW_DLV_OK */
+ if(cur_die != in_die) {
+ dwarf_dealloc(dbg,cur_die,DW_DLA_DIE);
+ }
+ cur_die = sib_die;
+ }
+ return;
+}
+
+static void
+print_die_data(Dwarf_Debug dbg, Dwarf_Die print_me,int level)
+{
+ char *name = 0;
+ Dwarf_Error error = 0;
+ Dwarf_Half tag = 0;
+ const char *tagname = 0;
+ int res = dwarf_diename(print_me,&name,&error);
+ if(res == DW_DLV_ERROR) {
+ printf("Error in dwarf_diename , level %d \n",level);
+ exit(1);
+ }
+ if(res == DW_DLV_NO_ENTRY) {
+ return;
+ }
+ res = dwarf_tag(print_me,&tag,&error);
+ if(res != DW_DLV_OK) {
+ printf("Error in dwarf_tag , level %d \n",level);
+ exit(1);
+ }
+ res = dwarf_get_TAG_name(tag,&tagname);
+ if(res != DW_DLV_OK) {
+ printf("Error in dwarf_get_TAG_name , level %d \n",level);
+ exit(1);
+ }
+ printf("<%d> tag: %d %s name: %s\n",level,tag,tagname,name);
+ dwarf_dealloc(dbg,name,DW_DLA_STRING);
+}
+
+
+