[Shell command collection linker tool] Linux ld command links target files and libraries into executable files or library files


Shell command column: Full analysis of Linux Shell commands


describe


ldIt is a linker tool in the Linux environment. Its main function is to link multiple target files ( .oor .objfiles) into an executable file or library file. The following are ldthe main functions and effects of the command:

  1. Object file linking : ldMultiple object files can be linked into a single output file. These object files are usually generated by a compiler and contain the machine code of the program.

  2. Resolving symbols : During the linking process, ldsymbols in the object files are resolved and all function and variable references are resolved correctly.

  3. Generate executable files : ldNot only can you generate executable files, but you can also generate shared libraries or static libraries.

  4. Handle relocation : Since the code in the target file may be executed at any location, ldit is necessary to handle the relocation of these codes to ensure that the code is executed at the correct memory address.

  5. Merge segments : ldSimilar segments in the target file will be merged, such as .text(code segment) or .data(data segment).

  6. Link-time optimization : In some cases, ldlink-time optimization can also be done to improve the performance of the generated executable.

  7. Handles startup code : ldAlso responsible for linking startup code, which is the first piece of code that runs when the program starts executing.

Overall, ldcommands are an indispensable tool in Linux programming. They ensure that all parts of the program are put together correctly to produce an executable file that can be run.


Syntax format

ld [options] object_files [--] [library_files]

Parameter Description

  • -b <input-format>: Specifies the format of the object code input file.
  • -Bstatic: Only use static libraries.
  • -Bdynamic: Only use dynamic libraries.
  • -Bsymbolic: Bundle references to global symbols in shared libraries.
  • -c <MRI-commandfile>, --mri-script=<MRI-commandfile>: For compatibility with the MRI linker, ld accepts script files written in the MRI command language.
  • --cref: Create a cross-reference table.
  • -d,-dc,-dp: Space is allocated for public symbols even if a relocatable output file is specified (using -r). The script command "FORCE_COMMON_ALLOCATION" has the same effect.
  • -defsym: Creates the specified global symbol in the output file.
  • -demangle: Restore symbol names in error messages.
  • -e <entry>: Use the specified symbol as the initial execution point of the program.
  • -E,--export-dynamic: For ELF format files, when creating a dynamically linked executable file, add all symbols to the dynamic symbol table.
  • -f <name>, --auxiliary=<name>: For ELF format shared objects, set the DT_AUXILIARY name.
  • -F <name>, --filter=<name>: For ELF format shared objects, set the DT_FILTER name. This tells the dynamic linker that the symbol table of the shared object being created should be used as a filter for the symbol table of the shared object name.
  • -g: be ignored. Used to provide compatibility with other tools.
  • -h: For ELF format shared objects, set the DT_SONAME name.
  • -I<file>, -dynamic-linker <file>, --dynamic-linker=<file>: Specify the dynamic linker. This only makes sense when building an ELF executable that depends on a dynamic link library. The default dynamic linker is usually correct, don't use this option unless you know what you are doing.
  • -l <namespec>, --library=<namespec>: Add the specified library file to the list of files to be linked.
  • -L <searchdir>, --library-path=searchdir: Add the specified path to the directory list of the search library.
  • -M, --print-map: Display link map for diagnostic purposes.
  • -Map=<mapfile>: Output the link map to the specified file.
  • -m <emulation>: Emulates the specified linker.
  • -N,--omagic: Specifies reading/writing text and data segments.
  • -n,--nmagic: Turns off page alignment for sections and disables linking to shared libraries. If the output format supports Unix-style magic numbers, mark the output as "NMAGIC".
  • -noinhibit-exec: Generate output files even if non-fatal link errors occur. Normally, if the linker encounters an error during the linking process, it will not generate an output file.
  • -no-keep-memory: ld usually caches the input file's symbol table in memory to optimize memory usage speed. This option tells ld not to cache the symbol table. When linking large executables, you may need to use this option if ld runs out of memory space.
  • -O <level>: For non-zero optimization levels, ld will optimize the output. This operation is time consuming and should be used only when generating final results.
  • -o <output>, --output=<output>: Specify the name of the output file.
  • -oformat=<output-format>: Specifies the binary format of the output file.
  • -R <filename>,--just-symbols=<filename>: Read symbol names and addresses from the specified file.
  • -r,--relocatable: Produces relocatable output (called a partial join).
  • -rpath=<dir>: Adds the specified directory to the runtime library search path.
  • -rpath-link=<dir>: Specifies the directory to search for runtime shared libraries.
  • -S,--strip-debug: Ignore debugger symbol information from the output file.
  • -s,--strip-all: Ignore all symbol information from the output file.
  • -shared, -Bshareable: Create a shared library.
  • -split-by-file[=size]: Create additional segments up to size in the output file for each object file. size defaults to 1.
  • -split-by-reloc[=count]: Creates additional segments in the output file of the specified length.
  • --section-start=<sectionname>=<org>: Locates the specified section at the specified address in the output file.
  • -T <scriptfile>, --script=<scriptfile>: Use scriptfile as linker script. This script replaces ld's default linker script (not adds to it), so the script must specify everything needed for the output file. If the script file does not exist in the current directory, ld searches in the directory specified by the -L option.
  • -Ttext=<org>: Use the specified address as the starting point of the text segment.
  • -Tdata=<org>: Use the specified address as the starting point of the data segment.
  • -Tbss=<org>: Use the specified address as the starting point of the bss segment.
  • -t,--trace: Display the names of input files as they are processed.
  • -u <symbol>, --undefined=<symbol>: Forces the specified symbol to be undefined in the output file.
  • -v, -V, --version: Display the ld version number.
  • -warn-common: Warn when a universal symbol is combined with another universal symbol.
  • -warn-constructors: Warn if no global constructor is used.
  • -warn-once: Warn only once for each undefined symbol.
  • -warn-section-align: Warn if the output section address has been changed for alignment.
  • --whole-archive: For the specified archive file, include all files in the archive.
  • -X, --discard-locals: Remove all local temporary symbols.
  • -x, --discard-all: Remove all local symbols.

