2

I have a one-line reduction of my x86-64 assembly program that gets a relocation truncation error:

movq %rdx,8(%rdi)

If you put that line, alone, in t.s it will assemble successfully with the command

as -o t.o -g -al=t.lst t.s

Note the -g option for debugging information.

After this, attempting to link this into an executable with this command:

ld -o t t.o

Results in these TWO error messages:

t.o:t.s:1:(.stab+0x14): relocation truncated to fit: R_X86_64_32 against `.text'
t.o:t.s:1:(.stab+0x20): relocation truncated to fit: R_X86_64_32 against `.text'

The salient lines of t.lst are:

1 0000 48895708       movq %rdx,8(%rdi)
1      90909090
1      90909090
1      90909090

There is no linker error if I leave the -g option out of the assembler command, so the problem might be in the debugger data rather than the executable portion of the output file.

This instruction was giving me trouble within a larger program, but as you can see, in isolation it is still a problem.

Why did I get a relocation truncation from this particular instruction? Would a linker option make a valid and debuggable program?

cardiff space man
  • 1,442
  • 14
  • 31
  • 2
    Interesting. It seems that you add stabs debugging information, which is an obsolete format. Try to add DWARF debugging information, that should work. – fuz May 12 '18 at 20:30
  • Use `gcc -g -c t.S` to assemble with debug info. Use `gcc -g -c -v t.S` to have gcc print out the `as` command it used. (And BTW, I'd recommend naming hand-written asm source files with capital-S extensions. `.s` is for machine-generated source code, like compiler output; `gcc -S t.c` will overwrite `t.s` without asking.) – Peter Cordes May 12 '18 at 21:40
  • @PeterCordes Files with suffix `.S` are passed through the preprocessor before assembly. Only name your files `foo.S` if that's what you want. – fuz May 12 '18 at 22:22
  • @fuz: That's still the standard / recommended naming convention whether you need preprocessing or not, according to what I've seen. You *can* assemble it with `as` directly if you don't want CPP. – Peter Cordes May 12 '18 at 22:24
  • 1
    @PeterCordes Thanks for the naming convention tip. The project in question is machine-generating the code. You're seeing a piece of the generated assembly code. Also it was valuable to see the `as` command included `-gdwarf2`. – cardiff space man May 12 '18 at 22:24
  • Now I need an answer to accept. :) Specifying dwarf2 does take care of it. – cardiff space man May 12 '18 at 22:25
  • @PeterCordes Your experience does not match the [traditional UNIX convention](https://man.openbsd.org/4.4BSD-Lite2/cc). – fuz May 12 '18 at 22:43
  • @fuz: That compiler documentation doesn't say anything about hand-written `.s` files. I read it as saying you might want to use `-S` to get a `.s` and then assemble it. [This comment](https://stackoverflow.com/questions/34098596/assembly-files-difference-between-a-s-asm#comment55950460_34098830) (which I incorporated into my answer) argues the same point, and in [What are .S files ?](https://stackoverflow.com/q/10285410) nobody says "you should use `.s` if you don't want CPP". And nobody silently used `.s` instead of `.S` in their answer. – Peter Cordes May 13 '18 at 01:22
  • @cardiffspaceman: You can answer you own question; it'd be great if you took the time to write up an answer incorporating tips from comments like `gcc -v` and the resulting `-gdwarf2`. – Peter Cordes May 13 '18 at 01:24
  • 1
    The answer I'd write, because it's the answer I'd want to read, would explain how there could have been truncation given that the instruction has no fields that need relocation. Using objdump I see that the t.o file has stabs but they are all line numbers or file path information. I'm researching this but I won't be bothered if someone beats me to it. – cardiff space man May 13 '18 at 03:19
  • @PeterCordes The answer you linked to is wrong. The right answer is in the manpage I linked: The suffix purely exists to indicates whether you want the preprocessor to run on your assembly or not. Just because people don't know this and write wrong answers out of ignorance doesn't make this any more right. BTW, the documentation clearly says: “.s Assembler source; assemble” and “.S Assembler source; preprocess, assemble.” An *assembler source* is clearly a source file written in assembly. – fuz May 13 '18 at 06:50
  • @fuz: Yeah, that's a reasonable argument. The main thing for me is that `gcc -S foo.c` will clobber `foo.s` without any warning, and you do sometimes want to have `foo.c` and `foo.[sS]`, at least while experimenting. (Although they both compile to`foo.o`, so that's often a bad plan in a bigger project if they're in the same directory.) – Peter Cordes May 13 '18 at 06:56
  • @PeterCordes Rename `foo.s` to `foo.1.s` or something like that to alleviate this issue but don't rename to `foo.S` without understanding what the difference is. – fuz May 13 '18 at 07:44
  • The .s vs .S stuff is fascinating. I am still researching the status of stabs without finding, you know, the tell-tale frame from the movie where Charlton Heston depicts the man carrying the tablet down from the mountain that says stabs is wrong. But the gist of what I'm finding by googling 'stabs x86_64' is that stabs can't work on x86_64 for some reason. – cardiff space man May 13 '18 at 23:27

0 Answers0