Thread overview
Can't add the allocated section to elf file using inline assembly
Nov 05, 2019
drug
Nov 05, 2019
kinke
Nov 05, 2019
drug
Nov 05, 2019
kinke
Nov 06, 2019
drug
Nov 07, 2019
drug
Nov 07, 2019
kinke
Nov 08, 2019
drug
Nov 30, 2019
Fangrui Song
November 05, 2019
Using clang the following code:
```
__asm__ __volatile__ (
	".ifndef _.stapsdt.base\n"                                     \
	".pushsection .stapsdt.base,\"aG\",\"progbits\", .stapsdt.base, comdat\n" \
	".weak _.stapsdt.base\n"                                       \
	".hidden _.stapsdt.base\n"                                     \
	"_.stapsdt.base: .space 1\n"                                   \
	".size _.stapsdt.base,1\n"                                     \
	".popsection\n"                                                \
	".endif"
);
```
adds the allocated section to elf file:
```
$ clang source/sdt_expanded.c -ocsdt
$ readelf -x .stapsdt.base csdt

Hex dump of section '.stapsdt.base':
  0x000aa442 00                                  .

```
I translated this code to ldc:
```
__asm (
	.ifndef _.stapsdt.base
	.pushsection .stapsdt.base,\"aG\",\"progbits\", .stapsdt.base, comdat
	.weak _.stapsdt.base
	.hidden _.stapsdt.base
	_.stapsdt.base: .space 1
	.size _.stapsdt.base,1
	.popsection
	.endif`, ""
);
```
but ldc (1.18) do not add the section without any error.
```
$ dub --compiler=ldc2
$ readelf -x .stapsdt.base usdt
readelf: Warning: Section '.stapsdt.base' was not dumped because it does not exist!
```

If I make the section non allocated (removing `a` from \"aG\") then the section is added.
```
$ readelf -x .stapsdt.base usdt

Hex dump of section '.stapsdt.base':
  0x00000000 00                                  .
```
But this section needs to be allocated.

Is it a bug or I misuse something? Is there way to work around it?
November 05, 2019
On Tuesday, 5 November 2019 at 09:49:35 UTC, drug wrote:
> Is it a bug or I misuse something? Is there way to work around it?

I assume you're looking for module-level assembly, not contained in a function; that's what we lower DMD-style asm to, but isn't supported for __asm AFAIK.

Anyway, I recommend comparing the generated assembly by clang (`-S` IIRC) and LDC (-output-s) to figure out the difference.
November 05, 2019
On 11/5/19 2:13 PM, kinke wrote:
> On Tuesday, 5 November 2019 at 09:49:35 UTC, drug wrote:
>> Is it a bug or I misuse something? Is there way to work around it?
> 
> I assume you're looking for module-level assembly, not contained in a function; that's what we lower DMD-style asm to, but isn't supported for __asm AFAIK.
> 
> Anyway, I recommend comparing the generated assembly by clang (`-S` IIRC) and LDC (-output-s) to figure out the difference.

Thanks for hint! Output of clang and ldc is identical

clang:
```
  #NO_APP
  #APP
  .section	.stapsdt.base,"aG",@progbits,.stapsdt.base,comdat
  .weak	_.stapsdt.base
  .hidden	_.stapsdt.base
_.stapsdt.base:
  .zero	1
  .size	_.stapsdt.base, 1
  .text
```
ldc
```
  .section	.stapsdt.base,"aG",@progbits,.stapsdt.base,comdat
  .weak	_.stapsdt.base
  .hidden	_.stapsdt.base
_.stapsdt.base:
  .zero	1
  .size	_.stapsdt.base, 1
```

Moreover, if I remove 'a' from "aG" the section appears in the binary. So I guess the generated assembly is correct and the problem is in another place.
How can I compile .s file? I tried
```
clang app.s -L/path/to/ldc/lib/ -ldruntime-ldc -lphobos2-ldc -Wl,pie -o app2
```
but I get
```
app.s:33187:2: error: unknown section type
        .hidden DW.ref._d_eh_personality
