Skip to content

Commit

Permalink
Add support for a few DWARF expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
emersion committed Mar 6, 2018
1 parent 7b00bf7 commit 322e118
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 13 deletions.
31 changes: 31 additions & 0 deletions expressions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <dwarf.h>
#include <dwarfw.h>
#include "leb128.h"
#include "write.h"

size_t dwarfw_op_write_deref(FILE *f) {
return write_u8(DW_OP_deref, f);
}

size_t dwarfw_op_write_bregx(uint64_t reg, long long int offset, FILE *f) {
size_t n, written = 0;

if (reg < 32) {
if (!(n = write_u8(DW_OP_breg0 + reg, f))) {
return 0;
}
written += n;
} else {
if (!(n = leb128_write_u64(reg, f, 0))) {
return 0;
}
written += n;
}

if (!(n = leb128_write_s64(offset, f, 0))) {
return 0;
}
written += n;

return written;
}
8 changes: 8 additions & 0 deletions include/dwarfw.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,17 @@ size_t dwarfw_cie_write_def_cfa_register(struct dwarfw_cie *cie, uint64_t reg,
FILE *f);
size_t dwarfw_cie_write_def_cfa_offset(struct dwarfw_cie *cie,
long long int offset, FILE *f);
size_t dwarfw_cie_write_def_cfa_expression(struct dwarfw_cie *cie,
const char *expr, size_t expr_len, FILE *f);
size_t dwarfw_cie_write_expression(struct dwarfw_cie *cie,
uint64_t reg, const char *expr, size_t expr_len, FILE *f);
size_t dwarfw_cie_write_val_offset(struct dwarfw_cie *cie, uint64_t reg,
long long int offset, FILE *f);

size_t dwarfw_cie_pad(struct dwarfw_cie *cie, size_t length, FILE *f);

// Call Frame Expressions
size_t dwarfw_op_write_deref(FILE *f);
size_t dwarfw_op_write_bregx(uint64_t reg, long long int offset, FILE *f);

#endif
11 changes: 11 additions & 0 deletions include/write.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef WRITE_H
#define WRITE_H

#include <stdint.h>
#include <stdio.h>

size_t write_u8(uint8_t b, FILE *f);
size_t write_u16(uint16_t b, FILE *f);
size_t write_u32(uint32_t b, FILE *f);

#endif
69 changes: 56 additions & 13 deletions instructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,7 @@
#include <stdbool.h>
#include "leb128.h"
#include "pointer.h"

static size_t write_u8(uint8_t b, FILE *f) {
return fwrite(&b, 1, sizeof(b), f);
}

static size_t write_u16(uint16_t b, FILE *f) {
return fwrite(&b, 1, sizeof(b), f);
}

static size_t write_u32(uint32_t b, FILE *f) {
return fwrite(&b, 1, sizeof(b), f);
}

#include "write.h"

#define OPCODE_LOW_MASK 0x3F

Expand Down Expand Up @@ -301,6 +289,61 @@ size_t dwarfw_cie_write_def_cfa_offset(struct dwarfw_cie *cie,
return written;
}

static size_t write_block(const char *buf, size_t buf_len, FILE *f) {
size_t n, written = 0;

if (!(n = leb128_write_u64(buf_len, f, 0))) {
return 0;
}
written += n;

if (!(n = fwrite(buf, 1, buf_len, f))) {
return 0;
}
written += n;

return written;
}

size_t dwarfw_cie_write_def_cfa_expression(struct dwarfw_cie *cie,
const char *expr, size_t expr_len, FILE *f) {
size_t n, written = 0;

if (!(n = write_u8(DW_CFA_def_cfa_expression, f))) {
return 0;
}
written += n;

if (!(n = write_block(expr, expr_len, f))) {
return 0;
}
written += n;

return written;
}

size_t dwarfw_cie_write_expression(struct dwarfw_cie *cie,
uint64_t reg, const char *expr, size_t expr_len, FILE *f) {
size_t n, written = 0;

if (!(n = write_u8(DW_CFA_expression, f))) {
return 0;
}
written += n;

if (!(n = leb128_write_u64(reg, f, 0))) {
return 0;
}
written += n;

if (!(n = write_block(expr, expr_len, f))) {
return 0;
}
written += n;

return written;
}

size_t dwarfw_cie_write_val_offset(struct dwarfw_cie *cie, uint64_t reg,
long long int offset, FILE *f) {
size_t n, written = 0;
Expand Down
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ lib_dwarfw = library(
meson.project_name(),
files(
'dwarfw.c',
'expressions.c',
'instructions.c',
'leb128.c',
'pointer.c',
'write.c',
),
include_directories: dwarfw_inc,
dependencies: [elf],
Expand Down
13 changes: 13 additions & 0 deletions write.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "write.h"

size_t write_u8(uint8_t b, FILE *f) {
return fwrite(&b, 1, sizeof(b), f);
}

size_t write_u16(uint16_t b, FILE *f) {
return fwrite(&b, 1, sizeof(b), f);
}

size_t write_u32(uint32_t b, FILE *f) {
return fwrite(&b, 1, sizeof(b), f);
}

0 comments on commit 322e118

Please sign in to comment.