LLDB on linux cannot step into function of shared library - lldb

I have build lldb from llvm tag 14.0.4 on linux (tested on archlinux latest and centos 7), but it cannot step into function of shared library but gdb could.
This is a minimal example
// main.cpp
#include "mylib.h"
int main(int argc, char *argv[]) {
add(argc, argc ^ 0xFF);
add(argc, argc ^ 0xFF);
return 0;
}
// mylib.h
int add(int a, int b);
// mylib.cpp
int add(int a, int b) {
return a ^ b & b;
}
The makefile is
all:
clang++ mylib.cpp -O0 -g3 -shared -fpic -o mylib.so
clang++ main.cpp -O0 -g3 mylib.so -o main
After building the program, you can use LD_LIBRARY_PATH=. lldb main to load the program into lldb and reproduce the problem with the following steps
b main to set a breakpoint at main function
r to start the program
and now you reached to line add(argc, argc ^ 0xFF);, press s to step into source, but you will get into assemble, a demo output will like
(lldb) s
Process 15758 stopped
* thread #1, name = 'main', stop reason = step in
frame #0: 0x0000000000400500 main`add(int, int)
main`add:
-> 0x400500 <+0>: jmp qword ptr [rip + 0x200b22] ; _GLOBAL_OFFSET_TABLE_ + 40
0x400506 <+6>: push 0x2
0x40050b <+11>: jmp 0x4004d0
main`_start:
0x400510 <+0>: xor ebp, ebp
If you use gdb to debug the program, gdb will step you into add function rather than assemble codes.
I have tried lldb on macOS 12.5, it works fine.

This problem was reported to the lldb bug tracker:
https://github.com/llvm/llvm-project/issues/54250
It seems to have been a bug in some of the 14.x versions of lldb on Linux, but the originator of that bug said it was fixed in 15.0 and the TOT lldb's.

Related

gcc error message: stray '\XXX' in program

I've started learning Assembly, and I have two files:
main.c
#include <stdio.h>
int assembly(void);
int main(void)
{
printf("Resultado: %d\n", assembly());
return 0;
}
and
assembly.asm
global assembly
assembly:
mov eax, 777
ret
So I used this command "nasm assembly.asm -f elf64" and it created the file "assembly.o". After that, I used another command "gcc -c main.c -o main.o" but it showed some errors on the shell:
What can I do?

How to fix ".c:6: undefined reference to 'printf'

