Skip to content

Commit

Permalink
Fix for mixed version loclists, tests (#521)
Browse files Browse the repository at this point in the history
  • Loading branch information
sevaa committed Nov 16, 2023
1 parent 5d31cad commit 8b97f5d
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 2 deletions.
2 changes: 1 addition & 1 deletion elftools/dwarf/dwarfinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def location_lists(self):
elif self.debug_loc_sec and self.debug_loclists_sec is None:
return LocationLists(self.debug_loc_sec.stream, self.structs, 4, self)
elif self.debug_loc_sec and self.debug_loclists_sec:
return LocationListsPair(self.debug_loclists_sec.stream, self.debug_loclists_sec.stream, self.structs, self)
return LocationListsPair(self.debug_loc_sec.stream, self.debug_loclists_sec.stream, self.structs, self)
else:
return None

Expand Down
4 changes: 3 additions & 1 deletion scripts/dwarfdump.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ def _desc_value(attr, die):
DW_AT_call_line=_desc_value,
DW_AT_call_file=_desc_decl_file,
DW_AT_abstract_origin=_desc_origin,
DW_AT_specification=_desc_spec
DW_AT_specification=_desc_spec,
DW_AT_call_site_value=lambda attr, die: _desc_expression(attr.value, die) if attr.form.startswith('DW_FORM_block') else _desc_locations(attr, die),
DW_AT_GNU_call_site_value=lambda attr, die: _desc_expression(attr.value, die) if attr.form.startswith('DW_FORM_block') else _desc_locations(attr, die),
)

class ReadElf(object):
Expand Down
48 changes: 48 additions & 0 deletions test/test_dwarf_llpair.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#-------------------------------------------------------------------------------
# elftools tests
#
# Seva Alekseyev (sevaa@sprynet.com)
# This code is in the public domain
#-------------------------------------------------------------------------------
import unittest
import os
from elftools.dwarf.locationlists import LocationListsPair, LocationParser
from elftools.elf.elffile import ELFFile

class TestLocListsPair(unittest.TestCase):
def test_llpair(self):
path = os.path.join('test', 'testfiles_for_unittests',
'dwarf_llpair.elf')
with open(path, 'rb') as f:
elffile = ELFFile(f)
dwarfinfo = elffile.get_dwarf_info(follow_links=False)
# This binary has both V4- loclists and V5+ loclists
self.assertTrue(dwarfinfo.debug_loc_sec and dwarfinfo.debug_loclists_sec)
# On this binary, it's a pair object
llp = dwarfinfo.location_lists()
self.assertTrue(isinstance(llp, LocationListsPair))
locparser = LocationParser(llp)

CUs = list(dwarfinfo.iter_CUs())

# The first CU is the v5 one
# Just in case, make sure we can hit a loclist in a V5 section
CU = CUs[0]
self.assertTrue(CU.header.version == 5)
# DW_TAG_variable for i inside b()
die = next(die for die in CU.iter_DIEs() if die.offset == 0x333)
ll = locparser.parse_from_attribute(die.attributes['DW_AT_location'], CU.header.version, die=die)
self.assertTrue(len(ll) == 8)

# The second CU is the V2 one
# Now hit a loclist in a V4- sectoin
# This would fail before 11/15/2023
CU = CUs[1]
self.assertTrue(CU.header.version == 2)
# DW_TAG_variable for i inside a()
die = next(die for die in CU.iter_DIEs() if die.offset == 0x796)
ll = locparser.parse_from_attribute(die.attributes['DW_AT_location'], CU.header.version, die=die)
self.assertTrue(len(ll) == 7)

if __name__ == '__main__':
unittest.main()
Binary file added test/testfiles_for_dwarfdump/dwarf_llpair.elf
Binary file not shown.
29 changes: 29 additions & 0 deletions test/testfiles_for_dwarfdump/llpair.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
To compile:
Linux x86-64
gcc version 8.3.0
gcc -gdwarf-2 -O2 -c llpaira.c
gcc -gdwarf-5 -O2 -o dwarf_llpair.elf llpair.c llpaira.o
*/
#include <stdlib.h>
#include <stdio.h>

extern void a(int n);

void b(int n)
{
int i;
for(i=0;i<n;i++)
printf("%d\n", i*i);
printf("%d\n", rand()*rand()*rand() + rand()*rand() + rand());
for(i=0;i<10;i++)
printf("%d\n", i*i+76543*i);
printf("%d\n", n);
}

int main()
{
b(rand());
return 0;
}
10 changes: 10 additions & 0 deletions test/testfiles_for_dwarfdump/llpaira.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <stdio.h>
void a(int n)
{
int i;
for(i=0;i<n;i++)
printf("%d\n", i*i);
for(i=0;i<10;i++)
printf("%d\n", i*i+76543*i);
printf("%d\n", n);
}
Binary file added test/testfiles_for_unittests/dwarf_llpair.elf
Binary file not shown.

0 comments on commit 8b97f5d

Please sign in to comment.