```
November 05, 2019
On Tuesday, 5 November 2019 at 12:20:14 UTC, drug wrote:
> How can I compile .s file?

The .s file is just the textual representation of the .o object file, so compiling it shouldn't be necessary.

> So I guess the generated assembly is correct and the problem is in another place.

I'd look at the surrounding assembly as well, probably easiest when wrapping your inline asm in a trivial `extern(C++) void foo() { ... }` (no other functions, and using -betterC) for direct comparability with clang's output.
November 06, 2019
On 11/5/19 7:55 PM, kinke wrote:
> On Tuesday, 5 November 2019 at 12:20:14 UTC, drug wrote:
>> How can I compile .s file?
> 
> The .s file is just the textual representation of the .o object file, so compiling it shouldn't be necessary.

Ah, I see, thanks

> 
>> So I guess the generated assembly is correct and the problem is in another place.
> 
> I'd look at the surrounding assembly as well, probably easiest when wrapping your inline asm in a trivial `extern(C++) void foo() { ... }` (no other functions, and using -betterC) for direct comparability with clang's output.

I try to add support for SystemTap userland probes in D. They shall be `injectable` in any place in your source.
I took a look at the surrounding assembly and as I understood considering my low skill the problem was in this section definition:
```
.section	".linker-options","e",@llvm_linker_options
```
clang complained about the code after this line no matter what code it was. I read the documentation about section directive https://sourceware.org/binutils/docs/as/Section.html but didn't see anything wrong
November 07, 2019
On 11/5/19 7:55 PM, kinke wrote:
> On Tuesday, 5 November 2019 at 12:20:14 UTC, drug wrote:
>> How can I compile .s file?
> 
> The .s file is just the textual representation of the .o object file, so compiling it shouldn't be necessary.
> 
>> So I guess the generated assembly is correct and the problem is in another place.
> 
> I'd look at the surrounding assembly as well, probably easiest when wrapping your inline asm in a trivial `extern(C++) void foo() { ... }` (no other functions, and using -betterC) for direct comparability with clang's output.

I found that if I compile sources to object file by means of ldc2 and then link it using clang then the resulting binary has this section.
```
ldc2 source/app.d source/sdt.d -c -ofsdt.o
clang sdt.o -osdt
```
if I use ldc2 for everything:
```
ldc2 source/app.d source/sdt.d -of sdt
```
The resulting binary has no the section.

What can be the reason of this?
November 07, 2019
On Thursday, 7 November 2019 at 14:58:24 UTC, drug wrote:
> What can be the reason of this?

--gc-sections applied by LDC by default - use -disable-linker-strip-dead to keep unreferenced sections.
November 08, 2019
On 11/7/19 6:20 PM, kinke wrote:
> On Thursday, 7 November 2019 at 14:58:24 UTC, drug wrote:
>> What can be the reason of this?
> 
> --gc-sections applied by LDC by default - use -disable-linker-strip-dead to keep unreferenced sections.

Thank you very much! It works now.

What is the best way to create a reference to this section to prevent its stripping?
November 30, 2019
On 2019-11-08, drug wrote:
>On 11/7/19 6:20 PM, kinke wrote:
>>On Thursday, 7 November 2019 at 14:58:24 UTC, drug wrote:
>>>What can be the reason of this?
>>
>>--gc-sections applied by LDC by default - use -disable-linker-strip-dead to keep unreferenced sections.
>
>Thank you very much! It works now.
>
>What is the best way to create a reference to this section to prevent its stripping?

Use the .reloc directive and an R_*_NONE (no-op) relocation to reference
the section from a known-live section (e.g. main). As an example:

import ldc.llvmasm;

void foo() {
  __asm!void(
    `.pushsection .stapsdt.base,"aG",%progbits,.stapsdt.base,comdat
     .weak _.stapsdt.base
     .hidden _.stapsdt.base
     _.stapsdt.base: .space 1
     .size _.stapsdt.base,1
     .popsection`, ""
  );
}

void main() {
  __asm!void(".reloc 0, R_X86_64_NONE, .stapsdt.base", "");
}

This works with GNU ld, gold and lld, and it does not require
-disable-linker-strip-dead. Parsing R_*_NONE requires llvm 9 or newer.
I added .reloc for x86/ARM/AArch64/PowerPC in May 2019. R_MIPS_NONE
worked even before that time.