Write a simplified (💩) linker from more or less scratch
Supported ELF Low endian 64 bits
Decode header, sections & symbolsDisplay symbols defined and undefinedHandle multiple object files- 👉 Display relocation info
- Describe layout of the result file
- Resolve symbol references
- Relocate entries
graph TD;
subgraph level3
session
end
subgraph level2
vocabulary
end
subgraph level1
raw
end
subgraph level0
io
utility
end
raw-->utility
vocabulary-->raw
vocabulary-->utility
session-->io
session-->vocabulary
(WIP) Introduce an object file type to wrap over vocabulary types as they get vivifed from decoding the headerWrite aContext
component that keep state of current linking session, this should be passed around or installed, so that client can find out what offset to apply to object files for example...ObjectFile
should rely on anAddressLoader
facility that knows how to fix address based on whether they need offset correction or not- Y no UT ?
- Lot of redundant identical objects in
ObjectFile
, the containers should hold shared ptr instead
- Now - Pausing to work on P3385 implementation :/
- 04/07 - Fix symbol names
For section type symbols, we have to (unless I'm wrong) go back to the section header definition using the
symbol.sectionHeaderIndex()
, then use classic way to get the name for that section... The string table linked to viash_link
from thesymtab
section header is useless for those.
So the symbol
{
"name": ".debug_str",
"section": "Symtab",
"symbol": {
"binding": "Local",
"nameIndex": 0,
"sectionHeaderIndex": 11,
"size": 0,
"type": "Section",
"value": "0x00000000",
"visibility": "Default"
}
}
tracks back to
{
"index": 11,
"name": ".debug_str",
"section": {
"addr": 0,
"addrAlign": 1,
"entrySize": 1,
"flags": [
"isMerge",
"isStrings"
],
"info": 0,
"link": 0,
"nameIndex": 112,
"offset": 674,
"size": 101,
"type": "Progbits"
}
}
- 02/25 - Fix interpretation of section index in symbols, confirm (eyeball) vs readelf
{
"name": "__gmon_start__",
"section": "Dynsym",
"symbol": {
"binding": "Weak",
"nameIndex": 1,
"sectionHeaderIndex": "Undef",
"size": 0,
"type": "NoType",
"value": "0x00000000",
"visibility": "Default"
}
61: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
{
"name": "cairo_clip_preserve",
"section": "Dynsym",
"symbol": {
"binding": "Global",
"nameIndex": 1421,
"sectionHeaderIndex": 11,
"size": 38,
"type": "Func",
"value": "0x000236b0",
"visibility": "Default"
}
404: 00000000000236b0 38 FUNC GLOBAL DEFAULT 11 cairo_clip_preserve
- 02/11 - Decode symbol names
{
"content": {
"binding": "Global",
"nameIndex": 13238,
"sectionHeaderIndex": "0",
"size": 0,
"type": 2,
"value": "0x00000000",
"visibility": "Default"
},
"name": "xcb_render_create_picture"
}
-
02/04 - Decode symbol table entries, w/o decoded symbol names
-
01/21 - Decode name of section header from the string table
{ "ELFHeader": { "abi": "None", "abiVersion": 0, "addressClass": "64bits", "architecture": "Advanced Micro Devices X86-64 processor", "endianness": "LowEndian", "executionAddress": "0x00015860", "flags": "0x0000", "headerSize": 64, "headerVersion": 1, "objectFileType": "Shared", "objectFileVersion": 1, "padding": " ", "programTableAddress": "0x00000040", "programTableCount": 7, "programTableSize": 56, "sectionNameIndex": 25, "sectionTableAddress": "0x001175d8", "sectionTableCount": 26, "sectionTableSize": 64 }, "sectionHeaders": [ { "content": { "addr": 0, "addrAlign": 0, "entrySize": 0, "flags": "[]", "info": 0, "link": 0, "nameIndex": 0, "offset": 0, "size": 0, "type": "Null" }, "name": "" }, { "...": "..." }, { "content": { "addr": 0, "addrAlign": 1, "entrySize": 0, "flags": "[]", "info": 0, "link": 0, "nameIndex": 1, "offset": 1144064, "size": 211, "type": "Strtab" }, "name": ".shstrtab" } ] }
-
01/14 - Extract all section headers from ELF header
=== Elf header === {"Abi":"None","AbiVersion":0,"AddressClass":"64bits","Architecture":"Advanced Micro Devices X86-64 processor","Endianness":"LowEndian","ExecutionAddress":"0x00015860","Flags":"0x0000","HeaderSize":64,"HeaderVersion":1,"ObjectFileType":"Shared","ObjectFileVersion":1,"Padding":" ","ProgramTableAddress":"0x00000040","ProgramTableCount":7,"ProgramTableSize":56,"SectionNameIndex":25,"SectionTableAddress":"0x001175d8","SectionTableCount":26,"SectionTableSize":64} === Section table header === {"addr":0,"addrAlign":0,"entrySize":0,"flags":"[]","info":0,"link":0,"nameIndex":0,"offset":0,"size":0,"type":"Null"} === Section table header === {"addr":456,"addrAlign":8,"entrySize":4,"flags":"[]","info":0,"link":456,"nameIndex":15,"offset":456,"size":7352,"type":"Hash"} === Section table header === {"addr":7808,"addrAlign":8,"entrySize":0,"flags":"[]","info":0,"link":7808,"nameIndex":11,"offset":7808,"size":5184,"type":"Unknown (0x6ffffff6)"} === Section table header === {"addr":12992,"addrAlign":8,"entrySize":24,"flags":"[]","info":2,"link":12992,"nameIndex":21,"offset":12992,"size":19560,"type":"Dynsym"} ...
-
01/08 - ELF header decoded, can search for section header entry of a particular type
{"Abi":"None","AbiVersion":0,"AddressClass":"64bits","Architecture":"Advanced Micro Devices X86-64 processor","Endianness":"LowEndian","ExecutionAddress":"0x00015860","Flags":"0x0000","HeaderSize":64,"HeaderVersion":1,"ObjectFileType":"Shared","ObjectFileVersion":1,"Padding":" ","ProgramTableAddress":"0x00000040","ProgramTableCount":7,"ProgramTableSize":56,"SectionNameIndex":25,"SectionTableAddress":"0x001175d8","SectionTableCount":26,"SectionTableSize":64} Found 'Strtab' entry at: 0x1089fe6d8 Found 'Strtab' entry at: 0x1089fec18
There is no PLT in .O files as this is created by the linker. If an object file needs PLT , it will create a special relocation entries, which the linker will use to populate the PLT. What does it do , when do you need it , draw me a PLT , what uses it
There is no GOT in .O files as this is created by the linker. Usually the address is held in a register for efficient access.
Two fundamental entities require names in an object file: sections, and symbols. For symbols, the symbol (SymTab, DynSym) section header point to the strings table via the link field. For sections, the object file directly point to the string table via the section header string index field