diff --git a/.cproject b/.cproject
index c683b296..8de35ed8 100644
--- a/.cproject
+++ b/.cproject
@@ -1,9 +1,11 @@
-
-
-
+
+
+
+
+
@@ -14,115 +16,35 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
@@ -132,32 +54,28 @@
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index b0c06c54..7364db3e 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -12,27 +12,35 @@ jobs:
runs-on: ${{matrix.os}}
strategy:
matrix:
- os: [ubuntu-18.04, ubuntu-latest]
+ os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- - name: Install Python 3
- uses: actions/setup-python@v1
with:
- python-version: 3.6
- - name: Install dependencies
- run: |
- pip install cpp-coveralls==0.4.2
- sudo apt-get install libdwarf-dev
- sudo apt-get install libelf-dev
- sudo apt-get install libsqlite3-dev
- sudo apt-get install g++
- sudo apt-get install gcovr
- - name: Checkout submodules
- run: git submodule update --init --recursive
- - name: Run tests
- run: make coverage
- #- name: publish to coveralls.io
- #uses: coverallsapp/github-action@v1.1.2
- #with:
- # github-token: ${{ github.token }}
+ submodules: true # Clone submodules
+ fetch-depth: 0 # Ensure full repository history is fetched
+
+ # Set up Docker Buildx (optional, useful for multi-platform builds)
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ # Build the Docker image
+ # - name: Build Docker image
+ # uses: docker/build-push-action@v5
+ # with:
+ # context: .
+ # push: false # Do not push the image
+ # tags: juicer:latest # Local tag for the built image
+
+ - name: Build Docker image For Ubuntu22
+ run: docker build --no-cache -t juicer:latest -f Dockerfile.ubuntu22 .
+
+ - name: Build Docker image For Ubuntu20
+ run: docker build --no-cache -t juicer:latest -f Dockerfile.ubuntu20 .
+ - name: Copy coverage report to host
+ run: docker image ls && img_id=$(docker create juicer:latest) && docker cp $img_id:/home/docker/juicer/coverage.gcov .
+ - name: publish to coveralls.io
+ run: wget https://github.com/coverallsapp/coverage-reporter/releases/download/v0.6.14/coveralls-linux && chmod a+x ./coveralls-linux && COVERALLS_REPO_TOKEN=${{ secrets.COVERALLS_REPO_TOKEN }} ./coveralls-linux
+
+ - name: Build Docker image For Ubuntu18
+ run: docker build --no-cache -t juicer:latest -f Dockerfile.ubuntu18 .
diff --git a/.gitignore b/.gitignore
index 378eac25..b201b2d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
build
+*autosave
diff --git a/.gitmodules b/.gitmodules
index c4f0301e..7dafbf5c 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "Catch2"]
path = Catch2
- url = git@penguin.windhoverlabs.lan:airliner/catch2.git
+ url = git@github.com:WindhoverLabs/Catch2.git
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
index d7da895f..8f3bb82c 100644
--- a/.settings/language.settings.xml
+++ b/.settings/language.settings.xml
@@ -1,35 +1,11 @@
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
new file mode 100644
index 00000000..c8ec5df2
--- /dev/null
+++ b/.settings/org.eclipse.cdt.core.prefs
@@ -0,0 +1,6 @@
+doxygen/doxygen_new_line_after_brief=true
+doxygen/doxygen_use_brief_tag=false
+doxygen/doxygen_use_javadoc_tags=true
+doxygen/doxygen_use_pre_tag=false
+doxygen/doxygen_use_structural_commands=false
+eclipse.preferences.version=1
diff --git a/Catch2 b/Catch2
index 7f21cc6c..182c910b 160000
--- a/Catch2
+++ b/Catch2
@@ -1 +1 @@
-Subproject commit 7f21cc6c5599f59835f769debf13b4c3e6148a28
+Subproject commit 182c910b4b63ff587a3440e08f84f70497e49a81
diff --git a/Dockerfile b/Dockerfile.ubuntu18
similarity index 67%
rename from Dockerfile
rename to Dockerfile.ubuntu18
index 8b048040..3c7a41b5 100644
--- a/Dockerfile
+++ b/Dockerfile.ubuntu18
@@ -1,4 +1,4 @@
-FROM ubuntu:20.04
+FROM ubuntu:18.04
RUN apt update
ARG DEBIAN_FRONTEND=noninteractive
ENV TERM xterm-256color
@@ -13,12 +13,18 @@ RUN apt-get install -y libelf-dev
RUN apt-get install -y libsqlite3-dev
RUN apt-get install -y libssl-dev
RUN apt-get install -y doxygen
+RUN apt-get install -y gcovr
RUN mkdir /home/docker
COPY . /home/docker/juicer
+
+
+RUN cd /home/docker/juicer && make clean
+RUN cd /home/docker/juicer && make docs
+
RUN cd /home/docker/juicer && make
RUN cd /home/docker/juicer && make clean
-RUN cd /home/docker/juicer && make build-tests
+RUN cd /home/docker/juicer && make all
WORKDIR /home/docker/juicer/build
RUN ./juicer-ut "[Enumeration]"
RUN ./juicer-ut "[main_test#1]"
@@ -29,11 +35,21 @@ RUN ./juicer-ut "[main_test#5]"
RUN ./juicer-ut "[main_test#6]"
RUN ./juicer-ut "[main_test#7]"
RUN ./juicer-ut "[main_test#8]"
+RUN ./juicer-ut "[main_test#9]"
+RUN ./juicer-ut "[main_test#10]"
+RUN ./juicer-ut "[main_test#11]"
+RUN ./juicer-ut "[main_test#12]"
+RUN ./juicer-ut "[main_test#13]"
+RUN ./juicer-ut "[main_test#14]"
+RUN ./juicer-ut "[main_test#15]"
+RUN ./juicer-ut "[main_test#16]"
+RUN ./juicer-ut "[main_test#17]"
+RUN ./juicer-ut "[main_test#18]"
+RUN ./juicer-ut "[main_test#19]"
+RUN ./juicer-ut "[main_test#20]"
RUN ./juicer-ut "[Module]"
RUN ./juicer-ut "[Symbol]"
-RUN cd /home/docker/juicer && make clean
-RUN cd /home/docker/juicer && make docs
diff --git a/Dockerfile.ubuntu18.dev b/Dockerfile.ubuntu18.dev
new file mode 100644
index 00000000..bc3295d9
--- /dev/null
+++ b/Dockerfile.ubuntu18.dev
@@ -0,0 +1,22 @@
+FROM ubuntu:18.04
+RUN apt update
+ARG DEBIAN_FRONTEND=noninteractive
+ENV TERM xterm-256color
+RUN apt-get update && \
+ apt-get -y install sudo
+
+RUN apt-get install -y gcc-multilib
+RUN apt-get install -y g++-multilib
+RUN apt-get install -y libdwarf-dev
+RUN apt-get install -y make
+RUN apt-get install -y libelf-dev
+RUN apt-get install -y libsqlite3-dev
+RUN apt-get install -y libssl-dev
+RUN apt-get install -y doxygen
+RUN apt-get install -y gcovr
+
+RUN mkdir /home/docker
+RUN mkdir /home/docker/juicer
+WORKDIR /home/docker/juicer
+
+
diff --git a/Dockerfile.ubuntu20 b/Dockerfile.ubuntu20
new file mode 100644
index 00000000..3cd7b29d
--- /dev/null
+++ b/Dockerfile.ubuntu20
@@ -0,0 +1,71 @@
+FROM ubuntu:20.04
+RUN apt update
+ARG DEBIAN_FRONTEND=noninteractive
+ENV TERM xterm-256color
+RUN apt-get update && \
+ apt-get -y install sudo
+
+RUN apt-get install -y gcc-multilib
+RUN apt-get install -y g++-multilib
+RUN apt-get install -y libdwarf-dev
+RUN apt-get install -y make
+RUN apt-get install -y libelf-dev
+RUN apt-get install -y libsqlite3-dev
+RUN apt-get install -y libssl-dev
+RUN apt-get install -y doxygen
+RUN apt-get install -y gcovr
+
+
+
+RUN apt-get install -y gnupg2
+RUN apt-get install -y software-properties-common
+RUN apt-get install -y python3-pip
+RUN pip3 install PyYAML
+
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421
+RUN add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal main'
+RUN apt-get install -y clang-format
+
+RUN mkdir /home/docker
+COPY . /home/docker/juicer
+
+
+RUN cd /home/docker/juicer && make check-format
+
+RUN cd /home/docker/juicer && make clean
+RUN cd /home/docker/juicer && make docs
+
+RUN cd /home/docker/juicer && make
+RUN cd /home/docker/juicer && make clean
+RUN cd /home/docker/juicer && make all
+WORKDIR /home/docker/juicer/build
+RUN ./juicer-ut "[Enumeration]"
+RUN ./juicer-ut "[main_test#1]"
+RUN ./juicer-ut "[main_test#2]"
+RUN ./juicer-ut "[main_test#3]"
+RUN ./juicer-ut "[main_test#4]"
+RUN ./juicer-ut "[main_test#5]"
+RUN ./juicer-ut "[main_test#6]"
+RUN ./juicer-ut "[main_test#7]"
+RUN ./juicer-ut "[main_test#8]"
+RUN ./juicer-ut "[main_test#9]"
+RUN ./juicer-ut "[main_test#10]"
+RUN ./juicer-ut "[main_test#11]"
+RUN ./juicer-ut "[main_test#12]"
+RUN ./juicer-ut "[main_test#13]"
+RUN ./juicer-ut "[main_test#14]"
+RUN ./juicer-ut "[main_test#15]"
+RUN ./juicer-ut "[main_test#16]"
+RUN ./juicer-ut "[main_test#17]"
+RUN ./juicer-ut "[main_test#18]"
+RUN ./juicer-ut "[main_test#19]"
+RUN ./juicer-ut "[main_test#20]"
+RUN ./juicer-ut "[Module]"
+RUN ./juicer-ut "[Symbol]"
+
+RUN cd /home/docker/juicer && make coverage
+#Useful for CI
+RUN cd /home/docker/juicer && gcovr --filter /home/docker/juicer/src/ --object-directory /home/docker/juicer/build/ut_obj/ --xml coverage.gcov
+
+
+
diff --git a/Dockerfile.ubuntu20.dev b/Dockerfile.ubuntu20.dev
new file mode 100644
index 00000000..61f55e19
--- /dev/null
+++ b/Dockerfile.ubuntu20.dev
@@ -0,0 +1,29 @@
+FROM ubuntu:20.04
+RUN apt update
+ARG DEBIAN_FRONTEND=noninteractive
+ENV TERM xterm-256color
+RUN apt-get update && \
+ apt-get -y install sudo
+
+RUN apt-get install -y gcc-multilib
+RUN apt-get install -y g++-multilib
+RUN apt-get install -y libdwarf-dev
+RUN apt-get install -y make
+RUN apt-get install -y libelf-dev
+RUN apt-get install -y libsqlite3-dev
+RUN apt-get install -y libssl-dev
+RUN apt-get install -y doxygen
+RUN apt-get install -y gdb
+RUN apt-get install -y gcovr
+RUN apt-get install -y gnupg2
+RUN apt-get install -y software-properties-common
+RUN apt-get install -y python3-pip
+RUN pip3 install PyYAML
+
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421
+RUN add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal main'
+RUN apt-get install -y clang-format
+
+RUN mkdir /home/docker
+RUN mkdir /home/docker/juicer
+WORKDIR /home/docker/juicer
diff --git a/Dockerfile.ubuntu22 b/Dockerfile.ubuntu22
new file mode 100644
index 00000000..1ae43458
--- /dev/null
+++ b/Dockerfile.ubuntu22
@@ -0,0 +1,58 @@
+FROM ubuntu:22.04
+RUN apt update
+ARG DEBIAN_FRONTEND=noninteractive
+ENV TERM xterm-256color
+RUN apt-get update && \
+ apt-get -y install sudo
+
+RUN apt-get install -y gcc-multilib
+RUN apt-get install -y g++-multilib
+RUN apt-get install -y libdwarf-dev
+RUN apt-get install -y make
+RUN apt-get install -y libelf-dev
+RUN apt-get install -y libsqlite3-dev
+RUN apt-get install -y libssl-dev
+RUN apt-get install -y doxygen
+RUN apt-get install -y gcovr
+
+RUN mkdir /home/docker
+COPY . /home/docker/juicer
+
+
+RUN cd /home/docker/juicer && make clean
+RUN cd /home/docker/juicer && make docs
+
+RUN cd /home/docker/juicer && make
+RUN cd /home/docker/juicer && make clean
+RUN cd /home/docker/juicer && make all
+WORKDIR /home/docker/juicer/build
+RUN ./juicer-ut "[Enumeration]"
+RUN ./juicer-ut "[main_test#1]"
+RUN ./juicer-ut "[main_test#2]"
+RUN ./juicer-ut "[main_test#3]"
+RUN ./juicer-ut "[main_test#4]"
+RUN ./juicer-ut "[main_test#5]"
+RUN ./juicer-ut "[main_test#6]"
+RUN ./juicer-ut "[main_test#7]"
+RUN ./juicer-ut "[main_test#8]"
+RUN ./juicer-ut "[main_test#9]"
+RUN ./juicer-ut "[main_test#10]"
+RUN ./juicer-ut "[main_test#11]"
+RUN ./juicer-ut "[main_test#12]"
+RUN ./juicer-ut "[main_test#13]"
+RUN ./juicer-ut "[main_test#14]"
+RUN ./juicer-ut "[main_test#15]"
+RUN ./juicer-ut "[main_test#16]"
+RUN ./juicer-ut "[main_test#17]"
+RUN ./juicer-ut "[main_test#18]"
+RUN ./juicer-ut "[main_test#19]"
+RUN ./juicer-ut "[main_test#20]"
+RUN ./juicer-ut "[Module]"
+RUN ./juicer-ut "[Symbol]"
+
+RUN cd /home/docker/juicer && make coverage
+#Useful for CI
+RUN cd /home/docker/juicer && gcovr --filter /home/docker/juicer/src/ --object-directory /home/docker/juicer/build/ut_obj/ --xml coverage.gcov
+
+
+
diff --git a/Dockerfile.ubuntu22.dev b/Dockerfile.ubuntu22.dev
new file mode 100644
index 00000000..79f5f591
--- /dev/null
+++ b/Dockerfile.ubuntu22.dev
@@ -0,0 +1,21 @@
+FROM ubuntu:22.04
+RUN apt update
+ARG DEBIAN_FRONTEND=noninteractive
+ENV TERM xterm-256color
+RUN apt-get update && \
+ apt-get -y install sudo
+
+RUN apt-get install -y gcc-multilib
+RUN apt-get install -y g++-multilib
+RUN apt-get install -y libdwarf-dev
+RUN apt-get install -y make
+RUN apt-get install -y libelf-dev
+RUN apt-get install -y libsqlite3-dev
+RUN apt-get install -y libssl-dev
+RUN apt-get install -y doxygen
+RUN apt-get install -y gdb
+RUN apt-get install -y gcovr
+
+RUN mkdir /home/docker
+RUN mkdir /home/docker/juicer
+WORKDIR /home/docker/juicer
diff --git a/Images/bit_packed_struct.png b/Images/bit_packed_struct.png
new file mode 100644
index 00000000..abe8e1a2
Binary files /dev/null and b/Images/bit_packed_struct.png differ
diff --git a/Images/fields_table.png b/Images/fields_table.png
index 1c5b693c..2475b83e 100644
Binary files a/Images/fields_table.png and b/Images/fields_table.png differ
diff --git a/Images/symbols_table.png b/Images/symbols_table.png
index fd679908..6f038c88 100644
Binary files a/Images/symbols_table.png and b/Images/symbols_table.png differ
diff --git a/Makefile b/Makefile
index 81d1d406..f9213f60 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@ CATCH2_DIR := $(ROOT_DIR)/Catch2
# Unit test directories
UT_SRC_DIR := $(ROOT_DIR)/unit-test
UT_OBJ_DIR := $(BUILD_DIR)/ut_obj
+UT_OBJ_32BIT_DIR := $(BUILD_DIR)/ut_obj_32
UT_BIN_DIR := $(BUILD_DIR)
UT_INCLUDES := -I$(CATCH2_DIR)/single_include/catch2
@@ -25,28 +26,38 @@ SRC := $(wildcard $(SRC_DIR)/*.cpp)
OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
# Unit test files
-UT_EXE := $(UT_BIN_DIR)/juicer-ut
-UT_SRC := $(wildcard $(UT_SRC_DIR)/*.cpp) $(filter-out $(SRC_DIR)/main.cpp, $(SRC))
-UT_OBJ := $(UT_SRC:$(UT_SRC_DIR)/%.cpp=$(UT_OBJ_DIR)/%.o)
-UT_OBJ := $(UT_OBJ:$(SRC_DIR)/%.cpp=$(UT_OBJ_DIR)/%.o)
+UT_EXE := $(UT_BIN_DIR)/juicer-ut
+
+UT_EXE_32BIT := $(UT_BIN_DIR)/juicer-ut-32
+UT_SRC := $(wildcard $(UT_SRC_DIR)/*.cpp) $(filter-out $(SRC_DIR)/main.cpp, $(SRC))
+UT_OBJ := $(UT_SRC:$(UT_SRC_DIR)/%.cpp=$(UT_OBJ_DIR)/%.o)
+UT_OBJ := $(UT_OBJ:$(SRC_DIR)/%.cpp=$(UT_OBJ_DIR)/%.o)
+
+
+UT_SRC_32 := $(wildcard $(UT_SRC_DIR)/test_file*.cpp)
+UT_OBJ_32 := $(UT_SRC_32:$(UT_SRC_DIR)/test_file%.cpp=$(UT_OBJ_32BIT_DIR)/test_file%.o)
+UT_OBJ_32 := $(UT_OBJ_32:$(UT_SRC_DIR)/test_file%.cpp=$(UT_OBJ_32BIT_DIR)/test_file%.o)
+
# Set target flags
-CPPFLAGS := -MMD -MP -std=c++14 -fmessage-length=0 $(INCLUDES)
-CFLAGS := -Wall -g
-LDFLAGS := -Llib
-LDLIBS := -lm -ldwarf -lsqlite3 -lelf -lcrypto
+CPPFLAGS := -MMD -MP -std=c++14 -fmessage-length=0 $(INCLUDES)
+CFLAGS := -Wall -g3
+CFLAGS_32BIT := -Wall -g3 -m32
+LDFLAGS := -Llib
+LDLIBS := -lm -ldwarf -lsqlite3 -lelf -lcrypto
# Set unit test flags
-UT_CPPFLAGS := $(CPPFLAGS) $(UT_INCLUDES)
-UT_CFLAGS := $(CFLAGS) --coverage
-UT_LDFLAGS := $(LDFLAGS)
-UT_LDLIBS := $(LDLIBS) -lgcov
+UT_CPPFLAGS := $(CPPFLAGS) $(UT_INCLUDES)
+UT_CFLAGS := $(CFLAGS) --coverage
+UT_CFLAGS_32BIT := $(CFLAGS_32BIT) --coverage
+UT_LDFLAGS := $(LDFLAGS)
+UT_LDLIBS := $(LDLIBS) -lgcov
# Set tools
CC := g++
LD := g++
-.PHONY: all clean run-tests coverage
+.PHONY: all clean run-tests coverage docs
# Target recipes
$(EXE): $(OBJ)
@@ -62,17 +73,38 @@ $(OBJ_DIR):
$(UT_EXE): $(UT_OBJ)
$(LD) $(UT_LDFLAGS) $^ $(UT_LDLIBS) -o $@
+
+
+$(UT_EXE_32BIT): $(UT_OBJ_32)
+
+
$(UT_OBJ_DIR)/%.o: $(UT_SRC_DIR)/%.cpp | $(UT_OBJ_DIR)
$(CC) $(UT_CPPFLAGS) $(UT_CFLAGS) -c $< -o $@
+
+$(UT_OBJ_DIR)/%.o: $(UT_SRC_DIR)/%.cpp | $(UT_OBJ_DIR)
+ $(CC) $(UT_CPPFLAGS) $(UT_CFLAGS) -c $< -o $@
+
+
+
$(UT_OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(UT_OBJ_DIR)
$(CC) $(UT_CPPFLAGS) $(UT_CFLAGS) -c $< -o $@
-$(UT_OBJ_DIR):
+$(UT_OBJ_32BIT_DIR)/test_file%.o: $(UT_SRC_DIR)/test_file%.cpp | $(UT_OBJ_32BIT_DIR)
+ $(CC) $(UT_CPPFLAGS) $(UT_CFLAGS_32BIT) -c $< -o $@
+
+
+$(UT_OBJ_DIR):
mkdir -p $@
-run-tests: | $(UT_EXE)
+
+$(UT_OBJ_32BIT_DIR):
+ mkdir -p $@
+
+
+run-tests: $(UT_EXE_32BIT) | $(UT_EXE)
-(cd $(BUILD_DIR); $(UT_EXE))
+
build-tests: | $(UT_EXE)
@@ -82,7 +114,8 @@ $(COVERAGE_DIR)/index.html: | run-tests
mkdir -p $(COVERAGE_DIR)
(cd $(COVERAGE_DIR); gcovr $(ROOT_DIR) --root $(ROOT_DIR) --object-directory $(UT_OBJ_DIR) --filter $(ROOT_DIR)/src/ --html --html-details -o index.html)
-all: $(EXE) $(UT_EXE)
+
+all: $(EXE) $(UT_EXE) $(UT_EXE_32BIT)
clean:
@$(RM) -Rf $(BUILD_DIR)
@@ -91,9 +124,29 @@ clean:
-include $(OBJ:.o=.d)
-docker-build:
- @sudo docker build --no-cache -t juicer:latest -f Dockerfile .
+docker-ubuntu18-build:
+ @sudo docker build --no-cache -t juicer:ubuntu18 -f Dockerfile.ubuntu18 .
+
+
+docker-ubuntu22-build:
+ @sudo docker build --no-cache -t juicer:ubuntu22 -f Dockerfile.ubuntu22 .
+
+docker-ubuntu20-build:
+ @sudo docker build --no-cache -t juicer:ubuntu20 -f Dockerfile.ubuntu20 .
+
+
+docker-ubuntu22-build-dev:
+ @sudo docker build --no-cache -t juicer-dev:ubuntu22 -f Dockerfile.ubuntu22.dev .
+ @sudo docker run -v .:/home/docker/juicer -it juicer-dev:ubuntu22 bash
+
+
+docker-ubuntu20-build-dev:
+ @sudo docker build --no-cache -t juicer-dev:ubuntu20 -f Dockerfile.ubuntu20.dev .
+ @sudo docker run -v .:/home/docker/juicer -it juicer-dev:ubuntu20 bash
+docker-ubuntu18-build-dev:
+ @sudo docker build --no-cache -t juicer-dev:ubuntu18 -f Dockerfile.ubuntu18 .
+ @sudo docker run -v .:/home/docker/juicer -it juicer-dev:ubuntu18 bash
check-format:
@python3 clang_format_all.py --config clang_format_all_config.yaml
diff --git a/README.md b/README.md
index 5fc59bdf..c4760666 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
[![Run juicer tests](https://github.com/WindhoverLabs/juicer/actions/workflows/ci.yaml/badge.svg)](https://github.com/WindhoverLabs/juicer/actions/workflows/ci.yaml)
+[![Coverage Status](https://coveralls.io/repos/github/WindhoverLabs/juicer/badge.svg?branch=unit_test_updates)](https://coveralls.io/github/WindhoverLabs/juicer?branch=unit_test_updates)
# Table of Contents
1. [Dependencies](#dependencies)
@@ -10,7 +11,12 @@
6. [Environment Setup](#environment-setup)
7. [Testing](#testing)
8. [DWARF Support](#dwarf_support)
-9. [vxWorks Support](#vxWorks)
+9. [Notes on Macros](#notes_on_macros)
+10. [Extra Elf Features](#extra_elf_features)
+11. [vxWorks Support](#vxWorks)
+12. [Notes On Multiple DWARF Versions](#multiple_dwarf_versions)
+13. [Bitfields](#Bitfields)
+14. [Docker Dev Environments](#docker_dev_env)
## Dependencies
* `libdwarf-dev`
@@ -60,13 +66,15 @@ make run-tests
## What is it?
-juicer extracts structs, arrays, enumerations and intrinsic types(support for everything else is planned for the future, but it is not a priority at the moment) from executable elf files and stores them in a SQLite database.
+juicer extracts structs, arrays, enumerations, macros and intrinsic types(support for everything else is planned for the future, but it is not a priority at the moment) from executable elf files and stores them in a SQLite database.
### An Example
Imagine we wrote some elf_file.cpp that looks like this.
```
#include "stdint.h"
+#define ARRAY_1D_SIZE 2
+
typedef struct
{
int32_t width = 101;
@@ -76,8 +84,8 @@ typedef struct
uint16_t more_stuff;
uint16_t padding2;
float floating_stuff;
- float matrix3D[2][4][4];
- float matrix1D[2];
+ float matrix3D[ARRAY_1D_SIZE][4][4];
+ float matrix1D[ARRAY_1D_SIZE];
}Square;
Square sq = {};
@@ -89,6 +97,15 @@ Square sq = {};
g++ -std=c++14 elf_file.cpp -g -c -o elf_file
```
+To include macros in the output, make sure to pass "-g3" when compiling:
+
+
+```
+g++ -std=c++14 elf_file.cpp -g -g3 -c -o elf_file
+```
+NOTE:Please beware that compiler switchess may have different names for different compilers.
+Here we use gcc as an example since it is a compiler that is accessible to most teams.
+
Assuming you've built juicer successfully, you can give this binary file to juicer:
```
@@ -100,20 +117,18 @@ This tells juicer to squeeze and extract as much as possible out of the binary a
After juicer is done, you will find a database populated with data about our binary file at `build/new_db.sqlite`. The database should have the following schemas:
+"*" = PRIMARY KEY
+"+" = FOREIGN KEY
+
### elfs
-| id* | name | checksum | date | little_endian |
-| --- | --- | --- | --- | --- |
-|INTEGER | TEXT | INTEGER | DATETIME | BOOLEAN |
+| id* | name | md5 | date | little_endian | short_description | long_description |
+| --- | --- |---------| --- | --- | -- | -- |
+|INTEGER | TEXT | INTEGER | DATETIME | BOOLEAN | TEXT | TEXT |
### enumerations
-| symbol* | value* | name |
-| --- | --- | --- |
-| INTEGER | INTEGER | TEXT |
-
-### bit_fields
-|field* | bit_size | bit_offset |
-|---|---|---|
-| INTEGER | INTEGER | INTEGER |
+| symbol* | value* | name | short_description | long_description |
+| --- | --- | --- | -- | -- |
+| INTEGER | INTEGER | TEXT | TEXT | TEXT |
### fields
| id* | name | symbol+ | byte_offset | type+ | little_endian | bit_size | bit_offset |
@@ -126,9 +141,9 @@ After juicer is done, you will find a database populated with data about our bin
| INTEGER | INTEGER | TEXT | INTEGER
### symbols
-| id* | elf+ | name | byte_size |
-| ---| --- | --- | --- |
-| INTEGER | INTEGER | TEXT | INTEGER |
+| id* | elf+ | name | byte_size | artifact* | target_symbol* | encoding* | short_description | long_descriptions |
+| ---| --- | --- | --- |-----------|----------------|-----------|------|------|
+| INTEGER | INTEGER | TEXT | INTEGER | INTEGER | INTEGER | INTEGER | TEXT | TEXT |
In our specific example, the **symbols** and **fields** tables are the ones we are interested in.
@@ -161,13 +176,13 @@ This is how juicer stores data in the database.
# GCC Compatibility
Since`juicer` is reading ELF files, the compiler one uses or the specific linux version *can* affect the behavior of the libelf libraries.
-Because of this we have tested `juicer`on the specified platforms in the table below.
+Because of this we have tested `juicer` (and continuously test in CI)on the specified platforms in the table below.
-| Ubuntu Version| GCC Version(s) |
-|---|---|
-| `Ubuntu 16.04.7 LTS` | `gcc 5.4.0`, ` gcc 6.5.0 ` |
-| `Ubuntu 18.04.5 LTS` | ` gcc 7.5.0`, `gcc 8.4.0` |
-| `Ubuntu 20.04.1 LTS` | `gcc 7.5.0`, `gcc 8.4.0`, `gcc 9.3.0` |
+| Ubuntu Version | GCC Version(s) | DWARF Version |
+|---|---| ---|
+| `Ubuntu 18.04.1 LTS` | `7.5.0` | 4 |
+| `Ubuntu 20.04.1 LTS` | `9.4.0` | 4 |
+| `Ubuntu 22.04.5 LTS` | `11.4.0` | 5 |
# Padding
@@ -290,26 +305,29 @@ make coverage
This will run all unit tests on juicer and generate a test coverage report for you. After `make` is done, the test coverage report can be found on `build/coverage/index.html`.
## Dwarf Support
-At the moment `juicer` follows the DWARF4 specification, which is the standard in all versions of gcc at the moment. If this changes, then this document will be updated accordingly.
+At the moment `juicer` follows the DWARF4 and DWARF5 specifications. If this changes, then this document will be updated accordingly.
As juicer evolves, dwarf support will grow and evolve as well. At the moment, we don't adhere to a particular DWARF version as we add support to the things that we need for our code base, which is airliner. In other words, we *mostly* support `C` code, or `C++` code without any cutting edge/modern features. For example, modern features such as `templates` or `namespaces` are not supported. If juicer finds these things in your elf files, it will simply ignore them. To have a more concrete idea of what we *do* support in the DWARF, take a look at the table below which records all DWARF tags we support.
### Dwarf Tags
-| Name | Description |
-| ---| --- |
-| DW_TAG_base_type | This is the tag that represents intrinsic types such as `int` and `char`. |
-| DW_TAG_typedef | This is the tag that represents anything that is typdef'd in code such as `typedef struct{...}`. At the moment, types such as `typedef int16 my_int` do *not* work. We will investigate this issue in the future, however, it is not a priority at the moment.|
+| Name | Description |
+|-----------------------| --- |
+| DW_TAG_base_type | This is the tag that represents intrinsic types such as `int` and `char`. |
+| DW_TAG_typedef | This is the tag that represents anything that is typdef'd in code such as `typedef struct{...}` `typedef int16 my_int`. This is what the "target_symbol" column is for in the symbols table. |
| DW_TAG_structure_type | This is the tag that represents structs such as `struct Square{ int width; int length; };` |
-| DW_TAG_array_type | This is the tag that represents *statically* allocated arrays such as `int flat_array[] = {1,2,3,4,5,6};`. Noe that this does not include dynamic arrays such as those allocated by malloc or new calls.|
-| DW_TAG_pointer_type | This is the tag that represents pointers in code such as `int* ptr = nullptr`|
+| DW_TAG_array_type | This is the tag that represents *statically* allocated arrays such as `int flat_array[] = {1,2,3,4,5,6};`. Note that this does not include dynamic arrays such as those allocated by malloc or new calls.|
+| DW_TAG_pointer_type | This is the tag that represents pointers in code such as `int* ptr = nullptr`|
| DW_TAG_enumeration_type | This is the tag that represents enumerations such as `enum Color{RED,BLUE,YELLOW};` |
-| DW_TAG_const_type | This is the tag that represents C/C++ const qualified type such as `sizetype`, which is used by containers(like std::vector) in the STL C++ library. |
+| DW_TAG_const_type | This is the tag that represents C/C++ const qualified type such as `sizetype`, which is used by containers(like std::vector) in the STL C++ library. |
+| DW_MACRO_define | This tag represents define macros such as "#define CFE_MISSION_ES_PERF_MAX_IDS 128"|
+| DW_AT_decl_file | This tag represents the file where a certain symbol is declared. Very useful for traceability of source code.|
+| DW_AT_encoding | The encoding of base type. For example; "unsigned int" will have encoding "DW_ATE_unsigned". This is what the "encodings" table is for in the SQLITE db.|
For more details on the DWARF debugging format, go on [here](http://www.dwarfstd.org/doc/DWARF4.pdf).
### `void*`
-DWARF version 4 has this to say about void pointers:
+DWARF version 4 and 5 has this to say about void pointers:
> The interpretation of this debugging information entry is intentionally left flexible to allow it to
be interpreted appropriately in different languages. For example, in C and C++ the language
@@ -321,6 +339,50 @@ referenced by the type attribute of pointer types and typedef declarations for '
juicer behaves accordingly. If a pointer does not have a type(meaning it does not have a DW_AT_type attribute), then it is assumed that the pointer in question is of the `void*` type.
+## Notes On #define Macros
+During testing we found that some pattern causes the macro being defined to "disappear" from the DWARF section:
+
+When this happens, it is most likely a case of the macro being on a seperate group number inside of the DWARF.
+
+To ensure juicer queries all macros, users can pass the "group number" via the "-g" flag.
+
+For example the command:
+```
+./juicer -g 5 --input elf_file --mode SQLITE --output build/new_db.sqlite -v4
+```
+
+tells juicer to get macros from group "5". The default is group "0", which is enough for most cases.
+
+This seems to happen on unlinked compiled ELF files that have the following define pattern where there is an #include between #define(s):
+```C
+#define MAC1 2
+#define MAC2 3
+#include "macro_test.h"
+#define MAC3 4
+```
+
+This is rare(especially unlinked files), but it does happen. In any case "-g" flag can be used to query macros (or any other DWARF data)
+from as many groups(starting at 0) as the the ELF file has.
+
+For more details on this issue and other macro issues:https://github.com/WindhoverLabs/juicer/issues/35
+
+
+## Extra ELF Features
+
+jucier's main focus is to extract DWARF, however, it can extract ELF sections too. To extract elf sections pass the extras "-x" flag:
+
+```
+./juicer -x --input elf_file --mode SQLITE --output build/new_db.sqlite -v4
+```
+
+This can be useful for extracting data from object files such as static variables that are assigned at build time and whose
+contents are stored in the elf symbols table. For an example of this see the "query_symbols.py" script under this repo.
+
+To learn more about the different ELF sections and how they're structured, there is a copy of the ELF standard under the docs directory on the repo.
+
+
+
+
## VxWorks Support
At the moment vxWorks support is a work in progress. Support is currently *not* tested, so at the moment it is on its own [branch]
(https://github.com/WindhoverLabs/juicer/tree/vxWorks).
@@ -331,6 +393,45 @@ At the moment vxWorks support is a work in progress. Support is currently *not*
```
catchsegv ./juicer-ut "[main_test#3]"
addr2line -e ./juicer-ut 0x19646c
+
+```
+
+
+## Notes On Multiple DWARF Versions
+- At the time of writing, juicer has been tested on DWARF4 and DWARF5.
+- Do *not* use DWARF experimental support from your compiler. Use the *default* DWARF version, whether that is 5 or 4. When using a
+DWARF version that still is experimental for your compiler, it is not guaranteed juicer will parse the binary correctly.
+
+
+# Bitfields
+
+For a bit-packed struct
+```
+struct S
+{
+ uint8_t before;
+ int j : 5;
+ int k : 6;
+ int m : 5;
+ uint8_t p;
+ int n : 8;
+ uint8_t after;
+};
```
-Documentation updated on September 29, 2021
\ No newline at end of file
+The fields table looks like this:
+
+![bit_packed_fields](Images/bit_packed_struct.png "symbols-table")
+
+Notice for the bitpacked fields(j,k,m,n) the bit_offset and bit_size columns are nonzero.
+
+
+# Docker Dev Environment
+
+It is often useful to use a virtualized environment for development. There are several recipes on this repo that make this easier.
+For example `make docker-ubuntu22-build-dev` will start a dev environment inside of Docker with Ubuntu22.
+The repo is mounted as a volume under "/home/docker/juicer" so developers can make their changes on the host and build inside the container.
+
+
+
+Documentation updated on September 19, 2024
\ No newline at end of file
diff --git a/clang_format_all.py b/clang_format_all.py
index 2b043d01..768af692 100644
--- a/clang_format_all.py
+++ b/clang_format_all.py
@@ -22,7 +22,7 @@ def parse_args():
return args
-def check_all_walk_recursive(root_dir: str, exclude_files=None, file_extensions=None):
+def check_all_walk_recursive(clang_format_command: str, root_dir: str, exclude_files=None, file_extensions=None):
if exclude_files is None:
exclude_files = set()
if file_extensions is None:
@@ -31,13 +31,13 @@ def check_all_walk_recursive(root_dir: str, exclude_files=None, file_extensions=
for root, dirs, files in os.walk(root_dir):
if dirs:
for d in dirs:
- check_all_walk_recursive((os.path.join(root, d)), exclude_files, file_extensions)
+ check_all_walk_recursive(clang_format_command, (os.path.join(root, d)), exclude_files, file_extensions)
for file in files:
path = Path(os.path.join(root, file))
if str(path) in exclude_files:
continue
if path.suffix in file_extensions:
- if subprocess.run(["clang-format-18", "--dry-run", "--Werror", "-style=file",
+ if subprocess.run([clang_format_command, "--dry-run", "--Werror", "-style=file",
path]).returncode != 0:
logger.info("\"%s\": does not comply to format according to clang-format", path)
exit(-1)
@@ -45,7 +45,7 @@ def check_all_walk_recursive(root_dir: str, exclude_files=None, file_extensions=
logger.info("\"%s\": looks fine according to clang-format", path)
-def format_all_walk_recursive(root_dir: str, exclude_files=None, file_extensions=None):
+def format_all_walk_recursive(clang_format_command: str, root_dir: str, exclude_files=None, file_extensions=None):
if exclude_files is None:
exclude_files = set()
if file_extensions is None:
@@ -53,13 +53,13 @@ def format_all_walk_recursive(root_dir: str, exclude_files=None, file_extensions
for root, dirs, files in os.walk(root_dir):
if dirs:
for d in dirs:
- format_all_walk_recursive((os.path.join(root, d)), file_extensions)
+ format_all_walk_recursive(clang_format_command, (os.path.join(root, d)), file_extensions)
for file in files:
path = Path(os.path.join(root, file))
if str(path) in exclude_files:
continue
if path.suffix in file_extensions:
- if subprocess.run(["clang-format-18", "-style=file", "-i",
+ if subprocess.run([clang_format_command, "-style=file", "-i",
path], capture_output=True).returncode != 0:
logger.info("\"%s\": An error occurred while parsing this file.", path)
exit(-1)
@@ -107,8 +107,8 @@ def main():
excluded_dirs = get_resolved_paths(config['exclude_dirs'], config["root_dir"])
if config['check_all'] is True:
- check_all_walk_recursive(str(Path(config["root_dir"]).resolve()), excluded_dirs, config['file_extensions'])
+ check_all_walk_recursive(config["clang_format_command"], str(Path(config["root_dir"]).resolve()), excluded_dirs, config['file_extensions'])
else:
- format_all_walk_recursive(str(Path(config["root_dir"]).resolve()), excluded_dirs, config['file_extensions'])
+ format_all_walk_recursive(config["clang_format_command"], str(Path(config["root_dir"]).resolve()), excluded_dirs, config['file_extensions'])
main()
\ No newline at end of file
diff --git a/clang_format_all_config.yaml b/clang_format_all_config.yaml
index ce9e6445..8d0a0157 100644
--- a/clang_format_all_config.yaml
+++ b/clang_format_all_config.yaml
@@ -1,4 +1,5 @@
-root_dir: "src"
+clang_format_command: "clang-format"
+root_dir: "."
#When true, files will only be checked. None will be modified.
check_all: true
@@ -21,4 +22,5 @@ exclude_dirs:
- "lc"
- "prmlib"
- "cfs_lib"
- - "vm"
\ No newline at end of file
+ - "vm"
+ - "Catch2"
\ No newline at end of file
diff --git a/clang_format_all_config_format.yaml b/clang_format_all_config_format.yaml
index 4c1c68b5..ab78a0be 100644
--- a/clang_format_all_config_format.yaml
+++ b/clang_format_all_config_format.yaml
@@ -1,4 +1,5 @@
-root_dir: "src"
+root_dir: "."
+clang_format_command: "clang-format"
#When true, files will only be checked. None will be modified.
check_all: false
@@ -21,4 +22,5 @@ exclude_dirs:
- "lc"
- "prmlib"
- "cfs_lib"
- - "vm"
\ No newline at end of file
+ - "vm"
+ - "Catch2"
\ No newline at end of file
diff --git a/docs/DWARF4.pdf b/docs/DWARF4.pdf
new file mode 100644
index 00000000..79457c34
Binary files /dev/null and b/docs/DWARF4.pdf differ
diff --git a/juicer.files b/juicer.files
index f6bb36be..98d2054c 100644
--- a/juicer.files
+++ b/juicer.files
@@ -291,6 +291,8 @@ src/ElfFile.cpp
src/ElfFile.h
src/ElfSection.cpp
src/ElfSection.h
+src/Encoding.cpp
+src/Encoding.h
src/Enumeration.cpp
src/Enumeration.h
src/Field.cpp
diff --git a/src/Artifact.cpp b/src/Artifact.cpp
index 711c75ed..a75c62b6 100644
--- a/src/Artifact.cpp
+++ b/src/Artifact.cpp
@@ -25,7 +25,6 @@ void Artifact::setId(uint32_t newID) { id = newID; }
uint32_t Artifact::getId() { return id; }
std::string Artifact::getFilePath() const { return filePath; }
-ElfFile& Artifact::getElf() { return elf; }
void Artifact::setMD5(std::string newCRC) { md5 = newCRC; }
std::string Artifact::getMD5() const { return md5; }
diff --git a/src/Artifact.h b/src/Artifact.h
index cc1ebf4f..ae4daaed 100644
--- a/src/Artifact.h
+++ b/src/Artifact.h
@@ -8,6 +8,7 @@
#ifndef SRC_ARTIFACT_H_
#define SRC_ARTIFACT_H_
+#include
#include
class ElfFile;
@@ -33,7 +34,6 @@ class Artifact
std::string getMD5() const;
std::string getFilePath() const;
- ElfFile &getElf();
~Artifact();
};
diff --git a/src/DefineMacro.cpp b/src/DefineMacro.cpp
index 4aa51e57..6b55afa4 100644
--- a/src/DefineMacro.cpp
+++ b/src/DefineMacro.cpp
@@ -14,12 +14,8 @@ DefineMacro::DefineMacro(std::string inName, std::string inValue) : name{inName}
const std::string& DefineMacro::getName() const { return name; }
-void DefineMacro::setName(const std::string& name) { this->name = name; }
-
const std::string& DefineMacro::getValue() const { return value; }
-void DefineMacro::setValue(const std::string& value) { this->value = value; }
-
DefineMacro::~DefineMacro()
{
// TODO Auto-generated destructor stub
diff --git a/src/DefineMacro.h b/src/DefineMacro.h
index 0378a4f5..9b63a5cb 100644
--- a/src/DefineMacro.h
+++ b/src/DefineMacro.h
@@ -17,12 +17,8 @@ class DefineMacro
const std::string& getName() const;
- void setName(const std::string& name);
-
const std::string& getValue() const;
- void setValue(const std::string& value);
-
virtual ~DefineMacro();
private:
diff --git a/src/DimensionList.cpp b/src/DimensionList.cpp
index 08844c2d..d4f4e71c 100644
--- a/src/DimensionList.cpp
+++ b/src/DimensionList.cpp
@@ -63,11 +63,6 @@ std::string DimensionList::toString()
return dimListStr;
}
-
-uint32_t DimensionList::getId() const { return id; }
-
-void DimensionList::setId(uint32_t id) { this->id = id; }
-
void DimensionList::addDimension(uint32_t upperBound) { dimensions.push_back(Dimension{upperBound}); }
const std::vector& DimensionList::getDimensions() const { return dimensions; }
diff --git a/src/DimensionList.h b/src/DimensionList.h
index 0a1cfec2..c9a6691d 100644
--- a/src/DimensionList.h
+++ b/src/DimensionList.h
@@ -90,12 +90,9 @@ class DimensionList
std::string toString();
void addDimension(uint32_t inUpperBound);
- uint32_t getId() const;
- void setId(uint32_t id);
const std::vector& getDimensions() const;
private:
- uint32_t id{};
std::vector dimensions{};
};
diff --git a/src/Elf64Symbol.cpp b/src/Elf64Symbol.cpp
new file mode 100644
index 00000000..a707d6fe
--- /dev/null
+++ b/src/Elf64Symbol.cpp
@@ -0,0 +1,12 @@
+#include "Elf64Symbol.h"
+
+Elf64Symbol::Elf64Symbol(Elf64_Sym newSymbol, uint32_t newFileOffset, uint32_t newStrTableFileOffset)
+ : symbol{newSymbol}, fileOffset{newFileOffset}, strTableFileOffset{newStrTableFileOffset}
+{
+}
+
+Elf64_Sym Elf64Symbol::getSymbol() const { return symbol; }
+
+uint32_t Elf64Symbol::getFileOffset() const { return fileOffset; }
+
+uint32_t Elf64Symbol::getStrTableFileOffset() const { return strTableFileOffset; }
diff --git a/src/Elf64Symbol.h b/src/Elf64Symbol.h
new file mode 100644
index 00000000..ae9cc9d3
--- /dev/null
+++ b/src/Elf64Symbol.h
@@ -0,0 +1,26 @@
+#ifndef ELF64SYMBOL_H
+#define ELF64SYMBOL_H
+
+#include
+
+/**
+ * @brief The Elf32Symbol class
+ * Extension of Elf32_Sym struct. Makes it easier to map symbol sections
+ * to file offsets.
+ */
+
+class Elf64Symbol
+{
+ private:
+ Elf64_Sym symbol;
+ uint32_t fileOffset;
+ uint32_t strTableFileOffset;
+
+ public:
+ Elf64_Sym getSymbol() const;
+ uint32_t getStrTableFileOffset() const;
+ uint32_t getFileOffset() const;
+ Elf64Symbol(Elf64_Sym newSymbol, uint32_t newFileOffset, uint32_t newStrTableFileOffset);
+};
+
+#endif // ELF32SYMBOL_H
diff --git a/src/ElfFile.cpp b/src/ElfFile.cpp
index 3e7a7cfa..c78c42cd 100644
--- a/src/ElfFile.cpp
+++ b/src/ElfFile.cpp
@@ -26,37 +26,15 @@ ElfFile::ElfFile(std::string& inName)
logger.logDebug("Elf '%s' created.", getName().c_str());
}
-ElfFile::ElfFile() : name{""}, id{0} { logger.logError("Cannot call Module default constructor."); }
-
-ElfFile::ElfFile(const ElfFile& elf)
- : name{elf.name}, // @suppress("Symbol is not resolved")
- id{0}
-{
- logger.logError("Cannot call Module copy constructor.");
-}
-
ElfFile::~ElfFile() {}
std::string ElfFile::getName() const { return name; }
-/**
- *@brief
- *
- *@note Absolute paths are enforced.
- */
-void ElfFile::setName(std::string& inName)
-{
- logger.logDebug("Module %s renamed to %s.", name.c_str(), inName.c_str());
+uint32_t ElfFile::getId(void) const { return id; }
- this->name = inName;
- normalizePath(name);
-}
+void ElfFile::setId(uint32_t newId) { id = newId; }
-uint32_t ElfFile::getId(void) const { return id; }
-
-void ElfFile::setId(uint32_t newId) { id = newId; }
-
-void ElfFile::isLittleEndian(bool inLittleEndian)
+void ElfFile::isLittleEndian(bool inLittleEndian)
{
logger.logDebug("ELF %s endian changed from %s to %s.", name.c_str(), little_endian ? "LE" : "BE", inLittleEndian ? "LE" : "BE");
@@ -107,32 +85,21 @@ Symbol* ElfFile::getSymbol(std::string& name)
return returnSymbol;
}
-bool ElfFile::isSymbolUnique(std::string& name)
+Symbol* ElfFile::addSymbol(std::string& inName, uint32_t inByteSize, Artifact newArtifact, Symbol* targetSymbol)
{
- bool rc = false;
- Symbol* symbol = getSymbol(name);
+ Symbol* symbol = getSymbol(inName);
if (symbol == nullptr)
{
- rc = true;
- }
- else
- {
- rc = false;
-
- logger.logDebug("isSymbolUnique is false.");
- }
-
- return rc;
-}
+ std::unique_ptr newSymbol = std::make_unique(*this, inName, inByteSize, newArtifact);
+ newSymbol->setTargetSymbol(targetSymbol);
-Symbol* ElfFile::addSymbol(std::unique_ptr inSymbol)
-{
- logger.logDebug("Adding Symbol %s to Module %s.", inSymbol->getName().c_str(), name.c_str());
+ symbols.push_back(std::move(newSymbol));
- symbols.push_back(std::move(inSymbol));
+ symbol = symbols.back().get();
+ }
- return symbols.back().get();
+ return symbol;
}
Symbol* ElfFile::addSymbol(std::string& inName, uint32_t inByteSize, Artifact newArtifact)
@@ -209,9 +176,8 @@ void ElfFile::normalizePath(std::string& path)
path.insert(0, resolvedPath);
}
-void ElfFile::addDefineMacro(std::string name, std::string value) { defineMacros.push_back(DefineMacro{name, value}); }
-void ElfFile::addDefineMacro(DefineMacro newMacro) { defineMacros.push_back(newMacro); }
-const std::vector& ElfFile::getDefineMacros() const { return defineMacros; }
+void ElfFile::addDefineMacro(DefineMacro newMacro) { defineMacros.push_back(newMacro); }
+const std::vector& ElfFile::getDefineMacros() const { return defineMacros; }
const std::map>& ElfFile::getInitializedSymbolData() const { return initializedSymbolData; }
void ElfFile::setInitializedSymbolData(const std::map>& initializedSymbolData)
@@ -224,8 +190,52 @@ void ElfFile::addVariable(Variable newVariable) { variab
const std::vector& ElfFile::getVariables() const { return variables; }
void ElfFile::addElf32SectionHeader(Elf32_Shdr newSectionHeader) { elf32Headers.push_back(newSectionHeader); }
+void ElfFile::addElf64SectionHeader(Elf64_Shdr newSectionHeader) { elf64Headers.push_back(newSectionHeader); }
std::vector ElfFile::getElf32Headers() const { return elf32Headers; }
+std::vector ElfFile::getElf64Headers() const { return elf64Headers; }
void ElfFile::addElf32SymbolTableSymbol(Elf32Symbol newSymbol) { elf32SymbolTable.push_back(newSymbol); }
std::vector ElfFile::getElf32SymbolTable() const { return elf32SymbolTable; }
+
+void ElfFile::addElf64SymbolTableSymbol(Elf64Symbol newSymbol) { elf64SymbolTable.push_back(newSymbol); }
+std::vector ElfFile::getElf64SymbolTable() const { return elf64SymbolTable; }
+
+/**
+ * @brief ElfFile::getEncodings
+ * @return a list of encodings as per DWARF5 specification document section 5.1.1 titled "Base Type Encodings"
+ */
+std::vector ElfFile::getDWARFEncodings()
+{
+ std::vector encodings{};
+
+ for (std::pair e : encodingsMap)
+ {
+ encodings.push_back(e.second);
+ }
+ return encodings;
+}
+
+/**
+ * @brief ElfFile::getDWARFEncoding
+ * @param encoding
+ * @todo add error-checking since we know the valid values
+ * @return
+ */
+Encoding& ElfFile::getDWARFEncoding(int encoding) { return encodingsMap.at(encoding); }
+
+void ElfFile::setElfClass(int newelfClass)
+{
+ switch (newelfClass)
+ {
+ case ELFCLASS32:
+ case ELFCLASS64:
+ elfClass = newelfClass;
+ break;
+ default:
+ elfClass = newelfClass;
+ logger.logWarning("Invalid elf class set:%d", elfClass);
+ }
+}
+
+int ElfFile::getElfClass() { return elfClass; }
diff --git a/src/ElfFile.h b/src/ElfFile.h
index 82990b7f..c6e236ac 100644
--- a/src/ElfFile.h
+++ b/src/ElfFile.h
@@ -16,10 +16,13 @@
#include "DefineMacro.h"
#include "Elf32Symbol.h"
+#include "Elf64Symbol.h"
+#include "Encoding.h"
#include "Field.h"
#include "Juicer.h"
#include "Logger.h"
#include "Variable.h"
+#include "dwarf.h"
class Symbol;
class Field;
@@ -41,21 +44,17 @@ class Variable;
class ElfFile
{
public:
- ElfFile();
ElfFile(std::string &name);
- ElfFile(const ElfFile &elf);
virtual ~ElfFile();
std::vector> &getSymbols();
std::string getName() const;
- void setName(std::string &name);
uint32_t getId(void) const;
void setId(uint32_t newId);
- Symbol *addSymbol(std::unique_ptr symbol);
Symbol *addSymbol(std::string &name, uint32_t byte_size, Artifact newArtifact);
+ Symbol *addSymbol(std::string &inName, uint32_t inByteSize, Artifact newArtifact, Symbol *targetSymbol);
std::vector getFields();
std::vector getEnumerations();
- bool isSymbolUnique(std::string &name);
Symbol *getSymbol(std::string &name);
const std::string &getDate() const;
void setDate(const std::string &date);
@@ -63,7 +62,6 @@ class ElfFile
void isLittleEndian(bool littleEndian);
void setMD5(std::string newID);
std::string getMD5() const;
- void addDefineMacro(std::string name, std::string value);
void addDefineMacro(DefineMacro newMacro);
const std::vector &getDefineMacros() const;
@@ -76,9 +74,23 @@ class ElfFile
void addElf32SectionHeader(Elf32_Shdr newVariable);
std::vector getElf32Headers() const;
+ void addElf64SectionHeader(Elf64_Shdr newVariable);
+ std::vector getElf64Headers() const;
+
void addElf32SymbolTableSymbol(Elf32Symbol newSymbol);
std::vector getElf32SymbolTable() const;
+ void addElf64SymbolTableSymbol(Elf64Symbol newSymbol);
+ std::vector getElf64SymbolTable() const;
+
+ std::vector getDWARFEncodings();
+
+ Encoding &getDWARFEncoding(int encoding);
+
+ int getElfClass();
+
+ void setElfClass(int newelfClass);
+
private:
std::string md5;
/**
@@ -110,6 +122,49 @@ class ElfFile
std::vector elf32SymbolTable{};
std::vector elf32StringsTable{};
+
+ std::vector elf64SymbolTable{};
+ std::vector elf64StringsTable{};
+
+ /**
+ * @note This list of encodings can be found in dwarf.h or
+ * in DWARF5 specification document section 5.1.1 titled "Base Type Encodings"
+ */
+ /**
+ * @brief encodingMap maps the DWARF macros to strings.
+ */
+ std::map encodingsMap = {
+ {DW_ATE_address, Encoding{"DW_ATE_address"}},
+ {DW_ATE_boolean, Encoding{"DW_ATE_boolean"}},
+ {DW_ATE_complex_float, Encoding{"DW_ATE_complex_float"}},
+ {DW_ATE_float, Encoding{"DW_ATE_float"}},
+ {DW_ATE_signed, Encoding{"DW_ATE_signed"}},
+ {DW_ATE_signed_char, Encoding{"DW_ATE_signed_char"}},
+ {DW_ATE_unsigned, Encoding{"DW_ATE_unsigned"}},
+ {DW_ATE_unsigned_char, Encoding{"DW_ATE_unsigned_char"}},
+ {DW_ATE_imaginary_float, Encoding{"DW_ATE_imaginary_float"}},
+ {DW_ATE_packed_decimal, Encoding{"DW_ATE_packed_decimal"}},
+ {DW_ATE_numeric_string, Encoding{"DW_ATE_numeric_string"}},
+ {DW_ATE_edited, Encoding{"DW_ATE_edited"}},
+ {DW_ATE_signed_fixed, Encoding{"DW_ATE_signed_fixed"}},
+ {DW_ATE_unsigned_fixed, Encoding{"DW_ATE_unsigned_fixed"}},
+ {DW_ATE_decimal_float, Encoding{"DW_ATE_decimal_float"}},
+ {DW_ATE_UTF, Encoding{"DW_ATE_UTF"}},
+ {DW_ATE_UCS, Encoding{"DW_ATE_UCS"}},
+ {DW_ATE_ASCII, Encoding{"DW_ATE_ASCII"}},
+
+ };
+
+ Encoding &getDWARFEncoding();
+
+ /**
+ * @brief elfClass
+ * as per the libelf defines
+ * #define ELFCLASSNONE 0 Invalid class
+ * #define ELFCLASS32 1 32-bit objects
+ * #define ELFCLASS64 2 64-bit objects
+ */
+ int elfClass{ELFCLASSNONE};
};
#endif /* ElfFile_H_ */
diff --git a/src/ElfSection.cpp b/src/ElfSection.cpp
deleted file mode 100644
index 20b7fce7..00000000
--- a/src/ElfSection.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "ElfSection.h"
-
-ElfSection::ElfSection() {}
diff --git a/src/ElfSection.h b/src/ElfSection.h
deleted file mode 100644
index 4feb7960..00000000
--- a/src/ElfSection.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef ELFSECTION_H
-#define ELFSECTION_H
-#include
-#include
-
-#include
-
-class ElfSection
-{
- public:
- ElfSection();
-
- private:
- std::string sectionName;
- uint32_t fileOffset;
- uint32_t sectionType; // See elf.h for legal values of sh_type
-
- Elf32_Shdr elf32_Header;
-};
-
-#endif // ELFSECTION_H
diff --git a/src/Encoding.cpp b/src/Encoding.cpp
new file mode 100644
index 00000000..c73499d7
--- /dev/null
+++ b/src/Encoding.cpp
@@ -0,0 +1,9 @@
+#include "Encoding.h"
+
+Encoding::Encoding(std::string name) : name{name} {}
+
+std::string& Encoding::getName() { return name; }
+
+void Encoding::setId(int newId) { id = newId; }
+
+int Encoding::getId() const { return id; }
diff --git a/src/Encoding.h b/src/Encoding.h
new file mode 100644
index 00000000..6529787f
--- /dev/null
+++ b/src/Encoding.h
@@ -0,0 +1,26 @@
+#ifndef ENCODING_H
+#define ENCODING_H
+
+#include
+
+/**
+ * @brief The Encoding class
+ * Simple wrapper for DWARF5 encoding macros.
+ * Read DWARF5 specification document section 5.1.1 titled "Base Type Encodings"
+ * for more details.
+ */
+
+class Encoding
+{
+ public:
+ Encoding(std::string name);
+ std::string& getName();
+ void setId(int);
+ int getId() const;
+
+ private:
+ std::string name;
+ int id;
+};
+
+#endif // ENCODING_H
diff --git a/src/Enumeration.cpp b/src/Enumeration.cpp
index f23960d4..ab9cc85e 100644
--- a/src/Enumeration.cpp
+++ b/src/Enumeration.cpp
@@ -27,13 +27,6 @@ Enumeration::Enumeration(Symbol& inSymbol, std::string& inName, int64_t inValue)
logger.logDebug("ENUM %s:%s value:%u created.", symbol.getName().c_str(), name.c_str(), value);
}
-Enumeration::Enumeration(Enumeration& inEnumeration)
- : symbol{inEnumeration.getSymbol()}, // @suppress("Symbol is not resolved")
- name{inEnumeration.getName()}, // @suppress("Symbol is not resolved")
- value{inEnumeration.getValue()}
-{
-}
-
Enumeration::~Enumeration() {}
std::string& Enumeration::getName() { return name; }
diff --git a/src/Enumeration.h b/src/Enumeration.h
index b3cd4f95..120e9b08 100644
--- a/src/Enumeration.h
+++ b/src/Enumeration.h
@@ -21,7 +21,6 @@ class Enumeration
Enumeration(Symbol& symbol);
Enumeration(Symbol& symbol, std::string& name, int64_t value);
virtual ~Enumeration();
- Enumeration(Enumeration& enumeration);
std::string& getName();
void setName(std::string& name);
Symbol& getSymbol();
diff --git a/src/Field.cpp b/src/Field.cpp
index 3c6f28f6..c7dadcd9 100644
--- a/src/Field.cpp
+++ b/src/Field.cpp
@@ -18,7 +18,7 @@ Field::Field(Symbol& inSymbol, Symbol& inType)
short_description{""},
long_description{""}
{
- logger.logDebug("Field %s::%s byte_offset=%u type=%s multiplicity=%d endian=%s created.", symbol.getName().c_str(), name.c_str(), byte_offset,
+ logger.logDebug("Field %s::%s byte_offset=%u type=%s multiplicity=%s endian=%s created.", symbol.getName().c_str(), name.c_str(), byte_offset,
type.getName().c_str(), dimensionList.toString(), little_endian ? "LE" : "BE");
}
@@ -30,15 +30,15 @@ Field::Field(Symbol& inSymbol, std::string& inName, uint32_t inByteOffset, Symbo
type{inType}, // @suppress("Symbol is not resolved")
dimensionList{inDimensionList},
little_endian{inLittleEndian},
- bit_offset{inBitSize},
+ bit_offset{inBitOffset},
bit_size{inBitSize},
id{0},
short_description{""},
long_description{""}
{
- logger.logDebug("Field %s::%s byte_offset=%u type=%s multiplicity=%d endian=%s created.", symbol.getName().c_str(), name.c_str(), byte_offset,
- type.getName().c_str(), dimensionList, little_endian ? "LE" : "BE");
+ logger.logDebug("Field %s::%s byte_offset=%u type=%s multiplicity=%s endian=%s created.", symbol.getName().c_str(), name.c_str(), byte_offset,
+ type.getName().c_str(), dimensionList.toString(), little_endian ? "LE" : "BE");
}
Field::Field(Symbol& inSymbol, std::string& inName, uint32_t inByteOffset, Symbol& inType, bool inLittleEndian, uint32_t inBitSize, uint32_t inBitOffset)
@@ -48,49 +48,21 @@ Field::Field(Symbol& inSymbol, std::string& inName, uint32_t inByteOffset, Symbo
type{inType}, // @suppress("Symbol is not resolved")
dimensionList{},
little_endian{inLittleEndian},
- bit_offset{inBitSize},
+ bit_offset{inBitOffset},
bit_size{inBitSize},
id{0},
short_description{""},
long_description{""}
{
- logger.logDebug("Field %s::%s byte_offset=%u type=%s multiplicity=%d endian=%s created.", symbol.getName().c_str(), name.c_str(), byte_offset,
- type.getName().c_str(), dimensionList, little_endian ? "LE" : "BE");
-}
-
-Field::Field(Field& field)
- : symbol{field.getSymbol()}, // @suppress("Symbol is not resolved")
- name{field.getName()}, // @suppress("Symbol is not resolved")
- byte_offset{field.getByteOffset()},
- type{field.getType()}, // @suppress("Symbol is not resolved")
- dimensionList(field.getDimensionList()),
- little_endian{field.isLittleEndian()},
- short_description{""},
- long_description{""}
-{
+ logger.logDebug("Field %s::%s byte_offset=%u type=%s multiplicity=%s endian=%s created.", symbol.getName().c_str(), name.c_str(), byte_offset,
+ type.getName().c_str(), dimensionList.toString(), little_endian ? "LE" : "BE");
}
-
Field::~Field() {}
-uint32_t Field::getByteOffset() const { return byte_offset; }
+uint32_t Field::getByteOffset() const { return byte_offset; }
-void Field::setByteOffset(uint32_t inByteOffset)
-{
- logger.logDebug("Field %s::%s byte_offset changed from %u to %u.", symbol.getName().c_str(), name.c_str(), byte_offset, inByteOffset);
-
- byte_offset = inByteOffset;
-}
-
-bool Field::isLittleEndian() const { return little_endian; }
-
-void Field::setLittleEndian(bool inLittleEndian)
-{
- logger.logDebug("Field %s::%s endian changed from %s to %s.", symbol.getName().c_str(), name.c_str(), little_endian ? "LE" : "BE",
- inLittleEndian ? "LE" : "BE");
-
- little_endian = inLittleEndian;
-}
+bool Field::isLittleEndian() const { return little_endian; }
std::string& Field::getName() { return name; }
diff --git a/src/Field.h b/src/Field.h
index 4fed1066..fa6797f6 100644
--- a/src/Field.h
+++ b/src/Field.h
@@ -34,24 +34,21 @@ class Field
uint32_t inBitOffset = 0);
Field(Symbol &symbol, std::string &name, uint32_t byte_offset, Symbol &type, bool little_endian, uint32_t inBitSize = 0, uint32_t inBitOffset = 0);
virtual ~Field();
- uint32_t getByteOffset() const;
- void setByteOffset(uint32_t byteOffset);
- bool isLittleEndian() const;
- void setLittleEndian(bool littleEndian);
- uint32_t getMultiplicity() const;
- uint32_t getArraySize() const;
- void setMultiplicity(uint32_t multiplicity);
- std::string &getName();
- void setName(const std::string &name);
- Symbol &getSymbol() const;
- Symbol &getType();
- uint32_t getId(void) const;
- void setId(uint32_t newId);
- uint32_t getBitOffset() const;
- void setBitOffset(uint32_t bitOffset);
- uint32_t getBitSize() const;
- void setBitSize(uint32_t bitSize);
- Field(Field &field);
+ uint32_t getByteOffset() const;
+ bool isLittleEndian() const;
+ uint32_t getMultiplicity() const;
+ uint32_t getArraySize() const;
+ void setMultiplicity(uint32_t multiplicity);
+ std::string &getName();
+ void setName(const std::string &name);
+ Symbol &getSymbol() const;
+ Symbol &getType();
+ uint32_t getId(void) const;
+ void setId(uint32_t newId);
+ uint32_t getBitOffset() const;
+ void setBitOffset(uint32_t bitOffset);
+ uint32_t getBitSize() const;
+ void setBitSize(uint32_t bitSize);
bool isBitField(void);
DimensionList &getDimensionList();
bool isArray(void) const;
diff --git a/src/IDataContainer.cpp b/src/IDataContainer.cpp
index b616ef88..b1fde9c0 100644
--- a/src/IDataContainer.cpp
+++ b/src/IDataContainer.cpp
@@ -87,35 +87,3 @@ IDataContainer *IDataContainer::Create(IDataContainer_Type_t containerType, cons
return container;
}
-
-std::string IDataContainer::vstring(const char *format, ...)
-{
- std::string result;
- va_list args, args_copy;
-
- va_start(args, format);
- va_copy(args_copy, args);
-
- int len = vsnprintf(nullptr, 0, format, args);
- if (len < 0)
- {
- va_end(args_copy);
- va_end(args);
- throw std::runtime_error("vsnprintf error");
- }
-
- if (len > 0)
- {
- result.resize(len);
- // note: &result[0] is *guaranteed* only in C++11 and later
- // to point to a buffer of contiguous memory with room for a
- // null-terminator, but this "works" in earlier versions
- // in *most* common implementations as well...
- vsnprintf(&result[0], len + 1, format, args_copy); // or result.data() in C++17 and later...
- }
-
- va_end(args_copy);
- va_end(args);
-
- return result;
-}
diff --git a/src/IDataContainer.h b/src/IDataContainer.h
index b8942f46..810e4937 100644
--- a/src/IDataContainer.h
+++ b/src/IDataContainer.h
@@ -38,8 +38,7 @@ class IDataContainer
virtual int initialize(std::string& initString) = 0;
private:
- static Logger logger;
- static std::string vstring(const char* format, ...);
+ static Logger logger;
};
#endif /* IDATACONTAINER_H_ */
diff --git a/src/Juicer.cpp b/src/Juicer.cpp
index e9b1e9b3..6b011fdd 100644
--- a/src/Juicer.cpp
+++ b/src/Juicer.cpp
@@ -69,148 +69,6 @@ struct macro_counts_s
long mc_unknown;
};
-static void print_one_macro_entry_detail(long i, char *type, struct Dwarf_Macro_Details_s *mdp)
-{
- /* "DW_MACINFO_*: section-offset file-index [line] string\n" */
- if (mdp->dmd_macro)
- {
- printf("%3ld %s: %6" DW_PR_DUu " %2" DW_PR_DSd " [%4" DW_PR_DSd "] \"%s\" \n", i, type, (Dwarf_Unsigned)mdp->dmd_offset, mdp->dmd_fileindex,
- mdp->dmd_lineno, mdp->dmd_macro);
- }
- else
- {
- printf("%3ld %s: %6" DW_PR_DUu " %2" DW_PR_DSd " [%4" DW_PR_DSd "] 0\n", i, type, (Dwarf_Unsigned)mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno);
- }
-}
-
-static void print_one_macro_entry(long i, struct Dwarf_Macro_Details_s *mdp, struct macro_counts_s *counts)
-{
- switch (mdp->dmd_type)
- {
- case 0:
- counts->mc_code_zero++;
- print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp);
- break;
-
- case DW_MACINFO_start_file:
- counts->mc_start_file++;
- print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp);
- break;
-
- case DW_MACINFO_end_file:
- counts->mc_end_file++;
- print_one_macro_entry_detail(i, "DW_MACINFO_end_file ", mdp);
- break;
-
- case DW_MACINFO_vendor_ext:
- counts->mc_extension++;
- print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp);
- break;
-
- case DW_MACINFO_define:
- counts->mc_define++;
- print_one_macro_entry_detail(i, "DW_MACINFO_define ", mdp);
- break;
-
- case DW_MACINFO_undef:
- counts->mc_undef++;
- print_one_macro_entry_detail(i, "DW_MACINFO_undef ", mdp);
- break;
-
- default:
- {
- char create_type[50]; /* More than large enough. */
-
- counts->mc_unknown++;
- snprintf(create_type, sizeof(create_type), "DW_MACINFO_0x%x", mdp->dmd_type);
- print_one_macro_entry_detail(i, create_type, mdp);
- }
- break;
- }
-}
-
-/* print data in .debug_macinfo */
-/* FIXME: should print name of file whose index is in macro data
- here -- somewhere. */
-/*ARGSUSED*/ extern void print_macinfo(Dwarf_Debug dbg, Dwarf_Error err)
-{
- Dwarf_Off offset = 0;
- Dwarf_Unsigned max = 10;
- Dwarf_Signed count = 0;
- long group = 0;
- Dwarf_Macro_Details *maclist = NULL;
- int lres = 0;
-
- bool do_print_dwarf = true;
- if (!do_print_dwarf)
- {
- return;
- }
-
- printf("\n.debug_macinfo\n");
-
- while ((lres = dwarf_get_macro_details(dbg, offset, max, &count, &maclist, &err)) == DW_DLV_OK)
- {
- printf("\n.debug_macinfo2\n");
- long i = 0;
- struct macro_counts_s counts;
-
- memset(&counts, 0, sizeof(counts));
-
- printf("\n");
- printf("compilation-unit .debug_macinfo # %ld\n", group);
- printf("num name section-offset file-index [line] \"string\"\n");
- for (i = 0; i < count; i++)
- {
- struct Dwarf_Macro_Details_s *mdp = &maclist[i];
-
- print_one_macro_entry(i, mdp, &counts);
- }
-
- if (counts.mc_start_file == 0)
- {
- printf("DW_MACINFO file count of zero is invalid DWARF2/3\n");
- }
- if (counts.mc_start_file != counts.mc_end_file)
- {
- printf(
- "Counts of DW_MACINFO file (%ld) end_file (%ld) "
- "do not match!.\n",
- counts.mc_start_file, counts.mc_end_file);
- }
- if (counts.mc_code_zero < 1)
- {
- printf(
- "Count of zeros in macro group should be non-zero "
- "(1 preferred), count is %ld\n",
- counts.mc_code_zero);
- }
- printf(
- "Macro counts: start file %ld, "
- "end file %ld, "
- "define %ld, "
- "undef %ld, "
- "ext %ld, "
- "code-zero %ld, "
- "unknown %ld\n",
- counts.mc_start_file, counts.mc_end_file, counts.mc_define, counts.mc_undef, counts.mc_extension, counts.mc_code_zero, counts.mc_unknown);
-
- /* int type= maclist[count - 1].dmd_type; */
- /* ASSERT: type is zero */
-
- offset = maclist[count - 1].dmd_offset + 1;
- dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
- ++group;
- }
- if (lres == DW_DLV_ERROR)
- {
- // std::cout << "dwarf_get_macro_details error" << std::endl;
- // print_error(dbg, "dwarf_get_macro_details", lres, err);
- }
-
- printf("\n.debug_macinfo3:%d\n", lres);
-}
-
Juicer::Juicer() {}
DefineMacro Juicer::getDefineMacroFromString(std::string macro_string)
@@ -306,8 +164,6 @@ DefineMacro Juicer::getDefineMacro(Dwarf_Half macro_operator, Dwarf_Macro_Contex
case DW_MACRO_import:
{
res = dwarf_get_macro_import(mac_context, i, &offset, &error);
- printf("dwarf_get_macro_import res:%d\n", res);
- printf("dwarf_get_macro_import offset:%d\n", offset);
if (offset == 0)
{
@@ -409,8 +265,6 @@ int Juicer::readCUList(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Error &error)
logger.logDebug("Reading CU %u.", cu_number);
- print_macinfo(dbg, error);
-
DisplayDie(cu_die, 0);
Dwarf_Unsigned mac_version;
@@ -842,9 +696,18 @@ Symbol *Juicer::process_DW_TAG_pointer_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf
if (pathIndex != 0)
{
+ /**
+ * Why we are checking against 0 as per DWARF section 2.14:
+ *
+ * The value of the DW_AT_decl_file attribute corresponds to a file number from the line number
+ * information table for the compilation unit containing the debugging information entry and
+ * represents the source file in which the declaration appeared (see Section 6.2 ). The value 0
+ * indicates that no source file has been specified.
+ *
+ */
/* This branch represents a "void*" since there is no valid type.
* Read section 5.2 of DWARF4 for details on this.*/
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
+ Artifact newArtifact{elf, getdbgSourceFile(elf, pathIndex)};
std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
newArtifact.setMD5(checkSum);
outSymbol = elf.addSymbol(voidType, byteSize, newArtifact);
@@ -899,9 +762,6 @@ Symbol *Juicer::process_DW_TAG_pointer_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf
if (res == DW_DLV_OK)
{
- unsigned long long pathIndex = 0;
- res = dwarf_formudata(attr_struct, &pathIndex, &error);
- // TODO: pathIndex will be extracted from the DWARF decl_file attribute.
/**
* According to 6.2 Line Number Information in DWARF 4:
* Line number information generated for a compilation unit is represented in the .debug_line
@@ -923,20 +783,11 @@ Symbol *Juicer::process_DW_TAG_pointer_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf
*
*/
- if (pathIndex != 0)
- {
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
- std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
- newArtifact.setMD5(checkSum);
- outSymbol = elf.addSymbol(name, byteSize, newArtifact);
- }
- else
- {
- Artifact newArtifact{elf, "NOT_FOUND:" + name};
- std::string checkSum{};
- newArtifact.setMD5(checkSum);
- outSymbol = elf.addSymbol(name, byteSize, newArtifact);
- }
+ // As per the DWARF; pointer types do not have any "DECL" attributes, aka declaration coords (line numbers, declaration files, etc).
+ Artifact newArtifact{elf, "NOT_FOUND:" + name};
+ std::string checkSum{};
+ newArtifact.setMD5(checkSum);
+ outSymbol = elf.addSymbol(name, byteSize, newArtifact);
}
}
@@ -1041,10 +892,18 @@ Symbol *Juicer::process_DW_TAG_variable_type(ElfFile &elf, Dwarf_Debug dbg, Dwar
if (elf.getInitializedSymbolData().find(outName) != elf.getInitializedSymbolData().end())
{
+ /**
+ * @todo variableData might be useful if we want to store the data
+ * inside the ELF inside of the db.
+ * CFS tables is an example of this.
+ * Though it should be noted that the data can be
+ * extracted by querying the SQL db; query_symbols.py is an example of this.
+ *
+ */
std::vector variableData = elf.getInitializedSymbolData().at(outName);
-
- elf.addVariable(newVariable);
}
+
+ elf.addVariable(newVariable);
}
}
}
@@ -1219,7 +1078,16 @@ Symbol *Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, DimensionList &
if (pathIndex != 0)
{
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
+ /**
+ * Why we are checking against 0 as per DWARF section 2.14:
+ *
+ * The value of the DW_AT_decl_file attribute corresponds to a file number from the line number
+ * information table for the compilation unit containing the debugging information entry and
+ * represents the source file in which the declaration appeared (see Section 6.2 ). The value 0
+ * indicates that no source file has been specified.
+ *
+ */
+ Artifact newArtifact{elf, getdbgSourceFile(elf, pathIndex)};
std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
newArtifact.setMD5(checkSum);
outSymbol = elf.addSymbol(cName, byteSize, newArtifact);
@@ -1383,7 +1251,16 @@ Symbol *Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, DimensionList &
if (pathIndex != 0)
{
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
+ /**
+ * Why we are checking against 0 as per DWARF section 2.14:
+ *
+ * The value of the DW_AT_decl_file attribute corresponds to a file number from the line number
+ * information table for the compilation unit containing the debugging information entry and
+ * represents the source file in which the declaration appeared (see Section 6.2 ). The value 0
+ * indicates that no source file has been specified.
+ *
+ */
+ Artifact newArtifact{elf, getdbgSourceFile(elf, pathIndex)};
std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
newArtifact.setMD5(checkSum);
outSymbol = elf.addSymbol(cName, byteSize, newArtifact);
@@ -1397,6 +1274,14 @@ Symbol *Juicer::getBaseTypeSymbol(ElfFile &elf, Dwarf_Die inDie, DimensionList &
}
}
+ else
+ {
+ Artifact newArtifact{elf, "NOT_FOUND:" + cName};
+ std::string checkSum{};
+ newArtifact.setMD5(checkSum);
+ outSymbol = elf.addSymbol(cName, byteSize, newArtifact);
+ }
+
process_DW_TAG_enumeration_type(elf, *outSymbol, dbg, typeDie);
}
break;
@@ -1492,1730 +1377,1732 @@ void Juicer::DisplayDie(Dwarf_Die inDie, uint32_t level)
char line[255];
Dwarf_Error error = 0;
- if (inDie != 0)
- {
- res = dwarf_tag(inDie, &tag, &error);
- if (res == DW_DLV_OK)
- {
- switch (tag)
- {
- case DW_TAG_array_type:
- sprintf(tagName, "DW_TAG_array_type");
- break;
-
- case DW_TAG_class_type:
- sprintf(tagName, "DW_TAG_class_type");
- break;
-
- case DW_TAG_entry_point:
- sprintf(tagName, "DW_TAG_entry_point");
- break;
-
- case DW_TAG_enumeration_type:
- sprintf(tagName, "DW_TAG_enumeration_type");
- break;
-
- case DW_TAG_formal_parameter:
- sprintf(tagName, "DW_TAG_formal_parameter");
- break;
-
- case DW_TAG_imported_declaration:
- sprintf(tagName, "DW_TAG_imported_declaration");
- break;
-
- case DW_TAG_label:
- sprintf(tagName, "DW_TAG_label");
- break;
-
- case DW_TAG_lexical_block:
- sprintf(tagName, "DW_TAG_lexical_block");
- break;
-
- case DW_TAG_member:
- sprintf(tagName, "DW_TAG_member");
- break;
-
- case DW_TAG_pointer_type:
- sprintf(tagName, "DW_TAG_pointer_type");
- break;
-
- case DW_TAG_reference_type:
- sprintf(tagName, "DW_TAG_reference_type");
- break;
-
- case DW_TAG_compile_unit:
- sprintf(tagName, "DW_TAG_compile_unit");
- break;
-
- case DW_TAG_string_type:
- sprintf(tagName, "DW_TAG_string_type");
- break;
-
- case DW_TAG_structure_type:
- sprintf(tagName, "DW_TAG_structure_type");
- break;
-
- case DW_TAG_subroutine_type:
- sprintf(tagName, "DW_TAG_subroutine_type");
- break;
-
- case DW_TAG_typedef:
- sprintf(tagName, "DW_TAG_typedef");
- break;
-
- case DW_TAG_union_type:
- sprintf(tagName, "DW_TAG_union_type");
- break;
-
- case DW_TAG_unspecified_parameters:
- sprintf(tagName, "DW_TAG_unspecified_parameters");
- break;
-
- case DW_TAG_variant:
- sprintf(tagName, "DW_TAG_variant");
- break;
-
- case DW_TAG_common_block:
- sprintf(tagName, "DW_TAG_common_block");
- break;
-
- case DW_TAG_common_inclusion:
- sprintf(tagName, "DW_TAG_common_inclusion");
- break;
-
- case DW_TAG_inheritance:
- sprintf(tagName, "DW_TAG_inheritance");
- break;
-
- case DW_TAG_inlined_subroutine:
- sprintf(tagName, "DW_TAG_inlined_subroutine");
- break;
-
- case DW_TAG_module:
- sprintf(tagName, "DW_TAG_module");
- break;
-
- case DW_TAG_ptr_to_member_type:
- sprintf(tagName, "DW_TAG_ptr_to_member_type");
- break;
-
- case DW_TAG_set_type:
- sprintf(tagName, "DW_TAG_set_type");
- break;
-
- case DW_TAG_subrange_type:
- sprintf(tagName, "DW_TAG_subrange_type");
- break;
-
- case DW_TAG_with_stmt:
- sprintf(tagName, "DW_TAG_with_stmt");
- break;
-
- case DW_TAG_access_declaration:
- sprintf(tagName, "DW_TAG_access_declaration");
- break;
-
- case DW_TAG_base_type:
- sprintf(tagName, "DW_TAG_base_type");
- break;
-
- case DW_TAG_catch_block:
- sprintf(tagName, "DW_TAG_catch_block");
- break;
-
- case DW_TAG_const_type:
- sprintf(tagName, "DW_TAG_const_type");
- break;
-
- case DW_TAG_constant:
- sprintf(tagName, "DW_TAG_constant");
- break;
-
- case DW_TAG_enumerator:
- sprintf(tagName, "DW_TAG_enumerator");
- break;
-
- case DW_TAG_file_type:
- sprintf(tagName, "DW_TAG_file_type");
- break;
-
- case DW_TAG_friend:
- sprintf(tagName, "DW_TAG_friend");
- break;
-
- case DW_TAG_namelist:
- sprintf(tagName, "DW_TAG_namelist");
- break;
-
- case DW_TAG_namelist_item:
- sprintf(tagName, "DW_TAG_namelist_item");
- break;
-
- case DW_TAG_packed_type:
- sprintf(tagName, "DW_TAG_packed_type");
- break;
-
- case DW_TAG_subprogram:
- sprintf(tagName, "DW_TAG_subprogram");
- break;
-
- case DW_TAG_template_type_parameter:
- sprintf(tagName, "DW_TAG_template_type_parameter");
- break;
-
- case DW_TAG_template_value_parameter:
- sprintf(tagName, "DW_TAG_template_value_parameter");
- break;
-
- case DW_TAG_thrown_type:
- sprintf(tagName, "DW_TAG_thrown_type");
- break;
-
- case DW_TAG_try_block:
- sprintf(tagName, "DW_TAG_try_block");
- break;
-
- case DW_TAG_variant_part:
- sprintf(tagName, "DW_TAG_variant_part");
- break;
-
- case DW_TAG_variable:
- sprintf(tagName, "DW_TAG_variable");
- break;
-
- case DW_TAG_volatile_type:
- sprintf(tagName, "DW_TAG_volatile_type");
- break;
-
- case DW_TAG_dwarf_procedure:
- sprintf(tagName, "DW_TAG_dwarf_procedure");
- break;
-
- case DW_TAG_restrict_type:
- sprintf(tagName, "DW_TAG_restrict_type");
- break;
-
- case DW_TAG_interface_type:
- sprintf(tagName, "DW_TAG_interface_type");
- break;
-
- case DW_TAG_namespace:
- sprintf(tagName, "DW_TAG_namespace");
- break;
-
- case DW_TAG_imported_module:
- sprintf(tagName, "DW_TAG_imported_module");
- break;
-
- case DW_TAG_unspecified_type:
- sprintf(tagName, "DW_TAG_unspecified_type");
- break;
-
- case DW_TAG_partial_unit:
- sprintf(tagName, "DW_TAG_partial_unit");
- break;
-
- case DW_TAG_imported_unit:
- sprintf(tagName, "DW_TAG_imported_unit");
- break;
-
- case DW_TAG_mutable_type:
- sprintf(tagName, "DW_TAG_mutable_type");
- break;
-
- case DW_TAG_condition:
- sprintf(tagName, "DW_TAG_condition");
- break;
+ // if (inDie != 0)
+ // {
+ // res = dwarf_tag(inDie, &tag, &error);
+ // if (res == DW_DLV_OK)
+ // {
+ // switch (tag)
+ // {
+ // case DW_TAG_array_type:
+ // sprintf(tagName, "DW_TAG_array_type");
+ // break;
+
+ // case DW_TAG_class_type:
+ // sprintf(tagName, "DW_TAG_class_type");
+ // break;
+
+ // case DW_TAG_entry_point:
+ // sprintf(tagName, "DW_TAG_entry_point");
+ // break;
+
+ // case DW_TAG_enumeration_type:
+ // sprintf(tagName, "DW_TAG_enumeration_type");
+ // break;
+
+ // case DW_TAG_formal_parameter:
+ // sprintf(tagName, "DW_TAG_formal_parameter");
+ // break;
+
+ // case DW_TAG_imported_declaration:
+ // sprintf(tagName, "DW_TAG_imported_declaration");
+ // break;
+
+ // case DW_TAG_label:
+ // sprintf(tagName, "DW_TAG_label");
+ // break;
+
+ // case DW_TAG_lexical_block:
+ // sprintf(tagName, "DW_TAG_lexical_block");
+ // break;
+
+ // case DW_TAG_member:
+ // sprintf(tagName, "DW_TAG_member");
+ // break;
+
+ // case DW_TAG_pointer_type:
+ // sprintf(tagName, "DW_TAG_pointer_type");
+ // break;
+
+ // case DW_TAG_reference_type:
+ // sprintf(tagName, "DW_TAG_reference_type");
+ // break;
+
+ // case DW_TAG_compile_unit:
+ // sprintf(tagName, "DW_TAG_compile_unit");
+ // break;
+
+ // case DW_TAG_string_type:
+ // sprintf(tagName, "DW_TAG_string_type");
+ // break;
+
+ // case DW_TAG_structure_type:
+ // sprintf(tagName, "DW_TAG_structure_type");
+ // break;
+
+ // case DW_TAG_subroutine_type:
+ // sprintf(tagName, "DW_TAG_subroutine_type");
+ // break;
+
+ // case DW_TAG_typedef:
+ // sprintf(tagName, "DW_TAG_typedef");
+ // break;
+
+ // case DW_TAG_union_type:
+ // sprintf(tagName, "DW_TAG_union_type");
+ // break;
+
+ // case DW_TAG_unspecified_parameters:
+ // sprintf(tagName, "DW_TAG_unspecified_parameters");
+ // break;
+
+ // case DW_TAG_variant:
+ // sprintf(tagName, "DW_TAG_variant");
+ // break;
+
+ // case DW_TAG_common_block:
+ // sprintf(tagName, "DW_TAG_common_block");
+ // break;
+
+ // case DW_TAG_common_inclusion:
+ // sprintf(tagName, "DW_TAG_common_inclusion");
+ // break;
+
+ // case DW_TAG_inheritance:
+ // sprintf(tagName, "DW_TAG_inheritance");
+ // break;
+
+ // case DW_TAG_inlined_subroutine:
+ // sprintf(tagName, "DW_TAG_inlined_subroutine");
+ // break;
+
+ // case DW_TAG_module:
+ // sprintf(tagName, "DW_TAG_module");
+ // break;
+
+ // case DW_TAG_ptr_to_member_type:
+ // sprintf(tagName, "DW_TAG_ptr_to_member_type");
+ // break;
- case DW_TAG_shared_type:
- sprintf(tagName, "DW_TAG_shared_type");
- break;
+ // case DW_TAG_set_type:
+ // sprintf(tagName, "DW_TAG_set_type");
+ // break;
- case DW_TAG_type_unit:
- sprintf(tagName, "DW_TAG_type_unit");
- break;
+ // case DW_TAG_subrange_type:
+ // sprintf(tagName, "DW_TAG_subrange_type");
+ // break;
- case DW_TAG_rvalue_reference_type:
- sprintf(tagName, "DW_TAG_rvalue_reference_type");
- break;
+ // case DW_TAG_with_stmt:
+ // sprintf(tagName, "DW_TAG_with_stmt");
+ // break;
- case DW_TAG_template_alias:
- sprintf(tagName, "DW_TAG_template_alias");
- break;
+ // case DW_TAG_access_declaration:
+ // sprintf(tagName, "DW_TAG_access_declaration");
+ // break;
- case DW_TAG_coarray_type:
- sprintf(tagName, "DW_TAG_coarray_type");
- break;
+ // case DW_TAG_base_type:
+ // sprintf(tagName, "DW_TAG_base_type");
+ // break;
- case DW_TAG_generic_subrange:
- sprintf(tagName, "DW_TAG_generic_subrange");
- break;
+ // case DW_TAG_catch_block:
+ // sprintf(tagName, "DW_TAG_catch_block");
+ // break;
- case DW_TAG_dynamic_type:
- sprintf(tagName, "DW_TAG_dynamic_type");
- break;
+ // case DW_TAG_const_type:
+ // sprintf(tagName, "DW_TAG_const_type");
+ // break;
- case DW_TAG_atomic_type:
- sprintf(tagName, "DW_TAG_dynamic_type");
- break;
+ // case DW_TAG_constant:
+ // sprintf(tagName, "DW_TAG_constant");
+ // break;
- case DW_TAG_call_site:
- sprintf(tagName, "DW_TAG_call_site");
- break;
+ // case DW_TAG_enumerator:
+ // sprintf(tagName, "DW_TAG_enumerator");
+ // break;
- case DW_TAG_call_site_parameter:
- sprintf(tagName, "DW_TAG_call_site_parameter");
- break;
+ // case DW_TAG_file_type:
+ // sprintf(tagName, "DW_TAG_file_type");
+ // break;
- case DW_TAG_skeleton_unit:
- sprintf(tagName, "DW_TAG_skeleton_unit");
- break;
+ // case DW_TAG_friend:
+ // sprintf(tagName, "DW_TAG_friend");
+ // break;
- case DW_TAG_immutable_type:
- sprintf(tagName, "DW_TAG_immutable_type");
- break;
+ // case DW_TAG_namelist:
+ // sprintf(tagName, "DW_TAG_namelist");
+ // break;
- default:
- sprintf(tagName, "UNKNOWN (0x%04x)", tag);
- break;
- }
- }
- else
- {
- sprintf(tagName, "<< error >>");
- }
+ // case DW_TAG_namelist_item:
+ // sprintf(tagName, "DW_TAG_namelist_item");
+ // break;
- res = dwarf_die_offsets(inDie, &globalOffset, &localOffset, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_die_offsets. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
+ // case DW_TAG_packed_type:
+ // sprintf(tagName, "DW_TAG_packed_type");
+ // break;
- abbrevCode = dwarf_die_abbrev_code(inDie);
+ // case DW_TAG_subprogram:
+ // sprintf(tagName, "DW_TAG_subprogram");
+ // break;
- res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- logger.logDebug(" Has children: %s\n", hasChildrenFlag ? "True" : "False");
- }
+ // case DW_TAG_template_type_parameter:
+ // sprintf(tagName, "DW_TAG_template_type_parameter");
+ // break;
- res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- logger.logDebug(" Has children: %s\n", hasChildrenFlag ? "True" : "False");
- }
+ // case DW_TAG_template_value_parameter:
+ // sprintf(tagName, "DW_TAG_template_value_parameter");
+ // break;
- sprintf(line, "<%u><%x>: Abbrev Number: %u (%s)\n", level, globalOffset, abbrevCode, tagName);
- strcpy(output, line);
+ // case DW_TAG_thrown_type:
+ // sprintf(tagName, "DW_TAG_thrown_type");
+ // break;
- res = dwarf_attrlist(inDie, &attribs, &attribCount, &error);
- if (res != DW_DLV_OK)
- {
- if (res == DW_DLV_ERROR)
- {
- logger.logError("Error in dwarf_attrlist. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else if (res == DW_DLV_NO_ENTRY)
- {
- logger.logWarning("No Entry in dwarf_attrlist. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- }
- else
- {
- if (attribCount > 0)
- {
- for (uint32_t i = 0; i < attribCount; ++i)
- {
- Dwarf_Half attrNum;
- char attribName[255];
- char formName[50];
- char value[50];
+ // case DW_TAG_try_block:
+ // sprintf(tagName, "DW_TAG_try_block");
+ // break;
- strcpy(value, "<< Form Not Supported >>");
+ // case DW_TAG_variant_part:
+ // sprintf(tagName, "DW_TAG_variant_part");
+ // break;
- res = dwarf_whatattr(attribs[i], &attrNum, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- Dwarf_Half formID;
+ // case DW_TAG_variable:
+ // sprintf(tagName, "DW_TAG_variable");
+ // break;
+
+ // case DW_TAG_volatile_type:
+ // sprintf(tagName, "DW_TAG_volatile_type");
+ // break;
+
+ // case DW_TAG_dwarf_procedure:
+ // sprintf(tagName, "DW_TAG_dwarf_procedure");
+ // break;
+
+ // case DW_TAG_restrict_type:
+ // sprintf(tagName, "DW_TAG_restrict_type");
+ // break;
+
+ // case DW_TAG_interface_type:
+ // sprintf(tagName, "DW_TAG_interface_type");
+ // break;
+
+ // case DW_TAG_namespace:
+ // sprintf(tagName, "DW_TAG_namespace");
+ // break;
+
+ // case DW_TAG_imported_module:
+ // sprintf(tagName, "DW_TAG_imported_module");
+ // break;
+
+ // case DW_TAG_unspecified_type:
+ // sprintf(tagName, "DW_TAG_unspecified_type");
+ // break;
+
+ // case DW_TAG_partial_unit:
+ // sprintf(tagName, "DW_TAG_partial_unit");
+ // break;
+
+ // case DW_TAG_imported_unit:
+ // sprintf(tagName, "DW_TAG_imported_unit");
+ // break;
+
+ // case DW_TAG_mutable_type:
+ // sprintf(tagName, "DW_TAG_mutable_type");
+ // break;
+
+ // case DW_TAG_condition:
+ // sprintf(tagName, "DW_TAG_condition");
+ // break;
+
+ // case DW_TAG_shared_type:
+ // sprintf(tagName, "DW_TAG_shared_type");
+ // break;
+
+ // case DW_TAG_type_unit:
+ // sprintf(tagName, "DW_TAG_type_unit");
+ // break;
+
+ // case DW_TAG_rvalue_reference_type:
+ // sprintf(tagName, "DW_TAG_rvalue_reference_type");
+ // break;
+
+ // case DW_TAG_template_alias:
+ // sprintf(tagName, "DW_TAG_template_alias");
+ // break;
+
+ // case DW_TAG_coarray_type:
+ // sprintf(tagName, "DW_TAG_coarray_type");
+ // break;
+
+ // case DW_TAG_generic_subrange:
+ // sprintf(tagName, "DW_TAG_generic_subrange");
+ // break;
+
+ // case DW_TAG_dynamic_type:
+ // sprintf(tagName, "DW_TAG_dynamic_type");
+ // break;
+
+ // case DW_TAG_atomic_type:
+ // sprintf(tagName, "DW_TAG_dynamic_type");
+ // break;
+
+ // case DW_TAG_call_site:
+ // sprintf(tagName, "DW_TAG_call_site");
+ // break;
+
+ // case DW_TAG_call_site_parameter:
+ // sprintf(tagName, "DW_TAG_call_site_parameter");
+ // break;
+
+ // case DW_TAG_skeleton_unit:
+ // sprintf(tagName, "DW_TAG_skeleton_unit");
+ // break;
+
+ // case DW_TAG_immutable_type:
+ // sprintf(tagName, "DW_TAG_immutable_type");
+ // break;
+
+ // default:
+ // sprintf(tagName, "UNKNOWN (0x%04x)", tag);
+ // break;
+ // }
+ // }
+ // else
+ // {
+ // sprintf(tagName, "<< error >>");
+ // }
+
+ // res = dwarf_die_offsets(inDie, &globalOffset, &localOffset, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_die_offsets. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+
+ // abbrevCode = dwarf_die_abbrev_code(inDie);
+
+ // res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // logger.logDebug(" Has children: %s\n", hasChildrenFlag ? "True" : "False");
+ // }
+
+ // res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // logger.logDebug(" Has children: %s\n", hasChildrenFlag ? "True" : "False");
+ // }
+
+ // sprintf(line, "<%u><%x>: Abbrev Number: %u (%s)\n", level, globalOffset, abbrevCode, tagName);
+ // strcpy(output, line);
+
+ // res = dwarf_attrlist(inDie, &attribs, &attribCount, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // if (res == DW_DLV_ERROR)
+ // {
+ // logger.logError("Error in dwarf_attrlist. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else if (res == DW_DLV_NO_ENTRY)
+ // {
+ // logger.logWarning("No Entry in dwarf_attrlist. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // }
+ // else
+ // {
+ // if (attribCount > 0)
+ // {
+ // for (uint32_t i = 0; i < attribCount; ++i)
+ // {
+ // Dwarf_Half attrNum;
+ // char attribName[255];
+ // char formName[50];
+ // char value[50];
+
+ // strcpy(value, "<< Form Not Supported >>");
+
+ // res = dwarf_whatattr(attribs[i], &attrNum, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // Dwarf_Half formID;
+
+ // switch (attrNum)
+ // {
+ // case DW_AT_sibling:
+ // strcpy(attribName, "DW_AT_sibling");
+ // break;
+
+ // case DW_AT_location:
+ // strcpy(attribName, "DW_AT_location");
+ // break;
+
+ // case DW_AT_name:
+ // strcpy(attribName, "DW_AT_name");
+ // break;
+
+ // case DW_AT_ordering:
+ // strcpy(attribName, "DW_AT_ordering");
+ // break;
+
+ // case DW_AT_subscr_data:
+ // strcpy(attribName, "DW_AT_subscr_data");
+ // break;
+
+ // case DW_AT_byte_size:
+ // strcpy(attribName, "DW_AT_byte_size");
+ // break;
+
+ // case DW_AT_bit_offset:
+ // strcpy(attribName, "DW_AT_bit_offset");
+ // break;
+
+ // case DW_AT_bit_size:
+ // strcpy(attribName, "DW_AT_bit_size");
+ // break;
+
+ // case DW_AT_element_list:
+ // strcpy(attribName, "DW_AT_element_list");
+ // break;
+
+ // case DW_AT_stmt_list:
+ // strcpy(attribName, "DW_AT_stmt_list");
+ // break;
+
+ // case DW_AT_low_pc:
+ // strcpy(attribName, "DW_AT_low_pc");
+ // break;
+
+ // case DW_AT_high_pc:
+ // strcpy(attribName, "DW_AT_high_pc");
+ // break;
+
+ // case DW_AT_language:
+ // strcpy(attribName, "DW_AT_language");
+ // break;
+
+ // case DW_AT_member:
+ // strcpy(attribName, "DW_AT_member");
+ // break;
+
+ // case DW_AT_discr:
+ // strcpy(attribName, "DW_AT_discr");
+ // break;
+
+ // case DW_AT_discr_value:
+ // strcpy(attribName, "DW_AT_discr_value");
+ // break;
+
+ // case DW_AT_visibility:
+ // strcpy(attribName, "DW_AT_visibility");
+ // break;
+
+ // case DW_AT_import:
+ // strcpy(attribName, "DW_AT_import");
+ // break;
+
+ // case DW_AT_string_length:
+ // strcpy(attribName, "DW_AT_string_length");
+ // break;
+
+ // case DW_AT_common_reference:
+ // strcpy(attribName, "DW_AT_common_reference");
+ // break;
+
+ // case DW_AT_comp_dir:
+ // strcpy(attribName, "DW_AT_comp_dir");
+ // break;
+
+ // case DW_AT_const_value:
+ // strcpy(attribName, "DW_AT_const_value");
+ // break;
+
+ // case DW_AT_containing_type:
+ // strcpy(attribName, "DW_AT_containing_type");
+ // break;
+
+ // case DW_AT_default_value:
+ // strcpy(attribName, "DW_AT_default_value");
+ // break;
- switch (attrNum)
- {
- case DW_AT_sibling:
- strcpy(attribName, "DW_AT_sibling");
- break;
+ // case DW_AT_inline:
+ // strcpy(attribName, "DW_AT_inline");
+ // break;
- case DW_AT_location:
- strcpy(attribName, "DW_AT_location");
- break;
+ // case DW_AT_is_optional:
+ // strcpy(attribName, "DW_AT_is_optional");
+ // break;
- case DW_AT_name:
- strcpy(attribName, "DW_AT_name");
- break;
+ // case DW_AT_lower_bound:
+ // strcpy(attribName, "DW_AT_lower_bound");
+ // break;
- case DW_AT_ordering:
- strcpy(attribName, "DW_AT_ordering");
- break;
+ // case DW_AT_producer:
+ // strcpy(attribName, "DW_AT_producer");
+ // break;
- case DW_AT_subscr_data:
- strcpy(attribName, "DW_AT_subscr_data");
- break;
+ // case DW_AT_prototyped:
+ // strcpy(attribName, "DW_AT_prototyped");
+ // break;
- case DW_AT_byte_size:
- strcpy(attribName, "DW_AT_byte_size");
- break;
+ // case DW_AT_return_addr:
+ // strcpy(attribName, "DW_AT_return_addr");
+ // break;
- case DW_AT_bit_offset:
- strcpy(attribName, "DW_AT_bit_offset");
- break;
+ // case DW_AT_start_scope:
+ // strcpy(attribName, "DW_AT_start_scope");
+ // break;
- case DW_AT_bit_size:
- strcpy(attribName, "DW_AT_bit_size");
- break;
+ // case DW_AT_bit_stride:
+ // strcpy(attribName, "DW_AT_bit_stride");
+ // break;
- case DW_AT_element_list:
- strcpy(attribName, "DW_AT_element_list");
- break;
+ // case DW_AT_upper_bound:
+ // strcpy(attribName, "DW_AT_upper_bound");
+ // break;
- case DW_AT_stmt_list:
- strcpy(attribName, "DW_AT_stmt_list");
- break;
+ // case DW_AT_abstract_origin:
+ // strcpy(attribName, "DW_AT_abstract_origin");
+ // break;
- case DW_AT_low_pc:
- strcpy(attribName, "DW_AT_low_pc");
- break;
+ // case DW_AT_accessibility:
+ // strcpy(attribName, "DW_AT_accessibility");
+ // break;
- case DW_AT_high_pc:
- strcpy(attribName, "DW_AT_high_pc");
- break;
+ // case DW_AT_address_class:
+ // strcpy(attribName, "DW_AT_address_class");
+ // break;
- case DW_AT_language:
- strcpy(attribName, "DW_AT_language");
- break;
+ // case DW_AT_artificial:
+ // strcpy(attribName, "DW_AT_artificial");
+ // break;
- case DW_AT_member:
- strcpy(attribName, "DW_AT_member");
- break;
+ // case DW_AT_base_types:
+ // strcpy(attribName, "DW_AT_base_types");
+ // break;
- case DW_AT_discr:
- strcpy(attribName, "DW_AT_discr");
- break;
+ // case DW_AT_calling_convention:
+ // strcpy(attribName, "DW_AT_calling_convention");
+ // break;
- case DW_AT_discr_value:
- strcpy(attribName, "DW_AT_discr_value");
- break;
+ // case DW_AT_count:
+ // strcpy(attribName, "DW_AT_count");
+ // break;
- case DW_AT_visibility:
- strcpy(attribName, "DW_AT_visibility");
- break;
+ // case DW_AT_data_member_location:
+ // strcpy(attribName, "DW_AT_data_member_location");
+ // break;
- case DW_AT_import:
- strcpy(attribName, "DW_AT_import");
- break;
+ // case DW_AT_decl_column:
+ // strcpy(attribName, "DW_AT_decl_column");
+ // break;
- case DW_AT_string_length:
- strcpy(attribName, "DW_AT_string_length");
- break;
+ // case DW_AT_decl_file:
+ // strcpy(attribName, "DW_AT_decl_file");
+ // break;
- case DW_AT_common_reference:
- strcpy(attribName, "DW_AT_common_reference");
- break;
+ // case DW_AT_decl_line:
+ // strcpy(attribName, "DW_AT_decl_line");
+ // break;
- case DW_AT_comp_dir:
- strcpy(attribName, "DW_AT_comp_dir");
- break;
+ // case DW_AT_declaration:
+ // strcpy(attribName, "DW_AT_declaration");
+ // break;
- case DW_AT_const_value:
- strcpy(attribName, "DW_AT_const_value");
- break;
+ // case DW_AT_discr_list:
+ // strcpy(attribName, "DW_AT_discr_list");
+ // break;
- case DW_AT_containing_type:
- strcpy(attribName, "DW_AT_containing_type");
- break;
+ // case DW_AT_encoding:
+ // strcpy(attribName, "DW_AT_encoding");
+ // break;
- case DW_AT_default_value:
- strcpy(attribName, "DW_AT_default_value");
- break;
+ // case DW_AT_external:
+ // strcpy(attribName, "DW_AT_external");
+ // break;
- case DW_AT_inline:
- strcpy(attribName, "DW_AT_inline");
- break;
+ // case DW_AT_frame_base:
+ // strcpy(attribName, "DW_AT_frame_base");
+ // break;
- case DW_AT_is_optional:
- strcpy(attribName, "DW_AT_is_optional");
- break;
+ // case DW_AT_friend:
+ // strcpy(attribName, "DW_AT_friend");
+ // break;
- case DW_AT_lower_bound:
- strcpy(attribName, "DW_AT_lower_bound");
- break;
+ // case DW_AT_identifier_case:
+ // strcpy(attribName, "DW_AT_identifier_case");
+ // break;
- case DW_AT_producer:
- strcpy(attribName, "DW_AT_producer");
- break;
+ // case DW_AT_macro_info:
+ // strcpy(attribName, "DW_AT_macro_info");
+ // printf("DW_AT_macro_info************************\n");
+ // break;
- case DW_AT_prototyped:
- strcpy(attribName, "DW_AT_prototyped");
- break;
+ // case DW_AT_namelist_item:
+ // strcpy(attribName, "DW_AT_namelist_item");
+ // break;
- case DW_AT_return_addr:
- strcpy(attribName, "DW_AT_return_addr");
- break;
+ // case DW_AT_priority:
+ // strcpy(attribName, "DW_AT_priority");
+ // break;
- case DW_AT_start_scope:
- strcpy(attribName, "DW_AT_start_scope");
- break;
+ // case DW_AT_segment:
+ // strcpy(attribName, "DW_AT_segment");
+ // break;
- case DW_AT_bit_stride:
- strcpy(attribName, "DW_AT_bit_stride");
- break;
+ // case DW_AT_specification:
+ // strcpy(attribName, "DW_AT_specification");
+ // break;
- case DW_AT_upper_bound:
- strcpy(attribName, "DW_AT_upper_bound");
- break;
+ // case DW_AT_static_link:
+ // strcpy(attribName, "DW_AT_static_link");
+ // break;
- case DW_AT_abstract_origin:
- strcpy(attribName, "DW_AT_abstract_origin");
- break;
+ // case DW_AT_type:
+ // strcpy(attribName, "DW_AT_type");
+ // break;
- case DW_AT_accessibility:
- strcpy(attribName, "DW_AT_accessibility");
- break;
+ // case DW_AT_use_location:
+ // strcpy(attribName, "DW_AT_use_location");
+ // break;
- case DW_AT_address_class:
- strcpy(attribName, "DW_AT_address_class");
- break;
+ // case DW_AT_variable_parameter:
+ // strcpy(attribName, "DW_AT_variable_parameter");
+ // break;
- case DW_AT_artificial:
- strcpy(attribName, "DW_AT_artificial");
- break;
+ // case DW_AT_virtuality:
+ // strcpy(attribName, "DW_AT_virtuality");
+ // break;
- case DW_AT_base_types:
- strcpy(attribName, "DW_AT_base_types");
- break;
+ // case DW_AT_vtable_elem_location:
+ // strcpy(attribName, "DW_AT_vtable_elem_location");
+ // break;
- case DW_AT_calling_convention:
- strcpy(attribName, "DW_AT_calling_convention");
- break;
+ // case DW_AT_allocated:
+ // strcpy(attribName, "DW_AT_allocated");
+ // break;
- case DW_AT_count:
- strcpy(attribName, "DW_AT_count");
- break;
+ // case DW_AT_associated:
+ // strcpy(attribName, "DW_AT_associated");
+ // break;
- case DW_AT_data_member_location:
- strcpy(attribName, "DW_AT_data_member_location");
- break;
+ // case DW_AT_data_location:
+ // strcpy(attribName, "DW_AT_data_location");
+ // break;
- case DW_AT_decl_column:
- strcpy(attribName, "DW_AT_decl_column");
- break;
+ // case DW_AT_byte_stride:
+ // strcpy(attribName, "DW_AT_byte_stride");
+ // break;
- case DW_AT_decl_file:
- strcpy(attribName, "DW_AT_decl_file");
- break;
+ // case DW_AT_entry_pc:
+ // strcpy(attribName, "DW_AT_entry_pc");
+ // break;
- case DW_AT_decl_line:
- strcpy(attribName, "DW_AT_decl_line");
- break;
+ // case DW_AT_use_UTF8:
+ // strcpy(attribName, "DW_AT_use_UTF8");
+ // break;
- case DW_AT_declaration:
- strcpy(attribName, "DW_AT_declaration");
- break;
+ // case DW_AT_extension:
+ // strcpy(attribName, "DW_AT_extension");
+ // break;
- case DW_AT_discr_list:
- strcpy(attribName, "DW_AT_discr_list");
- break;
-
- case DW_AT_encoding:
- strcpy(attribName, "DW_AT_encoding");
- break;
-
- case DW_AT_external:
- strcpy(attribName, "DW_AT_external");
- break;
-
- case DW_AT_frame_base:
- strcpy(attribName, "DW_AT_frame_base");
- break;
-
- case DW_AT_friend:
- strcpy(attribName, "DW_AT_friend");
- break;
-
- case DW_AT_identifier_case:
- strcpy(attribName, "DW_AT_identifier_case");
- break;
-
- case DW_AT_macro_info:
- strcpy(attribName, "DW_AT_macro_info");
- printf("DW_AT_macro_info************************\n");
- break;
-
- case DW_AT_namelist_item:
- strcpy(attribName, "DW_AT_namelist_item");
- break;
-
- case DW_AT_priority:
- strcpy(attribName, "DW_AT_priority");
- break;
-
- case DW_AT_segment:
- strcpy(attribName, "DW_AT_segment");
- break;
-
- case DW_AT_specification:
- strcpy(attribName, "DW_AT_specification");
- break;
-
- case DW_AT_static_link:
- strcpy(attribName, "DW_AT_static_link");
- break;
-
- case DW_AT_type:
- strcpy(attribName, "DW_AT_type");
- break;
-
- case DW_AT_use_location:
- strcpy(attribName, "DW_AT_use_location");
- break;
-
- case DW_AT_variable_parameter:
- strcpy(attribName, "DW_AT_variable_parameter");
- break;
-
- case DW_AT_virtuality:
- strcpy(attribName, "DW_AT_virtuality");
- break;
-
- case DW_AT_vtable_elem_location:
- strcpy(attribName, "DW_AT_vtable_elem_location");
- break;
-
- case DW_AT_allocated:
- strcpy(attribName, "DW_AT_allocated");
- break;
-
- case DW_AT_associated:
- strcpy(attribName, "DW_AT_associated");
- break;
-
- case DW_AT_data_location:
- strcpy(attribName, "DW_AT_data_location");
- break;
-
- case DW_AT_byte_stride:
- strcpy(attribName, "DW_AT_byte_stride");
- break;
-
- case DW_AT_entry_pc:
- strcpy(attribName, "DW_AT_entry_pc");
- break;
-
- case DW_AT_use_UTF8:
- strcpy(attribName, "DW_AT_use_UTF8");
- break;
-
- case DW_AT_extension:
- strcpy(attribName, "DW_AT_extension");
- break;
-
- case DW_AT_ranges:
- strcpy(attribName, "DW_AT_ranges");
- break;
-
- case DW_AT_trampoline:
- strcpy(attribName, "DW_AT_trampoline");
- break;
-
- case DW_AT_call_column:
- strcpy(attribName, "DW_AT_call_column");
- break;
-
- case DW_AT_call_file:
- strcpy(attribName, "DW_AT_call_file");
- break;
-
- case DW_AT_call_line:
- strcpy(attribName, "DW_AT_call_line");
- break;
-
- case DW_AT_description:
- strcpy(attribName, "DW_AT_description");
- break;
-
- case DW_AT_binary_scale:
- strcpy(attribName, "DW_AT_binary_scale");
- break;
-
- case DW_AT_decimal_scale:
- strcpy(attribName, "DW_AT_decimal_scale");
- break;
-
- case DW_AT_small:
- strcpy(attribName, "DW_AT_small");
- break;
-
- case DW_AT_decimal_sign:
- strcpy(attribName, "DW_AT_decimal_sign");
- break;
-
- case DW_AT_digit_count:
- strcpy(attribName, "DW_AT_digit_count");
- break;
-
- case DW_AT_picture_string:
- strcpy(attribName, "DW_AT_picture_string");
- break;
-
- case DW_AT_mutable:
- strcpy(attribName, "DW_AT_mutable");
- break;
-
- case DW_AT_threads_scaled:
- strcpy(attribName, "DW_AT_threads_scaled");
- break;
-
- case DW_AT_explicit:
- strcpy(attribName, "DW_AT_explicit");
- break;
-
- case DW_AT_object_pointer:
- strcpy(attribName, "DW_AT_object_pointer");
- break;
-
- case DW_AT_endianity:
- strcpy(attribName, "DW_AT_endianity");
- break;
-
- case DW_AT_elemental:
- strcpy(attribName, "DW_AT_elemental");
- break;
-
- case DW_AT_pure:
- strcpy(attribName, "DW_AT_pure");
- break;
-
- case DW_AT_recursive:
- strcpy(attribName, "DW_AT_recursive");
- break;
-
- case DW_AT_signature:
- strcpy(attribName, "DW_AT_signature");
- break;
-
- case DW_AT_main_subprogram:
- strcpy(attribName, "DW_AT_main_subprogram");
- break;
-
- case DW_AT_data_bit_offset:
- strcpy(attribName, "DW_AT_data_bit_offset");
- break;
-
- case DW_AT_const_expr:
- strcpy(attribName, "DW_AT_const_expr");
- break;
-
- case DW_AT_enum_class:
- strcpy(attribName, "DW_AT_enum_class");
- break;
-
- case DW_AT_linkage_name:
- strcpy(attribName, "DW_AT_linkage_name");
- break;
-
- case DW_AT_string_length_bit_size:
- strcpy(attribName, "DW_AT_string_length_bit_size");
- break;
-
- case DW_AT_string_length_byte_size:
- strcpy(attribName, "DW_AT_string_length_byte_size");
- break;
-
- case DW_AT_rank:
- strcpy(attribName, "DW_AT_rank");
- break;
-
- case DW_AT_str_offsets_base:
- strcpy(attribName, "DW_AT_str_offsets_base");
- break;
-
- case DW_AT_addr_base:
- strcpy(attribName, "DW_AT_addr_base");
- break;
-
- case DW_AT_rnglists_base:
- strcpy(attribName, "DW_AT_rnglists_base");
- break;
-
- case DW_AT_dwo_id:
- strcpy(attribName, "DW_AT_dwo_id");
- break;
-
- case DW_AT_dwo_name:
- strcpy(attribName, "DW_AT_dwo_name");
- break;
-
- case DW_AT_reference:
- strcpy(attribName, "DW_AT_reference");
- break;
-
- case DW_AT_rvalue_reference:
- strcpy(attribName, "DW_AT_rvalue_reference");
- break;
-
- case DW_AT_macros:
- strcpy(attribName, "DW_AT_macros");
- printf("DW_AT_macros\n");
- break;
-
- case DW_AT_call_all_calls:
- strcpy(attribName, "DW_AT_call_all_calls");
- break;
-
- case DW_AT_call_all_source_calls:
- strcpy(attribName, "DW_AT_call_all_source_calls");
- break;
-
- case DW_AT_call_all_tail_calls:
- strcpy(attribName, "DW_AT_call_all_tail_calls");
- break;
-
- case DW_AT_call_return_pc:
- strcpy(attribName, "DW_AT_call_return_pc");
- break;
-
- case DW_AT_call_value:
- strcpy(attribName, "DW_AT_call_value");
- break;
-
- case DW_AT_call_origin:
- strcpy(attribName, "DW_AT_call_origin");
- break;
-
- case DW_AT_call_parameter:
- strcpy(attribName, "DW_AT_call_parameter");
- break;
-
- case DW_AT_call_pc:
- strcpy(attribName, "DW_AT_call_pc");
- break;
-
- case DW_AT_call_tail_call:
- strcpy(attribName, "DW_AT_call_tail_call");
- break;
-
- case DW_AT_call_target:
- strcpy(attribName, "DW_AT_call_target");
- break;
-
- case DW_AT_call_target_clobbered:
- strcpy(attribName, "DW_AT_call_target_clobbered");
- break;
-
- case DW_AT_call_data_location:
- strcpy(attribName, "DW_AT_call_data_location");
- break;
-
- case DW_AT_call_data_value:
- strcpy(attribName, "DW_AT_call_data_value");
- break;
-
- case DW_AT_noreturn:
- strcpy(attribName, "DW_AT_noreturn");
- break;
-
- case DW_AT_alignment:
- strcpy(attribName, "DW_AT_alignment");
- break;
-
- case DW_AT_export_symbols:
- strcpy(attribName, "DW_AT_export_symbols");
- break;
-
- case DW_AT_deleted:
- strcpy(attribName, "DW_AT_deleted");
- break;
-
- case DW_AT_defaulted:
- strcpy(attribName, "DW_AT_defaulted");
- break;
-
- case DW_AT_loclists_base:
- strcpy(attribName, "DW_AT_loclists_base");
- break;
-
- default:
- sprintf(attribName, "UNKNOWN (%x)", attrNum);
- break;
- }
-
- res = dwarf_whatform(attribs[i], &attrNum, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- res = dwarf_whatform(attribs[i], &formID, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_whatform. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- switch (formID)
- {
- case DW_FORM_addr:
- {
- Dwarf_Addr addr = 0;
-
- strcpy(formName, "DW_FORM_addr");
-
- res = dwarf_formaddr(attribs[i], &addr, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in DW_FORM_addr. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- unsigned long long data = (unsigned int)addr;
- sprintf(value, "0x%016x", data);
- }
-
- break;
- }
-
- case DW_FORM_block2:
- {
- Dwarf_Unsigned udata = 0;
-
- strcpy(formName, "DW_FORM_block2");
-
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- unsigned short data = (unsigned short)udata;
- sprintf(value, "%d", data);
- }
-
- break;
- }
-
- case DW_FORM_block4:
- {
- Dwarf_Unsigned udata = 0;
-
- strcpy(formName, "DW_FORM_block4");
-
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in DW_FORM_block4. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- unsigned int data = (unsigned int)udata;
- sprintf(value, "%d", data);
- }
-
- break;
- }
-
- case DW_FORM_data2:
- {
- Dwarf_Unsigned udata = 0;
-
- strcpy(formName, "DW_FORM_data2");
-
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in DW_FORM_data2. line=%u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- unsigned short int data = (unsigned short int)udata;
- sprintf(value, "%d", data);
- }
-
- break;
- }
-
- case DW_FORM_data4:
- {
- Dwarf_Unsigned udata = 0;
-
- strcpy(formName, "DW_FORM_data4");
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- unsigned int data = (unsigned int)udata;
- sprintf(value, "%d", data);
- }
-
- break;
- }
-
- case DW_FORM_data8:
- {
- Dwarf_Unsigned udata = 0;
-
- strcpy(formName, "DW_FORM_data8");
-
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- sprintf(value, "%d", udata);
- }
-
- break;
- }
-
- case DW_FORM_string:
- {
- char *str = 0;
-
- strcpy(formName, "DW_FORM_string");
-
- res = dwarf_formstring(attribs[i], &str, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- sprintf(value, "%s", str);
- }
-
- break;
- }
-
- case DW_FORM_block:
- strcpy(formName, "DW_FORM_block");
- break;
-
- case DW_FORM_block1:
- {
- Dwarf_Block *bdata = 0;
- strcpy(formName, "DW_FORM_block1");
-
- res = dwarf_formblock(attribs[i], &bdata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formblock. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- sprintf(value, "len: %d", bdata->bl_len);
- }
-
- break;
- }
-
- case DW_FORM_data1:
- {
- Dwarf_Unsigned udata = 0;
- strcpy(formName, "DW_FORM_data1");
-
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- uint8_t data = (uint8_t)udata;
- sprintf(value, "%u", data);
- }
-
- break;
- }
-
- case DW_FORM_flag:
- {
- Dwarf_Bool dwarfBool = false;
- strcpy(formName, "DW_FORM_flag");
- char *strp = 0;
-
- res = dwarf_formflag(attribs[i], &dwarfBool, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in DW_FORM_flag. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- if (dwarfBool)
- {
- sprintf(value, "TRUE");
- }
- else
- {
- sprintf(value, "FALSE");
- }
- }
-
- break;
- }
-
- case DW_FORM_sdata:
- {
- Dwarf_Signed sdata = 0;
-
- strcpy(formName, "DW_FORM_sdata");
-
- res = dwarf_formsdata(attribs[i], &sdata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- sprintf(value, "%lli", sdata);
- }
-
- break;
- }
-
- case DW_FORM_strp:
- {
- char *strp = 0;
-
- strcpy(formName, "DW_FORM_strp");
-
- res = dwarf_formstring(attribs[i], &strp, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- char *text = dwarfStringToChar(strp);
- sprintf(value, "%s", text);
- }
-
- break;
- }
-
- case DW_FORM_udata:
- {
- Dwarf_Unsigned udata = 0;
-
- strcpy(formName, "DW_FORM_udata");
-
- res = dwarf_formudata(attribs[i], &udata, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- sprintf(value, "%llu", udata);
- }
-
- break;
- }
-
- case DW_FORM_ref_addr:
- strcpy(formName, "DW_FORM_ref_addr");
- break;
-
- case DW_FORM_ref1:
- {
- Dwarf_Off ref = 0;
-
- strcpy(formName, "DW_FORM_ref1");
- res = dwarf_formref(attribs[i], &ref, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- uint8_t data = (uint8_t)ref;
- sprintf(value, "%u", data);
- }
-
- break;
- }
-
- case DW_FORM_ref2:
- {
- Dwarf_Off ref = 0;
-
- strcpy(formName, "DW_FORM_ref1");
- res = dwarf_formref(attribs[i], &ref, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- unsigned short int data = (unsigned short int)ref;
- sprintf(value, "%u", data);
- }
-
- break;
- }
-
- case DW_FORM_ref4:
- {
- Dwarf_Off ref = 0;
-
- strcpy(formName, "DW_FORM_ref1");
- res = dwarf_formref(attribs[i], &ref, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- unsigned int data = (unsigned int)ref;
- sprintf(value, "%u", data);
- }
-
- break;
- }
-
- case DW_FORM_ref8:
- {
- Dwarf_Off ref = 0;
-
- strcpy(formName, "DW_FORM_ref1");
- res = dwarf_formref(attribs[i], &ref, &error);
- if (res != DW_DLV_OK)
- {
- logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- dwarf_errmsg(error));
- }
- else
- {
- sprintf(value, "%llu", ref);
- }
+ // case DW_AT_ranges:
+ // strcpy(attribName, "DW_AT_ranges");
+ // break;
- break;
- }
+ // case DW_AT_trampoline:
+ // strcpy(attribName, "DW_AT_trampoline");
+ // break;
- case DW_FORM_ref_udata:
- strcpy(formName, "DW_FORM_ref_udata");
- break;
+ // case DW_AT_call_column:
+ // strcpy(attribName, "DW_AT_call_column");
+ // break;
- case DW_FORM_indirect:
- strcpy(formName, "DW_FORM_indirect");
- break;
+ // case DW_AT_call_file:
+ // strcpy(attribName, "DW_AT_call_file");
+ // break;
- case DW_FORM_sec_offset:
- strcpy(formName, "DW_FORM_sec_offset");
- break;
+ // case DW_AT_call_line:
+ // strcpy(attribName, "DW_AT_call_line");
+ // break;
- case DW_FORM_exprloc:
- strcpy(formName, "DW_FORM_exprloc");
- break;
+ // case DW_AT_description:
+ // strcpy(attribName, "DW_AT_description");
+ // break;
- case DW_FORM_flag_present:
- strcpy(formName, "DW_FORM_flag_present");
- break;
+ // case DW_AT_binary_scale:
+ // strcpy(attribName, "DW_AT_binary_scale");
+ // break;
- case DW_FORM_strx:
- strcpy(formName, "DW_FORM_strx");
- break;
+ // case DW_AT_decimal_scale:
+ // strcpy(attribName, "DW_AT_decimal_scale");
+ // break;
- case DW_FORM_addrx:
- strcpy(formName, "DW_FORM_addrx");
- break;
+ // case DW_AT_small:
+ // strcpy(attribName, "DW_AT_small");
+ // break;
- case DW_FORM_ref_sup4:
- strcpy(formName, "DW_FORM_ref_sup4");
- break;
+ // case DW_AT_decimal_sign:
+ // strcpy(attribName, "DW_AT_decimal_sign");
+ // break;
- case DW_FORM_strp_sup:
- strcpy(formName, "DW_FORM_strp_sup");
- break;
+ // case DW_AT_digit_count:
+ // strcpy(attribName, "DW_AT_digit_count");
+ // break;
- case DW_FORM_data16:
- strcpy(formName, "DW_FORM_data16");
- break;
+ // case DW_AT_picture_string:
+ // strcpy(attribName, "DW_AT_picture_string");
+ // break;
- case DW_FORM_line_strp:
- strcpy(formName, "DW_FORM_line_strp");
- break;
+ // case DW_AT_mutable:
+ // strcpy(attribName, "DW_AT_mutable");
+ // break;
- case DW_FORM_ref_sig8:
- strcpy(formName, "DW_FORM_ref_sig8");
- break;
+ // case DW_AT_threads_scaled:
+ // strcpy(attribName, "DW_AT_threads_scaled");
+ // break;
- case DW_FORM_implicit_const:
- strcpy(formName, "DW_FORM_implicit_const");
- break;
+ // case DW_AT_explicit:
+ // strcpy(attribName, "DW_AT_explicit");
+ // break;
- case DW_FORM_loclistx:
- strcpy(formName, "DW_FORM_loclistx");
- break;
+ // case DW_AT_object_pointer:
+ // strcpy(attribName, "DW_AT_object_pointer");
+ // break;
- case DW_FORM_rnglistx:
- strcpy(formName, "DW_FORM_rnglistx");
- break;
+ // case DW_AT_endianity:
+ // strcpy(attribName, "DW_AT_endianity");
+ // break;
- case DW_FORM_ref_sup8:
- strcpy(formName, "DW_FORM_ref_sup8");
- break;
+ // case DW_AT_elemental:
+ // strcpy(attribName, "DW_AT_elemental");
+ // break;
- case DW_FORM_strx1:
- strcpy(formName, "DW_FORM_strx1");
- break;
+ // case DW_AT_pure:
+ // strcpy(attribName, "DW_AT_pure");
+ // break;
- case DW_FORM_strx2:
- strcpy(formName, "DW_FORM_strx2");
- break;
+ // case DW_AT_recursive:
+ // strcpy(attribName, "DW_AT_recursive");
+ // break;
- case DW_FORM_strx3:
- strcpy(formName, "DW_FORM_strx3");
- break;
+ // case DW_AT_signature:
+ // strcpy(attribName, "DW_AT_signature");
+ // break;
- case DW_FORM_strx4:
- strcpy(formName, "DW_FORM_strx4");
- break;
+ // case DW_AT_main_subprogram:
+ // strcpy(attribName, "DW_AT_main_subprogram");
+ // break;
- case DW_FORM_addrx1:
- strcpy(formName, "DW_FORM_addrx1");
- break;
+ // case DW_AT_data_bit_offset:
+ // strcpy(attribName, "DW_AT_data_bit_offset");
+ // break;
- case DW_FORM_addrx2:
- strcpy(formName, "DW_FORM_addrx2");
- break;
+ // case DW_AT_const_expr:
+ // strcpy(attribName, "DW_AT_const_expr");
+ // break;
- case DW_FORM_addrx3:
- strcpy(formName, "DW_FORM_addrx3");
- break;
+ // case DW_AT_enum_class:
+ // strcpy(attribName, "DW_AT_enum_class");
+ // break;
- case DW_FORM_addrx4:
- strcpy(formName, "DW_FORM_addrx4");
- break;
+ // case DW_AT_linkage_name:
+ // strcpy(attribName, "DW_AT_linkage_name");
+ // break;
- case DW_FORM_GNU_addr_index:
- strcpy(formName, "DW_FORM_GNU_addr_index");
- break;
+ // case DW_AT_string_length_bit_size:
+ // strcpy(attribName, "DW_AT_string_length_bit_size");
+ // break;
- case DW_FORM_GNU_str_index:
- strcpy(formName, "DW_FORM_GNU_str_index");
- break;
+ // case DW_AT_string_length_byte_size:
+ // strcpy(attribName, "DW_AT_string_length_byte_size");
+ // break;
- case DW_FORM_GNU_ref_alt:
- strcpy(formName, "DW_FORM_GNU_ref_alt");
- break;
+ // case DW_AT_rank:
+ // strcpy(attribName, "DW_AT_rank");
+ // break;
- case DW_FORM_GNU_strp_alt:
- strcpy(formName, "DW_FORM_GNU_strp_alt");
- break;
+ // case DW_AT_str_offsets_base:
+ // strcpy(attribName, "DW_AT_str_offsets_base");
+ // break;
- default:
- sprintf(formName, "UNKNOWN (%x)", formID);
- break;
- }
- }
- }
- }
+ // case DW_AT_addr_base:
+ // strcpy(attribName, "DW_AT_addr_base");
+ // break;
- sprintf(line, " %-20s : %-20s (%s)\n", attribName, value, formName);
- strcat(output, line);
- }
- }
- }
+ // case DW_AT_rnglists_base:
+ // strcpy(attribName, "DW_AT_rnglists_base");
+ // break;
- // res = dwarf_attr(inDie, DW_AT_name, &attr_struct, &error);
- // if(res == DW_DLV_OK)
- // {
- // res = dwarf_formstring(attr_struct, &dieName, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // sprintf(line, " DW_AT_name : %s", dieName);
- // strcpy(output, line);
- // }
- // }
- //
- // res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
-
- // else
- // {
- // logger.logDebug(" Has children: %s", hasChildrenFlag ? "True" : "False");
- // }
- //
- // int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/,
- // Dwarf_Half * /*ab_has_child*/);
- //
- // res = dwarf_attrlist(inDie, &attribs, &attribCount, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_attrlist. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // if(attribCount > 0)
- // {
- // logger.logDebug(" Attributes:");
- // for(uint32_t i = 0; i < attribCount; ++i)
- // {
- // Dwarf_Half attrNum;
- // res = dwarf_whatattr(attribs[i], &attrNum, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // Dwarf_Half formID;
- //
- // switch(attrNum)
- // {
- // case DW_AT_sibling:
- // logger.logDebug(" DW_AT_sibling");
- // break;
- //
- // case DW_AT_location:
- // logger.logDebug(" DW_AT_location");
- // break;
- //
- // case DW_AT_name:
- // logger.logDebug(" DW_AT_name");
- // break;
- //
- // case DW_AT_ordering:
- // logger.logDebug(" DW_AT_ordering");
- // break;
- //
- // case DW_AT_subscr_data:
- // logger.logDebug(" DW_AT_subscr_data");
- // break;
- //
- // case DW_AT_byte_size:
- // logger.logDebug(" DW_AT_byte_size");
- // break;
- //
- // case DW_AT_decl_file:
- // logger.logDebug(" DW_AT_decl_file");
- // break;
- //
- // case DW_AT_decl_line:
- // logger.logDebug(" DW_AT_decl_line");
- // break;
- //
- // case DW_AT_type:
- // logger.logDebug(" DW_AT_type");
- // break;
- //
- // default:
- // logger.logDebug(" 0x%02x", attrNum);
- // break;
- // }
- //
- // res = dwarf_whatform(attribs[i], &attrNum, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // res = dwarf_whatform(attribs[i], &formID, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_whatform. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // switch(formID)
- // {
- // case DW_FORM_addr:
- // logger.logDebug(":DW_FORM_addr");
- // break;
- //
- // case DW_FORM_block2:
- // logger.logDebug(":DW_FORM_block2");
- // break;
- //
- // case DW_FORM_block4:
- // logger.logDebug(":DW_FORM_block4");
- // break;
- //
- // case DW_FORM_data1:
- // {
- // Dwarf_Unsigned udata = 0;
- // res = dwarf_formudata(attribs[i], &udata, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // char data = (char) udata;
- // logger.logDebug(":DW_FORM_data1:%u", data);
- // }
- // break;
- // }
- //
- // case DW_FORM_data2:
- // {
- // Dwarf_Unsigned udata = 0;
- // res = dwarf_formudata(attribs[i], &udata, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // unsigned short data = (unsigned short) udata;
- // logger.logDebug(":DW_FORM_data2:%u", data);
- // }
- // break;
- // }
- //
- // case DW_FORM_data4:
- // {
- // Dwarf_Unsigned udata = 0;
- // res = dwarf_formudata(attribs[i], &udata, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // unsigned int data = (unsigned int) udata;
- // logger.logDebug(":DW_FORM_data4:%u", data);
- // }
- // break;
- // }
- //
- // case DW_FORM_data8:
- // {
- // Dwarf_Unsigned udata = 0;
- // res = dwarf_formudata(attribs[i], &udata, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // logger.logDebug(":DW_FORM_data8:%llu", udata);
- // }
- // break;
- // }
- //
- // case DW_FORM_string:
- // {
- // char *str = 0;
- // res = dwarf_formstring(attribs[i], &str, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // logger.logDebug(":DW_FORM_string:%s", str);
- // }
- // break;
- // }
- //
- // case DW_FORM_block:
- // logger.logDebug(":DW_FORM_block");
- // break;
- //
- // case DW_FORM_sdata:
- // logger.logDebug(":DW_FORM_sdata");
- // break;
- //
- // case DW_FORM_strp:
- // {
- // char *strp = 0;
- // res = dwarf_formstring(attribs[i], &strp, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // char *text = dwarfStringToChar(strp);
- // logger.logDebug(":DW_FORM_strp:%s", text);
- // }
- // break;
- // }
- //
- // case DW_FORM_udata:
- // {
- // Dwarf_Unsigned udata = 0;
- // res = dwarf_formudata(attribs[i], &udata, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // logger.logDebug(":DW_FORM_udata:%llu", udata);
- // }
- // break;
- // }
- //
- // case DW_FORM_ref_addr:
- // logger.logDebug(":DW_FORM_ref_addr");
- // break;
- //
- // case DW_FORM_ref1:
- // {
- // Dwarf_Off ref = 0;
- // res = dwarf_formref(attribs[i], &ref, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // char data = (char) ref;
- // logger.logDebug(":DW_FORM_ref1:%u", data);
- // }
- // break;
- // }
- //
- // case DW_FORM_ref2:
- // {
- // Dwarf_Off ref = 0;
- // res = dwarf_formref(attribs[i], &ref, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // unsigned short int data = (unsigned short int) ref;
- // logger.logDebug(":DW_FORM_ref2:%u", data);
- // }
- // break;
- // }
- //
- // case DW_FORM_ref4:
- // {
- // Dwarf_Off ref = 0;
- // res = dwarf_formref(attribs[i], &ref, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // unsigned int data = (unsigned int) ref;
- // logger.logDebug(":DW_FORM_ref4:%u", data);
- // }
- // break;
- // }
- //
- // case DW_FORM_ref8:
- // {
- // Dwarf_Off ref = 0;
- // res = dwarf_formref(attribs[i], &ref, &error);
- // if(res != DW_DLV_OK)
- // {
- // logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error),
- // dwarf_errmsg(error));
- // }
- // else
- // {
- // logger.logDebug(":DW_FORM_ref4:%llu", ref);
- // }
- // break;
- // }
- //
- // case DW_FORM_ref_udata:
- // logger.logDebug(":DW_FORM_ref_udata");
- // break;
- //
- // case DW_FORM_indirect:
- // logger.logDebug(":DW_FORM_indirect");
- // break;
- //
- // case DW_FORM_sec_offset:
- // logger.logDebug(":DW_FORM_sec_offset");
- // break;
- //
- // case DW_FORM_exprloc:
- // logger.logDebug(":DW_FORM_exprloc");
- // break;
- //
- // case DW_FORM_flag_present:
- // logger.logDebug(":DW_FORM_flag_present");
- // break;
- //
- // case DW_FORM_ref_sig8:
- // logger.logDebug(":DW_FORM_ref_sig8");
- // break;
- //
- // default:
- // logger.logDebug(":0x%02x", formID);
- // break;
- //
- // }
- // }
- // }
- // }
- // }
- // logger.logDebug("\n");
- // }
- // }
-
- logger.logDebug(output);
- }
+ // case DW_AT_dwo_id:
+ // strcpy(attribName, "DW_AT_dwo_id");
+ // break;
+
+ // case DW_AT_dwo_name:
+ // strcpy(attribName, "DW_AT_dwo_name");
+ // break;
+
+ // case DW_AT_reference:
+ // strcpy(attribName, "DW_AT_reference");
+ // break;
+
+ // case DW_AT_rvalue_reference:
+ // strcpy(attribName, "DW_AT_rvalue_reference");
+ // break;
+
+ // case DW_AT_macros:
+ // strcpy(attribName, "DW_AT_macros");
+ // printf("DW_AT_macros\n");
+ // break;
+
+ // case DW_AT_call_all_calls:
+ // strcpy(attribName, "DW_AT_call_all_calls");
+ // break;
+
+ // case DW_AT_call_all_source_calls:
+ // strcpy(attribName, "DW_AT_call_all_source_calls");
+ // break;
+
+ // case DW_AT_call_all_tail_calls:
+ // strcpy(attribName, "DW_AT_call_all_tail_calls");
+ // break;
+
+ // case DW_AT_call_return_pc:
+ // strcpy(attribName, "DW_AT_call_return_pc");
+ // break;
+
+ // case DW_AT_call_value:
+ // strcpy(attribName, "DW_AT_call_value");
+ // break;
+
+ // case DW_AT_call_origin:
+ // strcpy(attribName, "DW_AT_call_origin");
+ // break;
+
+ // case DW_AT_call_parameter:
+ // strcpy(attribName, "DW_AT_call_parameter");
+ // break;
+
+ // case DW_AT_call_pc:
+ // strcpy(attribName, "DW_AT_call_pc");
+ // break;
+
+ // case DW_AT_call_tail_call:
+ // strcpy(attribName, "DW_AT_call_tail_call");
+ // break;
+
+ // case DW_AT_call_target:
+ // strcpy(attribName, "DW_AT_call_target");
+ // break;
+
+ // case DW_AT_call_target_clobbered:
+ // strcpy(attribName, "DW_AT_call_target_clobbered");
+ // break;
+
+ // case DW_AT_call_data_location:
+ // strcpy(attribName, "DW_AT_call_data_location");
+ // break;
+
+ // case DW_AT_call_data_value:
+ // strcpy(attribName, "DW_AT_call_data_value");
+ // break;
+
+ // case DW_AT_noreturn:
+ // strcpy(attribName, "DW_AT_noreturn");
+ // break;
+
+ // case DW_AT_alignment:
+ // strcpy(attribName, "DW_AT_alignment");
+ // break;
+
+ // case DW_AT_export_symbols:
+ // strcpy(attribName, "DW_AT_export_symbols");
+ // break;
+
+ // case DW_AT_deleted:
+ // strcpy(attribName, "DW_AT_deleted");
+ // break;
+
+ // case DW_AT_defaulted:
+ // strcpy(attribName, "DW_AT_defaulted");
+ // break;
+
+ // case DW_AT_loclists_base:
+ // strcpy(attribName, "DW_AT_loclists_base");
+ // break;
+
+ // default:
+ // sprintf(attribName, "UNKNOWN (%x)", attrNum);
+ // break;
+ // }
+
+ // res = dwarf_whatform(attribs[i], &attrNum, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // res = dwarf_whatform(attribs[i], &formID, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_whatform. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // switch (formID)
+ // {
+ // case DW_FORM_addr:
+ // {
+ // Dwarf_Addr addr = 0;
+
+ // strcpy(formName, "DW_FORM_addr");
+
+ // res = dwarf_formaddr(attribs[i], &addr, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in DW_FORM_addr. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned long long data = (unsigned int)addr;
+ // sprintf(value, "0x%016x", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_block2:
+ // {
+ // Dwarf_Unsigned udata = 0;
+
+ // strcpy(formName, "DW_FORM_block2");
+
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned short data = (unsigned short)udata;
+ // sprintf(value, "%d", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_block4:
+ // {
+ // Dwarf_Unsigned udata = 0;
+
+ // strcpy(formName, "DW_FORM_block4");
+
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in DW_FORM_block4. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned int data = (unsigned int)udata;
+ // sprintf(value, "%d", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_data2:
+ // {
+ // Dwarf_Unsigned udata = 0;
+
+ // strcpy(formName, "DW_FORM_data2");
+
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in DW_FORM_data2. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned short int data = (unsigned short int)udata;
+ // sprintf(value, "%d", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_data4:
+ // {
+ // Dwarf_Unsigned udata = 0;
+
+ // strcpy(formName, "DW_FORM_data4");
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned int data = (unsigned int)udata;
+ // sprintf(value, "%d", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_data8:
+ // {
+ // Dwarf_Unsigned udata = 0;
+
+ // strcpy(formName, "DW_FORM_data8");
+
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // sprintf(value, "%d", udata);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_string:
+ // {
+ // char *str = 0;
+
+ // strcpy(formName, "DW_FORM_string");
+
+ // res = dwarf_formstring(attribs[i], &str, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // sprintf(value, "%s", str);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_block:
+ // strcpy(formName, "DW_FORM_block");
+ // break;
+
+ // case DW_FORM_block1:
+ // {
+ // Dwarf_Block *bdata = 0;
+ // strcpy(formName, "DW_FORM_block1");
+
+ // res = dwarf_formblock(attribs[i], &bdata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formblock. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // sprintf(value, "len: %d", bdata->bl_len);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_data1:
+ // {
+ // Dwarf_Unsigned udata = 0;
+ // strcpy(formName, "DW_FORM_data1");
+
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // uint8_t data = (uint8_t)udata;
+ // sprintf(value, "%u", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_flag:
+ // {
+ // Dwarf_Bool dwarfBool = false;
+ // strcpy(formName, "DW_FORM_flag");
+ // char *strp = 0;
+
+ // res = dwarf_formflag(attribs[i], &dwarfBool, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in DW_FORM_flag. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // if (dwarfBool)
+ // {
+ // sprintf(value, "TRUE");
+ // }
+ // else
+ // {
+ // sprintf(value, "FALSE");
+ // }
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_sdata:
+ // {
+ // Dwarf_Signed sdata = 0;
+
+ // strcpy(formName, "DW_FORM_sdata");
+
+ // res = dwarf_formsdata(attribs[i], &sdata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // sprintf(value, "%lli", sdata);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_strp:
+ // {
+ // char *strp = 0;
+
+ // strcpy(formName, "DW_FORM_strp");
+
+ // res = dwarf_formstring(attribs[i], &strp, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // char *text = dwarfStringToChar(strp);
+ // sprintf(value, "%s", text);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_udata:
+ // {
+ // Dwarf_Unsigned udata = 0;
+
+ // strcpy(formName, "DW_FORM_udata");
+
+ // res = dwarf_formudata(attribs[i], &udata, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // sprintf(value, "%llu", udata);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_ref_addr:
+ // strcpy(formName, "DW_FORM_ref_addr");
+ // break;
+
+ // case DW_FORM_ref1:
+ // {
+ // Dwarf_Off ref = 0;
+
+ // strcpy(formName, "DW_FORM_ref1");
+ // res = dwarf_formref(attribs[i], &ref, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // uint8_t data = (uint8_t)ref;
+ // sprintf(value, "%u", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_ref2:
+ // {
+ // Dwarf_Off ref = 0;
+
+ // strcpy(formName, "DW_FORM_ref1");
+ // res = dwarf_formref(attribs[i], &ref, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned short int data = (unsigned short int)ref;
+ // sprintf(value, "%u", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_ref4:
+ // {
+ // Dwarf_Off ref = 0;
+
+ // strcpy(formName, "DW_FORM_ref1");
+ // res = dwarf_formref(attribs[i], &ref, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // unsigned int data = (unsigned int)ref;
+ // sprintf(value, "%u", data);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_ref8:
+ // {
+ // Dwarf_Off ref = 0;
+
+ // strcpy(formName, "DW_FORM_ref1");
+ // res = dwarf_formref(attribs[i], &ref, &error);
+ // if (res != DW_DLV_OK)
+ // {
+ // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // dwarf_errmsg(error));
+ // }
+ // else
+ // {
+ // sprintf(value, "%llu", ref);
+ // }
+
+ // break;
+ // }
+
+ // case DW_FORM_ref_udata:
+ // strcpy(formName, "DW_FORM_ref_udata");
+ // break;
+
+ // case DW_FORM_indirect:
+ // strcpy(formName, "DW_FORM_indirect");
+ // break;
+
+ // case DW_FORM_sec_offset:
+ // strcpy(formName, "DW_FORM_sec_offset");
+ // break;
+
+ // case DW_FORM_exprloc:
+ // strcpy(formName, "DW_FORM_exprloc");
+ // break;
+
+ // case DW_FORM_flag_present:
+ // strcpy(formName, "DW_FORM_flag_present");
+ // break;
+
+ // case DW_FORM_strx:
+ // strcpy(formName, "DW_FORM_strx");
+ // break;
+
+ // case DW_FORM_addrx:
+ // strcpy(formName, "DW_FORM_addrx");
+ // break;
+
+ // case DW_FORM_ref_sup4:
+ // strcpy(formName, "DW_FORM_ref_sup4");
+ // break;
+
+ // case DW_FORM_strp_sup:
+ // strcpy(formName, "DW_FORM_strp_sup");
+ // break;
+
+ // case DW_FORM_data16:
+ // strcpy(formName, "DW_FORM_data16");
+ // break;
+
+ // case DW_FORM_line_strp:
+ // strcpy(formName, "DW_FORM_line_strp");
+ // break;
+
+ // case DW_FORM_ref_sig8:
+ // strcpy(formName, "DW_FORM_ref_sig8");
+ // break;
+
+ // case DW_FORM_implicit_const:
+ // strcpy(formName, "DW_FORM_implicit_const");
+ // break;
+
+ // case DW_FORM_loclistx:
+ // strcpy(formName, "DW_FORM_loclistx");
+ // break;
+
+ // case DW_FORM_rnglistx:
+ // strcpy(formName, "DW_FORM_rnglistx");
+ // break;
+
+ // case DW_FORM_ref_sup8:
+ // strcpy(formName, "DW_FORM_ref_sup8");
+ // break;
+
+ // case DW_FORM_strx1:
+ // strcpy(formName, "DW_FORM_strx1");
+ // break;
+
+ // case DW_FORM_strx2:
+ // strcpy(formName, "DW_FORM_strx2");
+ // break;
+
+ // case DW_FORM_strx3:
+ // strcpy(formName, "DW_FORM_strx3");
+ // break;
+
+ // case DW_FORM_strx4:
+ // strcpy(formName, "DW_FORM_strx4");
+ // break;
+
+ // case DW_FORM_addrx1:
+ // strcpy(formName, "DW_FORM_addrx1");
+ // break;
+
+ // case DW_FORM_addrx2:
+ // strcpy(formName, "DW_FORM_addrx2");
+ // break;
+
+ // case DW_FORM_addrx3:
+ // strcpy(formName, "DW_FORM_addrx3");
+ // break;
+
+ // case DW_FORM_addrx4:
+ // strcpy(formName, "DW_FORM_addrx4");
+ // break;
+
+ // case DW_FORM_GNU_addr_index:
+ // strcpy(formName, "DW_FORM_GNU_addr_index");
+ // break;
+
+ // case DW_FORM_GNU_str_index:
+ // strcpy(formName, "DW_FORM_GNU_str_index");
+ // break;
+
+ // case DW_FORM_GNU_ref_alt:
+ // strcpy(formName, "DW_FORM_GNU_ref_alt");
+ // break;
+
+ // case DW_FORM_GNU_strp_alt:
+ // strcpy(formName, "DW_FORM_GNU_strp_alt");
+ // break;
+
+ // default:
+ // sprintf(formName, "UNKNOWN (%x)", formID);
+ // break;
+ // }
+ // }
+ // }
+ // }
+
+ // sprintf(line, " %-20s : %-20s (%s)\n", attribName, value, formName);
+ // strcat(output, line);
+ // }
+ // }
+ // }
+
+ // // res = dwarf_attr(inDie, DW_AT_name, &attr_struct, &error);
+ // // if(res == DW_DLV_OK)
+ // // {
+ // // res = dwarf_formstring(attr_struct, &dieName, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // sprintf(line, " DW_AT_name : %s", dieName);
+ // // strcpy(output, line);
+ // // }
+ // // }
+ // //
+ // // res = dwarf_die_abbrev_children_flag(inDie, &hasChildrenFlag);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_die_abbrev_children_flag. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+
+ // // else
+ // // {
+ // // logger.logDebug(" Has children: %s", hasChildrenFlag ? "True" : "False");
+ // // }
+ // //
+ // // int dwarf_die_abbrev_children_flag(Dwarf_Die /*die*/,
+ // // Dwarf_Half * /*ab_has_child*/);
+ // //
+ // // res = dwarf_attrlist(inDie, &attribs, &attribCount, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_attrlist. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // if(attribCount > 0)
+ // // {
+ // // logger.logDebug(" Attributes:");
+ // // for(uint32_t i = 0; i < attribCount; ++i)
+ // // {
+ // // Dwarf_Half attrNum;
+ // // res = dwarf_whatattr(attribs[i], &attrNum, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // Dwarf_Half formID;
+ // //
+ // // switch(attrNum)
+ // // {
+ // // case DW_AT_sibling:
+ // // logger.logDebug(" DW_AT_sibling");
+ // // break;
+ // //
+ // // case DW_AT_location:
+ // // logger.logDebug(" DW_AT_location");
+ // // break;
+ // //
+ // // case DW_AT_name:
+ // // logger.logDebug(" DW_AT_name");
+ // // break;
+ // //
+ // // case DW_AT_ordering:
+ // // logger.logDebug(" DW_AT_ordering");
+ // // break;
+ // //
+ // // case DW_AT_subscr_data:
+ // // logger.logDebug(" DW_AT_subscr_data");
+ // // break;
+ // //
+ // // case DW_AT_byte_size:
+ // // logger.logDebug(" DW_AT_byte_size");
+ // // break;
+ // //
+ // // case DW_AT_decl_file:
+ // // logger.logDebug(" DW_AT_decl_file");
+ // // break;
+ // //
+ // // case DW_AT_decl_line:
+ // // logger.logDebug(" DW_AT_decl_line");
+ // // break;
+ // //
+ // // case DW_AT_type:
+ // // logger.logDebug(" DW_AT_type");
+ // // break;
+ // //
+ // // default:
+ // // logger.logDebug(" 0x%02x", attrNum);
+ // // break;
+ // // }
+ // //
+ // // res = dwarf_whatform(attribs[i], &attrNum, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_whatattr. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // res = dwarf_whatform(attribs[i], &formID, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_whatform. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // switch(formID)
+ // // {
+ // // case DW_FORM_addr:
+ // // logger.logDebug(":DW_FORM_addr");
+ // // break;
+ // //
+ // // case DW_FORM_block2:
+ // // logger.logDebug(":DW_FORM_block2");
+ // // break;
+ // //
+ // // case DW_FORM_block4:
+ // // logger.logDebug(":DW_FORM_block4");
+ // // break;
+ // //
+ // // case DW_FORM_data1:
+ // // {
+ // // Dwarf_Unsigned udata = 0;
+ // // res = dwarf_formudata(attribs[i], &udata, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // char data = (char) udata;
+ // // logger.logDebug(":DW_FORM_data1:%u", data);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_data2:
+ // // {
+ // // Dwarf_Unsigned udata = 0;
+ // // res = dwarf_formudata(attribs[i], &udata, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // unsigned short data = (unsigned short) udata;
+ // // logger.logDebug(":DW_FORM_data2:%u", data);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_data4:
+ // // {
+ // // Dwarf_Unsigned udata = 0;
+ // // res = dwarf_formudata(attribs[i], &udata, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // unsigned int data = (unsigned int) udata;
+ // // logger.logDebug(":DW_FORM_data4:%u", data);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_data8:
+ // // {
+ // // Dwarf_Unsigned udata = 0;
+ // // res = dwarf_formudata(attribs[i], &udata, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // logger.logDebug(":DW_FORM_data8:%llu", udata);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_string:
+ // // {
+ // // char *str = 0;
+ // // res = dwarf_formstring(attribs[i], &str, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // logger.logDebug(":DW_FORM_string:%s", str);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_block:
+ // // logger.logDebug(":DW_FORM_block");
+ // // break;
+ // //
+ // // case DW_FORM_sdata:
+ // // logger.logDebug(":DW_FORM_sdata");
+ // // break;
+ // //
+ // // case DW_FORM_strp:
+ // // {
+ // // char *strp = 0;
+ // // res = dwarf_formstring(attribs[i], &strp, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // char *text = dwarfStringToChar(strp);
+ // // logger.logDebug(":DW_FORM_strp:%s", text);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_udata:
+ // // {
+ // // Dwarf_Unsigned udata = 0;
+ // // res = dwarf_formudata(attribs[i], &udata, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // logger.logDebug(":DW_FORM_udata:%llu", udata);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_ref_addr:
+ // // logger.logDebug(":DW_FORM_ref_addr");
+ // // break;
+ // //
+ // // case DW_FORM_ref1:
+ // // {
+ // // Dwarf_Off ref = 0;
+ // // res = dwarf_formref(attribs[i], &ref, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formudata. line=%u errno=%u %s", __LINE__, dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // char data = (char) ref;
+ // // logger.logDebug(":DW_FORM_ref1:%u", data);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_ref2:
+ // // {
+ // // Dwarf_Off ref = 0;
+ // // res = dwarf_formref(attribs[i], &ref, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // unsigned short int data = (unsigned short int) ref;
+ // // logger.logDebug(":DW_FORM_ref2:%u", data);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_ref4:
+ // // {
+ // // Dwarf_Off ref = 0;
+ // // res = dwarf_formref(attribs[i], &ref, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // unsigned int data = (unsigned int) ref;
+ // // logger.logDebug(":DW_FORM_ref4:%u", data);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_ref8:
+ // // {
+ // // Dwarf_Off ref = 0;
+ // // res = dwarf_formref(attribs[i], &ref, &error);
+ // // if(res != DW_DLV_OK)
+ // // {
+ // // logger.logError("Error in dwarf_formref. errno=%u %s", dwarf_errno(error),
+ // // dwarf_errmsg(error));
+ // // }
+ // // else
+ // // {
+ // // logger.logDebug(":DW_FORM_ref4:%llu", ref);
+ // // }
+ // // break;
+ // // }
+ // //
+ // // case DW_FORM_ref_udata:
+ // // logger.logDebug(":DW_FORM_ref_udata");
+ // // break;
+ // //
+ // // case DW_FORM_indirect:
+ // // logger.logDebug(":DW_FORM_indirect");
+ // // break;
+ // //
+ // // case DW_FORM_sec_offset:
+ // // logger.logDebug(":DW_FORM_sec_offset");
+ // // break;
+ // //
+ // // case DW_FORM_exprloc:
+ // // logger.logDebug(":DW_FORM_exprloc");
+ // // break;
+ // //
+ // // case DW_FORM_flag_present:
+ // // logger.logDebug(":DW_FORM_flag_present");
+ // // break;
+ // //
+ // // case DW_FORM_ref_sig8:
+ // // logger.logDebug(":DW_FORM_ref_sig8");
+ // // break;
+ // //
+ // // default:
+ // // logger.logDebug(":0x%02x", formID);
+ // // break;
+ // //
+ // // }
+ // // }
+ // // }
+ // // }
+ // // }
+ // // logger.logDebug("\n");
+ // // }
+ // // }
+
+ // logger.logDebug(output);
+ // }
}
Symbol *Juicer::process_DW_TAG_base_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Die inDie)
@@ -3226,10 +3113,11 @@ Symbol *Juicer::process_DW_TAG_base_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Di
Dwarf_Attribute attr_struct;
Symbol *outSymbol = nullptr;
std::string cName;
- Dwarf_Error error = 0;
+ Dwarf_Error error = 0;
+ Dwarf_Signed encodingValue = -1;
/* Get the name attribute of this Die. */
- res = dwarf_attr(inDie, DW_AT_name, &attr_struct, &error);
+ res = dwarf_attr(inDie, DW_AT_name, &attr_struct, &error);
if (res != DW_DLV_OK)
{
logger.logError("Error in dwarf_attr(DW_AT_name). %u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error));
@@ -3256,6 +3144,21 @@ Symbol *Juicer::process_DW_TAG_base_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Di
cName = dieName;
}
+ res = dwarf_attr(inDie, DW_AT_encoding, &attr_struct, &error);
+ if (res != DW_DLV_OK)
+ {
+ logger.logError("Error in dwarf_attr(DW_AT_name). %u errno=%u %s", __LINE__, dwarf_errno(error), dwarf_errmsg(error));
+ }
+
+ if (res == DW_DLV_OK)
+ {
+ res = dwarf_formsdata(attr_struct, &encodingValue, &error);
+ if (res != DW_DLV_OK)
+ {
+ logger.logError("Error in dwarf_formstring. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
+ }
+ }
+
outSymbol = elf.getSymbol(cName);
if (outSymbol == 0)
@@ -3316,7 +3219,16 @@ Symbol *Juicer::process_DW_TAG_base_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Di
if (pathIndex != 0)
{
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
+ /**
+ * Why we are checking against 0 as per DWARF section 2.14:
+ *
+ * The value of the DW_AT_decl_file attribute corresponds to a file number from the line number
+ * information table for the compilation unit containing the debugging information entry and
+ * represents the source file in which the declaration appeared (see Section 6.2 ). The value 0
+ * indicates that no source file has been specified.
+ *
+ */
+ Artifact newArtifact{elf, getdbgSourceFile(elf, pathIndex)};
std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
newArtifact.setMD5(checkSum);
outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact);
@@ -3342,6 +3254,7 @@ Symbol *Juicer::process_DW_TAG_base_type(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Di
}
}
}
+ outSymbol->setEncoding(encodingValue);
}
}
@@ -3355,6 +3268,7 @@ void Juicer::process_DW_TAG_enumeration_type(ElfFile &elf, Symbol &symbol, Dwarf
Dwarf_Die enumeratorDie = 0;
Dwarf_Signed encodingValue;
Dwarf_Error error = 0;
+ std::string symbolEncoding{};
/* Get the fields by getting the first child. */
if (res == DW_DLV_OK)
@@ -3446,13 +3360,15 @@ void Juicer::process_DW_TAG_enumeration_type(ElfFile &elf, Symbol &symbol, Dwarf
{
case DW_ATE_signed:
{
- res = dwarf_formsdata(attr_struct, &enumeratorValue, &error);
+ res = dwarf_formsdata(attr_struct, &enumeratorValue, &error);
+ symbolEncoding = "DW_ATE_signed";
break;
}
case DW_ATE_unsigned:
{
- res = dwarf_formudata(attr_struct, (Dwarf_Unsigned *)&enumeratorValue, &error);
+ res = dwarf_formudata(attr_struct, (Dwarf_Unsigned *)&enumeratorValue, &error);
+ symbolEncoding = "DW_ATE_unsigned";
break;
}
default:
@@ -3474,6 +3390,7 @@ void Juicer::process_DW_TAG_enumeration_type(ElfFile &elf, Symbol &symbol, Dwarf
Dwarf_Die siblingDie = 0;
symbol.addEnumeration(sEnumeratorName, enumeratorValue);
+ symbol.setEncoding(encodingValue);
res = dwarf_siblingof(dbg, enumeratorDie, &siblingDie, &error);
if (res == DW_DLV_ERROR)
@@ -3545,6 +3462,10 @@ Symbol *Juicer::process_DW_TAG_typedef(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Die
/* Set the error code so we don't do anymore processing. */
res = DW_DLV_ERROR;
}
+ else
+ {
+ // FIXME:Handle else case
+ }
}
/* Get the size of this datatype. */
@@ -3588,17 +3509,26 @@ Symbol *Juicer::process_DW_TAG_typedef(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Die
if (pathIndex != 0)
{
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
+ /**
+ * Why we are checking against 0 as per DWARF section 2.14:
+ *
+ * The value of the DW_AT_decl_file attribute corresponds to a file number from the line number
+ * information table for the compilation unit containing the debugging information entry and
+ * represents the source file in which the declaration appeared (see Section 6.2 ). The value 0
+ * indicates that no source file has been specified.
+ *
+ */
+ Artifact newArtifact{elf, getdbgSourceFile(elf, pathIndex)};
std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
newArtifact.setMD5(checkSum);
- outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact);
+ outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact, baseTypeSymbol);
}
else
{
Artifact newArtifact{elf, "NOT_FOUND:" + sDieName};
std::string checkSum{};
newArtifact.setMD5(checkSum);
- outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact);
+ outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact, baseTypeSymbol);
}
}
}
@@ -4038,14 +3968,7 @@ void Juicer::addBitFields(Dwarf_Die dataMemberDie, Field &dataMemberField)
Dwarf_Unsigned bit_size = 0;
Dwarf_Error error = 0;
- res = dwarf_attr(dataMemberDie, DW_AT_data_bit_offset, &attr_struct, &error);
-
- if (DW_DLV_OK == res)
- {
- res = dwarf_formudata(attr_struct, &bit_offset, &error);
- }
-
- res = dwarf_attr(dataMemberDie, DW_AT_bit_size, &attr_struct, &error);
+ res = dwarf_attr(dataMemberDie, DW_AT_bit_size, &attr_struct, &error);
if (DW_DLV_OK == res)
{
@@ -4077,13 +4000,13 @@ void Juicer::addBitFields(Dwarf_Die dataMemberDie, Field &dataMemberField)
*/
bool Juicer::isDWARFVersionSupported(Dwarf_Die inDie)
{
- bool isSupported = true;
+ bool isSupported = true;
- Dwarf_Half dwarfVersion = 0;
+ dwarfVersion = 0;
- Dwarf_Half dwarfOffset = 0;
+ Dwarf_Half dwarfOffset = 0;
- int rec = dwarf_get_version_of_die(inDie, &dwarfVersion, &dwarfOffset);
+ int rec = dwarf_get_version_of_die(inDie, &dwarfVersion, &dwarfOffset);
if (rec != DW_DLV_OK)
{
@@ -4217,7 +4140,16 @@ int Juicer::getDieAndSiblings(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Die in_die, i
if (pathIndex != 0)
{
- Artifact newArtifact{elf, dbgSourceFiles.at(pathIndex - 1)};
+ /**
+ * Why we are checking against 0 as per DWARF section 2.14:
+ *
+ * The value of the DW_AT_decl_file attribute corresponds to a file number from the line number
+ * information table for the compilation unit containing the debugging information entry and
+ * represents the source file in which the declaration appeared (see Section 6.2 ). The value 0
+ * indicates that no source file has been specified.
+ *
+ */
+ Artifact newArtifact{elf, getdbgSourceFile(elf, pathIndex)};
std::string checkSum = generateMD5SumForFile(newArtifact.getFilePath());
newArtifact.setMD5(checkSum);
outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact);
@@ -4230,6 +4162,13 @@ int Juicer::getDieAndSiblings(ElfFile &elf, Dwarf_Debug dbg, Dwarf_Die in_die, i
outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact);
}
}
+ else
+ {
+ Artifact newArtifact{elf, "NOT_FOUND:" + sDieName};
+ std::string checkSum{};
+ newArtifact.setMD5(checkSum);
+ outSymbol = elf.addSymbol(sDieName, byteSize, newArtifact);
+ }
process_DW_TAG_structure_type(elf, *outSymbol, dbg, cur_die);
}
@@ -4338,11 +4277,6 @@ int Juicer::printDieData(Dwarf_Debug dbg, Dwarf_Die print_me, uint32_t level)
/* Do nothing */
}
- if (strcmp(name, "CFE_SB_TlmHdr_t") == 0)
- {
- printf("hello\n");
- }
-
if (tag != DW_TAG_structure_type)
{
res = dwarf_tag(print_me, &tag, &error);
@@ -4422,42 +4356,337 @@ std::map> Juicer::getObjDataFromElf(ElfFile *e
if (buffer[EI_CLASS] == ELFCLASS64)
{
- size_t elfSectionCount = -1;
- int res = elf_getshdrnum(elf, &elfSectionCount);
-
- for (size_t i = 0; i < elfSectionCount; i++)
+ elfFileObj->setElfClass(ELFCLASS64);
{
- Elf_Scn *section = elf_getscn(elf, i);
- std::cout << "section" << section << std::endl;
- }
- std::cout << "res:" << res << std::endl;
+ if (elf != NULL)
+ {
+ elf_hdr_64 = elf64_getehdr(elf);
+ size_t elfSectionCount = 0;
+ int res = elf_getshdrnum(elf, &elfSectionCount);
- if (elf != NULL)
- {
- elf_hdr_64 = elf64_getehdr(elf);
+ logger.logInfo("Found %d elf sections", elfSectionCount);
- ident_buffer = elf_hdr_64->e_ident;
- if (ident_buffer[EI_DATA] == ELFDATA2LSB)
- {
- rc = JUICER_ENDIAN_LITTLE;
- }
- else if (ident_buffer[EI_DATA] == ELFDATA2MSB)
- {
- rc = JUICER_ENDIAN_BIG;
+ for (size_t i = 0; i < elfSectionCount; i++)
+ {
+ Elf_Scn *section = elf_getscn(elf, i);
+
+ Elf64_Shdr *sectionHeader = elf64_getshdr(section);
+
+ elfFileObj->addElf64SectionHeader(*sectionHeader);
+
+ Elf32_Word sectionSize = sectionHeader->sh_size;
+ Elf32_Word sectionTableEntrySize = sectionHeader->sh_entsize; /*Only relevant for tables such as SHT_SYMTAB*/
+
+ switch (sectionHeader->sh_type)
+ {
+ case SHT_NULL:
+ {
+ logger.logWarning("Section SHT_NULL(%d) not supported.", SHT_NULL);
+ break;
+ }
+ case SHT_PROGBITS:
+ {
+ logger.logWarning("Section SHT_PROGBITS(%d) not supported.", SHT_PROGBITS);
+ break;
+ }
+ case SHT_SYMTAB:
+ {
+ logger.logInfo("Extracting SHT_SYMTAB(%d) at index(%d).", SHT_SYMTAB, i);
+ logger.logInfo("Section Size:%d", sectionSize);
+ logger.logInfo("Section Table Entry Size:%d", sectionTableEntrySize);
+
+ Elf64_Word sectionSize = sectionHeader->sh_size;
+ Elf64_Word sectionTableEntrySize = sectionHeader->sh_entsize; /*Only relevant for tables such as SHT_SYMTAB*/
+
+ int numberOfSymbols = sectionSize / sectionTableEntrySize;
+
+ logger.logInfo("Found %d symbols in Elf", numberOfSymbols);
+
+ Elf_Data *elfData = nullptr;
+ elfData = elf_getdata(section, elfData);
+ if (elfData != nullptr)
+ {
+ logger.logInfo("elfData Size:%d", elfData->d_size);
+
+ Elf64_Sym *sectionTableData = (Elf64_Sym *)elfData->d_buf;
+
+ size_t strTableIndex = sectionHeader->sh_link;
+ logger.logInfo("String table index for symbols:%d", strTableIndex);
+ for (int i = 0; i < numberOfSymbols; i++)
+ {
+ Elf64_Sym *symbol = sectionTableData;
+
+ uint32_t symbolSectionFileOffset = 0;
+ uint32_t symbolSectionStrTableFileOffset = 0;
+
+ if (symbol->st_size > 0)
+ {
+ if (symbol->st_shndx == SHN_COMMON)
+ {
+ logger.logWarning("Ignoring symbol since it has SHN_COMMON as its st_shndx");
+ }
+ else
+ {
+ Elf_Scn *stringTableSection = elf_getscn(elf, strTableIndex);
+ Elf64_Shdr *stringTableSectionHeader = elf64_getshdr(stringTableSection);
+
+ Elf64_Xword stringTableSectionHeaderSectionSize = stringTableSectionHeader->sh_size;
+
+ if (symbol->st_name > 0)
+ {
+ char *currentStrTblPtr = elf_strptr(elf, strTableIndex, symbol->st_name);
+
+ if (currentStrTblPtr != nullptr)
+ {
+ int stringTableCursor = 0;
+ std::string name{};
+ while (currentStrTblPtr[stringTableCursor] != '\0')
+ {
+ name.push_back(currentStrTblPtr[stringTableCursor]);
+ stringTableCursor++;
+ }
+
+ logger.logInfo(
+ "Found symbol %s with size: %d, st_value:%u, st_name:%u, st_info:%u, st_other:%u, st_shndx:%u\n",
+ name.c_str(), symbol->st_size, symbol->st_value, symbol->st_name, symbol->st_info, symbol->st_other,
+ symbol->st_shndx);
+
+ symbolSectionStrTableFileOffset = stringTableSectionHeader->sh_offset;
+
+ // TODO:Map it to DWARF here.
+ Elf_Scn *symbolSectionData = elf_getscn(elf, symbol->st_shndx);
+
+ Elf64_Shdr *symbolSectionHeader = elf64_getshdr(symbolSectionData);
+
+ if (symbolSectionHeader != nullptr)
+ {
+ // std::cout << "symbol data section file offset-->"
+ // << symbolSectionHeader->sh_offset << std::endl;
+ symbolSectionFileOffset = symbolSectionHeader->sh_offset;
+ }
+
+ Elf_Data *symbolSectionDataContents = nullptr;
+
+ symbolSectionDataContents = elf_getdata(symbolSectionData, symbolSectionDataContents);
+
+ if (symbolSectionDataContents->d_type == ELF_T_BYTE)
+ {
+ uint8_t *symbolDataCursor = (uint8_t *)symbolSectionDataContents->d_buf;
+
+ std::vector symbolData = std::vector();
+
+ if (symbolDataCursor != nullptr)
+ {
+ for (int i = symbol->st_value; i < symbol->st_size; i++)
+ {
+ symbolData.push_back(symbolDataCursor[i]);
+ }
+ }
+ else
+ {
+ logger.logWarning("Did not find size for symbol \"%d\"", name);
+ }
+
+ symbolToData.insert({name, symbolData});
+ }
+ else
+ {
+ logger.logWarning("Symbol %s ignored since ELF_T_BYTE was NOT found. Found %d type instead.",
+ name.c_str(), symbolSectionDataContents->d_type);
+ }
+ }
+ }
+ }
+ }
+
+ elfFileObj->addElf64SymbolTableSymbol(Elf64Symbol{*symbol, symbolSectionFileOffset, symbolSectionStrTableFileOffset});
+ sectionTableData++;
+ }
+ }
+
+ break;
+ }
+ case SHT_STRTAB:
+ {
+ logger.logWarning("Extracting SHT_STRTAB(%d) from section #%d.", SHT_STRTAB, i);
+ break;
+ }
+ case SHT_RELA:
+ {
+ logger.logWarning("Section SHT_RELA(%d) not supported.", SHT_RELA);
+ break;
+ }
+ case SHT_HASH:
+ {
+ logger.logWarning("Section SHT_HASH(%d) not supported.", SHT_HASH);
+ break;
+ }
+ case SHT_DYNAMIC:
+ {
+ logger.logWarning("Section %d not supported.", SHT_DYNAMIC);
+ break;
+ }
+ case SHT_NOTE:
+ {
+ logger.logWarning("Section SHT_NOTE(%d) not supported.", SHT_NOTE);
+ break;
+ }
+ case SHT_NOBITS:
+ {
+ logger.logWarning("Section SHT_NOBITS(%d) not supported.", SHT_NOBITS);
+ break;
+ }
+ case SHT_REL:
+ {
+ logger.logWarning("Section SHT_REL(%d) not supported.", SHT_REL);
+ break;
+ }
+ case SHT_SHLIB:
+ {
+ logger.logWarning("Section SHT_SHLIB(%d) not supported.", SHT_SHLIB);
+ break;
+ }
+ case SHT_DYNSYM:
+ {
+ logger.logWarning("Section SHT_DYNSYM(%d) not supported.", SHT_DYNSYM);
+ break;
+ }
+ case SHT_INIT_ARRAY:
+ {
+ logger.logWarning("Section SHT_INIT_ARRAY(%d) not supported.", SHT_INIT_ARRAY);
+ break;
+ }
+ case SHT_FINI_ARRAY:
+ {
+ logger.logWarning("Section SHT_FINI_ARRAY(%d) not supported.", SHT_FINI_ARRAY);
+ break;
+ }
+ case SHT_PREINIT_ARRAY:
+ {
+ logger.logWarning("Section SHT_PREINIT_ARRAY(%d) not supported.", SHT_PREINIT_ARRAY);
+ break;
+ }
+ case SHT_GROUP:
+ {
+ logger.logWarning("Section SHT_GROUP(%d) not supported.", SHT_GROUP);
+ break;
+ }
+ case SHT_SYMTAB_SHNDX:
+ {
+ logger.logWarning("Section SHT_SYMTAB_SHNDX(%d) not supported.", SHT_SYMTAB_SHNDX);
+ break;
+ }
+ case SHT_NUM:
+ {
+ logger.logWarning("Section SHT_NUM(%d) not supported.", SHT_NUM);
+ break;
+ }
+ case SHT_LOOS:
+ {
+ logger.logWarning("Section SHT_LOOS(%d) not supported.", SHT_LOOS);
+ break;
+ }
+ case SHT_GNU_ATTRIBUTES:
+ {
+ logger.logWarning("Section SHT_GNU_ATTRIBUTES(%d) not supported.", SHT_GNU_ATTRIBUTES);
+ break;
+ }
+ case SHT_GNU_HASH:
+ {
+ logger.logWarning("Section SHT_GNU_HASH(%d) not supported.", SHT_GNU_HASH);
+ break;
+ }
+ case SHT_GNU_LIBLIST:
+ {
+ logger.logWarning("Section %d not supported.", SHT_GNU_LIBLIST);
+ break;
+ }
+ case SHT_CHECKSUM:
+ {
+ logger.logWarning("Section %d not supported.", SHT_CHECKSUM);
+ break;
+ }
+ // case SHT_LOSUNW: SHT_LOSUNW and SHT_SUNW_move are the same value, for some reason.
+ case SHT_SUNW_move:
+ {
+ logger.logWarning("Section %d not supported.", SHT_SUNW_move);
+ break;
+ }
+ case SHT_SUNW_COMDAT:
+ {
+ logger.logWarning("Section %d not supported.", SHT_SUNW_COMDAT);
+ break;
+ }
+ case SHT_SUNW_syminfo:
+ {
+ logger.logWarning("Section %d not supported.", SHT_SUNW_syminfo);
+ break;
+ }
+ case SHT_GNU_verdef:
+ {
+ logger.logWarning("Section %d not supported.", SHT_GNU_verdef);
+ break;
+ }
+ case SHT_GNU_verneed:
+ {
+ logger.logWarning("Section %d not supported.", SHT_GNU_verneed);
+ break;
+ }
+
+ // case SHT_HISUNW: SHT_GNU_versym and SHT_HISUNW are the same value, for some reason.
+ case SHT_HIOS:
+ {
+ logger.logWarning("Section %d not supported.", SHT_HIOS);
+ break;
+ }
+ case SHT_LOPROC:
+ {
+ logger.logWarning("Section %d not supported.", SHT_LOPROC);
+ break;
+ }
+ case SHT_HIPROC:
+ {
+ logger.logWarning("Section %d not supported.", SHT_HIPROC);
+ break;
+ }
+ case SHT_LOUSER:
+ {
+ logger.logWarning("Section %d not supported.", SHT_LOUSER);
+ break;
+ }
+ case SHT_HIUSER:
+ {
+ logger.logWarning("Section %d not supported.", SHT_HIUSER);
+ break;
+ }
+ }
+ }
+
+ ident_buffer = elf_hdr_64->e_ident;
+
+ if (ident_buffer[EI_DATA] == ELFDATA2LSB)
+ {
+ rc = JUICER_ENDIAN_LITTLE;
+ }
+ else if (ident_buffer[EI_DATA] == ELFDATA2MSB)
+ {
+ rc = JUICER_ENDIAN_BIG;
+ }
+ else
+ {
+ rc = JUICER_ENDIAN_UNKNOWN;
+ }
+ elf_end(elf);
}
else
{
- rc = JUICER_ENDIAN_UNKNOWN;
+ logger.logError("elf_begin failed. errno=%d %s", errno, strerror(errno));
}
- elf_end(elf);
- }
- else
- {
- logger.logError("elf_begin failed. errno=%d %s", errno, strerror(errno));
}
}
else if (buffer[EI_CLASS] == ELFCLASS32)
{
+ elfFileObj->setElfClass(ELFCLASS32);
if (elf != NULL)
{
elf_hdr_32 = elf32_getehdr(elf);
@@ -4550,8 +4779,6 @@ std::map> Juicer::getObjDataFromElf(ElfFile *e
name.c_str(), symbol->st_size, symbol->st_value, symbol->st_name, symbol->st_info,
symbol->st_other, symbol->st_shndx);
- std::cout << "stringTableSectionHeader file offset:" << stringTableSectionHeader->sh_offset << std::endl;
-
symbolSectionStrTableFileOffset = stringTableSectionHeader->sh_offset;
// TODO:Map it to DWARF here.
@@ -4561,8 +4788,6 @@ std::map> Juicer::getObjDataFromElf(ElfFile *e
if (symbolSectionHeader != nullptr)
{
- // std::cout << "symbol data section file offset-->" <<
- // symbolSectionHeader->sh_offset << std::endl;
symbolSectionFileOffset = symbolSectionHeader->sh_offset;
}
@@ -4575,8 +4800,6 @@ std::map> Juicer::getObjDataFromElf(ElfFile *e
uint8_t *symbolDataCursor = (uint8_t *)symbolSectionDataContents->d_buf;
std::vector symbolData = std::vector();
- std::cout << "ELF32_ST_TYPE:" << ELF32_ST_TYPE(symbol->st_info) << std::endl;
- std::cout << "ELF32_ST_BIND:" << ELF32_ST_BIND(symbol->st_info) << std::endl;
if (symbolDataCursor != nullptr)
{
@@ -4763,11 +4986,7 @@ std::map> Juicer::getObjDataFromElf(ElfFile *e
break;
}
}
-
- // std::cout << "sh_type" << sectionHeader->sh_type << std::endl;
}
- std::cout << "res:" << res << std::endl;
-
ident_buffer = elf_hdr_32->e_ident;
if (ident_buffer[EI_DATA] == ELFDATA2LSB)
@@ -4930,7 +5149,8 @@ int Juicer::parse(std::string &elfFilePath)
if (JUICER_OK == return_value)
{
/* Initialize the Dwarf library. This will open the file. */
- dwarf_value = dwarf_init(elfFile, DW_DLC_READ, errhand, errarg, &dbg, &error);
+ /* Initialize the Dwarf library. This will open the file. */
+ dwarf_value = dwarf_init_b(elfFile, DW_DLC_READ, groupNumber, errhand, errarg, &dbg, &error);
if (dwarf_value != DW_DLV_OK)
{
logger.logError("Failed to read the dwarf");
@@ -5062,26 +5282,6 @@ uint32_t Juicer::calcArraySizeForDimension(Dwarf_Debug dbg, Dwarf_Die dieSubrang
return dimSize;
}
-/**
- *
- * @return The number of elements in the die array entry, including all dimensions. It is assumed that die is of type
- * DW_TAG_array_type.
- */
-int Juicer::calcArraySizeForAllDims(Dwarf_Debug dbg, Dwarf_Die die)
-{
- int arraySize = 0;
- std::vector children = getChildrenVector(dbg, die);
-
- for (auto child : children)
- {
- if (arraySize == 0) arraySize = 1;
-
- arraySize = arraySize * calcArraySizeForDimension(dbg, child);
- }
-
- return arraySize;
-}
-
/**
* Assuming that die is a DW_TAG_array_type, iterate through each DW_TAG_subrange_type and return
* a std::vector with all them as Dimension objects
@@ -5174,35 +5374,6 @@ int Juicer::getNumberOfSiblingsForDie(Dwarf_Debug dbg, Dwarf_Die die)
return siblingCount;
}
-
-std::vector Juicer::getSiblingsVector(Dwarf_Debug dbg, Dwarf_Die die)
-{
- int res = DW_DLV_OK;
- std::vector siblingList{};
-
- Dwarf_Die sibling_die;
-
- Dwarf_Error error = 0;
-
- int siblingCount = getNumberOfSiblingsForDie(dbg, die);
-
- for (int sibling = 0; sibling < siblingCount; sibling++)
- {
- res = dwarf_siblingof(dbg, die, &sibling_die, &error);
- if (res != DW_DLV_OK)
- {
- logger.logWarning("Error in dwarf_siblingof. errno=%u %s", dwarf_errno(error), dwarf_errmsg(error));
- }
- else
- {
- siblingList.push_back(sibling_die);
- die = sibling_die;
- }
- }
-
- return siblingList;
-}
-
/**
*@brief Get all of the children of the die in a nice STL vector.
*/
@@ -5283,3 +5454,32 @@ std::string Juicer::generateMD5SumForFile(std::string filePath)
auto md5 = hex.str();
return md5;
}
+
+/**
+ * handles debug source files lookups for different DWARF versions.
+ * It is assumed the pathIndex is the value of DW_AT_decl_file attribute
+ */
+std::string &Juicer::getdbgSourceFile(ElfFile &elf, int pathIndex)
+{
+ switch (dwarfVersion)
+ {
+ /**
+ *
+ * As per section 1.4 (Changes from Version 4 to Version 5) of DWARF5
+ *
+ * The line number table header is substantially revised.
+ **/
+
+ case 4:
+ {
+ return dbgSourceFiles.at(pathIndex - 1);
+ }
+ case 5:
+ {
+ return dbgSourceFiles.at(pathIndex);
+ }
+ }
+ return dbgSourceFiles.at(pathIndex);
+}
+
+unsigned int Juicer::getDwarfVersion() { return dwarfVersion; }
\ No newline at end of file
diff --git a/src/Juicer.h b/src/Juicer.h
index bef00721..0a4fece6 100644
--- a/src/Juicer.h
+++ b/src/Juicer.h
@@ -101,6 +101,10 @@ class Juicer
void setExtras(bool extras) { this->extras = extras; }
+ void setGroupNumber(unsigned int groupNumber) { this->groupNumber = groupNumber; };
+
+ unsigned int getDwarfVersion();
+
private:
Dwarf_Debug dbg = 0;
int res = DW_DLV_ERROR;
@@ -129,24 +133,26 @@ class Juicer
Symbol* getBaseTypeSymbol(ElfFile& elf, Dwarf_Die inDie, DimensionList& multiplicity);
void DisplayDie(Dwarf_Die inDie, uint32_t level);
- std::vector getSiblingsVector(Dwarf_Debug dbg, Dwarf_Die die);
std::vector getChildrenVector(Dwarf_Debug dbg, Dwarf_Die die);
int getNumberOfSiblingsForDie(Dwarf_Debug dbg, Dwarf_Die die);
uint32_t calcArraySizeForDimension(Dwarf_Debug dbg, Dwarf_Die die);
- int calcArraySizeForAllDims(Dwarf_Debug dbg, Dwarf_Die die);
DimensionList getDimList(Dwarf_Debug dbg, Dwarf_Die die);
std::vector dbgSourceFiles{};
std::string generateMD5SumForFile(std::string filePath);
+ std::string& getdbgSourceFile(ElfFile& elf, int pathIndex);
DefineMacro getDefineMacro(Dwarf_Half macro_operator, Dwarf_Macro_Context mac_context, int i, Dwarf_Unsigned line_number, Dwarf_Unsigned index,
Dwarf_Unsigned offset, const char* macro_string, Dwarf_Half& forms_count, Dwarf_Error& error, Dwarf_Die cu_die, ElfFile& elf);
DefineMacro getDefineMacroFromString(std::string macro_string);
std::map> getObjDataFromElf(ElfFile* elfFileObj);
bool extras;
+
+ unsigned int groupNumber{0};
+ Dwarf_Half dwarfVersion = 0;
};
#endif /* JUICER_H_ */
diff --git a/src/LoggerInstance.h b/src/LoggerInstance.h
index 86645865..8621d372 100644
--- a/src/LoggerInstance.h
+++ b/src/LoggerInstance.h
@@ -64,7 +64,7 @@ class LoggerInstance
void LogEvent(LoggerCriticality_t criticality, const std::string &message);
private:
- LoggerInstance(LoggerInstance const &){}; // copy constructor is private
+ LoggerInstance(LoggerInstance const &) {}; // copy constructor is private
LoggerInstance &operator=(LoggerInstance const &) { return *this; }; // assignment operator is private
static LoggerInstance *m_pInstance;
std::ofstream logFile;
diff --git a/src/SQLiteDB.cpp b/src/SQLiteDB.cpp
index 242a504d..f6aaabce 100644
--- a/src/SQLiteDB.cpp
+++ b/src/SQLiteDB.cpp
@@ -109,6 +109,32 @@ bool SQLiteDB::doesSymbolExist(std::string name)
return row_count == 0 ? false : true;
}
+bool SQLiteDB::doEncodingsExist()
+{
+ int32_t row_count = 0;
+
+ int rc = SQLITE_OK;
+
+ char* errorMessage = nullptr;
+
+ std::string countRowsQuery{"SELECT COUNT(*) FROM encodings"};
+ countRowsQuery += "";
+ countRowsQuery += ";";
+
+ rc = sqlite3_exec(database, countRowsQuery.c_str(), SQLiteDB::doesRowExistCallback, &row_count, &errorMessage);
+
+ if (SQLITE_OK != rc)
+ {
+ logger.logWarning(
+ "Looks like there was a problem sending query \"%s\" "
+ "to the database.",
+ countRowsQuery.c_str());
+ logger.logError("%s", errorMessage);
+ row_count = 0;
+ }
+ return row_count == 0 ? false : true;
+}
+
/**
*@brief Checks if the symbol called name exists on the symbols table.
*
@@ -302,6 +328,22 @@ int SQLiteDB::write(ElfFile& inElf)
rc = SQLITEDB_ERROR;
}
+ rc = writeEncodingsToDatabase(inElf);
+
+ if (SQLITEDB_ERROR != rc)
+ {
+ logger.logDebug(
+ "Variable entries were written to the variables schema "
+ "with SQLITE_OK status.");
+ }
+ else
+ {
+ logger.logDebug(
+ "There was an error while writing variable entries to the"
+ " database.");
+ rc = SQLITEDB_ERROR;
+ }
+
rc = writeSymbolsToDatabase(inElf);
if (SQLITEDB_ERROR != rc)
@@ -484,9 +526,7 @@ int SQLiteDB::writeElfToDatabase(ElfFile& inElf)
*/
int SQLiteDB::writeMacrosToDatabase(ElfFile& inElf)
{
- int rc = SQLITEDB_OK;
- char* errorMessage = NULL;
-
+ int rc = SQLITEDB_OK;
for (auto macro : inElf.getDefineMacros())
{
/*
@@ -494,40 +534,61 @@ int SQLiteDB::writeMacrosToDatabase(ElfFile& inElf)
* but I'm not sure what is the best way to do that without it being
* messy.
*/
- std::string writeMacroQuery{};
- writeMacroQuery +=
- "INSERT INTO macros(name, value) "
- "VALUES(\"";
- writeMacroQuery += macro.getName();
- writeMacroQuery += "\",";
- writeMacroQuery += "\"";
- writeMacroQuery += macro.getValue();
- writeMacroQuery += "\"";
- writeMacroQuery += ");";
+ // Create a SQL statement with placeholders
+ sqlite3_stmt* stmt;
+ const char* sql = "INSERT INTO macros (name, value) VALUES (?, ?);";
- logger.logDebug("Sending \"%s\" query to database.", writeMacroQuery.c_str());
+ // Prepare the SQL statement
+ rc = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);
- rc = sqlite3_exec(database, writeMacroQuery.c_str(), NULL, NULL, &errorMessage);
-
- if (SQLITE_OK == rc)
+ if (rc != SQLITE_OK)
{
- logger.logDebug(
- "Elf values were written to the macros schema with "
- "SQLITE_OK status.");
+ std::cerr << "SQL error: " << sqlite3_errmsg(database) << std::endl;
}
else
{
- if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ // Bind values to placeholders
+ sqlite3_bind_text(stmt, 1, macro.getName().c_str(), -1, SQLITE_STATIC);
+ sqlite3_bind_text(stmt, 2, macro.getValue().c_str(), -1, SQLITE_STATIC);
+
+ // Execute the SQL statement
+ if (sqlite3_step(stmt) != SQLITE_DONE)
{
- logger.logDebug("%s.", errorMessage);
- rc = SQLITE_OK;
+ const char* errorMessage = sqlite3_errmsg(database);
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Elf values were written to the macros schema with "
+ "SQLITE_OK status.");
+ }
+ else
+ {
+ if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ {
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITE_OK;
+ }
+ else
+ {
+ logger.logDebug("There was an error while writing data to the elfs table.");
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITEDB_ERROR;
+ }
+ }
+ }
+
+ // Finalize the statement
+ rc = sqlite3_finalize(stmt);
+ if (rc != SQLITE_OK)
+ {
+ logger.logDebug("There was an error while finalizing the sql statement for encodings table.");
}
else
{
- logger.logDebug("There was an error while writing data to the elfs table.");
- logger.logDebug("%s.", errorMessage);
- rc = SQLITEDB_ERROR;
+ // sqlite3_int64 lastRowId = sqlite3_last_insert_rowid(database);
+
+ // inElf.encodingsMap.at(encoding.first).setId(lastRowId);
}
}
}
@@ -552,11 +613,7 @@ int SQLiteDB::writeVariablesToDatabase(ElfFile& inElf)
for (auto variable : inElf.getVariables())
{
- // std::string symbolInitializedDataName = symbolDataPair.first;
- // std::vector symbolInitializedData = symbolDataPair.second;
-
inElf.getInitializedSymbolData();
- uint32_t typeID;
/*
* @todo I want to store these SQLite magical values into MACROS,
@@ -572,7 +629,7 @@ int SQLiteDB::writeVariablesToDatabase(ElfFile& inElf)
writeVariableQuery += variable.getName();
writeVariableQuery += "\"";
writeVariableQuery += ",";
- writeVariableQuery += std::to_string(inElf.getId());
+ writeVariableQuery += std::to_string(variable.getElf().getId());
writeVariableQuery += ",";
writeVariableQuery += std::to_string(variable.getType().getId());
@@ -585,7 +642,7 @@ int SQLiteDB::writeVariablesToDatabase(ElfFile& inElf)
writeVariableQuery += ",";
writeVariableQuery += "\"";
- writeVariableQuery += variable.getShortDescription();
+ writeVariableQuery += variable.getLongDescription();
writeVariableQuery += "\"";
writeVariableQuery += ");";
@@ -634,78 +691,153 @@ int SQLiteDB::writeElfSectionsToDatabase(ElfFile& inElf)
int rc = SQLITEDB_OK;
char* errorMessage = NULL;
- for (auto elf32Section : inElf.getElf32Headers())
+ switch (inElf.getElfClass())
{
- // std::string symbolInitializedDataName = symbolDataPair.first;
- // std::vector symbolInitializedData = symbolDataPair.second;
+ case ELFCLASS32:
+ {
+ for (auto elf32Section : inElf.getElf32Headers())
+ {
+ inElf.getInitializedSymbolData();
- inElf.getInitializedSymbolData();
- uint32_t typeID;
+ /*
+ * @todo I want to store these SQLite magical values into MACROS,
+ * but I'm not sure what is the best way to do that without it being
+ * messy.
+ */
+ std::string writeElfSectionsQuery{};
- /*
- * @todo I want to store these SQLite magical values into MACROS,
- * but I'm not sure what is the best way to do that without it being
- * messy.
- */
- std::string writeElfSectionsQuery{};
+ /**
+ *@todo Not sure if I should make a seperation in the db between 32-bit and 64-bit sections...
+ */
+ writeElfSectionsQuery +=
+ "INSERT INTO elf_sections"
+ "(name, elf, type, flags, address, file_offset, size, link, info, address_alignment, entry_size ) "
+ "VALUES(";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_name);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(inElf.getId());
+
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_type);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_flags);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_addr);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_offset);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_size);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_link);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_info);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_addralign);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Section.sh_entsize);
+
+ writeElfSectionsQuery += ");";
+
+ logger.logDebug("Sending \"%s\" query to database.", writeElfSectionsQuery.c_str());
+
+ rc = sqlite3_exec(database, writeElfSectionsQuery.c_str(), NULL, NULL, &errorMessage);
- /**
- *@todo Not sure if I should make a seperation in the db between 32-bit and 64-bit sections...
- */
- writeElfSectionsQuery +=
- "INSERT INTO elf_sections"
- "(name, elf, type, flags, address, file_offset, size, link, info, address_alignment, entry_size ) "
- "VALUES(";
- // writeElfSectionsQuery += "\"";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_name);
- // writeElfSectionsQuery += "\"";
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(inElf.getId());
-
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_type);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_flags);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_addr);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_offset);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_size);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_link);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_info);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_addralign);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Section.sh_entsize);
-
- writeElfSectionsQuery += ");";
-
- logger.logDebug("Sending \"%s\" query to database.", writeElfSectionsQuery.c_str());
-
- rc = sqlite3_exec(database, writeElfSectionsQuery.c_str(), NULL, NULL, &errorMessage);
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Variable values were written to the variables schema with "
+ "SQLITE_OK status.");
+ }
+ else
+ {
+ if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ {
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITE_OK;
+ }
+ else
+ {
+ logger.logDebug("There was an error while writing data to the variables table.");
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITEDB_ERROR;
+ }
+ }
+ }
- if (SQLITE_OK == rc)
- {
- logger.logDebug(
- "Variable values were written to the variables schema with "
- "SQLITE_OK status.");
+ break;
}
- else
+ case ELFCLASS64:
{
- if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
- {
- logger.logDebug("%s.", errorMessage);
- rc = SQLITE_OK;
- }
- else
+ for (auto elf64Section : inElf.getElf64Headers())
{
- logger.logDebug("There was an error while writing data to the variables table.");
- logger.logDebug("%s.", errorMessage);
- rc = SQLITEDB_ERROR;
+ inElf.getInitializedSymbolData();
+
+ /*
+ * @todo I want to store these SQLite magical values into MACROS,
+ * but I'm not sure what is the best way to do that without it being
+ * messy.
+ */
+ std::string writeElfSectionsQuery{};
+
+ /**
+ *@todo Not sure if I should make a seperation in the db between 32-bit and 64-bit sections...
+ */
+ writeElfSectionsQuery +=
+ "INSERT INTO elf_sections"
+ "(name, elf, type, flags, address, file_offset, size, link, info, address_alignment, entry_size ) "
+ "VALUES(";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_name);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(inElf.getId());
+
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_type);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_flags);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_addr);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_offset);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_size);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_link);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_info);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_addralign);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Section.sh_entsize);
+
+ writeElfSectionsQuery += ");";
+
+ logger.logDebug("Sending \"%s\" query to database.", writeElfSectionsQuery.c_str());
+
+ rc = sqlite3_exec(database, writeElfSectionsQuery.c_str(), NULL, NULL, &errorMessage);
+
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Variable values were written to the variables schema with "
+ "SQLITE_OK status.");
+ }
+ else
+ {
+ if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ {
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITE_OK;
+ }
+ else
+ {
+ logger.logDebug("There was an error while writing data to the variables table.");
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITEDB_ERROR;
+ }
+ }
}
+
+ break;
}
}
@@ -727,73 +859,145 @@ int SQLiteDB::writeElfSymboltableSymbolsToDatabase(ElfFile& inElf)
int rc = SQLITEDB_OK;
char* errorMessage = NULL;
- for (auto elf32Symbol : inElf.getElf32SymbolTable())
+ switch (inElf.getElfClass())
{
- // std::string symbolInitializedDataName = symbolDataPair.first;
- // std::vector symbolInitializedData = symbolDataPair.second;
-
- inElf.getInitializedSymbolData();
- uint32_t typeID;
+ case ELFCLASS32:
+ {
+ for (auto elf32Symbol : inElf.getElf32SymbolTable())
+ {
+ inElf.getInitializedSymbolData();
- /*
- * @todo I want to store these SQLite magical values into MACROS,
- * but I'm not sure what is the best way to do that without it being
- * messy.
- */
- std::string writeElfSectionsQuery{};
+ /*
+ * @todo I want to store these SQLite magical values into MACROS,
+ * but I'm not sure what is the best way to do that without it being
+ * messy.
+ */
+ std::string writeElfSectionsQuery{};
- /**
- *@todo Not sure if I should make a seperation in the db between 32-bit and 64-bit sections...
- */
- writeElfSectionsQuery +=
- "INSERT INTO elf_symbol_table"
- "(name, elf, value, size, info, other, section_index, file_offset, string_table_file_offset ) "
- "VALUES(";
- // writeElfSectionsQuery += "\"";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_name);
- // writeElfSectionsQuery += "\"";
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(inElf.getId());
-
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_value);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_size);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_info);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_other);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_shndx);
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getFileOffset());
- writeElfSectionsQuery += ",";
- writeElfSectionsQuery += std::to_string(elf32Symbol.getStrTableFileOffset());
- writeElfSectionsQuery += ");";
-
- logger.logDebug("Sending \"%s\" query to database.", writeElfSectionsQuery.c_str());
-
- rc = sqlite3_exec(database, writeElfSectionsQuery.c_str(), NULL, NULL, &errorMessage);
+ /**
+ *@todo Not sure if I should make a seperation in the db between 32-bit and 64-bit sections...
+ */
+ writeElfSectionsQuery +=
+ "INSERT INTO elf_symbol_table"
+ "(name, elf, value, size, info, other, section_index, file_offset, string_table_file_offset ) "
+ "VALUES(";
+ // writeElfSectionsQuery += "\"";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_name);
+ // writeElfSectionsQuery += "\"";
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(inElf.getId());
+
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_value);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_size);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_info);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_other);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getSymbol().st_shndx);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getFileOffset());
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf32Symbol.getStrTableFileOffset());
+ writeElfSectionsQuery += ");";
+
+ logger.logDebug("Sending \"%s\" query to database.", writeElfSectionsQuery.c_str());
+
+ rc = sqlite3_exec(database, writeElfSectionsQuery.c_str(), NULL, NULL, &errorMessage);
- if (SQLITE_OK == rc)
- {
- logger.logDebug(
- "Variable values were written to the variables schema with "
- "SQLITE_OK status.");
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Variable values were written to the variables schema with "
+ "SQLITE_OK status.");
+ }
+ else
+ {
+ if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ {
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITE_OK;
+ }
+ else
+ {
+ logger.logDebug("There was an error while writing data to the variables table.");
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITEDB_ERROR;
+ }
+ }
+ }
+ break;
}
- else
+ case ELFCLASS64:
{
- if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ for (auto elf64Symbol : inElf.getElf64SymbolTable())
{
- logger.logDebug("%s.", errorMessage);
- rc = SQLITE_OK;
- }
- else
- {
- logger.logDebug("There was an error while writing data to the variables table.");
- logger.logDebug("%s.", errorMessage);
- rc = SQLITEDB_ERROR;
+ inElf.getInitializedSymbolData();
+
+ /*
+ * @todo I want to store these SQLite magical values into MACROS,
+ * but I'm not sure what is the best way to do that without it being
+ * messy.
+ */
+ std::string writeElfSectionsQuery{};
+
+ /**
+ *@todo Not sure if I should make a seperation in the db between 32-bit and 64-bit sections...
+ */
+ writeElfSectionsQuery +=
+ "INSERT INTO elf_symbol_table"
+ "(name, elf, value, size, info, other, section_index, file_offset, string_table_file_offset ) "
+ "VALUES(";
+ // writeElfSectionsQuery += "\"";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getSymbol().st_name);
+ // writeElfSectionsQuery += "\"";
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(inElf.getId());
+
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getSymbol().st_value);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getSymbol().st_size);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getSymbol().st_info);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getSymbol().st_other);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getSymbol().st_shndx);
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getFileOffset());
+ writeElfSectionsQuery += ",";
+ writeElfSectionsQuery += std::to_string(elf64Symbol.getStrTableFileOffset());
+ writeElfSectionsQuery += ");";
+
+ logger.logDebug("Sending \"%s\" query to database.", writeElfSectionsQuery.c_str());
+
+ rc = sqlite3_exec(database, writeElfSectionsQuery.c_str(), NULL, NULL, &errorMessage);
+
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Variable values were written to the variables schema with "
+ "SQLITE_OK status.");
+ }
+ else
+ {
+ if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ {
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITE_OK;
+ }
+ else
+ {
+ logger.logDebug("There was an error while writing data to the variables table.");
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITEDB_ERROR;
+ }
+ }
}
+ break;
}
}
@@ -975,29 +1179,134 @@ int SQLiteDB::writeSymbolsToDatabase(ElfFile& inElf)
*/
std::string writeSymbolQuery{};
- writeSymbolQuery +=
- "INSERT INTO symbols(elf, name, byte_size, artifact, long_description, short_description) "
- "VALUES(";
- writeSymbolQuery += std::to_string(symbol->getElf().getId());
- writeSymbolQuery += ",\"";
- writeSymbolQuery += symbol->getName();
+ if (!symbol->hasEncoding())
+ {
+ writeSymbolQuery +=
+ "INSERT INTO symbols(elf, name, byte_size, artifact, long_description, short_description) "
+ "VALUES(";
+ writeSymbolQuery += std::to_string(symbol->getElf().getId());
+ writeSymbolQuery += ",\"";
+ writeSymbolQuery += symbol->getName();
- writeSymbolQuery += "\",";
- writeSymbolQuery += std::to_string(symbol->getByteSize());
- writeSymbolQuery += ",";
- writeSymbolQuery += std::to_string(symbol->getArtifact().getId());
+ writeSymbolQuery += "\",";
+ writeSymbolQuery += std::to_string(symbol->getByteSize());
+ writeSymbolQuery += ",";
+ writeSymbolQuery += std::to_string(symbol->getArtifact().getId());
- writeSymbolQuery += ",\"";
- writeSymbolQuery += symbol->getLongDescription();
+ writeSymbolQuery += ",\"";
+ writeSymbolQuery += symbol->getLongDescription();
- writeSymbolQuery += "\",";
+ writeSymbolQuery += "\",";
- writeSymbolQuery += "\"";
- writeSymbolQuery += symbol->getShortDescription();
+ writeSymbolQuery += "\"";
+ writeSymbolQuery += symbol->getShortDescription();
+
+ writeSymbolQuery += "\"";
+
+ writeSymbolQuery += ")";
+
+ rc = sqlite3_exec(database, writeSymbolQuery.c_str(), NULL, NULL, &errorMessage);
+
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Symbol values were written to the symbols schema with "
+ "SQLITE_OK status.");
+
+ /*Write the id to this symbol so that other tables can use it as
+ *a foreign key */
+ sqlite3_int64 lastRowId = sqlite3_last_insert_rowid(database);
+
+ symbol->setId(lastRowId);
+ }
+ else
+ {
+ logger.logError(
+ "Looks like something went wrong with query "
+ "\"%s\":\"%s\"",
+ writeSymbolQuery, errorMessage);
+ }
+ }
+
+ else
+ {
+ writeSymbolQuery +=
+ "INSERT INTO symbols(elf, name, byte_size, encoding, artifact, long_description, short_description) "
+ "VALUES(";
+ writeSymbolQuery += std::to_string(symbol->getElf().getId());
+ writeSymbolQuery += ",\"";
+ writeSymbolQuery += symbol->getName();
+
+ writeSymbolQuery += "\",";
+ writeSymbolQuery += std::to_string(symbol->getByteSize());
+ writeSymbolQuery += ",";
+
+ writeSymbolQuery += "\"";
+ writeSymbolQuery += std::to_string(symbol->getElf().getDWARFEncoding(symbol->getEncoding()).getId());
+ // writeSymbolQuery += "-47";
+ writeSymbolQuery += "\",";
+
+ writeSymbolQuery += std::to_string(symbol->getArtifact().getId());
+
+ writeSymbolQuery += ",\"";
+ writeSymbolQuery += symbol->getLongDescription();
+
+ writeSymbolQuery += "\",";
+
+ writeSymbolQuery += "\"";
+ writeSymbolQuery += symbol->getShortDescription();
+
+ writeSymbolQuery += "\"";
+
+ writeSymbolQuery += ")";
+
+ rc = sqlite3_exec(database, writeSymbolQuery.c_str(), NULL, NULL, &errorMessage);
+
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Symbol values were written to the symbols schema with "
+ "SQLITE_OK status.");
+
+ /*Write the id to this symbol so that other tables can use it as
+ *a foreign key */
+ sqlite3_int64 lastRowId = sqlite3_last_insert_rowid(database);
+
+ symbol->setId(lastRowId);
+ }
+ else
+ {
+ logger.logError(
+ "Looks like something went wrong with query "
+ "\"%s\":\"%s\"",
+ writeSymbolQuery, errorMessage);
+ }
+ }
+ }
+ }
+
+ // Add symbol to target_symbol mappings to database
+ for (auto&& symbol : inElf.getSymbols())
+ {
+ if (symbol->hasTargetSymbol())
+ {
+ /*
+ * @todo I want to store these SQLite magical values into MACROS,
+ * but I'm not sure what is the best way to do that without it being
+ * messy.
+ */
+ std::string writeSymbolQuery{};
+ writeSymbolQuery += "UPDATE symbols SET target_symbol = ";
writeSymbolQuery += "\"";
+ writeSymbolQuery += std::to_string(symbol->getTargetSymbol()->getId());
+ writeSymbolQuery += "\"";
+
+ writeSymbolQuery += " WHERE id = ";
- writeSymbolQuery += ")";
+ writeSymbolQuery += "\"";
+ writeSymbolQuery += std::to_string(symbol->getId());
+ writeSymbolQuery += "\"";
rc = sqlite3_exec(database, writeSymbolQuery.c_str(), NULL, NULL, &errorMessage);
@@ -1006,12 +1315,6 @@ int SQLiteDB::writeSymbolsToDatabase(ElfFile& inElf)
logger.logDebug(
"Symbol values were written to the symbols schema with "
"SQLITE_OK status.");
-
- /*Write the id to this symbol so that other tables can use it as
- *a foreign key */
- sqlite3_int64 lastRowId = sqlite3_last_insert_rowid(database);
-
- symbol->setId(lastRowId);
}
else
{
@@ -1275,6 +1578,239 @@ int SQLiteDB::writeEnumerationsToDatabase(ElfFile& inElf)
return rc;
}
+int SQLiteDB::writeEncodingsToDatabase(ElfFile& inElf)
+{
+ int rc = SQLITEDB_OK;
+
+ std::vector dwarfEncodings = inElf.getDWARFEncodings();
+
+ if (!doEncodingsExist())
+ {
+ for (Encoding encoding : dwarfEncodings)
+ {
+ // Create a SQL statement with placeholders
+ sqlite3_stmt* stmt;
+ const char* sql = "INSERT INTO encodings (encoding) VALUES (?);";
+
+ // Prepare the SQL statement
+ rc = sqlite3_prepare_v2(database, sql, -1, &stmt, NULL);
+
+ if (rc != SQLITE_OK)
+ {
+ std::cerr << "SQL error: " << sqlite3_errmsg(database) << std::endl;
+ }
+ else
+ {
+ // Bind values to placeholders
+ sqlite3_bind_text(stmt, 1, encoding.getName().c_str(), -1, SQLITE_STATIC);
+
+ rc = sqlite3_step(stmt);
+
+ // Execute the SQL statement
+ if (rc != SQLITE_DONE)
+ {
+ const char* errorMessage = sqlite3_errmsg(database);
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "Elf values were written to the encodings schema with "
+ "SQLITE_OK status.");
+ }
+ else
+ {
+ if (sqlite3_extended_errcode(database) == SQLITE_CONSTRAINT_UNIQUE)
+ {
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITE_OK;
+ }
+ else
+ {
+ logger.logDebug("There was an error while writing data to the encodings table.");
+ logger.logDebug("%s.", errorMessage);
+ rc = SQLITEDB_ERROR;
+ }
+ }
+ }
+
+ // Finalize the statement
+ rc = sqlite3_finalize(stmt);
+ if (rc != SQLITE_OK)
+ {
+ logger.logDebug("There was an error while finalizing the sql statement for encodings table.");
+ }
+ else
+ {
+ sqlite3_int64 lastRowId = sqlite3_last_insert_rowid(database);
+
+ if (encoding.getName() == "DW_ATE_address")
+ {
+ inElf.getDWARFEncoding(DW_ATE_address).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_boolean")
+ {
+ inElf.getDWARFEncoding(DW_ATE_boolean).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_complex_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_complex_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_signed")
+ {
+ inElf.getDWARFEncoding(DW_ATE_signed).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_unsigned")
+ {
+ inElf.getDWARFEncoding(DW_ATE_unsigned).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_signed_char")
+ {
+ inElf.getDWARFEncoding(DW_ATE_signed_char).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_unsigned_char")
+ {
+ inElf.getDWARFEncoding(DW_ATE_unsigned_char).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_imaginary_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_imaginary_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_packed_decimal")
+ {
+ inElf.getDWARFEncoding(DW_ATE_packed_decimal).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_numeric_string")
+ {
+ inElf.getDWARFEncoding(DW_ATE_numeric_string).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_edited")
+ {
+ inElf.getDWARFEncoding(DW_ATE_edited).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_signed_fixed")
+ {
+ inElf.getDWARFEncoding(DW_ATE_signed_fixed).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_unsigned_fixed")
+ {
+ inElf.getDWARFEncoding(DW_ATE_unsigned_fixed).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_decimal_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_decimal_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_UCS")
+ {
+ inElf.getDWARFEncoding(DW_ATE_UCS).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_ASCII")
+ {
+ inElf.getDWARFEncoding(DW_ATE_ASCII).setId(lastRowId);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ std::map> symbolsMap{};
+
+ std::string getSymbolIdQuery{"SELECT * FROM encodings;"};
+
+ char* errorMessage;
+
+ rc = sqlite3_exec(database, getSymbolIdQuery.c_str(), SQLiteDB::selectCallback, &symbolsMap, &errorMessage);
+
+ if (SQLITE_OK == rc)
+ {
+ /**
+ * We know there is only one element in our map, since symbol names are unique.
+ */
+ for (auto pair : symbolsMap)
+ {
+ // symbol->setId(std::stoi(pair.first));
+
+ Encoding encoding{pair.second.at(0)};
+
+ sqlite3_int64 lastRowId = std::stoi(pair.first);
+
+ if (encoding.getName() == "DW_ATE_address")
+ {
+ inElf.getDWARFEncoding(DW_ATE_address).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_boolean")
+ {
+ inElf.getDWARFEncoding(DW_ATE_boolean).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_complex_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_complex_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_signed")
+ {
+ inElf.getDWARFEncoding(DW_ATE_signed).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_unsigned")
+ {
+ inElf.getDWARFEncoding(DW_ATE_unsigned).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_signed_char")
+ {
+ inElf.getDWARFEncoding(DW_ATE_signed_char).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_unsigned_char")
+ {
+ inElf.getDWARFEncoding(DW_ATE_unsigned_char).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_imaginary_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_imaginary_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_packed_decimal")
+ {
+ inElf.getDWARFEncoding(DW_ATE_packed_decimal).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_numeric_string")
+ {
+ inElf.getDWARFEncoding(DW_ATE_numeric_string).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_edited")
+ {
+ inElf.getDWARFEncoding(DW_ATE_edited).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_signed_fixed")
+ {
+ inElf.getDWARFEncoding(DW_ATE_signed_fixed).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_unsigned_fixed")
+ {
+ inElf.getDWARFEncoding(DW_ATE_unsigned_fixed).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_decimal_float")
+ {
+ inElf.getDWARFEncoding(DW_ATE_decimal_float).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_UCS")
+ {
+ inElf.getDWARFEncoding(DW_ATE_UCS).setId(lastRowId);
+ }
+ else if (encoding.getName() == "DW_ATE_ASCII")
+ {
+ inElf.getDWARFEncoding(DW_ATE_ASCII).setId(lastRowId);
+ }
+ }
+ }
+ }
+ return rc;
+}
+
/**
*@brief This method creates all of the schemas that will be needed to store
*the DWARF and ELF data.
@@ -1356,8 +1892,22 @@ int SQLiteDB::createSchemas(void)
if (SQLITE_OK == rc)
{
logger.logDebug(
- "createElfSectionsSchema() created the variables schema "
+ "createElfSymbolTableSchema() created the variables schema "
"successfully.");
+
+ rc = createEncodingsTableSchema();
+
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug(
+ "createEncodingsTableSchema() created the variables schema "
+ "successfully.");
+ }
+ else
+ {
+ logger.logDebug("createEncodingsTableSchema() failed.");
+ rc = SQLITEDB_ERROR;
+ }
}
else
{
@@ -1748,3 +2298,27 @@ int SQLiteDB::createElfSymbolTableSchema(void)
return rc;
}
+
+int SQLiteDB::createEncodingsTableSchema(void)
+{
+ std::string createEncodingsTableQuery{CREATE_ENCODINGS_TABLE};
+
+ int rc = SQLITE_OK;
+
+ /*@todo The last argument for sqlite3_exec is an error handler that is not
+ * necessary to pass in, but I really think we should for better error
+ * logging.*/
+ rc = sqlite3_exec(database, createEncodingsTableQuery.c_str(), NULL, NULL, NULL);
+
+ if (SQLITE_OK == rc)
+ {
+ logger.logDebug("Created table \"artifacts\" with OK status");
+ }
+ else
+ {
+ logger.logError("Failed to create the artifacts table. '%s'", sqlite3_errmsg(database));
+ rc = SQLITEDB_ERROR;
+ }
+
+ return rc;
+}
diff --git a/src/SQLiteDB.h b/src/SQLiteDB.h
index be28691e..2cea08cb 100644
--- a/src/SQLiteDB.h
+++ b/src/SQLiteDB.h
@@ -40,10 +40,14 @@
name TEXT UNIQUE NOT NULL,\
byte_size INTEGER NOT NULL,\
artifact INTEGER,\
+ target_symbol INTEGER,\
+ encoding INTEGER,\
short_description TEXT ,\
long_description TEXT ,\
FOREIGN KEY(elf) REFERENCES elfs(id),\
FOREIGN KEY(artifact) REFERENCES artifacts(id)\
+ FOREIGN KEY(target_symbol) REFERENCES symbols(id)\
+ FOREIGN KEY(encoding) REFERENCES encodings(id)\
UNIQUE(name));"
#define CREATE_DIMENSION_TABLE \
@@ -146,6 +150,12 @@
FOREIGN KEY (elf) REFERENCES elfs(id),\
UNIQUE (name, type, elf));"
+#define CREATE_ENCODINGS_TABLE \
+ "CREATE TABLE IF NOT EXISTS encodings(\
+ id INTEGER PRIMARY KEY,\
+ encoding TEXT NOT NULL,\
+ UNIQUE (encoding));"
+
//#define CREATE_DATA_OBJECTS_TABLE \
// "CREATE TABLE IF NOT EXISTS data_objects(\
// id INTEGER PRIMARY KEY,\
@@ -183,6 +193,7 @@ class SQLiteDB : public IDataContainer
int createVariablesSchema(void);
int createElfSectionsSchema(void);
int createElfSymbolTableSchema(void);
+ int createEncodingsTableSchema(void);
int writeElfToDatabase(ElfFile &inModule);
int writeMacrosToDatabase(ElfFile &inModule);
int writeVariablesToDatabase(ElfFile &inModule);
@@ -193,10 +204,13 @@ class SQLiteDB : public IDataContainer
int writeFieldsToDatabase(ElfFile &inModule);
int writeEnumerationsToDatabase(ElfFile &inModule);
int writeDimensionsListToDatabase(ElfFile &inElf);
+ int writeEncodingsToDatabase(ElfFile &inElf);
static int doesRowExistCallback(void *veryUsed, int argc, char **argv, char **azColName);
bool doesSymbolExist(std::string name);
bool doesArtifactExist(std::string name);
+ bool doEncodingsExist();
+
public:
SQLiteDB();
int initialize(std::string &initString);
diff --git a/src/Symbol.cpp b/src/Symbol.cpp
index 3b1d1512..a96805ae 100644
--- a/src/Symbol.cpp
+++ b/src/Symbol.cpp
@@ -170,31 +170,6 @@ bool Symbol::isFieldUnique(std::string& name)
return rc;
}
-
-bool Symbol::hasFields(void)
-{
- bool rc = false;
-
- if (fields.size() > 0)
- {
- rc = true;
- }
-
- return rc;
-}
-
-bool Symbol::isEnumerated(void)
-{
- bool rc = false;
-
- if (enumerations.size() > 0)
- {
- rc = true;
- }
-
- return rc;
-}
-
/**
*@brief Checks if this symbol has any fields that are bitfields.
*
@@ -217,3 +192,30 @@ bool Symbol::hasBitFields(void)
}
Artifact& Symbol::getArtifact() { return artifact; }
+
+/**
+ * @brief Symbol::setTargetSymbol
+ * @note Might make sense to use std:optional for targetSymbol, however need to upgrade to C++17 first.
+ * @param newTargetSymbol
+ */
+void Symbol::setTargetSymbol(Symbol* newTargetSymbol) { targetSymbol = newTargetSymbol; }
+
+/**
+ * @brief Symbol::hasTargetSymbol
+ * If this function returns false, then
+ * that means this is the concrete symbol not a typdef'd(aliased) symbol.
+ */
+bool Symbol::hasTargetSymbol() { return targetSymbol != nullptr; }
+
+Symbol* Symbol::getTargetSymbol() { return targetSymbol; }
+
+/**
+ * @brief Symbol::setEncoding
+ * @param newEncoding an integer which is one of the values specified in
+ * in dwarf.h or in DWARF5 specification document section 5.1.1 titled "Base Type Encodings"
+ */
+void Symbol::setEncoding(int newEncoding) { encoding = newEncoding; }
+
+bool Symbol::hasEncoding() { return encoding != -1; }
+
+int Symbol::getEncoding() { return encoding; }
diff --git a/src/Symbol.h b/src/Symbol.h
index 6b664832..2d8c1807 100644
--- a/src/Symbol.h
+++ b/src/Symbol.h
@@ -16,6 +16,7 @@
#include "Artifact.h"
#include "DimensionList.h"
#include "ElfFile.h"
+#include "Encoding.h"
#include "Enumeration.h"
#include "Field.h"
#include "Logger.h"
@@ -24,11 +25,16 @@ class Field;
class Enumeration;
class ElfFile;
+/**
+ *@class Symbol represents a "symbol" in the dwarf.
+ *These include intrinsic types and struct types.
+ */
class Symbol
{
public:
Symbol(ElfFile &elf);
Symbol(ElfFile &elf, std::string &name, uint32_t byte_size, Artifact);
+ Symbol(ElfFile &elf, std::string &name, uint32_t byte_size, Artifact, Symbol &targetSymbol);
virtual ~Symbol();
const std::string &getName(void) const;
void setName(std::string &name);
@@ -49,14 +55,24 @@ class Symbol
bool hasBitFields();
bool isFieldUnique(std::string &name);
Field *getField(std::string &name) const;
- bool hasFields(void);
- bool isEnumerated(void);
Artifact &getArtifact();
const std::string &getShortDescription() const { return short_description; }
const std::string &getLongDescription() const { return long_description; }
+ void setTargetSymbol(Symbol *newTargetSymbol);
+
+ Symbol *getTargetSymbol();
+
+ bool hasTargetSymbol();
+
+ void setEncoding(int newEncoding);
+
+ bool hasEncoding();
+
+ int getEncoding();
+
private:
ElfFile &elf;
std::string name;
@@ -66,9 +82,12 @@ class Symbol
std::vector> fields;
std::vector> enumerations;
Artifact artifact;
+ Symbol *targetSymbol{nullptr}; // This is useful for typedef'd names
std::string short_description;
std::string long_description;
+
+ int encoding{-1};
};
#endif /* SYMBOL_H_ */
diff --git a/src/YAMCS.cpp b/src/YAMCS.cpp
deleted file mode 100644
index 305ab3cc..00000000
--- a/src/YAMCS.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************************
- *
- * Copyright (c) 2017 Windhover Labs, L.L.C. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name Windhover Labs 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE
- * COPYRIGHT OWNER OR CONTRIBUTORS 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.
- *
- *****************************************************************************/
-
-#include "YAMCS.h"
-
-YAMCS::YAMCS()
-{
- // TODO Auto-generated constructor stub
-}
-
-YAMCS::~YAMCS()
-{
- // TODO Auto-generated destructor stub
-}
diff --git a/src/YAMCS.h b/src/YAMCS.h
deleted file mode 100644
index 12b22a87..00000000
--- a/src/YAMCS.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/****************************************************************************
- *
- * Copyright (c) 2017 Windhover Labs, L.L.C. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name Windhover Labs 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 THE
- * COPYRIGHT OWNER OR CONTRIBUTORS 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.
- *
- *****************************************************************************/
-
-#ifndef YAMCS_H_
-#define YAMCS_H_
-
-class YAMCS
-{
- public:
- YAMCS();
- virtual ~YAMCS();
-};
-
-#endif /* YAMCS_H_ */
diff --git a/src/main.cpp b/src/main.cpp
index b8407536..bb136a24 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,7 +56,7 @@ static char doc[] =
/* A description of the arguments we accept. */
static char args_doc[] =
"--input --mode (--output | "
- "(--address --port --project )) -x";
+ "(--address --port --project )) -x -g";
/* The options we understand. */
static struct argp_option options[] = {{"input", 'i', "FILE", 0, "Input ELF file"},
@@ -74,6 +74,10 @@ static struct argp_option options[] = {{"input", 'i', "FILE", 0, "Input ELF file
{"extras", 'x', NULL, 0,
"Extra DWARF and ELF data such as variables. Enabling this"
"will cause juicer to take longer."},
+ {"groupNumber", 'g', "group", 0,
+ "Group number to extract data forom inside of DWARF section."
+ "Useful for situations where debug sections (eg. debug_macros) are spreadout through different groups."
+ " An example of this is when macros are split in different groups by gcc for unlinked ELF object files."},
{0}};
/* Used by main to communicate with parse_opt. */
@@ -99,6 +103,7 @@ typedef struct
char *project;
bool project_set;
bool extras;
+ int groupNumber;
} arguments_t;
/* Parse a single option. */
@@ -180,6 +185,22 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
break;
}
+ case 'g':
+ {
+ for (int i = 0; i < strlen(arg); i++)
+ {
+ if (isdigit(arg[i]) == 0)
+ {
+ printf("Error: group number MUST be a number");
+ argp_usage(state);
+ return ARGP_KEY_ERROR;
+ }
+ }
+
+ arguments->groupNumber = atoi(arg);
+ break;
+ }
+
case ARGP_KEY_ARG:
{
// if (state->arg_num >= 2)
@@ -285,13 +306,13 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
}
}
- // /* Verify Extras. */
- // if (arguments->extras)
- // {
- // // printf("Error: extras name must be set.\n");
- // // argp_usage(state);
- // return ARGP_KEY_ERROR;
- // }
+ /* Verify group number. */
+ if (arguments->groupNumber < 0)
+ {
+ printf("Error: Group number must be 0 or greater.\n");
+ argp_usage(state);
+ return ARGP_KEY_ERROR;
+ }
break;
}
@@ -305,11 +326,8 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
return 0;
}
-TestStructA_t testStructA2 = {};
-TestStructB_t testStructB2 = {};
-
/* Our argp parser. */
-static struct argp argp = {options, parse_opt, args_doc, doc};
+static struct argp argp = {options, parse_opt, args_doc, doc};
int main(int argc, char **argv)
{
@@ -318,16 +336,18 @@ int main(int argc, char **argv)
/* Set argument default values. */
memset(&arguments, 0, sizeof(arguments));
- arguments.verbosity = 1;
- arguments.extras = false;
+ arguments.verbosity = 1;
+ arguments.extras = false;
+ arguments.groupNumber = 0;
/* Parse our arguments; every option seen by parse_opt will
be reflected in arguments. */
- parse_error = argp_parse(&argp, argc, argv, 0, 0, &arguments);
+ parse_error = argp_parse(&argp, argc, argv, 0, 0, &arguments);
if (parse_error == 0)
{
Juicer juicer;
juicer.setExtras(arguments.extras);
+ juicer.setGroupNumber(arguments.groupNumber);
IDataContainer *idc = 0;
Logger logger = Logger(arguments.verbosity);
diff --git a/unit-test/TestElfFile.cpp b/unit-test/TestElfFile.cpp
index 4e5bdc8a..973a8028 100644
--- a/unit-test/TestElfFile.cpp
+++ b/unit-test/TestElfFile.cpp
@@ -5,16 +5,17 @@
* Author: vagrant
*/
-#include "../src/ElfFile.h"
-#include "catch.hpp"
#include
+#include "../src/ElfFile.h"
+#include "catch.hpp"
/**
*@todo This testing module is not done yet.
*/
-TEST_CASE( "Correctness of a Module object instance", "[Module] " ) {
+TEST_CASE("Correctness of a Module object instance", "[Module] ")
+{
std::string newElfName{"ABC"};
uint32_t elfId = 102;
ElfFile myElf{newElfName};
@@ -25,11 +26,6 @@ TEST_CASE( "Correctness of a Module object instance", "[Module] " ) {
newElfName.insert(0, resolvedPath);
myElf.setId(elfId);
- REQUIRE( myElf.getName() == newElfName );
- REQUIRE( myElf.getId() == elfId );
-
+ REQUIRE(myElf.getName() == newElfName);
+ REQUIRE(myElf.getId() == elfId);
}
-
-
-
-
diff --git a/unit-test/TestEnumeration.cpp b/unit-test/TestEnumeration.cpp
index 8e5a4533..96498d94 100644
--- a/unit-test/TestEnumeration.cpp
+++ b/unit-test/TestEnumeration.cpp
@@ -4,8 +4,8 @@
* Created on: Aug 12, 2020
* Author: vagrant
*/
-#include "catch.hpp"
#include "Enumeration.h"
+#include "catch.hpp"
/**
* @brief Unit tests for Enumeration class.
@@ -16,9 +16,9 @@ TEST_CASE("Test Enumeration name correctness", "[Enumeration]")
std::string symbolName{"string"};
std::string elfName{"ABC"};
- ElfFile symbolModule{elfName};
+ ElfFile symbolModule{elfName};
- Symbol enumSymbol{symbolModule};
+ Symbol enumSymbol{symbolModule};
enumSymbol.setName(symbolName);
std::string colorName{"Color"};
@@ -34,11 +34,11 @@ TEST_CASE("Test Enumeration value correctness", "[Enumeration]")
std::string symbolName{"string"};
std::string elfName{"ABC"};
- ElfFile symbolModule{elfName};
+ ElfFile symbolModule{elfName};
- Symbol enumSymbol{symbolModule};
+ Symbol enumSymbol{symbolModule};
enumSymbol.setName(symbolName);
- uint64_t value{714};
+ uint64_t value{714};
Enumeration colorEnumeration{enumSymbol};
@@ -47,15 +47,17 @@ TEST_CASE("Test Enumeration value correctness", "[Enumeration]")
REQUIRE(colorEnumeration.getValue() == value);
}
-TEST_CASE("Test Constructor Enumeration(Symbol &symbol) "
- " correctness ", "[Enumeration]")
+TEST_CASE(
+ "Test Constructor Enumeration(Symbol &symbol) "
+ " correctness ",
+ "[Enumeration]")
{
std::string symbolName{"string"};
std::string elfName{"ABC"};
- ElfFile symbolModule{elfName};
+ ElfFile symbolModule{elfName};
- Symbol enumSymbol{symbolModule};
+ Symbol enumSymbol{symbolModule};
enumSymbol.setName(symbolName);
Enumeration colorEnumeration{enumSymbol};
@@ -63,17 +65,19 @@ TEST_CASE("Test Constructor Enumeration(Symbol &symbol) "
REQUIRE(colorEnumeration.getSymbol().getName() == symbolName);
}
-TEST_CASE("Test Constructor Enumeration(Symbol &symbol, std::string &name, uint64_t value) "
- " correctness ", "[Enumeration]")
+TEST_CASE(
+ "Test Constructor Enumeration(Symbol &symbol, std::string &name, uint64_t value) "
+ " correctness ",
+ "[Enumeration]")
{
std::string symbolName{"string"};
std::string enumName{"Color"};
uint64_t value{714};
std::string elfName{"ABC"};
- ElfFile symbolModule{elfName};
+ ElfFile symbolModule{elfName};
- Symbol enumSymbol{symbolModule};
+ Symbol enumSymbol{symbolModule};
enumSymbol.setName(symbolName);
Enumeration colorEnumeration{enumSymbol, enumName, value};
diff --git a/unit-test/TestIDataContainer.cpp b/unit-test/TestIDataContainer.cpp
index fdb21df6..0e011edf 100644
--- a/unit-test/TestIDataContainer.cpp
+++ b/unit-test/TestIDataContainer.cpp
@@ -5,6 +5,7 @@
* Author: vagrant
*/
#include
+
#include "IDataContainer.h"
/**
diff --git a/unit-test/TestLogger.cpp b/unit-test/TestLogger.cpp
index ee0ed84c..65474158 100644
--- a/unit-test/TestLogger.cpp
+++ b/unit-test/TestLogger.cpp
@@ -4,7 +4,3 @@
* Created on: Aug 21, 2020
* Author: vagrant
*/
-
-
-
-
diff --git a/unit-test/TestSymbol.cpp b/unit-test/TestSymbol.cpp
index 6eca635b..574b9fc1 100644
--- a/unit-test/TestSymbol.cpp
+++ b/unit-test/TestSymbol.cpp
@@ -6,63 +6,65 @@
*/
#include
-#include "catch.hpp"
-#include "Field.h"
-#include "Enumeration.h"
#include
+#include "Enumeration.h"
+#include "Field.h"
+#include "catch.hpp"
+
/**
*@todo This testing elf is not done yet.
*/
-TEST_CASE( "Test the correctness of name", "[Symbol]" )
+TEST_CASE("Test the correctness of name", "[Symbol]")
{
std::string newElfName{"ABC"};
std::string newSymbolName{"string"};
- ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ ElfFile myelf{newElfName};
+ Symbol newSymbol{myelf};
newSymbol.setName(newSymbolName);
REQUIRE(newSymbol.getName() == newSymbolName);
}
-TEST_CASE( "Test the correctness of byte_size ", "[Symbol]" )
+TEST_CASE("Test the correctness of byte_size ", "[Symbol]")
{
- std::string newElfName{"ABC"};;
- uint32_t byteSize{8};
- ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ std::string newElfName{"ABC"};
+ ;
+ uint32_t byteSize{8};
+ ElfFile myelf{newElfName};
+ Symbol newSymbol{myelf};
newSymbol.setByteSize(byteSize);
REQUIRE(newSymbol.getByteSize() == byteSize);
}
-TEST_CASE( "Test the correctness of id ", "[Symbol]" )
+TEST_CASE("Test the correctness of id ", "[Symbol]")
{
std::string newElfName{"ABC"};
std::string newSymbolName{"string"};
uint32_t id{123};
- ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ ElfFile myelf{newElfName};
+ Symbol newSymbol{myelf};
newSymbol.setId(id);
REQUIRE(newSymbol.getId() == id);
}
-TEST_CASE( "Test addField(Field &inField) method", "[Symbol]" )
+TEST_CASE("Test addField(Field &inField) method", "[Symbol]")
{
- std::string newElfName{"ABC"};
- std::string newSymbolName{"string"};
+ std::string newElfName{"ABC"};
+ std::string newSymbolName{"string"};
const std::string fieldName{"intField"};
- ElfFile myelf{newElfName};
+ ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ Symbol newSymbol{myelf};
- Symbol newType{myelf};
+ Symbol newType{myelf};
- Field newField{newSymbol, newType};
+ Field newField{newSymbol, newType};
newField.setName(fieldName);
newSymbol.addField(newField);
@@ -70,21 +72,23 @@ TEST_CASE( "Test addField(Field &inField) method", "[Symbol]" )
REQUIRE(newSymbol.getFields().back()->getName() == fieldName);
}
-TEST_CASE( "Test addField(std::string& inName, uint32_t inByteOffset, "
- "Symbol &inType, uint32_t inMultiplicity, "
- "bool inLittleEndian) method ", "[Symbol]" )
+TEST_CASE(
+ "Test addField(std::string& inName, uint32_t inByteOffset, "
+ "Symbol &inType, uint32_t inMultiplicity, "
+ "bool inLittleEndian) method ",
+ "[Symbol]")
{
- std::string fieldName{"intField"};
- std::string newElfName{"ABC"};
- std::string newSymbolName{"string"};
- std::string newTypeName{"Shape"};
- ElfFile myelf{newElfName};
- bool littleEndian = true;
- uint32_t byteOffset{32};
- DimensionList dimList{};
-
- Symbol newSymbol{myelf};
- Symbol newType{myelf};
+ std::string fieldName{"intField"};
+ std::string newElfName{"ABC"};
+ std::string newSymbolName{"string"};
+ std::string newTypeName{"Shape"};
+ ElfFile myelf{newElfName};
+ bool littleEndian = true;
+ uint32_t byteOffset{32};
+ DimensionList dimList{};
+
+ Symbol newSymbol{myelf};
+ Symbol newType{myelf};
newType.setName(newTypeName);
@@ -93,18 +97,17 @@ TEST_CASE( "Test addField(std::string& inName, uint32_t inByteOffset, "
REQUIRE(newSymbol.getFields().back()->getName() == fieldName);
REQUIRE(newSymbol.getFields().back()->getByteOffset() == byteOffset);
REQUIRE(newSymbol.getFields().back()->getType().getName() == newTypeName);
-// REQUIRE(newSymbol.getFields().back()->getDimensionList().size()== dimList.size());
+ // REQUIRE(newSymbol.getFields().back()->getDimensionList().size()== dimList.size());
REQUIRE(newSymbol.getFields().back()->isLittleEndian() == littleEndian);
}
-TEST_CASE( "Test addEnumeration(Enumeration &inEnumeration); method",
- "[Symbol]" )
+TEST_CASE("Test addEnumeration(Enumeration &inEnumeration); method", "[Symbol]")
{
- std::string newElfName{"ABC"};
- std::string newSymbolName{"string"};
- std::string enumName{"Color"};
- ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ std::string newElfName{"ABC"};
+ std::string newSymbolName{"string"};
+ std::string enumName{"Color"};
+ ElfFile myelf{newElfName};
+ Symbol newSymbol{myelf};
Enumeration newEnum(newSymbol);
newEnum.setName(enumName);
@@ -114,15 +117,14 @@ TEST_CASE( "Test addEnumeration(Enumeration &inEnumeration); method",
REQUIRE(newSymbol.getEnumerations().back()->getName() == enumName);
}
-TEST_CASE( "Test addEnumeration(std::string& inName, int32_t inValue); method",
- "[Symbol]" )
+TEST_CASE("Test addEnumeration(std::string& inName, int32_t inValue); method", "[Symbol]")
{
- std::string newElfName{"ABC"};
- std::string newSymbolName{"string"};
- std::string enumName{"Color"};
- uint64_t enumValue{589};
- ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ std::string newElfName{"ABC"};
+ std::string newSymbolName{"string"};
+ std::string enumName{"Color"};
+ uint64_t enumValue{589};
+ ElfFile myelf{newElfName};
+ Symbol newSymbol{myelf};
Enumeration newEnum(newSymbol);
newEnum.setName(enumName);
@@ -133,15 +135,14 @@ TEST_CASE( "Test addEnumeration(std::string& inName, int32_t inValue); method",
REQUIRE(newSymbol.getEnumerations().back()->getValue() == enumValue);
}
-TEST_CASE( "Test getEnumerations() method",
- "[Symbol]" )
+TEST_CASE("Test getEnumerations() method", "[Symbol]")
{
- std::string newElfName{"ABC"};
- std::string newSymbolName{"string"};
- std::string enumName{"Color"};
- uint64_t enumValue{589};
- ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
+ std::string newElfName{"ABC"};
+ std::string newSymbolName{"string"};
+ std::string enumName{"Color"};
+ uint64_t enumValue{589};
+ ElfFile myelf{newElfName};
+ Symbol newSymbol{myelf};
Enumeration newEnum(newSymbol);
newEnum.setName(enumName);
@@ -153,36 +154,36 @@ TEST_CASE( "Test getEnumerations() method",
REQUIRE(newSymbol.getEnumerations().back()->getValue() == enumValue);
}
-TEST_CASE( "Test getFields() method", "[Symbol]" )
+TEST_CASE("Test getFields() method", "[Symbol]")
{
- std::string newElfName{"ABC"};
- std::string newSymbolName{"string"};
+ std::string newElfName{"ABC"};
+ std::string newSymbolName{"string"};
const std::string fieldName{"intField"};
- ElfFile myelf{newElfName};
+ ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
- Symbol newType{myelf};
+ Symbol newSymbol{myelf};
+ Symbol newType{myelf};
- Field newField{newSymbol, newType};
+ Field newField{newSymbol, newType};
newField.setName(fieldName);
newSymbol.addField(newField);
- REQUIRE(1 ==newSymbol.getFields().size());
+ REQUIRE(1 == newSymbol.getFields().size());
REQUIRE(newSymbol.getFields().back()->getName() == fieldName);
}
-TEST_CASE( "Test isFieldUnique(std::string &name) method with unique fields", "[Symbol]" )
+TEST_CASE("Test isFieldUnique(std::string &name) method with unique fields", "[Symbol]")
{
std::string newElfName{"ABC"};
std::string newSymbolName{"string"};
std::string intFieldName{"intField"};
std::string floatFieldName{"floatField"};
- ElfFile myelf{newElfName};
+ ElfFile myelf{newElfName};
- Symbol newSymbol{myelf};
- Symbol newType{myelf};
+ Symbol newSymbol{myelf};
+ Symbol newType{myelf};
- Field newIntField{newSymbol, newType};
+ Field newIntField{newSymbol, newType};
newIntField.setName(intFieldName);
@@ -194,10 +195,10 @@ TEST_CASE( "Test isFieldUnique(std::string &name) method with unique fields", "[
/**
* Test constructors
*/
-TEST_CASE( "Test the correctness of constructor Symbol(elf &elf) ", "[Symbol]" )
+TEST_CASE("Test the correctness of constructor Symbol(elf &elf) ", "[Symbol]")
{
std::string newElfName{"ABC"};
- ElfFile myelf{newElfName};
+ ElfFile myelf{newElfName};
Symbol newSymbol{myelf};
char resolvedPath[PATH_MAX];
@@ -208,18 +209,19 @@ TEST_CASE( "Test the correctness of constructor Symbol(elf &elf) ", "[Symbol]" )
REQUIRE(newSymbol.getElf().getName() == newElfName);
}
-TEST_CASE( "Test the correctness of constructor Symbol(elf &elf,"
- "std::string &name,"
- "uint32_t byte_size) ",
- "[Symbol]" )
+TEST_CASE(
+ "Test the correctness of constructor Symbol(elf &elf,"
+ "std::string &name,"
+ "uint32_t byte_size) ",
+ "[Symbol]")
{
std::string newElfName{"ABC"};
- ElfFile myelf{newElfName};
+ ElfFile myelf{newElfName};
std::string symbolName{"string"};
uint32_t byteSize{8};
char resolvedPath[PATH_MAX];
- Symbol newSymbol{myelf, symbolName, byteSize, myelf};
+ Symbol newSymbol{myelf, symbolName, byteSize, myelf};
realpath(newElfName.c_str(), resolvedPath);
newElfName.clear();
@@ -230,17 +232,17 @@ TEST_CASE( "Test the correctness of constructor Symbol(elf &elf,"
REQUIRE(newSymbol.getByteSize() == byteSize);
}
-TEST_CASE( "Test the correctness of constructor Symbol(const Symbol &symbol)", "[Symbol]" )
+TEST_CASE("Test the correctness of constructor Symbol(const Symbol &symbol)", "[Symbol]")
{
std::string newElfName{"ABC"};
- ElfFile myelf{newElfName};
+ ElfFile myelf{newElfName};
std::string symbolName{"string"};
uint32_t byteSize{8};
char resolvedPath[PATH_MAX];
- Symbol copySymbol{myelf, symbolName, byteSize, Artifact{myelf}};
+ Symbol copySymbol{myelf, symbolName, byteSize, Artifact{myelf}};
- Symbol constSymbol{copySymbol}; // @suppress("Invalid arguments")
+ Symbol constSymbol{copySymbol}; // @suppress("Invalid arguments")
realpath(newElfName.c_str(), resolvedPath);
newElfName.clear();
diff --git a/unit-test/macro_test.cpp b/unit-test/macro_test.cpp
new file mode 100644
index 00000000..04b129a2
--- /dev/null
+++ b/unit-test/macro_test.cpp
@@ -0,0 +1,4 @@
+#define MAC1 2
+#define MAC2 3
+#include "macro_test.h"
+#define MAC3 4
\ No newline at end of file
diff --git a/unit-test/macro_test.h b/unit-test/macro_test.h
new file mode 100644
index 00000000..ffb490f7
--- /dev/null
+++ b/unit-test/macro_test.h
@@ -0,0 +1,2 @@
+#define MAC4
+#define MAC5 1
\ No newline at end of file
diff --git a/unit-test/main.cpp b/unit-test/main.cpp
index a7b585c8..bcf84bd2 100644
--- a/unit-test/main.cpp
+++ b/unit-test/main.cpp
@@ -9,12 +9,11 @@
/*This tells Catch to provide a main() - only do this in one cpp file*/
#define CATCH_CONFIG_MAIN
-
/**This disables coloring output so that Eclipse CDT(Version: 9.7.0.201903092251)
*will be able to render it. If you really like colored output, you'll have to use
*something else other than Eclipse's console(such as GNOME shell) to run the tests
*and comment out the CATCH_CONFIG_COLOUR_NONE macro.
*/
-//#define CATCH_CONFIG_COLOUR_NONE
+// #define CATCH_CONFIG_COLOUR_NONE
#include "catch.hpp"
diff --git a/unit-test/main_test.cpp b/unit-test/main_test.cpp
index 120cdc60..d4924364 100644
--- a/unit-test/main_test.cpp
+++ b/unit-test/main_test.cpp
@@ -4,70 +4,74 @@
* Created on: Aug 20, 2020
* Author: vagrant
*/
-#include "catch.hpp"
-#include "Juicer.h"
-#include "IDataContainer.h"
-#include "SQLiteDB.h"
-#include