1

Suppose you have the following assembly files:

  .file "print.s"
  .intel_syntax noprefix

  .text

  .globl _start
  .type _start, @function
_start:
  mov rax, 1
  mov rdi, 1
  lea rsi, hello_string
  mov rdx, 14
  syscall
  mov rax, 60
  mov rdi, 0
  syscall
  .size _start, .-_start

and

  .file "string.s"
  .intel_syntax noprefix

  .data

  .globl hello_string
  .type hello_string, @object
hello_string:
  .string "Hello, world!\n"
  .size hello_string, 14

If you run as string.s -o string.o, as print.s -o print.o and then ld *.o -o hello.elf, you get a executable file which prints Hello, world!. Now suppose that you change the _start label in print.s to print and you have the following C file:

// main.c
void print(void);

int main (void) {
  print();
  return 0;
}

I want to run something like gcc -o main.elf main.c string.s print.s to take my two assembly files and link them into the standard C runtime. This command as written doesn't work. I get the following error message:

/usr/bin/ld: /tmp/ccc1yRif.o: relocation R_X86_64_32S against symbol `hello_string' can not be used when making a shared object; recompile with -fPIC

I can't figure out how to correctly use the -fPIC flag to make things work. I am not even sure if that is what I should be doing. I could try and use the inline assembler to do this, but for my actual use cases, that would be extremely annoying and I would much rather learn how to correctly link assembly chunks into my C programs. I haven't been able to find much information about this online.

Question: How do you correctly use the GNU linker to link assembly files into the C runtime?

EDIT: In How to link a C object file with a Assembly Language object file?, the OP is asking about how to solve a similar linking problem just using ld. I want to use gcc which is the recommended solution in the linked question, but I can't even get that to work.

DBr
  • 143
  • 1
  • 8
  • Possible duplicate of [How to link a C object file with a Assembly Language object file?](https://stackoverflow.com/questions/8691138/how-to-link-a-c-object-file-with-a-assembly-language-object-file) – Robin Green May 05 '18 at 05:55
  • @RobinGreen: Hi Robin, that question is a little different. The OP is asking about how do this linking just using `ld`. I want to use `gcc`, which is their recommended answer, but it isn't working for me and I don't understand why – DBr May 05 '18 at 06:10
  • But you are not calling it the same way as in the recommended answer. Obviously you can leave off the `-m32` because you are writing 64-bit code, but it looks like you should output a `.o` not a `.elf`. – Robin Green May 05 '18 at 06:11
  • I get what you are saying. Maybe I should be producing an object file from my c file first and then combining the three object files together with gcc. However, when I try and compile exactly the OPs C file `main2.c` using `gcc main2.c -o main2.o`, the linker errors out and complains about an undefined reference to `strlength` – DBr May 05 '18 at 06:21
  • @RobinGreen: Do you know how to make gcc output a relocatable object file? I cant see the flag for it in the manual. The -o outputs an elf file which can be directly loaded by the opsys. This isn't relocatable so cant be linked anymore – DBr May 05 '18 at 06:25

1 Answers1

1

OK, so I have figured it out now. The error message seems to be telling me that gcc is trying to make a shared object. This lead me to the question gcc 6.2.0 is attempting to create shared object when it shouldn't?

The solution is to run gcc -no-pie main.c string.s print.s -o main.elf

according to the man page, -no-pie tells gcc to not produce a position indipendent executable.

DBr
  • 143
  • 1
  • 8
  • 1
    A better solution is to write C code that defines and refers to a string (e.g., a small function that returns the address of the string), compile it to assembly, examine the assembly to see how the compiler refers to the string in a position-independent way, then use that technique in your own code. – Eric Postpischil May 05 '18 at 10:55
  • @EricPostpischil: Yeah that is a good idea! Thanks for the thought – DBr May 06 '18 at 23:21