[PATCH v3] LoongArch: Batch-delete bytes at the end of each relax trip
WANG Xuerui
i.swmail@xen0n.name
Tue Jun 17 01:59:36 GMT 2025
On 6/16/25 18:12, mengqinggang wrote:
>
> 在 2025/6/16 下午4:23, WANG Xuerui 写道:
>> On 6/16/25 14:52, mengqinggang wrote:
>>>
>>> 在 2025/6/14 下午10:15, WANG Xuerui 写道:
>>>> [snip]
>>>>
>>>> +static void
>>>> +loongarch_relax_perform_deletes (bfd *abfd, asection *sec,
>>>> + struct bfd_link_info *link_info)
>>>> {
>>>> unsigned int i, symcount;
>>>> bfd_vma toaddr = sec->size;
>>>> @@ -4737,30 +4877,72 @@ loongarch_relax_delete_bytes (bfd *abfd,
>>>> Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
>>>> unsigned int sec_shndx = _bfd_elf_section_from_bfd_section
>>>> (abfd, sec);
>>>> struct bfd_elf_section_data *data = elf_section_data (sec);
>>>> - bfd_byte *contents = data->this_hdr.contents;
>>>> + bfd_byte *contents = data->this_hdr.contents, *contents_end = NULL;
>>>> struct relr_entry *relr = loongarch_elf_section_data (sec)->relr;
>>>> struct loongarch_elf_link_hash_table *htab =
>>>> loongarch_elf_hash_table (link_info);
>>>> struct relr_entry *relr_end = NULL;
>>>> + splay_tree pdops = htab->pending_delete_ops;
>>>> + splay_tree_node node1 = NULL, node2 = NULL;
>>>> if (htab->relr_count)
>>>> relr_end = htab->relr + htab->relr_count;
>>>> - /* Actually delete the bytes. */
>>>> - sec->size -= count;
>>>> - memmove (contents + addr, contents + addr + count, toaddr - addr
>>>> - count);
>>>> + BFD_ASSERT (pdops != NULL);
>>>> + node1 = splay_tree_min (pdops);
>>>> +
>>>> + if (node1 == NULL)
>>>> + /* No pending delete ops, nothing to do. */
>>>> + return;
>>>> +
>>>> + /* Actually delete the bytes. For each delete op the pointer
>>>> arithmetics
>>>> + look like this:
>>>> +
>>>> + node1->key -\ /- node2->key
>>>> + |<-- op1->size -->| |
>>>> + v v v
>>>> + ...---------------xxxxxxxxxxxxxxxxxxx---------xxxxxxxxxxx----...
>>>> + ^
>>>> + node1->key + op1->size -/
>>>
>>> These pointers seem to not change after delete op. The delete op
>>> just copy (node1->key+op1->size, node2->key) to node1->key.
>>>
>> Sorry I didn't understand this, isn't there a "node1 = node2" below
>> in the for statement's expression 3 position? But indeed the memmove
>> destination is not node1->key as the illustration might suggest
>> otherwise, maybe I can clarify that in a v4. What do you think?
>
> I mean the memmove cant change the values of pointers in the
> illustration, it just copy a memory.
>
> The illustrations seem to show (node1->key + op1->size) move to
> node2->key after delete op.
>
>
What about this?
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index aed1ef26d49..dc6251486c0 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4898,12 +4898,18 @@ loongarch_relax_perform_deletes (bfd *abfd, asection *sec,
/* Actually delete the bytes. For each delete op the pointer arithmetics
look like this:
- node1->key -\ /- node2->key
- |<-- op1->size -->| |
- v v v
- ...---------------xxxxxxxxxxxxxxxxxxx---------xxxxxxxxxxx----...
- ^
- node1->key + op1->size -/
+ node1->key -\ /- node2->key
+ |<- op1->size ->| |
+ v v v
+ ...-DDDDDDD-------xxxxxxxxxxxxxxxxxSSSSSSSxxxxxxxxxx----...
+ ^ ^
+ | node1->key + op1->size -/
+ \- contents_end
+
+ where the "S" and "D" bytes are the memmove's source and destination
+ respectively. In case node1 is the first op, contents_end is initialized
+ to the op's start; in case node2 == NULL, the chunk's end is the section's
+ end.
For memmove, we need to translate offsets to pointers by adding them to
`contents`. */
If it sounds good I'll send v4.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20250617/8847dc89/attachment.htm>
More information about the Binutils
mailing list