gcc中链接脚本lds如何使用?

gcc中链接脚本lds如何使用?,第1张

有两种使用方法:

1,lds作为外置脚本,参与对gcc链接过程的控制。使用方法为

gcc XXX.c XX.lds。

gcc能够自动识别你的文件列中后缀不能识别的文件,作为链接脚本使用。这样编译出来的程序,还是要使用gcc默认的lds脚本,你的脚本只是一个辅助。

2,lds代替系统的脚本。

这种要先使用gcc -c参数编译你的源程序,编译出来的.o文件,使用命令ld -T来指定lds文件链接到一起。

可以参考:

#include

<sys/types.h>

#include

<sys/stat.h>

#include

<unistd.h>

#include

<stdio.h>

#include

<string.h>

#include

<errno.h>

#include

<pwd.h>

#include

<grp.h>

#include

<time.h>

#include

<dirent.h>

int

do_ls(char

*dir,char

*filename,int

lflag)

{

int

n

struct

stat

buf

char

out[100]

struct

passwd

*pw

struct

group

*gr

struct

tm

*t

if(lflag

==

0)

//如果不带l参数,直接显示文件/目录

{

printf("%s\t",filename)

return

0

}

if(lstat(dir,&buf)<0)

{

fprintf(stderr,"stat

error:%s\n",strerror(errno))

return

-1

}

switch(buf.st_mode

&

s_ifmt)

//获取字符串的属性:普通文件-、目录d、字符设备c、块设备b、管道文件p、连接文件l、套接字文件s

{

case

s_ifreg:

printf("-")

break

case

s_ifdir:

printf("d")

break

case

s_ifchr:

printf("c")

break

case

s_ifblk:

printf("b")

break

case

s_ififo:

printf("p")

break

case

s_iflnk:

printf("l")

break

case

s_ifsock:

printf("s")

break

}

for(n=8n>=0n--)

//打印文件的读写属性:读r、写w、执行x、无权限-

{

if(buf.st_mode&(1<<n))

{

switch(n%3)

{

case

2:

printf("r")

break

case

1:

printf("w")

break

case

0:

printf("x")

break

default:

break

}

}

else

{

printf("-")

}

}

printf("

%d",buf.st_nlink)

//硬链接数,此链接非彼链接,指(包含)目录的个数,文件为1,目录起始为2,再加上目录里包含的目录个数(不递归,只一层)

pw

=

getpwuid(buf.st_uid)

//所属用户名

printf("

%s",pw->pw_name)

gr

=

getgrgid(buf.st_gid)

//所属组名

printf("

%s",gr->gr_name)

printf("

%ld",buf.st_size)

//字节计总大小

t

=

localtime(&buf.st_atime)

//最后一次访问时间

printf("

%d-%d-%d

%d:%d"

,t->tm_year+1900

,t->tm_mon+1

,t->tm_mday

,t->tm_hour

,t->tm_min)

printf("

%s

",filename)

if(s_islnk(buf.st_mode))

//判断是否为链接,是返回真

{

printf("

->

")

if(readlink(filename,out,100)==-1)

{

//printf("readlink

error\n")

}

printf("%s",out)

}

printf("\n")

return

0

}

int

ls_prepare(char

*w,int

aflag,int

lflag)

//ls的准备工作

{

struct

stat

buf

//man

lstat可以看到此结构

char

name[100]

dir

*dir

//类似打开文件的fd描述符

struct

dirent

*pdr

//man

readdir可以看到此结构

if(lstat(w,&buf)<0)

//获取文件/目录属性并赋值给buf,该函数和lstat一样,只是当w为链接时,指代他本身,并不存在文件

{

fprintf(stderr,"stat

error:%s\n",strerror(errno))

return

-1

}

if(s_isdir(buf.st_mode))

//判断是否为目录,是返回真

{

dir

=

opendir(w)

//打开目录

while

((pdr

=

readdir(dir))!=null)

//读/遍历目录

{

if(aflag==0)

//如果不带a参数,越过以.开头的所有文件/目录

{

if(pdr->d_name[0]=='.')

continue

memset(name,0,100)

strcpy(name,w)

//拷贝

strcat(name,"/")

//追加

strcat(name,pdr->d_name)

do_ls(name,pdr->d_name,lflag)

}else

//有a参数显示所有

{

memset(name,0,100)

strcpy(name,w)

strcat(name,"/")

strcat(name,pdr->d_name)

do_ls(name,pdr->d_name,lflag)

}

}

closedir(dir)

}else

//为文件则直接显示

{

do_ls(w,w,lflag)

}

return

0

}

int

main(int

argc,char

**argv)

{

int

aflag

=0

int

lflag

=0

char

c

int

i

while((c

=

getopt(argc,argv,"al"))!=-1)

//解析命令行参数,即-/--后面的字符串和给定的字符串匹配,有未解析字母返回字母或问号(取决于第3个参数),否则返回-1

{

switch(c)

//此处仅匹配a(所有)和l(列表),即只支持参数a、l

{

case

'a':

aflag

=1

break

case

'l':

lflag

=1

break

default:

break

}

}

if(argc

==

optind

)

//optind系统变量,执行命令参数的个数(不包括命令,奇怪的是无参情况下他为1),判断argc是否为1,是则取当前路径,让我们显得更专业点

{

ls_prepare("./",aflag,lflag)

}

else

{

for(i=optindi<argci++)

//所有目录都传进去

ls_prepare(argv[i],aflag,lflag)

}

printf("\n")

return

0

}

在Linux内核中,使用 vmlinux.lds.S 文件(路径: arch/arm64/kernel/ )布局内核映像中相关段(例: .text、.data )的位置。

在Linux内核编译时, vmlinux.lds.S 文件最终会被构建成链接脚本 vmlinux.lds 文件(路径: arch/arm64/kernel/ )。

本文主要介绍Linux内核程序运行的起始位置 _text ,在 vmlinux.lds.S 文件中定义如下:

从上面可以看出: _text = KIMAGE_VADDR + TEXT_OFFSET 。

1、KIMAGE_VADDR定义

文件: arch/arm64/include/asm/memory.h ,定义如下:

文件: include/linux/sizes.h ,定义如下:

宏 KIMAGE_VADDR 展开如下:

上面是按照无符号计算, KIMAGE_VADDR 为: 0xFFFFFF8008000000 。

2、TEXT_OFFSET定义

文件: arch/arm64/Makefile ,定义如下:

通过计算, _text 值为: 0xFFFFFF8008080000 。

在Linux内核启动时,从 log 信息中也可以找到对应的地址:

_text 对应的是虚拟地址 在内核中可以直接通过访问该地址获取其保存的值 ,其对应 Image 映像中的第一个字 0x14424000 。

Image 映像查看方法如下:

本文基于 RockPI 4A 单板Linux 4.4内核。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/8991293.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-23
下一篇 2023-04-23

发表评论

登录后才能评论

评论列表(0条)

保存