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

Alexey Lapshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 20 15:20:30 PDT 2023


avl added a comment.

In D154638#4520579 <https://reviews.llvm.org/D154638#4520579>, @rastogishubham wrote:

> @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

Right. We need to clean(), sorry. I missed the fact that DIECloner enumerates several compile units.


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

https://reviews.llvm.org/D154638



More information about the llvm-commits mailing list