error condition

  • Unresolved symbol : If ldthe definition of a symbol cannot be found during the linking process, it will report an error and prompt an unresolved symbol.
  • Multiple definitions : If the same symbol is defined in multiple target files, ldan error will be reported.
  • File format mismatch : If you try to link target files in different formats, such as ELF and a.out, ldan error will be reported.
  • Library not found : -lIf the library specified using the option is not found in the library search path, ldan error will be reported.
  • Input/output errors : If an error occurs while reading the input file or writing the output file, an error ldwill be reported.

Precautions

When using commands in Linux ld, there are a few things to consider to ensure that the linking process goes smoothly and produces the correct output file:

  1. Order of libraries : On the command line, the order of libraries matters. Normally, object files should be listed first, followed by library files. This is because ldarguments are processed from left to right, and when it resolves symbol references in an object file, it looks for those symbols in subsequent library files.

  2. Linking of system libraries : When linking with system libraries, -loptions are usually used, for example -lmfor linking with math libraries. But to make sure the library's search paths are set correctly, you can use -Lthe option to add additional search paths.

  3. Static vs. dynamic linking : By default, lddynamically linked libraries are tried. If static linking is required, options are available -static. But be aware that static linking will increase the size of the output file.

  4. Symbol conflict : Make sure there are no duplicate definitions of symbols in different target files, otherwise ldmultiple definition errors will be reported.

  5. Use appropriate linker scripts : ldUse linker scripts to control the layout of your output files. If you have special needs, you can use -Tthe option to specify a custom linker script.

  6. Remove unnecessary symbol information : To reduce the size of the output file, you can use -sthe option to remove symbol information. But this can make subsequent debugging difficult.

  7. Ensure compatibility : Compatibility issues may arise if the linked object files were generated on a different system or using different compiler options. Make sure all files are compiled in the same environment.

  8. Check the output : After linking is complete, use filethe command to check the type of the output file to make sure it is in the expected format (for example, an ELF executable).

  9. Avoid using outdated libraries or options : Over time, some libraries or options may have been deprecated. Make sure you are using current versions of libraries and recommended linking options.

  10. Read the documentation : ldFeatures and options may change from version to version. Regularly consult man ldthis or other relevant documentation for the latest information and advice.

In summary, there are several aspects that need to be paid attention to when using ldthe command to ensure that the linking process is correct and the expected output file is generated.


underlying implementation

ldcommand, part of the GNU Binutils suite, is the standard linker in Linux. Its underlying implementation involves multiple complex steps and algorithms. The following is an overview of its core implementation:

  1. Input processing :

    • ldFirst read all input object files and library files.
    • It parses ELF (Executable and Linkable Format) or other format file headers to obtain segment information, symbol tables, etc.
  2. Symbol analysis :

    • ldBuild a global symbol table containing symbols from all input files.
    • For unresolved symbols (for example, functions referenced in one object file but defined elsewhere), ldall input library files are searched for definitions of these symbols.
    • If the definition of a symbol cannot be found, ldan error will be reported.
  3. Address assignment :

    • ldCombine all input file segments (eg .text, .data) into one large segment and assign addresses to it.
    • It also handles relocation entries that specify the location of code or data that needs to be modified at link time.
  4. Relocation :

    • Because object files are compiled independently, the address references they contain may not be the final correct addresses. ldUse relocation entries to update these references so that they point to the correct addresses.
  5. Output generated :

    • Once all symbols have been resolved and all segments assigned addresses, ldan output file is generated.
    • The output file is usually in ELF format, but can be in other formats, depending on the target platform.
  6. Optimization :

    • In some cases, ldlink-time optimization is also possible, such as removing unused code or data.

