Skip to content

Commit

Permalink
Improve readme.
Browse files Browse the repository at this point in the history
  • Loading branch information
caikelun committed Jun 25, 2021
1 parent 42a365a commit a8ef386
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 17 deletions.
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void *xdl_open(const char *filename, int flags);
void *xdl_close(void *handle);
```
They are very similar to `dlopen()` and `dlclose()`. But `xdl_open()` can bypass the restrictions of Android 7.0+ linker namespace.
They are very similar to [`dlopen()`](https://man7.org/linux/man-pages/man3/dlopen.3.html) and [`dlclose()`](https://man7.org/linux/man-pages/man3/dlclose.3.html). But `xdl_open()` can bypass the restrictions of Android 7.0+ linker namespace.
Depending on the value of the `flags` parameter, the behavior of `xdl_open()` will have some differences:
Expand Down Expand Up @@ -176,7 +176,7 @@ void *xdl_sym(void *handle, const char *symbol, size_t *symbol_size);
void *xdl_dsym(void *handle, const char *symbol, size_t *symbol_size);
```

They are very similar to `dlsym()`. They all takes a "handle" of an ELF returned by `xdl_open()` and the null-terminated symbol name, returning the address where that symbol is loaded into memory.
They are very similar to [`dlsym()`](https://man7.org/linux/man-pages/man3/dlsym.3.html). They all takes a "handle" of an ELF returned by `xdl_open()` and the null-terminated symbol name, returning the address where that symbol is loaded into memory.

If the `symbol_size` parameter is not `NULL`, it will be assigned as "the bytes occupied by the content corresponding to the symbol in the ELF". If you don't need this information, just pass `NULL`.

Expand All @@ -193,18 +193,30 @@ Notice:
### 3. `xdl_addr()`

```C
int xdl_addr(void *addr, Dl_info *info, void **cache);
typedef struct
{
const char *dli_fname;
void *dli_fbase;
const char *dli_sname;
void *dli_saddr;
size_t dli_ssize;
const ElfW(Phdr) *dlpi_phdr;
size_t dlpi_phnum;
} xdl_info;

int xdl_addr(void *addr, xdl_info *info, void **cache);
void xdl_addr_clean(void **cache);
```
`xdl_addr()` is similar to `dladdr()`. But there are a few differences:
`xdl_addr()` is similar to [`dladdr()`](https://man7.org/linux/man-pages/man3/dladdr.3.html). But there are a few differences:
* `xdl_addr()` can lookup not only dynamic link symbols, but also debugging symbols.
* `xdl_addr()` uses the `xdl_info` structure instead of the `Dl_info` structure, which contains more extended information: `dli_ssize` is the number of bytes occupied by the current symbol; `dlpi_phdr` points to the program headers array of the ELF where the current symbol is located; `dlpi_phnum` is the number of elements in the `dlpi_phdr` array.
* `xdl_addr()` needs to pass an additional parameter (`cache`), which will cache the ELF handle opened during the execution of `xdl_addr()`. The purpose of caching is to make subsequent executions of `xdl_addr()` of the same ELF faster. When you do not need to execute `xdl_addr()`, please use `xdl_addr_clean()` to clear the cache. For example:
```C
void *cache = NULL;
Dl_info info;
xdl_info info;
xdl_addr(addr_1, &info, &cache);
xdl_addr(addr_2, &info, &cache);
xdl_addr(addr_3, &info, &cache);
Expand All @@ -215,18 +227,16 @@ xdl_addr_clean(&cache);

```C
#define XDL_DEFAULT 0x00
#define XDL_WITH_LINKER 0x01
#define XDL_FULL_PATHNAME 0x02
#define XDL_FULL_PATHNAME 0x01

int xdl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *data, int flags);
```
`xdl_iterate_phdr()` is similar to `dl_iterate_phdr()`. But `xdl_iterate_phdr()` is compatible with android 4.x on ARM32.
`xdl_iterate_phdr()` is similar to [`dl_iterate_phdr()`](https://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html). But `xdl_iterate_phdr()` is compatible with android 4.x on ARM32, and always including linker / linker64.
`xdl_iterate_phdr()` has an additional "flags" parameter, one or more flags can be bitwise-or'd in it:
* `XDL_DEFAULT`: Default behavior.
* `XDL_WITH_LINKER`: Always including linker / linker64.
* `XDL_FULL_PATHNAME`: Always return full pathname instead of basename.
These flags are needed because these capabilities require additional execution time, and you don't always need them.
Expand Down
26 changes: 18 additions & 8 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void *xdl_open(const char *filename, int flags);
void *xdl_close(void *handle);
```
它们和 `dlopen()` / `dlclose()` 很相似。但是 `xdl_open()` 可以绕过 Android 7.0+ linker namespace 的限制。
它们和 [`dlopen()`](https://man7.org/linux/man-pages/man3/dlopen.3.html) / [`dlclose()`](https://man7.org/linux/man-pages/man3/dlclose.3.html) 很相似。但是 `xdl_open()` 可以绕过 Android 7.0+ linker namespace 的限制。
根据 `flags` 参数值的不同,`xdl_open()` 的行为会有一些差异:
Expand Down Expand Up @@ -176,7 +176,7 @@ void *xdl_sym(void *handle, const char *symbol, size_t *symbol_size);
void *xdl_dsym(void *handle, const char *symbol, size_t *symbol_size);
```

它们和 `dlsym()` 很相似。 它们都需要传递一个 `xdl_open()` 返回的 “handle”,和一个 null 结尾的符号名字,返回该符号在内存中的加载地址。
它们和 [`dlsym()`](https://man7.org/linux/man-pages/man3/dlsym.3.html) 很相似。 它们都需要传递一个 `xdl_open()` 返回的 “handle”,和一个 null 结尾的符号名字,返回该符号在内存中的加载地址。

如果 `symbol_size` 参数不为 `NULL`,它将被赋值为“符号对应的内容在 ELF 中占用的字节数”,如果你不需要这个信息,传递 `NULL` 就可以了。

Expand All @@ -193,13 +193,25 @@ void *xdl_dsym(void *handle, const char *symbol, size_t *symbol_size);
### 3. `xdl_addr()`

```C
int xdl_addr(void *addr, Dl_info *info, void **cache);
typedef struct
{
const char *dli_fname;
void *dli_fbase;
const char *dli_sname;
void *dli_saddr;
size_t dli_ssize;
const ElfW(Phdr) *dlpi_phdr;
size_t dlpi_phnum;
} xdl_info;

int xdl_addr(void *addr, xdl_info *info, void **cache);
void xdl_addr_clean(void **cache);
```
`xdl_addr()` 和 `dladdr()` 很相似。但有以下几点不同:
`xdl_addr()` 和 [`dladdr()`](https://man7.org/linux/man-pages/man3/dladdr.3.html) 很相似。但有以下几点不同:
* `xdl_addr()` 不仅能查询动态链接符号,还能查询调试符号。
* `xdl_addr()` 使用 `dl_info` 结构体代替了 `Dl_info` 结构体,它包含了更多的扩展信息:`dli_ssize` 是当前符号所占用的字节数;`dlpi_phdr` 指向当前符号所在 ELF 的 program headers 数组;`dlpi_phnum` 是 `dlpi_phdr` 数组的元素个数。
* `xdl_addr()` 需要传递一个附加的参数(cache),其中会缓存 `xdl_addr()` 执行过程中打开的 ELF handle,缓存的目的是使后续对同一个 ELF 的 `xdl_addr()` 执行的更快。当不需要再执行 `xdl_addr()` 时,请使用 `xdl_addr_clean()` 清除缓存。举例:
```C
Expand All @@ -215,18 +227,16 @@ xdl_addr_clean(&cache);

```C
#define XDL_DEFAULT 0x00
#define XDL_WITH_LINKER 0x01
#define XDL_FULL_PATHNAME 0x02
#define XDL_FULL_PATHNAME 0x01

int xdl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *data, int flags);
```
`xdl_iterate_phdr()` 和 `dl_iterate_phdr()` 很相似。但是 `xdl_iterate_phdr()` 兼容 ARM32 平台的 Android 4.x 系统。
`xdl_iterate_phdr()` 和 [`dl_iterate_phdr()`](https://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html) 很相似。但是 `xdl_iterate_phdr()` 兼容 ARM32 平台的 Android 4.x 系统,并且总是包含 linker / linker64
`xdl_iterate_phdr()` 有一个额外的“flags”参数,一个或多个“flag”可以按位“或”后传递给它:
* `XDL_DEFAULT`: 默认行为。
* `XDL_WITH_LINKER`: 总是包含 linker / linker64。
* `XDL_FULL_PATHNAME`: 总是返回完整的路径名(full pathname),而不是文件名(basename)。
需要这些 flags 的原因是,这些额外的能力也需要花费额外的执行时间,而你并不总是需要这些能力。
Expand Down

0 comments on commit a8ef386

Please sign in to comment.