[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