[PATCH] D154638: Emit a .debug_addr section with dsymutil

Shubham Sandeep Rastogi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 20 15:01:38 PDT 2023


rastogishubham added a comment.

@avl

We have to clear the `AddrPool` after one compile unit is processed. If we consider the following test case with the attached files:

F28371074: test.o <https://reviews.llvm.org/F28371074>

F28371077: test.map <https://reviews.llvm.org/F28371077>

when using the following command:
`dwarfdump -a -v test.o| less`

The output looks like:

.debug_info contents:
0x00000000: Compile Unit: length = 0x0000004d, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x00000051)

0x0000000c: DW_TAG_compile_unit [1] *

  DW_AT_producer [DW_FORM_string]   ("by_hand")
  DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
  DW_AT_name [DW_FORM_string]       ("GoodCU")
  DW_AT_low_pc [DW_FORM_addrx]      (indexed (00000000) address = 0x0000000000001130)
  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000010)
  DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000008)

0x0000002b:   DW_TAG_subprogram [2] * (0x0000000c)

  DW_AT_name [DW_FORM_string]     ("foo")
  DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000001130)
  DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
  DW_AT_type [DW_FORM_ref4]       (cu + 0x003e => {0x0000003e} "int")

0x0000003d:     NULL

0x0000003e:   DW_TAG_base_type [3]   (0x0000000c)

  DW_AT_name [DW_FORM_string]     ("int")

0x00000043:   DW_TAG_variable [4]   (0x0000000c)

  DW_AT_name [DW_FORM_string]     ("var1")
  DW_AT_type [DW_FORM_ref4]       (cu + 0x003e => {0x0000003e} "int")
  DW_AT_location [DW_FORM_exprloc]        (DW_OP_addrx 0x0)

0x00000050:   NULL
0x00000051: Compile Unit: length = 0x0000004d, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0031, addr_size = 0x08 (next unit at 0x000000a2)

0x0000005d: DW_TAG_compile_unit [1] *

  DW_AT_producer [DW_FORM_string]   ("by_hand")
  DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
  DW_AT_name [DW_FORM_string]       ("BadCU")
  DW_AT_low_pc [DW_FORM_addrx]      (indexed (00000000) address = 0x0000000000000010)
  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000010)
  DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000018)

0x0000007b:   DW_TAG_subprogram [2] * (0x0000005d)

  DW_AT_name [DW_FORM_string]     ("foo1")
  DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000000010)
  DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
  DW_AT_type [DW_FORM_ref4]       (cu + 0x003e => {0x0000008f} "int")

0x0000008e:     NULL

0x0000008f:   DW_TAG_base_type [3]   (0x0000005d)

  DW_AT_name [DW_FORM_string]     ("int")

0x00000094:   DW_TAG_variable [4]   (0x0000005d)

  DW_AT_name [DW_FORM_string]     ("var1")
  DW_AT_type [DW_FORM_ref4]       (cu + 0x003e => {0x0000008f} "int")
  DW_AT_location [DW_FORM_exprloc]        (DW_OP_addrx 0x0)

0x000000a1:   NULL

.debug_addr contents:
0x00000000: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
Addrs: [
0x0000000000001130
]
0x00000010: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
Addrs: [
0x0000000000000010

Notice how the debug_addr section only has one address for each compile unit

If we use the following testcase:
`llvm-project/build_ninja/bin/dsymutil -y test.map -o test.o.dSYM`
`dwarfdump -a -v test.o.dSYM | less`
and dsymutil does not clear the `AddrPool`

.debug_info contents:
0x00000000: Compile Unit: length = 0x0000004b, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000004f)

0x0000000c: DW_TAG_compile_unit [1] *

  DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "by_hand")
  DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
  DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000009] = "GoodCU")
  DW_AT_low_pc [DW_FORM_addrx]      (indexed (00000000) address = 0x0000000000012260)
  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000010)
  DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000008)

0x00000024:   DW_TAG_subprogram [2]   (0x0000000c)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000010] = "foo")
  DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000012260)
  DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000036 "int")

0x00000036:   DW_TAG_base_type [3]   (0x0000000c)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000014] = "int")

0x0000003b:   DW_TAG_variable [4]   (0x0000000c)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000018] = "var1")
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000036 "int")
  DW_AT_location [DW_FORM_exprloc]        (DW_OP_addr 0x12260)

