Skip to content

Latest commit

 

History

History
101 lines (87 loc) · 2.83 KB

README.md

File metadata and controls

101 lines (87 loc) · 2.83 KB

StructDump

Requirement

Given an elf and a C struct global variable, print the members' name, type, offset, size, and theoretically initial value
This code can be modified to do tasks like generating GUI table config, generating XCP A2L file

Implementation

All the type information is in the elf's .debug_info section in DWARF format. The LLVM library is used to inspect .debug_info. The initial value can also be derived by inspecting the .data section (not done).

The LLVM document provides a example CMakeLists. But during linking the libraries -lLLVMCore -lLLVMIRReader cannot be found in Arch Linux and msys2. In the PKGBUILD, the LLVM static libraries goes to llvm-libs package in a single libLLVM.so. The flags provided by llvm-config --cxxflagsllvm-config --libs work.

The code of this repo is based on llvm-dwarfdump.

Build

After install the LLVM libraries, run basic cmake build instructions:

cmake -B build -S .
cd build
cmake --build .

Usage

StructDump <elf> <variable>

Example:

// example.c
#include <stdint.h>
typedef struct PidTag{
  float p;
  float i;
  float d;
} Pid;
typedef uint8_t uint8;
typedef struct {
  uint8 u8;
  int32_t i32;
  float f32;
  float mapX[5];
  float mapY[5];
  Pid pid;
} MyStruct;
MyStruct g_param = {.u8 = 1,
                    .i32 = -1,
                    .f32 = 5.5f,
                    .mapX = {1.0f, 1.5f, 2.0f, 2.5f, 3.0f},
                    .mapY = {-10.0f, -9.5f, -9.0f, -8.5f, -8.0f},
                    .pid = {.p = 0.25f, .i = 0.5f, .d = 0.75f}};
gcc -g -c example.c
StructDump example.o g_param

Output:

type of g_param is MyStruct
struct (anonymous) size 64
-member name u8 offset 0
--typedef: uint8 -> uint8_t -> __uint8_t
---base type unsigned char size 1
-member name i32 offset 4
--typedef: int32_t -> __int32_t
---base type int size 4
-member name f32 offset 8
--base type float size 4
-member name mapX offset 12
--array of float length 5
-member name mapY offset 32
--array of float length 5
-member name pid offset 52
--typedef: Pid
---struct PidTag size 12
----member name p offset 0
-----base type float size 4
----member name i offset 4
-----base type float size 4
----member name d offset 8
-----base type float size 4

expected output

type of g_param is MyStruct
struct (anonymous) size 64
-u8: uint8 offset 0 size 1
	(possibly sth about non-zero padding)
-i32: int32_t offset 4 size 4
-f32: float offset 8 size 4
-mapX: float[5] offset 12 size 20(4*5)
-mapY: float[5] offset 32 size 20(4*5)
-pid: Pid offset 52 size 12
--pid.p: float offset 52(52+0) size 4
--pid.i: float offset 56(52+4) size 4
--pid.d: float offset 60(52+8) size 4