0

I am working on a utility in assembler (x86, NASM 2.13, gcc 7.50, Ubuntu 18.X) to be called from C. The problem that I am running into is that the string constant addresses seem to be lost in the making process, so messages are not printing. I can see the string constants in the final binary.

This is the sample assembler code

SECTION .data
    error_len_message: db  "test", 10
    error_len_message_len: equ $-error_len_message
    
SECTION .text

    global test_func
    
    test_func:
        mov eax, 4
        mov ebx, 1
        mov ecx, error_len_message
        mov edx, error_len_message_len
        int 80H

The header file would be trivial as it would only need the signature used in main.c

#include    "....."

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

The make file of the executable is as follows:

util_tests: ../asm/utilities/utilities.o
    gcc -Wall -o ./build/$@ main.c  $?

../asm/utilities/utilities.o:
    cd ../asm/utilities && make && cd ../../util_tests;

clean:
    cd ../asm/utilities && make clean && cd ../../util_tests;

The make file of the utilities is as follows:

utilities.o: test/test.o
    ld $? -o $@
    
test/test.o:
    cd test && make && cd ..;

clean:
    cd test && make clean && cd ..;
    rm *.o

The make file of test assembler code is:

test.o: test.asm
    nasm -f elf64 -g -F dwarf $?
clean:
    rm *.o

I have no trouble turning this into an executable using assembler only and printing strings defined in .data section. Make file:

test: test.o
    ld -o test $^ 

test.o: *.asm
    nasm -f elf64 -g -F stabs $?
clean:
    rm *.o

I can successfully define and use variables in the .bss section (not shown for brevity)

The problem, I believe, is in the way I am building the utility. Thanks in advance!

bichito
  • 1,406
  • 2
  • 19
  • 23
  • 1
    It's kind of hard to follow all the makefiles. Can you just show the commands that are actually executed by make in order to build this? – Nate Eldredge Aug 06 '20 at 06:57
  • 1
    Perhaps your problem is that you're calling int80 while building 64bit, which [doesn't always work](https://stackoverflow.com/q/46087730/2189500). – David Wohlferd Aug 06 '20 at 09:14
  • I will repost the question with comments suggestions later today. Thanks! – bichito Aug 06 '20 at 15:18
  • It turns out that by having an intermediate *.o (utilities) was masking the fact that test.asm was not really PIC. When I tried to simplify as suggested by previous comments, the linker complained about .data not being relocatable. I will address this which explains why the labels in the .data had weird addresses – bichito Aug 07 '20 at 21:25
  • Problem solved, removed intermediate Makefile and removed int 80H call to avoid limitations. Thanks! – bichito Aug 08 '20 at 05:02

1 Answers1

0

So after adding the pertinent "default rel" to the assembler source file, removing direct calls to int 80H, and adding calls printf, the linker fails because it also tries to relocate "printf@glibc_x.x.x". After trying linker options to ignore unresolved symbols, it seems like a dead end.

So it seems there are only two choices, assemble in 32 bit to avoid problems with "int 80H", or return status/results and let the caller deal with the rest. The following assemble, link, and gdb displays labels and offsets matching correctly

DEFAULT REL

SECTION .text    

    global silly    
    
    silly:
        lea r9, [message]
        ret
        
SECTION .data
    message: db  "A Message", 10

Makefile:

silly.so: silly.o
    ld -shared $? -o $@

silly.o: silly.asm
    nasm -f elf64 -g -F dwarf $?
    
clean:
    rm *.o
    rm *.so

Hopefully, this would be useful to anyone

bichito
  • 1,406
  • 2
  • 19
  • 23