| """ |
| 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.assertNotEqual(section.GetName(), ".absolute.absolute") |