lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <9d14c8fa-d61d-bd12-efd7-5a17f4f8cb35@loongson.cn>
Date: Wed, 11 Dec 2024 11:16:33 +0800
From: Tiezhu Yang <yangtiezhu@...ngson.cn>
To: Josh Poimboeuf <jpoimboe@...nel.org>
Cc: Huacai Chen <chenhuacai@...nel.org>, Peter Zijlstra
 <peterz@...radead.org>, loongarch@...ts.linux.dev,
 linux-kernel@...r.kernel.org
Subject: Re: [PATCH v5 03/10] objtool: Handle PC relative relocation type

On 12/10/2024 04:35 AM, Josh Poimboeuf wrote:
> On Sat, Dec 07, 2024 at 09:59:08AM +0800, Tiezhu Yang wrote:
>> +unsigned long arch_adjust_offset(struct reloc *reloc, struct reloc *table)
>> +{
>> +	switch (reloc_type(reloc)) {
>> +	case R_LARCH_32_PCREL:
>> +	case R_LARCH_64_PCREL:
>> +		if (reloc->sym->type == STT_SECTION)
>> +			return reloc->sym->offset + reloc_addend(reloc) -
>> +			       (reloc_offset(reloc) - reloc_offset(table));
>
> How does this even work?  i.e., why does the reloc offset (basically the
> jump table index) have anything to do with calculating the location of
> the instruction it's referencing?

Let me try to explain it, this is related with the relocation type.

In short, the jump table index is not used to calculate the location of
the destination instruction for absolute relocation types, but it should
be used for PC relative relocation types.

For the most part, an absolute relocation type is used for rodata.
In the case of STT_SECTION, reloc->sym->offset is always zero, and
for the other symbol types, reloc_addend(reloc) is always zero, thus it
can use a simple statement "reloc->sym->offset + reloc_addend(reloc)"
to obtain the symbol offset for various symbol types.

When compiling on LoongArch, there are some PC relative relocation types
for rodata, it needs to calculate the symbol offset with "S + A - PC" in
this case according to the spec of "ELF for the LoongArch Architecture",
the "PC" is the index of each jump table which is equal with the value
of reloc_offset(reloc) - reloc_offset(table).

I will add the above description to the commit message to make it clear.

>
>> +		else
>> +			return reloc->sym->offset;
>
> This also seems odd.  Why is the addend being ignored?  Shouldn't it
> point to the instruction's offset?

Sorry for that, I forgot to calculate the table size if the symbol type
is local label generated by GCC on LoongArch, after doing that, no need
to check the symbol type, just check whether the reloc types are PC
relative, the final code should be something like this:

unsigned long arch_adjust_offset(struct reloc *reloc, struct reloc *table)
{
         switch (reloc_type(reloc)) {
         case R_LARCH_32_PCREL:
         case R_LARCH_64_PCREL:
                 return reloc->sym->offset + reloc_addend(reloc) -
                        (reloc_offset(reloc) - reloc_offset(table));
         default:
                 return reloc->sym->offset + reloc_addend(reloc);
         }
}

Thanks,
Tiezhu


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