【Linux】库制作与原理

库制作与原理


文章目录

  • 库制作与原理
  • 一、什么是库
  • 四个总结
  • 二、静态库
    • [2.1 静态库生成](#2.1 静态库生成)
    • [2.2 静态库使用](#2.2 静态库使用)
  • 三、动态库
    • [3.1 动态库生成](#3.1 动态库生成)
    • [3.2 动态库使用](#3.2 动态库使用)
    • [3.3 库运行搜索路径](#3.3 库运行搜索路径)
  • 五、目标文件
  • 六、ELF文件
  • 七、ELF从形成到加载轮廓
    • [7.1 ELF形成可执行](#7.1 ELF形成可执行)
    • [7.2 ELF可执行文件加载](#7.2 ELF可执行文件加载)
  • 八、理解链接与加载
    • [8.1 静态链接](#8.1 静态链接)
    • [8.2 ELF加载与进程地址空间](#8.2 ELF加载与进程地址空间)
      • [8.2.1 虚拟地址/逻辑地址](#8.2.1 虚拟地址/逻辑地址)
      • [8.2.2 重新理解进程虚拟地址空间](#8.2.2 重新理解进程虚拟地址空间)
    • [8.3 动态链接与动态库加载](#8.3 动态链接与动态库加载)
      • [8.3.1 进程如何看到动态库](#8.3.1 进程如何看到动态库)
      • [8.3.2 进程间如何共享库](#8.3.2 进程间如何共享库)
      • [8.3.3 动态链接](#8.3.3 动态链接)
        • [8.3.3.1 概要](#8.3.3.1 概要)
        • [8.3.3.2 我们的可执行程序被编译器动了手脚](#8.3.3.2 我们的可执行程序被编译器动了手脚)
        • [8.3.3.3 动态库中的相对地址](#8.3.3.3 动态库中的相对地址)
        • [8.3.3.4 我们的程序怎么和库具体映射起来的](#8.3.3.4 我们的程序怎么和库具体映射起来的)
        • [8-3-3-5 我们的程序,怎么进⾏库函数调⽤](#8-3-3-5 我们的程序,怎么进⾏库函数调⽤)
        • [8-3-3-6 全局偏移量表GOT(global offset table)](#8-3-3-6 全局偏移量表GOT(global offset table))
        • [8-3-3-7 库间依赖](#8-3-3-7 库间依赖)
      • [8.3.4 总结](#8.3.4 总结)

一、什么是库





预备工作,准备好历史封装的libc代码,在任意新增"库文件"

代码如下(示例):

c 复制代码
// my_stdio.h
#pragma once
#define SIZE 1024
#define FLUSH_NONE 0
#define FLUSH_LINE 1
#define FLUSH_FULL 2
struct IO_FILE
{
int flag; // 刷新⽅式
int fileno; // ⽂件描述符
char outbuffer[SIZE];
int cap;
int size;
// TODO
};
typedef struct IO_FILE mFILE;
mFILE *mfopen(const char *filename, const char *mode);
int mfwrite(const void *ptr, int num, mFILE *stream);
void mfflush(mFILE *stream);
void mfclose(mFILE *stream);
// my_stdio.c
#include "my_stdio.h"
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
mFILE *mfopen(const char *filename, const char *mode)
{
int fd = -1;
if(strcmp(mode, "r") == 0)
{
fd = open(filename, O_RDONLY);
}
else if(strcmp(mode, "w")== 0)
{
fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC, 0666);
}
else if(strcmp(mode, "a") == 0)
{
fd = open(filename, O_CREAT|O_WRONLY|O_APPEND, 0666);
}
if(fd < 0) return NULL;
mFILE *mf = (mFILE*)malloc(sizeof(mFILE));
if(!mf)
{
close(fd);
return NULL;
}
mf->fileno = fd;
mf->flag = FLUSH_LINE;
mf->size = 0;
mf->cap = SIZE;
return mf;
}
void mfflush(mFILE *stream)
{
if(stream->size > 0)
{
// 写到内核⽂件的⽂件缓冲区中!
write(stream->fileno, stream->outbuffer, stream->size);
// 刷新到外设
fsync(stream->fileno);
stream->size = 0;
}
}
int mfwrite(const void *ptr, int num, mFILE *stream)
{
// 1. 拷⻉
memcpy(stream->outbuffer+stream->size, ptr, num);
stream->size += num;
// 2. 检测是否要刷新
if(stream->flag == FLUSH_LINE && stream->size > 0 && stream-
>outbuffer[stream->size-1]== '\n')
{
mfflush(stream);
}
return num;
}
void mfclose(mFILE *stream)
{
if(stream->size > 0)
{
mfflush(stream);
}
close(stream->fileno);
}
// my_string.h
#pragma once
int my_strlen(const char *s);
// my_string.c
#include "my_string.h"
int my_strlen(const char *s)
{
const char *end = s;
while(*end != '\0')end++;
return end - s;
}

四个总结


二、静态库

2.1 静态库生成



2.2 静态库使用


三、动态库

3.1 动态库生成



3.2 动态库使用


3.3 库运行搜索路径


五、目标文件






六、ELF文件





七、ELF从形成到加载轮廓

7.1 ELF形成可执行



注意:实际合并是在链接时进行的,但是并不是这么简单的合并,也会
涉及对库的合并!


7.2 ELF可执行文件加载






八、理解链接与加载

8.1 静态链接





8.2 ELF加载与进程地址空间

8.2.1 虚拟地址/逻辑地址


8.2.2 重新理解进程虚拟地址空间

ELF在被编译好之后,会把自己未来程序的入口地址记录在
ELF header的Entry字段中


8.3 动态链接与动态库加载

8.3.1 进程如何看到动态库


8.3.2 进程间如何共享库


8.3.3 动态链接

8.3.3.1 概要

8.3.3.2 我们的可执行程序被编译器动了手脚




8.3.3.3 动态库中的相对地址

8.3.3.4 我们的程序怎么和库具体映射起来的

8-3-3-5 我们的程序,怎么进⾏库函数调⽤

8-3-3-6 全局偏移量表GOT(global offset table)


8-3-3-7 库间依赖





8.3.4 总结


相关推荐
shan~~4 小时前
linux安装海量数据库和操作
linux·数据库·oracle
JAVA学习通4 小时前
Docker 安装 Harbor 教程
运维·docker·容器
fatiaozhang95274 小时前
高安版_中兴B860AV3.2M_晶晨S905L3B_安卓9_兼容uwe5621ds无线-线刷固件包
android·电脑·电视盒子·av1·刷机固件
qq_203183574 小时前
flink的Standalone-HA模式安装
linux
乌萨奇也要立志学C++4 小时前
【Linux】进程控制(二) 深入理解进程程序替换与 exec 系列函数
linux·运维·服务器
ShareBeHappy_Qin4 小时前
Linux 命令 —— 常用命令总结
linux·运维·服务器
Ronin3055 小时前
【Linux网络】Socket编程:TCP网络编程
linux·网络·网络编程·tcp
是店小二呀5 小时前
【技术文档:Dify 本地 Docker 环境邮件服务排错指南】
运维·docker·容器
不会c嘎嘎5 小时前
Linux -- 网络层
linux·运维·网络