From 204f543cae7a5dc908264b49d558191d0ceb989c Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Sun, 10 Mar 2019 19:21:58 +0100 Subject: [PATCH] dwarf2: Align relocation within .debug_line section All relocations specify a byte address. As dwarf debug information is organized in octets, some relocations may not be aligned. While it might be possible to define special relocations that operate at an octet offset from their address, it's easier to ensure the relocations are aligned by padding with "nop" statements. In most dwarf sections this requirement is already fulfilled, only relocations for symbol address within the .debug_line section can be misaligned. * dwarf2dbg.c (out_set_addr): Align relocation within .debug_line. --- gas/ChangeLog | 4 ++++ gas/dwarf2dbg.c | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 5b209741f15..d08c09647c6 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,7 @@ +2019-03-13 Christian Eggers + + * dwarf2dbg.c (out_set_addr): Align relocation within .debug_line. + 2019-03-13 Christian Eggers * dwarf2dbg.c (out_debug_line): Pad size of .debug_line section. diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index 0b7b78c8c3a..2d316ddcb9c 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -1108,16 +1108,28 @@ get_frag_fix (fragS *frag, segT seg) /* Set an absolute address (may result in a relocation entry). */ +static void +out_inc_line_addr (int line_delta, addressT addr_delta); + static void out_set_addr (symbolS *sym) { expressionS exp; + addressT expr_addr, expr_addr_aligned; memset (&exp, 0, sizeof exp); - out_opcode (DW_LNS_extended_op); - out_uleb128 (sizeof_address + 1); - out_opcode (DW_LNE_set_address); + /* The expression at the bottom must be aligned to OCTETS_PER_BYTE. The + statements after the for loop will contribute 3 more octets. */ + expr_addr = frag_now_fix_octets () + 3; + expr_addr_aligned = (expr_addr + OCTETS_PER_BYTE - 1) & -OCTETS_PER_BYTE; + for ( ; expr_addr != expr_addr_aligned; expr_addr++) + out_inc_line_addr (0, 0); /* NOP */ + + out_opcode (DW_LNS_extended_op); /* 1 octet */ + out_uleb128 (sizeof_address + 1); /* 1 octet */ + + out_opcode (DW_LNE_set_address); /* 1 octet */ exp.X_op = O_symbol; exp.X_add_symbol = sym; exp.X_add_number = 0; -- 2.30.2