ld: Symbol type of a symbol assignment?

Fangrui Song i@maskray.me
Mon Aug 3 23:41:30 GMT 2020


cat > a.s <<e
  .type fun,@function
  .type ifunc,@gnu_indirect_function
  .type obj,@object
  .globl _start, fun, ifunc, obj
  _start: fun: ifunc: obj: ret
e
as a.s -o a.o
ld.bfd a.o --defsym 'bar=ifunc+1' => bar is STT_GNU_IFUNC

Let's try some other expressions:
* --defsym 'bar=ifunc+ifunc' => bar is STT_NOTYPE. The sum is not
   meaningful, so downgrading to STT_NOTYPE seems fine.

The forms '--defsym' supports are limited. So I'll switch to -T for
other symbol assignments.

* -T =(printf 'bar = obj - obj;') => bar is STT_NOTYPE.
* -T =(printf 'bar = obj / 2;') => bar is STT_OBJECT.
   Division does not create a meaningful symbol reference, so I expected STT_NOTYPE.
   I don't get upset by STT_OBJECT, though.
* -T =(printf 'bar = obj * 2;') => similarly, bar is STT_OBJECT.
* -T =(printf 'bar = !obj;') => bar is STT_OBJECT.
* -T =(printf 'bar = ~obj;') => bar is STT_OBJECT.
* -T =(printf 'bar = -obj;') => bar is STT_OBJECT.
* ...

So what are rules for the symbol type? For direct aliases like `bar = ifunc`,
I think having the same type as the aliased symbol is fine. This is even
desired because in some backends, symbol types can affect relocation processing
(for example, if the referenced symbol is not STT_FUNC, no interworking is performed)

For `ifunc+1`, I am less sure that retaining the original type is reasonable:
how can you tell there is another entity of the same type at the plus 1 address ?

For other expressions, I am even less sure that retaining the original type is reasonable.


More information about the Binutils mailing list