Symbols that have the section index of SHN_ABS were previously creating extra top level sections that contained the value of the symbol as if the symbol's value was an address. As far as I can tell, these symbol's values are not addresses, even if they do have a size. To make matters worse, adding these extra sections can stop address lookups from succeeding if the symbol's value + size overlaps with an existing section as these sections get mapped into memory when the image is loaded by the dynamic loader. This can cause stack frames to appear empty as the address lookup fails completely. This patch: - doesn't create a section for any SHN_ABS symbols - makes symbols that are absolute have values that are not addresses - add accessors to SBSymbol to get the value and size of a symbol as raw integers. Prevoiusly there was no way to access a symbol's value from a SBSymbol because the only accessors were: SBAddress SBSymbol::GetStartAddress(); SBAddress SBSymbol::GetEndAddress(); and these accessors would return an invalid SBAddress if the symbol's value wasn't an address - Adds a test to ensure no ".absolute.<symbol-name>" sections are created - Adds a test to test the new SBSymbol APIs Differential Revision: https://reviews.llvm.org/D131705
81 lines
3.9 KiB
Python
81 lines
3.9 KiB
Python
"""
|
|
Test absolute symbols in ELF files to make sure they don't create sections and
|
|
to verify that symbol values and size can still be accessed via SBSymbol APIs.
|
|
"""
|
|
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
import os
|
|
|
|
class TestAbsoluteSymbol(TestBase):
|
|
|
|
@no_debug_info_test
|
|
def test_absolute_symbol(self):
|
|
'''
|
|
Load an ELF file that contains two symbols:
|
|
- "absolute" which is a symbol with the section SHN_ABS
|
|
- "main" which is a code symbol in .text
|
|
|
|
Index st_name st_value st_size st_info st_other st_shndx Name
|
|
======= ---------- ------------------ ------------------ ----------------------------------- -------- -------- ===========================
|
|
[ 0] 0x00000000 0x0000000000000000 0x0000000000000000 0x00 (STB_LOCAL STT_NOTYPE ) 0x00 0
|
|
[ 1] 0x00000001 0x0000000000001000 0x0000000000000004 0x12 (STB_GLOBAL STT_FUNC ) 0x00 1 main
|
|
[ 2] 0x00000006 0xffffffff80000000 0x0000000000000009 0x10 (STB_GLOBAL STT_NOTYPE ) 0x00 SHN_ABS absolute
|
|
|
|
We used to create sections for symbols whose section ID was SHN_ABS
|
|
and this caused problems as the new sections could interfere with
|
|
with address resolution. Absolute symbols' values are not addresses
|
|
and should not be treated this way.
|
|
|
|
New APIs were added to SBSymbol to allow access to the raw integer
|
|
value and size of symbols so symbols whose value was not an address
|
|
could be accessed. Prior to this commit, you could only call:
|
|
|
|
SBAddress SBSymbol::GetStartAddress()
|
|
SBAddress SBSymbol::GetEndAddress()
|
|
|
|
If the symbol's value was not an address, you couldn't access the
|
|
raw value because the above accessors would return invalid SBAddress
|
|
objects if the value wasn't an address. New APIs were added for this:
|
|
|
|
uint64_t SBSymbol::GetValue()
|
|
uint64_t SBSymbol::GetSize();
|
|
'''
|
|
src_dir = self.getSourceDir()
|
|
yaml_path = os.path.join(src_dir, "absolute.yaml")
|
|
yaml_base, ext = os.path.splitext(yaml_path)
|
|
obj_path = self.getBuildArtifact("a.out")
|
|
self.yaml2obj(yaml_path, obj_path)
|
|
|
|
# Create a target with the object file we just created from YAML
|
|
target = self.dbg.CreateTarget(obj_path)
|
|
self.assertTrue(target, VALID_TARGET)
|
|
|
|
module = target.modules[0]
|
|
|
|
# Make sure the 'main' symbol is valid and has address values. Also make
|
|
# sure we can access the raw file address and size via the new APIS.
|
|
symbol = module.FindSymbol('main')
|
|
self.assertTrue(symbol.IsValid())
|
|
self.assertTrue(symbol.GetStartAddress().IsValid())
|
|
self.assertTrue(symbol.GetEndAddress().IsValid())
|
|
self.assertEqual(symbol.GetValue(), 0x1000)
|
|
self.assertEqual(symbol.GetSize(), 0x4)
|
|
|
|
# Make sure the 'absolute' symbol is valid and has no address values.
|
|
# Also make sure we can access the raw file address and size via the new
|
|
# APIS.
|
|
symbol = module.FindSymbol('absolute')
|
|
self.assertTrue(symbol.IsValid())
|
|
self.assertFalse(symbol.GetStartAddress().IsValid())
|
|
self.assertFalse(symbol.GetEndAddress().IsValid())
|
|
self.assertEqual(symbol.GetValue(), 0xffffffff80000000)
|
|
self.assertEqual(symbol.GetSize(), 9)
|
|
|
|
# Make sure no sections were created for the absolute symbol with a
|
|
# prefix of ".absolute." followed by the symbol name as they interfere
|
|
# with address lookups if they are treated like real sections.
|
|
for section in module.sections:
|
|
self.assertTrue(section.GetName() != ".absolute.absolute")
|