I am freshman, I want to learn about ARM assembly language and using gnu toolchain so I decided to start with small project that mixes arm-assembly file and C file by gnu toolchain. My idea is calling a function that is defined in assembly file.
multi.S:
.globl multi
multi:
str fp,[sp,#-4]!
add fp,sp,#0
sub sp,sp,#12
str r0,[fp,#-8]
str r1,[fp,#-12]
ldr r3,[fp,#-8]
ldr r2,[fp,#-12]
mul r1,r2,r3
mov r3,r1
mov r0,r3
add sp,fp,#0
ldr fp,[sp],#4
bx lr
multi.c:
#include <stdio.h>
unsigned int multi(unsigned int a, unsigned int b);
int main(int argc, char *argv[]){
unsigned int x = multi(3,4);
printf("%u\n",x);
return 0;
}
Then I tried to link them together by using command as follows:
arm-none-eabi-gcc -g -c -o multi-arm.o multi.S
arm-none-eabi-gcc -g -c -o multi.o multi.c
arm-none-eabi-ld multi.o multi-arm.o -o multi.elf
But there's some errors occurred:
warning: can not find entry symbol _start; defaulting to 0000000082000000
=> I solved this problem by adding -lc --entry main and the warning message is gone.
multi.c:6: undefined reference to 'printf'. I am stuck with this error and it took me 2 hours searching for sulution but I still can't not fix it.
Above is my question.
Thank you all for reading.
Try this
arm-none-eabi-as -g -o multi-arm.o multi.S
arm-none-eabi-gcc -g -o multi.elf multi.c multi-arm.o
If you want to use the linker directly then you have to provide the path to the C library on the command line. Gcc knows where the library is (relative to where it executes from and was compiled for) when it calls the linker, but for some strange reason ld does not.

Commands to compile ASM file with C program [duplicate]

This question already has an answer here:
32-bit absolute addresses no longer allowed in x86-64 Linux?
(1 answer)
Closed 4 years ago.
with à 64 Linux system and using NASM.
I'm trying too link my ASM (hello.asm) file with a C file (main.c) and compile to a execution file.
I create a ASM file that print "Hello" with printf by using printHello function.
extern printf, exit
section .data
format db "Hello", 10, 0
section .text
global printHello
printHello:
sub rsp, 8
mov rsi, 0x12345677
mov rdi, format
xor rax, rax
call printf
mov rdi, 0
call exit
I create a simple main.c and call my function "printHello" to print "Hello"
#include <stdio.h>
void printHello();
int main()
{
printHello();
}
My command for compile :
$ nasm -f elf64 hello.asm
$ gcc -c main.c
$ gcc -o executable main.o hello.o
$ ./executable
And it prints :
./executable: Symbol `printf' causes overflow in R_X86_64_PC32 relocation
./executable: Symbol `exit' causes overflow in R_X86_64_PC32 relocation
[1] 6011 segmentation fault ./executable
I'm already learning ASM. Is the problem come from my command or my code ?
I resolved the problem by using your #Jester solution :
gcc -no-pie -o executable main.o hello.o
and thanks Ped7g for explanation.

Calling a C main() function from an x86 32-bit assembly _start [duplicate]

This question already has answers here:
x86 Linux assembler get program parameters from _start
(1 answer)
Get argv[2] address in assembler x64
(1 answer)
Closed 5 years ago.
I am trying to write a homework assignment which is to:
write a simple Assembly program that all it does is call a C program,
and send to it the command line arguments so that it may run properly
with (argc and argv).
How can this be done? We were given this asm as part of the assignment:
section .text
global _start
extern main
_start:
;;code to setup argc and argv for C program's main()
call main
mov eax,1
int 0x80
So what I want to know is, where are argc and argv located? Also, do I just need to put the pointer to argc in the eax register like when returning a value to a regular C function and the C program will work the rest out?
In the end, after compiling my C program with the following Makefile (as I said, I am new to Assembly and this is the Makefile given to us by the teacher, I do not fully understand it):
%.o: %.asm
nasm -g -O1 -f elf -o $# $<
%.o: %.c
gcc -m32 -g -nostdlib -fno-stack-protector -c -o $# $<
all: lwca
lwca: lwc.o start.o
ld -melf_i386 -o $# $^
Running ./lwca arg1 arg2 should result in argc = 3 and argv[1]=arg1 argc[2]=arg2
ANSWER:
No answer quite solved my problem, in the end the what worked was:
pop dword ecx ; ecx = argc
mov ebx,esp ; ebx = argv
push ebx ; char** argv
push ecx ; int argc
call main

ld makes all my functions link to the last one in header file

I've started working on a home-brew OS for learning purposes. So it works like this :
Once the kernel is loaded I create a stack and call my kmain()
In kmain I try calling function foo() defined in header.h
//Header.h
#ifndef INCLUDE_HEADER_H
#define INCLUDE_HEADER_H
int foo(char* buf);
int bar();
#endif
Using nm on my kernel I can clearly see that foo() is in the binary but when I disassemble kmain with gdb I see that foo isn't called, instead bar is.
This problem is recurrent on all headers containing multiple functions.
I compile on windows 10 in a Cygwin environment. I use the following arguments passed to nasm/gcc/ld in my makefile
CC = gcc
CFLAGS = -m32 -nostdlib -nostdinc \
-nostartfiles -fno-leading-underscore -nodefaultlibs\
-Wall -Wextra -Wno-unused-variable -Wno-unused-function\
-c
LD = i686-elf-ld
LDFLAGS = -Tlink.ld -melf_i386
AS = nasm
ASFLAGS = -f elf
Any ideas why ?
EDIT :
//screen.h
#ifndef SCREEN_H
#define SCREEN_H
int test();
void print(char c);
#endif
And
//kmain.c
#include "screen.h"
int kmain(){
int b = test();
print('A');
return 0xcafebabe;
}
nm kernel.elf
$ nm kernel.elf
e4524ffe a CHECKSUM
00000000 a FLAGS
0010011c b kernel_stack
00004000 a KERNEL_STACK_SIZE
00100000 T kmain
001000c8 T loader
001000dd t loader.loop
1badb002 a MAGIC_NUMBER
001000b0 T outb
00100072 T print
0010002c T strlen
00100068 T test
0010005c T testFunc
gdb disassembly of kmain:
(gdb) disassemble kmain
Dump of assembler code for function kmain:
0x00100000 <kmain+0>: push %ebp
0x00100001 <kmain+1>: mov %esp,%ebp
0x00100003 <kmain+3>: sub $0x28,%esp
0x00100006 <kmain+6>: call 0x10006b <print+1> ;should call test but calls print instead
0x0010000b <kmain+11>: mov %eax,-0xc(%ebp)
0x0010000e <kmain+14>: movl $0x41,(%esp) ;pushes 'A'
0x00100015 <kmain+21>: call 0x100084 <print+26> ;calls print('A')
0x0010001a <kmain+26>: mov $0xcafebabe,%eax
0x0010001f <kmain+31>: leave
0x00100020 <kmain+32>: ret
0x00100021 <kmain+33>: nop
0x00100022 <kmain+34>: nop
0x00100023 <kmain+35>: nop
End of assembler dump.
0x00100006 <kmain+6>: call 0x10006b <print+1> ;should call test but calls print instead
<print+1> is just the label. This instruction does call the test function as can be seen from the address 0x10006b :
00100068 T test
00100072 T print
It'll be clearer if you look at the disassembly of the compiled "screen.c".
I found that the problem was in the compiler tool-chain I was using. It's what created the weird linking problem.
Here are the instructions I followed to compile a clean new Binutils + Gcc and it's working now !

Resources