ldThe underlying implementation is mainly written in C language and is open source. Interested in the detailed implementation, you can check out the source code of the GNU Binutils project.

Overall, ldthe underlying implementation involves multiple complex steps, from parsing of input files to address assignment, relocation and final output generation. These steps ensure that the resulting executable or library file has correct access to its code and data when run.


Example

Example 1

Link two object files file1.oand file2.ogenerate an executable file program:

ld -o program file1.o file2.o

Example 2

Link object files file.oand use static libraries libstatic.a:

ld -o program file.o -Bstatic -lstatic

Example three

Link the object file and specify the path of the dynamic linker:

ld -o program file.o -I/usr/local/lib/ld-linux.so.2

Example 4

Link the target file and specify the binary format of the output file as elf64-x86-64:

ld -o program file.o -oformat=elf64-x86-64

Example five

Link object files and force symbols my_symbolto be undefined symbols in the output file:

ld -o program file.o -u my_symbol

Example 6

Link object files and use linker scripts linker_script.ld:

ld -o program file.o -T linker_script.ld

Example 7

Link the target file and display the name when processing the input file:

ld -o program file.o -t

Here are seven ldusage examples that I hope you find helpful. If you have additional questions or need further explanation, please let me know.


Use c language to simulate ld ideas

Implementing ldthe functionality of the command is a complex task, as ldit is a complete program linker that handles multiple file formats, parses symbols, handles relocations, etc. Full implementation ldof the functionality requires a lot of code and in-depth knowledge.

But I can provide you with a simplified conceptual implementation of a linker that will help you understand the basic workings of a linker. This is just a very basic example and cannot be used for actual linking tasks.

#include <stdio.h>
#include <stdlib.h>

// 假设我们有两个简单的目标文件格式:
// file1.o: "HELLO "
// file2.o: "WORLD"

int main(int argc, char *argv[]) {
    
    
    if (argc < 4) {
    
    
        printf("Usage: %s output input1 input2\n", argv[0]);
        return 1;
    }

    FILE *input1 = fopen(argv[2], "rb");
    FILE *input2 = fopen(argv[3], "rb");
    FILE *output = fopen(argv[1], "wb");

    if (!input1 || !input2 || !output) {
    
    
        perror("Error opening files");
        return 1;
    }

    // 简单地将两个输入文件的内容复制到输出文件
    char ch;
    while ((ch = fgetc(input1)) != EOF) {
    
    
        fputc(ch, output);
    }
    while ((ch = fgetc(input2)) != EOF) {
    
    
        fputc(ch, output);
    }

    fclose(input1);
    fclose(input2);
    fclose(output);

    printf("Linking completed.\n");
    return 0;
}

This simplified version of the linker simply copies the contents of two input files to a single output file. In an actual ldlinker, it handles complex tasks such as various object file formats, parsing symbols, handling relocations, and merging sections.

If you really want to get a deeper understanding of how linkers work, I recommend reading professional books on linkers and loaders, or looking at the source code of an open source linker like GNU ld.



Conclusion

During our exploration, we have gained an in-depth understanding of the power and wide application of Shell commands. However, learning these techniques is just the beginning. The real power comes from how you integrate them into your daily routine to increase efficiency and productivity.

Psychology tells us that learning is a continuous and active process. So, I encourage you to not only read and understand these commands, but also practice them. Try creating your own commands and gradually master shell programming so that it becomes part of your daily routine.

同时,请记住分享是学习过程中非常重要的一环。如果你发现本博客对你有帮助,请不吝点赞并留下评论。分享你自己在使用Shell命令时遇到的问题或者有趣的经验,可以帮助更多人从中学习。
此外,我也欢迎你收藏本博客,并随时回来查阅。因为复习和反复实践也是巩固知识、提高技能的关键。

最后,请记住:每个人都可以通过持续学习和实践成为Shell编程专家。我期待看到你在这个旅途中取得更大进步!


阅读我的CSDN主页,解锁更多精彩内容:泡沫的CSDN主页

在这里插入图片描述

Guess you like

Origin blog.csdn.net/qq_21438461/article/details/132913787