0x0000004e:   NULL
0x0000004f: Compile Unit: length = 0x0000004b, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000009e)

0x0000005b: DW_TAG_compile_unit [1] *

  DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "by_hand")
  DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
  DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000001d] = "BadCU")
  DW_AT_low_pc [DW_FORM_addrx]      (indexed (00000001) address = 0x0000000000010010)
  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000010)
  DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000018)

0x00000073:   DW_TAG_subprogram [2]   (0x0000005b)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000023] = "foo1")
  DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000001) address = 0x0000000000010010)
  DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000085 "int")

0x00000085:   DW_TAG_base_type [3]   (0x0000005b)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000014] = "int")

0x0000008a:   DW_TAG_variable [4]   (0x0000005b)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000018] = "var1")
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000085 "int")
  DW_AT_location [DW_FORM_exprloc]        (DW_OP_addr 0x10010)

0x0000009d:   NULL

.debug_addr contents:
0x00000000: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
Addrs: [
0x0000000000012260
]
0x00000010: Address table header: length = 0x00000014, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
Addrs: [
0x0000000000012260
0x0000000000010010
]

Notice how the debug_addr section for the second compile unit, contains the address in the first compile unit as well.

But if we clear the `AddrPool`

`llvm-project/build_ninja/bin/dsymutil -y test.map -o test.o.dSYM`
`dwarfdump -a -v test.o.dSYM | less`

.debug_info contents:
0x00000000: Compile Unit: length = 0x0000004b, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000004f)

0x0000000c: DW_TAG_compile_unit [1] *

  DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "by_hand")
  DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
  DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000009] = "GoodCU")
  DW_AT_low_pc [DW_FORM_addrx]      (indexed (00000000) address = 0x0000000000012260)
  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000010)
  DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000008)

0x00000024:   DW_TAG_subprogram [2]   (0x0000000c)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000010] = "foo")
  DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000012260)
  DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000036 "int")

0x00000036:   DW_TAG_base_type [3]   (0x0000000c)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000014] = "int")

0x0000003b:   DW_TAG_variable [4]   (0x0000000c)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000018] = "var1")
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000036 "int")
  DW_AT_location [DW_FORM_exprloc]        (DW_OP_addr 0x12260)

0x0000004e:   NULL
0x0000004f: Compile Unit: length = 0x0000004b, format = DWARF32, version = 0x0005, unit_type = DW_UT_compile, abbr_offset = 0x0000, addr_size = 0x08 (next unit at 0x0000009e)

0x0000005b: DW_TAG_compile_unit [1] *

  DW_AT_producer [DW_FORM_strp]     ( .debug_str[0x00000001] = "by_hand")
  DW_AT_language [DW_FORM_data2]    (DW_LANG_C_plus_plus)
  DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000001d] = "BadCU")
  DW_AT_low_pc [DW_FORM_addrx]      (indexed (00000000) address = 0x0000000000010010)
  DW_AT_high_pc [DW_FORM_data8]     (0x0000000000000010)
  DW_AT_addr_base [DW_FORM_sec_offset]      (0x00000018)

0x00000073:   DW_TAG_subprogram [2]   (0x0000005b)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000023] = "foo1")
  DW_AT_low_pc [DW_FORM_addrx]    (indexed (00000000) address = 0x0000000000010010)
  DW_AT_high_pc [DW_FORM_data8]   (0x0000000000000010)
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000085 "int")

0x00000085:   DW_TAG_base_type [3]   (0x0000005b)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000014] = "int")

0x0000008a:   DW_TAG_variable [4]   (0x0000005b)

  DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000018] = "var1")
  DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000085 "int")
  DW_AT_location [DW_FORM_exprloc]        (DW_OP_addr 0x10010)

0x0000009d:   NULL

.debug_addr contents:
0x00000000: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
Addrs: [
0x0000000000012260
]
0x00000010: Address table header: length = 0x0000000c, format = DWARF32, version = 0x0005, addr_size = 0x08, seg_size = 0x00
Addrs: [
0x0000000000010010
]

Notice how the debug_addr section matches the one in the object file, and doesn't contain a copy of the address from the first compile unit


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154638/new/

https://reviews.llvm.org/D154638



More information about the llvm-commits mailing list