[PATCH] Fix IFUNC symbols assembly mode.
Rafael EspĂndola
rafael.espindola at gmail.com
Mon Jan 6 14:12:23 PST 2014
On 6 January 2014 13:50, Roman Divacky <rdivacky at freebsd.org> wrote:
> Actually, the merging rules are not so simple, this is my attempt to simulate
> what gnu as is doing:
>
> Index: lib/MC/ELFObjectWriter.cpp
> ===================================================================
> --- lib/MC/ELFObjectWriter.cpp (revision 198593)
> +++ lib/MC/ELFObjectWriter.cpp (working copy)
> @@ -546,6 +546,35 @@
> // Binding and Type share the same byte as upper and lower nibbles
> uint8_t Binding = MCELF::GetBinding(OrigData);
> uint8_t Type = MCELF::GetType(Data);
> +
> + // Propagation rules:
> + // IFUNC > FUNC > OBJECT > NOTYPE
> + // TLS_OBJECT > OBJECT > NOTYPE
> + //
> + // dont let the new type degrade the old type
These need tests. Can IFUNC or FUNC show up in a comparison with
TLS_OBJECT? Please try to refactor this into a pair of functions like
unsigned getTypePreference(uint8_t Type) {....}
bool compareTypes(uint8_t TypeA, uint8_t TypeB) { return
getTypePreference(TypeA) > getTypePreference(TypeB); }
> + switch (MCELF::GetType(OrigData)) {
> + default:
> + break;
> + case ELF::STT_GNU_IFUNC:
> + if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
> + Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
> + Type = ELF::STT_GNU_IFUNC;
> + break;
> + case ELF::STT_FUNC:
> + if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
> + Type == ELF::STT_TLS)
> + Type = ELF::STT_FUNC;
> + break;
> + case ELF::STT_OBJECT:
> + if (Type == ELF::STT_NOTYPE)
> + Type = ELF::STT_OBJECT;
> + break;
> + case ELF::STT_TLS:
> + if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
> + Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
> + Type = ELF::STT_TLS;
> + break;
> + }
> uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
>
> // Other and Visibility share the same byte with Visibility using the lower
>
>
> On Sat, Jan 04, 2014 at 03:49:28PM +0100, Roman Divacky wrote:
>> Hi,
>>
>> .globl memcpy
>> .type memcpy, @gnu_indirect_function
>> .set memcpy,resolve_memcpy
>>
>> is currently misassembled (the memcpy is of type STT_FUNC instead of
>> STT_GNU_IFUNC).
>>
>> This patch fixes it:
>>
>> Index: lib/MC/ELFObjectWriter.cpp
>> ===================================================================
>> --- lib/MC/ELFObjectWriter.cpp (revision 198480)
>> +++ lib/MC/ELFObjectWriter.cpp (working copy)
>> @@ -546,6 +546,9 @@
>> // Binding and Type share the same byte as upper and lower nibbles
>> uint8_t Binding = MCELF::GetBinding(OrigData);
>> uint8_t Type = MCELF::GetType(Data);
>> + // Keep IFUNC type.
>> + if (Type == ELF::STT_FUNC && MCELF::GetType(OrigData) == ELF::STT_GNU_IFUNC)
>> + Type = ELF::STT_GNU_IFUNC;
>> uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
>>
>> // Other and Visibility share the same byte with Visibility using the lower
>> Index: test/MC/ELF/type.s
>> ===================================================================
>> --- test/MC/ELF/type.s (revision 198480)
>> +++ test/MC/ELF/type.s (working copy)
>> @@ -22,9 +22,9 @@
>> .type func, at function
>> .type func, at object
>>
>> -ifunc:
>> .global ifunc
>> .type ifunc, at gnu_indirect_function
>> + .set ifunc,func
>>
>> tls:
>> .global tls
>>
>> I track this in #18372. Is the patch ok to commit?
>>
>> Roman
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list